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,
33 #include "pim_mroute.h"
35 #include "pim_iface.h"
37 #include "pim_mroute.h"
40 #include "pim_igmpv3.h"
45 #include "pim_neighbor.h"
47 #include "pim_ifchannel.h"
48 #include "pim_hello.h"
50 #include "pim_upstream.h"
52 #include "pim_macro.h"
53 #include "pim_ssmpingd.h"
54 #include "pim_zebra.h"
55 #include "pim_static.h"
57 #include "pim_zlookup.h"
62 static struct cmd_node pim_global_node
= {
68 static struct cmd_node interface_node
= {
74 static struct cmd_node debug_node
=
81 static void pim_if_membership_clear(struct interface
*ifp
)
83 struct pim_interface
*pim_ifp
;
88 if (PIM_IF_TEST_PIM(pim_ifp
->options
) &&
89 PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
93 pim_ifchannel_membership_clear(ifp
);
97 When PIM is disabled on interface, IGMPv3 local membership
98 information is not injected into PIM interface state.
100 The function pim_if_membership_refresh() fetches all IGMPv3 local
101 membership information into PIM. It is intented to be called
102 whenever PIM is enabled on the interface in order to collect missed
103 local membership information.
105 static void pim_if_membership_refresh(struct interface
*ifp
)
107 struct pim_interface
*pim_ifp
;
108 struct listnode
*sock_node
;
109 struct igmp_sock
*igmp
;
114 if (!PIM_IF_TEST_PIM(pim_ifp
->options
))
116 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
))
120 First clear off membership from all PIM (S,G) entries on the
124 pim_ifchannel_membership_clear(ifp
);
127 Then restore PIM (S,G) membership from all IGMPv3 (S,G) entries on
131 /* scan igmp sockets */
132 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
133 struct listnode
*grpnode
;
134 struct igmp_group
*grp
;
136 /* scan igmp groups */
137 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grpnode
, grp
)) {
138 struct listnode
*srcnode
;
139 struct igmp_source
*src
;
141 /* scan group sources */
142 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
, srcnode
, src
)) {
144 if (IGMP_SOURCE_TEST_FORWARDING(src
->source_flags
)) {
147 memset (&sg
, 0, sizeof (struct prefix_sg
));
148 sg
.src
= src
->source_addr
;
149 sg
.grp
= grp
->group_addr
;
150 pim_ifchannel_local_membership_add(ifp
, &sg
);
153 } /* scan group sources */
154 } /* scan igmp groups */
155 } /* scan igmp sockets */
158 Finally delete every PIM (S,G) entry lacking all state info
161 pim_ifchannel_delete_on_noinfo(ifp
);
165 static void pim_show_assert(struct vty
*vty
)
167 struct pim_interface
*pim_ifp
;
168 struct pim_ifchannel
*ch
;
169 struct listnode
*ch_node
;
170 struct in_addr ifaddr
;
173 now
= pim_time_monotonic_sec();
176 "Interface Address Source Group State Winner Uptime Timer%s",
179 for (ALL_LIST_ELEMENTS_RO(pim_ifchannel_list
, ch_node
, ch
)) {
180 char ch_src_str
[INET_ADDRSTRLEN
];
181 char ch_grp_str
[INET_ADDRSTRLEN
];
182 char winner_str
[INET_ADDRSTRLEN
];
186 pim_ifp
= ch
->interface
->info
;
191 ifaddr
= pim_ifp
->primary_address
;
193 pim_inet4_dump("<ch_src?>", ch
->sg
.src
,
194 ch_src_str
, sizeof(ch_src_str
));
195 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
,
196 ch_grp_str
, sizeof(ch_grp_str
));
197 pim_inet4_dump("<assrt_win?>", ch
->ifassert_winner
,
198 winner_str
, sizeof(winner_str
));
200 pim_time_uptime(uptime
, sizeof(uptime
), now
- ch
->ifassert_creation
);
201 pim_time_timer_to_mmss(timer
, sizeof(timer
),
202 ch
->t_ifassert_timer
);
204 vty_out(vty
, "%-9s %-15s %-15s %-15s %-6s %-15s %-8s %-5s%s",
209 pim_ifchannel_ifassert_name(ch
->ifassert_state
),
214 } /* scan interface channels */
217 static void pim_show_assert_internal(struct vty
*vty
)
219 struct pim_interface
*pim_ifp
;
220 struct listnode
*ch_node
;
221 struct pim_ifchannel
*ch
;
222 struct in_addr ifaddr
;
226 "ECA: Evaluate CouldAssert%s"
227 "ATD: AssertTrackingDesired%s"
228 "eATD: Evaluate AssertTrackingDesired%s%s",
229 VTY_NEWLINE
, VTY_NEWLINE
, VTY_NEWLINE
, VTY_NEWLINE
, VTY_NEWLINE
);
232 "Interface Address Source Group CA eCA ATD eATD%s",
235 for (ALL_LIST_ELEMENTS_RO(pim_ifchannel_list
, ch_node
, ch
)) {
236 pim_ifp
= ch
->interface
->info
;
241 ifaddr
= pim_ifp
->primary_address
;
243 char ch_src_str
[INET_ADDRSTRLEN
];
244 char ch_grp_str
[INET_ADDRSTRLEN
];
246 pim_inet4_dump("<ch_src?>", ch
->sg
.src
,
247 ch_src_str
, sizeof(ch_src_str
));
248 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
,
249 ch_grp_str
, sizeof(ch_grp_str
));
250 vty_out(vty
, "%-9s %-15s %-15s %-15s %-3s %-3s %-3s %-4s%s",
255 PIM_IF_FLAG_TEST_COULD_ASSERT(ch
->flags
) ? "yes" : "no",
256 pim_macro_ch_could_assert_eval(ch
) ? "yes" : "no",
257 PIM_IF_FLAG_TEST_ASSERT_TRACKING_DESIRED(ch
->flags
) ? "yes" : "no",
258 pim_macro_assert_tracking_desired_eval(ch
) ? "yes" : "no",
260 } /* scan interface channels */
263 static void pim_show_assert_metric(struct vty
*vty
)
265 struct pim_interface
*pim_ifp
;
266 struct listnode
*ch_node
;
267 struct pim_ifchannel
*ch
;
268 struct in_addr ifaddr
;
271 "Interface Address Source Group RPT Pref Metric Address %s",
274 for (ALL_LIST_ELEMENTS_RO(pim_ifchannel_list
, ch_node
, ch
)) {
275 pim_ifp
= ch
->interface
->info
;
280 ifaddr
= pim_ifp
->primary_address
;
282 char ch_src_str
[INET_ADDRSTRLEN
];
283 char ch_grp_str
[INET_ADDRSTRLEN
];
284 char addr_str
[INET_ADDRSTRLEN
];
285 struct pim_assert_metric am
;
287 am
= pim_macro_spt_assert_metric(&ch
->upstream
->rpf
, pim_ifp
->primary_address
);
289 pim_inet4_dump("<ch_src?>", ch
->sg
.src
,
290 ch_src_str
, sizeof(ch_src_str
));
291 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
,
292 ch_grp_str
, sizeof(ch_grp_str
));
293 pim_inet4_dump("<addr?>", am
.ip_address
,
294 addr_str
, sizeof(addr_str
));
296 vty_out(vty
, "%-9s %-15s %-15s %-15s %-3s %4u %6u %-15s%s",
301 am
.rpt_bit_flag
? "yes" : "no",
302 am
.metric_preference
,
306 } /* scan interface channels */
309 static void pim_show_assert_winner_metric(struct vty
*vty
)
311 struct pim_interface
*pim_ifp
;
312 struct listnode
*ch_node
;
313 struct pim_ifchannel
*ch
;
314 struct in_addr ifaddr
;
317 "Interface Address Source Group RPT Pref Metric Address %s",
320 for (ALL_LIST_ELEMENTS_RO(pim_ifchannel_list
, ch_node
, ch
)) {
321 pim_ifp
= ch
->interface
->info
;
326 ifaddr
= pim_ifp
->primary_address
;
328 char ch_src_str
[INET_ADDRSTRLEN
];
329 char ch_grp_str
[INET_ADDRSTRLEN
];
330 char addr_str
[INET_ADDRSTRLEN
];
331 struct pim_assert_metric
*am
;
335 am
= &ch
->ifassert_winner_metric
;
337 pim_inet4_dump("<ch_src?>", ch
->sg
.src
,
338 ch_src_str
, sizeof(ch_src_str
));
339 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
,
340 ch_grp_str
, sizeof(ch_grp_str
));
341 pim_inet4_dump("<addr?>", am
->ip_address
,
342 addr_str
, sizeof(addr_str
));
344 if (am
->metric_preference
== PIM_ASSERT_METRIC_PREFERENCE_MAX
)
345 snprintf(pref_str
, sizeof(pref_str
), "INFI");
347 snprintf(pref_str
, sizeof(pref_str
), "%4u", am
->metric_preference
);
349 if (am
->route_metric
== PIM_ASSERT_ROUTE_METRIC_MAX
)
350 snprintf(metr_str
, sizeof(metr_str
), "INFI");
352 snprintf(metr_str
, sizeof(metr_str
), "%6u", am
->route_metric
);
354 vty_out(vty
, "%-9s %-15s %-15s %-15s %-3s %-4s %-6s %-15s%s",
359 am
->rpt_bit_flag
? "yes" : "no",
364 } /* scan interface channels */
367 static void json_object_pim_ifp_add(struct json_object
*json
, struct interface
*ifp
)
369 struct pim_interface
*pim_ifp
;
372 json_object_string_add(json
, "name", ifp
->name
);
373 json_object_string_add(json
, "state", if_is_up(ifp
) ? "up" : "down");
374 json_object_string_add(json
, "address", inet_ntoa(pim_ifp
->primary_address
));
375 json_object_int_add(json
, "index", ifp
->ifindex
);
377 if (if_is_multicast(ifp
))
378 json_object_boolean_true_add(json
, "flagMulticast");
380 if (if_is_broadcast(ifp
))
381 json_object_boolean_true_add(json
, "flagBroadcast");
383 if (ifp
->flags
& IFF_ALLMULTI
)
384 json_object_boolean_true_add(json
, "flagAllMulticast");
386 if (ifp
->flags
& IFF_PROMISC
)
387 json_object_boolean_true_add(json
, "flagPromiscuous");
389 if (PIM_IF_IS_DELETED(ifp
))
390 json_object_boolean_true_add(json
, "flagDeleted");
392 if (pim_if_lan_delay_enabled(ifp
))
393 json_object_boolean_true_add(json
, "lanDelayEnabled");
396 static void pim_show_membership(struct vty
*vty
, u_char uj
)
398 struct pim_interface
*pim_ifp
;
399 struct listnode
*ch_node
;
400 struct pim_ifchannel
*ch
;
402 json_object
*json
= NULL
;
403 json_object
*json_iface
= NULL
;
404 json_object
*json_row
= NULL
;
405 json_object
*json_tmp
= NULL
;
407 json
= json_object_new_object();
409 for (ALL_LIST_ELEMENTS_RO(pim_ifchannel_list
, ch_node
, ch
)) {
411 pim_ifp
= ch
->interface
->info
;
416 char ch_src_str
[INET_ADDRSTRLEN
];
417 char ch_grp_str
[INET_ADDRSTRLEN
];
419 pim_inet4_dump("<ch_src?>", ch
->sg
.src
,
420 ch_src_str
, sizeof(ch_src_str
));
421 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
,
422 ch_grp_str
, sizeof(ch_grp_str
));
424 json_object_object_get_ex(json
, ch
->interface
->name
, &json_iface
);
427 json_iface
= json_object_new_object();
428 json_object_pim_ifp_add(json_iface
, ch
->interface
);
429 json_object_object_add(json
, ch
->interface
->name
, json_iface
);
432 json_row
= json_object_new_object();
433 json_object_string_add(json_row
, "source", ch_src_str
);
434 json_object_string_add(json_row
, "group", ch_grp_str
);
435 json_object_string_add(json_row
, "localMembership",
436 ch
->local_ifmembership
== PIM_IFMEMBERSHIP_NOINFO
? "NOINFO" : "INCLUDE");
437 json_object_object_add(json_iface
, ch_grp_str
, json_row
);
438 } /* scan interface channels */
441 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
444 "Interface Address Source Group Membership%s",
448 * Example of the json data we are traversing
454 * "address":"10.1.20.1",
456 * "flagMulticast":true,
457 * "flagBroadcast":true,
458 * "lanDelayEnabled":true,
461 * "group":"226.10.10.10",
462 * "localMembership":"INCLUDE"
468 /* foreach interface */
469 json_object_object_foreach(json
, key
, val
) {
471 /* Find all of the keys where the val is an object. In the example
472 * above the only one is 226.10.10.10
474 json_object_object_foreach(val
, if_field_key
, if_field_val
) {
475 type
= json_object_get_type(if_field_val
);
477 if (type
== json_type_object
) {
478 vty_out(vty
, "%-9s ", key
);
480 json_object_object_get_ex(val
, "address", &json_tmp
);
481 vty_out(vty
, "%-15s ", json_object_get_string(json_tmp
));
483 json_object_object_get_ex(if_field_val
, "source", &json_tmp
);
484 vty_out(vty
, "%-15s ", json_object_get_string(json_tmp
));
487 vty_out(vty
, "%-15s ", if_field_key
);
489 json_object_object_get_ex(if_field_val
, "localMembership", &json_tmp
);
490 vty_out(vty
, "%-10s%s", json_object_get_string(json_tmp
), VTY_NEWLINE
);
496 json_object_free(json
);
499 static void pim_print_ifp_flags(struct vty
*vty
, struct interface
*ifp
, int mloop
)
501 vty_out(vty
, "Flags%s", VTY_NEWLINE
);
502 vty_out(vty
, "-----%s", VTY_NEWLINE
);
503 vty_out(vty
, "All Multicast : %s%s", (ifp
->flags
& IFF_ALLMULTI
) ? "yes" : "no", VTY_NEWLINE
);
504 vty_out(vty
, "Broadcast : %s%s", if_is_broadcast(ifp
)? "yes" : "no", VTY_NEWLINE
);
505 vty_out(vty
, "Deleted : %s%s", PIM_IF_IS_DELETED(ifp
) ? "yes" : "no", VTY_NEWLINE
);
506 vty_out(vty
, "Interface Index : %d%s", ifp
->ifindex
, VTY_NEWLINE
);
507 vty_out(vty
, "Multicast : %s%s", if_is_multicast(ifp
) ? "yes" : "no", VTY_NEWLINE
);
508 vty_out(vty
, "Multicast Loop : %d%s", mloop
, VTY_NEWLINE
);
509 vty_out(vty
, "Promiscuous : %s%s", (ifp
->flags
& IFF_PROMISC
) ? "yes" : "no", VTY_NEWLINE
);
510 vty_out(vty
, "%s", VTY_NEWLINE
);
511 vty_out(vty
, "%s", VTY_NEWLINE
);
514 static void igmp_show_interfaces(struct vty
*vty
, u_char uj
)
516 struct listnode
*node
;
517 struct interface
*ifp
;
519 json_object
*json
= NULL
;
520 json_object
*json_row
= NULL
;
522 now
= pim_time_monotonic_sec();
525 json
= json_object_new_object();
528 "Interface State Address V Querier Query Timer Uptime%s",
531 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), node
, ifp
)) {
532 struct pim_interface
*pim_ifp
;
533 struct listnode
*sock_node
;
534 struct igmp_sock
*igmp
;
541 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
543 char query_hhmmss
[10];
545 pim_time_uptime(uptime
, sizeof(uptime
), now
- igmp
->sock_creation
);
546 pim_time_timer_to_hhmmss(query_hhmmss
, sizeof(query_hhmmss
), igmp
->t_igmp_query_timer
);
549 json_row
= json_object_new_object();
550 json_object_pim_ifp_add(json_row
, ifp
);
551 json_object_string_add(json_row
, "upTime", uptime
);
552 json_object_int_add(json_row
, "version", pim_ifp
->igmp_version
);
554 if (igmp
->t_igmp_query_timer
) {
555 json_object_boolean_true_add(json_row
, "querier");
556 json_object_string_add(json_row
, "queryTimer", query_hhmmss
);
559 json_object_object_add(json
, ifp
->name
, json_row
);
562 vty_out(vty
, "%-9s %5s %15s %d %7s %11s %8s%s",
564 if_is_up(ifp
) ? "up" : "down",
565 inet_ntoa(igmp
->ifaddr
),
566 pim_ifp
->igmp_version
,
567 igmp
->t_igmp_query_timer
? "local" : "other",
576 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
577 json_object_free(json
);
581 static void igmp_show_interfaces_single(struct vty
*vty
, const char *ifname
, u_char uj
)
583 struct igmp_sock
*igmp
;
584 struct interface
*ifp
;
585 struct listnode
*node
;
586 struct listnode
*sock_node
;
587 struct pim_interface
*pim_ifp
;
589 char query_hhmmss
[10];
590 char other_hhmmss
[10];
591 int found_ifname
= 0;
594 long gmi_msec
; /* Group Membership Interval */
597 long oqpi_msec
; /* Other Querier Present Interval */
601 json_object
*json
= NULL
;
602 json_object
*json_row
= NULL
;
605 json
= json_object_new_object();
607 now
= pim_time_monotonic_sec();
609 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), node
, ifp
)) {
615 if (strcmp(ifname
, "detail") && strcmp(ifname
, ifp
->name
))
618 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
620 pim_time_uptime(uptime
, sizeof(uptime
), now
- igmp
->sock_creation
);
621 pim_time_timer_to_hhmmss(query_hhmmss
, sizeof(query_hhmmss
), igmp
->t_igmp_query_timer
);
622 pim_time_timer_to_hhmmss(other_hhmmss
, sizeof(other_hhmmss
), igmp
->t_other_querier_timer
);
624 gmi_msec
= PIM_IGMP_GMI_MSEC(igmp
->querier_robustness_variable
,
625 igmp
->querier_query_interval
,
626 pim_ifp
->igmp_query_max_response_time_dsec
);
628 sqi
= PIM_IGMP_SQI(pim_ifp
->igmp_default_query_interval
);
630 oqpi_msec
= PIM_IGMP_OQPI_MSEC(igmp
->querier_robustness_variable
,
631 igmp
->querier_query_interval
,
632 pim_ifp
->igmp_query_max_response_time_dsec
);
634 lmqt_msec
= PIM_IGMP_LMQT_MSEC(pim_ifp
->igmp_query_max_response_time_dsec
,
635 igmp
->querier_robustness_variable
);
637 ohpi_msec
= PIM_IGMP_OHPI_DSEC(igmp
->querier_robustness_variable
,
638 igmp
->querier_query_interval
,
639 pim_ifp
->igmp_query_max_response_time_dsec
) * 100;
641 qri_msec
= pim_ifp
->igmp_query_max_response_time_dsec
* 100;
642 mloop
= pim_socket_mcastloop_get(pim_ifp
->pim_sock_fd
);
645 json_row
= json_object_new_object();
646 json_object_pim_ifp_add(json_row
, ifp
);
647 json_object_string_add(json_row
, "upTime", uptime
);
648 json_object_string_add(json_row
, "querier", igmp
->t_igmp_query_timer
? "local" : "other");
649 json_object_int_add(json_row
, "queryStartCount", igmp
->startup_query_count
);
650 json_object_string_add(json_row
, "queryQueryTimer", query_hhmmss
);
651 json_object_string_add(json_row
, "queryOtherTimer", other_hhmmss
);
652 json_object_int_add(json_row
, "version", pim_ifp
->igmp_version
);
653 json_object_int_add(json_row
, "timerGroupMembershipIntervalMsec", gmi_msec
);
654 json_object_int_add(json_row
, "timerLastMemberQueryMsec", lmqt_msec
);
655 json_object_int_add(json_row
, "timerOlderHostPresentIntervalMsec", ohpi_msec
);
656 json_object_int_add(json_row
, "timerOtherQuerierPresentIntervalMsec", oqpi_msec
);
657 json_object_int_add(json_row
, "timerQueryInterval", igmp
->querier_query_interval
);
658 json_object_int_add(json_row
, "timerQueryResponseIntervalMsec", qri_msec
);
659 json_object_int_add(json_row
, "timerRobustnessVariable", igmp
->querier_robustness_variable
);
660 json_object_int_add(json_row
, "timerStartupQueryInterval", sqi
);
662 json_object_object_add(json
, ifp
->name
, json_row
);
665 vty_out(vty
, "Interface : %s%s", ifp
->name
, VTY_NEWLINE
);
666 vty_out(vty
, "State : %s%s", if_is_up(ifp
) ? "up" : "down", VTY_NEWLINE
);
667 vty_out(vty
, "Address : %s%s", inet_ntoa(pim_ifp
->primary_address
), VTY_NEWLINE
);
668 vty_out(vty
, "Uptime : %s%s", uptime
, VTY_NEWLINE
);
669 vty_out(vty
, "Version : %d%s", pim_ifp
->igmp_version
, VTY_NEWLINE
);
670 vty_out(vty
, "%s", VTY_NEWLINE
);
671 vty_out(vty
, "%s", VTY_NEWLINE
);
673 vty_out(vty
, "Querier%s", VTY_NEWLINE
);
674 vty_out(vty
, "-------%s", VTY_NEWLINE
);
675 vty_out(vty
, "Querier : %s%s", igmp
->t_igmp_query_timer
? "local" : "other", VTY_NEWLINE
);
676 vty_out(vty
, "Start Count : %d%s", igmp
->startup_query_count
, VTY_NEWLINE
);
677 vty_out(vty
, "Query Timer : %s%s", query_hhmmss
, VTY_NEWLINE
);
678 vty_out(vty
, "Other Timer : %s%s", other_hhmmss
, VTY_NEWLINE
);
679 vty_out(vty
, "%s", VTY_NEWLINE
);
680 vty_out(vty
, "%s", VTY_NEWLINE
);
682 vty_out(vty
, "Timers%s", VTY_NEWLINE
);
683 vty_out(vty
, "------%s", VTY_NEWLINE
);
684 vty_out(vty
, "Group Membership Interval : %lis%s", gmi_msec
/1000, VTY_NEWLINE
);
685 vty_out(vty
, "Last Member Query Time : %lis%s", lmqt_msec
/1000, VTY_NEWLINE
);
686 vty_out(vty
, "Older Host Present Interval : %lis%s", ohpi_msec
/1000, VTY_NEWLINE
);
687 vty_out(vty
, "Other Querier Present Interval : %lis%s", oqpi_msec
/1000, VTY_NEWLINE
);
688 vty_out(vty
, "Query Interval : %ds%s", igmp
->querier_query_interval
, VTY_NEWLINE
);
689 vty_out(vty
, "Query Response Interval : %lis%s", qri_msec
/1000, VTY_NEWLINE
);
690 vty_out(vty
, "Robustness Variable : %d%s", igmp
->querier_robustness_variable
, VTY_NEWLINE
);
691 vty_out(vty
, "Startup Query Interval : %ds%s", sqi
, VTY_NEWLINE
);
692 vty_out(vty
, "%s", VTY_NEWLINE
);
693 vty_out(vty
, "%s", VTY_NEWLINE
);
695 pim_print_ifp_flags(vty
, ifp
, mloop
);
701 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
702 json_object_free(json
);
705 vty_out (vty
, "%% No such interface%s", VTY_NEWLINE
);
709 static void igmp_show_interface_join(struct vty
*vty
)
711 struct listnode
*node
;
712 struct interface
*ifp
;
715 now
= pim_time_monotonic_sec();
718 "Interface Address Source Group Socket Uptime %s",
721 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), node
, ifp
)) {
722 struct pim_interface
*pim_ifp
;
723 struct listnode
*join_node
;
724 struct igmp_join
*ij
;
725 struct in_addr pri_addr
;
726 char pri_addr_str
[INET_ADDRSTRLEN
];
733 if (!pim_ifp
->igmp_join_list
)
736 pri_addr
= pim_find_primary_addr(ifp
);
737 pim_inet4_dump("<pri?>", pri_addr
, pri_addr_str
, sizeof(pri_addr_str
));
739 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_join_list
, join_node
, ij
)) {
740 char group_str
[INET_ADDRSTRLEN
];
741 char source_str
[INET_ADDRSTRLEN
];
744 pim_time_uptime(uptime
, sizeof(uptime
), now
- ij
->sock_creation
);
745 pim_inet4_dump("<grp?>", ij
->group_addr
, group_str
, sizeof(group_str
));
746 pim_inet4_dump("<src?>", ij
->source_addr
, source_str
, sizeof(source_str
));
748 vty_out(vty
, "%-9s %-15s %-15s %-15s %6d %8s%s",
756 } /* for (pim_ifp->igmp_join_list) */
762 static void pim_show_interfaces_single(struct vty
*vty
, const char *ifname
, u_char uj
)
764 struct in_addr ifaddr
;
765 struct interface
*ifp
;
766 struct listnode
*neighnode
;
767 struct listnode
*node
;
768 struct listnode
*upnode
;
769 struct pim_interface
*pim_ifp
;
770 struct pim_neighbor
*neigh
;
771 struct pim_upstream
*up
;
773 char dr_str
[INET_ADDRSTRLEN
];
776 char grp_str
[INET_ADDRSTRLEN
];
777 char hello_period
[10];
778 char hello_timer
[10];
779 char neigh_src_str
[INET_ADDRSTRLEN
];
780 char src_str
[INET_ADDRSTRLEN
];
781 char stat_uptime
[10];
784 int found_ifname
= 0;
786 json_object
*json
= NULL
;
787 json_object
*json_row
= NULL
;
788 json_object
*json_pim_neighbor
= NULL
;
789 json_object
*json_pim_neighbors
= NULL
;
790 json_object
*json_group
= NULL
;
791 json_object
*json_group_source
= NULL
;
792 json_object
*json_fhr_sources
= NULL
;
793 struct pim_secondary_addr
*sec_addr
;
794 struct listnode
*sec_node
;
796 now
= pim_time_monotonic_sec();
799 json
= json_object_new_object();
801 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), node
, ifp
)) {
807 if (pim_ifp
->pim_sock_fd
< 0)
810 if (strcmp(ifname
, "detail") && strcmp(ifname
, ifp
->name
))
814 ifaddr
= pim_ifp
->primary_address
;
815 pim_inet4_dump("<dr?>", pim_ifp
->pim_dr_addr
, dr_str
, sizeof(dr_str
));
816 pim_time_uptime_begin(dr_uptime
, sizeof(dr_uptime
), now
, pim_ifp
->pim_dr_election_last
);
817 pim_time_timer_to_hhmmss(hello_timer
, sizeof(hello_timer
), pim_ifp
->t_pim_hello_timer
);
818 pim_time_mmss(hello_period
, sizeof(hello_period
), pim_ifp
->pim_hello_period
);
819 pim_time_uptime(stat_uptime
, sizeof(stat_uptime
), now
- pim_ifp
->pim_ifstat_start
);
820 mloop
= pim_socket_mcastloop_get(pim_ifp
->pim_sock_fd
);
823 char pbuf
[PREFIX2STR_BUFFER
];
824 json_row
= json_object_new_object();
825 json_object_pim_ifp_add(json_row
, ifp
);
827 if (pim_ifp
->update_source
.s_addr
!= INADDR_ANY
) {
828 json_object_string_add(json_row
, "useSource", inet_ntoa(pim_ifp
->update_source
));
830 if (pim_ifp
->sec_addr_list
) {
831 json_object
*sec_list
= NULL
;
833 sec_list
= json_object_new_array();
834 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->sec_addr_list
, sec_node
, sec_addr
)) {
835 json_object_array_add(sec_list
,
836 json_object_new_string(prefix2str(&sec_addr
->addr
,
840 json_object_object_add(json_row
, "secondaryAddressList", sec_list
);
844 if (pim_ifp
->pim_neighbor_list
->count
) {
845 json_pim_neighbors
= json_object_new_object();
847 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
, neigh
)) {
848 json_pim_neighbor
= json_object_new_object();
849 pim_inet4_dump("<src?>", neigh
->source_addr
, neigh_src_str
, sizeof(neigh_src_str
));
850 pim_time_uptime(uptime
, sizeof(uptime
), now
- neigh
->creation
);
851 pim_time_timer_to_hhmmss(expire
, sizeof(expire
), neigh
->t_expire_timer
);
853 json_object_string_add(json_pim_neighbor
, "address", neigh_src_str
);
854 json_object_string_add(json_pim_neighbor
, "upTime", uptime
);
855 json_object_string_add(json_pim_neighbor
, "holdtime", expire
);
857 json_object_object_add(json_pim_neighbors
, neigh_src_str
, json_pim_neighbor
);
860 json_object_object_add(json_row
, "neighbors", json_pim_neighbors
);
863 json_object_string_add(json_row
, "drAddress", dr_str
);
864 json_object_int_add(json_row
, "drPriority", pim_ifp
->pim_dr_priority
);
865 json_object_string_add(json_row
, "drUptime", dr_uptime
);
866 json_object_int_add(json_row
, "drElections", pim_ifp
->pim_dr_election_count
);
867 json_object_int_add(json_row
, "drChanges", pim_ifp
->pim_dr_election_changes
);
870 for (ALL_LIST_ELEMENTS_RO(pim_upstream_list
, upnode
, up
)) {
871 if (ifp
== up
->rpf
.source_nexthop
.interface
) {
872 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
) {
873 if (!json_fhr_sources
) {
874 json_fhr_sources
= json_object_new_object();
877 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
878 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
879 pim_time_uptime(uptime
, sizeof(uptime
), now
- up
->state_transition
);
881 /* Does this group live in json_fhr_sources? If not create it. */
882 json_object_object_get_ex(json_fhr_sources
, grp_str
, &json_group
);
885 json_group
= json_object_new_object();
886 json_object_object_add(json_fhr_sources
, grp_str
, json_group
);
889 json_group_source
= json_object_new_object();
890 json_object_string_add(json_group_source
, "source", src_str
);
891 json_object_string_add(json_group_source
, "group", grp_str
);
892 json_object_string_add(json_group_source
, "upTime", uptime
);
893 json_object_object_add(json_group
, src_str
, json_group_source
);
898 if (json_fhr_sources
) {
899 json_object_object_add(json_row
, "firstHopRouter", json_fhr_sources
);
902 json_object_int_add(json_row
, "helloPeriod", pim_ifp
->pim_hello_period
);
903 json_object_string_add(json_row
, "helloTimer", hello_timer
);
904 json_object_string_add(json_row
, "helloStatStart", stat_uptime
);
905 json_object_int_add(json_row
, "helloReceived", pim_ifp
->pim_ifstat_hello_recv
);
906 json_object_int_add(json_row
, "helloReceivedFailed", pim_ifp
->pim_ifstat_hello_recvfail
);
907 json_object_int_add(json_row
, "helloSend", pim_ifp
->pim_ifstat_hello_sent
);
908 json_object_int_add(json_row
, "hellosendFailed", pim_ifp
->pim_ifstat_hello_sendfail
);
909 json_object_int_add(json_row
, "helloGenerationId", pim_ifp
->pim_generation_id
);
910 json_object_int_add(json_row
, "flagMulticastLoop", mloop
);
912 json_object_int_add(json_row
, "effectivePropagationDelay", pim_if_effective_propagation_delay_msec(ifp
));
913 json_object_int_add(json_row
, "effectiveOverrideInterval", pim_if_effective_override_interval_msec(ifp
));
914 json_object_int_add(json_row
, "joinPruneOverrideInterval", pim_if_jp_override_interval_msec(ifp
));
916 json_object_int_add(json_row
, "propagationDelay", pim_ifp
->pim_propagation_delay_msec
);
917 json_object_int_add(json_row
, "propagationDelayHighest", pim_ifp
->pim_neighbors_highest_propagation_delay_msec
);
918 json_object_int_add(json_row
, "overrideInterval", pim_ifp
->pim_override_interval_msec
);
919 json_object_int_add(json_row
, "overrideIntervalHighest", pim_ifp
->pim_neighbors_highest_override_interval_msec
);
920 json_object_object_add(json
, ifp
->name
, json_row
);
923 vty_out(vty
, "Interface : %s%s", ifp
->name
, VTY_NEWLINE
);
924 vty_out(vty
, "State : %s%s", if_is_up(ifp
) ? "up" : "down", VTY_NEWLINE
);
925 if (pim_ifp
->update_source
.s_addr
!= INADDR_ANY
) {
926 vty_out(vty
, "Use Source : %s%s", inet_ntoa(pim_ifp
->update_source
), VTY_NEWLINE
);
928 if (pim_ifp
->sec_addr_list
) {
929 char pbuf
[PREFIX2STR_BUFFER
];
930 vty_out(vty
, "Address : %s (primary)%s",
931 inet_ntoa(ifaddr
), VTY_NEWLINE
);
932 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->sec_addr_list
, sec_node
, sec_addr
)) {
933 vty_out(vty
, " %s%s",
934 prefix2str(&sec_addr
->addr
,
936 sizeof(pbuf
)), VTY_NEWLINE
);
939 vty_out(vty
, "Address : %s%s", inet_ntoa(ifaddr
), VTY_NEWLINE
);
941 vty_out(vty
, "%s", VTY_NEWLINE
);
946 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
, neigh
)) {
949 vty_out(vty
, "PIM Neighbors%s", VTY_NEWLINE
);
950 vty_out(vty
, "-------------%s", VTY_NEWLINE
);
954 pim_inet4_dump("<src?>", neigh
->source_addr
, neigh_src_str
, sizeof(neigh_src_str
));
955 pim_time_uptime(uptime
, sizeof(uptime
), now
- neigh
->creation
);
956 pim_time_timer_to_hhmmss(expire
, sizeof(expire
), neigh
->t_expire_timer
);
957 vty_out(vty
, "%-15s : up for %s, holdtime expires in %s%s", neigh_src_str
, uptime
, expire
, VTY_NEWLINE
);
961 vty_out(vty
, "%s", VTY_NEWLINE
);
962 vty_out(vty
, "%s", VTY_NEWLINE
);
965 vty_out(vty
, "Designated Router%s", VTY_NEWLINE
);
966 vty_out(vty
, "-----------------%s", VTY_NEWLINE
);
967 vty_out(vty
, "Address : %s%s", dr_str
, VTY_NEWLINE
);
968 vty_out(vty
, "Priority : %d%s", pim_ifp
->pim_dr_priority
, VTY_NEWLINE
);
969 vty_out(vty
, "Uptime : %s%s", dr_uptime
, VTY_NEWLINE
);
970 vty_out(vty
, "Elections : %d%s", pim_ifp
->pim_dr_election_count
, VTY_NEWLINE
);
971 vty_out(vty
, "Changes : %d%s", pim_ifp
->pim_dr_election_changes
, VTY_NEWLINE
);
972 vty_out(vty
, "%s", VTY_NEWLINE
);
973 vty_out(vty
, "%s", VTY_NEWLINE
);
977 for (ALL_LIST_ELEMENTS_RO(pim_upstream_list
, upnode
, up
)) {
978 if (strcmp(ifp
->name
, up
->rpf
.source_nexthop
.interface
->name
) == 0) {
979 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
) {
982 vty_out(vty
, "FHR - First Hop Router%s", VTY_NEWLINE
);
983 vty_out(vty
, "----------------------%s", VTY_NEWLINE
);
987 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
988 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
989 pim_time_uptime(uptime
, sizeof(uptime
), now
- up
->state_transition
);
990 vty_out(vty
, "%s : %s is a source, uptime is %s%s", grp_str
, src_str
, uptime
, VTY_NEWLINE
);
996 vty_out(vty
, "%s", VTY_NEWLINE
);
997 vty_out(vty
, "%s", VTY_NEWLINE
);
1000 vty_out(vty
, "Hellos%s", VTY_NEWLINE
);
1001 vty_out(vty
, "------%s", VTY_NEWLINE
);
1002 vty_out(vty
, "Period : %d%s", pim_ifp
->pim_hello_period
, VTY_NEWLINE
);
1003 vty_out(vty
, "Timer : %s%s", hello_timer
, VTY_NEWLINE
);
1004 vty_out(vty
, "StatStart : %s%s", stat_uptime
, VTY_NEWLINE
);
1005 vty_out(vty
, "Receive : %d%s", pim_ifp
->pim_ifstat_hello_recv
, VTY_NEWLINE
);
1006 vty_out(vty
, "Receive Failed : %d%s", pim_ifp
->pim_ifstat_hello_recvfail
, VTY_NEWLINE
);
1007 vty_out(vty
, "Send : %d%s", pim_ifp
->pim_ifstat_hello_sent
, VTY_NEWLINE
);
1008 vty_out(vty
, "Send Failed : %d%s", pim_ifp
->pim_ifstat_hello_sendfail
, VTY_NEWLINE
);
1009 vty_out(vty
, "Generation ID : %08x%s", pim_ifp
->pim_generation_id
, VTY_NEWLINE
);
1010 vty_out(vty
, "%s", VTY_NEWLINE
);
1011 vty_out(vty
, "%s", VTY_NEWLINE
);
1013 pim_print_ifp_flags(vty
, ifp
, mloop
);
1015 vty_out(vty
, "Join Prune Interval%s", VTY_NEWLINE
);
1016 vty_out(vty
, "-------------------%s", VTY_NEWLINE
);
1017 vty_out(vty
, "LAN Delay : %s%s", pim_if_lan_delay_enabled(ifp
) ? "yes" : "no", VTY_NEWLINE
);
1018 vty_out(vty
, "Effective Propagation Delay : %d msec%s", pim_if_effective_propagation_delay_msec(ifp
), VTY_NEWLINE
);
1019 vty_out(vty
, "Effective Override Interval : %d msec%s", pim_if_effective_override_interval_msec(ifp
), VTY_NEWLINE
);
1020 vty_out(vty
, "Join Prune Override Interval : %d msec%s", pim_if_jp_override_interval_msec(ifp
), VTY_NEWLINE
);
1021 vty_out(vty
, "%s", VTY_NEWLINE
);
1022 vty_out(vty
, "%s", VTY_NEWLINE
);
1024 vty_out(vty
, "LAN Prune Delay%s", VTY_NEWLINE
);
1025 vty_out(vty
, "---------------%s", VTY_NEWLINE
);
1026 vty_out(vty
, "Propagation Delay : %d msec%s", pim_ifp
->pim_propagation_delay_msec
, VTY_NEWLINE
);
1027 vty_out(vty
, "Propagation Delay (Highest) : %d msec%s", pim_ifp
->pim_neighbors_highest_propagation_delay_msec
, VTY_NEWLINE
);
1028 vty_out(vty
, "Override Interval : %d msec%s", pim_ifp
->pim_override_interval_msec
, VTY_NEWLINE
);
1029 vty_out(vty
, "Override Interval (Highest) : %d msec%s", pim_ifp
->pim_neighbors_highest_override_interval_msec
, VTY_NEWLINE
);
1030 vty_out(vty
, "%s", VTY_NEWLINE
);
1031 vty_out(vty
, "%s", VTY_NEWLINE
);
1036 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
1037 json_object_free(json
);
1040 vty_out (vty
, "%% No such interface%s", VTY_NEWLINE
);
1044 static void pim_show_interfaces(struct vty
*vty
, u_char uj
)
1046 struct interface
*ifp
;
1047 struct listnode
*node
;
1048 struct listnode
*upnode
;
1049 struct pim_interface
*pim_ifp
;
1050 struct pim_upstream
*up
;
1053 int pim_ifchannels
= 0;
1054 json_object
*json
= NULL
;
1055 json_object
*json_row
= NULL
;
1056 json_object
*json_tmp
;
1058 json
= json_object_new_object();
1060 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), node
, ifp
)) {
1061 pim_ifp
= ifp
->info
;
1066 if (pim_ifp
->pim_sock_fd
< 0)
1069 pim_nbrs
= pim_ifp
->pim_neighbor_list
->count
;
1070 pim_ifchannels
= pim_ifp
->pim_ifchannel_list
->count
;
1073 for (ALL_LIST_ELEMENTS_RO(pim_upstream_list
, upnode
, up
))
1074 if (ifp
== up
->rpf
.source_nexthop
.interface
)
1075 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
)
1078 json_row
= json_object_new_object();
1079 json_object_pim_ifp_add(json_row
, ifp
);
1080 json_object_int_add(json_row
, "pimNeighbors", pim_nbrs
);
1081 json_object_int_add(json_row
, "pimIfChannels", pim_ifchannels
);
1082 json_object_int_add(json_row
, "firstHopRouter", fhr
);
1083 json_object_string_add(json_row
, "pimDesignatedRouter", inet_ntoa(pim_ifp
->pim_dr_addr
));
1085 if (pim_ifp
->pim_dr_addr
.s_addr
== pim_ifp
->primary_address
.s_addr
)
1086 json_object_boolean_true_add(json_row
, "pimDesignatedRouterLocal");
1088 json_object_object_add(json
, ifp
->name
, json_row
);
1092 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
1094 vty_out(vty
, "Interface State Address PIM Nbrs PIM DR FHR IfChannels%s", VTY_NEWLINE
);
1096 json_object_object_foreach(json
, key
, val
) {
1097 vty_out(vty
, "%-9s ", key
);
1099 json_object_object_get_ex(val
, "state", &json_tmp
);
1100 vty_out(vty
, "%5s ", json_object_get_string(json_tmp
));
1102 json_object_object_get_ex(val
, "address", &json_tmp
);
1103 vty_out(vty
, "%15s ", json_object_get_string(json_tmp
));
1105 json_object_object_get_ex(val
, "pimNeighbors", &json_tmp
);
1106 vty_out(vty
, "%8d ", json_object_get_int(json_tmp
));
1108 if (json_object_object_get_ex(val
, "pimDesignatedRouterLocal", &json_tmp
)) {
1109 vty_out(vty
, "%15s ", "local");
1111 json_object_object_get_ex(val
, "pimDesignatedRouter", &json_tmp
);
1112 vty_out(vty
, "%15s ", json_object_get_string(json_tmp
));
1115 json_object_object_get_ex(val
, "firstHopRouter", &json_tmp
);
1116 vty_out(vty
, "%3d ", json_object_get_int(json_tmp
));
1118 json_object_object_get_ex(val
, "pimIfChannels", &json_tmp
);
1119 vty_out(vty
, "%9d%s", json_object_get_int(json_tmp
), VTY_NEWLINE
);
1123 json_object_free(json
);
1126 static void pim_show_interface_traffic (struct vty
*vty
, u_char uj
)
1128 struct interface
*ifp
= NULL
;
1129 struct pim_interface
*pim_ifp
= NULL
;
1130 struct listnode
*node
= NULL
;
1131 json_object
*json
= NULL
;
1132 json_object
*json_row
= NULL
;
1135 json
= json_object_new_object ();
1138 vty_out (vty
, "%s", VTY_NEWLINE
);
1139 vty_out (vty
, "%-12s%-17s%-17s%-17s%-17s%-17s%-17s%s", "Interface",
1140 " HELLO", " JOIN", " PRUNE", " REGISTER",
1141 " REGISTER-STOP", " ASSERT", VTY_NEWLINE
);
1143 "%-10s%-18s%-17s%-17s%-17s%-17s%-17s%s",
1144 "", " Rx/Tx", " Rx/Tx", " Rx/Tx", " Rx/Tx",
1145 " Rx/Tx", " Rx/Tx", VTY_NEWLINE
);
1147 "---------------------------------------------------------------------------------------------------------------%s",
1151 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), node
, ifp
))
1153 pim_ifp
= ifp
->info
;
1158 if (pim_ifp
->pim_sock_fd
< 0)
1162 json_row
= json_object_new_object ();
1163 json_object_pim_ifp_add (json_row
, ifp
);
1164 json_object_int_add (json_row
, "helloRx", pim_ifp
->pim_ifstat_hello_recv
);
1165 json_object_int_add (json_row
, "helloTx", pim_ifp
->pim_ifstat_hello_sent
);
1166 json_object_int_add (json_row
, "joinRx", pim_ifp
->pim_ifstat_join_recv
);
1167 json_object_int_add (json_row
, "joinTx", pim_ifp
->pim_ifstat_join_send
);
1168 json_object_int_add (json_row
, "registerRx", pim_ifp
->pim_ifstat_reg_recv
);
1169 json_object_int_add (json_row
, "registerTx", pim_ifp
->pim_ifstat_reg_recv
);
1170 json_object_int_add (json_row
, "registerStopRx", pim_ifp
->pim_ifstat_reg_stop_recv
);
1171 json_object_int_add (json_row
, "registerStopTx", pim_ifp
->pim_ifstat_reg_stop_send
);
1172 json_object_int_add (json_row
, "assertRx", pim_ifp
->pim_ifstat_assert_recv
);
1173 json_object_int_add (json_row
, "assertTx", pim_ifp
->pim_ifstat_assert_send
);
1175 json_object_object_add (json
, ifp
->name
, json_row
);
1180 "%-10s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %s",
1181 ifp
->name
, pim_ifp
->pim_ifstat_hello_recv
,
1182 pim_ifp
->pim_ifstat_hello_sent
, pim_ifp
->pim_ifstat_join_recv
,
1183 pim_ifp
->pim_ifstat_join_send
, pim_ifp
->pim_ifstat_prune_recv
,
1184 pim_ifp
->pim_ifstat_prune_send
, pim_ifp
->pim_ifstat_reg_recv
,
1185 pim_ifp
->pim_ifstat_reg_send
,
1186 pim_ifp
->pim_ifstat_reg_stop_recv
,
1187 pim_ifp
->pim_ifstat_reg_stop_send
,
1188 pim_ifp
->pim_ifstat_assert_recv
,
1189 pim_ifp
->pim_ifstat_assert_send
, VTY_NEWLINE
);
1194 vty_out (vty
, "%s%s", json_object_to_json_string_ext (json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
1195 json_object_free (json
);
1199 static void pim_show_interface_traffic_single (struct vty
*vty
, const char *ifname
, u_char uj
)
1201 struct interface
*ifp
= NULL
;
1202 struct pim_interface
*pim_ifp
= NULL
;
1203 struct listnode
*node
= NULL
;
1204 json_object
*json
= NULL
;
1205 json_object
*json_row
= NULL
;
1206 uint8_t found_ifname
= 0;
1209 json
= json_object_new_object ();
1212 vty_out (vty
, "%s", VTY_NEWLINE
);
1213 vty_out (vty
, "%-12s%-17s%-17s%-17s%-17s%-17s%-17s%s", "Interface",
1214 " HELLO", " JOIN", " PRUNE", " REGISTER",
1215 " REGISTER-STOP", " ASSERT", VTY_NEWLINE
);
1217 "%-10s%-18s%-17s%-17s%-17s%-17s%-17s%s",
1218 "", " Rx/Tx", " Rx/Tx", " Rx/Tx", " Rx/Tx",
1219 " Rx/Tx", " Rx/Tx", VTY_NEWLINE
);
1221 "---------------------------------------------------------------------------------------------------------------%s",
1225 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), node
, ifp
))
1227 if (strcmp (ifname
, ifp
->name
))
1230 pim_ifp
= ifp
->info
;
1235 if (pim_ifp
->pim_sock_fd
< 0)
1241 json_row
= json_object_new_object ();
1242 json_object_pim_ifp_add (json_row
, ifp
);
1243 json_object_int_add (json_row
, "helloRx", pim_ifp
->pim_ifstat_hello_recv
);
1244 json_object_int_add (json_row
, "helloTx", pim_ifp
->pim_ifstat_hello_sent
);
1245 json_object_int_add (json_row
, "joinRx", pim_ifp
->pim_ifstat_join_recv
);
1246 json_object_int_add (json_row
, "joinTx", pim_ifp
->pim_ifstat_join_send
);
1247 json_object_int_add (json_row
, "registerRx", pim_ifp
->pim_ifstat_reg_recv
);
1248 json_object_int_add (json_row
, "registerTx", pim_ifp
->pim_ifstat_reg_recv
);
1249 json_object_int_add (json_row
, "registerStopRx", pim_ifp
->pim_ifstat_reg_stop_recv
);
1250 json_object_int_add (json_row
, "registerStopTx", pim_ifp
->pim_ifstat_reg_stop_send
);
1251 json_object_int_add (json_row
, "assertRx", pim_ifp
->pim_ifstat_assert_recv
);
1252 json_object_int_add (json_row
, "assertTx", pim_ifp
->pim_ifstat_assert_send
);
1254 json_object_object_add (json
, ifp
->name
, json_row
);
1259 "%-10s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %s",
1260 ifp
->name
, pim_ifp
->pim_ifstat_hello_recv
,
1261 pim_ifp
->pim_ifstat_hello_sent
, pim_ifp
->pim_ifstat_join_recv
,
1262 pim_ifp
->pim_ifstat_join_send
, pim_ifp
->pim_ifstat_prune_recv
,
1263 pim_ifp
->pim_ifstat_prune_send
, pim_ifp
->pim_ifstat_reg_recv
,
1264 pim_ifp
->pim_ifstat_reg_send
,
1265 pim_ifp
->pim_ifstat_reg_stop_recv
,
1266 pim_ifp
->pim_ifstat_reg_stop_send
,
1267 pim_ifp
->pim_ifstat_assert_recv
,
1268 pim_ifp
->pim_ifstat_assert_send
, VTY_NEWLINE
);
1273 vty_out (vty
, "%s%s", json_object_to_json_string_ext (json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
1274 json_object_free (json
);
1279 vty_out (vty
, "%% No such interface%s", VTY_NEWLINE
);
1283 static void pim_show_join(struct vty
*vty
, u_char uj
)
1285 struct pim_interface
*pim_ifp
;
1286 struct in_addr ifaddr
;
1287 struct listnode
*ch_node
;
1288 struct pim_ifchannel
*ch
;
1290 json_object
*json
= NULL
;
1291 json_object
*json_iface
= NULL
;
1292 json_object
*json_row
= NULL
;
1293 json_object
*json_grp
= NULL
;
1295 now
= pim_time_monotonic_sec();
1298 json
= json_object_new_object();
1301 "Interface Address Source Group State Uptime Expire Prune%s",
1304 for (ALL_LIST_ELEMENTS_RO(pim_ifchannel_list
, ch_node
, ch
)) {
1306 pim_ifp
= ch
->interface
->info
;
1311 ifaddr
= pim_ifp
->primary_address
;
1313 char ch_src_str
[INET_ADDRSTRLEN
];
1314 char ch_grp_str
[INET_ADDRSTRLEN
];
1319 pim_inet4_dump("<ch_src?>", ch
->sg
.src
,
1320 ch_src_str
, sizeof(ch_src_str
));
1321 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
,
1322 ch_grp_str
, sizeof(ch_grp_str
));
1324 pim_time_uptime_begin(uptime
, sizeof(uptime
), now
, ch
->ifjoin_creation
);
1325 pim_time_timer_to_mmss(expire
, sizeof(expire
),
1326 ch
->t_ifjoin_expiry_timer
);
1327 pim_time_timer_to_mmss(prune
, sizeof(prune
),
1328 ch
->t_ifjoin_prune_pending_timer
);
1331 json_object_object_get_ex(json
, ch
->interface
->name
, &json_iface
);
1334 json_iface
= json_object_new_object();
1335 json_object_pim_ifp_add(json_iface
, ch
->interface
);
1336 json_object_object_add(json
, ch
->interface
->name
, json_iface
);
1339 json_row
= json_object_new_object();
1340 json_object_string_add(json_row
, "source", ch_src_str
);
1341 json_object_string_add(json_row
, "group", ch_grp_str
);
1342 json_object_string_add(json_row
, "upTime", uptime
);
1343 json_object_string_add(json_row
, "expire", expire
);
1344 json_object_string_add(json_row
, "prune", prune
);
1345 json_object_string_add(json_row
, "channelJoinName",
1346 pim_ifchannel_ifjoin_name(ch
->ifjoin_state
, ch
->flags
));
1347 if (PIM_IF_FLAG_TEST_S_G_RPT(ch
->flags
))
1348 json_object_int_add(json_row
, "SGRpt", 1);
1350 json_object_object_get_ex(json_iface
, ch_grp_str
, &json_grp
);
1353 json_grp
= json_object_new_object();
1354 json_object_object_add(json_grp
, ch_src_str
, json_row
);
1355 json_object_object_add(json_iface
, ch_grp_str
, json_grp
);
1358 json_object_object_add(json_grp
, ch_src_str
, json_row
);
1360 vty_out(vty
, "%-9s %-15s %-15s %-15s %-6s %8s %-6s %5s%s",
1361 ch
->interface
->name
,
1365 pim_ifchannel_ifjoin_name(ch
->ifjoin_state
, ch
->flags
),
1371 } /* scan interface channels */
1374 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
1375 json_object_free(json
);
1379 static void pim_show_neighbors_single(struct vty
*vty
, const char *neighbor
, u_char uj
)
1381 struct listnode
*node
;
1382 struct listnode
*neighnode
;
1383 struct interface
*ifp
;
1384 struct pim_interface
*pim_ifp
;
1385 struct pim_neighbor
*neigh
;
1387 int found_neighbor
= 0;
1388 int option_address_list
;
1389 int option_dr_priority
;
1390 int option_generation_id
;
1391 int option_holdtime
;
1392 int option_lan_prune_delay
;
1396 char neigh_src_str
[INET_ADDRSTRLEN
];
1398 json_object
*json
= NULL
;
1399 json_object
*json_ifp
= NULL
;
1400 json_object
*json_row
= NULL
;
1402 now
= pim_time_monotonic_sec();
1405 json
= json_object_new_object();
1407 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), node
, ifp
)) {
1408 pim_ifp
= ifp
->info
;
1413 if (pim_ifp
->pim_sock_fd
< 0)
1416 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
, neigh
)) {
1417 pim_inet4_dump("<src?>", neigh
->source_addr
,
1418 neigh_src_str
, sizeof(neigh_src_str
));
1421 * The user can specify either the interface name or the PIM neighbor IP.
1422 * If this pim_ifp matches neither then skip.
1424 if (strcmp(neighbor
, "detail") &&
1425 strcmp(neighbor
, ifp
->name
) &&
1426 strcmp(neighbor
, neigh_src_str
))
1430 pim_time_uptime(uptime
, sizeof(uptime
), now
- neigh
->creation
);
1431 pim_time_timer_to_hhmmss(expire
, sizeof(expire
), neigh
->t_expire_timer
);
1433 option_address_list
= 0;
1434 option_dr_priority
= 0;
1435 option_generation_id
= 0;
1436 option_holdtime
= 0;
1437 option_lan_prune_delay
= 0;
1440 if (PIM_OPTION_IS_SET(neigh
->hello_options
, PIM_OPTION_MASK_ADDRESS_LIST
))
1441 option_address_list
= 1;
1443 if (PIM_OPTION_IS_SET(neigh
->hello_options
, PIM_OPTION_MASK_DR_PRIORITY
))
1444 option_dr_priority
= 1;
1446 if (PIM_OPTION_IS_SET(neigh
->hello_options
, PIM_OPTION_MASK_GENERATION_ID
))
1447 option_generation_id
= 1;
1449 if (PIM_OPTION_IS_SET(neigh
->hello_options
, PIM_OPTION_MASK_HOLDTIME
))
1450 option_holdtime
= 1;
1452 if (PIM_OPTION_IS_SET(neigh
->hello_options
, PIM_OPTION_MASK_LAN_PRUNE_DELAY
))
1453 option_lan_prune_delay
= 1;
1455 if (PIM_OPTION_IS_SET(neigh
->hello_options
, PIM_OPTION_MASK_CAN_DISABLE_JOIN_SUPPRESSION
))
1460 /* Does this ifp live in json? If not create it. */
1461 json_object_object_get_ex(json
, ifp
->name
, &json_ifp
);
1464 json_ifp
= json_object_new_object();
1465 json_object_pim_ifp_add(json_ifp
, ifp
);
1466 json_object_object_add(json
, ifp
->name
, json_ifp
);
1469 json_row
= json_object_new_object();
1470 json_object_string_add(json_row
, "interface", ifp
->name
);
1471 json_object_string_add(json_row
, "address", neigh_src_str
);
1472 json_object_string_add(json_row
, "upTime", uptime
);
1473 json_object_string_add(json_row
, "holdtime", expire
);
1474 json_object_int_add(json_row
, "drPriority", neigh
->dr_priority
);
1475 json_object_int_add(json_row
, "generationId", neigh
->generation_id
);
1477 if (option_address_list
)
1478 json_object_boolean_true_add(json_row
, "helloOptionAddressList");
1480 if (option_dr_priority
)
1481 json_object_boolean_true_add(json_row
, "helloOptionDrPriority");
1483 if (option_generation_id
)
1484 json_object_boolean_true_add(json_row
, "helloOptionGenerationId");
1486 if (option_holdtime
)
1487 json_object_boolean_true_add(json_row
, "helloOptionHoldtime");
1489 if (option_lan_prune_delay
)
1490 json_object_boolean_true_add(json_row
, "helloOptionLanPruneDelay");
1493 json_object_boolean_true_add(json_row
, "helloOptionTBit");
1495 json_object_object_add(json_ifp
, neigh_src_str
, json_row
);
1498 vty_out(vty
, "Interface : %s%s", ifp
->name
, VTY_NEWLINE
);
1499 vty_out(vty
, "Neighbor : %s%s", neigh_src_str
, VTY_NEWLINE
);
1500 vty_out(vty
, " Uptime : %s%s", uptime
, VTY_NEWLINE
);
1501 vty_out(vty
, " Holdtime : %s%s", expire
, VTY_NEWLINE
);
1502 vty_out(vty
, " DR Priority : %d%s", neigh
->dr_priority
, VTY_NEWLINE
);
1503 vty_out(vty
, " Generation ID : %08x%s", neigh
->generation_id
, VTY_NEWLINE
);
1504 vty_out(vty
, " Override Interval (msec) : %d%s", neigh
->override_interval_msec
, VTY_NEWLINE
);
1505 vty_out(vty
, " Propagation Delay (msec) : %d%s", neigh
->propagation_delay_msec
, VTY_NEWLINE
);
1506 vty_out(vty
, " Hello Option - Address List : %s%s", option_address_list
? "yes" : "no", VTY_NEWLINE
);
1507 vty_out(vty
, " Hello Option - DR Priority : %s%s", option_dr_priority
? "yes" : "no", VTY_NEWLINE
);
1508 vty_out(vty
, " Hello Option - Generation ID : %s%s", option_generation_id
? "yes" : "no", VTY_NEWLINE
);
1509 vty_out(vty
, " Hello Option - Holdtime : %s%s", option_holdtime
? "yes" : "no", VTY_NEWLINE
);
1510 vty_out(vty
, " Hello Option - LAN Prune Delay : %s%s", option_lan_prune_delay
? "yes" : "no", VTY_NEWLINE
);
1511 vty_out(vty
, " Hello Option - T-bit : %s%s", option_t_bit
? "yes" : "no", VTY_NEWLINE
);
1512 vty_out(vty
, "%s", VTY_NEWLINE
);
1518 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
1519 json_object_free(json
);
1522 if (!found_neighbor
)
1523 vty_out (vty
, "%% No such interface or neighbor%s", VTY_NEWLINE
);
1529 pim_show_state(struct vty
*vty
, const char *src_or_group
, const char *group
, u_char uj
)
1531 struct channel_oil
*c_oil
;
1532 struct listnode
*node
;
1533 json_object
*json
= NULL
;
1534 json_object
*json_group
= NULL
;
1535 json_object
*json_ifp_in
= NULL
;
1536 json_object
*json_ifp_out
= NULL
;
1537 json_object
*json_source
= NULL
;
1540 now
= pim_time_monotonic_sec();
1543 json
= json_object_new_object();
1545 vty_out(vty
, "Codes: J -> Pim Join, I -> IGMP Report, S -> Source, * -> Inherited from (*,G)");
1546 vty_out(vty
, "%sInstalled Source Group IIF OIL%s", VTY_NEWLINE
, VTY_NEWLINE
);
1549 for (ALL_LIST_ELEMENTS_RO(pim_channel_oil_list
, node
, c_oil
)) {
1550 char grp_str
[INET_ADDRSTRLEN
];
1551 char src_str
[INET_ADDRSTRLEN
];
1552 char in_ifname
[INTERFACE_NAMSIZ
+1];
1553 char out_ifname
[INTERFACE_NAMSIZ
+1];
1555 struct interface
*ifp_in
;
1558 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, grp_str
, sizeof(grp_str
));
1559 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, src_str
, sizeof(src_str
));
1560 ifp_in
= pim_if_find_by_vif_index(c_oil
->oil
.mfcc_parent
);
1563 strcpy(in_ifname
, ifp_in
->name
);
1565 strcpy(in_ifname
, "<iif?>");
1569 if (strcmp(src_or_group
, src_str
) && strcmp(src_or_group
, grp_str
))
1572 if (group
&& strcmp(group
, grp_str
))
1578 /* Find the group, create it if it doesn't exist */
1579 json_object_object_get_ex(json
, grp_str
, &json_group
);
1582 json_group
= json_object_new_object();
1583 json_object_object_add(json
, grp_str
, json_group
);
1586 /* Find the source nested under the group, create it if it doesn't exist */
1587 json_object_object_get_ex(json_group
, src_str
, &json_source
);
1590 json_source
= json_object_new_object();
1591 json_object_object_add(json_group
, src_str
, json_source
);
1594 /* Find the inbound interface nested under the source, create it if it doesn't exist */
1595 json_object_object_get_ex(json_source
, in_ifname
, &json_ifp_in
);
1598 json_ifp_in
= json_object_new_object();
1599 json_object_object_add(json_source
, in_ifname
, json_ifp_in
);
1600 json_object_int_add (json_source
, "Installed", c_oil
->installed
);
1601 json_object_int_add (json_source
, "RefCount", c_oil
->oil_ref_count
);
1602 json_object_int_add (json_source
, "OilListSize", c_oil
->oil_size
);
1603 json_object_int_add (json_source
, "OilRescan", c_oil
->oil_inherited_rescan
);
1604 json_object_int_add (json_source
, "LastUsed", c_oil
->cc
.lastused
);
1605 json_object_int_add (json_source
, "PacketCount", c_oil
->cc
.pktcnt
);
1606 json_object_int_add (json_source
, "ByteCount", c_oil
->cc
.bytecnt
);
1607 json_object_int_add (json_source
, "WrongInterface", c_oil
->cc
.wrong_if
);
1610 vty_out(vty
, "%-9d %-15s %-15s %-7s ",
1617 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
; ++oif_vif_index
) {
1618 struct interface
*ifp_out
;
1619 char oif_uptime
[10];
1622 ttl
= c_oil
->oil
.mfcc_ttls
[oif_vif_index
];
1626 ifp_out
= pim_if_find_by_vif_index(oif_vif_index
);
1627 pim_time_uptime(oif_uptime
, sizeof(oif_uptime
), now
- c_oil
->oif_creation
[oif_vif_index
]);
1630 strcpy(out_ifname
, ifp_out
->name
);
1632 strcpy(out_ifname
, "<oif?>");
1635 json_ifp_out
= json_object_new_object();
1636 json_object_string_add(json_ifp_out
, "source", src_str
);
1637 json_object_string_add(json_ifp_out
, "group", grp_str
);
1638 json_object_string_add(json_ifp_out
, "inboundInterface", in_ifname
);
1639 json_object_string_add(json_ifp_out
, "outboundInterface", out_ifname
);
1640 json_object_int_add(json_ifp_out
, "installed", c_oil
->installed
);
1642 json_object_object_add(json_ifp_in
, out_ifname
, json_ifp_out
);
1647 vty_out(vty
, "%s(%c%c%c%c)", out_ifname
,
1648 (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_IGMP
) ? 'I' : ' ',
1649 (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_PIM
) ? 'J' : ' ',
1650 (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_SOURCE
) ? 'S' : ' ',
1651 (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_STAR
) ? '*' : ' ');
1654 vty_out(vty
, ", %s(%c%c%c%c)", out_ifname
,
1655 (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_IGMP
) ? 'I' : ' ',
1656 (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_PIM
) ? 'J' : ' ',
1657 (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_SOURCE
) ? 'S' : ' ',
1658 (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_STAR
) ? '*' : ' ' );
1663 vty_out(vty
, "%s", VTY_NEWLINE
);
1668 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
1669 json_object_free(json
);
1671 vty_out(vty
, "%s", VTY_NEWLINE
);
1675 static void pim_show_neighbors(struct vty
*vty
, u_char uj
)
1677 struct listnode
*node
;
1678 struct listnode
*neighnode
;
1679 struct interface
*ifp
;
1680 struct pim_interface
*pim_ifp
;
1681 struct pim_neighbor
*neigh
;
1685 char neigh_src_str
[INET_ADDRSTRLEN
];
1686 json_object
*json
= NULL
;
1687 json_object
*json_ifp_rows
= NULL
;
1688 json_object
*json_row
= NULL
;
1690 now
= pim_time_monotonic_sec();
1693 json
= json_object_new_object();
1695 vty_out(vty
, "Interface Neighbor Uptime Holdtime DR Pri%s", VTY_NEWLINE
);
1698 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), node
, ifp
)) {
1699 pim_ifp
= ifp
->info
;
1704 if (pim_ifp
->pim_sock_fd
< 0)
1708 json_ifp_rows
= json_object_new_object();
1710 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
, neigh
)) {
1711 pim_inet4_dump("<src?>", neigh
->source_addr
,
1712 neigh_src_str
, sizeof(neigh_src_str
));
1713 pim_time_uptime(uptime
, sizeof(uptime
), now
- neigh
->creation
);
1714 pim_time_timer_to_hhmmss(expire
, sizeof(expire
), neigh
->t_expire_timer
);
1717 json_row
= json_object_new_object();
1718 json_object_string_add(json_row
, "interface", ifp
->name
);
1719 json_object_string_add(json_row
, "neighbor", neigh_src_str
);
1720 json_object_string_add(json_row
, "upTime", uptime
);
1721 json_object_string_add(json_row
, "holdTime", expire
);
1722 json_object_int_add(json_row
, "holdTimeMax", neigh
->holdtime
);
1723 json_object_int_add(json_row
, "drPriority", neigh
->dr_priority
);
1724 json_object_object_add(json_ifp_rows
, neigh_src_str
, json_row
);
1727 vty_out(vty
, "%-9s %15s %8s %8s %6d%s",
1738 json_object_object_add(json
, ifp
->name
, json_ifp_rows
);
1739 json_ifp_rows
= NULL
;
1744 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
1745 json_object_free(json
);
1749 static void pim_show_neighbors_secondary(struct vty
*vty
)
1751 struct listnode
*node
;
1752 struct interface
*ifp
;
1754 vty_out(vty
, "Interface Address Neighbor Secondary %s", VTY_NEWLINE
);
1756 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), node
, ifp
)) {
1757 struct pim_interface
*pim_ifp
;
1758 struct in_addr ifaddr
;
1759 struct listnode
*neighnode
;
1760 struct pim_neighbor
*neigh
;
1762 pim_ifp
= ifp
->info
;
1767 if (pim_ifp
->pim_sock_fd
< 0)
1770 ifaddr
= pim_ifp
->primary_address
;
1772 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
, neigh
)) {
1773 char neigh_src_str
[INET_ADDRSTRLEN
];
1774 struct listnode
*prefix_node
;
1777 if (!neigh
->prefix_list
)
1780 pim_inet4_dump("<src?>", neigh
->source_addr
,
1781 neigh_src_str
, sizeof(neigh_src_str
));
1783 for (ALL_LIST_ELEMENTS_RO(neigh
->prefix_list
, prefix_node
, p
)) {
1784 char neigh_sec_str
[PREFIX2STR_BUFFER
];
1786 prefix2str(p
, neigh_sec_str
, sizeof(neigh_sec_str
));
1788 vty_out(vty
, "%-9s %-15s %-15s %-15s%s",
1800 json_object_pim_upstream_add (json_object
*json
, struct pim_upstream
*up
)
1802 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED
)
1803 json_object_boolean_true_add(json
, "drJoinDesired");
1805 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED_UPDATED
)
1806 json_object_boolean_true_add(json
, "drJoinDesiredUpdated");
1808 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
)
1809 json_object_boolean_true_add(json
, "firstHopRouter");
1811 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_IGMP
)
1812 json_object_boolean_true_add(json
, "sourceIgmp");
1814 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_PIM
)
1815 json_object_boolean_true_add(json
, "sourcePim");
1817 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_STREAM
)
1818 json_object_boolean_true_add(json
, "sourceStream");
1820 /* XXX: need to print ths flag in the plain text display as well */
1821 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_MSDP
)
1822 json_object_boolean_true_add(json
, "sourceMsdp");
1826 pim_upstream_state2brief_str (enum pim_upstream_state join_state
, char *state_str
)
1830 case PIM_UPSTREAM_NOTJOINED
:
1831 strcpy (state_str
, "NotJ");
1833 case PIM_UPSTREAM_JOINED
:
1834 strcpy (state_str
, "J");
1837 strcpy (state_str
, "Unk");
1843 pim_reg_state2brief_str (enum pim_reg_state reg_state
, char *state_str
)
1847 case PIM_REG_NOINFO
:
1848 strcpy (state_str
, "RegNI");
1851 strcpy (state_str
, "RegJ");
1853 case PIM_REG_JOIN_PENDING
:
1855 strcpy (state_str
, "RegP");
1858 strcpy (state_str
, "Unk");
1863 static void pim_show_upstream(struct vty
*vty
, u_char uj
)
1865 struct listnode
*upnode
;
1866 struct pim_upstream
*up
;
1868 json_object
*json
= NULL
;
1869 json_object
*json_group
= NULL
;
1870 json_object
*json_row
= NULL
;
1872 now
= pim_time_monotonic_sec();
1875 json
= json_object_new_object();
1877 vty_out(vty
, "Iif Source Group State Uptime JoinTimer RSTimer KATimer RefCnt%s", VTY_NEWLINE
);
1879 for (ALL_LIST_ELEMENTS_RO(pim_upstream_list
, upnode
, up
)) {
1880 char src_str
[INET_ADDRSTRLEN
];
1881 char grp_str
[INET_ADDRSTRLEN
];
1883 char join_timer
[10];
1886 char msdp_reg_timer
[10];
1887 char state_str
[PIM_REG_STATE_STR_LEN
];
1889 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
1890 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
1891 pim_time_uptime(uptime
, sizeof(uptime
), now
- up
->state_transition
);
1892 pim_time_timer_to_hhmmss (join_timer
, sizeof(join_timer
), up
->t_join_timer
);
1895 * If we have a J/P timer for the neighbor display that
1897 if (!up
->t_join_timer
)
1899 struct pim_neighbor
*nbr
;
1901 nbr
= pim_neighbor_find (up
->rpf
.source_nexthop
.interface
,
1902 up
->rpf
.rpf_addr
.u
.prefix4
);
1904 pim_time_timer_to_hhmmss (join_timer
, sizeof(join_timer
), nbr
->jp_timer
);
1907 pim_time_timer_to_hhmmss (rs_timer
, sizeof (rs_timer
), up
->t_rs_timer
);
1908 pim_time_timer_to_hhmmss (ka_timer
, sizeof (ka_timer
), up
->t_ka_timer
);
1909 pim_time_timer_to_hhmmss (msdp_reg_timer
, sizeof (msdp_reg_timer
), up
->t_msdp_reg_timer
);
1911 pim_upstream_state2brief_str (up
->join_state
, state_str
);
1912 if (up
->reg_state
!= PIM_REG_NOINFO
) {
1913 char tmp_str
[PIM_REG_STATE_STR_LEN
];
1915 sprintf (state_str
+ strlen (state_str
), ",%s",
1916 pim_reg_state2brief_str (up
->reg_state
, tmp_str
));
1920 json_object_object_get_ex(json
, grp_str
, &json_group
);
1923 json_group
= json_object_new_object();
1924 json_object_object_add(json
, grp_str
, json_group
);
1927 json_row
= json_object_new_object();
1928 json_object_pim_upstream_add(json_row
, up
);
1929 json_object_string_add(json_row
, "inboundInterface", up
->rpf
.source_nexthop
.interface
->name
);
1930 json_object_string_add(json_row
, "source", src_str
);
1931 json_object_string_add(json_row
, "group", grp_str
);
1932 json_object_string_add(json_row
, "state", state_str
);
1933 json_object_string_add(json_row
, "joinState", pim_upstream_state2str (up
->join_state
));
1934 json_object_string_add(json_row
, "regState", pim_reg_state2str (up
->reg_state
, state_str
));
1935 json_object_string_add(json_row
, "upTime", uptime
);
1936 json_object_string_add(json_row
, "joinTimer", join_timer
);
1937 json_object_string_add(json_row
, "resetTimer", rs_timer
);
1938 json_object_string_add(json_row
, "keepaliveTimer", ka_timer
);
1939 json_object_string_add(json_row
, "msdpRegTimer", msdp_reg_timer
);
1940 json_object_int_add(json_row
, "refCount", up
->ref_count
);
1941 json_object_int_add(json_row
, "sptBit", up
->sptbit
);
1942 json_object_object_add(json_group
, src_str
, json_row
);
1944 vty_out(vty
, "%-10s%-15s %-15s %-11s %-8s %-9s %-9s %-9s %6d%s",
1945 up
->rpf
.source_nexthop
.interface
->name
,
1959 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
1960 json_object_free(json
);
1964 static void pim_show_join_desired(struct vty
*vty
, u_char uj
)
1966 struct listnode
*chnode
;
1967 struct pim_interface
*pim_ifp
;
1968 struct pim_ifchannel
*ch
;
1969 char src_str
[INET_ADDRSTRLEN
];
1970 char grp_str
[INET_ADDRSTRLEN
];
1971 json_object
*json
= NULL
;
1972 json_object
*json_group
= NULL
;
1973 json_object
*json_row
= NULL
;
1976 json
= json_object_new_object();
1979 "Interface Source Group LostAssert Joins PimInclude JoinDesired EvalJD%s",
1982 /* scan per-interface (S,G) state */
1983 for (ALL_LIST_ELEMENTS_RO(pim_ifchannel_list
, chnode
, ch
)) {
1984 /* scan all interfaces */
1985 pim_ifp
= ch
->interface
->info
;
1989 struct pim_upstream
*up
= ch
->upstream
;
1991 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
1992 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
1995 json_object_object_get_ex(json
, grp_str
, &json_group
);
1998 json_group
= json_object_new_object();
1999 json_object_object_add(json
, grp_str
, json_group
);
2002 json_row
= json_object_new_object();
2003 json_object_pim_upstream_add(json_row
, up
);
2004 json_object_string_add(json_row
, "interface", ch
->interface
->name
);
2005 json_object_string_add(json_row
, "source", src_str
);
2006 json_object_string_add(json_row
, "group", grp_str
);
2008 if (pim_macro_ch_lost_assert(ch
))
2009 json_object_boolean_true_add(json_row
, "lostAssert");
2011 if (pim_macro_chisin_joins(ch
))
2012 json_object_boolean_true_add(json_row
, "joins");
2014 if (pim_macro_chisin_pim_include(ch
))
2015 json_object_boolean_true_add(json_row
, "pimInclude");
2017 if (pim_upstream_evaluate_join_desired(up
))
2018 json_object_boolean_true_add(json_row
, "evaluateJoinDesired");
2020 json_object_object_add(json_group
, src_str
, json_row
);
2023 vty_out(vty
, "%-9s %-15s %-15s %-10s %-5s %-10s %-11s %-6s%s",
2024 ch
->interface
->name
,
2027 pim_macro_ch_lost_assert(ch
) ? "yes" : "no",
2028 pim_macro_chisin_joins(ch
) ? "yes" : "no",
2029 pim_macro_chisin_pim_include(ch
) ? "yes" : "no",
2030 PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED(up
->flags
) ? "yes" : "no",
2031 pim_upstream_evaluate_join_desired(up
) ? "yes" : "no",
2037 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
2038 json_object_free(json
);
2042 static void pim_show_upstream_rpf(struct vty
*vty
, u_char uj
)
2044 struct listnode
*upnode
;
2045 struct pim_upstream
*up
;
2046 json_object
*json
= NULL
;
2047 json_object
*json_group
= NULL
;
2048 json_object
*json_row
= NULL
;
2051 json
= json_object_new_object();
2054 "Source Group RpfIface RibNextHop RpfAddress %s",
2057 for (ALL_LIST_ELEMENTS_RO(pim_upstream_list
, upnode
, up
)) {
2058 char src_str
[INET_ADDRSTRLEN
];
2059 char grp_str
[INET_ADDRSTRLEN
];
2060 char rpf_nexthop_str
[PREFIX_STRLEN
];
2061 char rpf_addr_str
[PREFIX_STRLEN
];
2062 struct pim_rpf
*rpf
;
2063 const char *rpf_ifname
;
2067 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2068 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2069 pim_addr_dump("<nexthop?>", &rpf
->source_nexthop
.mrib_nexthop_addr
, rpf_nexthop_str
, sizeof(rpf_nexthop_str
));
2070 pim_addr_dump("<rpf?>", &rpf
->rpf_addr
, rpf_addr_str
, sizeof(rpf_addr_str
));
2072 rpf_ifname
= rpf
->source_nexthop
.interface
? rpf
->source_nexthop
.interface
->name
: "<ifname?>";
2075 json_object_object_get_ex(json
, grp_str
, &json_group
);
2078 json_group
= json_object_new_object();
2079 json_object_object_add(json
, grp_str
, json_group
);
2082 json_row
= json_object_new_object();
2083 json_object_pim_upstream_add(json_row
, up
);
2084 json_object_string_add(json_row
, "source", src_str
);
2085 json_object_string_add(json_row
, "group", grp_str
);
2086 json_object_string_add(json_row
, "rpfInterface", rpf_ifname
);
2087 json_object_string_add(json_row
, "ribNexthop", rpf_nexthop_str
);
2088 json_object_string_add(json_row
, "rpfAddress", rpf_addr_str
);
2089 json_object_object_add(json_group
, src_str
, json_row
);
2091 vty_out(vty
, "%-15s %-15s %-8s %-15s %-15s%s",
2102 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
2103 json_object_free(json
);
2107 static void show_rpf_refresh_stats(struct vty
*vty
, time_t now
, json_object
*json
)
2109 char refresh_uptime
[10];
2111 pim_time_uptime_begin(refresh_uptime
, sizeof(refresh_uptime
), now
, qpim_rpf_cache_refresh_last
);
2114 json_object_int_add(json
, "rpfCacheRefreshDelayMsecs", qpim_rpf_cache_refresh_delay_msec
);
2115 json_object_int_add(json
, "rpfCacheRefreshTimer", pim_time_timer_remain_msec(qpim_rpf_cache_refresher
));
2116 json_object_int_add(json
, "rpfCacheRefreshRequests", qpim_rpf_cache_refresh_requests
);
2117 json_object_int_add(json
, "rpfCacheRefreshEvents", qpim_rpf_cache_refresh_events
);
2118 json_object_string_add(json
, "rpfCacheRefreshLast", refresh_uptime
);
2119 json_object_int_add(json
, "nexthopLookups", qpim_nexthop_lookups
);
2120 json_object_int_add(json
, "nexthopLookupsAvoided", nexthop_lookups_avoided
);
2123 "RPF Cache Refresh Delay: %ld msecs%s"
2124 "RPF Cache Refresh Timer: %ld msecs%s"
2125 "RPF Cache Refresh Requests: %lld%s"
2126 "RPF Cache Refresh Events: %lld%s"
2127 "RPF Cache Refresh Last: %s%s"
2128 "Nexthop Lookups: %lld%s"
2129 "Nexthop Lookups Avoided: %lld%s",
2130 qpim_rpf_cache_refresh_delay_msec
, VTY_NEWLINE
,
2131 pim_time_timer_remain_msec(qpim_rpf_cache_refresher
), VTY_NEWLINE
,
2132 (long long)qpim_rpf_cache_refresh_requests
, VTY_NEWLINE
,
2133 (long long)qpim_rpf_cache_refresh_events
, VTY_NEWLINE
,
2134 refresh_uptime
, VTY_NEWLINE
,
2135 (long long) qpim_nexthop_lookups
, VTY_NEWLINE
,
2136 (long long)nexthop_lookups_avoided
, VTY_NEWLINE
);
2140 static void show_scan_oil_stats(struct vty
*vty
, time_t now
)
2142 char uptime_scan_oil
[10];
2143 char uptime_mroute_add
[10];
2144 char uptime_mroute_del
[10];
2146 pim_time_uptime_begin(uptime_scan_oil
, sizeof(uptime_scan_oil
), now
, qpim_scan_oil_last
);
2147 pim_time_uptime_begin(uptime_mroute_add
, sizeof(uptime_mroute_add
), now
, qpim_mroute_add_last
);
2148 pim_time_uptime_begin(uptime_mroute_del
, sizeof(uptime_mroute_del
), now
, qpim_mroute_del_last
);
2151 "Scan OIL - Last: %s Events: %lld%s"
2152 "MFC Add - Last: %s Events: %lld%s"
2153 "MFC Del - Last: %s Events: %lld%s",
2154 uptime_scan_oil
, (long long) qpim_scan_oil_events
, VTY_NEWLINE
,
2155 uptime_mroute_add
, (long long) qpim_mroute_add_events
, VTY_NEWLINE
,
2156 uptime_mroute_del
, (long long) qpim_mroute_del_events
, VTY_NEWLINE
);
2159 static void pim_show_rpf(struct vty
*vty
, u_char uj
)
2161 struct listnode
*up_node
;
2162 struct pim_upstream
*up
;
2163 time_t now
= pim_time_monotonic_sec();
2164 json_object
*json
= NULL
;
2165 json_object
*json_group
= NULL
;
2166 json_object
*json_row
= NULL
;
2169 json
= json_object_new_object();
2170 show_rpf_refresh_stats(vty
, now
, json
);
2172 show_rpf_refresh_stats(vty
, now
, json
);
2173 vty_out(vty
, "%s", VTY_NEWLINE
);
2175 "Source Group RpfIface RpfAddress RibNextHop Metric Pref%s",
2179 for (ALL_LIST_ELEMENTS_RO(pim_upstream_list
, up_node
, up
)) {
2180 char src_str
[INET_ADDRSTRLEN
];
2181 char grp_str
[INET_ADDRSTRLEN
];
2182 char rpf_addr_str
[PREFIX_STRLEN
];
2183 char rib_nexthop_str
[PREFIX_STRLEN
];
2184 const char *rpf_ifname
;
2185 struct pim_rpf
*rpf
= &up
->rpf
;
2187 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2188 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2189 pim_addr_dump("<rpf?>", &rpf
->rpf_addr
, rpf_addr_str
, sizeof(rpf_addr_str
));
2190 pim_addr_dump("<nexthop?>", &rpf
->source_nexthop
.mrib_nexthop_addr
, rib_nexthop_str
, sizeof(rib_nexthop_str
));
2192 rpf_ifname
= rpf
->source_nexthop
.interface
? rpf
->source_nexthop
.interface
->name
: "<ifname?>";
2195 json_object_object_get_ex(json
, grp_str
, &json_group
);
2198 json_group
= json_object_new_object();
2199 json_object_object_add(json
, grp_str
, json_group
);
2202 json_row
= json_object_new_object();
2203 json_object_string_add(json_row
, "source", src_str
);
2204 json_object_string_add(json_row
, "group", grp_str
);
2205 json_object_string_add(json_row
, "rpfInterface", rpf_ifname
);
2206 json_object_string_add(json_row
, "rpfAddress", rpf_addr_str
);
2207 json_object_string_add(json_row
, "ribNexthop", rib_nexthop_str
);
2208 json_object_int_add(json_row
, "routeMetric", rpf
->source_nexthop
.mrib_route_metric
);
2209 json_object_int_add(json_row
, "routePreference", rpf
->source_nexthop
.mrib_metric_preference
);
2210 json_object_object_add(json_group
, src_str
, json_row
);
2213 vty_out(vty
, "%-15s %-15s %-8s %-15s %-15s %6d %4d%s",
2219 rpf
->source_nexthop
.mrib_route_metric
,
2220 rpf
->source_nexthop
.mrib_metric_preference
,
2226 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
2227 json_object_free(json
);
2232 pim_print_pnc_cache_walkcb (struct hash_backet
*backet
, void *arg
)
2234 struct pim_nexthop_cache
*pnc
= backet
->data
;
2235 struct vty
*vty
= arg
;
2236 struct nexthop
*nh_node
= NULL
;
2237 ifindex_t first_ifindex
;
2238 struct interface
*ifp
= NULL
;
2243 for (nh_node
= pnc
->nexthop
; nh_node
; nh_node
= nh_node
->next
)
2245 first_ifindex
= nh_node
->ifindex
;
2246 ifp
= if_lookup_by_index (first_ifindex
, VRF_DEFAULT
);
2248 vty_out (vty
, "%-15s ", inet_ntoa (pnc
->rpf
.rpf_addr
.u
.prefix4
));
2249 vty_out (vty
, "%-14s ", ifp
? ifp
->name
: "NULL");
2250 vty_out (vty
, "%s ", inet_ntoa (nh_node
->gate
.ipv4
));
2251 vty_out (vty
, "%s", VTY_NEWLINE
);
2257 pim_show_nexthop (struct vty
*vty
)
2260 if (pimg
&& !pimg
->rpf_hash
)
2262 vty_out (vty
, "no nexthop cache %s", VTY_NEWLINE
);
2266 vty_out (vty
, "Number of registered addresses: %lu %s",
2267 pimg
->rpf_hash
->count
, VTY_NEWLINE
);
2268 vty_out (vty
, "Address Interface Nexthop%s", VTY_NEWLINE
);
2269 vty_out (vty
, "-------------------------------------------%s", VTY_NEWLINE
);
2271 hash_walk (pimg
->rpf_hash
, pim_print_pnc_cache_walkcb
, vty
);
2275 static void igmp_show_groups(struct vty
*vty
, u_char uj
)
2277 struct listnode
*ifnode
;
2278 struct interface
*ifp
;
2280 json_object
*json
= NULL
;
2281 json_object
*json_iface
= NULL
;
2282 json_object
*json_row
= NULL
;
2284 now
= pim_time_monotonic_sec();
2287 json
= json_object_new_object();
2289 vty_out(vty
, "Interface Address Group Mode Timer Srcs V Uptime %s", VTY_NEWLINE
);
2291 /* scan interfaces */
2292 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), ifnode
, ifp
)) {
2293 struct pim_interface
*pim_ifp
= ifp
->info
;
2294 struct listnode
*sock_node
;
2295 struct igmp_sock
*igmp
;
2300 /* scan igmp sockets */
2301 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
2302 char ifaddr_str
[INET_ADDRSTRLEN
];
2303 struct listnode
*grpnode
;
2304 struct igmp_group
*grp
;
2306 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
, sizeof(ifaddr_str
));
2308 /* scan igmp groups */
2309 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grpnode
, grp
)) {
2310 char group_str
[INET_ADDRSTRLEN
];
2314 pim_inet4_dump("<group?>", grp
->group_addr
, group_str
, sizeof(group_str
));
2315 pim_time_timer_to_hhmmss(hhmmss
, sizeof(hhmmss
), grp
->t_group_timer
);
2316 pim_time_uptime(uptime
, sizeof(uptime
), now
- grp
->group_creation
);
2319 json_object_object_get_ex(json
, ifp
->name
, &json_iface
);
2322 json_iface
= json_object_new_object();
2323 json_object_pim_ifp_add(json_iface
, ifp
);
2324 json_object_object_add(json
, ifp
->name
, json_iface
);
2327 json_row
= json_object_new_object();
2328 json_object_string_add(json_row
, "source", ifaddr_str
);
2329 json_object_string_add(json_row
, "group", group_str
);
2331 if (grp
->igmp_version
== 3)
2332 json_object_string_add(json_row
, "mode", grp
->group_filtermode_isexcl
? "EXCLUDE" : "INCLUDE");
2334 json_object_string_add(json_row
, "timer", hhmmss
);
2335 json_object_int_add(json_row
, "sourcesCount", grp
->group_source_list
? listcount(grp
->group_source_list
) : 0);
2336 json_object_int_add(json_row
, "version", grp
->igmp_version
);
2337 json_object_string_add(json_row
, "uptime", uptime
);
2338 json_object_object_add(json_iface
, group_str
, json_row
);
2341 vty_out(vty
, "%-9s %-15s %-15s %4s %8s %4d %d %8s%s",
2345 grp
->igmp_version
== 3 ? (grp
->group_filtermode_isexcl
? "EXCL" : "INCL") : "----",
2347 grp
->group_source_list
? listcount(grp
->group_source_list
) : 0,
2352 } /* scan igmp groups */
2353 } /* scan igmp sockets */
2354 } /* scan interfaces */
2357 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
2358 json_object_free(json
);
2362 static void igmp_show_group_retransmission(struct vty
*vty
)
2364 struct listnode
*ifnode
;
2365 struct interface
*ifp
;
2367 vty_out(vty
, "Interface Address Group RetTimer Counter RetSrcs%s", VTY_NEWLINE
);
2369 /* scan interfaces */
2370 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), ifnode
, ifp
)) {
2371 struct pim_interface
*pim_ifp
= ifp
->info
;
2372 struct listnode
*sock_node
;
2373 struct igmp_sock
*igmp
;
2378 /* scan igmp sockets */
2379 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
2380 char ifaddr_str
[INET_ADDRSTRLEN
];
2381 struct listnode
*grpnode
;
2382 struct igmp_group
*grp
;
2384 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
, sizeof(ifaddr_str
));
2386 /* scan igmp groups */
2387 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grpnode
, grp
)) {
2388 char group_str
[INET_ADDRSTRLEN
];
2389 char grp_retr_mmss
[10];
2390 struct listnode
*src_node
;
2391 struct igmp_source
*src
;
2392 int grp_retr_sources
= 0;
2394 pim_inet4_dump("<group?>", grp
->group_addr
, group_str
, sizeof(group_str
));
2395 pim_time_timer_to_mmss(grp_retr_mmss
, sizeof(grp_retr_mmss
), grp
->t_group_query_retransmit_timer
);
2398 /* count group sources with retransmission state */
2399 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
, src_node
, src
)) {
2400 if (src
->source_query_retransmit_count
> 0) {
2405 vty_out(vty
, "%-9s %-15s %-15s %-8s %7d %7d%s",
2410 grp
->group_specific_query_retransmit_count
,
2414 } /* scan igmp groups */
2415 } /* scan igmp sockets */
2416 } /* scan interfaces */
2419 static void igmp_show_sources(struct vty
*vty
)
2421 struct listnode
*ifnode
;
2422 struct interface
*ifp
;
2425 now
= pim_time_monotonic_sec();
2427 vty_out(vty
, "Interface Address Group Source Timer Fwd Uptime %s", VTY_NEWLINE
);
2429 /* scan interfaces */
2430 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), ifnode
, ifp
)) {
2431 struct pim_interface
*pim_ifp
= ifp
->info
;
2432 struct listnode
*sock_node
;
2433 struct igmp_sock
*igmp
;
2438 /* scan igmp sockets */
2439 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
2440 char ifaddr_str
[INET_ADDRSTRLEN
];
2441 struct listnode
*grpnode
;
2442 struct igmp_group
*grp
;
2444 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
, sizeof(ifaddr_str
));
2446 /* scan igmp groups */
2447 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grpnode
, grp
)) {
2448 char group_str
[INET_ADDRSTRLEN
];
2449 struct listnode
*srcnode
;
2450 struct igmp_source
*src
;
2452 pim_inet4_dump("<group?>", grp
->group_addr
, group_str
, sizeof(group_str
));
2454 /* scan group sources */
2455 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
, srcnode
, src
)) {
2456 char source_str
[INET_ADDRSTRLEN
];
2460 pim_inet4_dump("<source?>", src
->source_addr
, source_str
, sizeof(source_str
));
2462 pim_time_timer_to_mmss(mmss
, sizeof(mmss
), src
->t_source_timer
);
2464 pim_time_uptime(uptime
, sizeof(uptime
), now
- src
->source_creation
);
2466 vty_out(vty
, "%-9s %-15s %-15s %-15s %5s %3s %8s%s",
2472 IGMP_SOURCE_TEST_FORWARDING(src
->source_flags
) ? "Y" : "N",
2476 } /* scan group sources */
2477 } /* scan igmp groups */
2478 } /* scan igmp sockets */
2479 } /* scan interfaces */
2482 static void igmp_show_source_retransmission(struct vty
*vty
)
2484 struct listnode
*ifnode
;
2485 struct interface
*ifp
;
2487 vty_out(vty
, "Interface Address Group Source Counter%s", VTY_NEWLINE
);
2489 /* scan interfaces */
2490 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), ifnode
, ifp
)) {
2491 struct pim_interface
*pim_ifp
= ifp
->info
;
2492 struct listnode
*sock_node
;
2493 struct igmp_sock
*igmp
;
2498 /* scan igmp sockets */
2499 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
2500 char ifaddr_str
[INET_ADDRSTRLEN
];
2501 struct listnode
*grpnode
;
2502 struct igmp_group
*grp
;
2504 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
, sizeof(ifaddr_str
));
2506 /* scan igmp groups */
2507 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grpnode
, grp
)) {
2508 char group_str
[INET_ADDRSTRLEN
];
2509 struct listnode
*srcnode
;
2510 struct igmp_source
*src
;
2512 pim_inet4_dump("<group?>", grp
->group_addr
, group_str
, sizeof(group_str
));
2514 /* scan group sources */
2515 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
, srcnode
, src
)) {
2516 char source_str
[INET_ADDRSTRLEN
];
2518 pim_inet4_dump("<source?>", src
->source_addr
, source_str
, sizeof(source_str
));
2520 vty_out(vty
, "%-9s %-15s %-15s %-15s %7d%s",
2525 src
->source_query_retransmit_count
,
2528 } /* scan group sources */
2529 } /* scan igmp groups */
2530 } /* scan igmp sockets */
2531 } /* scan interfaces */
2534 static void clear_igmp_interfaces()
2536 struct listnode
*ifnode
;
2537 struct listnode
*ifnextnode
;
2538 struct interface
*ifp
;
2540 for (ALL_LIST_ELEMENTS (vrf_iflist (VRF_DEFAULT
), ifnode
, ifnextnode
, ifp
)) {
2541 pim_if_addr_del_all_igmp(ifp
);
2544 for (ALL_LIST_ELEMENTS (vrf_iflist (VRF_DEFAULT
), ifnode
, ifnextnode
, ifp
)) {
2545 pim_if_addr_add_all(ifp
);
2549 static void clear_pim_interfaces()
2551 struct listnode
*ifnode
;
2552 struct listnode
*ifnextnode
;
2553 struct interface
*ifp
;
2555 for (ALL_LIST_ELEMENTS (vrf_iflist (VRF_DEFAULT
), ifnode
, ifnextnode
, ifp
)) {
2557 pim_neighbor_delete_all(ifp
, "interface cleared");
2562 static void clear_interfaces()
2564 clear_igmp_interfaces();
2565 clear_pim_interfaces();
2568 DEFUN (clear_ip_interfaces
,
2569 clear_ip_interfaces_cmd
,
2570 "clear ip interfaces",
2573 "Reset interfaces\n")
2580 DEFUN (clear_ip_igmp_interfaces
,
2581 clear_ip_igmp_interfaces_cmd
,
2582 "clear ip igmp interfaces",
2586 "Reset IGMP interfaces\n")
2588 clear_igmp_interfaces();
2593 static void mroute_add_all()
2595 struct listnode
*node
;
2596 struct channel_oil
*c_oil
;
2598 for (ALL_LIST_ELEMENTS_RO(pim_channel_oil_list
, node
, c_oil
)) {
2599 if (pim_mroute_add(c_oil
, __PRETTY_FUNCTION__
)) {
2600 /* just log warning */
2601 char source_str
[INET_ADDRSTRLEN
];
2602 char group_str
[INET_ADDRSTRLEN
];
2603 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, source_str
, sizeof(source_str
));
2604 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, group_str
, sizeof(group_str
));
2605 zlog_warn("%s %s: (S,G)=(%s,%s) failure writing MFC",
2606 __FILE__
, __PRETTY_FUNCTION__
,
2607 source_str
, group_str
);
2612 static void mroute_del_all()
2614 struct listnode
*node
;
2615 struct channel_oil
*c_oil
;
2617 for (ALL_LIST_ELEMENTS_RO(pim_channel_oil_list
, node
, c_oil
)) {
2618 if (pim_mroute_del(c_oil
, __PRETTY_FUNCTION__
)) {
2619 /* just log warning */
2620 char source_str
[INET_ADDRSTRLEN
];
2621 char group_str
[INET_ADDRSTRLEN
];
2622 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, source_str
, sizeof(source_str
));
2623 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, group_str
, sizeof(group_str
));
2624 zlog_warn("%s %s: (S,G)=(%s,%s) failure clearing MFC",
2625 __FILE__
, __PRETTY_FUNCTION__
,
2626 source_str
, group_str
);
2631 DEFUN (clear_ip_mroute
,
2632 clear_ip_mroute_cmd
,
2636 "Reset multicast routes\n")
2644 DEFUN (clear_ip_pim_interfaces
,
2645 clear_ip_pim_interfaces_cmd
,
2646 "clear ip pim interfaces",
2650 "Reset PIM interfaces\n")
2652 clear_pim_interfaces();
2657 DEFUN (clear_ip_pim_interface_traffic
,
2658 clear_ip_pim_interface_traffic_cmd
,
2659 "clear ip pim interface traffic",
2662 "PIM clear commands\n"
2663 "Reset PIM interfaces\n"
2664 "Reset Protocol Packet counters\n")
2666 struct listnode
*ifnode
= NULL
;
2667 struct listnode
*ifnextnode
= NULL
;
2668 struct interface
*ifp
= NULL
;
2669 struct pim_interface
*pim_ifp
= NULL
;
2671 for (ALL_LIST_ELEMENTS (vrf_iflist (VRF_DEFAULT
), ifnode
, ifnextnode
, ifp
))
2673 pim_ifp
= ifp
->info
;
2678 pim_ifp
->pim_ifstat_hello_recv
= 0;
2679 pim_ifp
->pim_ifstat_hello_sent
= 0;
2680 pim_ifp
->pim_ifstat_join_recv
= 0;
2681 pim_ifp
->pim_ifstat_join_send
= 0;
2682 pim_ifp
->pim_ifstat_prune_recv
= 0;
2683 pim_ifp
->pim_ifstat_prune_send
= 0;
2684 pim_ifp
->pim_ifstat_reg_recv
= 0;
2685 pim_ifp
->pim_ifstat_reg_send
= 0;
2686 pim_ifp
->pim_ifstat_reg_stop_recv
= 0;
2687 pim_ifp
->pim_ifstat_reg_stop_send
= 0;
2688 pim_ifp
->pim_ifstat_assert_recv
= 0;
2689 pim_ifp
->pim_ifstat_assert_send
= 0;
2696 DEFUN (clear_ip_pim_oil
,
2697 clear_ip_pim_oil_cmd
,
2702 "Rescan PIM OIL (output interface list)\n")
2709 DEFUN (show_ip_igmp_interface
,
2710 show_ip_igmp_interface_cmd
,
2711 "show ip igmp interface [detail|WORD] [json]",
2715 "IGMP interface information\n"
2718 "JavaScript Object Notation\n")
2720 u_char uj
= use_json(argc
, argv
);
2723 if (argv_find(argv
, argc
, "detail", &idx
) ||
2724 argv_find(argv
, argc
, "WORD", &idx
))
2725 igmp_show_interfaces_single(vty
, argv
[idx
]->arg
, uj
);
2727 igmp_show_interfaces(vty
, uj
);
2732 DEFUN (show_ip_igmp_join
,
2733 show_ip_igmp_join_cmd
,
2734 "show ip igmp join",
2738 "IGMP static join information\n")
2740 igmp_show_interface_join(vty
);
2745 DEFUN (show_ip_igmp_groups
,
2746 show_ip_igmp_groups_cmd
,
2747 "show ip igmp groups [json]",
2752 "JavaScript Object Notation\n")
2754 u_char uj
= use_json(argc
, argv
);
2755 igmp_show_groups(vty
, uj
);
2760 DEFUN (show_ip_igmp_groups_retransmissions
,
2761 show_ip_igmp_groups_retransmissions_cmd
,
2762 "show ip igmp groups retransmissions",
2767 "IGMP group retransmissions\n")
2769 igmp_show_group_retransmission(vty
);
2774 DEFUN (show_ip_igmp_sources
,
2775 show_ip_igmp_sources_cmd
,
2776 "show ip igmp sources",
2782 igmp_show_sources(vty
);
2787 DEFUN (show_ip_igmp_sources_retransmissions
,
2788 show_ip_igmp_sources_retransmissions_cmd
,
2789 "show ip igmp sources retransmissions",
2794 "IGMP source retransmissions\n")
2796 igmp_show_source_retransmission(vty
);
2801 DEFUN (show_ip_pim_assert
,
2802 show_ip_pim_assert_cmd
,
2803 "show ip pim assert",
2807 "PIM interface assert\n")
2809 pim_show_assert(vty
);
2814 DEFUN (show_ip_pim_assert_internal
,
2815 show_ip_pim_assert_internal_cmd
,
2816 "show ip pim assert-internal",
2820 "PIM interface internal assert state\n")
2822 pim_show_assert_internal(vty
);
2827 DEFUN (show_ip_pim_assert_metric
,
2828 show_ip_pim_assert_metric_cmd
,
2829 "show ip pim assert-metric",
2833 "PIM interface assert metric\n")
2835 pim_show_assert_metric(vty
);
2840 DEFUN (show_ip_pim_assert_winner_metric
,
2841 show_ip_pim_assert_winner_metric_cmd
,
2842 "show ip pim assert-winner-metric",
2846 "PIM interface assert winner metric\n")
2848 pim_show_assert_winner_metric(vty
);
2853 DEFUN (show_ip_pim_interface
,
2854 show_ip_pim_interface_cmd
,
2855 "show ip pim interface [detail|WORD] [json]",
2859 "PIM interface information\n"
2862 "JavaScript Object Notation\n")
2864 u_char uj
= use_json(argc
, argv
);
2867 if (argv_find(argv
, argc
, "WORD", &idx
) ||
2868 argv_find(argv
, argc
, "detail", &idx
))
2869 pim_show_interfaces_single(vty
, argv
[idx
]->arg
, uj
);
2872 pim_show_interfaces(vty
, uj
);
2877 DEFUN (show_ip_pim_join
,
2878 show_ip_pim_join_cmd
,
2879 "show ip pim join [json]",
2883 "PIM interface join information\n"
2886 u_char uj
= use_json(argc
, argv
);
2887 pim_show_join(vty
, uj
);
2892 DEFUN (show_ip_pim_local_membership
,
2893 show_ip_pim_local_membership_cmd
,
2894 "show ip pim local-membership [json]",
2898 "PIM interface local-membership\n"
2901 u_char uj
= use_json(argc
, argv
);
2902 pim_show_membership(vty
, uj
);
2907 DEFUN (show_ip_pim_neighbor
,
2908 show_ip_pim_neighbor_cmd
,
2909 "show ip pim neighbor [detail|WORD] [json]",
2913 "PIM neighbor information\n"
2915 "Name of interface or neighbor\n"
2916 "JavaScript Object Notation\n")
2918 u_char uj
= use_json(argc
, argv
);
2921 if (argv_find(argv
, argc
, "detail", &idx
) ||
2922 argv_find(argv
, argc
, "WORD", &idx
))
2923 pim_show_neighbors_single(vty
, argv
[idx
]->arg
, uj
);
2925 pim_show_neighbors(vty
, uj
);
2930 DEFUN (show_ip_pim_secondary
,
2931 show_ip_pim_secondary_cmd
,
2932 "show ip pim secondary",
2936 "PIM neighbor addresses\n")
2938 pim_show_neighbors_secondary(vty
);
2943 DEFUN (show_ip_pim_state
,
2944 show_ip_pim_state_cmd
,
2945 "show ip pim state [A.B.C.D [A.B.C.D]] [json]",
2949 "PIM state information\n"
2950 "Unicast or Multicast address\n"
2951 "Multicast address\n"
2952 "JavaScript Object Notation\n")
2954 const char *src_or_group
= NULL
;
2955 const char *group
= NULL
;
2956 u_char uj
= use_json(argc
, argv
);
2962 src_or_group
= argv
[4]->arg
;
2963 group
= argv
[5]->arg
;
2966 src_or_group
= argv
[4]->arg
;
2968 pim_show_state(vty
, src_or_group
, group
, uj
);
2973 DEFUN (show_ip_pim_upstream
,
2974 show_ip_pim_upstream_cmd
,
2975 "show ip pim upstream [json]",
2979 "PIM upstream information\n"
2980 "JavaScript Object Notation\n")
2982 u_char uj
= use_json(argc
, argv
);
2983 pim_show_upstream(vty
, uj
);
2988 DEFUN (show_ip_pim_upstream_join_desired
,
2989 show_ip_pim_upstream_join_desired_cmd
,
2990 "show ip pim upstream-join-desired [json]",
2994 "PIM upstream join-desired\n"
2995 "JavaScript Object Notation\n")
2997 u_char uj
= use_json(argc
, argv
);
2998 pim_show_join_desired(vty
, uj
);
3003 DEFUN (show_ip_pim_upstream_rpf
,
3004 show_ip_pim_upstream_rpf_cmd
,
3005 "show ip pim upstream-rpf [json]",
3009 "PIM upstream source rpf\n"
3010 "JavaScript Object Notation\n")
3012 u_char uj
= use_json(argc
, argv
);
3013 pim_show_upstream_rpf(vty
, uj
);
3018 DEFUN (show_ip_pim_rp
,
3020 "show ip pim rp-info [json]",
3024 "PIM RP information\n"
3025 "JavaScript Object Notation\n")
3027 u_char uj
= use_json(argc
, argv
);
3028 pim_rp_show_information (vty
, uj
);
3033 DEFUN (show_ip_pim_rpf
,
3034 show_ip_pim_rpf_cmd
,
3035 "show ip pim rpf [json]",
3039 "PIM cached source rpf information\n"
3040 "JavaScript Object Notation\n")
3042 u_char uj
= use_json(argc
, argv
);
3043 pim_show_rpf(vty
, uj
);
3048 DEFUN (show_ip_pim_nexthop
,
3049 show_ip_pim_nexthop_cmd
,
3050 "show ip pim nexthop",
3054 "PIM cached nexthop rpf information\n")
3056 pim_show_nexthop (vty
);
3061 DEFUN (show_ip_pim_nexthop_lookup
,
3062 show_ip_pim_nexthop_lookup_cmd
,
3063 "show ip pim nexthop-lookup A.B.C.D A.B.C.D",
3067 "PIM cached nexthop rpf lookup\n"
3068 "Source/RP address\n"
3069 "Multicast Group address\n")
3071 struct pim_nexthop_cache pnc
;
3072 struct prefix nht_p
;
3074 struct in_addr src_addr
, grp_addr
;
3075 struct in_addr vif_source
;
3076 const char *addr_str
, *addr_str1
;
3078 struct pim_nexthop nexthop
;
3079 char nexthop_addr_str
[PREFIX_STRLEN
];
3080 char grp_str
[PREFIX_STRLEN
];
3082 addr_str
= argv
[4]->arg
;
3083 result
= inet_pton (AF_INET
, addr_str
, &src_addr
);
3086 vty_out (vty
, "Bad unicast address %s: errno=%d: %s%s",
3087 addr_str
, errno
, safe_strerror (errno
), VTY_NEWLINE
);
3091 if (pim_is_group_224_4 (src_addr
))
3093 vty_out (vty
, "Invalid argument. Expected Valid Source Address.%s", VTY_NEWLINE
);
3097 addr_str1
= argv
[5]->arg
;
3098 result
= inet_pton (AF_INET
, addr_str1
, &grp_addr
);
3101 vty_out (vty
, "Bad unicast address %s: errno=%d: %s%s",
3102 addr_str
, errno
, safe_strerror (errno
), VTY_NEWLINE
);
3106 if (!pim_is_group_224_4 (grp_addr
))
3108 vty_out (vty
, "Invalid argument. Expected Valid Multicast Group Address.%s", VTY_NEWLINE
);
3112 if (!pim_rp_set_upstream_addr (&vif_source
, src_addr
, grp_addr
))
3115 memset (&pnc
, 0, sizeof (struct pim_nexthop_cache
));
3116 nht_p
.family
= AF_INET
;
3117 nht_p
.prefixlen
= IPV4_MAX_BITLEN
;
3118 nht_p
.u
.prefix4
= vif_source
;
3119 grp
.family
= AF_INET
;
3120 grp
.prefixlen
= IPV4_MAX_BITLEN
;
3121 grp
.u
.prefix4
= grp_addr
;
3122 memset (&nexthop
, 0, sizeof (nexthop
));
3124 if ((pim_find_or_track_nexthop (&nht_p
, NULL
, NULL
, &pnc
)) == 1)
3126 //Compute PIM RPF using Cached nexthop
3127 pim_ecmp_nexthop_search (&pnc
, &nexthop
, &nht_p
, &grp
, 0);
3130 pim_ecmp_nexthop_lookup (&nexthop
, vif_source
, &nht_p
, &grp
, 0);
3132 pim_addr_dump ("<grp?>", &grp
, grp_str
, sizeof (grp_str
));
3133 pim_addr_dump ("<nexthop?>", &nexthop
.mrib_nexthop_addr
,
3134 nexthop_addr_str
, sizeof (nexthop_addr_str
));
3135 vty_out (vty
, "Group %s --- Nexthop %s Interface %s %s", grp_str
,
3136 nexthop_addr_str
, nexthop
.interface
->name
, VTY_NEWLINE
);
3141 DEFUN (show_ip_pim_interface_traffic
,
3142 show_ip_pim_interface_traffic_cmd
,
3143 "show ip pim interface traffic [WORD] [json]",
3147 "PIM interface information\n"
3148 "Protocol Packet counters\n"
3150 "JavaScript Object Notation\n")
3152 u_char uj
= use_json (argc
, argv
);
3155 if (argv_find(argv
, argc
, "WORD", &idx
))
3156 pim_show_interface_traffic_single (vty
, argv
[idx
]->arg
, uj
);
3158 pim_show_interface_traffic (vty
, uj
);
3163 static void show_multicast_interfaces(struct vty
*vty
)
3165 struct listnode
*node
;
3166 struct interface
*ifp
;
3168 vty_out(vty
, "%s", VTY_NEWLINE
);
3170 vty_out(vty
, "Interface Address ifi Vif PktsIn PktsOut BytesIn BytesOut%s",
3173 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), node
, ifp
)) {
3174 struct pim_interface
*pim_ifp
;
3175 struct in_addr ifaddr
;
3176 struct sioc_vif_req vreq
;
3178 pim_ifp
= ifp
->info
;
3183 memset(&vreq
, 0, sizeof(vreq
));
3184 vreq
.vifi
= pim_ifp
->mroute_vif_index
;
3186 if (ioctl(qpim_mroute_socket_fd
, SIOCGETVIFCNT
, &vreq
)) {
3187 zlog_warn("ioctl(SIOCGETVIFCNT=%lu) failure for interface %s vif_index=%d: errno=%d: %s%s",
3188 (unsigned long)SIOCGETVIFCNT
,
3190 pim_ifp
->mroute_vif_index
,
3192 safe_strerror(errno
),
3196 ifaddr
= pim_ifp
->primary_address
;
3198 vty_out(vty
, "%-9s %-15s %3d %3d %7lu %7lu %10lu %10lu%s",
3202 pim_ifp
->mroute_vif_index
,
3203 (unsigned long) vreq
.icount
,
3204 (unsigned long) vreq
.ocount
,
3205 (unsigned long) vreq
.ibytes
,
3206 (unsigned long) vreq
.obytes
,
3211 DEFUN (show_ip_multicast
,
3212 show_ip_multicast_cmd
,
3213 "show ip multicast",
3216 "Multicast global information\n")
3218 time_t now
= pim_time_monotonic_sec();
3222 vty_out(vty
, "Mroute socket descriptor: %d%s",
3223 qpim_mroute_socket_fd
,
3226 pim_time_uptime(uptime
, sizeof(uptime
), now
- qpim_mroute_socket_creation
);
3227 vty_out(vty
, "Mroute socket uptime: %s%s",
3231 vty_out(vty
, "%s", VTY_NEWLINE
);
3233 pim_zebra_zclient_update (vty
);
3234 pim_zlookup_show_ip_multicast (vty
);
3236 vty_out(vty
, "%s", VTY_NEWLINE
);
3237 vty_out(vty
, "Maximum highest VifIndex: %d%s",
3238 PIM_MAX_USABLE_VIFS
,
3241 vty_out (vty
, "%s", VTY_NEWLINE
);
3242 vty_out (vty
, "Upstream Join Timer: %d secs%s",
3243 qpim_t_periodic
, VTY_NEWLINE
);
3244 vty_out (vty
, "Join/Prune Holdtime: %d secs%s",
3245 PIM_JP_HOLDTIME
, VTY_NEWLINE
);
3246 vty_out (vty
, "PIM ECMP: %s%s",
3247 qpim_ecmp_enable
? "Enable" : "Disable", VTY_NEWLINE
);
3248 vty_out (vty
, "PIM ECMP Rebalance: %s%s",
3249 qpim_ecmp_rebalance_enable
? "Enable" : "Disable", VTY_NEWLINE
);
3251 vty_out (vty
, "%s", VTY_NEWLINE
);
3253 show_rpf_refresh_stats(vty
, now
, NULL
);
3255 vty_out(vty
, "%s", VTY_NEWLINE
);
3257 show_scan_oil_stats(vty
, now
);
3259 show_multicast_interfaces(vty
);
3264 static void show_mroute(struct vty
*vty
, u_char uj
)
3266 struct listnode
*node
;
3267 struct channel_oil
*c_oil
;
3268 struct static_route
*s_route
;
3270 json_object
*json
= NULL
;
3271 json_object
*json_group
= NULL
;
3272 json_object
*json_source
= NULL
;
3273 json_object
*json_oil
= NULL
;
3274 json_object
*json_ifp_out
= NULL
;
3277 char grp_str
[INET_ADDRSTRLEN
];
3278 char src_str
[INET_ADDRSTRLEN
];
3279 char in_ifname
[INTERFACE_NAMSIZ
+1];
3280 char out_ifname
[INTERFACE_NAMSIZ
+1];
3282 struct interface
*ifp_in
;
3286 json
= json_object_new_object();
3288 vty_out(vty
, "Source Group Proto Input Output TTL Uptime%s",
3292 now
= pim_time_monotonic_sec();
3294 /* print list of PIM and IGMP routes */
3295 for (ALL_LIST_ELEMENTS_RO(pim_channel_oil_list
, node
, c_oil
)) {
3298 if (!c_oil
->installed
&& !uj
)
3301 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, grp_str
, sizeof(grp_str
));
3302 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, src_str
, sizeof(src_str
));
3303 ifp_in
= pim_if_find_by_vif_index(c_oil
->oil
.mfcc_parent
);
3306 strcpy(in_ifname
, ifp_in
->name
);
3308 strcpy(in_ifname
, "<iif?>");
3312 /* Find the group, create it if it doesn't exist */
3313 json_object_object_get_ex(json
, grp_str
, &json_group
);
3316 json_group
= json_object_new_object();
3317 json_object_object_add(json
, grp_str
, json_group
);
3320 /* Find the source nested under the group, create it if it doesn't exist */
3321 json_object_object_get_ex(json_group
, src_str
, &json_source
);
3324 json_source
= json_object_new_object();
3325 json_object_object_add(json_group
, src_str
, json_source
);
3328 /* Find the inbound interface nested under the source, create it if it doesn't exist */
3329 json_object_int_add(json_source
, "installed", c_oil
->installed
);
3330 json_object_int_add(json_source
, "refCount", c_oil
->oil_ref_count
);
3331 json_object_int_add(json_source
, "oilSize", c_oil
->oil_size
);
3332 json_object_int_add(json_source
, "OilInheritedRescan", c_oil
->oil_inherited_rescan
);
3333 json_object_string_add(json_source
, "iif", in_ifname
);
3337 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
; ++oif_vif_index
) {
3338 struct interface
*ifp_out
;
3339 char oif_uptime
[10];
3342 ttl
= c_oil
->oil
.mfcc_ttls
[oif_vif_index
];
3346 ifp_out
= pim_if_find_by_vif_index(oif_vif_index
);
3347 pim_time_uptime(oif_uptime
, sizeof(oif_uptime
), now
- c_oil
->oif_creation
[oif_vif_index
]);
3351 strcpy(out_ifname
, ifp_out
->name
);
3353 strcpy(out_ifname
, "<oif?>");
3356 json_ifp_out
= json_object_new_object();
3357 json_object_string_add(json_ifp_out
, "source", src_str
);
3358 json_object_string_add(json_ifp_out
, "group", grp_str
);
3360 if (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_PIM
)
3361 json_object_boolean_true_add(json_ifp_out
, "protocolPim");
3363 if (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_IGMP
)
3364 json_object_boolean_true_add(json_ifp_out
, "protocolIgmp");
3366 if (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_SOURCE
)
3367 json_object_boolean_true_add(json_ifp_out
, "protocolSource");
3369 if (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_STAR
)
3370 json_object_boolean_true_add(json_ifp_out
, "protocolInherited");
3372 json_object_string_add(json_ifp_out
, "inboundInterface", in_ifname
);
3373 json_object_int_add(json_ifp_out
, "iVifI", c_oil
->oil
.mfcc_parent
);
3374 json_object_string_add(json_ifp_out
, "outboundInterface", out_ifname
);
3375 json_object_int_add(json_ifp_out
, "oVifI", oif_vif_index
);
3376 json_object_int_add(json_ifp_out
, "ttl", ttl
);
3377 json_object_string_add(json_ifp_out
, "upTime", oif_uptime
);
3379 json_oil
= json_object_new_object();
3380 json_object_object_add(json_source
, "oil", json_oil
);
3382 json_object_object_add(json_oil
, out_ifname
, json_ifp_out
);
3384 if (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_PIM
) {
3385 strcpy(proto
, "PIM");
3388 if (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_IGMP
) {
3389 strcpy(proto
, "IGMP");
3392 if (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_SOURCE
) {
3393 strcpy(proto
, "SRC");
3396 if (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_STAR
) {
3397 strcpy(proto
, "STAR");
3400 vty_out(vty
, "%-15s %-15s %-6s %-10s %-10s %-3d %8s%s",
3414 in_ifname
[0] = '\0';
3420 if (!uj
&& !found_oif
) {
3421 vty_out(vty
, "%-15s %-15s %-6s %-10s %-10s %-3d %8s%s",
3433 /* Print list of static routes */
3434 for (ALL_LIST_ELEMENTS_RO(qpim_static_route_list
, node
, s_route
)) {
3437 if (!s_route
->c_oil
.installed
)
3440 pim_inet4_dump("<group?>", s_route
->group
, grp_str
, sizeof(grp_str
));
3441 pim_inet4_dump("<source?>", s_route
->source
, src_str
, sizeof(src_str
));
3442 ifp_in
= pim_if_find_by_vif_index(s_route
->iif
);
3446 strcpy(in_ifname
, ifp_in
->name
);
3448 strcpy(in_ifname
, "<iif?>");
3452 /* Find the group, create it if it doesn't exist */
3453 json_object_object_get_ex(json
, grp_str
, &json_group
);
3456 json_group
= json_object_new_object();
3457 json_object_object_add(json
, grp_str
, json_group
);
3460 /* Find the source nested under the group, create it if it doesn't exist */
3461 json_object_object_get_ex(json_group
, src_str
, &json_source
);
3464 json_source
= json_object_new_object();
3465 json_object_object_add(json_group
, src_str
, json_source
);
3468 json_object_string_add(json_source
, "iif", in_ifname
);
3471 strcpy(proto
, "STATIC");
3474 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
; ++oif_vif_index
) {
3475 struct interface
*ifp_out
;
3476 char oif_uptime
[10];
3479 ttl
= s_route
->oif_ttls
[oif_vif_index
];
3483 ifp_out
= pim_if_find_by_vif_index(oif_vif_index
);
3484 pim_time_uptime(oif_uptime
, sizeof(oif_uptime
), now
- s_route
->c_oil
.oif_creation
[oif_vif_index
]);
3488 strcpy(out_ifname
, ifp_out
->name
);
3490 strcpy(out_ifname
, "<oif?>");
3493 json_ifp_out
= json_object_new_object();
3494 json_object_string_add(json_ifp_out
, "source", src_str
);
3495 json_object_string_add(json_ifp_out
, "group", grp_str
);
3496 json_object_boolean_true_add(json_ifp_out
, "protocolStatic");
3497 json_object_string_add(json_ifp_out
, "inboundInterface", in_ifname
);
3498 json_object_int_add(json_ifp_out
, "iVifI", c_oil
->oil
.mfcc_parent
);
3499 json_object_string_add(json_ifp_out
, "outboundInterface", out_ifname
);
3500 json_object_int_add(json_ifp_out
, "oVifI", oif_vif_index
);
3501 json_object_int_add(json_ifp_out
, "ttl", ttl
);
3502 json_object_string_add(json_ifp_out
, "upTime", oif_uptime
);
3504 json_oil
= json_object_new_object();
3505 json_object_object_add(json_source
, "oil", json_oil
);
3507 json_object_object_add(json_oil
, out_ifname
, json_ifp_out
);
3509 vty_out(vty
, "%-15s %-15s %-6s %-10s %-10s %-3d %8s%s",
3522 in_ifname
[0] = '\0';
3528 if (!uj
&& !found_oif
) {
3529 vty_out(vty
, "%-15s %-15s %-6s %-10s %-10s %-3d %8s%s",
3542 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
3543 json_object_free(json
);
3547 DEFUN (show_ip_mroute
,
3549 "show ip mroute [json]",
3555 u_char uj
= use_json(argc
, argv
);
3556 show_mroute(vty
, uj
);
3560 static void show_mroute_count(struct vty
*vty
)
3562 struct listnode
*node
;
3563 struct channel_oil
*c_oil
;
3564 struct static_route
*s_route
;
3566 vty_out(vty
, "%s", VTY_NEWLINE
);
3568 vty_out(vty
, "Source Group LastUsed Packets Bytes WrongIf %s",
3571 /* Print PIM and IGMP route counts */
3572 for (ALL_LIST_ELEMENTS_RO(pim_channel_oil_list
, node
, c_oil
)) {
3573 char group_str
[INET_ADDRSTRLEN
];
3574 char source_str
[INET_ADDRSTRLEN
];
3576 if (!c_oil
->installed
)
3579 pim_mroute_update_counters (c_oil
);
3581 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, group_str
, sizeof(group_str
));
3582 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, source_str
, sizeof(source_str
));
3584 vty_out(vty
, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld%s",
3587 c_oil
->cc
.lastused
/100,
3594 /* Print static route counts */
3595 for (ALL_LIST_ELEMENTS_RO(qpim_static_route_list
, node
, s_route
)) {
3596 char group_str
[INET_ADDRSTRLEN
];
3597 char source_str
[INET_ADDRSTRLEN
];
3599 if (!s_route
->c_oil
.installed
)
3602 pim_mroute_update_counters (&s_route
->c_oil
);
3604 pim_inet4_dump("<group?>", s_route
->c_oil
.oil
.mfcc_mcastgrp
, group_str
, sizeof(group_str
));
3605 pim_inet4_dump("<source?>", s_route
->c_oil
.oil
.mfcc_origin
, source_str
, sizeof(source_str
));
3607 vty_out(vty
, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld%s",
3610 s_route
->c_oil
.cc
.lastused
,
3611 s_route
->c_oil
.cc
.pktcnt
,
3612 s_route
->c_oil
.cc
.bytecnt
,
3613 s_route
->c_oil
.cc
.wrong_if
,
3618 DEFUN (show_ip_mroute_count
,
3619 show_ip_mroute_count_cmd
,
3620 "show ip mroute count",
3624 "Route and packet count data\n")
3626 show_mroute_count(vty
);
3632 "show ip rib A.B.C.D",
3636 "Unicast address\n")
3639 struct in_addr addr
;
3640 const char *addr_str
;
3641 struct pim_nexthop nexthop
;
3642 char nexthop_addr_str
[PREFIX_STRLEN
];
3645 memset (&nexthop
, 0, sizeof (nexthop
));
3646 addr_str
= argv
[idx_ipv4
]->arg
;
3647 result
= inet_pton(AF_INET
, addr_str
, &addr
);
3649 vty_out(vty
, "Bad unicast address %s: errno=%d: %s%s",
3650 addr_str
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
3654 if (pim_nexthop_lookup(&nexthop
, addr
, 0)) {
3655 vty_out(vty
, "Failure querying RIB nexthop for unicast address %s%s",
3656 addr_str
, VTY_NEWLINE
);
3660 vty_out(vty
, "Address NextHop Interface Metric Preference%s",
3663 pim_addr_dump("<nexthop?>", &nexthop
.mrib_nexthop_addr
,
3664 nexthop_addr_str
, sizeof(nexthop_addr_str
));
3666 vty_out(vty
, "%-15s %-15s %-9s %6d %10d%s",
3669 nexthop
.interface
? nexthop
.interface
->name
: "<ifname?>",
3670 nexthop
.mrib_route_metric
,
3671 nexthop
.mrib_metric_preference
,
3677 static void show_ssmpingd(struct vty
*vty
)
3679 struct listnode
*node
;
3680 struct ssmpingd_sock
*ss
;
3683 vty_out(vty
, "Source Socket Address Port Uptime Requests%s",
3686 if (!qpim_ssmpingd_list
)
3689 now
= pim_time_monotonic_sec();
3691 for (ALL_LIST_ELEMENTS_RO(qpim_ssmpingd_list
, node
, ss
)) {
3692 char source_str
[INET_ADDRSTRLEN
];
3694 struct sockaddr_in bind_addr
;
3695 socklen_t len
= sizeof(bind_addr
);
3696 char bind_addr_str
[INET_ADDRSTRLEN
];
3698 pim_inet4_dump("<src?>", ss
->source_addr
, source_str
, sizeof(source_str
));
3700 if (pim_socket_getsockname(ss
->sock_fd
, (struct sockaddr
*) &bind_addr
, &len
)) {
3701 vty_out(vty
, "%% Failure reading socket name for ssmpingd source %s on fd=%d%s",
3702 source_str
, ss
->sock_fd
, VTY_NEWLINE
);
3705 pim_inet4_dump("<addr?>", bind_addr
.sin_addr
, bind_addr_str
, sizeof(bind_addr_str
));
3706 pim_time_uptime(ss_uptime
, sizeof(ss_uptime
), now
- ss
->creation
);
3708 vty_out(vty
, "%-15s %6d %-15s %5d %8s %8lld%s",
3712 ntohs(bind_addr
.sin_port
),
3714 (long long)ss
->requests
,
3719 DEFUN (show_ip_ssmpingd
,
3720 show_ip_ssmpingd_cmd
,
3731 pim_rp_cmd_worker (struct vty
*vty
, const char *rp
, const char *group
, const char *plist
)
3735 result
= pim_rp_new (rp
, group
, plist
);
3737 if (result
== PIM_MALLOC_FAIL
)
3739 vty_out (vty
, "%% Out of memory%s", VTY_NEWLINE
);
3743 if (result
== PIM_GROUP_BAD_ADDRESS
)
3745 vty_out (vty
, "%% Bad group address specified: %s%s", group
, VTY_NEWLINE
);
3749 if (result
== PIM_RP_BAD_ADDRESS
)
3751 vty_out (vty
, "%% Bad RP address specified: %s%s", rp
, VTY_NEWLINE
);
3755 if (result
== PIM_RP_NO_PATH
)
3757 vty_out (vty
, "%% No Path to RP address specified: %s%s", rp
, VTY_NEWLINE
);
3761 if (result
== PIM_GROUP_OVERLAP
)
3763 vty_out (vty
, "%% Group range specified cannot overlap%s", VTY_NEWLINE
);
3767 if (result
== PIM_GROUP_PFXLIST_OVERLAP
)
3769 vty_out (vty
, "%% This group is already covered by a RP prefix-list%s", VTY_NEWLINE
);
3773 if (result
== PIM_RP_PFXLIST_IN_USE
)
3775 vty_out (vty
, "%% The same prefix-list cannot be applied to multiple RPs%s", VTY_NEWLINE
);
3782 DEFUN (ip_pim_spt_switchover_infinity
,
3783 ip_pim_spt_switchover_infinity_cmd
,
3784 "ip pim spt-switchover infinity-and-beyond",
3788 "Never switch to SPT Tree\n")
3790 pimg
->spt_switchover
= PIM_SPT_INFINITY
;
3792 pim_upstream_remove_lhr_star_pimreg();
3796 DEFUN (no_ip_pim_spt_switchover_infinity
,
3797 no_ip_pim_spt_switchover_infinity_cmd
,
3798 "no ip pim spt-switchover infinity-and-beyond",
3803 "Never switch to SPT Tree\n")
3805 pimg
->spt_switchover
= PIM_SPT_IMMEDIATE
;
3807 pim_upstream_add_lhr_star_pimreg();
3811 DEFUN (ip_pim_joinprune_time
,
3812 ip_pim_joinprune_time_cmd
,
3813 "ip pim join-prune-interval <60-600>",
3815 "pim multicast routing\n"
3816 "Join Prune Send Interval\n"
3819 qpim_t_periodic
= atoi(argv
[3]->arg
);
3823 DEFUN (no_ip_pim_joinprune_time
,
3824 no_ip_pim_joinprune_time_cmd
,
3825 "no ip pim join-prune-interval <60-600>",
3828 "pim multicast routing\n"
3829 "Join Prune Send Interval\n"
3832 qpim_t_periodic
= PIM_DEFAULT_T_PERIODIC
;
3836 DEFUN (ip_pim_register_suppress
,
3837 ip_pim_register_suppress_cmd
,
3838 "ip pim register-suppress-time <5-60000>",
3840 "pim multicast routing\n"
3841 "Register Suppress Timer\n"
3844 qpim_keep_alive_time
= atoi (argv
[3]->arg
);
3848 DEFUN (no_ip_pim_register_suppress
,
3849 no_ip_pim_register_suppress_cmd
,
3850 "no ip pim register-suppress-time <5-60000>",
3853 "pim multicast routing\n"
3854 "Register Suppress Timer\n"
3857 qpim_register_suppress_time
= PIM_REGISTER_SUPPRESSION_TIME_DEFAULT
;
3861 DEFUN (ip_pim_keep_alive
,
3862 ip_pim_keep_alive_cmd
,
3863 "ip pim keep-alive-timer <31-60000>",
3865 "pim multicast routing\n"
3866 "Keep alive Timer\n"
3869 qpim_rp_keep_alive_time
= atoi (argv
[4]->arg
);
3873 DEFUN (no_ip_pim_keep_alive
,
3874 no_ip_pim_keep_alive_cmd
,
3875 "no ip pim keep-alive-timer <31-60000>",
3878 "pim multicast routing\n"
3879 "Keep alive Timer\n"
3882 qpim_keep_alive_time
= PIM_KEEPALIVE_PERIOD
;
3886 DEFUN (ip_pim_packets
,
3888 "ip pim packets <1-100>",
3890 "pim multicast routing\n"
3891 "packets to process at one time per fd\n"
3892 "Number of packets\n")
3894 qpim_packet_process
= atoi (argv
[3]->arg
);
3898 DEFUN (no_ip_pim_packets
,
3899 no_ip_pim_packets_cmd
,
3900 "no ip pim packets <1-100>",
3903 "pim multicast routing\n"
3904 "packets to process at one time per fd\n"
3905 "Number of packets\n")
3907 qpim_packet_process
= PIM_DEFAULT_PACKET_PROCESS
;
3911 DEFUN (ip_pim_v6_secondary
,
3912 ip_pim_v6_secondary_cmd
,
3913 "ip pim send-v6-secondary",
3915 "pim multicast routing\n"
3916 "Send v6 secondary addresses\n")
3918 pimg
->send_v6_secondary
= 1;
3923 DEFUN (no_ip_pim_v6_secondary
,
3924 no_ip_pim_v6_secondary_cmd
,
3925 "no ip pim send-v6-secondary",
3928 "pim multicast routing\n"
3929 "Send v6 secondary addresses\n")
3931 pimg
->send_v6_secondary
= 0;
3938 "ip pim rp A.B.C.D [A.B.C.D/M]",
3940 "pim multicast routing\n"
3942 "ip address of RP\n"
3943 "Group Address range to cover\n")
3947 if (argc
== (idx_ipv4
+ 1))
3948 return pim_rp_cmd_worker (vty
, argv
[idx_ipv4
]->arg
, argv
[idx_ipv4
+ 1]->arg
, NULL
);
3950 return pim_rp_cmd_worker (vty
, argv
[idx_ipv4
]->arg
, NULL
, NULL
);
3953 DEFUN (ip_pim_rp_prefix_list
,
3954 ip_pim_rp_prefix_list_cmd
,
3955 "ip pim rp A.B.C.D prefix-list WORD",
3957 "pim multicast routing\n"
3959 "ip address of RP\n"
3960 "group prefix-list filter\n"
3961 "Name of a prefix-list\n")
3963 return pim_rp_cmd_worker (vty
, argv
[3]->arg
, NULL
, argv
[5]->arg
);
3967 pim_no_rp_cmd_worker (struct vty
*vty
, const char *rp
, const char *group
,
3970 int result
= pim_rp_del (rp
, group
, plist
);
3972 if (result
== PIM_GROUP_BAD_ADDRESS
)
3974 vty_out (vty
, "%% Bad group address specified: %s%s", group
, VTY_NEWLINE
);
3978 if (result
== PIM_RP_BAD_ADDRESS
)
3980 vty_out (vty
, "%% Bad RP address specified: %s%s", rp
, VTY_NEWLINE
);
3984 if (result
== PIM_RP_NOT_FOUND
)
3986 vty_out (vty
, "%% Unable to find specified RP%s", VTY_NEWLINE
);
3993 DEFUN (no_ip_pim_rp
,
3995 "no ip pim rp A.B.C.D [A.B.C.D/M]",
3998 "pim multicast routing\n"
4000 "ip address of RP\n"
4001 "Group Address range to cover\n")
4003 int idx_ipv4
= 4, idx_group
= 0;
4005 if (argv_find (argv
, argc
, "A.B.C.D/M", &idx_group
))
4006 return pim_no_rp_cmd_worker (vty
, argv
[idx_ipv4
]->arg
, argv
[idx_group
]->arg
, NULL
);
4008 return pim_no_rp_cmd_worker (vty
, argv
[idx_ipv4
]->arg
, NULL
, NULL
);
4011 DEFUN (no_ip_pim_rp_prefix_list
,
4012 no_ip_pim_rp_prefix_list_cmd
,
4013 "no ip pim rp A.B.C.D prefix-list WORD",
4016 "pim multicast routing\n"
4018 "ip address of RP\n"
4019 "group prefix-list filter\n"
4020 "Name of a prefix-list\n")
4022 return pim_no_rp_cmd_worker (vty
, argv
[4]->arg
, NULL
, argv
[6]->arg
);
4026 pim_ssm_cmd_worker (struct vty
*vty
, const char *plist
)
4028 int result
= pim_ssm_range_set (VRF_DEFAULT
, plist
);
4030 if (result
== PIM_SSM_ERR_NONE
)
4035 case PIM_SSM_ERR_NO_VRF
:
4036 vty_out (vty
, "%% VRF doesn't exist%s", VTY_NEWLINE
);
4038 case PIM_SSM_ERR_DUP
:
4039 vty_out (vty
, "%% duplicate config%s", VTY_NEWLINE
);
4042 vty_out (vty
, "%% ssm range config failed%s", VTY_NEWLINE
);
4048 DEFUN (ip_pim_ssm_prefix_list
,
4049 ip_pim_ssm_prefix_list_cmd
,
4050 "ip pim ssm prefix-list WORD",
4052 "pim multicast routing\n"
4053 "Source Specific Multicast\n"
4054 "group range prefix-list filter\n"
4055 "Name of a prefix-list\n")
4057 return pim_ssm_cmd_worker (vty
, argv
[0]->arg
);
4060 DEFUN (no_ip_pim_ssm_prefix_list
,
4061 no_ip_pim_ssm_prefix_list_cmd
,
4062 "no ip pim ssm prefix-list",
4065 "pim multicast routing\n"
4066 "Source Specific Multicast\n"
4067 "group range prefix-list filter\n")
4069 return pim_ssm_cmd_worker (vty
, NULL
);
4072 DEFUN (no_ip_pim_ssm_prefix_list_name
,
4073 no_ip_pim_ssm_prefix_list_name_cmd
,
4074 "no ip pim ssm prefix-list WORD",
4077 "pim multicast routing\n"
4078 "Source Specific Multicast\n"
4079 "group range prefix-list filter\n"
4080 "Name of a prefix-list\n")
4082 struct pim_ssm
*ssm
= pimg
->ssm_info
;
4084 if (ssm
->plist_name
&& !strcmp(ssm
->plist_name
, argv
[0]->arg
))
4085 return pim_ssm_cmd_worker (vty
, NULL
);
4087 vty_out (vty
, "%% pim ssm prefix-list %s doesn't exist%s",
4088 argv
[0]->arg
, VTY_NEWLINE
);
4094 ip_pim_ssm_show_group_range(struct vty
*vty
, u_char uj
)
4096 struct pim_ssm
*ssm
= pimg
->ssm_info
;
4097 const char *range_str
= ssm
->plist_name
?ssm
->plist_name
:PIM_SSM_STANDARD_RANGE
;
4102 json
= json_object_new_object();
4103 json_object_string_add(json
, "ssmGroups", range_str
);
4104 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
4105 json_object_free(json
);
4108 vty_out(vty
, "SSM group range : %s%s", range_str
, VTY_NEWLINE
);
4111 DEFUN (show_ip_pim_ssm_range
,
4112 show_ip_pim_ssm_range_cmd
,
4113 "show ip pim group-type [json]",
4118 "JavaScript Object Notation\n")
4120 u_char uj
= use_json(argc
, argv
);
4121 ip_pim_ssm_show_group_range(vty
, uj
);
4127 ip_pim_ssm_show_group_type(struct vty
*vty
, u_char uj
, const char *group
)
4129 struct in_addr group_addr
;
4130 const char *type_str
;
4133 result
= inet_pton(AF_INET
, group
, &group_addr
);
4135 type_str
= "invalid";
4138 if (pim_is_group_224_4 (group_addr
))
4139 type_str
= pim_is_grp_ssm (group_addr
)?"SSM":"ASM";
4141 type_str
= "not-multicast";
4147 json
= json_object_new_object();
4148 json_object_string_add(json
, "groupType", type_str
);
4149 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
4150 json_object_free(json
);
4153 vty_out(vty
, "Group type : %s%s", type_str
, VTY_NEWLINE
);
4156 DEFUN (show_ip_pim_group_type
,
4157 show_ip_pim_group_type_cmd
,
4158 "show ip pim group-type A.B.C.D [json]",
4162 "multicast group type\n"
4164 "JavaScript Object Notation\n")
4166 u_char uj
= use_json(argc
, argv
);
4167 ip_pim_ssm_show_group_type(vty
, uj
, argv
[0]->arg
);
4172 DEFUN_HIDDEN (ip_multicast_routing
,
4173 ip_multicast_routing_cmd
,
4174 "ip multicast-routing",
4176 "Enable IP multicast forwarding\n")
4181 DEFUN_HIDDEN (no_ip_multicast_routing
,
4182 no_ip_multicast_routing_cmd
,
4183 "no ip multicast-routing",
4186 "Global IP configuration subcommands\n"
4187 "Enable IP multicast forwarding\n")
4189 vty_out (vty
, "Command is Disabled and will be removed in a future version%s", VTY_NEWLINE
);
4195 "ip ssmpingd [A.B.C.D]",
4202 struct in_addr source_addr
;
4203 const char *source_str
= (argc
== idx_ipv4
) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
4205 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
4207 vty_out(vty
, "%% Bad source address %s: errno=%d: %s%s",
4208 source_str
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
4212 result
= pim_ssmpingd_start(source_addr
);
4214 vty_out(vty
, "%% Failure starting ssmpingd for source %s: %d%s",
4215 source_str
, result
, VTY_NEWLINE
);
4222 DEFUN (no_ip_ssmpingd
,
4224 "no ip ssmpingd [A.B.C.D]",
4232 struct in_addr source_addr
;
4233 const char *source_str
= (argc
== idx_ipv4
) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
4235 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
4237 vty_out(vty
, "%% Bad source address %s: errno=%d: %s%s",
4238 source_str
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
4242 result
= pim_ssmpingd_stop(source_addr
);
4244 vty_out(vty
, "%% Failure stopping ssmpingd for source %s: %d%s",
4245 source_str
, result
, VTY_NEWLINE
);
4256 "pim multicast routing\n"
4257 "Enable PIM ECMP \n")
4259 qpim_ecmp_enable
= 1;
4264 DEFUN (no_ip_pim_ecmp
,
4269 "pim multicast routing\n"
4270 "Disable PIM ECMP \n")
4272 qpim_ecmp_enable
= 0;
4277 DEFUN (ip_pim_ecmp_rebalance
,
4278 ip_pim_ecmp_rebalance_cmd
,
4279 "ip pim ecmp rebalance",
4281 "pim multicast routing\n"
4282 "Enable PIM ECMP \n"
4283 "Enable PIM ECMP Rebalance\n")
4285 qpim_ecmp_rebalance_enable
= 1;
4290 DEFUN (no_ip_pim_ecmp_rebalance
,
4291 no_ip_pim_ecmp_rebalance_cmd
,
4292 "no ip pim ecmp rebalance",
4295 "pim multicast routing\n"
4296 "Disable PIM ECMP \n"
4297 "Disable PIM ECMP Rebalance\n")
4299 qpim_ecmp_rebalance_enable
= 0;
4305 pim_cmd_igmp_start (struct vty
*vty
, struct interface
*ifp
)
4307 struct pim_interface
*pim_ifp
;
4309 pim_ifp
= ifp
->info
;
4312 pim_ifp
= pim_if_new(ifp
, 1 /* igmp=true */, 0 /* pim=false */);
4314 vty_out(vty
, "Could not enable IGMP on interface %s%s",
4315 ifp
->name
, VTY_NEWLINE
);
4320 PIM_IF_DO_IGMP(pim_ifp
->options
);
4323 pim_if_addr_add_all(ifp
);
4324 pim_if_membership_refresh(ifp
);
4329 DEFUN (interface_ip_igmp
,
4330 interface_ip_igmp_cmd
,
4335 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4337 return pim_cmd_igmp_start(vty
, ifp
);
4340 DEFUN (interface_no_ip_igmp
,
4341 interface_no_ip_igmp_cmd
,
4347 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4348 struct pim_interface
*pim_ifp
;
4350 pim_ifp
= ifp
->info
;
4354 PIM_IF_DONT_IGMP(pim_ifp
->options
);
4356 pim_if_membership_clear(ifp
);
4358 pim_if_addr_del_all_igmp(ifp
);
4360 if (!PIM_IF_TEST_PIM(pim_ifp
->options
)) {
4367 DEFUN (interface_ip_igmp_join
,
4368 interface_ip_igmp_join_cmd
,
4369 "ip igmp join A.B.C.D A.B.C.D",
4372 "IGMP join multicast group\n"
4373 "Multicast group address\n"
4376 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4379 const char *group_str
;
4380 const char *source_str
;
4381 struct in_addr group_addr
;
4382 struct in_addr source_addr
;
4386 group_str
= argv
[idx_ipv4
]->arg
;
4387 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
4389 vty_out(vty
, "Bad group address %s: errno=%d: %s%s",
4390 group_str
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
4394 /* Source address */
4395 source_str
= argv
[idx_ipv4_2
]->arg
;
4396 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
4398 vty_out(vty
, "Bad source address %s: errno=%d: %s%s",
4399 source_str
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
4403 result
= pim_if_igmp_join_add(ifp
, group_addr
, source_addr
);
4405 vty_out(vty
, "%% Failure joining IGMP group %s source %s on interface %s: %d%s",
4406 group_str
, source_str
, ifp
->name
, result
, VTY_NEWLINE
);
4413 DEFUN (interface_no_ip_igmp_join
,
4414 interface_no_ip_igmp_join_cmd
,
4415 "no ip igmp join A.B.C.D A.B.C.D",
4419 "IGMP join multicast group\n"
4420 "Multicast group address\n"
4423 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4426 const char *group_str
;
4427 const char *source_str
;
4428 struct in_addr group_addr
;
4429 struct in_addr source_addr
;
4433 group_str
= argv
[idx_ipv4
]->arg
;
4434 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
4436 vty_out(vty
, "Bad group address %s: errno=%d: %s%s",
4437 group_str
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
4441 /* Source address */
4442 source_str
= argv
[idx_ipv4_2
]->arg
;
4443 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
4445 vty_out(vty
, "Bad source address %s: errno=%d: %s%s",
4446 source_str
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
4450 result
= pim_if_igmp_join_del(ifp
, group_addr
, source_addr
);
4452 vty_out(vty
, "%% Failure leaving IGMP group %s source %s on interface %s: %d%s",
4453 group_str
, source_str
, ifp
->name
, result
, VTY_NEWLINE
);
4461 CLI reconfiguration affects the interface level (struct pim_interface).
4462 This function propagates the reconfiguration to every active socket
4465 static void igmp_sock_query_interval_reconfig(struct igmp_sock
*igmp
)
4467 struct interface
*ifp
;
4468 struct pim_interface
*pim_ifp
;
4472 /* other querier present? */
4474 if (igmp
->t_other_querier_timer
)
4477 /* this is the querier */
4479 zassert(igmp
->interface
);
4480 zassert(igmp
->interface
->info
);
4482 ifp
= igmp
->interface
;
4483 pim_ifp
= ifp
->info
;
4485 if (PIM_DEBUG_IGMP_TRACE
) {
4486 char ifaddr_str
[INET_ADDRSTRLEN
];
4487 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
, sizeof(ifaddr_str
));
4488 zlog_debug("%s: Querier %s on %s reconfig query_interval=%d",
4489 __PRETTY_FUNCTION__
,
4492 pim_ifp
->igmp_default_query_interval
);
4496 igmp_startup_mode_on() will reset QQI:
4498 igmp->querier_query_interval = pim_ifp->igmp_default_query_interval;
4500 igmp_startup_mode_on(igmp
);
4503 static void igmp_sock_query_reschedule(struct igmp_sock
*igmp
)
4505 if (igmp
->t_igmp_query_timer
) {
4506 /* other querier present */
4507 zassert(igmp
->t_igmp_query_timer
);
4508 zassert(!igmp
->t_other_querier_timer
);
4510 pim_igmp_general_query_off(igmp
);
4511 pim_igmp_general_query_on(igmp
);
4513 zassert(igmp
->t_igmp_query_timer
);
4514 zassert(!igmp
->t_other_querier_timer
);
4517 /* this is the querier */
4519 zassert(!igmp
->t_igmp_query_timer
);
4520 zassert(igmp
->t_other_querier_timer
);
4522 pim_igmp_other_querier_timer_off(igmp
);
4523 pim_igmp_other_querier_timer_on(igmp
);
4525 zassert(!igmp
->t_igmp_query_timer
);
4526 zassert(igmp
->t_other_querier_timer
);
4530 static void change_query_interval(struct pim_interface
*pim_ifp
,
4533 struct listnode
*sock_node
;
4534 struct igmp_sock
*igmp
;
4536 pim_ifp
->igmp_default_query_interval
= query_interval
;
4538 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
4539 igmp_sock_query_interval_reconfig(igmp
);
4540 igmp_sock_query_reschedule(igmp
);
4544 static void change_query_max_response_time(struct pim_interface
*pim_ifp
,
4545 int query_max_response_time_dsec
)
4547 struct listnode
*sock_node
;
4548 struct igmp_sock
*igmp
;
4550 pim_ifp
->igmp_query_max_response_time_dsec
= query_max_response_time_dsec
;
4553 Below we modify socket/group/source timers in order to quickly
4554 reflect the change. Otherwise, those timers would eventually catch
4558 /* scan all sockets */
4559 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
4560 struct listnode
*grp_node
;
4561 struct igmp_group
*grp
;
4563 /* reschedule socket general query */
4564 igmp_sock_query_reschedule(igmp
);
4566 /* scan socket groups */
4567 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grp_node
, grp
)) {
4568 struct listnode
*src_node
;
4569 struct igmp_source
*src
;
4571 /* reset group timers for groups in EXCLUDE mode */
4572 if (grp
->group_filtermode_isexcl
) {
4573 igmp_group_reset_gmi(grp
);
4576 /* scan group sources */
4577 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
, src_node
, src
)) {
4579 /* reset source timers for sources with running timers */
4580 if (src
->t_source_timer
) {
4581 igmp_source_reset_gmi(igmp
, grp
, src
);
4588 #define IGMP_QUERY_INTERVAL_MIN (1)
4589 #define IGMP_QUERY_INTERVAL_MAX (1800)
4591 DEFUN (interface_ip_igmp_query_interval
,
4592 interface_ip_igmp_query_interval_cmd
,
4593 "ip igmp query-interval (1-1800)",
4596 IFACE_IGMP_QUERY_INTERVAL_STR
4597 "Query interval in seconds\n")
4599 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4600 struct pim_interface
*pim_ifp
;
4602 int query_interval_dsec
;
4605 pim_ifp
= ifp
->info
;
4608 ret
= pim_cmd_igmp_start(vty
, ifp
);
4609 if (ret
!= CMD_SUCCESS
)
4611 pim_ifp
= ifp
->info
;
4614 query_interval
= atoi(argv
[3]->arg
);
4615 query_interval_dsec
= 10 * query_interval
;
4618 It seems we don't need to check bounds since command.c does it
4619 already, but we verify them anyway for extra safety.
4621 if (query_interval
< IGMP_QUERY_INTERVAL_MIN
) {
4622 vty_out(vty
, "General query interval %d lower than minimum %d%s",
4624 IGMP_QUERY_INTERVAL_MIN
,
4628 if (query_interval
> IGMP_QUERY_INTERVAL_MAX
) {
4629 vty_out(vty
, "General query interval %d higher than maximum %d%s",
4631 IGMP_QUERY_INTERVAL_MAX
,
4636 if (query_interval_dsec
<= pim_ifp
->igmp_query_max_response_time_dsec
) {
4638 "Can't set general query interval %d dsec <= query max response time %d dsec.%s",
4639 query_interval_dsec
, pim_ifp
->igmp_query_max_response_time_dsec
,
4644 change_query_interval(pim_ifp
, query_interval
);
4649 DEFUN (interface_no_ip_igmp_query_interval
,
4650 interface_no_ip_igmp_query_interval_cmd
,
4651 "no ip igmp query-interval",
4655 IFACE_IGMP_QUERY_INTERVAL_STR
)
4657 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4658 struct pim_interface
*pim_ifp
;
4659 int default_query_interval_dsec
;
4661 pim_ifp
= ifp
->info
;
4666 default_query_interval_dsec
= IGMP_GENERAL_QUERY_INTERVAL
* 10;
4668 if (default_query_interval_dsec
<= pim_ifp
->igmp_query_max_response_time_dsec
) {
4670 "Can't set default general query interval %d dsec <= query max response time %d dsec.%s",
4671 default_query_interval_dsec
, pim_ifp
->igmp_query_max_response_time_dsec
,
4676 change_query_interval(pim_ifp
, IGMP_GENERAL_QUERY_INTERVAL
);
4681 DEFUN (interface_ip_igmp_version
,
4682 interface_ip_igmp_version_cmd
,
4683 "ip igmp version (2-3)",
4687 "IGMP version number\n")
4689 VTY_DECLVAR_CONTEXT(interface
,ifp
);
4690 struct pim_interface
*pim_ifp
;
4694 pim_ifp
= ifp
->info
;
4697 ret
= pim_cmd_igmp_start(vty
, ifp
);
4698 if (ret
!= CMD_SUCCESS
)
4700 pim_ifp
= ifp
->info
;
4703 igmp_version
= atoi(argv
[3]->arg
);
4704 pim_ifp
->igmp_version
= igmp_version
;
4709 DEFUN (interface_no_ip_igmp_version
,
4710 interface_no_ip_igmp_version_cmd
,
4711 "no ip igmp version (2-3)",
4716 "IGMP version number\n")
4718 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4719 struct pim_interface
*pim_ifp
;
4721 pim_ifp
= ifp
->info
;
4726 pim_ifp
->igmp_version
= IGMP_DEFAULT_VERSION
;
4731 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
4732 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
4734 DEFUN (interface_ip_igmp_query_max_response_time
,
4735 interface_ip_igmp_query_max_response_time_cmd
,
4736 "ip igmp query-max-response-time (10-250)",
4739 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
4740 "Query response value in deci-seconds\n")
4742 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4743 struct pim_interface
*pim_ifp
;
4744 int query_max_response_time
;
4747 pim_ifp
= ifp
->info
;
4750 ret
= pim_cmd_igmp_start(vty
, ifp
);
4751 if (ret
!= CMD_SUCCESS
)
4753 pim_ifp
= ifp
->info
;
4756 query_max_response_time
= atoi(argv
[3]->arg
);
4758 if (query_max_response_time
>= pim_ifp
->igmp_default_query_interval
* 10) {
4760 "Can't set query max response time %d sec >= general query interval %d sec%s",
4761 query_max_response_time
, pim_ifp
->igmp_default_query_interval
,
4766 change_query_max_response_time(pim_ifp
, query_max_response_time
);
4771 DEFUN (interface_no_ip_igmp_query_max_response_time
,
4772 interface_no_ip_igmp_query_max_response_time_cmd
,
4773 "no ip igmp query-max-response-time (10-250)",
4777 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
4778 "Time for response in deci-seconds\n")
4780 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4781 struct pim_interface
*pim_ifp
;
4783 pim_ifp
= ifp
->info
;
4788 change_query_max_response_time(pim_ifp
, IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
4793 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
4794 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
4796 DEFUN_HIDDEN (interface_ip_igmp_query_max_response_time_dsec
,
4797 interface_ip_igmp_query_max_response_time_dsec_cmd
,
4798 "ip igmp query-max-response-time-dsec (10-250)",
4801 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
4802 "Query response value in deciseconds\n")
4804 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4805 struct pim_interface
*pim_ifp
;
4806 int query_max_response_time_dsec
;
4807 int default_query_interval_dsec
;
4810 pim_ifp
= ifp
->info
;
4813 ret
= pim_cmd_igmp_start(vty
, ifp
);
4814 if (ret
!= CMD_SUCCESS
)
4816 pim_ifp
= ifp
->info
;
4819 query_max_response_time_dsec
= atoi(argv
[4]->arg
);
4821 default_query_interval_dsec
= 10 * pim_ifp
->igmp_default_query_interval
;
4823 if (query_max_response_time_dsec
>= default_query_interval_dsec
) {
4825 "Can't set query max response time %d dsec >= general query interval %d dsec%s",
4826 query_max_response_time_dsec
, default_query_interval_dsec
,
4831 change_query_max_response_time(pim_ifp
, query_max_response_time_dsec
);
4836 DEFUN_HIDDEN (interface_no_ip_igmp_query_max_response_time_dsec
,
4837 interface_no_ip_igmp_query_max_response_time_dsec_cmd
,
4838 "no ip igmp query-max-response-time-dsec",
4842 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
)
4844 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4845 struct pim_interface
*pim_ifp
;
4847 pim_ifp
= ifp
->info
;
4852 change_query_max_response_time(pim_ifp
, IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
4857 DEFUN (interface_ip_pim_drprio
,
4858 interface_ip_pim_drprio_cmd
,
4859 "ip pim drpriority (1-4294967295)",
4862 "Set the Designated Router Election Priority\n"
4863 "Value of the new DR Priority\n")
4865 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4867 struct pim_interface
*pim_ifp
;
4868 uint32_t old_dr_prio
;
4870 pim_ifp
= ifp
->info
;
4873 vty_out(vty
, "Please enable PIM on interface, first%s", VTY_NEWLINE
);
4877 old_dr_prio
= pim_ifp
->pim_dr_priority
;
4879 pim_ifp
->pim_dr_priority
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
4881 if (old_dr_prio
!= pim_ifp
->pim_dr_priority
) {
4882 if (pim_if_dr_election(ifp
))
4883 pim_hello_restart_now(ifp
);
4889 DEFUN (interface_no_ip_pim_drprio
,
4890 interface_no_ip_pim_drprio_cmd
,
4891 "no ip pim drpriority [(1-4294967295)]",
4895 "Revert the Designated Router Priority to default\n"
4896 "Old Value of the Priority\n")
4898 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4899 struct pim_interface
*pim_ifp
;
4901 pim_ifp
= ifp
->info
;
4904 vty_out(vty
, "Pim not enabled on this interface%s", VTY_NEWLINE
);
4908 if (pim_ifp
->pim_dr_priority
!= PIM_DEFAULT_DR_PRIORITY
) {
4909 pim_ifp
->pim_dr_priority
= PIM_DEFAULT_DR_PRIORITY
;
4910 if (pim_if_dr_election(ifp
))
4911 pim_hello_restart_now(ifp
);
4918 pim_cmd_interface_add (struct interface
*ifp
)
4920 struct pim_interface
*pim_ifp
= ifp
->info
;
4923 pim_ifp
= pim_if_new(ifp
, 0 /* igmp=false */, 1 /* pim=true */);
4929 PIM_IF_DO_PIM(pim_ifp
->options
);
4932 pim_if_addr_add_all(ifp
);
4933 pim_if_membership_refresh(ifp
);
4937 DEFUN_HIDDEN (interface_ip_pim_ssm
,
4938 interface_ip_pim_ssm_cmd
,
4944 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4946 if (!pim_cmd_interface_add(ifp
)) {
4947 vty_out(vty
, "Could not enable PIM SM on interface%s", VTY_NEWLINE
);
4951 vty_out(vty
, "WARN: Enabled PIM SM on interface; configure PIM SSM range if needed%s", VTY_NEWLINE
);
4955 DEFUN (interface_ip_pim_sm
,
4956 interface_ip_pim_sm_cmd
,
4962 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4963 if (!pim_cmd_interface_add(ifp
)) {
4964 vty_out(vty
, "Could not enable PIM SM on interface%s", VTY_NEWLINE
);
4968 pim_if_create_pimreg();
4974 pim_cmd_interface_delete (struct interface
*ifp
)
4976 struct pim_interface
*pim_ifp
= ifp
->info
;
4981 PIM_IF_DONT_PIM(pim_ifp
->options
);
4983 pim_if_membership_clear(ifp
);
4986 pim_sock_delete() removes all neighbors from
4987 pim_ifp->pim_neighbor_list.
4989 pim_sock_delete(ifp
, "pim unconfigured on interface");
4991 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
4992 pim_if_addr_del_all(ifp
);
4999 DEFUN_HIDDEN (interface_no_ip_pim_ssm
,
5000 interface_no_ip_pim_ssm_cmd
,
5007 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5008 if (!pim_cmd_interface_delete(ifp
)) {
5009 vty_out(vty
, "Unable to delete interface information%s", VTY_NEWLINE
);
5016 DEFUN (interface_no_ip_pim_sm
,
5017 interface_no_ip_pim_sm_cmd
,
5024 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5025 if (!pim_cmd_interface_delete(ifp
)) {
5026 vty_out(vty
, "Unable to delete interface information%s", VTY_NEWLINE
);
5033 DEFUN (interface_ip_mroute
,
5034 interface_ip_mroute_cmd
,
5035 "ip mroute INTERFACE A.B.C.D",
5037 "Add multicast route\n"
5038 "Outgoing interface name\n"
5041 VTY_DECLVAR_CONTEXT(interface
, iif
);
5042 int idx_interface
= 2;
5044 struct interface
*oif
;
5045 const char *oifname
;
5046 const char *grp_str
;
5047 struct in_addr grp_addr
;
5048 struct in_addr src_addr
;
5051 oifname
= argv
[idx_interface
]->arg
;
5052 oif
= if_lookup_by_name(oifname
, VRF_DEFAULT
);
5054 vty_out(vty
, "No such interface name %s%s",
5055 oifname
, VTY_NEWLINE
);
5059 grp_str
= argv
[idx_ipv4
]->arg
;
5060 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
5062 vty_out(vty
, "Bad group address %s: errno=%d: %s%s",
5063 grp_str
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
5067 src_addr
.s_addr
= INADDR_ANY
;
5069 if (pim_static_add(iif
, oif
, grp_addr
, src_addr
)) {
5070 vty_out(vty
, "Failed to add route%s", VTY_NEWLINE
);
5077 DEFUN (interface_ip_mroute_source
,
5078 interface_ip_mroute_source_cmd
,
5079 "ip mroute INTERFACE A.B.C.D A.B.C.D",
5081 "Add multicast route\n"
5082 "Outgoing interface name\n"
5086 VTY_DECLVAR_CONTEXT(interface
, iif
);
5087 int idx_interface
= 2;
5090 struct interface
*oif
;
5091 const char *oifname
;
5092 const char *grp_str
;
5093 struct in_addr grp_addr
;
5094 const char *src_str
;
5095 struct in_addr src_addr
;
5098 oifname
= argv
[idx_interface
]->arg
;
5099 oif
= if_lookup_by_name(oifname
, VRF_DEFAULT
);
5101 vty_out(vty
, "No such interface name %s%s",
5102 oifname
, VTY_NEWLINE
);
5106 grp_str
= argv
[idx_ipv4
]->arg
;
5107 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
5109 vty_out(vty
, "Bad group address %s: errno=%d: %s%s",
5110 grp_str
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
5114 src_str
= argv
[idx_ipv4_2
]->arg
;
5115 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
5117 vty_out(vty
, "Bad source address %s: errno=%d: %s%s",
5118 src_str
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
5122 if (pim_static_add(iif
, oif
, grp_addr
, src_addr
)) {
5123 vty_out(vty
, "Failed to add route%s", VTY_NEWLINE
);
5130 DEFUN (interface_no_ip_mroute
,
5131 interface_no_ip_mroute_cmd
,
5132 "no ip mroute INTERFACE A.B.C.D",
5135 "Add multicast route\n"
5136 "Outgoing interface name\n"
5139 VTY_DECLVAR_CONTEXT(interface
, iif
);
5140 int idx_interface
= 3;
5142 struct interface
*oif
;
5143 const char *oifname
;
5144 const char *grp_str
;
5145 struct in_addr grp_addr
;
5146 struct in_addr src_addr
;
5149 oifname
= argv
[idx_interface
]->arg
;
5150 oif
= if_lookup_by_name(oifname
, VRF_DEFAULT
);
5152 vty_out(vty
, "No such interface name %s%s",
5153 oifname
, VTY_NEWLINE
);
5157 grp_str
= argv
[idx_ipv4
]->arg
;
5158 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
5160 vty_out(vty
, "Bad group address %s: errno=%d: %s%s",
5161 grp_str
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
5165 src_addr
.s_addr
= INADDR_ANY
;
5167 if (pim_static_del(iif
, oif
, grp_addr
, src_addr
)) {
5168 vty_out(vty
, "Failed to remove route%s", VTY_NEWLINE
);
5175 DEFUN (interface_no_ip_mroute_source
,
5176 interface_no_ip_mroute_source_cmd
,
5177 "no ip mroute INTERFACE A.B.C.D A.B.C.D",
5180 "Add multicast route\n"
5181 "Outgoing interface name\n"
5185 VTY_DECLVAR_CONTEXT(interface
, iif
);
5186 int idx_interface
= 3;
5189 struct interface
*oif
;
5190 const char *oifname
;
5191 const char *grp_str
;
5192 struct in_addr grp_addr
;
5193 const char *src_str
;
5194 struct in_addr src_addr
;
5197 oifname
= argv
[idx_interface
]->arg
;
5198 oif
= if_lookup_by_name(oifname
, VRF_DEFAULT
);
5200 vty_out(vty
, "No such interface name %s%s",
5201 oifname
, VTY_NEWLINE
);
5205 grp_str
= argv
[idx_ipv4
]->arg
;
5206 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
5208 vty_out(vty
, "Bad group address %s: errno=%d: %s%s",
5209 grp_str
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
5213 src_str
= argv
[idx_ipv4_2
]->arg
;
5214 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
5216 vty_out(vty
, "Bad source address %s: errno=%d: %s%s",
5217 src_str
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
5221 if (pim_static_del(iif
, oif
, grp_addr
, src_addr
)) {
5222 vty_out(vty
, "Failed to remove route%s", VTY_NEWLINE
);
5229 DEFUN (interface_ip_pim_hello
,
5230 interface_ip_pim_hello_cmd
,
5231 "ip pim hello (1-180) [(1-180)]",
5235 IFACE_PIM_HELLO_TIME_STR
5236 IFACE_PIM_HELLO_HOLD_STR
)
5238 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5241 struct pim_interface
*pim_ifp
;
5243 pim_ifp
= ifp
->info
;
5246 vty_out(vty
, "Pim not enabled on this interface%s", VTY_NEWLINE
);
5250 pim_ifp
->pim_hello_period
= strtol(argv
[idx_time
]->arg
, NULL
, 10);
5252 if (argc
== idx_hold
)
5253 pim_ifp
->pim_default_holdtime
= strtol(argv
[idx_hold
]->arg
, NULL
, 10);
5260 DEFUN (interface_no_ip_pim_hello
,
5261 interface_no_ip_pim_hello_cmd
,
5262 "no ip pim hello [(1-180) (1-180)]",
5267 IFACE_PIM_HELLO_TIME_STR
5268 IFACE_PIM_HELLO_HOLD_STR
)
5270 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5271 struct pim_interface
*pim_ifp
;
5273 pim_ifp
= ifp
->info
;
5276 vty_out(vty
, "Pim not enabled on this interface%s", VTY_NEWLINE
);
5280 pim_ifp
->pim_hello_period
= PIM_DEFAULT_HELLO_PERIOD
;
5281 pim_ifp
->pim_default_holdtime
= -1;
5292 PIM_DO_DEBUG_IGMP_EVENTS
;
5293 PIM_DO_DEBUG_IGMP_PACKETS
;
5294 PIM_DO_DEBUG_IGMP_TRACE
;
5298 DEFUN (no_debug_igmp
,
5305 PIM_DONT_DEBUG_IGMP_EVENTS
;
5306 PIM_DONT_DEBUG_IGMP_PACKETS
;
5307 PIM_DONT_DEBUG_IGMP_TRACE
;
5312 DEFUN (debug_igmp_events
,
5313 debug_igmp_events_cmd
,
5314 "debug igmp events",
5317 DEBUG_IGMP_EVENTS_STR
)
5319 PIM_DO_DEBUG_IGMP_EVENTS
;
5323 DEFUN (no_debug_igmp_events
,
5324 no_debug_igmp_events_cmd
,
5325 "no debug igmp events",
5329 DEBUG_IGMP_EVENTS_STR
)
5331 PIM_DONT_DEBUG_IGMP_EVENTS
;
5336 DEFUN (debug_igmp_packets
,
5337 debug_igmp_packets_cmd
,
5338 "debug igmp packets",
5341 DEBUG_IGMP_PACKETS_STR
)
5343 PIM_DO_DEBUG_IGMP_PACKETS
;
5347 DEFUN (no_debug_igmp_packets
,
5348 no_debug_igmp_packets_cmd
,
5349 "no debug igmp packets",
5353 DEBUG_IGMP_PACKETS_STR
)
5355 PIM_DONT_DEBUG_IGMP_PACKETS
;
5360 DEFUN (debug_igmp_trace
,
5361 debug_igmp_trace_cmd
,
5365 DEBUG_IGMP_TRACE_STR
)
5367 PIM_DO_DEBUG_IGMP_TRACE
;
5371 DEFUN (no_debug_igmp_trace
,
5372 no_debug_igmp_trace_cmd
,
5373 "no debug igmp trace",
5377 DEBUG_IGMP_TRACE_STR
)
5379 PIM_DONT_DEBUG_IGMP_TRACE
;
5384 DEFUN (debug_mroute
,
5390 PIM_DO_DEBUG_MROUTE
;
5394 DEFUN (debug_mroute_detail
,
5395 debug_mroute_detail_cmd
,
5396 "debug mroute detail",
5401 PIM_DO_DEBUG_MROUTE_DETAIL
;
5405 DEFUN (no_debug_mroute
,
5406 no_debug_mroute_cmd
,
5412 PIM_DONT_DEBUG_MROUTE
;
5416 DEFUN (no_debug_mroute_detail
,
5417 no_debug_mroute_detail_cmd
,
5418 "no debug mroute detail",
5424 PIM_DONT_DEBUG_MROUTE_DETAIL
;
5428 DEFUN (debug_static
,
5434 PIM_DO_DEBUG_STATIC
;
5438 DEFUN (no_debug_static
,
5439 no_debug_static_cmd
,
5445 PIM_DONT_DEBUG_STATIC
;
5456 PIM_DO_DEBUG_PIM_EVENTS
;
5457 PIM_DO_DEBUG_PIM_PACKETS
;
5458 PIM_DO_DEBUG_PIM_TRACE
;
5459 PIM_DO_DEBUG_MSDP_EVENTS
;
5460 PIM_DO_DEBUG_MSDP_PACKETS
;
5464 DEFUN (no_debug_pim
,
5471 PIM_DONT_DEBUG_PIM_EVENTS
;
5472 PIM_DONT_DEBUG_PIM_PACKETS
;
5473 PIM_DONT_DEBUG_PIM_TRACE
;
5474 PIM_DONT_DEBUG_MSDP_EVENTS
;
5475 PIM_DONT_DEBUG_MSDP_PACKETS
;
5477 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
5478 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
5484 DEFUN (debug_pim_events
,
5485 debug_pim_events_cmd
,
5489 DEBUG_PIM_EVENTS_STR
)
5491 PIM_DO_DEBUG_PIM_EVENTS
;
5495 DEFUN (no_debug_pim_events
,
5496 no_debug_pim_events_cmd
,
5497 "no debug pim events",
5501 DEBUG_PIM_EVENTS_STR
)
5503 PIM_DONT_DEBUG_PIM_EVENTS
;
5507 DEFUN (debug_pim_packets
,
5508 debug_pim_packets_cmd
,
5509 "debug pim packets [<hello|joins|register>]",
5512 DEBUG_PIM_PACKETS_STR
5513 DEBUG_PIM_HELLO_PACKETS_STR
5514 DEBUG_PIM_J_P_PACKETS_STR
5515 DEBUG_PIM_PIM_REG_PACKETS_STR
)
5518 if (argv_find (argv
, argc
, "hello", &idx
))
5520 PIM_DO_DEBUG_PIM_HELLO
;
5521 vty_out (vty
, "PIM Hello debugging is on%s", VTY_NEWLINE
);
5523 else if (argv_find (argv
, argc
,"joins", &idx
))
5525 PIM_DO_DEBUG_PIM_J_P
;
5526 vty_out (vty
, "PIM Join/Prune debugging is on%s", VTY_NEWLINE
);
5528 else if (argv_find (argv
, argc
, "register", &idx
))
5530 PIM_DO_DEBUG_PIM_REG
;
5531 vty_out (vty
, "PIM Register debugging is on%s", VTY_NEWLINE
);
5535 PIM_DO_DEBUG_PIM_PACKETS
;
5536 vty_out (vty
, "PIM Packet debugging is on %s", VTY_NEWLINE
);
5541 DEFUN (no_debug_pim_packets
,
5542 no_debug_pim_packets_cmd
,
5543 "no debug pim packets [<hello|joins|register>]",
5547 DEBUG_PIM_PACKETS_STR
5548 DEBUG_PIM_HELLO_PACKETS_STR
5549 DEBUG_PIM_J_P_PACKETS_STR
5550 DEBUG_PIM_PIM_REG_PACKETS_STR
)
5553 if (argv_find (argv
, argc
,"hello",&idx
))
5555 PIM_DONT_DEBUG_PIM_HELLO
;
5556 vty_out (vty
, "PIM Hello debugging is off %s", VTY_NEWLINE
);
5558 else if (argv_find (argv
, argc
, "joins", &idx
))
5560 PIM_DONT_DEBUG_PIM_J_P
;
5561 vty_out (vty
, "PIM Join/Prune debugging is off %s", VTY_NEWLINE
);
5563 else if (argv_find (argv
, argc
, "register", &idx
))
5565 PIM_DONT_DEBUG_PIM_REG
;
5566 vty_out (vty
, "PIM Register debugging is off%s", VTY_NEWLINE
);
5569 PIM_DONT_DEBUG_PIM_PACKETS
;
5575 DEFUN (debug_pim_packetdump_send
,
5576 debug_pim_packetdump_send_cmd
,
5577 "debug pim packet-dump send",
5580 DEBUG_PIM_PACKETDUMP_STR
5581 DEBUG_PIM_PACKETDUMP_SEND_STR
)
5583 PIM_DO_DEBUG_PIM_PACKETDUMP_SEND
;
5587 DEFUN (no_debug_pim_packetdump_send
,
5588 no_debug_pim_packetdump_send_cmd
,
5589 "no debug pim packet-dump send",
5593 DEBUG_PIM_PACKETDUMP_STR
5594 DEBUG_PIM_PACKETDUMP_SEND_STR
)
5596 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
5601 DEFUN (debug_pim_packetdump_recv
,
5602 debug_pim_packetdump_recv_cmd
,
5603 "debug pim packet-dump receive",
5606 DEBUG_PIM_PACKETDUMP_STR
5607 DEBUG_PIM_PACKETDUMP_RECV_STR
)
5609 PIM_DO_DEBUG_PIM_PACKETDUMP_RECV
;
5613 DEFUN (no_debug_pim_packetdump_recv
,
5614 no_debug_pim_packetdump_recv_cmd
,
5615 "no debug pim packet-dump receive",
5619 DEBUG_PIM_PACKETDUMP_STR
5620 DEBUG_PIM_PACKETDUMP_RECV_STR
)
5622 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
5627 DEFUN (debug_pim_trace
,
5628 debug_pim_trace_cmd
,
5632 DEBUG_PIM_TRACE_STR
)
5634 PIM_DO_DEBUG_PIM_TRACE
;
5638 DEFUN (no_debug_pim_trace
,
5639 no_debug_pim_trace_cmd
,
5640 "no debug pim trace",
5644 DEBUG_PIM_TRACE_STR
)
5646 PIM_DONT_DEBUG_PIM_TRACE
;
5651 DEFUN (debug_ssmpingd
,
5658 PIM_DO_DEBUG_SSMPINGD
;
5662 DEFUN (no_debug_ssmpingd
,
5663 no_debug_ssmpingd_cmd
,
5664 "no debug ssmpingd",
5670 PIM_DONT_DEBUG_SSMPINGD
;
5675 DEFUN (debug_pim_zebra
,
5676 debug_pim_zebra_cmd
,
5680 DEBUG_PIM_ZEBRA_STR
)
5686 DEFUN (no_debug_pim_zebra
,
5687 no_debug_pim_zebra_cmd
,
5688 "no debug pim zebra",
5692 DEBUG_PIM_ZEBRA_STR
)
5694 PIM_DONT_DEBUG_ZEBRA
;
5705 PIM_DO_DEBUG_MSDP_EVENTS
;
5706 PIM_DO_DEBUG_MSDP_PACKETS
;
5710 DEFUN (no_debug_msdp
,
5717 PIM_DONT_DEBUG_MSDP_EVENTS
;
5718 PIM_DONT_DEBUG_MSDP_PACKETS
;
5722 ALIAS (no_debug_msdp
,
5728 DEFUN (debug_msdp_events
,
5729 debug_msdp_events_cmd
,
5730 "debug msdp events",
5733 DEBUG_MSDP_EVENTS_STR
)
5735 PIM_DO_DEBUG_MSDP_EVENTS
;
5739 DEFUN (no_debug_msdp_events
,
5740 no_debug_msdp_events_cmd
,
5741 "no debug msdp events",
5745 DEBUG_MSDP_EVENTS_STR
)
5747 PIM_DONT_DEBUG_MSDP_EVENTS
;
5751 ALIAS (no_debug_msdp_events
,
5752 undebug_msdp_events_cmd
,
5753 "undebug msdp events",
5756 DEBUG_MSDP_EVENTS_STR
)
5758 DEFUN (debug_msdp_packets
,
5759 debug_msdp_packets_cmd
,
5760 "debug msdp packets",
5763 DEBUG_MSDP_PACKETS_STR
)
5765 PIM_DO_DEBUG_MSDP_PACKETS
;
5769 DEFUN (no_debug_msdp_packets
,
5770 no_debug_msdp_packets_cmd
,
5771 "no debug msdp packets",
5775 DEBUG_MSDP_PACKETS_STR
)
5777 PIM_DONT_DEBUG_MSDP_PACKETS
;
5781 ALIAS (no_debug_msdp_packets
,
5782 undebug_msdp_packets_cmd
,
5783 "undebug msdp packets",
5786 DEBUG_MSDP_PACKETS_STR
)
5788 DEFUN (show_debugging_pim
,
5789 show_debugging_pim_cmd
,
5790 "show debugging pim",
5795 pim_debug_config_write(vty
);
5800 interface_pim_use_src_cmd_worker(struct vty
*vty
, const char *source
)
5803 struct in_addr source_addr
;
5804 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5806 result
= inet_pton(AF_INET
, source
, &source_addr
);
5808 vty_out(vty
, "%% Bad source address %s: errno=%d: %s%s",
5809 source
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
5813 result
= pim_update_source_set(ifp
, source_addr
);
5817 case PIM_IFACE_NOT_FOUND
:
5818 vty_out(vty
, "Pim not enabled on this interface%s", VTY_NEWLINE
);
5820 case PIM_UPDATE_SOURCE_DUP
:
5821 vty_out(vty
, "%% Source already set to %s%s", source
, VTY_NEWLINE
);
5824 vty_out(vty
, "%% Source set failed%s", VTY_NEWLINE
);
5827 return result
?CMD_WARNING
:CMD_SUCCESS
;
5830 DEFUN (interface_pim_use_source
,
5831 interface_pim_use_source_cmd
,
5832 "ip pim use-source A.B.C.D",
5834 "pim multicast routing\n"
5835 "Configure primary IP address\n"
5836 "source ip address\n")
5838 return interface_pim_use_src_cmd_worker (vty
, argv
[3]->arg
);
5841 DEFUN (interface_no_pim_use_source
,
5842 interface_no_pim_use_source_cmd
,
5843 "no ip pim use-source",
5846 "pim multicast routing\n"
5847 "Delete source IP address\n")
5849 return interface_pim_use_src_cmd_worker (vty
, "0.0.0.0");
5853 ip_msdp_peer_cmd_worker (struct vty
*vty
, const char *peer
, const char *local
)
5855 enum pim_msdp_err result
;
5856 struct in_addr peer_addr
;
5857 struct in_addr local_addr
;
5859 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
5861 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s%s",
5862 peer
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
5866 result
= inet_pton(AF_INET
, local
, &local_addr
);
5868 vty_out(vty
, "%% Bad source address %s: errno=%d: %s%s",
5869 local
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
5873 result
= pim_msdp_peer_add(peer_addr
, local_addr
, "default", NULL
/* mp_p */);
5875 case PIM_MSDP_ERR_NONE
:
5877 case PIM_MSDP_ERR_OOM
:
5878 vty_out(vty
, "%% Out of memory%s", VTY_NEWLINE
);
5880 case PIM_MSDP_ERR_PEER_EXISTS
:
5881 vty_out(vty
, "%% Peer exists%s", VTY_NEWLINE
);
5883 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
5884 vty_out(vty
, "%% Only one mesh-group allowed currently%s", VTY_NEWLINE
);
5887 vty_out(vty
, "%% peer add failed%s", VTY_NEWLINE
);
5890 return result
?CMD_WARNING
:CMD_SUCCESS
;
5893 DEFUN_HIDDEN (ip_msdp_peer
,
5895 "ip msdp peer A.B.C.D source A.B.C.D",
5898 "Configure MSDP peer\n"
5900 "Source address for TCP connection\n"
5901 "local ip address\n")
5903 return ip_msdp_peer_cmd_worker (vty
, argv
[3]->arg
, argv
[5]->arg
);
5907 ip_no_msdp_peer_cmd_worker (struct vty
*vty
, const char *peer
)
5909 enum pim_msdp_err result
;
5910 struct in_addr peer_addr
;
5912 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
5914 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s%s",
5915 peer
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
5919 result
= pim_msdp_peer_del(peer_addr
);
5921 case PIM_MSDP_ERR_NONE
:
5923 case PIM_MSDP_ERR_NO_PEER
:
5924 vty_out(vty
, "%% Peer does not exist%s", VTY_NEWLINE
);
5927 vty_out(vty
, "%% peer del failed%s", VTY_NEWLINE
);
5930 return result
?CMD_WARNING
:CMD_SUCCESS
;
5933 DEFUN_HIDDEN (no_ip_msdp_peer
,
5934 no_ip_msdp_peer_cmd
,
5935 "no ip msdp peer A.B.C.D",
5939 "Delete MSDP peer\n"
5940 "peer ip address\n")
5942 return ip_no_msdp_peer_cmd_worker (vty
, argv
[4]->arg
);
5946 ip_msdp_mesh_group_member_cmd_worker(struct vty
*vty
, const char *mg
, const char *mbr
)
5948 enum pim_msdp_err result
;
5949 struct in_addr mbr_ip
;
5951 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
5953 vty_out(vty
, "%% Bad member address %s: errno=%d: %s%s",
5954 mbr
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
5958 result
= pim_msdp_mg_mbr_add(mg
, mbr_ip
);
5960 case PIM_MSDP_ERR_NONE
:
5962 case PIM_MSDP_ERR_OOM
:
5963 vty_out(vty
, "%% Out of memory%s", VTY_NEWLINE
);
5965 case PIM_MSDP_ERR_MG_MBR_EXISTS
:
5966 vty_out(vty
, "%% mesh-group member exists%s", VTY_NEWLINE
);
5968 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
5969 vty_out(vty
, "%% Only one mesh-group allowed currently%s", VTY_NEWLINE
);
5972 vty_out(vty
, "%% member add failed%s", VTY_NEWLINE
);
5975 return result
?CMD_WARNING
:CMD_SUCCESS
;
5978 DEFUN (ip_msdp_mesh_group_member
,
5979 ip_msdp_mesh_group_member_cmd
,
5980 "ip msdp mesh-group WORD member A.B.C.D",
5983 "Configure MSDP mesh-group\n"
5985 "mesh group member\n"
5986 "peer ip address\n")
5988 return ip_msdp_mesh_group_member_cmd_worker(vty
, argv
[3]->arg
, argv
[5]->arg
);
5992 ip_no_msdp_mesh_group_member_cmd_worker(struct vty
*vty
, const char *mg
, const char *mbr
)
5994 enum pim_msdp_err result
;
5995 struct in_addr mbr_ip
;
5997 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
5999 vty_out(vty
, "%% Bad member address %s: errno=%d: %s%s",
6000 mbr
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
6004 result
= pim_msdp_mg_mbr_del(mg
, mbr_ip
);
6006 case PIM_MSDP_ERR_NONE
:
6008 case PIM_MSDP_ERR_NO_MG
:
6009 vty_out(vty
, "%% mesh-group does not exist%s", VTY_NEWLINE
);
6011 case PIM_MSDP_ERR_NO_MG_MBR
:
6012 vty_out(vty
, "%% mesh-group member does not exist%s", VTY_NEWLINE
);
6015 vty_out(vty
, "%% mesh-group member del failed%s", VTY_NEWLINE
);
6018 return result
?CMD_WARNING
:CMD_SUCCESS
;
6020 DEFUN (no_ip_msdp_mesh_group_member
,
6021 no_ip_msdp_mesh_group_member_cmd
,
6022 "no ip msdp mesh-group WORD member A.B.C.D",
6026 "Delete MSDP mesh-group member\n"
6028 "mesh group member\n"
6029 "peer ip address\n")
6031 return ip_no_msdp_mesh_group_member_cmd_worker(vty
, argv
[4]->arg
, argv
[6]->arg
);
6035 ip_msdp_mesh_group_source_cmd_worker(struct vty
*vty
, const char *mg
, const char *src
)
6037 enum pim_msdp_err result
;
6038 struct in_addr src_ip
;
6040 result
= inet_pton(AF_INET
, src
, &src_ip
);
6042 vty_out(vty
, "%% Bad source address %s: errno=%d: %s%s",
6043 src
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
6047 result
= pim_msdp_mg_src_add(mg
, src_ip
);
6049 case PIM_MSDP_ERR_NONE
:
6051 case PIM_MSDP_ERR_OOM
:
6052 vty_out(vty
, "%% Out of memory%s", VTY_NEWLINE
);
6054 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
6055 vty_out(vty
, "%% Only one mesh-group allowed currently%s", VTY_NEWLINE
);
6058 vty_out(vty
, "%% source add failed%s", VTY_NEWLINE
);
6061 return result
?CMD_WARNING
:CMD_SUCCESS
;
6065 DEFUN (ip_msdp_mesh_group_source
,
6066 ip_msdp_mesh_group_source_cmd
,
6067 "ip msdp mesh-group WORD source A.B.C.D",
6070 "Configure MSDP mesh-group\n"
6072 "mesh group local address\n"
6073 "source ip address for the TCP connection\n")
6075 return ip_msdp_mesh_group_source_cmd_worker(vty
, argv
[3]->arg
, argv
[5]->arg
);
6079 ip_no_msdp_mesh_group_source_cmd_worker(struct vty
*vty
, const char *mg
)
6081 enum pim_msdp_err result
;
6083 result
= pim_msdp_mg_src_del(mg
);
6085 case PIM_MSDP_ERR_NONE
:
6087 case PIM_MSDP_ERR_NO_MG
:
6088 vty_out(vty
, "%% mesh-group does not exist%s", VTY_NEWLINE
);
6091 vty_out(vty
, "%% mesh-group source del failed%s", VTY_NEWLINE
);
6094 return result
?CMD_WARNING
:CMD_SUCCESS
;
6098 ip_no_msdp_mesh_group_cmd_worker(struct vty
*vty
, const char *mg
)
6100 enum pim_msdp_err result
;
6102 result
= pim_msdp_mg_del(mg
);
6104 case PIM_MSDP_ERR_NONE
:
6106 case PIM_MSDP_ERR_NO_MG
:
6107 vty_out(vty
, "%% mesh-group does not exist%s", VTY_NEWLINE
);
6110 vty_out(vty
, "%% mesh-group source del failed%s", VTY_NEWLINE
);
6113 return result
? CMD_WARNING
: CMD_SUCCESS
;
6116 DEFUN (no_ip_msdp_mesh_group_source
,
6117 no_ip_msdp_mesh_group_source_cmd
,
6118 "no ip msdp mesh-group WORD source [A.B.C.D]",
6122 "Delete MSDP mesh-group source\n"
6124 "mesh group source\n"
6125 "mesh group local address\n")
6128 return ip_no_msdp_mesh_group_cmd_worker(vty
, argv
[6]->arg
);
6130 return ip_no_msdp_mesh_group_source_cmd_worker(vty
, argv
[4]->arg
);
6134 print_empty_json_obj(struct vty
*vty
)
6137 json
= json_object_new_object();
6138 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
6139 json_object_free(json
);
6143 ip_msdp_show_mesh_group(struct vty
*vty
, u_char uj
)
6145 struct listnode
*mbrnode
;
6146 struct pim_msdp_mg_mbr
*mbr
;
6147 struct pim_msdp_mg
*mg
= msdp
->mg
;
6148 char mbr_str
[INET_ADDRSTRLEN
];
6149 char src_str
[INET_ADDRSTRLEN
];
6150 char state_str
[PIM_MSDP_STATE_STRLEN
];
6151 enum pim_msdp_peer_state state
;
6152 json_object
*json
= NULL
;
6153 json_object
*json_mg_row
= NULL
;
6154 json_object
*json_members
= NULL
;
6155 json_object
*json_row
= NULL
;
6159 print_empty_json_obj(vty
);
6163 pim_inet4_dump("<source?>", mg
->src_ip
, src_str
, sizeof(src_str
));
6165 json
= json_object_new_object();
6166 /* currently there is only one mesh group but we should still make
6167 * it a dict with mg-name as key */
6168 json_mg_row
= json_object_new_object();
6169 json_object_string_add(json_mg_row
, "name", mg
->mesh_group_name
);
6170 json_object_string_add(json_mg_row
, "source", src_str
);
6172 vty_out(vty
, "Mesh group : %s%s", mg
->mesh_group_name
, VTY_NEWLINE
);
6173 vty_out(vty
, " Source : %s%s", src_str
, VTY_NEWLINE
);
6174 vty_out(vty
, " Member State%s", VTY_NEWLINE
);
6177 for (ALL_LIST_ELEMENTS_RO(mg
->mbr_list
, mbrnode
, mbr
)) {
6178 pim_inet4_dump("<mbr?>", mbr
->mbr_ip
, mbr_str
, sizeof(mbr_str
));
6180 state
= mbr
->mp
->state
;
6182 state
= PIM_MSDP_DISABLED
;
6184 pim_msdp_state_dump(state
, state_str
, sizeof(state_str
));
6186 json_row
= json_object_new_object();
6187 json_object_string_add(json_row
, "member", mbr_str
);
6188 json_object_string_add(json_row
, "state", state_str
);
6189 if (!json_members
) {
6190 json_members
= json_object_new_object();
6191 json_object_object_add(json_mg_row
, "members", json_members
);
6193 json_object_object_add(json_members
, mbr_str
, json_row
);
6195 vty_out(vty
, " %-15s %11s%s",
6196 mbr_str
, state_str
, VTY_NEWLINE
);
6201 json_object_object_add(json
, mg
->mesh_group_name
, json_mg_row
);
6202 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
6203 json_object_free(json
);
6207 DEFUN (show_ip_msdp_mesh_group
,
6208 show_ip_msdp_mesh_group_cmd
,
6209 "show ip msdp mesh-group [json]",
6213 "MSDP mesh-group information\n"
6214 "JavaScript Object Notation\n")
6216 u_char uj
= use_json(argc
, argv
);
6217 ip_msdp_show_mesh_group(vty
, uj
);
6223 ip_msdp_show_peers(struct vty
*vty
, u_char uj
)
6225 struct listnode
*mpnode
;
6226 struct pim_msdp_peer
*mp
;
6227 char peer_str
[INET_ADDRSTRLEN
];
6228 char local_str
[INET_ADDRSTRLEN
];
6229 char state_str
[PIM_MSDP_STATE_STRLEN
];
6230 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
6232 json_object
*json
= NULL
;
6233 json_object
*json_row
= NULL
;
6237 json
= json_object_new_object();
6239 vty_out(vty
, "Peer Local State Uptime SaCnt%s", VTY_NEWLINE
);
6242 for (ALL_LIST_ELEMENTS_RO(msdp
->peer_list
, mpnode
, mp
)) {
6243 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
6244 now
= pim_time_monotonic_sec();
6245 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- mp
->uptime
);
6247 strcpy(timebuf
, "-");
6249 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
6250 pim_inet4_dump("<local?>", mp
->local
, local_str
, sizeof(local_str
));
6251 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
6253 json_row
= json_object_new_object();
6254 json_object_string_add(json_row
, "peer", peer_str
);
6255 json_object_string_add(json_row
, "local", local_str
);
6256 json_object_string_add(json_row
, "state", state_str
);
6257 json_object_string_add(json_row
, "upTime", timebuf
);
6258 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
6259 json_object_object_add(json
, peer_str
, json_row
);
6261 vty_out(vty
, "%-15s %15s %11s %8s %6d%s",
6262 peer_str
, local_str
, state_str
,
6263 timebuf
, mp
->sa_cnt
, VTY_NEWLINE
);
6268 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
6269 json_object_free(json
);
6274 ip_msdp_show_peers_detail(struct vty
*vty
, const char *peer
, u_char uj
)
6276 struct listnode
*mpnode
;
6277 struct pim_msdp_peer
*mp
;
6278 char peer_str
[INET_ADDRSTRLEN
];
6279 char local_str
[INET_ADDRSTRLEN
];
6280 char state_str
[PIM_MSDP_STATE_STRLEN
];
6281 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
6282 char katimer
[PIM_MSDP_TIMER_STRLEN
];
6283 char crtimer
[PIM_MSDP_TIMER_STRLEN
];
6284 char holdtimer
[PIM_MSDP_TIMER_STRLEN
];
6286 json_object
*json
= NULL
;
6287 json_object
*json_row
= NULL
;
6290 json
= json_object_new_object();
6293 for (ALL_LIST_ELEMENTS_RO(msdp
->peer_list
, mpnode
, mp
)) {
6294 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
6295 if (strcmp(peer
, "detail") &&
6296 strcmp(peer
, peer_str
))
6299 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
6300 now
= pim_time_monotonic_sec();
6301 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- mp
->uptime
);
6303 strcpy(timebuf
, "-");
6305 pim_inet4_dump("<local?>", mp
->local
, local_str
, sizeof(local_str
));
6306 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
6307 pim_time_timer_to_hhmmss(katimer
, sizeof(katimer
), mp
->ka_timer
);
6308 pim_time_timer_to_hhmmss(crtimer
, sizeof(crtimer
), mp
->cr_timer
);
6309 pim_time_timer_to_hhmmss(holdtimer
, sizeof(holdtimer
), mp
->hold_timer
);
6312 json_row
= json_object_new_object();
6313 json_object_string_add(json_row
, "peer", peer_str
);
6314 json_object_string_add(json_row
, "local", local_str
);
6315 json_object_string_add(json_row
, "meshGroupName", mp
->mesh_group_name
);
6316 json_object_string_add(json_row
, "state", state_str
);
6317 json_object_string_add(json_row
, "upTime", timebuf
);
6318 json_object_string_add(json_row
, "keepAliveTimer", katimer
);
6319 json_object_string_add(json_row
, "connRetryTimer", crtimer
);
6320 json_object_string_add(json_row
, "holdTimer", holdtimer
);
6321 json_object_string_add(json_row
, "lastReset", mp
->last_reset
);
6322 json_object_int_add(json_row
, "connAttempts", mp
->conn_attempts
);
6323 json_object_int_add(json_row
, "establishedChanges", mp
->est_flaps
);
6324 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
6325 json_object_int_add(json_row
, "kaSent", mp
->ka_tx_cnt
);
6326 json_object_int_add(json_row
, "kaRcvd", mp
->ka_rx_cnt
);
6327 json_object_int_add(json_row
, "saSent", mp
->sa_tx_cnt
);
6328 json_object_int_add(json_row
, "saRcvd", mp
->sa_rx_cnt
);
6329 json_object_object_add(json
, peer_str
, json_row
);
6331 vty_out(vty
, "Peer : %s%s", peer_str
, VTY_NEWLINE
);
6332 vty_out(vty
, " Local : %s%s", local_str
, VTY_NEWLINE
);
6333 vty_out(vty
, " Mesh Group : %s%s", mp
->mesh_group_name
, VTY_NEWLINE
);
6334 vty_out(vty
, " State : %s%s", state_str
, VTY_NEWLINE
);
6335 vty_out(vty
, " Uptime : %s%s", timebuf
, VTY_NEWLINE
);
6337 vty_out(vty
, " Keepalive Timer : %s%s", katimer
, VTY_NEWLINE
);
6338 vty_out(vty
, " Conn Retry Timer : %s%s", crtimer
, VTY_NEWLINE
);
6339 vty_out(vty
, " Hold Timer : %s%s", holdtimer
, VTY_NEWLINE
);
6340 vty_out(vty
, " Last Reset : %s%s", mp
->last_reset
, VTY_NEWLINE
);
6341 vty_out(vty
, " Conn Attempts : %d%s", mp
->conn_attempts
, VTY_NEWLINE
);
6342 vty_out(vty
, " Established Changes : %d%s", mp
->est_flaps
, VTY_NEWLINE
);
6343 vty_out(vty
, " SA Count : %d%s", mp
->sa_cnt
, VTY_NEWLINE
);
6344 vty_out(vty
, " Statistics :%s", VTY_NEWLINE
);
6345 vty_out(vty
, " Sent Rcvd%s", VTY_NEWLINE
);
6346 vty_out(vty
, " Keepalives : %10d %10d%s",
6347 mp
->ka_tx_cnt
, mp
->ka_rx_cnt
, VTY_NEWLINE
);
6348 vty_out(vty
, " SAs : %10d %10d%s",
6349 mp
->sa_tx_cnt
, mp
->sa_rx_cnt
, VTY_NEWLINE
);
6350 vty_out(vty
, "%s", VTY_NEWLINE
);
6355 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
6356 json_object_free(json
);
6360 DEFUN (show_ip_msdp_peer_detail
,
6361 show_ip_msdp_peer_detail_cmd
,
6362 "show ip msdp peer [detail|A.B.C.D] [json]",
6366 "MSDP peer information\n"
6369 "JavaScript Object Notation\n")
6371 u_char uj
= use_json(argc
, argv
);
6376 ip_msdp_show_peers_detail(vty
, argv
[4]->arg
, uj
);
6378 ip_msdp_show_peers(vty
, uj
);
6384 ip_msdp_show_sa(struct vty
*vty
, u_char uj
)
6386 struct listnode
*sanode
;
6387 struct pim_msdp_sa
*sa
;
6388 char src_str
[INET_ADDRSTRLEN
];
6389 char grp_str
[INET_ADDRSTRLEN
];
6390 char rp_str
[INET_ADDRSTRLEN
];
6391 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
6395 json_object
*json
= NULL
;
6396 json_object
*json_group
= NULL
;
6397 json_object
*json_row
= NULL
;
6400 json
= json_object_new_object();
6402 vty_out(vty
, "Source Group RP Local SPT Uptime%s", VTY_NEWLINE
);
6405 for (ALL_LIST_ELEMENTS_RO(msdp
->sa_list
, sanode
, sa
)) {
6406 now
= pim_time_monotonic_sec();
6407 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
6408 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
6409 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
6410 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
6411 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
6413 strcpy(spt_str
, "yes");
6415 strcpy(spt_str
, "no");
6418 strcpy(rp_str
, "-");
6419 strcpy(spt_str
, "-");
6421 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
6422 strcpy(local_str
, "yes");
6424 strcpy(local_str
, "no");
6427 json_object_object_get_ex(json
, grp_str
, &json_group
);
6430 json_group
= json_object_new_object();
6431 json_object_object_add(json
, grp_str
, json_group
);
6434 json_row
= json_object_new_object();
6435 json_object_string_add(json_row
, "source", src_str
);
6436 json_object_string_add(json_row
, "group", grp_str
);
6437 json_object_string_add(json_row
, "rp", rp_str
);
6438 json_object_string_add(json_row
, "local", local_str
);
6439 json_object_string_add(json_row
, "sptSetup", spt_str
);
6440 json_object_string_add(json_row
, "upTime", timebuf
);
6441 json_object_object_add(json_group
, src_str
, json_row
);
6443 vty_out(vty
, "%-15s %15s %15s %5c %3c %8s%s",
6444 src_str
, grp_str
, rp_str
, local_str
[0], spt_str
[0], timebuf
, VTY_NEWLINE
);
6450 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
6451 json_object_free(json
);
6456 ip_msdp_show_sa_entry_detail(struct pim_msdp_sa
*sa
, const char *src_str
,
6457 const char *grp_str
, struct vty
*vty
,
6458 u_char uj
, json_object
*json
)
6460 char rp_str
[INET_ADDRSTRLEN
];
6461 char peer_str
[INET_ADDRSTRLEN
];
6462 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
6465 char statetimer
[PIM_MSDP_TIMER_STRLEN
];
6467 json_object
*json_group
= NULL
;
6468 json_object
*json_row
= NULL
;
6470 now
= pim_time_monotonic_sec();
6471 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
6472 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
6473 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
6474 pim_inet4_dump("<peer?>", sa
->peer
, peer_str
, sizeof(peer_str
));
6476 strcpy(spt_str
, "yes");
6478 strcpy(spt_str
, "no");
6481 strcpy(rp_str
, "-");
6482 strcpy(peer_str
, "-");
6483 strcpy(spt_str
, "-");
6485 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
6486 strcpy(local_str
, "yes");
6488 strcpy(local_str
, "no");
6490 pim_time_timer_to_hhmmss(statetimer
, sizeof(statetimer
), sa
->sa_state_timer
);
6492 json_object_object_get_ex(json
, grp_str
, &json_group
);
6495 json_group
= json_object_new_object();
6496 json_object_object_add(json
, grp_str
, json_group
);
6499 json_row
= json_object_new_object();
6500 json_object_string_add(json_row
, "source", src_str
);
6501 json_object_string_add(json_row
, "group", grp_str
);
6502 json_object_string_add(json_row
, "rp", rp_str
);
6503 json_object_string_add(json_row
, "local", local_str
);
6504 json_object_string_add(json_row
, "sptSetup", spt_str
);
6505 json_object_string_add(json_row
, "upTime", timebuf
);
6506 json_object_string_add(json_row
, "stateTimer", statetimer
);
6507 json_object_object_add(json_group
, src_str
, json_row
);
6509 vty_out(vty
, "SA : %s%s", sa
->sg_str
, VTY_NEWLINE
);
6510 vty_out(vty
, " RP : %s%s", rp_str
, VTY_NEWLINE
);
6511 vty_out(vty
, " Peer : %s%s", peer_str
, VTY_NEWLINE
);
6512 vty_out(vty
, " Local : %s%s", local_str
, VTY_NEWLINE
);
6513 vty_out(vty
, " SPT Setup : %s%s", spt_str
, VTY_NEWLINE
);
6514 vty_out(vty
, " Uptime : %s%s", timebuf
, VTY_NEWLINE
);
6515 vty_out(vty
, " State Timer : %s%s", statetimer
, VTY_NEWLINE
);
6516 vty_out(vty
, "%s", VTY_NEWLINE
);
6521 ip_msdp_show_sa_detail(struct vty
*vty
, u_char uj
)
6523 struct listnode
*sanode
;
6524 struct pim_msdp_sa
*sa
;
6525 char src_str
[INET_ADDRSTRLEN
];
6526 char grp_str
[INET_ADDRSTRLEN
];
6527 json_object
*json
= NULL
;
6530 json
= json_object_new_object();
6533 for (ALL_LIST_ELEMENTS_RO(msdp
->sa_list
, sanode
, sa
)) {
6534 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
6535 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
6536 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
, uj
, json
);
6540 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
6541 json_object_free(json
);
6545 DEFUN (show_ip_msdp_sa_detail
,
6546 show_ip_msdp_sa_detail_cmd
,
6547 "show ip msdp sa detail [json]",
6551 "MSDP active-source information\n"
6553 "JavaScript Object Notation\n")
6555 u_char uj
= use_json(argc
, argv
);
6556 ip_msdp_show_sa_detail(vty
, uj
);
6562 ip_msdp_show_sa_addr(struct vty
*vty
, const char *addr
, u_char uj
)
6564 struct listnode
*sanode
;
6565 struct pim_msdp_sa
*sa
;
6566 char src_str
[INET_ADDRSTRLEN
];
6567 char grp_str
[INET_ADDRSTRLEN
];
6568 json_object
*json
= NULL
;
6571 json
= json_object_new_object();
6574 for (ALL_LIST_ELEMENTS_RO(msdp
->sa_list
, sanode
, sa
)) {
6575 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
6576 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
6577 if (!strcmp(addr
, src_str
) || !strcmp(addr
, grp_str
)) {
6578 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
, uj
, json
);
6583 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
6584 json_object_free(json
);
6589 ip_msdp_show_sa_sg(struct vty
*vty
, const char *src
, const char *grp
, u_char uj
)
6591 struct listnode
*sanode
;
6592 struct pim_msdp_sa
*sa
;
6593 char src_str
[INET_ADDRSTRLEN
];
6594 char grp_str
[INET_ADDRSTRLEN
];
6595 json_object
*json
= NULL
;
6598 json
= json_object_new_object();
6601 for (ALL_LIST_ELEMENTS_RO(msdp
->sa_list
, sanode
, sa
)) {
6602 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
6603 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
6604 if (!strcmp(src
, src_str
) && !strcmp(grp
, grp_str
)) {
6605 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
, uj
, json
);
6610 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
6611 json_object_free(json
);
6615 DEFUN (show_ip_msdp_sa_sg
,
6616 show_ip_msdp_sa_sg_cmd
,
6617 "show ip msdp sa [A.B.C.D [A.B.C.D]] [json]",
6621 "MSDP active-source information\n"
6622 "source or group ip\n"
6624 "JavaScript Object Notation\n")
6626 u_char uj
= use_json(argc
, argv
);
6629 char *src_ip
= argv_find (argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
++]->arg
: NULL
;
6630 char *grp_ip
= idx
< argc
&& argv_find (argv
, argc
, "A.B.C.D", &idx
) ?
6631 argv
[idx
]->arg
: NULL
;
6633 if (src_ip
&& grp_ip
)
6634 ip_msdp_show_sa_sg(vty
, src_ip
, grp_ip
, uj
);
6636 ip_msdp_show_sa_addr(vty
, src_ip
, uj
);
6638 ip_msdp_show_sa(vty
, uj
);
6645 install_node (&pim_global_node
, pim_global_config_write
); /* PIM_NODE */
6646 install_node (&interface_node
, pim_interface_config_write
); /* INTERFACE_NODE */
6649 install_node (&debug_node
, pim_debug_config_write
);
6651 install_element (CONFIG_NODE
, &ip_multicast_routing_cmd
);
6652 install_element (CONFIG_NODE
, &no_ip_multicast_routing_cmd
);
6653 install_element (CONFIG_NODE
, &ip_pim_rp_cmd
);
6654 install_element (CONFIG_NODE
, &no_ip_pim_rp_cmd
);
6655 install_element (CONFIG_NODE
, &ip_pim_rp_prefix_list_cmd
);
6656 install_element (CONFIG_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
6657 install_element (CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_cmd
);
6658 install_element (CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_name_cmd
);
6659 install_element (CONFIG_NODE
, &ip_pim_ssm_prefix_list_cmd
);
6660 install_element (CONFIG_NODE
, &ip_pim_register_suppress_cmd
);
6661 install_element (CONFIG_NODE
, &no_ip_pim_register_suppress_cmd
);
6662 install_element (CONFIG_NODE
, &ip_pim_spt_switchover_infinity_cmd
);
6663 install_element (CONFIG_NODE
, &no_ip_pim_spt_switchover_infinity_cmd
);
6664 install_element (CONFIG_NODE
, &ip_pim_joinprune_time_cmd
);
6665 install_element (CONFIG_NODE
, &no_ip_pim_joinprune_time_cmd
);
6666 install_element (CONFIG_NODE
, &ip_pim_keep_alive_cmd
);
6667 install_element (CONFIG_NODE
, &no_ip_pim_keep_alive_cmd
);
6668 install_element (CONFIG_NODE
, &ip_pim_packets_cmd
);
6669 install_element (CONFIG_NODE
, &no_ip_pim_packets_cmd
);
6670 install_element (CONFIG_NODE
, &ip_pim_v6_secondary_cmd
);
6671 install_element (CONFIG_NODE
, &no_ip_pim_v6_secondary_cmd
);
6672 install_element (CONFIG_NODE
, &ip_ssmpingd_cmd
);
6673 install_element (CONFIG_NODE
, &no_ip_ssmpingd_cmd
);
6674 install_element (CONFIG_NODE
, &ip_msdp_peer_cmd
);
6675 install_element (CONFIG_NODE
, &no_ip_msdp_peer_cmd
);
6676 install_element (CONFIG_NODE
, &ip_pim_ecmp_cmd
);
6677 install_element (CONFIG_NODE
, &no_ip_pim_ecmp_cmd
);
6678 install_element (CONFIG_NODE
, &ip_pim_ecmp_rebalance_cmd
);
6679 install_element (CONFIG_NODE
, &no_ip_pim_ecmp_rebalance_cmd
);
6681 install_element (INTERFACE_NODE
, &interface_ip_igmp_cmd
);
6682 install_element (INTERFACE_NODE
, &interface_no_ip_igmp_cmd
);
6683 install_element (INTERFACE_NODE
, &interface_ip_igmp_join_cmd
);
6684 install_element (INTERFACE_NODE
, &interface_no_ip_igmp_join_cmd
);
6685 install_element (INTERFACE_NODE
, &interface_ip_igmp_version_cmd
);
6686 install_element (INTERFACE_NODE
, &interface_no_ip_igmp_version_cmd
);
6687 install_element (INTERFACE_NODE
, &interface_ip_igmp_query_interval_cmd
);
6688 install_element (INTERFACE_NODE
, &interface_no_ip_igmp_query_interval_cmd
);
6689 install_element (INTERFACE_NODE
, &interface_ip_igmp_query_max_response_time_cmd
);
6690 install_element (INTERFACE_NODE
, &interface_no_ip_igmp_query_max_response_time_cmd
);
6691 install_element (INTERFACE_NODE
, &interface_ip_igmp_query_max_response_time_dsec_cmd
);
6692 install_element (INTERFACE_NODE
, &interface_no_ip_igmp_query_max_response_time_dsec_cmd
);
6693 install_element (INTERFACE_NODE
, &interface_ip_pim_ssm_cmd
);
6694 install_element (INTERFACE_NODE
, &interface_no_ip_pim_ssm_cmd
);
6695 install_element (INTERFACE_NODE
, &interface_ip_pim_sm_cmd
);
6696 install_element (INTERFACE_NODE
, &interface_no_ip_pim_sm_cmd
);
6697 install_element (INTERFACE_NODE
, &interface_ip_pim_drprio_cmd
);
6698 install_element (INTERFACE_NODE
, &interface_no_ip_pim_drprio_cmd
);
6699 install_element (INTERFACE_NODE
, &interface_ip_pim_hello_cmd
);
6700 install_element (INTERFACE_NODE
, &interface_no_ip_pim_hello_cmd
);
6702 // Static mroutes NEB
6703 install_element (INTERFACE_NODE
, &interface_ip_mroute_cmd
);
6704 install_element (INTERFACE_NODE
, &interface_ip_mroute_source_cmd
);
6705 install_element (INTERFACE_NODE
, &interface_no_ip_mroute_cmd
);
6706 install_element (INTERFACE_NODE
, &interface_no_ip_mroute_source_cmd
);
6708 install_element (VIEW_NODE
, &show_ip_igmp_interface_cmd
);
6709 install_element (VIEW_NODE
, &show_ip_igmp_join_cmd
);
6710 install_element (VIEW_NODE
, &show_ip_igmp_groups_cmd
);
6711 install_element (VIEW_NODE
, &show_ip_igmp_groups_retransmissions_cmd
);
6712 install_element (VIEW_NODE
, &show_ip_igmp_sources_cmd
);
6713 install_element (VIEW_NODE
, &show_ip_igmp_sources_retransmissions_cmd
);
6714 install_element (VIEW_NODE
, &show_ip_pim_assert_cmd
);
6715 install_element (VIEW_NODE
, &show_ip_pim_assert_internal_cmd
);
6716 install_element (VIEW_NODE
, &show_ip_pim_assert_metric_cmd
);
6717 install_element (VIEW_NODE
, &show_ip_pim_assert_winner_metric_cmd
);
6718 install_element (VIEW_NODE
, &show_ip_pim_interface_traffic_cmd
);
6719 install_element (VIEW_NODE
, &show_ip_pim_interface_traffic_single_cmd
);
6720 install_element (VIEW_NODE
, &show_ip_pim_interface_cmd
);
6721 install_element (VIEW_NODE
, &show_ip_pim_join_cmd
);
6722 install_element (VIEW_NODE
, &show_ip_pim_local_membership_cmd
);
6723 install_element (VIEW_NODE
, &show_ip_pim_neighbor_cmd
);
6724 install_element (VIEW_NODE
, &show_ip_pim_rpf_cmd
);
6725 install_element (VIEW_NODE
, &show_ip_pim_secondary_cmd
);
6726 install_element (VIEW_NODE
, &show_ip_pim_state_cmd
);
6727 install_element (VIEW_NODE
, &show_ip_pim_upstream_cmd
);
6728 install_element (VIEW_NODE
, &show_ip_pim_upstream_join_desired_cmd
);
6729 install_element (VIEW_NODE
, &show_ip_pim_upstream_rpf_cmd
);
6730 install_element (VIEW_NODE
, &show_ip_pim_rp_cmd
);
6731 install_element (VIEW_NODE
, &show_ip_multicast_cmd
);
6732 install_element (VIEW_NODE
, &show_ip_mroute_cmd
);
6733 install_element (VIEW_NODE
, &show_ip_mroute_count_cmd
);
6734 install_element (VIEW_NODE
, &show_ip_rib_cmd
);
6735 install_element (VIEW_NODE
, &show_ip_ssmpingd_cmd
);
6736 install_element (VIEW_NODE
, &show_debugging_pim_cmd
);
6737 install_element (VIEW_NODE
, &show_ip_pim_nexthop_cmd
);
6738 install_element (VIEW_NODE
, &show_ip_pim_nexthop_lookup_cmd
);
6740 install_element (ENABLE_NODE
, &clear_ip_interfaces_cmd
);
6741 install_element (ENABLE_NODE
, &clear_ip_igmp_interfaces_cmd
);
6742 install_element (ENABLE_NODE
, &clear_ip_mroute_cmd
);
6743 install_element (ENABLE_NODE
, &clear_ip_pim_interfaces_cmd
);
6744 install_element (ENABLE_NODE
, &clear_ip_pim_interface_traffic_cmd
);
6745 install_element (ENABLE_NODE
, &clear_ip_pim_oil_cmd
);
6747 install_element (ENABLE_NODE
, &debug_igmp_cmd
);
6748 install_element (ENABLE_NODE
, &no_debug_igmp_cmd
);
6749 install_element (ENABLE_NODE
, &debug_igmp_events_cmd
);
6750 install_element (ENABLE_NODE
, &no_debug_igmp_events_cmd
);
6751 install_element (ENABLE_NODE
, &debug_igmp_packets_cmd
);
6752 install_element (ENABLE_NODE
, &no_debug_igmp_packets_cmd
);
6753 install_element (ENABLE_NODE
, &debug_igmp_trace_cmd
);
6754 install_element (ENABLE_NODE
, &no_debug_igmp_trace_cmd
);
6755 install_element (ENABLE_NODE
, &debug_mroute_cmd
);
6756 install_element (ENABLE_NODE
, &debug_mroute_detail_cmd
);
6757 install_element (ENABLE_NODE
, &no_debug_mroute_cmd
);
6758 install_element (ENABLE_NODE
, &no_debug_mroute_detail_cmd
);
6759 install_element (ENABLE_NODE
, &debug_static_cmd
);
6760 install_element (ENABLE_NODE
, &no_debug_static_cmd
);
6761 install_element (ENABLE_NODE
, &debug_pim_cmd
);
6762 install_element (ENABLE_NODE
, &no_debug_pim_cmd
);
6763 install_element (ENABLE_NODE
, &debug_pim_events_cmd
);
6764 install_element (ENABLE_NODE
, &no_debug_pim_events_cmd
);
6765 install_element (ENABLE_NODE
, &debug_pim_packets_cmd
);
6766 install_element (ENABLE_NODE
, &no_debug_pim_packets_cmd
);
6767 install_element (ENABLE_NODE
, &debug_pim_packetdump_send_cmd
);
6768 install_element (ENABLE_NODE
, &no_debug_pim_packetdump_send_cmd
);
6769 install_element (ENABLE_NODE
, &debug_pim_packetdump_recv_cmd
);
6770 install_element (ENABLE_NODE
, &no_debug_pim_packetdump_recv_cmd
);
6771 install_element (ENABLE_NODE
, &debug_pim_trace_cmd
);
6772 install_element (ENABLE_NODE
, &no_debug_pim_trace_cmd
);
6773 install_element (ENABLE_NODE
, &debug_ssmpingd_cmd
);
6774 install_element (ENABLE_NODE
, &no_debug_ssmpingd_cmd
);
6775 install_element (ENABLE_NODE
, &debug_pim_zebra_cmd
);
6776 install_element (ENABLE_NODE
, &no_debug_pim_zebra_cmd
);
6777 install_element (ENABLE_NODE
, &debug_msdp_cmd
);
6778 install_element (ENABLE_NODE
, &no_debug_msdp_cmd
);
6779 install_element (ENABLE_NODE
, &undebug_msdp_cmd
);
6780 install_element (ENABLE_NODE
, &debug_msdp_events_cmd
);
6781 install_element (ENABLE_NODE
, &no_debug_msdp_events_cmd
);
6782 install_element (ENABLE_NODE
, &undebug_msdp_events_cmd
);
6783 install_element (ENABLE_NODE
, &debug_msdp_packets_cmd
);
6784 install_element (ENABLE_NODE
, &no_debug_msdp_packets_cmd
);
6785 install_element (ENABLE_NODE
, &undebug_msdp_packets_cmd
);
6787 install_element (CONFIG_NODE
, &debug_igmp_cmd
);
6788 install_element (CONFIG_NODE
, &no_debug_igmp_cmd
);
6789 install_element (CONFIG_NODE
, &debug_igmp_events_cmd
);
6790 install_element (CONFIG_NODE
, &no_debug_igmp_events_cmd
);
6791 install_element (CONFIG_NODE
, &debug_igmp_packets_cmd
);
6792 install_element (CONFIG_NODE
, &no_debug_igmp_packets_cmd
);
6793 install_element (CONFIG_NODE
, &debug_igmp_trace_cmd
);
6794 install_element (CONFIG_NODE
, &no_debug_igmp_trace_cmd
);
6795 install_element (CONFIG_NODE
, &debug_mroute_cmd
);
6796 install_element (CONFIG_NODE
, &debug_mroute_detail_cmd
);
6797 install_element (CONFIG_NODE
, &no_debug_mroute_cmd
);
6798 install_element (CONFIG_NODE
, &no_debug_mroute_detail_cmd
);
6799 install_element (CONFIG_NODE
, &debug_static_cmd
);
6800 install_element (CONFIG_NODE
, &no_debug_static_cmd
);
6801 install_element (CONFIG_NODE
, &debug_pim_cmd
);
6802 install_element (CONFIG_NODE
, &no_debug_pim_cmd
);
6803 install_element (CONFIG_NODE
, &debug_pim_events_cmd
);
6804 install_element (CONFIG_NODE
, &no_debug_pim_events_cmd
);
6805 install_element (CONFIG_NODE
, &debug_pim_packets_cmd
);
6806 install_element (CONFIG_NODE
, &no_debug_pim_packets_cmd
);
6807 install_element (CONFIG_NODE
, &debug_pim_trace_cmd
);
6808 install_element (CONFIG_NODE
, &no_debug_pim_trace_cmd
);
6809 install_element (CONFIG_NODE
, &debug_ssmpingd_cmd
);
6810 install_element (CONFIG_NODE
, &no_debug_ssmpingd_cmd
);
6811 install_element (CONFIG_NODE
, &debug_pim_zebra_cmd
);
6812 install_element (CONFIG_NODE
, &no_debug_pim_zebra_cmd
);
6813 install_element (CONFIG_NODE
, &debug_msdp_cmd
);
6814 install_element (CONFIG_NODE
, &no_debug_msdp_cmd
);
6815 install_element (CONFIG_NODE
, &undebug_msdp_cmd
);
6816 install_element (CONFIG_NODE
, &debug_msdp_events_cmd
);
6817 install_element (CONFIG_NODE
, &no_debug_msdp_events_cmd
);
6818 install_element (CONFIG_NODE
, &undebug_msdp_events_cmd
);
6819 install_element (CONFIG_NODE
, &debug_msdp_packets_cmd
);
6820 install_element (CONFIG_NODE
, &no_debug_msdp_packets_cmd
);
6821 install_element (CONFIG_NODE
, &undebug_msdp_packets_cmd
);
6822 install_element (CONFIG_NODE
, &ip_msdp_mesh_group_member_cmd
);
6823 install_element (CONFIG_NODE
, &no_ip_msdp_mesh_group_member_cmd
);
6824 install_element (CONFIG_NODE
, &ip_msdp_mesh_group_source_cmd
);
6825 install_element (CONFIG_NODE
, &no_ip_msdp_mesh_group_source_cmd
);
6826 install_element (VIEW_NODE
, &show_ip_msdp_peer_detail_cmd
);
6827 install_element (VIEW_NODE
, &show_ip_msdp_sa_detail_cmd
);
6828 install_element (VIEW_NODE
, &show_ip_msdp_sa_sg_cmd
);
6829 install_element (VIEW_NODE
, &show_ip_msdp_mesh_group_cmd
);
6830 install_element (VIEW_NODE
, &show_ip_pim_ssm_range_cmd
);
6831 install_element (VIEW_NODE
, &show_ip_pim_group_type_cmd
);
6832 install_element (INTERFACE_NODE
, &interface_pim_use_source_cmd
);
6833 install_element (INTERFACE_NODE
, &interface_no_pim_use_source_cmd
);