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 along
16 * with this program; see the file COPYING; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
32 #include "pim_mroute.h"
34 #include "pim_iface.h"
36 #include "pim_mroute.h"
39 #include "pim_igmpv3.h"
44 #include "pim_neighbor.h"
46 #include "pim_ifchannel.h"
47 #include "pim_hello.h"
49 #include "pim_upstream.h"
51 #include "pim_macro.h"
52 #include "pim_ssmpingd.h"
53 #include "pim_zebra.h"
54 #include "pim_static.h"
56 #include "pim_zlookup.h"
61 static struct cmd_node pim_global_node
= {
67 static struct cmd_node interface_node
= {
73 static struct cmd_node debug_node
=
80 static void pim_if_membership_clear(struct interface
*ifp
)
82 struct pim_interface
*pim_ifp
;
87 if (PIM_IF_TEST_PIM(pim_ifp
->options
) &&
88 PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
92 pim_ifchannel_membership_clear(ifp
);
96 When PIM is disabled on interface, IGMPv3 local membership
97 information is not injected into PIM interface state.
99 The function pim_if_membership_refresh() fetches all IGMPv3 local
100 membership information into PIM. It is intented to be called
101 whenever PIM is enabled on the interface in order to collect missed
102 local membership information.
104 static void pim_if_membership_refresh(struct interface
*ifp
)
106 struct pim_interface
*pim_ifp
;
107 struct listnode
*sock_node
;
108 struct igmp_sock
*igmp
;
113 if (!PIM_IF_TEST_PIM(pim_ifp
->options
))
115 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
))
119 First clear off membership from all PIM (S,G) entries on the
123 pim_ifchannel_membership_clear(ifp
);
126 Then restore PIM (S,G) membership from all IGMPv3 (S,G) entries on
130 /* scan igmp sockets */
131 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
132 struct listnode
*grpnode
;
133 struct igmp_group
*grp
;
135 /* scan igmp groups */
136 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grpnode
, grp
)) {
137 struct listnode
*srcnode
;
138 struct igmp_source
*src
;
140 /* scan group sources */
141 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
, srcnode
, src
)) {
143 if (IGMP_SOURCE_TEST_FORWARDING(src
->source_flags
)) {
146 memset (&sg
, 0, sizeof (struct prefix_sg
));
147 sg
.src
= src
->source_addr
;
148 sg
.grp
= grp
->group_addr
;
149 pim_ifchannel_local_membership_add(ifp
, &sg
);
152 } /* scan group sources */
153 } /* scan igmp groups */
154 } /* scan igmp sockets */
157 Finally delete every PIM (S,G) entry lacking all state info
160 pim_ifchannel_delete_on_noinfo(ifp
);
164 static void pim_show_assert(struct vty
*vty
)
166 struct pim_interface
*pim_ifp
;
167 struct pim_ifchannel
*ch
;
168 struct listnode
*ch_node
;
169 struct in_addr ifaddr
;
172 now
= pim_time_monotonic_sec();
175 "Interface Address Source Group State Winner Uptime Timer%s",
178 for (ALL_LIST_ELEMENTS_RO(pim_ifchannel_list
, ch_node
, ch
)) {
179 char ch_src_str
[INET_ADDRSTRLEN
];
180 char ch_grp_str
[INET_ADDRSTRLEN
];
181 char winner_str
[INET_ADDRSTRLEN
];
185 pim_ifp
= ch
->interface
->info
;
190 ifaddr
= pim_ifp
->primary_address
;
192 pim_inet4_dump("<ch_src?>", ch
->sg
.src
,
193 ch_src_str
, sizeof(ch_src_str
));
194 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
,
195 ch_grp_str
, sizeof(ch_grp_str
));
196 pim_inet4_dump("<assrt_win?>", ch
->ifassert_winner
,
197 winner_str
, sizeof(winner_str
));
199 pim_time_uptime(uptime
, sizeof(uptime
), now
- ch
->ifassert_creation
);
200 pim_time_timer_to_mmss(timer
, sizeof(timer
),
201 ch
->t_ifassert_timer
);
203 vty_out(vty
, "%-9s %-15s %-15s %-15s %-6s %-15s %-8s %-5s%s",
208 pim_ifchannel_ifassert_name(ch
->ifassert_state
),
213 } /* scan interface channels */
216 static void pim_show_assert_internal(struct vty
*vty
)
218 struct pim_interface
*pim_ifp
;
219 struct listnode
*ch_node
;
220 struct pim_ifchannel
*ch
;
221 struct in_addr ifaddr
;
225 "ECA: Evaluate CouldAssert%s"
226 "ATD: AssertTrackingDesired%s"
227 "eATD: Evaluate AssertTrackingDesired%s%s",
228 VTY_NEWLINE
, VTY_NEWLINE
, VTY_NEWLINE
, VTY_NEWLINE
, VTY_NEWLINE
);
231 "Interface Address Source Group CA eCA ATD eATD%s",
234 for (ALL_LIST_ELEMENTS_RO(pim_ifchannel_list
, ch_node
, ch
)) {
235 pim_ifp
= ch
->interface
->info
;
240 ifaddr
= pim_ifp
->primary_address
;
242 char ch_src_str
[INET_ADDRSTRLEN
];
243 char ch_grp_str
[INET_ADDRSTRLEN
];
245 pim_inet4_dump("<ch_src?>", ch
->sg
.src
,
246 ch_src_str
, sizeof(ch_src_str
));
247 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
,
248 ch_grp_str
, sizeof(ch_grp_str
));
249 vty_out(vty
, "%-9s %-15s %-15s %-15s %-3s %-3s %-3s %-4s%s",
254 PIM_IF_FLAG_TEST_COULD_ASSERT(ch
->flags
) ? "yes" : "no",
255 pim_macro_ch_could_assert_eval(ch
) ? "yes" : "no",
256 PIM_IF_FLAG_TEST_ASSERT_TRACKING_DESIRED(ch
->flags
) ? "yes" : "no",
257 pim_macro_assert_tracking_desired_eval(ch
) ? "yes" : "no",
259 } /* scan interface channels */
262 static void pim_show_assert_metric(struct vty
*vty
)
264 struct pim_interface
*pim_ifp
;
265 struct listnode
*ch_node
;
266 struct pim_ifchannel
*ch
;
267 struct in_addr ifaddr
;
270 "Interface Address Source Group RPT Pref Metric Address %s",
273 for (ALL_LIST_ELEMENTS_RO(pim_ifchannel_list
, ch_node
, ch
)) {
274 pim_ifp
= ch
->interface
->info
;
279 ifaddr
= pim_ifp
->primary_address
;
281 char ch_src_str
[INET_ADDRSTRLEN
];
282 char ch_grp_str
[INET_ADDRSTRLEN
];
283 char addr_str
[INET_ADDRSTRLEN
];
284 struct pim_assert_metric am
;
286 am
= pim_macro_spt_assert_metric(&ch
->upstream
->rpf
, pim_ifp
->primary_address
);
288 pim_inet4_dump("<ch_src?>", ch
->sg
.src
,
289 ch_src_str
, sizeof(ch_src_str
));
290 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
,
291 ch_grp_str
, sizeof(ch_grp_str
));
292 pim_inet4_dump("<addr?>", am
.ip_address
,
293 addr_str
, sizeof(addr_str
));
295 vty_out(vty
, "%-9s %-15s %-15s %-15s %-3s %4u %6u %-15s%s",
300 am
.rpt_bit_flag
? "yes" : "no",
301 am
.metric_preference
,
305 } /* scan interface channels */
308 static void pim_show_assert_winner_metric(struct vty
*vty
)
310 struct pim_interface
*pim_ifp
;
311 struct listnode
*ch_node
;
312 struct pim_ifchannel
*ch
;
313 struct in_addr ifaddr
;
316 "Interface Address Source Group RPT Pref Metric Address %s",
319 for (ALL_LIST_ELEMENTS_RO(pim_ifchannel_list
, ch_node
, ch
)) {
320 pim_ifp
= ch
->interface
->info
;
325 ifaddr
= pim_ifp
->primary_address
;
327 char ch_src_str
[INET_ADDRSTRLEN
];
328 char ch_grp_str
[INET_ADDRSTRLEN
];
329 char addr_str
[INET_ADDRSTRLEN
];
330 struct pim_assert_metric
*am
;
334 am
= &ch
->ifassert_winner_metric
;
336 pim_inet4_dump("<ch_src?>", ch
->sg
.src
,
337 ch_src_str
, sizeof(ch_src_str
));
338 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
,
339 ch_grp_str
, sizeof(ch_grp_str
));
340 pim_inet4_dump("<addr?>", am
->ip_address
,
341 addr_str
, sizeof(addr_str
));
343 if (am
->metric_preference
== PIM_ASSERT_METRIC_PREFERENCE_MAX
)
344 snprintf(pref_str
, sizeof(pref_str
), "INFI");
346 snprintf(pref_str
, sizeof(pref_str
), "%4u", am
->metric_preference
);
348 if (am
->route_metric
== PIM_ASSERT_ROUTE_METRIC_MAX
)
349 snprintf(metr_str
, sizeof(metr_str
), "INFI");
351 snprintf(metr_str
, sizeof(metr_str
), "%6u", am
->route_metric
);
353 vty_out(vty
, "%-9s %-15s %-15s %-15s %-3s %-4s %-6s %-15s%s",
358 am
->rpt_bit_flag
? "yes" : "no",
363 } /* scan interface channels */
366 static void json_object_pim_ifp_add(struct json_object
*json
, struct interface
*ifp
)
368 struct pim_interface
*pim_ifp
;
371 json_object_string_add(json
, "name", ifp
->name
);
372 json_object_string_add(json
, "state", if_is_up(ifp
) ? "up" : "down");
373 json_object_string_add(json
, "address", inet_ntoa(pim_ifp
->primary_address
));
374 json_object_int_add(json
, "index", ifp
->ifindex
);
376 if (if_is_multicast(ifp
))
377 json_object_boolean_true_add(json
, "flagMulticast");
379 if (if_is_broadcast(ifp
))
380 json_object_boolean_true_add(json
, "flagBroadcast");
382 if (ifp
->flags
& IFF_ALLMULTI
)
383 json_object_boolean_true_add(json
, "flagAllMulticast");
385 if (ifp
->flags
& IFF_PROMISC
)
386 json_object_boolean_true_add(json
, "flagPromiscuous");
388 if (PIM_IF_IS_DELETED(ifp
))
389 json_object_boolean_true_add(json
, "flagDeleted");
391 if (pim_if_lan_delay_enabled(ifp
))
392 json_object_boolean_true_add(json
, "lanDelayEnabled");
395 static void pim_show_membership(struct vty
*vty
, u_char uj
)
397 struct pim_interface
*pim_ifp
;
398 struct listnode
*ch_node
;
399 struct pim_ifchannel
*ch
;
401 json_object
*json
= NULL
;
402 json_object
*json_iface
= NULL
;
403 json_object
*json_row
= NULL
;
404 json_object
*json_tmp
= NULL
;
406 json
= json_object_new_object();
408 for (ALL_LIST_ELEMENTS_RO(pim_ifchannel_list
, ch_node
, ch
)) {
410 pim_ifp
= ch
->interface
->info
;
415 char ch_src_str
[INET_ADDRSTRLEN
];
416 char ch_grp_str
[INET_ADDRSTRLEN
];
418 pim_inet4_dump("<ch_src?>", ch
->sg
.src
,
419 ch_src_str
, sizeof(ch_src_str
));
420 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
,
421 ch_grp_str
, sizeof(ch_grp_str
));
423 json_object_object_get_ex(json
, ch
->interface
->name
, &json_iface
);
426 json_iface
= json_object_new_object();
427 json_object_pim_ifp_add(json_iface
, ch
->interface
);
428 json_object_object_add(json
, ch
->interface
->name
, json_iface
);
431 json_row
= json_object_new_object();
432 json_object_string_add(json_row
, "source", ch_src_str
);
433 json_object_string_add(json_row
, "group", ch_grp_str
);
434 json_object_string_add(json_row
, "localMembership",
435 ch
->local_ifmembership
== PIM_IFMEMBERSHIP_NOINFO
? "NOINFO" : "INCLUDE");
436 json_object_object_add(json_iface
, ch_grp_str
, json_row
);
437 } /* scan interface channels */
440 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
443 "Interface Address Source Group Membership%s",
447 * Example of the json data we are traversing
453 * "address":"10.1.20.1",
455 * "flagMulticast":true,
456 * "flagBroadcast":true,
457 * "lanDelayEnabled":true,
460 * "group":"226.10.10.10",
461 * "localMembership":"INCLUDE"
467 /* foreach interface */
468 json_object_object_foreach(json
, key
, val
) {
470 /* Find all of the keys where the val is an object. In the example
471 * above the only one is 226.10.10.10
473 json_object_object_foreach(val
, if_field_key
, if_field_val
) {
474 type
= json_object_get_type(if_field_val
);
476 if (type
== json_type_object
) {
477 vty_out(vty
, "%-9s ", key
);
479 json_object_object_get_ex(val
, "address", &json_tmp
);
480 vty_out(vty
, "%-15s ", json_object_get_string(json_tmp
));
482 json_object_object_get_ex(if_field_val
, "source", &json_tmp
);
483 vty_out(vty
, "%-15s ", json_object_get_string(json_tmp
));
486 vty_out(vty
, "%-15s ", if_field_key
);
488 json_object_object_get_ex(if_field_val
, "localMembership", &json_tmp
);
489 vty_out(vty
, "%-10s%s", json_object_get_string(json_tmp
), VTY_NEWLINE
);
495 json_object_free(json
);
498 static void pim_print_ifp_flags(struct vty
*vty
, struct interface
*ifp
, int mloop
)
500 vty_out(vty
, "Flags%s", VTY_NEWLINE
);
501 vty_out(vty
, "-----%s", VTY_NEWLINE
);
502 vty_out(vty
, "All Multicast : %s%s", (ifp
->flags
& IFF_ALLMULTI
) ? "yes" : "no", VTY_NEWLINE
);
503 vty_out(vty
, "Broadcast : %s%s", if_is_broadcast(ifp
)? "yes" : "no", VTY_NEWLINE
);
504 vty_out(vty
, "Deleted : %s%s", PIM_IF_IS_DELETED(ifp
) ? "yes" : "no", VTY_NEWLINE
);
505 vty_out(vty
, "Interface Index : %d%s", ifp
->ifindex
, VTY_NEWLINE
);
506 vty_out(vty
, "Multicast : %s%s", if_is_multicast(ifp
) ? "yes" : "no", VTY_NEWLINE
);
507 vty_out(vty
, "Multicast Loop : %d%s", mloop
, VTY_NEWLINE
);
508 vty_out(vty
, "Promiscuous : %s%s", (ifp
->flags
& IFF_PROMISC
) ? "yes" : "no", VTY_NEWLINE
);
509 vty_out(vty
, "%s", VTY_NEWLINE
);
510 vty_out(vty
, "%s", VTY_NEWLINE
);
513 static void igmp_show_interfaces(struct vty
*vty
, u_char uj
)
515 struct listnode
*node
;
516 struct interface
*ifp
;
518 json_object
*json
= NULL
;
519 json_object
*json_row
= NULL
;
521 now
= pim_time_monotonic_sec();
524 json
= json_object_new_object();
527 "Interface State Address V Querier Query Timer Uptime%s",
530 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), node
, ifp
)) {
531 struct pim_interface
*pim_ifp
;
532 struct listnode
*sock_node
;
533 struct igmp_sock
*igmp
;
540 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
542 char query_hhmmss
[10];
544 pim_time_uptime(uptime
, sizeof(uptime
), now
- igmp
->sock_creation
);
545 pim_time_timer_to_hhmmss(query_hhmmss
, sizeof(query_hhmmss
), igmp
->t_igmp_query_timer
);
548 json_row
= json_object_new_object();
549 json_object_pim_ifp_add(json_row
, ifp
);
550 json_object_string_add(json_row
, "upTime", uptime
);
551 json_object_int_add(json_row
, "version", pim_ifp
->igmp_version
);
553 if (igmp
->t_igmp_query_timer
) {
554 json_object_boolean_true_add(json_row
, "querier");
555 json_object_string_add(json_row
, "queryTimer", query_hhmmss
);
558 json_object_object_add(json
, ifp
->name
, json_row
);
561 vty_out(vty
, "%-9s %5s %15s %d %7s %11s %8s%s",
563 if_is_up(ifp
) ? "up" : "down",
564 inet_ntoa(igmp
->ifaddr
),
565 pim_ifp
->igmp_version
,
566 igmp
->t_igmp_query_timer
? "local" : "other",
575 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
576 json_object_free(json
);
580 static void igmp_show_interfaces_single(struct vty
*vty
, const char *ifname
, u_char uj
)
582 struct igmp_sock
*igmp
;
583 struct interface
*ifp
;
584 struct listnode
*node
;
585 struct listnode
*sock_node
;
586 struct pim_interface
*pim_ifp
;
588 char query_hhmmss
[10];
589 char other_hhmmss
[10];
590 int found_ifname
= 0;
593 long gmi_msec
; /* Group Membership Interval */
596 long oqpi_msec
; /* Other Querier Present Interval */
600 json_object
*json
= NULL
;
601 json_object
*json_row
= NULL
;
604 json
= json_object_new_object();
606 now
= pim_time_monotonic_sec();
608 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), node
, ifp
)) {
614 if (strcmp(ifname
, "detail") && strcmp(ifname
, ifp
->name
))
617 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
619 pim_time_uptime(uptime
, sizeof(uptime
), now
- igmp
->sock_creation
);
620 pim_time_timer_to_hhmmss(query_hhmmss
, sizeof(query_hhmmss
), igmp
->t_igmp_query_timer
);
621 pim_time_timer_to_hhmmss(other_hhmmss
, sizeof(other_hhmmss
), igmp
->t_other_querier_timer
);
623 gmi_msec
= PIM_IGMP_GMI_MSEC(igmp
->querier_robustness_variable
,
624 igmp
->querier_query_interval
,
625 pim_ifp
->igmp_query_max_response_time_dsec
);
627 sqi
= PIM_IGMP_SQI(pim_ifp
->igmp_default_query_interval
);
629 oqpi_msec
= PIM_IGMP_OQPI_MSEC(igmp
->querier_robustness_variable
,
630 igmp
->querier_query_interval
,
631 pim_ifp
->igmp_query_max_response_time_dsec
);
633 lmqt_msec
= PIM_IGMP_LMQT_MSEC(pim_ifp
->igmp_query_max_response_time_dsec
,
634 igmp
->querier_robustness_variable
);
636 ohpi_msec
= PIM_IGMP_OHPI_DSEC(igmp
->querier_robustness_variable
,
637 igmp
->querier_query_interval
,
638 pim_ifp
->igmp_query_max_response_time_dsec
) * 100;
640 qri_msec
= pim_ifp
->igmp_query_max_response_time_dsec
* 100;
641 mloop
= pim_socket_mcastloop_get(pim_ifp
->pim_sock_fd
);
644 json_row
= json_object_new_object();
645 json_object_pim_ifp_add(json_row
, ifp
);
646 json_object_string_add(json_row
, "upTime", uptime
);
647 json_object_string_add(json_row
, "querier", igmp
->t_igmp_query_timer
? "local" : "other");
648 json_object_int_add(json_row
, "queryStartCount", igmp
->startup_query_count
);
649 json_object_string_add(json_row
, "queryQueryTimer", query_hhmmss
);
650 json_object_string_add(json_row
, "queryOtherTimer", other_hhmmss
);
651 json_object_int_add(json_row
, "version", pim_ifp
->igmp_version
);
652 json_object_int_add(json_row
, "timerGroupMembershipIntervalMsec", gmi_msec
);
653 json_object_int_add(json_row
, "timerLastMemberQueryMsec", lmqt_msec
);
654 json_object_int_add(json_row
, "timerOlderHostPresentIntervalMsec", ohpi_msec
);
655 json_object_int_add(json_row
, "timerOtherQuerierPresentIntervalMsec", oqpi_msec
);
656 json_object_int_add(json_row
, "timerQueryInterval", igmp
->querier_query_interval
);
657 json_object_int_add(json_row
, "timerQueryResponseIntervalMsec", qri_msec
);
658 json_object_int_add(json_row
, "timerRobustnessVariable", igmp
->querier_robustness_variable
);
659 json_object_int_add(json_row
, "timerStartupQueryInterval", sqi
);
661 json_object_object_add(json
, ifp
->name
, json_row
);
664 vty_out(vty
, "Interface : %s%s", ifp
->name
, VTY_NEWLINE
);
665 vty_out(vty
, "State : %s%s", if_is_up(ifp
) ? "up" : "down", VTY_NEWLINE
);
666 vty_out(vty
, "Address : %s%s", inet_ntoa(pim_ifp
->primary_address
), VTY_NEWLINE
);
667 vty_out(vty
, "Uptime : %s%s", uptime
, VTY_NEWLINE
);
668 vty_out(vty
, "Version : %d%s", pim_ifp
->igmp_version
, VTY_NEWLINE
);
669 vty_out(vty
, "%s", VTY_NEWLINE
);
670 vty_out(vty
, "%s", VTY_NEWLINE
);
672 vty_out(vty
, "Querier%s", VTY_NEWLINE
);
673 vty_out(vty
, "-------%s", VTY_NEWLINE
);
674 vty_out(vty
, "Querier : %s%s", igmp
->t_igmp_query_timer
? "local" : "other", VTY_NEWLINE
);
675 vty_out(vty
, "Start Count : %d%s", igmp
->startup_query_count
, VTY_NEWLINE
);
676 vty_out(vty
, "Query Timer : %s%s", query_hhmmss
, VTY_NEWLINE
);
677 vty_out(vty
, "Other Timer : %s%s", other_hhmmss
, VTY_NEWLINE
);
678 vty_out(vty
, "%s", VTY_NEWLINE
);
679 vty_out(vty
, "%s", VTY_NEWLINE
);
681 vty_out(vty
, "Timers%s", VTY_NEWLINE
);
682 vty_out(vty
, "------%s", VTY_NEWLINE
);
683 vty_out(vty
, "Group Membership Interval : %lis%s", gmi_msec
/1000, VTY_NEWLINE
);
684 vty_out(vty
, "Last Member Query Time : %lis%s", lmqt_msec
/1000, VTY_NEWLINE
);
685 vty_out(vty
, "Older Host Present Interval : %lis%s", ohpi_msec
/1000, VTY_NEWLINE
);
686 vty_out(vty
, "Other Querier Present Interval : %lis%s", oqpi_msec
/1000, VTY_NEWLINE
);
687 vty_out(vty
, "Query Interval : %ds%s", igmp
->querier_query_interval
, VTY_NEWLINE
);
688 vty_out(vty
, "Query Response Interval : %lis%s", qri_msec
/1000, VTY_NEWLINE
);
689 vty_out(vty
, "Robustness Variable : %d%s", igmp
->querier_robustness_variable
, VTY_NEWLINE
);
690 vty_out(vty
, "Startup Query Interval : %ds%s", sqi
, VTY_NEWLINE
);
691 vty_out(vty
, "%s", VTY_NEWLINE
);
692 vty_out(vty
, "%s", VTY_NEWLINE
);
694 pim_print_ifp_flags(vty
, ifp
, mloop
);
700 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
701 json_object_free(json
);
704 vty_out (vty
, "%% No such interface%s", VTY_NEWLINE
);
708 static void igmp_show_interface_join(struct vty
*vty
)
710 struct listnode
*node
;
711 struct interface
*ifp
;
714 now
= pim_time_monotonic_sec();
717 "Interface Address Source Group Socket Uptime %s",
720 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), node
, ifp
)) {
721 struct pim_interface
*pim_ifp
;
722 struct listnode
*join_node
;
723 struct igmp_join
*ij
;
724 struct in_addr pri_addr
;
725 char pri_addr_str
[INET_ADDRSTRLEN
];
732 if (!pim_ifp
->igmp_join_list
)
735 pri_addr
= pim_find_primary_addr(ifp
);
736 pim_inet4_dump("<pri?>", pri_addr
, pri_addr_str
, sizeof(pri_addr_str
));
738 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_join_list
, join_node
, ij
)) {
739 char group_str
[INET_ADDRSTRLEN
];
740 char source_str
[INET_ADDRSTRLEN
];
743 pim_time_uptime(uptime
, sizeof(uptime
), now
- ij
->sock_creation
);
744 pim_inet4_dump("<grp?>", ij
->group_addr
, group_str
, sizeof(group_str
));
745 pim_inet4_dump("<src?>", ij
->source_addr
, source_str
, sizeof(source_str
));
747 vty_out(vty
, "%-9s %-15s %-15s %-15s %6d %8s%s",
755 } /* for (pim_ifp->igmp_join_list) */
761 static void pim_show_interfaces_single(struct vty
*vty
, const char *ifname
, u_char uj
)
763 struct in_addr ifaddr
;
764 struct interface
*ifp
;
765 struct listnode
*neighnode
;
766 struct listnode
*node
;
767 struct listnode
*upnode
;
768 struct pim_interface
*pim_ifp
;
769 struct pim_neighbor
*neigh
;
770 struct pim_upstream
*up
;
772 char dr_str
[INET_ADDRSTRLEN
];
775 char grp_str
[INET_ADDRSTRLEN
];
776 char hello_period
[10];
777 char hello_timer
[10];
778 char neigh_src_str
[INET_ADDRSTRLEN
];
779 char src_str
[INET_ADDRSTRLEN
];
780 char stat_uptime
[10];
783 int found_ifname
= 0;
785 json_object
*json
= NULL
;
786 json_object
*json_row
= NULL
;
787 json_object
*json_pim_neighbor
= NULL
;
788 json_object
*json_pim_neighbors
= NULL
;
789 json_object
*json_group
= NULL
;
790 json_object
*json_group_source
= NULL
;
791 json_object
*json_fhr_sources
= NULL
;
792 struct pim_secondary_addr
*sec_addr
;
793 struct listnode
*sec_node
;
795 now
= pim_time_monotonic_sec();
798 json
= json_object_new_object();
800 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), node
, ifp
)) {
806 if (pim_ifp
->pim_sock_fd
< 0)
809 if (strcmp(ifname
, "detail") && strcmp(ifname
, ifp
->name
))
813 ifaddr
= pim_ifp
->primary_address
;
814 pim_inet4_dump("<dr?>", pim_ifp
->pim_dr_addr
, dr_str
, sizeof(dr_str
));
815 pim_time_uptime_begin(dr_uptime
, sizeof(dr_uptime
), now
, pim_ifp
->pim_dr_election_last
);
816 pim_time_timer_to_hhmmss(hello_timer
, sizeof(hello_timer
), pim_ifp
->t_pim_hello_timer
);
817 pim_time_mmss(hello_period
, sizeof(hello_period
), pim_ifp
->pim_hello_period
);
818 pim_time_uptime(stat_uptime
, sizeof(stat_uptime
), now
- pim_ifp
->pim_ifstat_start
);
819 mloop
= pim_socket_mcastloop_get(pim_ifp
->pim_sock_fd
);
822 char pbuf
[PREFIX2STR_BUFFER
];
823 json_row
= json_object_new_object();
824 json_object_pim_ifp_add(json_row
, ifp
);
826 if (pim_ifp
->update_source
.s_addr
!= INADDR_ANY
) {
827 json_object_string_add(json_row
, "useSource", inet_ntoa(pim_ifp
->update_source
));
829 if (pim_ifp
->sec_addr_list
) {
830 json_object
*sec_list
= NULL
;
832 sec_list
= json_object_new_array();
833 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->sec_addr_list
, sec_node
, sec_addr
)) {
834 json_object_array_add(sec_list
,
835 json_object_new_string(prefix2str(&sec_addr
->addr
,
839 json_object_object_add(json_row
, "secondaryAddressList", sec_list
);
843 if (pim_ifp
->pim_neighbor_list
->count
) {
844 json_pim_neighbors
= json_object_new_object();
846 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
, neigh
)) {
847 json_pim_neighbor
= json_object_new_object();
848 pim_inet4_dump("<src?>", neigh
->source_addr
, neigh_src_str
, sizeof(neigh_src_str
));
849 pim_time_uptime(uptime
, sizeof(uptime
), now
- neigh
->creation
);
850 pim_time_timer_to_hhmmss(expire
, sizeof(expire
), neigh
->t_expire_timer
);
852 json_object_string_add(json_pim_neighbor
, "address", neigh_src_str
);
853 json_object_string_add(json_pim_neighbor
, "upTime", uptime
);
854 json_object_string_add(json_pim_neighbor
, "holdtime", expire
);
856 json_object_object_add(json_pim_neighbors
, neigh_src_str
, json_pim_neighbor
);
859 json_object_object_add(json_row
, "neighbors", json_pim_neighbors
);
862 json_object_string_add(json_row
, "drAddress", dr_str
);
863 json_object_int_add(json_row
, "drPriority", pim_ifp
->pim_dr_priority
);
864 json_object_string_add(json_row
, "drUptime", dr_uptime
);
865 json_object_int_add(json_row
, "drElections", pim_ifp
->pim_dr_election_count
);
866 json_object_int_add(json_row
, "drChanges", pim_ifp
->pim_dr_election_changes
);
869 for (ALL_LIST_ELEMENTS_RO(pim_upstream_list
, upnode
, up
)) {
870 if (ifp
== up
->rpf
.source_nexthop
.interface
) {
871 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
) {
872 if (!json_fhr_sources
) {
873 json_fhr_sources
= json_object_new_object();
876 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
877 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
878 pim_time_uptime(uptime
, sizeof(uptime
), now
- up
->state_transition
);
880 /* Does this group live in json_fhr_sources? If not create it. */
881 json_object_object_get_ex(json_fhr_sources
, grp_str
, &json_group
);
884 json_group
= json_object_new_object();
885 json_object_object_add(json_fhr_sources
, grp_str
, json_group
);
888 json_group_source
= json_object_new_object();
889 json_object_string_add(json_group_source
, "source", src_str
);
890 json_object_string_add(json_group_source
, "group", grp_str
);
891 json_object_string_add(json_group_source
, "upTime", uptime
);
892 json_object_object_add(json_group
, src_str
, json_group_source
);
897 if (json_fhr_sources
) {
898 json_object_object_add(json_row
, "firstHopRouter", json_fhr_sources
);
901 json_object_int_add(json_row
, "helloPeriod", pim_ifp
->pim_hello_period
);
902 json_object_string_add(json_row
, "helloTimer", hello_timer
);
903 json_object_string_add(json_row
, "helloStatStart", stat_uptime
);
904 json_object_int_add(json_row
, "helloReceived", pim_ifp
->pim_ifstat_hello_recv
);
905 json_object_int_add(json_row
, "helloReceivedFailed", pim_ifp
->pim_ifstat_hello_recvfail
);
906 json_object_int_add(json_row
, "helloSend", pim_ifp
->pim_ifstat_hello_sent
);
907 json_object_int_add(json_row
, "hellosendFailed", pim_ifp
->pim_ifstat_hello_sendfail
);
908 json_object_int_add(json_row
, "helloGenerationId", pim_ifp
->pim_generation_id
);
909 json_object_int_add(json_row
, "flagMulticastLoop", mloop
);
911 json_object_int_add(json_row
, "effectivePropagationDelay", pim_if_effective_propagation_delay_msec(ifp
));
912 json_object_int_add(json_row
, "effectiveOverrideInterval", pim_if_effective_override_interval_msec(ifp
));
913 json_object_int_add(json_row
, "joinPruneOverrideInterval", pim_if_jp_override_interval_msec(ifp
));
915 json_object_int_add(json_row
, "propagationDelay", pim_ifp
->pim_propagation_delay_msec
);
916 json_object_int_add(json_row
, "propagationDelayHighest", pim_ifp
->pim_neighbors_highest_propagation_delay_msec
);
917 json_object_int_add(json_row
, "overrideInterval", pim_ifp
->pim_override_interval_msec
);
918 json_object_int_add(json_row
, "overrideIntervalHighest", pim_ifp
->pim_neighbors_highest_override_interval_msec
);
919 json_object_object_add(json
, ifp
->name
, json_row
);
922 vty_out(vty
, "Interface : %s%s", ifp
->name
, VTY_NEWLINE
);
923 vty_out(vty
, "State : %s%s", if_is_up(ifp
) ? "up" : "down", VTY_NEWLINE
);
924 if (pim_ifp
->update_source
.s_addr
!= INADDR_ANY
) {
925 vty_out(vty
, "Use Source : %s%s", inet_ntoa(pim_ifp
->update_source
), VTY_NEWLINE
);
927 if (pim_ifp
->sec_addr_list
) {
928 char pbuf
[PREFIX2STR_BUFFER
];
929 vty_out(vty
, "Address : %s (primary)%s",
930 inet_ntoa(ifaddr
), VTY_NEWLINE
);
931 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->sec_addr_list
, sec_node
, sec_addr
)) {
932 vty_out(vty
, " %s%s",
933 prefix2str(&sec_addr
->addr
,
935 sizeof(pbuf
)), VTY_NEWLINE
);
938 vty_out(vty
, "Address : %s%s", inet_ntoa(ifaddr
), VTY_NEWLINE
);
940 vty_out(vty
, "%s", VTY_NEWLINE
);
945 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
, neigh
)) {
948 vty_out(vty
, "PIM Neighbors%s", VTY_NEWLINE
);
949 vty_out(vty
, "-------------%s", VTY_NEWLINE
);
953 pim_inet4_dump("<src?>", neigh
->source_addr
, neigh_src_str
, sizeof(neigh_src_str
));
954 pim_time_uptime(uptime
, sizeof(uptime
), now
- neigh
->creation
);
955 pim_time_timer_to_hhmmss(expire
, sizeof(expire
), neigh
->t_expire_timer
);
956 vty_out(vty
, "%-15s : up for %s, holdtime expires in %s%s", neigh_src_str
, uptime
, expire
, VTY_NEWLINE
);
960 vty_out(vty
, "%s", VTY_NEWLINE
);
961 vty_out(vty
, "%s", VTY_NEWLINE
);
964 vty_out(vty
, "Designated Router%s", VTY_NEWLINE
);
965 vty_out(vty
, "-----------------%s", VTY_NEWLINE
);
966 vty_out(vty
, "Address : %s%s", dr_str
, VTY_NEWLINE
);
967 vty_out(vty
, "Priority : %d%s", pim_ifp
->pim_dr_priority
, VTY_NEWLINE
);
968 vty_out(vty
, "Uptime : %s%s", dr_uptime
, VTY_NEWLINE
);
969 vty_out(vty
, "Elections : %d%s", pim_ifp
->pim_dr_election_count
, VTY_NEWLINE
);
970 vty_out(vty
, "Changes : %d%s", pim_ifp
->pim_dr_election_changes
, VTY_NEWLINE
);
971 vty_out(vty
, "%s", VTY_NEWLINE
);
972 vty_out(vty
, "%s", VTY_NEWLINE
);
976 for (ALL_LIST_ELEMENTS_RO(pim_upstream_list
, upnode
, up
)) {
977 if (strcmp(ifp
->name
, up
->rpf
.source_nexthop
.interface
->name
) == 0) {
978 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
) {
981 vty_out(vty
, "FHR - First Hop Router%s", VTY_NEWLINE
);
982 vty_out(vty
, "----------------------%s", VTY_NEWLINE
);
986 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
987 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
988 pim_time_uptime(uptime
, sizeof(uptime
), now
- up
->state_transition
);
989 vty_out(vty
, "%s : %s is a source, uptime is %s%s", grp_str
, src_str
, uptime
, VTY_NEWLINE
);
995 vty_out(vty
, "%s", VTY_NEWLINE
);
996 vty_out(vty
, "%s", VTY_NEWLINE
);
999 vty_out(vty
, "Hellos%s", VTY_NEWLINE
);
1000 vty_out(vty
, "------%s", VTY_NEWLINE
);
1001 vty_out(vty
, "Period : %d%s", pim_ifp
->pim_hello_period
, VTY_NEWLINE
);
1002 vty_out(vty
, "Timer : %s%s", hello_timer
, VTY_NEWLINE
);
1003 vty_out(vty
, "StatStart : %s%s", stat_uptime
, VTY_NEWLINE
);
1004 vty_out(vty
, "Receive : %d%s", pim_ifp
->pim_ifstat_hello_recv
, VTY_NEWLINE
);
1005 vty_out(vty
, "Receive Failed : %d%s", pim_ifp
->pim_ifstat_hello_recvfail
, VTY_NEWLINE
);
1006 vty_out(vty
, "Send : %d%s", pim_ifp
->pim_ifstat_hello_sent
, VTY_NEWLINE
);
1007 vty_out(vty
, "Send Failed : %d%s", pim_ifp
->pim_ifstat_hello_sendfail
, VTY_NEWLINE
);
1008 vty_out(vty
, "Generation ID : %08x%s", pim_ifp
->pim_generation_id
, VTY_NEWLINE
);
1009 vty_out(vty
, "%s", VTY_NEWLINE
);
1010 vty_out(vty
, "%s", VTY_NEWLINE
);
1012 pim_print_ifp_flags(vty
, ifp
, mloop
);
1014 vty_out(vty
, "Join Prune Interval%s", VTY_NEWLINE
);
1015 vty_out(vty
, "-------------------%s", VTY_NEWLINE
);
1016 vty_out(vty
, "LAN Delay : %s%s", pim_if_lan_delay_enabled(ifp
) ? "yes" : "no", VTY_NEWLINE
);
1017 vty_out(vty
, "Effective Propagation Delay : %d msec%s", pim_if_effective_propagation_delay_msec(ifp
), VTY_NEWLINE
);
1018 vty_out(vty
, "Effective Override Interval : %d msec%s", pim_if_effective_override_interval_msec(ifp
), VTY_NEWLINE
);
1019 vty_out(vty
, "Join Prune Override Interval : %d msec%s", pim_if_jp_override_interval_msec(ifp
), VTY_NEWLINE
);
1020 vty_out(vty
, "%s", VTY_NEWLINE
);
1021 vty_out(vty
, "%s", VTY_NEWLINE
);
1023 vty_out(vty
, "LAN Prune Delay%s", VTY_NEWLINE
);
1024 vty_out(vty
, "---------------%s", VTY_NEWLINE
);
1025 vty_out(vty
, "Propagation Delay : %d msec%s", pim_ifp
->pim_propagation_delay_msec
, VTY_NEWLINE
);
1026 vty_out(vty
, "Propagation Delay (Highest) : %d msec%s", pim_ifp
->pim_neighbors_highest_propagation_delay_msec
, VTY_NEWLINE
);
1027 vty_out(vty
, "Override Interval : %d msec%s", pim_ifp
->pim_override_interval_msec
, VTY_NEWLINE
);
1028 vty_out(vty
, "Override Interval (Highest) : %d msec%s", pim_ifp
->pim_neighbors_highest_override_interval_msec
, VTY_NEWLINE
);
1029 vty_out(vty
, "%s", VTY_NEWLINE
);
1030 vty_out(vty
, "%s", VTY_NEWLINE
);
1035 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
1036 json_object_free(json
);
1039 vty_out (vty
, "%% No such interface%s", VTY_NEWLINE
);
1043 static void pim_show_interfaces(struct vty
*vty
, u_char uj
)
1045 struct interface
*ifp
;
1046 struct listnode
*node
;
1047 struct listnode
*upnode
;
1048 struct pim_interface
*pim_ifp
;
1049 struct pim_upstream
*up
;
1052 int pim_ifchannels
= 0;
1053 json_object
*json
= NULL
;
1054 json_object
*json_row
= NULL
;
1055 json_object
*json_tmp
;
1057 json
= json_object_new_object();
1059 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), node
, ifp
)) {
1060 pim_ifp
= ifp
->info
;
1065 if (pim_ifp
->pim_sock_fd
< 0)
1068 pim_nbrs
= pim_ifp
->pim_neighbor_list
->count
;
1069 pim_ifchannels
= pim_ifp
->pim_ifchannel_list
->count
;
1072 for (ALL_LIST_ELEMENTS_RO(pim_upstream_list
, upnode
, up
))
1073 if (ifp
== up
->rpf
.source_nexthop
.interface
)
1074 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
)
1077 json_row
= json_object_new_object();
1078 json_object_pim_ifp_add(json_row
, ifp
);
1079 json_object_int_add(json_row
, "pimNeighbors", pim_nbrs
);
1080 json_object_int_add(json_row
, "pimIfChannels", pim_ifchannels
);
1081 json_object_int_add(json_row
, "firstHopRouter", fhr
);
1082 json_object_string_add(json_row
, "pimDesignatedRouter", inet_ntoa(pim_ifp
->pim_dr_addr
));
1084 if (pim_ifp
->pim_dr_addr
.s_addr
== pim_ifp
->primary_address
.s_addr
)
1085 json_object_boolean_true_add(json_row
, "pimDesignatedRouterLocal");
1087 json_object_object_add(json
, ifp
->name
, json_row
);
1091 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
1093 vty_out(vty
, "Interface State Address PIM Nbrs PIM DR FHR IfChannels%s", VTY_NEWLINE
);
1095 json_object_object_foreach(json
, key
, val
) {
1096 vty_out(vty
, "%-9s ", key
);
1098 json_object_object_get_ex(val
, "state", &json_tmp
);
1099 vty_out(vty
, "%5s ", json_object_get_string(json_tmp
));
1101 json_object_object_get_ex(val
, "address", &json_tmp
);
1102 vty_out(vty
, "%15s ", json_object_get_string(json_tmp
));
1104 json_object_object_get_ex(val
, "pimNeighbors", &json_tmp
);
1105 vty_out(vty
, "%8d ", json_object_get_int(json_tmp
));
1107 if (json_object_object_get_ex(val
, "pimDesignatedRouterLocal", &json_tmp
)) {
1108 vty_out(vty
, "%15s ", "local");
1110 json_object_object_get_ex(val
, "pimDesignatedRouter", &json_tmp
);
1111 vty_out(vty
, "%15s ", json_object_get_string(json_tmp
));
1114 json_object_object_get_ex(val
, "firstHopRouter", &json_tmp
);
1115 vty_out(vty
, "%3d ", json_object_get_int(json_tmp
));
1117 json_object_object_get_ex(val
, "pimIfChannels", &json_tmp
);
1118 vty_out(vty
, "%9d%s", json_object_get_int(json_tmp
), VTY_NEWLINE
);
1122 json_object_free(json
);
1125 static void pim_show_interface_traffic (struct vty
*vty
, u_char uj
)
1127 struct interface
*ifp
= NULL
;
1128 struct pim_interface
*pim_ifp
= NULL
;
1129 struct listnode
*node
= NULL
;
1130 json_object
*json
= NULL
;
1131 json_object
*json_row
= NULL
;
1134 json
= json_object_new_object ();
1137 vty_out (vty
, "%s", VTY_NEWLINE
);
1138 vty_out (vty
, "%-12s%-17s%-17s%-17s%-17s%-17s%-17s%s", "Interface",
1139 " HELLO", " JOIN", " PRUNE", " REGISTER",
1140 " REGISTER-STOP", " ASSERT", VTY_NEWLINE
);
1142 "%-10s%-18s%-17s%-17s%-17s%-17s%-17s%s",
1143 "", " Rx/Tx", " Rx/Tx", " Rx/Tx", " Rx/Tx",
1144 " Rx/Tx", " Rx/Tx", VTY_NEWLINE
);
1146 "---------------------------------------------------------------------------------------------------------------%s",
1150 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), node
, ifp
))
1152 pim_ifp
= ifp
->info
;
1157 if (pim_ifp
->pim_sock_fd
< 0)
1161 json_row
= json_object_new_object ();
1162 json_object_pim_ifp_add (json_row
, ifp
);
1163 json_object_int_add (json_row
, "helloRx", pim_ifp
->pim_ifstat_hello_recv
);
1164 json_object_int_add (json_row
, "helloTx", pim_ifp
->pim_ifstat_hello_sent
);
1165 json_object_int_add (json_row
, "joinRx", pim_ifp
->pim_ifstat_join_recv
);
1166 json_object_int_add (json_row
, "joinTx", pim_ifp
->pim_ifstat_join_send
);
1167 json_object_int_add (json_row
, "registerRx", pim_ifp
->pim_ifstat_reg_recv
);
1168 json_object_int_add (json_row
, "registerTx", pim_ifp
->pim_ifstat_reg_recv
);
1169 json_object_int_add (json_row
, "registerStopRx", pim_ifp
->pim_ifstat_reg_stop_recv
);
1170 json_object_int_add (json_row
, "registerStopTx", pim_ifp
->pim_ifstat_reg_stop_send
);
1171 json_object_int_add (json_row
, "assertRx", pim_ifp
->pim_ifstat_assert_recv
);
1172 json_object_int_add (json_row
, "assertTx", pim_ifp
->pim_ifstat_assert_send
);
1174 json_object_object_add (json
, ifp
->name
, json_row
);
1179 "%-10s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %s",
1180 ifp
->name
, pim_ifp
->pim_ifstat_hello_recv
,
1181 pim_ifp
->pim_ifstat_hello_sent
, pim_ifp
->pim_ifstat_join_recv
,
1182 pim_ifp
->pim_ifstat_join_send
, pim_ifp
->pim_ifstat_prune_recv
,
1183 pim_ifp
->pim_ifstat_prune_send
, pim_ifp
->pim_ifstat_reg_recv
,
1184 pim_ifp
->pim_ifstat_reg_send
,
1185 pim_ifp
->pim_ifstat_reg_stop_recv
,
1186 pim_ifp
->pim_ifstat_reg_stop_send
,
1187 pim_ifp
->pim_ifstat_assert_recv
,
1188 pim_ifp
->pim_ifstat_assert_send
, VTY_NEWLINE
);
1193 vty_out (vty
, "%s%s", json_object_to_json_string_ext (json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
1194 json_object_free (json
);
1198 static void pim_show_interface_traffic_single (struct vty
*vty
, const char *ifname
, u_char uj
)
1200 struct interface
*ifp
= NULL
;
1201 struct pim_interface
*pim_ifp
= NULL
;
1202 struct listnode
*node
= NULL
;
1203 json_object
*json
= NULL
;
1204 json_object
*json_row
= NULL
;
1205 uint8_t found_ifname
= 0;
1208 json
= json_object_new_object ();
1211 vty_out (vty
, "%s", VTY_NEWLINE
);
1212 vty_out (vty
, "%-12s%-17s%-17s%-17s%-17s%-17s%-17s%s", "Interface",
1213 " HELLO", " JOIN", " PRUNE", " REGISTER",
1214 " REGISTER-STOP", " ASSERT", VTY_NEWLINE
);
1216 "%-10s%-18s%-17s%-17s%-17s%-17s%-17s%s",
1217 "", " Rx/Tx", " Rx/Tx", " Rx/Tx", " Rx/Tx",
1218 " Rx/Tx", " Rx/Tx", VTY_NEWLINE
);
1220 "---------------------------------------------------------------------------------------------------------------%s",
1224 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), node
, ifp
))
1226 if (strcmp (ifname
, ifp
->name
))
1229 pim_ifp
= ifp
->info
;
1234 if (pim_ifp
->pim_sock_fd
< 0)
1240 json_row
= json_object_new_object ();
1241 json_object_pim_ifp_add (json_row
, ifp
);
1242 json_object_int_add (json_row
, "helloRx", pim_ifp
->pim_ifstat_hello_recv
);
1243 json_object_int_add (json_row
, "helloTx", pim_ifp
->pim_ifstat_hello_sent
);
1244 json_object_int_add (json_row
, "joinRx", pim_ifp
->pim_ifstat_join_recv
);
1245 json_object_int_add (json_row
, "joinTx", pim_ifp
->pim_ifstat_join_send
);
1246 json_object_int_add (json_row
, "registerRx", pim_ifp
->pim_ifstat_reg_recv
);
1247 json_object_int_add (json_row
, "registerTx", pim_ifp
->pim_ifstat_reg_recv
);
1248 json_object_int_add (json_row
, "registerStopRx", pim_ifp
->pim_ifstat_reg_stop_recv
);
1249 json_object_int_add (json_row
, "registerStopTx", pim_ifp
->pim_ifstat_reg_stop_send
);
1250 json_object_int_add (json_row
, "assertRx", pim_ifp
->pim_ifstat_assert_recv
);
1251 json_object_int_add (json_row
, "assertTx", pim_ifp
->pim_ifstat_assert_send
);
1253 json_object_object_add (json
, ifp
->name
, json_row
);
1258 "%-10s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %s",
1259 ifp
->name
, pim_ifp
->pim_ifstat_hello_recv
,
1260 pim_ifp
->pim_ifstat_hello_sent
, pim_ifp
->pim_ifstat_join_recv
,
1261 pim_ifp
->pim_ifstat_join_send
, pim_ifp
->pim_ifstat_prune_recv
,
1262 pim_ifp
->pim_ifstat_prune_send
, pim_ifp
->pim_ifstat_reg_recv
,
1263 pim_ifp
->pim_ifstat_reg_send
,
1264 pim_ifp
->pim_ifstat_reg_stop_recv
,
1265 pim_ifp
->pim_ifstat_reg_stop_send
,
1266 pim_ifp
->pim_ifstat_assert_recv
,
1267 pim_ifp
->pim_ifstat_assert_send
, VTY_NEWLINE
);
1272 vty_out (vty
, "%s%s", json_object_to_json_string_ext (json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
1273 json_object_free (json
);
1278 vty_out (vty
, "%% No such interface%s", VTY_NEWLINE
);
1282 static void pim_show_join(struct vty
*vty
, u_char uj
)
1284 struct pim_interface
*pim_ifp
;
1285 struct in_addr ifaddr
;
1286 struct listnode
*ch_node
;
1287 struct pim_ifchannel
*ch
;
1289 json_object
*json
= NULL
;
1290 json_object
*json_iface
= NULL
;
1291 json_object
*json_row
= NULL
;
1292 json_object
*json_grp
= NULL
;
1294 now
= pim_time_monotonic_sec();
1297 json
= json_object_new_object();
1300 "Interface Address Source Group State Uptime Expire Prune%s",
1303 for (ALL_LIST_ELEMENTS_RO(pim_ifchannel_list
, ch_node
, ch
)) {
1305 pim_ifp
= ch
->interface
->info
;
1310 ifaddr
= pim_ifp
->primary_address
;
1312 char ch_src_str
[INET_ADDRSTRLEN
];
1313 char ch_grp_str
[INET_ADDRSTRLEN
];
1318 pim_inet4_dump("<ch_src?>", ch
->sg
.src
,
1319 ch_src_str
, sizeof(ch_src_str
));
1320 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
,
1321 ch_grp_str
, sizeof(ch_grp_str
));
1323 pim_time_uptime_begin(uptime
, sizeof(uptime
), now
, ch
->ifjoin_creation
);
1324 pim_time_timer_to_mmss(expire
, sizeof(expire
),
1325 ch
->t_ifjoin_expiry_timer
);
1326 pim_time_timer_to_mmss(prune
, sizeof(prune
),
1327 ch
->t_ifjoin_prune_pending_timer
);
1330 json_object_object_get_ex(json
, ch
->interface
->name
, &json_iface
);
1333 json_iface
= json_object_new_object();
1334 json_object_pim_ifp_add(json_iface
, ch
->interface
);
1335 json_object_object_add(json
, ch
->interface
->name
, json_iface
);
1338 json_row
= json_object_new_object();
1339 json_object_string_add(json_row
, "source", ch_src_str
);
1340 json_object_string_add(json_row
, "group", ch_grp_str
);
1341 json_object_string_add(json_row
, "upTime", uptime
);
1342 json_object_string_add(json_row
, "expire", expire
);
1343 json_object_string_add(json_row
, "prune", prune
);
1344 json_object_string_add(json_row
, "channelJoinName",
1345 pim_ifchannel_ifjoin_name(ch
->ifjoin_state
, ch
->flags
));
1346 if (PIM_IF_FLAG_TEST_S_G_RPT(ch
->flags
))
1347 json_object_int_add(json_row
, "SGRpt", 1);
1349 json_object_object_get_ex(json_iface
, ch_grp_str
, &json_grp
);
1352 json_grp
= json_object_new_object();
1353 json_object_object_add(json_grp
, ch_src_str
, json_row
);
1354 json_object_object_add(json_iface
, ch_grp_str
, json_grp
);
1357 json_object_object_add(json_grp
, ch_src_str
, json_row
);
1359 vty_out(vty
, "%-9s %-15s %-15s %-15s %-6s %8s %-6s %5s%s",
1360 ch
->interface
->name
,
1364 pim_ifchannel_ifjoin_name(ch
->ifjoin_state
, ch
->flags
),
1370 } /* scan interface channels */
1373 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
1374 json_object_free(json
);
1378 static void pim_show_neighbors_single(struct vty
*vty
, const char *neighbor
, u_char uj
)
1380 struct listnode
*node
;
1381 struct listnode
*neighnode
;
1382 struct interface
*ifp
;
1383 struct pim_interface
*pim_ifp
;
1384 struct pim_neighbor
*neigh
;
1386 int found_neighbor
= 0;
1387 int option_address_list
;
1388 int option_dr_priority
;
1389 int option_generation_id
;
1390 int option_holdtime
;
1391 int option_lan_prune_delay
;
1395 char neigh_src_str
[INET_ADDRSTRLEN
];
1397 json_object
*json
= NULL
;
1398 json_object
*json_ifp
= NULL
;
1399 json_object
*json_row
= NULL
;
1401 now
= pim_time_monotonic_sec();
1404 json
= json_object_new_object();
1406 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), node
, ifp
)) {
1407 pim_ifp
= ifp
->info
;
1412 if (pim_ifp
->pim_sock_fd
< 0)
1415 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
, neigh
)) {
1416 pim_inet4_dump("<src?>", neigh
->source_addr
,
1417 neigh_src_str
, sizeof(neigh_src_str
));
1420 * The user can specify either the interface name or the PIM neighbor IP.
1421 * If this pim_ifp matches neither then skip.
1423 if (strcmp(neighbor
, "detail") &&
1424 strcmp(neighbor
, ifp
->name
) &&
1425 strcmp(neighbor
, neigh_src_str
))
1429 pim_time_uptime(uptime
, sizeof(uptime
), now
- neigh
->creation
);
1430 pim_time_timer_to_hhmmss(expire
, sizeof(expire
), neigh
->t_expire_timer
);
1432 option_address_list
= 0;
1433 option_dr_priority
= 0;
1434 option_generation_id
= 0;
1435 option_holdtime
= 0;
1436 option_lan_prune_delay
= 0;
1439 if (PIM_OPTION_IS_SET(neigh
->hello_options
, PIM_OPTION_MASK_ADDRESS_LIST
))
1440 option_address_list
= 1;
1442 if (PIM_OPTION_IS_SET(neigh
->hello_options
, PIM_OPTION_MASK_DR_PRIORITY
))
1443 option_dr_priority
= 1;
1445 if (PIM_OPTION_IS_SET(neigh
->hello_options
, PIM_OPTION_MASK_GENERATION_ID
))
1446 option_generation_id
= 1;
1448 if (PIM_OPTION_IS_SET(neigh
->hello_options
, PIM_OPTION_MASK_HOLDTIME
))
1449 option_holdtime
= 1;
1451 if (PIM_OPTION_IS_SET(neigh
->hello_options
, PIM_OPTION_MASK_LAN_PRUNE_DELAY
))
1452 option_lan_prune_delay
= 1;
1454 if (PIM_OPTION_IS_SET(neigh
->hello_options
, PIM_OPTION_MASK_CAN_DISABLE_JOIN_SUPPRESSION
))
1459 /* Does this ifp live in json? If not create it. */
1460 json_object_object_get_ex(json
, ifp
->name
, &json_ifp
);
1463 json_ifp
= json_object_new_object();
1464 json_object_pim_ifp_add(json_ifp
, ifp
);
1465 json_object_object_add(json
, ifp
->name
, json_ifp
);
1468 json_row
= json_object_new_object();
1469 json_object_string_add(json_row
, "interface", ifp
->name
);
1470 json_object_string_add(json_row
, "address", neigh_src_str
);
1471 json_object_string_add(json_row
, "upTime", uptime
);
1472 json_object_string_add(json_row
, "holdtime", expire
);
1473 json_object_int_add(json_row
, "drPriority", neigh
->dr_priority
);
1474 json_object_int_add(json_row
, "generationId", neigh
->generation_id
);
1476 if (option_address_list
)
1477 json_object_boolean_true_add(json_row
, "helloOptionAddressList");
1479 if (option_dr_priority
)
1480 json_object_boolean_true_add(json_row
, "helloOptionDrPriority");
1482 if (option_generation_id
)
1483 json_object_boolean_true_add(json_row
, "helloOptionGenerationId");
1485 if (option_holdtime
)
1486 json_object_boolean_true_add(json_row
, "helloOptionHoldtime");
1488 if (option_lan_prune_delay
)
1489 json_object_boolean_true_add(json_row
, "helloOptionLanPruneDelay");
1492 json_object_boolean_true_add(json_row
, "helloOptionTBit");
1494 json_object_object_add(json_ifp
, neigh_src_str
, json_row
);
1497 vty_out(vty
, "Interface : %s%s", ifp
->name
, VTY_NEWLINE
);
1498 vty_out(vty
, "Neighbor : %s%s", neigh_src_str
, VTY_NEWLINE
);
1499 vty_out(vty
, " Uptime : %s%s", uptime
, VTY_NEWLINE
);
1500 vty_out(vty
, " Holdtime : %s%s", expire
, VTY_NEWLINE
);
1501 vty_out(vty
, " DR Priority : %d%s", neigh
->dr_priority
, VTY_NEWLINE
);
1502 vty_out(vty
, " Generation ID : %08x%s", neigh
->generation_id
, VTY_NEWLINE
);
1503 vty_out(vty
, " Override Interval (msec) : %d%s", neigh
->override_interval_msec
, VTY_NEWLINE
);
1504 vty_out(vty
, " Propagation Delay (msec) : %d%s", neigh
->propagation_delay_msec
, VTY_NEWLINE
);
1505 vty_out(vty
, " Hello Option - Address List : %s%s", option_address_list
? "yes" : "no", VTY_NEWLINE
);
1506 vty_out(vty
, " Hello Option - DR Priority : %s%s", option_dr_priority
? "yes" : "no", VTY_NEWLINE
);
1507 vty_out(vty
, " Hello Option - Generation ID : %s%s", option_generation_id
? "yes" : "no", VTY_NEWLINE
);
1508 vty_out(vty
, " Hello Option - Holdtime : %s%s", option_holdtime
? "yes" : "no", VTY_NEWLINE
);
1509 vty_out(vty
, " Hello Option - LAN Prune Delay : %s%s", option_lan_prune_delay
? "yes" : "no", VTY_NEWLINE
);
1510 vty_out(vty
, " Hello Option - T-bit : %s%s", option_t_bit
? "yes" : "no", VTY_NEWLINE
);
1511 vty_out(vty
, "%s", VTY_NEWLINE
);
1517 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
1518 json_object_free(json
);
1521 if (!found_neighbor
)
1522 vty_out (vty
, "%% No such interface or neighbor%s", VTY_NEWLINE
);
1528 pim_show_state(struct vty
*vty
, const char *src_or_group
, const char *group
, u_char uj
)
1530 struct channel_oil
*c_oil
;
1531 struct listnode
*node
;
1532 json_object
*json
= NULL
;
1533 json_object
*json_group
= NULL
;
1534 json_object
*json_ifp_in
= NULL
;
1535 json_object
*json_ifp_out
= NULL
;
1536 json_object
*json_source
= NULL
;
1539 now
= pim_time_monotonic_sec();
1542 json
= json_object_new_object();
1544 vty_out(vty
, "Codes: J -> Pim Join, I -> IGMP Report, S -> Source, * -> Inherited from (*,G)");
1545 vty_out(vty
, "%sInstalled Source Group IIF OIL%s", VTY_NEWLINE
, VTY_NEWLINE
);
1548 for (ALL_LIST_ELEMENTS_RO(pim_channel_oil_list
, node
, c_oil
)) {
1549 char grp_str
[INET_ADDRSTRLEN
];
1550 char src_str
[INET_ADDRSTRLEN
];
1551 char in_ifname
[INTERFACE_NAMSIZ
+1];
1552 char out_ifname
[INTERFACE_NAMSIZ
+1];
1554 struct interface
*ifp_in
;
1557 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, grp_str
, sizeof(grp_str
));
1558 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, src_str
, sizeof(src_str
));
1559 ifp_in
= pim_if_find_by_vif_index(c_oil
->oil
.mfcc_parent
);
1562 strcpy(in_ifname
, ifp_in
->name
);
1564 strcpy(in_ifname
, "<iif?>");
1568 if (strcmp(src_or_group
, src_str
) && strcmp(src_or_group
, grp_str
))
1571 if (group
&& strcmp(group
, grp_str
))
1577 /* Find the group, create it if it doesn't exist */
1578 json_object_object_get_ex(json
, grp_str
, &json_group
);
1581 json_group
= json_object_new_object();
1582 json_object_object_add(json
, grp_str
, json_group
);
1585 /* Find the source nested under the group, create it if it doesn't exist */
1586 json_object_object_get_ex(json_group
, src_str
, &json_source
);
1589 json_source
= json_object_new_object();
1590 json_object_object_add(json_group
, src_str
, json_source
);
1593 /* Find the inbound interface nested under the source, create it if it doesn't exist */
1594 json_object_object_get_ex(json_source
, in_ifname
, &json_ifp_in
);
1597 json_ifp_in
= json_object_new_object();
1598 json_object_object_add(json_source
, in_ifname
, json_ifp_in
);
1599 json_object_int_add (json_source
, "Installed", c_oil
->installed
);
1600 json_object_int_add (json_source
, "RefCount", c_oil
->oil_ref_count
);
1601 json_object_int_add (json_source
, "OilListSize", c_oil
->oil_size
);
1602 json_object_int_add (json_source
, "OilRescan", c_oil
->oil_inherited_rescan
);
1603 json_object_int_add (json_source
, "LastUsed", c_oil
->cc
.lastused
);
1604 json_object_int_add (json_source
, "PacketCount", c_oil
->cc
.pktcnt
);
1605 json_object_int_add (json_source
, "ByteCount", c_oil
->cc
.bytecnt
);
1606 json_object_int_add (json_source
, "WrongInterface", c_oil
->cc
.wrong_if
);
1609 vty_out(vty
, "%-9d %-15s %-15s %-7s ",
1616 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
; ++oif_vif_index
) {
1617 struct interface
*ifp_out
;
1618 char oif_uptime
[10];
1621 ttl
= c_oil
->oil
.mfcc_ttls
[oif_vif_index
];
1625 ifp_out
= pim_if_find_by_vif_index(oif_vif_index
);
1626 pim_time_uptime(oif_uptime
, sizeof(oif_uptime
), now
- c_oil
->oif_creation
[oif_vif_index
]);
1629 strcpy(out_ifname
, ifp_out
->name
);
1631 strcpy(out_ifname
, "<oif?>");
1634 json_ifp_out
= json_object_new_object();
1635 json_object_string_add(json_ifp_out
, "source", src_str
);
1636 json_object_string_add(json_ifp_out
, "group", grp_str
);
1637 json_object_string_add(json_ifp_out
, "inboundInterface", in_ifname
);
1638 json_object_string_add(json_ifp_out
, "outboundInterface", out_ifname
);
1639 json_object_int_add(json_ifp_out
, "installed", c_oil
->installed
);
1641 json_object_object_add(json_ifp_in
, out_ifname
, json_ifp_out
);
1646 vty_out(vty
, "%s(%c%c%c%c)", out_ifname
,
1647 (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_IGMP
) ? 'I' : ' ',
1648 (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_PIM
) ? 'J' : ' ',
1649 (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_SOURCE
) ? 'S' : ' ',
1650 (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_STAR
) ? '*' : ' ');
1653 vty_out(vty
, ", %s(%c%c%c%c)", out_ifname
,
1654 (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_IGMP
) ? 'I' : ' ',
1655 (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_PIM
) ? 'J' : ' ',
1656 (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_SOURCE
) ? 'S' : ' ',
1657 (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_STAR
) ? '*' : ' ' );
1662 vty_out(vty
, "%s", VTY_NEWLINE
);
1667 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
1668 json_object_free(json
);
1670 vty_out(vty
, "%s", VTY_NEWLINE
);
1674 static void pim_show_neighbors(struct vty
*vty
, u_char uj
)
1676 struct listnode
*node
;
1677 struct listnode
*neighnode
;
1678 struct interface
*ifp
;
1679 struct pim_interface
*pim_ifp
;
1680 struct pim_neighbor
*neigh
;
1684 char neigh_src_str
[INET_ADDRSTRLEN
];
1685 json_object
*json
= NULL
;
1686 json_object
*json_ifp_rows
= NULL
;
1687 json_object
*json_row
= NULL
;
1689 now
= pim_time_monotonic_sec();
1692 json
= json_object_new_object();
1694 vty_out(vty
, "Interface Neighbor Uptime Holdtime DR Pri%s", VTY_NEWLINE
);
1697 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), node
, ifp
)) {
1698 pim_ifp
= ifp
->info
;
1703 if (pim_ifp
->pim_sock_fd
< 0)
1707 json_ifp_rows
= json_object_new_object();
1709 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
, neigh
)) {
1710 pim_inet4_dump("<src?>", neigh
->source_addr
,
1711 neigh_src_str
, sizeof(neigh_src_str
));
1712 pim_time_uptime(uptime
, sizeof(uptime
), now
- neigh
->creation
);
1713 pim_time_timer_to_hhmmss(expire
, sizeof(expire
), neigh
->t_expire_timer
);
1716 json_row
= json_object_new_object();
1717 json_object_string_add(json_row
, "interface", ifp
->name
);
1718 json_object_string_add(json_row
, "neighbor", neigh_src_str
);
1719 json_object_string_add(json_row
, "upTime", uptime
);
1720 json_object_string_add(json_row
, "holdTime", expire
);
1721 json_object_int_add(json_row
, "holdTimeMax", neigh
->holdtime
);
1722 json_object_int_add(json_row
, "drPriority", neigh
->dr_priority
);
1723 json_object_object_add(json_ifp_rows
, neigh_src_str
, json_row
);
1726 vty_out(vty
, "%-9s %15s %8s %8s %6d%s",
1737 json_object_object_add(json
, ifp
->name
, json_ifp_rows
);
1738 json_ifp_rows
= NULL
;
1743 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
1744 json_object_free(json
);
1748 static void pim_show_neighbors_secondary(struct vty
*vty
)
1750 struct listnode
*node
;
1751 struct interface
*ifp
;
1753 vty_out(vty
, "Interface Address Neighbor Secondary %s", VTY_NEWLINE
);
1755 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), node
, ifp
)) {
1756 struct pim_interface
*pim_ifp
;
1757 struct in_addr ifaddr
;
1758 struct listnode
*neighnode
;
1759 struct pim_neighbor
*neigh
;
1761 pim_ifp
= ifp
->info
;
1766 if (pim_ifp
->pim_sock_fd
< 0)
1769 ifaddr
= pim_ifp
->primary_address
;
1771 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
, neigh
)) {
1772 char neigh_src_str
[INET_ADDRSTRLEN
];
1773 struct listnode
*prefix_node
;
1776 if (!neigh
->prefix_list
)
1779 pim_inet4_dump("<src?>", neigh
->source_addr
,
1780 neigh_src_str
, sizeof(neigh_src_str
));
1782 for (ALL_LIST_ELEMENTS_RO(neigh
->prefix_list
, prefix_node
, p
)) {
1783 char neigh_sec_str
[PREFIX2STR_BUFFER
];
1785 prefix2str(p
, neigh_sec_str
, sizeof(neigh_sec_str
));
1787 vty_out(vty
, "%-9s %-15s %-15s %-15s%s",
1799 json_object_pim_upstream_add (json_object
*json
, struct pim_upstream
*up
)
1801 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED
)
1802 json_object_boolean_true_add(json
, "drJoinDesired");
1804 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED_UPDATED
)
1805 json_object_boolean_true_add(json
, "drJoinDesiredUpdated");
1807 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
)
1808 json_object_boolean_true_add(json
, "firstHopRouter");
1810 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_IGMP
)
1811 json_object_boolean_true_add(json
, "sourceIgmp");
1813 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_PIM
)
1814 json_object_boolean_true_add(json
, "sourcePim");
1816 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_STREAM
)
1817 json_object_boolean_true_add(json
, "sourceStream");
1819 /* XXX: need to print ths flag in the plain text display as well */
1820 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_MSDP
)
1821 json_object_boolean_true_add(json
, "sourceMsdp");
1825 pim_upstream_state2brief_str (enum pim_upstream_state join_state
, char *state_str
)
1829 case PIM_UPSTREAM_NOTJOINED
:
1830 strcpy (state_str
, "NotJ");
1832 case PIM_UPSTREAM_JOINED
:
1833 strcpy (state_str
, "J");
1836 strcpy (state_str
, "Unk");
1842 pim_reg_state2brief_str (enum pim_reg_state reg_state
, char *state_str
)
1846 case PIM_REG_NOINFO
:
1847 strcpy (state_str
, "RegNI");
1850 strcpy (state_str
, "RegJ");
1852 case PIM_REG_JOIN_PENDING
:
1854 strcpy (state_str
, "RegP");
1857 strcpy (state_str
, "Unk");
1862 static void pim_show_upstream(struct vty
*vty
, u_char uj
)
1864 struct listnode
*upnode
;
1865 struct pim_upstream
*up
;
1867 json_object
*json
= NULL
;
1868 json_object
*json_group
= NULL
;
1869 json_object
*json_row
= NULL
;
1871 now
= pim_time_monotonic_sec();
1874 json
= json_object_new_object();
1876 vty_out(vty
, "Iif Source Group State Uptime JoinTimer RSTimer KATimer RefCnt%s", VTY_NEWLINE
);
1878 for (ALL_LIST_ELEMENTS_RO(pim_upstream_list
, upnode
, up
)) {
1879 char src_str
[INET_ADDRSTRLEN
];
1880 char grp_str
[INET_ADDRSTRLEN
];
1882 char join_timer
[10];
1885 char msdp_reg_timer
[10];
1886 char state_str
[PIM_REG_STATE_STR_LEN
];
1888 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
1889 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
1890 pim_time_uptime(uptime
, sizeof(uptime
), now
- up
->state_transition
);
1891 pim_time_timer_to_hhmmss (join_timer
, sizeof(join_timer
), up
->t_join_timer
);
1894 * If we have a J/P timer for the neighbor display that
1896 if (!up
->t_join_timer
)
1898 struct pim_neighbor
*nbr
;
1900 nbr
= pim_neighbor_find (up
->rpf
.source_nexthop
.interface
,
1901 up
->rpf
.rpf_addr
.u
.prefix4
);
1903 pim_time_timer_to_hhmmss (join_timer
, sizeof(join_timer
), nbr
->jp_timer
);
1906 pim_time_timer_to_hhmmss (rs_timer
, sizeof (rs_timer
), up
->t_rs_timer
);
1907 pim_time_timer_to_hhmmss (ka_timer
, sizeof (ka_timer
), up
->t_ka_timer
);
1908 pim_time_timer_to_hhmmss (msdp_reg_timer
, sizeof (msdp_reg_timer
), up
->t_msdp_reg_timer
);
1910 pim_upstream_state2brief_str (up
->join_state
, state_str
);
1911 if (up
->reg_state
!= PIM_REG_NOINFO
) {
1912 char tmp_str
[PIM_REG_STATE_STR_LEN
];
1914 sprintf (state_str
+ strlen (state_str
), ",%s",
1915 pim_reg_state2brief_str (up
->reg_state
, tmp_str
));
1919 json_object_object_get_ex(json
, grp_str
, &json_group
);
1922 json_group
= json_object_new_object();
1923 json_object_object_add(json
, grp_str
, json_group
);
1926 json_row
= json_object_new_object();
1927 json_object_pim_upstream_add(json_row
, up
);
1928 json_object_string_add(json_row
, "inboundInterface", up
->rpf
.source_nexthop
.interface
->name
);
1929 json_object_string_add(json_row
, "source", src_str
);
1930 json_object_string_add(json_row
, "group", grp_str
);
1931 json_object_string_add(json_row
, "state", state_str
);
1932 json_object_string_add(json_row
, "joinState", pim_upstream_state2str (up
->join_state
));
1933 json_object_string_add(json_row
, "regState", pim_reg_state2str (up
->reg_state
, state_str
));
1934 json_object_string_add(json_row
, "upTime", uptime
);
1935 json_object_string_add(json_row
, "joinTimer", join_timer
);
1936 json_object_string_add(json_row
, "resetTimer", rs_timer
);
1937 json_object_string_add(json_row
, "keepaliveTimer", ka_timer
);
1938 json_object_string_add(json_row
, "msdpRegTimer", msdp_reg_timer
);
1939 json_object_int_add(json_row
, "refCount", up
->ref_count
);
1940 json_object_int_add(json_row
, "sptBit", up
->sptbit
);
1941 json_object_object_add(json_group
, src_str
, json_row
);
1943 vty_out(vty
, "%-10s%-15s %-15s %-11s %-8s %-9s %-9s %-9s %6d%s",
1944 up
->rpf
.source_nexthop
.interface
->name
,
1958 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
1959 json_object_free(json
);
1963 static void pim_show_join_desired(struct vty
*vty
, u_char uj
)
1965 struct listnode
*chnode
;
1966 struct pim_interface
*pim_ifp
;
1967 struct pim_ifchannel
*ch
;
1968 char src_str
[INET_ADDRSTRLEN
];
1969 char grp_str
[INET_ADDRSTRLEN
];
1970 json_object
*json
= NULL
;
1971 json_object
*json_group
= NULL
;
1972 json_object
*json_row
= NULL
;
1975 json
= json_object_new_object();
1978 "Interface Source Group LostAssert Joins PimInclude JoinDesired EvalJD%s",
1981 /* scan per-interface (S,G) state */
1982 for (ALL_LIST_ELEMENTS_RO(pim_ifchannel_list
, chnode
, ch
)) {
1983 /* scan all interfaces */
1984 pim_ifp
= ch
->interface
->info
;
1988 struct pim_upstream
*up
= ch
->upstream
;
1990 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
1991 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
1994 json_object_object_get_ex(json
, grp_str
, &json_group
);
1997 json_group
= json_object_new_object();
1998 json_object_object_add(json
, grp_str
, json_group
);
2001 json_row
= json_object_new_object();
2002 json_object_pim_upstream_add(json_row
, up
);
2003 json_object_string_add(json_row
, "interface", ch
->interface
->name
);
2004 json_object_string_add(json_row
, "source", src_str
);
2005 json_object_string_add(json_row
, "group", grp_str
);
2007 if (pim_macro_ch_lost_assert(ch
))
2008 json_object_boolean_true_add(json_row
, "lostAssert");
2010 if (pim_macro_chisin_joins(ch
))
2011 json_object_boolean_true_add(json_row
, "joins");
2013 if (pim_macro_chisin_pim_include(ch
))
2014 json_object_boolean_true_add(json_row
, "pimInclude");
2016 if (pim_upstream_evaluate_join_desired(up
))
2017 json_object_boolean_true_add(json_row
, "evaluateJoinDesired");
2019 json_object_object_add(json_group
, src_str
, json_row
);
2022 vty_out(vty
, "%-9s %-15s %-15s %-10s %-5s %-10s %-11s %-6s%s",
2023 ch
->interface
->name
,
2026 pim_macro_ch_lost_assert(ch
) ? "yes" : "no",
2027 pim_macro_chisin_joins(ch
) ? "yes" : "no",
2028 pim_macro_chisin_pim_include(ch
) ? "yes" : "no",
2029 PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED(up
->flags
) ? "yes" : "no",
2030 pim_upstream_evaluate_join_desired(up
) ? "yes" : "no",
2036 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
2037 json_object_free(json
);
2041 static void pim_show_upstream_rpf(struct vty
*vty
, u_char uj
)
2043 struct listnode
*upnode
;
2044 struct pim_upstream
*up
;
2045 json_object
*json
= NULL
;
2046 json_object
*json_group
= NULL
;
2047 json_object
*json_row
= NULL
;
2050 json
= json_object_new_object();
2053 "Source Group RpfIface RibNextHop RpfAddress %s",
2056 for (ALL_LIST_ELEMENTS_RO(pim_upstream_list
, upnode
, up
)) {
2057 char src_str
[INET_ADDRSTRLEN
];
2058 char grp_str
[INET_ADDRSTRLEN
];
2059 char rpf_nexthop_str
[PREFIX_STRLEN
];
2060 char rpf_addr_str
[PREFIX_STRLEN
];
2061 struct pim_rpf
*rpf
;
2062 const char *rpf_ifname
;
2066 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2067 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2068 pim_addr_dump("<nexthop?>", &rpf
->source_nexthop
.mrib_nexthop_addr
, rpf_nexthop_str
, sizeof(rpf_nexthop_str
));
2069 pim_addr_dump("<rpf?>", &rpf
->rpf_addr
, rpf_addr_str
, sizeof(rpf_addr_str
));
2071 rpf_ifname
= rpf
->source_nexthop
.interface
? rpf
->source_nexthop
.interface
->name
: "<ifname?>";
2074 json_object_object_get_ex(json
, grp_str
, &json_group
);
2077 json_group
= json_object_new_object();
2078 json_object_object_add(json
, grp_str
, json_group
);
2081 json_row
= json_object_new_object();
2082 json_object_pim_upstream_add(json_row
, up
);
2083 json_object_string_add(json_row
, "source", src_str
);
2084 json_object_string_add(json_row
, "group", grp_str
);
2085 json_object_string_add(json_row
, "rpfInterface", rpf_ifname
);
2086 json_object_string_add(json_row
, "ribNexthop", rpf_nexthop_str
);
2087 json_object_string_add(json_row
, "rpfAddress", rpf_addr_str
);
2088 json_object_object_add(json_group
, src_str
, json_row
);
2090 vty_out(vty
, "%-15s %-15s %-8s %-15s %-15s%s",
2101 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
2102 json_object_free(json
);
2106 static void show_rpf_refresh_stats(struct vty
*vty
, time_t now
, json_object
*json
)
2108 char refresh_uptime
[10];
2110 pim_time_uptime_begin(refresh_uptime
, sizeof(refresh_uptime
), now
, qpim_rpf_cache_refresh_last
);
2113 json_object_int_add(json
, "rpfCacheRefreshDelayMsecs", qpim_rpf_cache_refresh_delay_msec
);
2114 json_object_int_add(json
, "rpfCacheRefreshTimer", pim_time_timer_remain_msec(qpim_rpf_cache_refresher
));
2115 json_object_int_add(json
, "rpfCacheRefreshRequests", qpim_rpf_cache_refresh_requests
);
2116 json_object_int_add(json
, "rpfCacheRefreshEvents", qpim_rpf_cache_refresh_events
);
2117 json_object_string_add(json
, "rpfCacheRefreshLast", refresh_uptime
);
2118 json_object_int_add(json
, "nexthopLookups", qpim_nexthop_lookups
);
2119 json_object_int_add(json
, "nexthopLookupsAvoided", nexthop_lookups_avoided
);
2122 "RPF Cache Refresh Delay: %ld msecs%s"
2123 "RPF Cache Refresh Timer: %ld msecs%s"
2124 "RPF Cache Refresh Requests: %lld%s"
2125 "RPF Cache Refresh Events: %lld%s"
2126 "RPF Cache Refresh Last: %s%s"
2127 "Nexthop Lookups: %lld%s"
2128 "Nexthop Lookups Avoided: %lld%s",
2129 qpim_rpf_cache_refresh_delay_msec
, VTY_NEWLINE
,
2130 pim_time_timer_remain_msec(qpim_rpf_cache_refresher
), VTY_NEWLINE
,
2131 (long long)qpim_rpf_cache_refresh_requests
, VTY_NEWLINE
,
2132 (long long)qpim_rpf_cache_refresh_events
, VTY_NEWLINE
,
2133 refresh_uptime
, VTY_NEWLINE
,
2134 (long long) qpim_nexthop_lookups
, VTY_NEWLINE
,
2135 (long long)nexthop_lookups_avoided
, VTY_NEWLINE
);
2139 static void show_scan_oil_stats(struct vty
*vty
, time_t now
)
2141 char uptime_scan_oil
[10];
2142 char uptime_mroute_add
[10];
2143 char uptime_mroute_del
[10];
2145 pim_time_uptime_begin(uptime_scan_oil
, sizeof(uptime_scan_oil
), now
, qpim_scan_oil_last
);
2146 pim_time_uptime_begin(uptime_mroute_add
, sizeof(uptime_mroute_add
), now
, qpim_mroute_add_last
);
2147 pim_time_uptime_begin(uptime_mroute_del
, sizeof(uptime_mroute_del
), now
, qpim_mroute_del_last
);
2150 "Scan OIL - Last: %s Events: %lld%s"
2151 "MFC Add - Last: %s Events: %lld%s"
2152 "MFC Del - Last: %s Events: %lld%s",
2153 uptime_scan_oil
, (long long) qpim_scan_oil_events
, VTY_NEWLINE
,
2154 uptime_mroute_add
, (long long) qpim_mroute_add_events
, VTY_NEWLINE
,
2155 uptime_mroute_del
, (long long) qpim_mroute_del_events
, VTY_NEWLINE
);
2158 static void pim_show_rpf(struct vty
*vty
, u_char uj
)
2160 struct listnode
*up_node
;
2161 struct pim_upstream
*up
;
2162 time_t now
= pim_time_monotonic_sec();
2163 json_object
*json
= NULL
;
2164 json_object
*json_group
= NULL
;
2165 json_object
*json_row
= NULL
;
2168 json
= json_object_new_object();
2169 show_rpf_refresh_stats(vty
, now
, json
);
2171 show_rpf_refresh_stats(vty
, now
, json
);
2172 vty_out(vty
, "%s", VTY_NEWLINE
);
2174 "Source Group RpfIface RpfAddress RibNextHop Metric Pref%s",
2178 for (ALL_LIST_ELEMENTS_RO(pim_upstream_list
, up_node
, up
)) {
2179 char src_str
[INET_ADDRSTRLEN
];
2180 char grp_str
[INET_ADDRSTRLEN
];
2181 char rpf_addr_str
[PREFIX_STRLEN
];
2182 char rib_nexthop_str
[PREFIX_STRLEN
];
2183 const char *rpf_ifname
;
2184 struct pim_rpf
*rpf
= &up
->rpf
;
2186 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2187 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2188 pim_addr_dump("<rpf?>", &rpf
->rpf_addr
, rpf_addr_str
, sizeof(rpf_addr_str
));
2189 pim_addr_dump("<nexthop?>", &rpf
->source_nexthop
.mrib_nexthop_addr
, rib_nexthop_str
, sizeof(rib_nexthop_str
));
2191 rpf_ifname
= rpf
->source_nexthop
.interface
? rpf
->source_nexthop
.interface
->name
: "<ifname?>";
2194 json_object_object_get_ex(json
, grp_str
, &json_group
);
2197 json_group
= json_object_new_object();
2198 json_object_object_add(json
, grp_str
, json_group
);
2201 json_row
= json_object_new_object();
2202 json_object_string_add(json_row
, "source", src_str
);
2203 json_object_string_add(json_row
, "group", grp_str
);
2204 json_object_string_add(json_row
, "rpfInterface", rpf_ifname
);
2205 json_object_string_add(json_row
, "rpfAddress", rpf_addr_str
);
2206 json_object_string_add(json_row
, "ribNexthop", rib_nexthop_str
);
2207 json_object_int_add(json_row
, "routeMetric", rpf
->source_nexthop
.mrib_route_metric
);
2208 json_object_int_add(json_row
, "routePreference", rpf
->source_nexthop
.mrib_metric_preference
);
2209 json_object_object_add(json_group
, src_str
, json_row
);
2212 vty_out(vty
, "%-15s %-15s %-8s %-15s %-15s %6d %4d%s",
2218 rpf
->source_nexthop
.mrib_route_metric
,
2219 rpf
->source_nexthop
.mrib_metric_preference
,
2225 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
2226 json_object_free(json
);
2231 pim_print_pnc_cache_walkcb (struct hash_backet
*backet
, void *arg
)
2233 struct pim_nexthop_cache
*pnc
= backet
->data
;
2234 struct vty
*vty
= arg
;
2235 struct nexthop
*nh_node
= NULL
;
2236 ifindex_t first_ifindex
;
2237 struct interface
*ifp
= NULL
;
2242 for (nh_node
= pnc
->nexthop
; nh_node
; nh_node
= nh_node
->next
)
2244 first_ifindex
= nh_node
->ifindex
;
2245 ifp
= if_lookup_by_index (first_ifindex
, VRF_DEFAULT
);
2247 vty_out (vty
, "%-15s ", inet_ntoa (pnc
->rpf
.rpf_addr
.u
.prefix4
));
2248 vty_out (vty
, "%-14s ", ifp
? ifp
->name
: "NULL");
2249 vty_out (vty
, "%s ", inet_ntoa (nh_node
->gate
.ipv4
));
2250 vty_out (vty
, "%s", VTY_NEWLINE
);
2256 pim_show_nexthop (struct vty
*vty
)
2259 if (pimg
&& !pimg
->rpf_hash
)
2261 vty_out (vty
, "no nexthop cache %s", VTY_NEWLINE
);
2265 vty_out (vty
, "Number of registered addresses: %lu %s",
2266 pimg
->rpf_hash
->count
, VTY_NEWLINE
);
2267 vty_out (vty
, "Address Interface Nexthop%s", VTY_NEWLINE
);
2268 vty_out (vty
, "-------------------------------------------%s", VTY_NEWLINE
);
2270 hash_walk (pimg
->rpf_hash
, pim_print_pnc_cache_walkcb
, vty
);
2274 static void igmp_show_groups(struct vty
*vty
, u_char uj
)
2276 struct listnode
*ifnode
;
2277 struct interface
*ifp
;
2279 json_object
*json
= NULL
;
2280 json_object
*json_iface
= NULL
;
2281 json_object
*json_row
= NULL
;
2283 now
= pim_time_monotonic_sec();
2286 json
= json_object_new_object();
2288 vty_out(vty
, "Interface Address Group Mode Timer Srcs V Uptime %s", VTY_NEWLINE
);
2290 /* scan interfaces */
2291 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), ifnode
, ifp
)) {
2292 struct pim_interface
*pim_ifp
= ifp
->info
;
2293 struct listnode
*sock_node
;
2294 struct igmp_sock
*igmp
;
2299 /* scan igmp sockets */
2300 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
2301 char ifaddr_str
[INET_ADDRSTRLEN
];
2302 struct listnode
*grpnode
;
2303 struct igmp_group
*grp
;
2305 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
, sizeof(ifaddr_str
));
2307 /* scan igmp groups */
2308 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grpnode
, grp
)) {
2309 char group_str
[INET_ADDRSTRLEN
];
2313 pim_inet4_dump("<group?>", grp
->group_addr
, group_str
, sizeof(group_str
));
2314 pim_time_timer_to_hhmmss(hhmmss
, sizeof(hhmmss
), grp
->t_group_timer
);
2315 pim_time_uptime(uptime
, sizeof(uptime
), now
- grp
->group_creation
);
2318 json_object_object_get_ex(json
, ifp
->name
, &json_iface
);
2321 json_iface
= json_object_new_object();
2322 json_object_pim_ifp_add(json_iface
, ifp
);
2323 json_object_object_add(json
, ifp
->name
, json_iface
);
2326 json_row
= json_object_new_object();
2327 json_object_string_add(json_row
, "source", ifaddr_str
);
2328 json_object_string_add(json_row
, "group", group_str
);
2330 if (grp
->igmp_version
== 3)
2331 json_object_string_add(json_row
, "mode", grp
->group_filtermode_isexcl
? "EXCLUDE" : "INCLUDE");
2333 json_object_string_add(json_row
, "timer", hhmmss
);
2334 json_object_int_add(json_row
, "sourcesCount", grp
->group_source_list
? listcount(grp
->group_source_list
) : 0);
2335 json_object_int_add(json_row
, "version", grp
->igmp_version
);
2336 json_object_string_add(json_row
, "uptime", uptime
);
2337 json_object_object_add(json_iface
, group_str
, json_row
);
2340 vty_out(vty
, "%-9s %-15s %-15s %4s %8s %4d %d %8s%s",
2344 grp
->igmp_version
== 3 ? (grp
->group_filtermode_isexcl
? "EXCL" : "INCL") : "----",
2346 grp
->group_source_list
? listcount(grp
->group_source_list
) : 0,
2351 } /* scan igmp groups */
2352 } /* scan igmp sockets */
2353 } /* scan interfaces */
2356 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
2357 json_object_free(json
);
2361 static void igmp_show_group_retransmission(struct vty
*vty
)
2363 struct listnode
*ifnode
;
2364 struct interface
*ifp
;
2366 vty_out(vty
, "Interface Address Group RetTimer Counter RetSrcs%s", VTY_NEWLINE
);
2368 /* scan interfaces */
2369 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), ifnode
, ifp
)) {
2370 struct pim_interface
*pim_ifp
= ifp
->info
;
2371 struct listnode
*sock_node
;
2372 struct igmp_sock
*igmp
;
2377 /* scan igmp sockets */
2378 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
2379 char ifaddr_str
[INET_ADDRSTRLEN
];
2380 struct listnode
*grpnode
;
2381 struct igmp_group
*grp
;
2383 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
, sizeof(ifaddr_str
));
2385 /* scan igmp groups */
2386 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grpnode
, grp
)) {
2387 char group_str
[INET_ADDRSTRLEN
];
2388 char grp_retr_mmss
[10];
2389 struct listnode
*src_node
;
2390 struct igmp_source
*src
;
2391 int grp_retr_sources
= 0;
2393 pim_inet4_dump("<group?>", grp
->group_addr
, group_str
, sizeof(group_str
));
2394 pim_time_timer_to_mmss(grp_retr_mmss
, sizeof(grp_retr_mmss
), grp
->t_group_query_retransmit_timer
);
2397 /* count group sources with retransmission state */
2398 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
, src_node
, src
)) {
2399 if (src
->source_query_retransmit_count
> 0) {
2404 vty_out(vty
, "%-9s %-15s %-15s %-8s %7d %7d%s",
2409 grp
->group_specific_query_retransmit_count
,
2413 } /* scan igmp groups */
2414 } /* scan igmp sockets */
2415 } /* scan interfaces */
2418 static void igmp_show_sources(struct vty
*vty
)
2420 struct listnode
*ifnode
;
2421 struct interface
*ifp
;
2424 now
= pim_time_monotonic_sec();
2426 vty_out(vty
, "Interface Address Group Source Timer Fwd Uptime %s", VTY_NEWLINE
);
2428 /* scan interfaces */
2429 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), ifnode
, ifp
)) {
2430 struct pim_interface
*pim_ifp
= ifp
->info
;
2431 struct listnode
*sock_node
;
2432 struct igmp_sock
*igmp
;
2437 /* scan igmp sockets */
2438 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
2439 char ifaddr_str
[INET_ADDRSTRLEN
];
2440 struct listnode
*grpnode
;
2441 struct igmp_group
*grp
;
2443 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
, sizeof(ifaddr_str
));
2445 /* scan igmp groups */
2446 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grpnode
, grp
)) {
2447 char group_str
[INET_ADDRSTRLEN
];
2448 struct listnode
*srcnode
;
2449 struct igmp_source
*src
;
2451 pim_inet4_dump("<group?>", grp
->group_addr
, group_str
, sizeof(group_str
));
2453 /* scan group sources */
2454 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
, srcnode
, src
)) {
2455 char source_str
[INET_ADDRSTRLEN
];
2459 pim_inet4_dump("<source?>", src
->source_addr
, source_str
, sizeof(source_str
));
2461 pim_time_timer_to_mmss(mmss
, sizeof(mmss
), src
->t_source_timer
);
2463 pim_time_uptime(uptime
, sizeof(uptime
), now
- src
->source_creation
);
2465 vty_out(vty
, "%-9s %-15s %-15s %-15s %5s %3s %8s%s",
2471 IGMP_SOURCE_TEST_FORWARDING(src
->source_flags
) ? "Y" : "N",
2475 } /* scan group sources */
2476 } /* scan igmp groups */
2477 } /* scan igmp sockets */
2478 } /* scan interfaces */
2481 static void igmp_show_source_retransmission(struct vty
*vty
)
2483 struct listnode
*ifnode
;
2484 struct interface
*ifp
;
2486 vty_out(vty
, "Interface Address Group Source Counter%s", VTY_NEWLINE
);
2488 /* scan interfaces */
2489 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), ifnode
, ifp
)) {
2490 struct pim_interface
*pim_ifp
= ifp
->info
;
2491 struct listnode
*sock_node
;
2492 struct igmp_sock
*igmp
;
2497 /* scan igmp sockets */
2498 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
2499 char ifaddr_str
[INET_ADDRSTRLEN
];
2500 struct listnode
*grpnode
;
2501 struct igmp_group
*grp
;
2503 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
, sizeof(ifaddr_str
));
2505 /* scan igmp groups */
2506 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grpnode
, grp
)) {
2507 char group_str
[INET_ADDRSTRLEN
];
2508 struct listnode
*srcnode
;
2509 struct igmp_source
*src
;
2511 pim_inet4_dump("<group?>", grp
->group_addr
, group_str
, sizeof(group_str
));
2513 /* scan group sources */
2514 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
, srcnode
, src
)) {
2515 char source_str
[INET_ADDRSTRLEN
];
2517 pim_inet4_dump("<source?>", src
->source_addr
, source_str
, sizeof(source_str
));
2519 vty_out(vty
, "%-9s %-15s %-15s %-15s %7d%s",
2524 src
->source_query_retransmit_count
,
2527 } /* scan group sources */
2528 } /* scan igmp groups */
2529 } /* scan igmp sockets */
2530 } /* scan interfaces */
2533 static void clear_igmp_interfaces()
2535 struct listnode
*ifnode
;
2536 struct listnode
*ifnextnode
;
2537 struct interface
*ifp
;
2539 for (ALL_LIST_ELEMENTS (vrf_iflist (VRF_DEFAULT
), ifnode
, ifnextnode
, ifp
)) {
2540 pim_if_addr_del_all_igmp(ifp
);
2543 for (ALL_LIST_ELEMENTS (vrf_iflist (VRF_DEFAULT
), ifnode
, ifnextnode
, ifp
)) {
2544 pim_if_addr_add_all(ifp
);
2548 static void clear_pim_interfaces()
2550 struct listnode
*ifnode
;
2551 struct listnode
*ifnextnode
;
2552 struct interface
*ifp
;
2554 for (ALL_LIST_ELEMENTS (vrf_iflist (VRF_DEFAULT
), ifnode
, ifnextnode
, ifp
)) {
2556 pim_neighbor_delete_all(ifp
, "interface cleared");
2561 static void clear_interfaces()
2563 clear_igmp_interfaces();
2564 clear_pim_interfaces();
2567 DEFUN (clear_ip_interfaces
,
2568 clear_ip_interfaces_cmd
,
2569 "clear ip interfaces",
2572 "Reset interfaces\n")
2579 DEFUN (clear_ip_igmp_interfaces
,
2580 clear_ip_igmp_interfaces_cmd
,
2581 "clear ip igmp interfaces",
2585 "Reset IGMP interfaces\n")
2587 clear_igmp_interfaces();
2592 static void mroute_add_all()
2594 struct listnode
*node
;
2595 struct channel_oil
*c_oil
;
2597 for (ALL_LIST_ELEMENTS_RO(pim_channel_oil_list
, node
, c_oil
)) {
2598 if (pim_mroute_add(c_oil
, __PRETTY_FUNCTION__
)) {
2599 /* just log warning */
2600 char source_str
[INET_ADDRSTRLEN
];
2601 char group_str
[INET_ADDRSTRLEN
];
2602 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, source_str
, sizeof(source_str
));
2603 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, group_str
, sizeof(group_str
));
2604 zlog_warn("%s %s: (S,G)=(%s,%s) failure writing MFC",
2605 __FILE__
, __PRETTY_FUNCTION__
,
2606 source_str
, group_str
);
2611 static void mroute_del_all()
2613 struct listnode
*node
;
2614 struct channel_oil
*c_oil
;
2616 for (ALL_LIST_ELEMENTS_RO(pim_channel_oil_list
, node
, c_oil
)) {
2617 if (pim_mroute_del(c_oil
, __PRETTY_FUNCTION__
)) {
2618 /* just log warning */
2619 char source_str
[INET_ADDRSTRLEN
];
2620 char group_str
[INET_ADDRSTRLEN
];
2621 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, source_str
, sizeof(source_str
));
2622 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, group_str
, sizeof(group_str
));
2623 zlog_warn("%s %s: (S,G)=(%s,%s) failure clearing MFC",
2624 __FILE__
, __PRETTY_FUNCTION__
,
2625 source_str
, group_str
);
2630 DEFUN (clear_ip_mroute
,
2631 clear_ip_mroute_cmd
,
2635 "Reset multicast routes\n")
2643 DEFUN (clear_ip_pim_interfaces
,
2644 clear_ip_pim_interfaces_cmd
,
2645 "clear ip pim interfaces",
2649 "Reset PIM interfaces\n")
2651 clear_pim_interfaces();
2656 DEFUN (clear_ip_pim_interface_traffic
,
2657 clear_ip_pim_interface_traffic_cmd
,
2658 "clear ip pim interface traffic",
2661 "PIM clear commands\n"
2662 "Reset PIM interfaces\n"
2663 "Reset Protocol Packet counters\n")
2665 struct listnode
*ifnode
= NULL
;
2666 struct listnode
*ifnextnode
= NULL
;
2667 struct interface
*ifp
= NULL
;
2668 struct pim_interface
*pim_ifp
= NULL
;
2670 for (ALL_LIST_ELEMENTS (vrf_iflist (VRF_DEFAULT
), ifnode
, ifnextnode
, ifp
))
2672 pim_ifp
= ifp
->info
;
2677 pim_ifp
->pim_ifstat_hello_recv
= 0;
2678 pim_ifp
->pim_ifstat_hello_sent
= 0;
2679 pim_ifp
->pim_ifstat_join_recv
= 0;
2680 pim_ifp
->pim_ifstat_join_send
= 0;
2681 pim_ifp
->pim_ifstat_prune_recv
= 0;
2682 pim_ifp
->pim_ifstat_prune_send
= 0;
2683 pim_ifp
->pim_ifstat_reg_recv
= 0;
2684 pim_ifp
->pim_ifstat_reg_send
= 0;
2685 pim_ifp
->pim_ifstat_reg_stop_recv
= 0;
2686 pim_ifp
->pim_ifstat_reg_stop_send
= 0;
2687 pim_ifp
->pim_ifstat_assert_recv
= 0;
2688 pim_ifp
->pim_ifstat_assert_send
= 0;
2695 DEFUN (clear_ip_pim_oil
,
2696 clear_ip_pim_oil_cmd
,
2701 "Rescan PIM OIL (output interface list)\n")
2708 DEFUN (show_ip_igmp_interface
,
2709 show_ip_igmp_interface_cmd
,
2710 "show ip igmp interface [detail|WORD] [json]",
2714 "IGMP interface information\n"
2717 "JavaScript Object Notation\n")
2719 u_char uj
= use_json(argc
, argv
);
2722 if (argv_find(argv
, argc
, "detail", &idx
) ||
2723 argv_find(argv
, argc
, "WORD", &idx
))
2724 igmp_show_interfaces_single(vty
, argv
[idx
]->arg
, uj
);
2726 igmp_show_interfaces(vty
, uj
);
2731 DEFUN (show_ip_igmp_join
,
2732 show_ip_igmp_join_cmd
,
2733 "show ip igmp join",
2737 "IGMP static join information\n")
2739 igmp_show_interface_join(vty
);
2744 DEFUN (show_ip_igmp_groups
,
2745 show_ip_igmp_groups_cmd
,
2746 "show ip igmp groups [json]",
2751 "JavaScript Object Notation\n")
2753 u_char uj
= use_json(argc
, argv
);
2754 igmp_show_groups(vty
, uj
);
2759 DEFUN (show_ip_igmp_groups_retransmissions
,
2760 show_ip_igmp_groups_retransmissions_cmd
,
2761 "show ip igmp groups retransmissions",
2766 "IGMP group retransmissions\n")
2768 igmp_show_group_retransmission(vty
);
2773 DEFUN (show_ip_igmp_sources
,
2774 show_ip_igmp_sources_cmd
,
2775 "show ip igmp sources",
2781 igmp_show_sources(vty
);
2786 DEFUN (show_ip_igmp_sources_retransmissions
,
2787 show_ip_igmp_sources_retransmissions_cmd
,
2788 "show ip igmp sources retransmissions",
2793 "IGMP source retransmissions\n")
2795 igmp_show_source_retransmission(vty
);
2800 DEFUN (show_ip_pim_assert
,
2801 show_ip_pim_assert_cmd
,
2802 "show ip pim assert",
2806 "PIM interface assert\n")
2808 pim_show_assert(vty
);
2813 DEFUN (show_ip_pim_assert_internal
,
2814 show_ip_pim_assert_internal_cmd
,
2815 "show ip pim assert-internal",
2819 "PIM interface internal assert state\n")
2821 pim_show_assert_internal(vty
);
2826 DEFUN (show_ip_pim_assert_metric
,
2827 show_ip_pim_assert_metric_cmd
,
2828 "show ip pim assert-metric",
2832 "PIM interface assert metric\n")
2834 pim_show_assert_metric(vty
);
2839 DEFUN (show_ip_pim_assert_winner_metric
,
2840 show_ip_pim_assert_winner_metric_cmd
,
2841 "show ip pim assert-winner-metric",
2845 "PIM interface assert winner metric\n")
2847 pim_show_assert_winner_metric(vty
);
2852 DEFUN (show_ip_pim_interface
,
2853 show_ip_pim_interface_cmd
,
2854 "show ip pim interface [detail|WORD] [json]",
2858 "PIM interface information\n"
2861 "JavaScript Object Notation\n")
2863 u_char uj
= use_json(argc
, argv
);
2866 if (argv_find(argv
, argc
, "WORD", &idx
) ||
2867 argv_find(argv
, argc
, "detail", &idx
))
2868 pim_show_interfaces_single(vty
, argv
[idx
]->arg
, uj
);
2871 pim_show_interfaces(vty
, uj
);
2876 DEFUN (show_ip_pim_join
,
2877 show_ip_pim_join_cmd
,
2878 "show ip pim join [json]",
2882 "PIM interface join information\n"
2885 u_char uj
= use_json(argc
, argv
);
2886 pim_show_join(vty
, uj
);
2891 DEFUN (show_ip_pim_local_membership
,
2892 show_ip_pim_local_membership_cmd
,
2893 "show ip pim local-membership [json]",
2897 "PIM interface local-membership\n"
2900 u_char uj
= use_json(argc
, argv
);
2901 pim_show_membership(vty
, uj
);
2906 DEFUN (show_ip_pim_neighbor
,
2907 show_ip_pim_neighbor_cmd
,
2908 "show ip pim neighbor [detail|WORD] [json]",
2912 "PIM neighbor information\n"
2914 "Name of interface or neighbor\n"
2915 "JavaScript Object Notation\n")
2917 u_char uj
= use_json(argc
, argv
);
2920 if (argv_find(argv
, argc
, "detail", &idx
) ||
2921 argv_find(argv
, argc
, "WORD", &idx
))
2922 pim_show_neighbors_single(vty
, argv
[idx
]->arg
, uj
);
2924 pim_show_neighbors(vty
, uj
);
2929 DEFUN (show_ip_pim_secondary
,
2930 show_ip_pim_secondary_cmd
,
2931 "show ip pim secondary",
2935 "PIM neighbor addresses\n")
2937 pim_show_neighbors_secondary(vty
);
2942 DEFUN (show_ip_pim_state
,
2943 show_ip_pim_state_cmd
,
2944 "show ip pim state [A.B.C.D [A.B.C.D]] [json]",
2948 "PIM state information\n"
2949 "Unicast or Multicast address\n"
2950 "Multicast address\n"
2951 "JavaScript Object Notation\n")
2953 const char *src_or_group
= NULL
;
2954 const char *group
= NULL
;
2955 u_char uj
= use_json(argc
, argv
);
2961 src_or_group
= argv
[4]->arg
;
2962 group
= argv
[5]->arg
;
2965 src_or_group
= argv
[4]->arg
;
2967 pim_show_state(vty
, src_or_group
, group
, uj
);
2972 DEFUN (show_ip_pim_upstream
,
2973 show_ip_pim_upstream_cmd
,
2974 "show ip pim upstream [json]",
2978 "PIM upstream information\n"
2979 "JavaScript Object Notation\n")
2981 u_char uj
= use_json(argc
, argv
);
2982 pim_show_upstream(vty
, uj
);
2987 DEFUN (show_ip_pim_upstream_join_desired
,
2988 show_ip_pim_upstream_join_desired_cmd
,
2989 "show ip pim upstream-join-desired [json]",
2993 "PIM upstream join-desired\n"
2994 "JavaScript Object Notation\n")
2996 u_char uj
= use_json(argc
, argv
);
2997 pim_show_join_desired(vty
, uj
);
3002 DEFUN (show_ip_pim_upstream_rpf
,
3003 show_ip_pim_upstream_rpf_cmd
,
3004 "show ip pim upstream-rpf [json]",
3008 "PIM upstream source rpf\n"
3009 "JavaScript Object Notation\n")
3011 u_char uj
= use_json(argc
, argv
);
3012 pim_show_upstream_rpf(vty
, uj
);
3017 DEFUN (show_ip_pim_rp
,
3019 "show ip pim rp-info [json]",
3023 "PIM RP information\n"
3024 "JavaScript Object Notation\n")
3026 u_char uj
= use_json(argc
, argv
);
3027 pim_rp_show_information (vty
, uj
);
3032 DEFUN (show_ip_pim_rpf
,
3033 show_ip_pim_rpf_cmd
,
3034 "show ip pim rpf [json]",
3038 "PIM cached source rpf information\n"
3039 "JavaScript Object Notation\n")
3041 u_char uj
= use_json(argc
, argv
);
3042 pim_show_rpf(vty
, uj
);
3047 DEFUN (show_ip_pim_nexthop
,
3048 show_ip_pim_nexthop_cmd
,
3049 "show ip pim nexthop",
3053 "PIM cached nexthop rpf information\n")
3055 pim_show_nexthop (vty
);
3060 DEFUN (show_ip_pim_nexthop_lookup
,
3061 show_ip_pim_nexthop_lookup_cmd
,
3062 "show ip pim nexthop-lookup A.B.C.D A.B.C.D",
3066 "PIM cached nexthop rpf lookup\n"
3067 "Source/RP address\n"
3068 "Multicast Group address\n")
3070 struct pim_nexthop_cache pnc
;
3071 struct prefix nht_p
;
3073 struct in_addr src_addr
, grp_addr
;
3074 struct in_addr vif_source
;
3075 const char *addr_str
, *addr_str1
;
3077 struct pim_nexthop nexthop
;
3078 char nexthop_addr_str
[PREFIX_STRLEN
];
3079 char grp_str
[PREFIX_STRLEN
];
3081 addr_str
= argv
[4]->arg
;
3082 result
= inet_pton (AF_INET
, addr_str
, &src_addr
);
3085 vty_out (vty
, "Bad unicast address %s: errno=%d: %s%s",
3086 addr_str
, errno
, safe_strerror (errno
), VTY_NEWLINE
);
3090 if (pim_is_group_224_4 (src_addr
))
3092 vty_out (vty
, "Invalid argument. Expected Valid Source Address.%s", VTY_NEWLINE
);
3096 addr_str1
= argv
[5]->arg
;
3097 result
= inet_pton (AF_INET
, addr_str1
, &grp_addr
);
3100 vty_out (vty
, "Bad unicast address %s: errno=%d: %s%s",
3101 addr_str
, errno
, safe_strerror (errno
), VTY_NEWLINE
);
3105 if (!pim_is_group_224_4 (grp_addr
))
3107 vty_out (vty
, "Invalid argument. Expected Valid Multicast Group Address.%s", VTY_NEWLINE
);
3111 if (!pim_rp_set_upstream_addr (&vif_source
, src_addr
, grp_addr
))
3114 memset (&pnc
, 0, sizeof (struct pim_nexthop_cache
));
3115 nht_p
.family
= AF_INET
;
3116 nht_p
.prefixlen
= IPV4_MAX_BITLEN
;
3117 nht_p
.u
.prefix4
= vif_source
;
3118 grp
.family
= AF_INET
;
3119 grp
.prefixlen
= IPV4_MAX_BITLEN
;
3120 grp
.u
.prefix4
= grp_addr
;
3121 memset (&nexthop
, 0, sizeof (nexthop
));
3123 if ((pim_find_or_track_nexthop (&nht_p
, NULL
, NULL
, &pnc
)) == 1)
3125 //Compute PIM RPF using Cached nexthop
3126 pim_ecmp_nexthop_search (&pnc
, &nexthop
, &nht_p
, &grp
, 0);
3129 pim_ecmp_nexthop_lookup (&nexthop
, vif_source
, &nht_p
, &grp
, 0);
3131 pim_addr_dump ("<grp?>", &grp
, grp_str
, sizeof (grp_str
));
3132 pim_addr_dump ("<nexthop?>", &nexthop
.mrib_nexthop_addr
,
3133 nexthop_addr_str
, sizeof (nexthop_addr_str
));
3134 vty_out (vty
, "Group %s --- Nexthop %s Interface %s %s", grp_str
,
3135 nexthop_addr_str
, nexthop
.interface
->name
, VTY_NEWLINE
);
3140 DEFUN (show_ip_pim_interface_traffic
,
3141 show_ip_pim_interface_traffic_cmd
,
3142 "show ip pim interface traffic [WORD] [json]",
3146 "PIM interface information\n"
3147 "Protocol Packet counters\n"
3149 "JavaScript Object Notation\n")
3151 u_char uj
= use_json (argc
, argv
);
3154 if (argv_find(argv
, argc
, "WORD", &idx
))
3155 pim_show_interface_traffic_single (vty
, argv
[idx
]->arg
, uj
);
3157 pim_show_interface_traffic (vty
, uj
);
3162 static void show_multicast_interfaces(struct vty
*vty
)
3164 struct listnode
*node
;
3165 struct interface
*ifp
;
3167 vty_out(vty
, "%s", VTY_NEWLINE
);
3169 vty_out(vty
, "Interface Address ifi Vif PktsIn PktsOut BytesIn BytesOut%s",
3172 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT
), node
, ifp
)) {
3173 struct pim_interface
*pim_ifp
;
3174 struct in_addr ifaddr
;
3175 struct sioc_vif_req vreq
;
3177 pim_ifp
= ifp
->info
;
3182 memset(&vreq
, 0, sizeof(vreq
));
3183 vreq
.vifi
= pim_ifp
->mroute_vif_index
;
3185 if (ioctl(qpim_mroute_socket_fd
, SIOCGETVIFCNT
, &vreq
)) {
3186 zlog_warn("ioctl(SIOCGETVIFCNT=%lu) failure for interface %s vif_index=%d: errno=%d: %s%s",
3187 (unsigned long)SIOCGETVIFCNT
,
3189 pim_ifp
->mroute_vif_index
,
3191 safe_strerror(errno
),
3195 ifaddr
= pim_ifp
->primary_address
;
3197 vty_out(vty
, "%-9s %-15s %3d %3d %7lu %7lu %10lu %10lu%s",
3201 pim_ifp
->mroute_vif_index
,
3202 (unsigned long) vreq
.icount
,
3203 (unsigned long) vreq
.ocount
,
3204 (unsigned long) vreq
.ibytes
,
3205 (unsigned long) vreq
.obytes
,
3210 DEFUN (show_ip_multicast
,
3211 show_ip_multicast_cmd
,
3212 "show ip multicast",
3215 "Multicast global information\n")
3217 time_t now
= pim_time_monotonic_sec();
3221 vty_out(vty
, "Mroute socket descriptor: %d%s",
3222 qpim_mroute_socket_fd
,
3225 pim_time_uptime(uptime
, sizeof(uptime
), now
- qpim_mroute_socket_creation
);
3226 vty_out(vty
, "Mroute socket uptime: %s%s",
3230 vty_out(vty
, "%s", VTY_NEWLINE
);
3232 pim_zebra_zclient_update (vty
);
3233 pim_zlookup_show_ip_multicast (vty
);
3235 vty_out(vty
, "%s", VTY_NEWLINE
);
3236 vty_out(vty
, "Maximum highest VifIndex: %d%s",
3237 PIM_MAX_USABLE_VIFS
,
3240 vty_out (vty
, "%s", VTY_NEWLINE
);
3241 vty_out (vty
, "Upstream Join Timer: %d secs%s",
3242 qpim_t_periodic
, VTY_NEWLINE
);
3243 vty_out (vty
, "Join/Prune Holdtime: %d secs%s",
3244 PIM_JP_HOLDTIME
, VTY_NEWLINE
);
3245 vty_out (vty
, "PIM ECMP: %s%s",
3246 qpim_ecmp_enable
? "Enable" : "Disable", VTY_NEWLINE
);
3247 vty_out (vty
, "PIM ECMP Rebalance: %s%s",
3248 qpim_ecmp_rebalance_enable
? "Enable" : "Disable", VTY_NEWLINE
);
3250 vty_out (vty
, "%s", VTY_NEWLINE
);
3252 show_rpf_refresh_stats(vty
, now
, NULL
);
3254 vty_out(vty
, "%s", VTY_NEWLINE
);
3256 show_scan_oil_stats(vty
, now
);
3258 show_multicast_interfaces(vty
);
3263 static void show_mroute(struct vty
*vty
, u_char uj
)
3265 struct listnode
*node
;
3266 struct channel_oil
*c_oil
;
3267 struct static_route
*s_route
;
3269 json_object
*json
= NULL
;
3270 json_object
*json_group
= NULL
;
3271 json_object
*json_source
= NULL
;
3272 json_object
*json_oil
= NULL
;
3273 json_object
*json_ifp_out
= NULL
;
3276 char grp_str
[INET_ADDRSTRLEN
];
3277 char src_str
[INET_ADDRSTRLEN
];
3278 char in_ifname
[INTERFACE_NAMSIZ
+1];
3279 char out_ifname
[INTERFACE_NAMSIZ
+1];
3281 struct interface
*ifp_in
;
3285 json
= json_object_new_object();
3287 vty_out(vty
, "Source Group Proto Input Output TTL Uptime%s",
3291 now
= pim_time_monotonic_sec();
3293 /* print list of PIM and IGMP routes */
3294 for (ALL_LIST_ELEMENTS_RO(pim_channel_oil_list
, node
, c_oil
)) {
3297 if (!c_oil
->installed
&& !uj
)
3300 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, grp_str
, sizeof(grp_str
));
3301 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, src_str
, sizeof(src_str
));
3302 ifp_in
= pim_if_find_by_vif_index(c_oil
->oil
.mfcc_parent
);
3305 strcpy(in_ifname
, ifp_in
->name
);
3307 strcpy(in_ifname
, "<iif?>");
3311 /* Find the group, create it if it doesn't exist */
3312 json_object_object_get_ex(json
, grp_str
, &json_group
);
3315 json_group
= json_object_new_object();
3316 json_object_object_add(json
, grp_str
, json_group
);
3319 /* Find the source nested under the group, create it if it doesn't exist */
3320 json_object_object_get_ex(json_group
, src_str
, &json_source
);
3323 json_source
= json_object_new_object();
3324 json_object_object_add(json_group
, src_str
, json_source
);
3327 /* Find the inbound interface nested under the source, create it if it doesn't exist */
3328 json_object_int_add(json_source
, "installed", c_oil
->installed
);
3329 json_object_int_add(json_source
, "refCount", c_oil
->oil_ref_count
);
3330 json_object_int_add(json_source
, "oilSize", c_oil
->oil_size
);
3331 json_object_int_add(json_source
, "OilInheritedRescan", c_oil
->oil_inherited_rescan
);
3332 json_object_string_add(json_source
, "iif", in_ifname
);
3336 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
; ++oif_vif_index
) {
3337 struct interface
*ifp_out
;
3338 char oif_uptime
[10];
3341 ttl
= c_oil
->oil
.mfcc_ttls
[oif_vif_index
];
3345 ifp_out
= pim_if_find_by_vif_index(oif_vif_index
);
3346 pim_time_uptime(oif_uptime
, sizeof(oif_uptime
), now
- c_oil
->oif_creation
[oif_vif_index
]);
3350 strcpy(out_ifname
, ifp_out
->name
);
3352 strcpy(out_ifname
, "<oif?>");
3355 json_ifp_out
= json_object_new_object();
3356 json_object_string_add(json_ifp_out
, "source", src_str
);
3357 json_object_string_add(json_ifp_out
, "group", grp_str
);
3359 if (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_PIM
)
3360 json_object_boolean_true_add(json_ifp_out
, "protocolPim");
3362 if (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_IGMP
)
3363 json_object_boolean_true_add(json_ifp_out
, "protocolIgmp");
3365 if (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_SOURCE
)
3366 json_object_boolean_true_add(json_ifp_out
, "protocolSource");
3368 if (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_STAR
)
3369 json_object_boolean_true_add(json_ifp_out
, "protocolInherited");
3371 json_object_string_add(json_ifp_out
, "inboundInterface", in_ifname
);
3372 json_object_int_add(json_ifp_out
, "iVifI", c_oil
->oil
.mfcc_parent
);
3373 json_object_string_add(json_ifp_out
, "outboundInterface", out_ifname
);
3374 json_object_int_add(json_ifp_out
, "oVifI", oif_vif_index
);
3375 json_object_int_add(json_ifp_out
, "ttl", ttl
);
3376 json_object_string_add(json_ifp_out
, "upTime", oif_uptime
);
3378 json_oil
= json_object_new_object();
3379 json_object_object_add(json_source
, "oil", json_oil
);
3381 json_object_object_add(json_oil
, out_ifname
, json_ifp_out
);
3383 if (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_PIM
) {
3384 strcpy(proto
, "PIM");
3387 if (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_IGMP
) {
3388 strcpy(proto
, "IGMP");
3391 if (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_SOURCE
) {
3392 strcpy(proto
, "SRC");
3395 if (c_oil
->oif_flags
[oif_vif_index
] & PIM_OIF_FLAG_PROTO_STAR
) {
3396 strcpy(proto
, "STAR");
3399 vty_out(vty
, "%-15s %-15s %-6s %-10s %-10s %-3d %8s%s",
3413 in_ifname
[0] = '\0';
3419 if (!uj
&& !found_oif
) {
3420 vty_out(vty
, "%-15s %-15s %-6s %-10s %-10s %-3d %8s%s",
3432 /* Print list of static routes */
3433 for (ALL_LIST_ELEMENTS_RO(qpim_static_route_list
, node
, s_route
)) {
3436 if (!s_route
->c_oil
.installed
)
3439 pim_inet4_dump("<group?>", s_route
->group
, grp_str
, sizeof(grp_str
));
3440 pim_inet4_dump("<source?>", s_route
->source
, src_str
, sizeof(src_str
));
3441 ifp_in
= pim_if_find_by_vif_index(s_route
->iif
);
3445 strcpy(in_ifname
, ifp_in
->name
);
3447 strcpy(in_ifname
, "<iif?>");
3451 /* Find the group, create it if it doesn't exist */
3452 json_object_object_get_ex(json
, grp_str
, &json_group
);
3455 json_group
= json_object_new_object();
3456 json_object_object_add(json
, grp_str
, json_group
);
3459 /* Find the source nested under the group, create it if it doesn't exist */
3460 json_object_object_get_ex(json_group
, src_str
, &json_source
);
3463 json_source
= json_object_new_object();
3464 json_object_object_add(json_group
, src_str
, json_source
);
3467 json_object_string_add(json_source
, "iif", in_ifname
);
3470 strcpy(proto
, "STATIC");
3473 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
; ++oif_vif_index
) {
3474 struct interface
*ifp_out
;
3475 char oif_uptime
[10];
3478 ttl
= s_route
->oif_ttls
[oif_vif_index
];
3482 ifp_out
= pim_if_find_by_vif_index(oif_vif_index
);
3483 pim_time_uptime(oif_uptime
, sizeof(oif_uptime
), now
- s_route
->c_oil
.oif_creation
[oif_vif_index
]);
3487 strcpy(out_ifname
, ifp_out
->name
);
3489 strcpy(out_ifname
, "<oif?>");
3492 json_ifp_out
= json_object_new_object();
3493 json_object_string_add(json_ifp_out
, "source", src_str
);
3494 json_object_string_add(json_ifp_out
, "group", grp_str
);
3495 json_object_boolean_true_add(json_ifp_out
, "protocolStatic");
3496 json_object_string_add(json_ifp_out
, "inboundInterface", in_ifname
);
3497 json_object_int_add(json_ifp_out
, "iVifI", s_route
->c_oil
.oil
.mfcc_parent
);
3498 json_object_string_add(json_ifp_out
, "outboundInterface", out_ifname
);
3499 json_object_int_add(json_ifp_out
, "oVifI", oif_vif_index
);
3500 json_object_int_add(json_ifp_out
, "ttl", ttl
);
3501 json_object_string_add(json_ifp_out
, "upTime", oif_uptime
);
3503 json_oil
= json_object_new_object();
3504 json_object_object_add(json_source
, "oil", json_oil
);
3506 json_object_object_add(json_oil
, out_ifname
, json_ifp_out
);
3508 vty_out(vty
, "%-15s %-15s %-6s %-10s %-10s %-3d %8s%s",
3521 in_ifname
[0] = '\0';
3527 if (!uj
&& !found_oif
) {
3528 vty_out(vty
, "%-15s %-15s %-6s %-10s %-10s %-3d %8s%s",
3541 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
3542 json_object_free(json
);
3546 DEFUN (show_ip_mroute
,
3548 "show ip mroute [json]",
3554 u_char uj
= use_json(argc
, argv
);
3555 show_mroute(vty
, uj
);
3559 static void show_mroute_count(struct vty
*vty
)
3561 struct listnode
*node
;
3562 struct channel_oil
*c_oil
;
3563 struct static_route
*s_route
;
3565 vty_out(vty
, "%s", VTY_NEWLINE
);
3567 vty_out(vty
, "Source Group LastUsed Packets Bytes WrongIf %s",
3570 /* Print PIM and IGMP route counts */
3571 for (ALL_LIST_ELEMENTS_RO(pim_channel_oil_list
, node
, c_oil
)) {
3572 char group_str
[INET_ADDRSTRLEN
];
3573 char source_str
[INET_ADDRSTRLEN
];
3575 if (!c_oil
->installed
)
3578 pim_mroute_update_counters (c_oil
);
3580 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, group_str
, sizeof(group_str
));
3581 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, source_str
, sizeof(source_str
));
3583 vty_out(vty
, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld%s",
3586 c_oil
->cc
.lastused
/100,
3593 /* Print static route counts */
3594 for (ALL_LIST_ELEMENTS_RO(qpim_static_route_list
, node
, s_route
)) {
3595 char group_str
[INET_ADDRSTRLEN
];
3596 char source_str
[INET_ADDRSTRLEN
];
3598 if (!s_route
->c_oil
.installed
)
3601 pim_mroute_update_counters (&s_route
->c_oil
);
3603 pim_inet4_dump("<group?>", s_route
->c_oil
.oil
.mfcc_mcastgrp
, group_str
, sizeof(group_str
));
3604 pim_inet4_dump("<source?>", s_route
->c_oil
.oil
.mfcc_origin
, source_str
, sizeof(source_str
));
3606 vty_out(vty
, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld%s",
3609 s_route
->c_oil
.cc
.lastused
,
3610 s_route
->c_oil
.cc
.pktcnt
,
3611 s_route
->c_oil
.cc
.bytecnt
,
3612 s_route
->c_oil
.cc
.wrong_if
,
3617 DEFUN (show_ip_mroute_count
,
3618 show_ip_mroute_count_cmd
,
3619 "show ip mroute count",
3623 "Route and packet count data\n")
3625 show_mroute_count(vty
);
3631 "show ip rib A.B.C.D",
3635 "Unicast address\n")
3638 struct in_addr addr
;
3639 const char *addr_str
;
3640 struct pim_nexthop nexthop
;
3641 char nexthop_addr_str
[PREFIX_STRLEN
];
3644 memset (&nexthop
, 0, sizeof (nexthop
));
3645 addr_str
= argv
[idx_ipv4
]->arg
;
3646 result
= inet_pton(AF_INET
, addr_str
, &addr
);
3648 vty_out(vty
, "Bad unicast address %s: errno=%d: %s%s",
3649 addr_str
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
3653 if (pim_nexthop_lookup(&nexthop
, addr
, 0)) {
3654 vty_out(vty
, "Failure querying RIB nexthop for unicast address %s%s",
3655 addr_str
, VTY_NEWLINE
);
3659 vty_out(vty
, "Address NextHop Interface Metric Preference%s",
3662 pim_addr_dump("<nexthop?>", &nexthop
.mrib_nexthop_addr
,
3663 nexthop_addr_str
, sizeof(nexthop_addr_str
));
3665 vty_out(vty
, "%-15s %-15s %-9s %6d %10d%s",
3668 nexthop
.interface
? nexthop
.interface
->name
: "<ifname?>",
3669 nexthop
.mrib_route_metric
,
3670 nexthop
.mrib_metric_preference
,
3676 static void show_ssmpingd(struct vty
*vty
)
3678 struct listnode
*node
;
3679 struct ssmpingd_sock
*ss
;
3682 vty_out(vty
, "Source Socket Address Port Uptime Requests%s",
3685 if (!qpim_ssmpingd_list
)
3688 now
= pim_time_monotonic_sec();
3690 for (ALL_LIST_ELEMENTS_RO(qpim_ssmpingd_list
, node
, ss
)) {
3691 char source_str
[INET_ADDRSTRLEN
];
3693 struct sockaddr_in bind_addr
;
3694 socklen_t len
= sizeof(bind_addr
);
3695 char bind_addr_str
[INET_ADDRSTRLEN
];
3697 pim_inet4_dump("<src?>", ss
->source_addr
, source_str
, sizeof(source_str
));
3699 if (pim_socket_getsockname(ss
->sock_fd
, (struct sockaddr
*) &bind_addr
, &len
)) {
3700 vty_out(vty
, "%% Failure reading socket name for ssmpingd source %s on fd=%d%s",
3701 source_str
, ss
->sock_fd
, VTY_NEWLINE
);
3704 pim_inet4_dump("<addr?>", bind_addr
.sin_addr
, bind_addr_str
, sizeof(bind_addr_str
));
3705 pim_time_uptime(ss_uptime
, sizeof(ss_uptime
), now
- ss
->creation
);
3707 vty_out(vty
, "%-15s %6d %-15s %5d %8s %8lld%s",
3711 ntohs(bind_addr
.sin_port
),
3713 (long long)ss
->requests
,
3718 DEFUN (show_ip_ssmpingd
,
3719 show_ip_ssmpingd_cmd
,
3730 pim_rp_cmd_worker (struct vty
*vty
, const char *rp
, const char *group
, const char *plist
)
3734 result
= pim_rp_new (rp
, group
, plist
);
3736 if (result
== PIM_MALLOC_FAIL
)
3738 vty_out (vty
, "%% Out of memory%s", VTY_NEWLINE
);
3742 if (result
== PIM_GROUP_BAD_ADDRESS
)
3744 vty_out (vty
, "%% Bad group address specified: %s%s", group
, VTY_NEWLINE
);
3748 if (result
== PIM_RP_BAD_ADDRESS
)
3750 vty_out (vty
, "%% Bad RP address specified: %s%s", rp
, VTY_NEWLINE
);
3754 if (result
== PIM_RP_NO_PATH
)
3756 vty_out (vty
, "%% No Path to RP address specified: %s%s", rp
, VTY_NEWLINE
);
3760 if (result
== PIM_GROUP_OVERLAP
)
3762 vty_out (vty
, "%% Group range specified cannot overlap%s", VTY_NEWLINE
);
3766 if (result
== PIM_GROUP_PFXLIST_OVERLAP
)
3768 vty_out (vty
, "%% This group is already covered by a RP prefix-list%s", VTY_NEWLINE
);
3772 if (result
== PIM_RP_PFXLIST_IN_USE
)
3774 vty_out (vty
, "%% The same prefix-list cannot be applied to multiple RPs%s", VTY_NEWLINE
);
3782 pim_cmd_spt_switchover (enum pim_spt_switchover spt
, const char *plist
)
3784 pimg
->spt
.switchover
= spt
;
3786 switch (pimg
->spt
.switchover
)
3788 case PIM_SPT_IMMEDIATE
:
3789 if (pimg
->spt
.plist
)
3790 XFREE (MTYPE_PIM_SPT_PLIST_NAME
, pimg
->spt
.plist
);
3792 pim_upstream_add_lhr_star_pimreg ();
3794 case PIM_SPT_INFINITY
:
3795 pim_upstream_remove_lhr_star_pimreg (plist
);
3797 if (pimg
->spt
.plist
)
3798 XFREE (MTYPE_PIM_SPT_PLIST_NAME
, pimg
->spt
.plist
);
3801 pimg
->spt
.plist
= XSTRDUP (MTYPE_PIM_SPT_PLIST_NAME
, plist
);
3808 DEFUN (ip_pim_spt_switchover_infinity
,
3809 ip_pim_spt_switchover_infinity_cmd
,
3810 "ip pim spt-switchover infinity-and-beyond",
3814 "Never switch to SPT Tree\n")
3816 return pim_cmd_spt_switchover (PIM_SPT_INFINITY
, NULL
);
3819 DEFUN (ip_pim_spt_switchover_infinity_plist
,
3820 ip_pim_spt_switchover_infinity_plist_cmd
,
3821 "ip pim spt-switchover infinity-and-beyond prefix-list WORD",
3825 "Never switch to SPT Tree\n"
3826 "Prefix-List to control which groups to switch\n"
3827 "Prefix-List name\n")
3829 return pim_cmd_spt_switchover (PIM_SPT_INFINITY
, argv
[5]->arg
);
3832 DEFUN (no_ip_pim_spt_switchover_infinity
,
3833 no_ip_pim_spt_switchover_infinity_cmd
,
3834 "no ip pim spt-switchover infinity-and-beyond",
3839 "Never switch to SPT Tree\n")
3841 return pim_cmd_spt_switchover (PIM_SPT_IMMEDIATE
, NULL
);
3844 DEFUN (no_ip_pim_spt_switchover_infinity_plist
,
3845 no_ip_pim_spt_switchover_infinity_plist_cmd
,
3846 "no ip pim spt-switchover infinity-and-beyond prefix-list WORD",
3851 "Never switch to SPT Tree\n"
3852 "Prefix-List to control which groups to switch\n"
3853 "Prefix-List name\n")
3855 return pim_cmd_spt_switchover (PIM_SPT_IMMEDIATE
, NULL
);
3858 DEFUN (ip_pim_joinprune_time
,
3859 ip_pim_joinprune_time_cmd
,
3860 "ip pim join-prune-interval (60-600)",
3862 "pim multicast routing\n"
3863 "Join Prune Send Interval\n"
3866 qpim_t_periodic
= atoi(argv
[3]->arg
);
3870 DEFUN (no_ip_pim_joinprune_time
,
3871 no_ip_pim_joinprune_time_cmd
,
3872 "no ip pim join-prune-interval (60-600)",
3875 "pim multicast routing\n"
3876 "Join Prune Send Interval\n"
3879 qpim_t_periodic
= PIM_DEFAULT_T_PERIODIC
;
3883 DEFUN (ip_pim_register_suppress
,
3884 ip_pim_register_suppress_cmd
,
3885 "ip pim register-suppress-time (5-60000)",
3887 "pim multicast routing\n"
3888 "Register Suppress Timer\n"
3891 qpim_register_suppress_time
= atoi (argv
[3]->arg
);
3895 DEFUN (no_ip_pim_register_suppress
,
3896 no_ip_pim_register_suppress_cmd
,
3897 "no ip pim register-suppress-time (5-60000)",
3900 "pim multicast routing\n"
3901 "Register Suppress Timer\n"
3904 qpim_register_suppress_time
= PIM_REGISTER_SUPPRESSION_TIME_DEFAULT
;
3908 DEFUN (ip_pim_keep_alive
,
3909 ip_pim_keep_alive_cmd
,
3910 "ip pim keep-alive-timer (31-60000)",
3912 "pim multicast routing\n"
3913 "Keep alive Timer\n"
3916 qpim_keep_alive_time
= atoi (argv
[3]->arg
);
3920 DEFUN (no_ip_pim_keep_alive
,
3921 no_ip_pim_keep_alive_cmd
,
3922 "no ip pim keep-alive-timer (31-60000)",
3925 "pim multicast routing\n"
3926 "Keep alive Timer\n"
3929 qpim_keep_alive_time
= PIM_KEEPALIVE_PERIOD
;
3933 DEFUN (ip_pim_packets
,
3935 "ip pim packets (1-100)",
3937 "pim multicast routing\n"
3938 "packets to process at one time per fd\n"
3939 "Number of packets\n")
3941 qpim_packet_process
= atoi (argv
[3]->arg
);
3945 DEFUN (no_ip_pim_packets
,
3946 no_ip_pim_packets_cmd
,
3947 "no ip pim packets (1-100)",
3950 "pim multicast routing\n"
3951 "packets to process at one time per fd\n"
3952 "Number of packets\n")
3954 qpim_packet_process
= PIM_DEFAULT_PACKET_PROCESS
;
3958 DEFUN (ip_pim_v6_secondary
,
3959 ip_pim_v6_secondary_cmd
,
3960 "ip pim send-v6-secondary",
3962 "pim multicast routing\n"
3963 "Send v6 secondary addresses\n")
3965 pimg
->send_v6_secondary
= 1;
3970 DEFUN (no_ip_pim_v6_secondary
,
3971 no_ip_pim_v6_secondary_cmd
,
3972 "no ip pim send-v6-secondary",
3975 "pim multicast routing\n"
3976 "Send v6 secondary addresses\n")
3978 pimg
->send_v6_secondary
= 0;
3985 "ip pim rp A.B.C.D [A.B.C.D/M]",
3987 "pim multicast routing\n"
3989 "ip address of RP\n"
3990 "Group Address range to cover\n")
3994 if (argc
== (idx_ipv4
+ 1))
3995 return pim_rp_cmd_worker (vty
, argv
[idx_ipv4
]->arg
, NULL
, NULL
);
3997 return pim_rp_cmd_worker (vty
, argv
[idx_ipv4
]->arg
, argv
[idx_ipv4
+ 1]->arg
, NULL
);
4001 DEFUN (ip_pim_rp_prefix_list
,
4002 ip_pim_rp_prefix_list_cmd
,
4003 "ip pim rp A.B.C.D prefix-list WORD",
4005 "pim multicast routing\n"
4007 "ip address of RP\n"
4008 "group prefix-list filter\n"
4009 "Name of a prefix-list\n")
4011 return pim_rp_cmd_worker (vty
, argv
[3]->arg
, NULL
, argv
[5]->arg
);
4015 pim_no_rp_cmd_worker (struct vty
*vty
, const char *rp
, const char *group
,
4018 int result
= pim_rp_del (rp
, group
, plist
);
4020 if (result
== PIM_GROUP_BAD_ADDRESS
)
4022 vty_out (vty
, "%% Bad group address specified: %s%s", group
, VTY_NEWLINE
);
4026 if (result
== PIM_RP_BAD_ADDRESS
)
4028 vty_out (vty
, "%% Bad RP address specified: %s%s", rp
, VTY_NEWLINE
);
4032 if (result
== PIM_RP_NOT_FOUND
)
4034 vty_out (vty
, "%% Unable to find specified RP%s", VTY_NEWLINE
);
4041 DEFUN (no_ip_pim_rp
,
4043 "no ip pim rp A.B.C.D [A.B.C.D/M]",
4046 "pim multicast routing\n"
4048 "ip address of RP\n"
4049 "Group Address range to cover\n")
4051 int idx_ipv4
= 4, idx_group
= 0;
4053 if (argv_find (argv
, argc
, "A.B.C.D/M", &idx_group
))
4054 return pim_no_rp_cmd_worker (vty
, argv
[idx_ipv4
]->arg
, argv
[idx_group
]->arg
, NULL
);
4056 return pim_no_rp_cmd_worker (vty
, argv
[idx_ipv4
]->arg
, NULL
, NULL
);
4059 DEFUN (no_ip_pim_rp_prefix_list
,
4060 no_ip_pim_rp_prefix_list_cmd
,
4061 "no ip pim rp A.B.C.D prefix-list WORD",
4064 "pim multicast routing\n"
4066 "ip address of RP\n"
4067 "group prefix-list filter\n"
4068 "Name of a prefix-list\n")
4070 return pim_no_rp_cmd_worker (vty
, argv
[4]->arg
, NULL
, argv
[6]->arg
);
4074 pim_ssm_cmd_worker (struct vty
*vty
, const char *plist
)
4076 int result
= pim_ssm_range_set (VRF_DEFAULT
, plist
);
4078 if (result
== PIM_SSM_ERR_NONE
)
4083 case PIM_SSM_ERR_NO_VRF
:
4084 vty_out (vty
, "%% VRF doesn't exist%s", VTY_NEWLINE
);
4086 case PIM_SSM_ERR_DUP
:
4087 vty_out (vty
, "%% duplicate config%s", VTY_NEWLINE
);
4090 vty_out (vty
, "%% ssm range config failed%s", VTY_NEWLINE
);
4096 DEFUN (ip_pim_ssm_prefix_list
,
4097 ip_pim_ssm_prefix_list_cmd
,
4098 "ip pim ssm prefix-list WORD",
4100 "pim multicast routing\n"
4101 "Source Specific Multicast\n"
4102 "group range prefix-list filter\n"
4103 "Name of a prefix-list\n")
4105 return pim_ssm_cmd_worker (vty
, argv
[0]->arg
);
4108 DEFUN (no_ip_pim_ssm_prefix_list
,
4109 no_ip_pim_ssm_prefix_list_cmd
,
4110 "no ip pim ssm prefix-list",
4113 "pim multicast routing\n"
4114 "Source Specific Multicast\n"
4115 "group range prefix-list filter\n")
4117 return pim_ssm_cmd_worker (vty
, NULL
);
4120 DEFUN (no_ip_pim_ssm_prefix_list_name
,
4121 no_ip_pim_ssm_prefix_list_name_cmd
,
4122 "no ip pim ssm prefix-list WORD",
4125 "pim multicast routing\n"
4126 "Source Specific Multicast\n"
4127 "group range prefix-list filter\n"
4128 "Name of a prefix-list\n")
4130 struct pim_ssm
*ssm
= pimg
->ssm_info
;
4132 if (ssm
->plist_name
&& !strcmp(ssm
->plist_name
, argv
[0]->arg
))
4133 return pim_ssm_cmd_worker (vty
, NULL
);
4135 vty_out (vty
, "%% pim ssm prefix-list %s doesn't exist%s",
4136 argv
[0]->arg
, VTY_NEWLINE
);
4142 ip_pim_ssm_show_group_range(struct vty
*vty
, u_char uj
)
4144 struct pim_ssm
*ssm
= pimg
->ssm_info
;
4145 const char *range_str
= ssm
->plist_name
?ssm
->plist_name
:PIM_SSM_STANDARD_RANGE
;
4150 json
= json_object_new_object();
4151 json_object_string_add(json
, "ssmGroups", range_str
);
4152 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
4153 json_object_free(json
);
4156 vty_out(vty
, "SSM group range : %s%s", range_str
, VTY_NEWLINE
);
4159 DEFUN (show_ip_pim_ssm_range
,
4160 show_ip_pim_ssm_range_cmd
,
4161 "show ip pim group-type [json]",
4166 "JavaScript Object Notation\n")
4168 u_char uj
= use_json(argc
, argv
);
4169 ip_pim_ssm_show_group_range(vty
, uj
);
4175 ip_pim_ssm_show_group_type(struct vty
*vty
, u_char uj
, const char *group
)
4177 struct in_addr group_addr
;
4178 const char *type_str
;
4181 result
= inet_pton(AF_INET
, group
, &group_addr
);
4183 type_str
= "invalid";
4186 if (pim_is_group_224_4 (group_addr
))
4187 type_str
= pim_is_grp_ssm (group_addr
)?"SSM":"ASM";
4189 type_str
= "not-multicast";
4195 json
= json_object_new_object();
4196 json_object_string_add(json
, "groupType", type_str
);
4197 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
4198 json_object_free(json
);
4201 vty_out(vty
, "Group type : %s%s", type_str
, VTY_NEWLINE
);
4204 DEFUN (show_ip_pim_group_type
,
4205 show_ip_pim_group_type_cmd
,
4206 "show ip pim group-type A.B.C.D [json]",
4210 "multicast group type\n"
4212 "JavaScript Object Notation\n")
4214 u_char uj
= use_json(argc
, argv
);
4215 ip_pim_ssm_show_group_type(vty
, uj
, argv
[0]->arg
);
4220 DEFUN_HIDDEN (ip_multicast_routing
,
4221 ip_multicast_routing_cmd
,
4222 "ip multicast-routing",
4224 "Enable IP multicast forwarding\n")
4229 DEFUN_HIDDEN (no_ip_multicast_routing
,
4230 no_ip_multicast_routing_cmd
,
4231 "no ip multicast-routing",
4234 "Global IP configuration subcommands\n"
4235 "Enable IP multicast forwarding\n")
4237 vty_out (vty
, "Command is Disabled and will be removed in a future version%s", VTY_NEWLINE
);
4243 "ip ssmpingd [A.B.C.D]",
4250 struct in_addr source_addr
;
4251 const char *source_str
= (argc
== 3) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
4253 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
4255 vty_out(vty
, "%% Bad source address %s: errno=%d: %s%s",
4256 source_str
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
4260 result
= pim_ssmpingd_start(source_addr
);
4262 vty_out(vty
, "%% Failure starting ssmpingd for source %s: %d%s",
4263 source_str
, result
, VTY_NEWLINE
);
4270 DEFUN (no_ip_ssmpingd
,
4272 "no ip ssmpingd [A.B.C.D]",
4280 struct in_addr source_addr
;
4281 const char *source_str
= (argc
== 4) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
4283 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
4285 vty_out(vty
, "%% Bad source address %s: errno=%d: %s%s",
4286 source_str
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
4290 result
= pim_ssmpingd_stop(source_addr
);
4292 vty_out(vty
, "%% Failure stopping ssmpingd for source %s: %d%s",
4293 source_str
, result
, VTY_NEWLINE
);
4304 "pim multicast routing\n"
4305 "Enable PIM ECMP \n")
4307 qpim_ecmp_enable
= 1;
4312 DEFUN (no_ip_pim_ecmp
,
4317 "pim multicast routing\n"
4318 "Disable PIM ECMP \n")
4320 qpim_ecmp_enable
= 0;
4325 DEFUN (ip_pim_ecmp_rebalance
,
4326 ip_pim_ecmp_rebalance_cmd
,
4327 "ip pim ecmp rebalance",
4329 "pim multicast routing\n"
4330 "Enable PIM ECMP \n"
4331 "Enable PIM ECMP Rebalance\n")
4333 qpim_ecmp_enable
= 1;
4334 qpim_ecmp_rebalance_enable
= 1;
4339 DEFUN (no_ip_pim_ecmp_rebalance
,
4340 no_ip_pim_ecmp_rebalance_cmd
,
4341 "no ip pim ecmp rebalance",
4344 "pim multicast routing\n"
4345 "Disable PIM ECMP \n"
4346 "Disable PIM ECMP Rebalance\n")
4348 qpim_ecmp_rebalance_enable
= 0;
4354 pim_cmd_igmp_start (struct vty
*vty
, struct interface
*ifp
)
4356 struct pim_interface
*pim_ifp
;
4357 uint8_t need_startup
= 0;
4359 pim_ifp
= ifp
->info
;
4363 pim_ifp
= pim_if_new(ifp
, 1 /* igmp=true */, 0 /* pim=false */);
4366 vty_out(vty
, "Could not enable IGMP on interface %s%s",
4367 ifp
->name
, VTY_NEWLINE
);
4374 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
))
4376 PIM_IF_DO_IGMP(pim_ifp
->options
);
4381 /* 'ip igmp' executed multiple times, with need_startup
4382 avoid multiple if add all and membership refresh */
4385 pim_if_addr_add_all(ifp
);
4386 pim_if_membership_refresh(ifp
);
4392 DEFUN (interface_ip_igmp
,
4393 interface_ip_igmp_cmd
,
4398 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4400 return pim_cmd_igmp_start(vty
, ifp
);
4403 DEFUN (interface_no_ip_igmp
,
4404 interface_no_ip_igmp_cmd
,
4410 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4411 struct pim_interface
*pim_ifp
;
4413 pim_ifp
= ifp
->info
;
4417 PIM_IF_DONT_IGMP(pim_ifp
->options
);
4419 pim_if_membership_clear(ifp
);
4421 pim_if_addr_del_all_igmp(ifp
);
4423 if (!PIM_IF_TEST_PIM(pim_ifp
->options
)) {
4430 DEFUN (interface_ip_igmp_join
,
4431 interface_ip_igmp_join_cmd
,
4432 "ip igmp join A.B.C.D A.B.C.D",
4435 "IGMP join multicast group\n"
4436 "Multicast group address\n"
4439 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4442 const char *group_str
;
4443 const char *source_str
;
4444 struct in_addr group_addr
;
4445 struct in_addr source_addr
;
4449 group_str
= argv
[idx_ipv4
]->arg
;
4450 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
4452 vty_out(vty
, "Bad group address %s: errno=%d: %s%s",
4453 group_str
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
4457 /* Source address */
4458 source_str
= argv
[idx_ipv4_2
]->arg
;
4459 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
4461 vty_out(vty
, "Bad source address %s: errno=%d: %s%s",
4462 source_str
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
4466 result
= pim_if_igmp_join_add(ifp
, group_addr
, source_addr
);
4468 vty_out(vty
, "%% Failure joining IGMP group %s source %s on interface %s: %d%s",
4469 group_str
, source_str
, ifp
->name
, result
, VTY_NEWLINE
);
4476 DEFUN (interface_no_ip_igmp_join
,
4477 interface_no_ip_igmp_join_cmd
,
4478 "no ip igmp join A.B.C.D A.B.C.D",
4482 "IGMP join multicast group\n"
4483 "Multicast group address\n"
4486 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4489 const char *group_str
;
4490 const char *source_str
;
4491 struct in_addr group_addr
;
4492 struct in_addr source_addr
;
4496 group_str
= argv
[idx_ipv4
]->arg
;
4497 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
4499 vty_out(vty
, "Bad group address %s: errno=%d: %s%s",
4500 group_str
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
4504 /* Source address */
4505 source_str
= argv
[idx_ipv4_2
]->arg
;
4506 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
4508 vty_out(vty
, "Bad source address %s: errno=%d: %s%s",
4509 source_str
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
4513 result
= pim_if_igmp_join_del(ifp
, group_addr
, source_addr
);
4515 vty_out(vty
, "%% Failure leaving IGMP group %s source %s on interface %s: %d%s",
4516 group_str
, source_str
, ifp
->name
, result
, VTY_NEWLINE
);
4524 CLI reconfiguration affects the interface level (struct pim_interface).
4525 This function propagates the reconfiguration to every active socket
4528 static void igmp_sock_query_interval_reconfig(struct igmp_sock
*igmp
)
4530 struct interface
*ifp
;
4531 struct pim_interface
*pim_ifp
;
4535 /* other querier present? */
4537 if (igmp
->t_other_querier_timer
)
4540 /* this is the querier */
4542 zassert(igmp
->interface
);
4543 zassert(igmp
->interface
->info
);
4545 ifp
= igmp
->interface
;
4546 pim_ifp
= ifp
->info
;
4548 if (PIM_DEBUG_IGMP_TRACE
) {
4549 char ifaddr_str
[INET_ADDRSTRLEN
];
4550 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
, sizeof(ifaddr_str
));
4551 zlog_debug("%s: Querier %s on %s reconfig query_interval=%d",
4552 __PRETTY_FUNCTION__
,
4555 pim_ifp
->igmp_default_query_interval
);
4559 igmp_startup_mode_on() will reset QQI:
4561 igmp->querier_query_interval = pim_ifp->igmp_default_query_interval;
4563 igmp_startup_mode_on(igmp
);
4566 static void igmp_sock_query_reschedule(struct igmp_sock
*igmp
)
4568 if (igmp
->t_igmp_query_timer
) {
4569 /* other querier present */
4570 zassert(igmp
->t_igmp_query_timer
);
4571 zassert(!igmp
->t_other_querier_timer
);
4573 pim_igmp_general_query_off(igmp
);
4574 pim_igmp_general_query_on(igmp
);
4576 zassert(igmp
->t_igmp_query_timer
);
4577 zassert(!igmp
->t_other_querier_timer
);
4580 /* this is the querier */
4582 zassert(!igmp
->t_igmp_query_timer
);
4583 zassert(igmp
->t_other_querier_timer
);
4585 pim_igmp_other_querier_timer_off(igmp
);
4586 pim_igmp_other_querier_timer_on(igmp
);
4588 zassert(!igmp
->t_igmp_query_timer
);
4589 zassert(igmp
->t_other_querier_timer
);
4593 static void change_query_interval(struct pim_interface
*pim_ifp
,
4596 struct listnode
*sock_node
;
4597 struct igmp_sock
*igmp
;
4599 pim_ifp
->igmp_default_query_interval
= query_interval
;
4601 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
4602 igmp_sock_query_interval_reconfig(igmp
);
4603 igmp_sock_query_reschedule(igmp
);
4607 static void change_query_max_response_time(struct pim_interface
*pim_ifp
,
4608 int query_max_response_time_dsec
)
4610 struct listnode
*sock_node
;
4611 struct igmp_sock
*igmp
;
4613 pim_ifp
->igmp_query_max_response_time_dsec
= query_max_response_time_dsec
;
4616 Below we modify socket/group/source timers in order to quickly
4617 reflect the change. Otherwise, those timers would eventually catch
4621 /* scan all sockets */
4622 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
4623 struct listnode
*grp_node
;
4624 struct igmp_group
*grp
;
4626 /* reschedule socket general query */
4627 igmp_sock_query_reschedule(igmp
);
4629 /* scan socket groups */
4630 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grp_node
, grp
)) {
4631 struct listnode
*src_node
;
4632 struct igmp_source
*src
;
4634 /* reset group timers for groups in EXCLUDE mode */
4635 if (grp
->group_filtermode_isexcl
) {
4636 igmp_group_reset_gmi(grp
);
4639 /* scan group sources */
4640 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
, src_node
, src
)) {
4642 /* reset source timers for sources with running timers */
4643 if (src
->t_source_timer
) {
4644 igmp_source_reset_gmi(igmp
, grp
, src
);
4651 #define IGMP_QUERY_INTERVAL_MIN (1)
4652 #define IGMP_QUERY_INTERVAL_MAX (1800)
4654 DEFUN (interface_ip_igmp_query_interval
,
4655 interface_ip_igmp_query_interval_cmd
,
4656 "ip igmp query-interval (1-1800)",
4659 IFACE_IGMP_QUERY_INTERVAL_STR
4660 "Query interval in seconds\n")
4662 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4663 struct pim_interface
*pim_ifp
;
4665 int query_interval_dsec
;
4668 pim_ifp
= ifp
->info
;
4671 ret
= pim_cmd_igmp_start(vty
, ifp
);
4672 if (ret
!= CMD_SUCCESS
)
4674 pim_ifp
= ifp
->info
;
4677 query_interval
= atoi(argv
[3]->arg
);
4678 query_interval_dsec
= 10 * query_interval
;
4681 It seems we don't need to check bounds since command.c does it
4682 already, but we verify them anyway for extra safety.
4684 if (query_interval
< IGMP_QUERY_INTERVAL_MIN
) {
4685 vty_out(vty
, "General query interval %d lower than minimum %d%s",
4687 IGMP_QUERY_INTERVAL_MIN
,
4691 if (query_interval
> IGMP_QUERY_INTERVAL_MAX
) {
4692 vty_out(vty
, "General query interval %d higher than maximum %d%s",
4694 IGMP_QUERY_INTERVAL_MAX
,
4699 if (query_interval_dsec
<= pim_ifp
->igmp_query_max_response_time_dsec
) {
4701 "Can't set general query interval %d dsec <= query max response time %d dsec.%s",
4702 query_interval_dsec
, pim_ifp
->igmp_query_max_response_time_dsec
,
4707 change_query_interval(pim_ifp
, query_interval
);
4712 DEFUN (interface_no_ip_igmp_query_interval
,
4713 interface_no_ip_igmp_query_interval_cmd
,
4714 "no ip igmp query-interval",
4718 IFACE_IGMP_QUERY_INTERVAL_STR
)
4720 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4721 struct pim_interface
*pim_ifp
;
4722 int default_query_interval_dsec
;
4724 pim_ifp
= ifp
->info
;
4729 default_query_interval_dsec
= IGMP_GENERAL_QUERY_INTERVAL
* 10;
4731 if (default_query_interval_dsec
<= pim_ifp
->igmp_query_max_response_time_dsec
) {
4733 "Can't set default general query interval %d dsec <= query max response time %d dsec.%s",
4734 default_query_interval_dsec
, pim_ifp
->igmp_query_max_response_time_dsec
,
4739 change_query_interval(pim_ifp
, IGMP_GENERAL_QUERY_INTERVAL
);
4744 DEFUN (interface_ip_igmp_version
,
4745 interface_ip_igmp_version_cmd
,
4746 "ip igmp version (2-3)",
4750 "IGMP version number\n")
4752 VTY_DECLVAR_CONTEXT(interface
,ifp
);
4753 struct pim_interface
*pim_ifp
= NULL
;
4754 int igmp_version
, old_version
= 0;
4757 pim_ifp
= ifp
->info
;
4761 ret
= pim_cmd_igmp_start(vty
, ifp
);
4762 if (ret
!= CMD_SUCCESS
)
4764 pim_ifp
= ifp
->info
;
4767 igmp_version
= atoi(argv
[3]->arg
);
4768 old_version
= pim_ifp
->igmp_version
;
4769 pim_ifp
->igmp_version
= igmp_version
;
4771 //Check if IGMP is Enabled otherwise, enable on interface
4772 if (!PIM_IF_TEST_IGMP (pim_ifp
->options
))
4774 PIM_IF_DO_IGMP(pim_ifp
->options
);
4775 pim_if_addr_add_all(ifp
);
4776 pim_if_membership_refresh(ifp
);
4777 old_version
= igmp_version
; //avoid refreshing membership again.
4779 /* Current and new version is different refresh existing
4780 membership. Going from 3 -> 2 or 2 -> 3. */
4781 if (old_version
!= igmp_version
)
4782 pim_if_membership_refresh(ifp
);
4787 DEFUN (interface_no_ip_igmp_version
,
4788 interface_no_ip_igmp_version_cmd
,
4789 "no ip igmp version (2-3)",
4794 "IGMP version number\n")
4796 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4797 struct pim_interface
*pim_ifp
;
4799 pim_ifp
= ifp
->info
;
4804 pim_ifp
->igmp_version
= IGMP_DEFAULT_VERSION
;
4809 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
4810 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
4812 DEFUN (interface_ip_igmp_query_max_response_time
,
4813 interface_ip_igmp_query_max_response_time_cmd
,
4814 "ip igmp query-max-response-time (10-250)",
4817 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
4818 "Query response value in deci-seconds\n")
4820 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4821 struct pim_interface
*pim_ifp
;
4822 int query_max_response_time
;
4825 pim_ifp
= ifp
->info
;
4828 ret
= pim_cmd_igmp_start(vty
, ifp
);
4829 if (ret
!= CMD_SUCCESS
)
4831 pim_ifp
= ifp
->info
;
4834 query_max_response_time
= atoi(argv
[3]->arg
);
4836 if (query_max_response_time
>= pim_ifp
->igmp_default_query_interval
* 10) {
4838 "Can't set query max response time %d sec >= general query interval %d sec%s",
4839 query_max_response_time
, pim_ifp
->igmp_default_query_interval
,
4844 change_query_max_response_time(pim_ifp
, query_max_response_time
);
4849 DEFUN (interface_no_ip_igmp_query_max_response_time
,
4850 interface_no_ip_igmp_query_max_response_time_cmd
,
4851 "no ip igmp query-max-response-time (10-250)",
4855 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
4856 "Time for response in deci-seconds\n")
4858 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4859 struct pim_interface
*pim_ifp
;
4861 pim_ifp
= ifp
->info
;
4866 change_query_max_response_time(pim_ifp
, IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
4871 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
4872 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
4874 DEFUN_HIDDEN (interface_ip_igmp_query_max_response_time_dsec
,
4875 interface_ip_igmp_query_max_response_time_dsec_cmd
,
4876 "ip igmp query-max-response-time-dsec (10-250)",
4879 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
4880 "Query response value in deciseconds\n")
4882 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4883 struct pim_interface
*pim_ifp
;
4884 int query_max_response_time_dsec
;
4885 int default_query_interval_dsec
;
4888 pim_ifp
= ifp
->info
;
4891 ret
= pim_cmd_igmp_start(vty
, ifp
);
4892 if (ret
!= CMD_SUCCESS
)
4894 pim_ifp
= ifp
->info
;
4897 query_max_response_time_dsec
= atoi(argv
[4]->arg
);
4899 default_query_interval_dsec
= 10 * pim_ifp
->igmp_default_query_interval
;
4901 if (query_max_response_time_dsec
>= default_query_interval_dsec
) {
4903 "Can't set query max response time %d dsec >= general query interval %d dsec%s",
4904 query_max_response_time_dsec
, default_query_interval_dsec
,
4909 change_query_max_response_time(pim_ifp
, query_max_response_time_dsec
);
4914 DEFUN_HIDDEN (interface_no_ip_igmp_query_max_response_time_dsec
,
4915 interface_no_ip_igmp_query_max_response_time_dsec_cmd
,
4916 "no ip igmp query-max-response-time-dsec",
4920 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
)
4922 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4923 struct pim_interface
*pim_ifp
;
4925 pim_ifp
= ifp
->info
;
4930 change_query_max_response_time(pim_ifp
, IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
4935 DEFUN (interface_ip_pim_drprio
,
4936 interface_ip_pim_drprio_cmd
,
4937 "ip pim drpriority (1-4294967295)",
4940 "Set the Designated Router Election Priority\n"
4941 "Value of the new DR Priority\n")
4943 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4945 struct pim_interface
*pim_ifp
;
4946 uint32_t old_dr_prio
;
4948 pim_ifp
= ifp
->info
;
4951 vty_out(vty
, "Please enable PIM on interface, first%s", VTY_NEWLINE
);
4955 old_dr_prio
= pim_ifp
->pim_dr_priority
;
4957 pim_ifp
->pim_dr_priority
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
4959 if (old_dr_prio
!= pim_ifp
->pim_dr_priority
) {
4960 if (pim_if_dr_election(ifp
))
4961 pim_hello_restart_now(ifp
);
4967 DEFUN (interface_no_ip_pim_drprio
,
4968 interface_no_ip_pim_drprio_cmd
,
4969 "no ip pim drpriority [(1-4294967295)]",
4973 "Revert the Designated Router Priority to default\n"
4974 "Old Value of the Priority\n")
4976 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4977 struct pim_interface
*pim_ifp
;
4979 pim_ifp
= ifp
->info
;
4982 vty_out(vty
, "Pim not enabled on this interface%s", VTY_NEWLINE
);
4986 if (pim_ifp
->pim_dr_priority
!= PIM_DEFAULT_DR_PRIORITY
) {
4987 pim_ifp
->pim_dr_priority
= PIM_DEFAULT_DR_PRIORITY
;
4988 if (pim_if_dr_election(ifp
))
4989 pim_hello_restart_now(ifp
);
4996 pim_cmd_interface_add (struct interface
*ifp
)
4998 struct pim_interface
*pim_ifp
= ifp
->info
;
5001 pim_ifp
= pim_if_new(ifp
, 0 /* igmp=false */, 1 /* pim=true */);
5007 PIM_IF_DO_PIM(pim_ifp
->options
);
5010 pim_if_addr_add_all(ifp
);
5011 pim_if_membership_refresh(ifp
);
5015 DEFUN_HIDDEN (interface_ip_pim_ssm
,
5016 interface_ip_pim_ssm_cmd
,
5022 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5024 if (!pim_cmd_interface_add(ifp
)) {
5025 vty_out(vty
, "Could not enable PIM SM on interface%s", VTY_NEWLINE
);
5029 vty_out(vty
, "WARN: Enabled PIM SM on interface; configure PIM SSM range if needed%s", VTY_NEWLINE
);
5033 DEFUN (interface_ip_pim_sm
,
5034 interface_ip_pim_sm_cmd
,
5040 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5041 if (!pim_cmd_interface_add(ifp
)) {
5042 vty_out(vty
, "Could not enable PIM SM on interface%s", VTY_NEWLINE
);
5046 pim_if_create_pimreg();
5052 pim_cmd_interface_delete (struct interface
*ifp
)
5054 struct pim_interface
*pim_ifp
= ifp
->info
;
5059 PIM_IF_DONT_PIM(pim_ifp
->options
);
5061 pim_if_membership_clear(ifp
);
5064 pim_sock_delete() removes all neighbors from
5065 pim_ifp->pim_neighbor_list.
5067 pim_sock_delete(ifp
, "pim unconfigured on interface");
5069 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
5070 pim_if_addr_del_all(ifp
);
5077 DEFUN_HIDDEN (interface_no_ip_pim_ssm
,
5078 interface_no_ip_pim_ssm_cmd
,
5085 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5086 if (!pim_cmd_interface_delete(ifp
)) {
5087 vty_out(vty
, "Unable to delete interface information%s", VTY_NEWLINE
);
5094 DEFUN (interface_no_ip_pim_sm
,
5095 interface_no_ip_pim_sm_cmd
,
5102 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5103 if (!pim_cmd_interface_delete(ifp
)) {
5104 vty_out(vty
, "Unable to delete interface information%s", VTY_NEWLINE
);
5111 DEFUN (interface_ip_mroute
,
5112 interface_ip_mroute_cmd
,
5113 "ip mroute INTERFACE A.B.C.D",
5115 "Add multicast route\n"
5116 "Outgoing interface name\n"
5119 VTY_DECLVAR_CONTEXT(interface
, iif
);
5120 int idx_interface
= 2;
5122 struct interface
*oif
;
5123 const char *oifname
;
5124 const char *grp_str
;
5125 struct in_addr grp_addr
;
5126 struct in_addr src_addr
;
5129 oifname
= argv
[idx_interface
]->arg
;
5130 oif
= if_lookup_by_name(oifname
, VRF_DEFAULT
);
5132 vty_out(vty
, "No such interface name %s%s",
5133 oifname
, VTY_NEWLINE
);
5137 grp_str
= argv
[idx_ipv4
]->arg
;
5138 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
5140 vty_out(vty
, "Bad group address %s: errno=%d: %s%s",
5141 grp_str
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
5145 src_addr
.s_addr
= INADDR_ANY
;
5147 if (pim_static_add(iif
, oif
, grp_addr
, src_addr
)) {
5148 vty_out(vty
, "Failed to add route%s", VTY_NEWLINE
);
5155 DEFUN (interface_ip_mroute_source
,
5156 interface_ip_mroute_source_cmd
,
5157 "ip mroute INTERFACE A.B.C.D A.B.C.D",
5159 "Add multicast route\n"
5160 "Outgoing interface name\n"
5164 VTY_DECLVAR_CONTEXT(interface
, iif
);
5165 int idx_interface
= 2;
5168 struct interface
*oif
;
5169 const char *oifname
;
5170 const char *grp_str
;
5171 struct in_addr grp_addr
;
5172 const char *src_str
;
5173 struct in_addr src_addr
;
5176 oifname
= argv
[idx_interface
]->arg
;
5177 oif
= if_lookup_by_name(oifname
, VRF_DEFAULT
);
5179 vty_out(vty
, "No such interface name %s%s",
5180 oifname
, VTY_NEWLINE
);
5184 grp_str
= argv
[idx_ipv4
]->arg
;
5185 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
5187 vty_out(vty
, "Bad group address %s: errno=%d: %s%s",
5188 grp_str
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
5192 src_str
= argv
[idx_ipv4_2
]->arg
;
5193 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
5195 vty_out(vty
, "Bad source address %s: errno=%d: %s%s",
5196 src_str
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
5200 if (pim_static_add(iif
, oif
, grp_addr
, src_addr
)) {
5201 vty_out(vty
, "Failed to add route%s", VTY_NEWLINE
);
5208 DEFUN (interface_no_ip_mroute
,
5209 interface_no_ip_mroute_cmd
,
5210 "no ip mroute INTERFACE A.B.C.D",
5213 "Add multicast route\n"
5214 "Outgoing interface name\n"
5217 VTY_DECLVAR_CONTEXT(interface
, iif
);
5218 int idx_interface
= 3;
5220 struct interface
*oif
;
5221 const char *oifname
;
5222 const char *grp_str
;
5223 struct in_addr grp_addr
;
5224 struct in_addr src_addr
;
5227 oifname
= argv
[idx_interface
]->arg
;
5228 oif
= if_lookup_by_name(oifname
, VRF_DEFAULT
);
5230 vty_out(vty
, "No such interface name %s%s",
5231 oifname
, VTY_NEWLINE
);
5235 grp_str
= argv
[idx_ipv4
]->arg
;
5236 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
5238 vty_out(vty
, "Bad group address %s: errno=%d: %s%s",
5239 grp_str
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
5243 src_addr
.s_addr
= INADDR_ANY
;
5245 if (pim_static_del(iif
, oif
, grp_addr
, src_addr
)) {
5246 vty_out(vty
, "Failed to remove route%s", VTY_NEWLINE
);
5253 DEFUN (interface_no_ip_mroute_source
,
5254 interface_no_ip_mroute_source_cmd
,
5255 "no ip mroute INTERFACE A.B.C.D A.B.C.D",
5258 "Add multicast route\n"
5259 "Outgoing interface name\n"
5263 VTY_DECLVAR_CONTEXT(interface
, iif
);
5264 int idx_interface
= 3;
5267 struct interface
*oif
;
5268 const char *oifname
;
5269 const char *grp_str
;
5270 struct in_addr grp_addr
;
5271 const char *src_str
;
5272 struct in_addr src_addr
;
5275 oifname
= argv
[idx_interface
]->arg
;
5276 oif
= if_lookup_by_name(oifname
, VRF_DEFAULT
);
5278 vty_out(vty
, "No such interface name %s%s",
5279 oifname
, VTY_NEWLINE
);
5283 grp_str
= argv
[idx_ipv4
]->arg
;
5284 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
5286 vty_out(vty
, "Bad group address %s: errno=%d: %s%s",
5287 grp_str
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
5291 src_str
= argv
[idx_ipv4_2
]->arg
;
5292 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
5294 vty_out(vty
, "Bad source address %s: errno=%d: %s%s",
5295 src_str
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
5299 if (pim_static_del(iif
, oif
, grp_addr
, src_addr
)) {
5300 vty_out(vty
, "Failed to remove route%s", VTY_NEWLINE
);
5307 DEFUN (interface_ip_pim_hello
,
5308 interface_ip_pim_hello_cmd
,
5309 "ip pim hello (1-180) [(1-180)]",
5313 IFACE_PIM_HELLO_TIME_STR
5314 IFACE_PIM_HELLO_HOLD_STR
)
5316 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5319 struct pim_interface
*pim_ifp
;
5321 pim_ifp
= ifp
->info
;
5325 if (!pim_cmd_interface_add(ifp
))
5327 vty_out(vty
, "Could not enable PIM SM on interface%s", VTY_NEWLINE
);
5332 pim_ifp
= ifp
->info
;
5333 pim_ifp
->pim_hello_period
= strtol(argv
[idx_time
]->arg
, NULL
, 10);
5335 if (argc
== idx_hold
+ 1)
5336 pim_ifp
->pim_default_holdtime
= strtol(argv
[idx_hold
]->arg
, NULL
, 10);
5343 DEFUN (interface_no_ip_pim_hello
,
5344 interface_no_ip_pim_hello_cmd
,
5345 "no ip pim hello [(1-180) (1-180)]",
5350 IFACE_PIM_HELLO_TIME_STR
5351 IFACE_PIM_HELLO_HOLD_STR
)
5353 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5354 struct pim_interface
*pim_ifp
;
5356 pim_ifp
= ifp
->info
;
5359 vty_out(vty
, "Pim not enabled on this interface%s", VTY_NEWLINE
);
5363 pim_ifp
->pim_hello_period
= PIM_DEFAULT_HELLO_PERIOD
;
5364 pim_ifp
->pim_default_holdtime
= -1;
5375 PIM_DO_DEBUG_IGMP_EVENTS
;
5376 PIM_DO_DEBUG_IGMP_PACKETS
;
5377 PIM_DO_DEBUG_IGMP_TRACE
;
5381 DEFUN (no_debug_igmp
,
5388 PIM_DONT_DEBUG_IGMP_EVENTS
;
5389 PIM_DONT_DEBUG_IGMP_PACKETS
;
5390 PIM_DONT_DEBUG_IGMP_TRACE
;
5395 DEFUN (debug_igmp_events
,
5396 debug_igmp_events_cmd
,
5397 "debug igmp events",
5400 DEBUG_IGMP_EVENTS_STR
)
5402 PIM_DO_DEBUG_IGMP_EVENTS
;
5406 DEFUN (no_debug_igmp_events
,
5407 no_debug_igmp_events_cmd
,
5408 "no debug igmp events",
5412 DEBUG_IGMP_EVENTS_STR
)
5414 PIM_DONT_DEBUG_IGMP_EVENTS
;
5419 DEFUN (debug_igmp_packets
,
5420 debug_igmp_packets_cmd
,
5421 "debug igmp packets",
5424 DEBUG_IGMP_PACKETS_STR
)
5426 PIM_DO_DEBUG_IGMP_PACKETS
;
5430 DEFUN (no_debug_igmp_packets
,
5431 no_debug_igmp_packets_cmd
,
5432 "no debug igmp packets",
5436 DEBUG_IGMP_PACKETS_STR
)
5438 PIM_DONT_DEBUG_IGMP_PACKETS
;
5443 DEFUN (debug_igmp_trace
,
5444 debug_igmp_trace_cmd
,
5448 DEBUG_IGMP_TRACE_STR
)
5450 PIM_DO_DEBUG_IGMP_TRACE
;
5454 DEFUN (no_debug_igmp_trace
,
5455 no_debug_igmp_trace_cmd
,
5456 "no debug igmp trace",
5460 DEBUG_IGMP_TRACE_STR
)
5462 PIM_DONT_DEBUG_IGMP_TRACE
;
5467 DEFUN (debug_mroute
,
5473 PIM_DO_DEBUG_MROUTE
;
5477 DEFUN (debug_mroute_detail
,
5478 debug_mroute_detail_cmd
,
5479 "debug mroute detail",
5484 PIM_DO_DEBUG_MROUTE_DETAIL
;
5488 DEFUN (no_debug_mroute
,
5489 no_debug_mroute_cmd
,
5495 PIM_DONT_DEBUG_MROUTE
;
5499 DEFUN (no_debug_mroute_detail
,
5500 no_debug_mroute_detail_cmd
,
5501 "no debug mroute detail",
5507 PIM_DONT_DEBUG_MROUTE_DETAIL
;
5511 DEFUN (debug_static
,
5517 PIM_DO_DEBUG_STATIC
;
5521 DEFUN (no_debug_static
,
5522 no_debug_static_cmd
,
5528 PIM_DONT_DEBUG_STATIC
;
5539 PIM_DO_DEBUG_PIM_EVENTS
;
5540 PIM_DO_DEBUG_PIM_PACKETS
;
5541 PIM_DO_DEBUG_PIM_TRACE
;
5542 PIM_DO_DEBUG_MSDP_EVENTS
;
5543 PIM_DO_DEBUG_MSDP_PACKETS
;
5547 DEFUN (no_debug_pim
,
5554 PIM_DONT_DEBUG_PIM_EVENTS
;
5555 PIM_DONT_DEBUG_PIM_PACKETS
;
5556 PIM_DONT_DEBUG_PIM_TRACE
;
5557 PIM_DONT_DEBUG_MSDP_EVENTS
;
5558 PIM_DONT_DEBUG_MSDP_PACKETS
;
5560 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
5561 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
5567 DEFUN (debug_pim_events
,
5568 debug_pim_events_cmd
,
5572 DEBUG_PIM_EVENTS_STR
)
5574 PIM_DO_DEBUG_PIM_EVENTS
;
5578 DEFUN (no_debug_pim_events
,
5579 no_debug_pim_events_cmd
,
5580 "no debug pim events",
5584 DEBUG_PIM_EVENTS_STR
)
5586 PIM_DONT_DEBUG_PIM_EVENTS
;
5590 DEFUN (debug_pim_packets
,
5591 debug_pim_packets_cmd
,
5592 "debug pim packets [<hello|joins|register>]",
5595 DEBUG_PIM_PACKETS_STR
5596 DEBUG_PIM_HELLO_PACKETS_STR
5597 DEBUG_PIM_J_P_PACKETS_STR
5598 DEBUG_PIM_PIM_REG_PACKETS_STR
)
5601 if (argv_find (argv
, argc
, "hello", &idx
))
5603 PIM_DO_DEBUG_PIM_HELLO
;
5604 vty_out (vty
, "PIM Hello debugging is on%s", VTY_NEWLINE
);
5606 else if (argv_find (argv
, argc
,"joins", &idx
))
5608 PIM_DO_DEBUG_PIM_J_P
;
5609 vty_out (vty
, "PIM Join/Prune debugging is on%s", VTY_NEWLINE
);
5611 else if (argv_find (argv
, argc
, "register", &idx
))
5613 PIM_DO_DEBUG_PIM_REG
;
5614 vty_out (vty
, "PIM Register debugging is on%s", VTY_NEWLINE
);
5618 PIM_DO_DEBUG_PIM_PACKETS
;
5619 vty_out (vty
, "PIM Packet debugging is on %s", VTY_NEWLINE
);
5624 DEFUN (no_debug_pim_packets
,
5625 no_debug_pim_packets_cmd
,
5626 "no debug pim packets [<hello|joins|register>]",
5630 DEBUG_PIM_PACKETS_STR
5631 DEBUG_PIM_HELLO_PACKETS_STR
5632 DEBUG_PIM_J_P_PACKETS_STR
5633 DEBUG_PIM_PIM_REG_PACKETS_STR
)
5636 if (argv_find (argv
, argc
,"hello",&idx
))
5638 PIM_DONT_DEBUG_PIM_HELLO
;
5639 vty_out (vty
, "PIM Hello debugging is off %s", VTY_NEWLINE
);
5641 else if (argv_find (argv
, argc
, "joins", &idx
))
5643 PIM_DONT_DEBUG_PIM_J_P
;
5644 vty_out (vty
, "PIM Join/Prune debugging is off %s", VTY_NEWLINE
);
5646 else if (argv_find (argv
, argc
, "register", &idx
))
5648 PIM_DONT_DEBUG_PIM_REG
;
5649 vty_out (vty
, "PIM Register debugging is off%s", VTY_NEWLINE
);
5652 PIM_DONT_DEBUG_PIM_PACKETS
;
5658 DEFUN (debug_pim_packetdump_send
,
5659 debug_pim_packetdump_send_cmd
,
5660 "debug pim packet-dump send",
5663 DEBUG_PIM_PACKETDUMP_STR
5664 DEBUG_PIM_PACKETDUMP_SEND_STR
)
5666 PIM_DO_DEBUG_PIM_PACKETDUMP_SEND
;
5670 DEFUN (no_debug_pim_packetdump_send
,
5671 no_debug_pim_packetdump_send_cmd
,
5672 "no debug pim packet-dump send",
5676 DEBUG_PIM_PACKETDUMP_STR
5677 DEBUG_PIM_PACKETDUMP_SEND_STR
)
5679 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
5684 DEFUN (debug_pim_packetdump_recv
,
5685 debug_pim_packetdump_recv_cmd
,
5686 "debug pim packet-dump receive",
5689 DEBUG_PIM_PACKETDUMP_STR
5690 DEBUG_PIM_PACKETDUMP_RECV_STR
)
5692 PIM_DO_DEBUG_PIM_PACKETDUMP_RECV
;
5696 DEFUN (no_debug_pim_packetdump_recv
,
5697 no_debug_pim_packetdump_recv_cmd
,
5698 "no debug pim packet-dump receive",
5702 DEBUG_PIM_PACKETDUMP_STR
5703 DEBUG_PIM_PACKETDUMP_RECV_STR
)
5705 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
5710 DEFUN (debug_pim_trace
,
5711 debug_pim_trace_cmd
,
5715 DEBUG_PIM_TRACE_STR
)
5717 PIM_DO_DEBUG_PIM_TRACE
;
5721 DEFUN (no_debug_pim_trace
,
5722 no_debug_pim_trace_cmd
,
5723 "no debug pim trace",
5727 DEBUG_PIM_TRACE_STR
)
5729 PIM_DONT_DEBUG_PIM_TRACE
;
5734 DEFUN (debug_ssmpingd
,
5741 PIM_DO_DEBUG_SSMPINGD
;
5745 DEFUN (no_debug_ssmpingd
,
5746 no_debug_ssmpingd_cmd
,
5747 "no debug ssmpingd",
5753 PIM_DONT_DEBUG_SSMPINGD
;
5758 DEFUN (debug_pim_zebra
,
5759 debug_pim_zebra_cmd
,
5763 DEBUG_PIM_ZEBRA_STR
)
5769 DEFUN (no_debug_pim_zebra
,
5770 no_debug_pim_zebra_cmd
,
5771 "no debug pim zebra",
5775 DEBUG_PIM_ZEBRA_STR
)
5777 PIM_DONT_DEBUG_ZEBRA
;
5788 PIM_DO_DEBUG_MSDP_EVENTS
;
5789 PIM_DO_DEBUG_MSDP_PACKETS
;
5793 DEFUN (no_debug_msdp
,
5800 PIM_DONT_DEBUG_MSDP_EVENTS
;
5801 PIM_DONT_DEBUG_MSDP_PACKETS
;
5805 ALIAS (no_debug_msdp
,
5811 DEFUN (debug_msdp_events
,
5812 debug_msdp_events_cmd
,
5813 "debug msdp events",
5816 DEBUG_MSDP_EVENTS_STR
)
5818 PIM_DO_DEBUG_MSDP_EVENTS
;
5822 DEFUN (no_debug_msdp_events
,
5823 no_debug_msdp_events_cmd
,
5824 "no debug msdp events",
5828 DEBUG_MSDP_EVENTS_STR
)
5830 PIM_DONT_DEBUG_MSDP_EVENTS
;
5834 ALIAS (no_debug_msdp_events
,
5835 undebug_msdp_events_cmd
,
5836 "undebug msdp events",
5839 DEBUG_MSDP_EVENTS_STR
)
5841 DEFUN (debug_msdp_packets
,
5842 debug_msdp_packets_cmd
,
5843 "debug msdp packets",
5846 DEBUG_MSDP_PACKETS_STR
)
5848 PIM_DO_DEBUG_MSDP_PACKETS
;
5852 DEFUN (no_debug_msdp_packets
,
5853 no_debug_msdp_packets_cmd
,
5854 "no debug msdp packets",
5858 DEBUG_MSDP_PACKETS_STR
)
5860 PIM_DONT_DEBUG_MSDP_PACKETS
;
5864 ALIAS (no_debug_msdp_packets
,
5865 undebug_msdp_packets_cmd
,
5866 "undebug msdp packets",
5869 DEBUG_MSDP_PACKETS_STR
)
5871 DEFUN (show_debugging_pim
,
5872 show_debugging_pim_cmd
,
5873 "show debugging pim",
5878 pim_debug_config_write(vty
);
5883 interface_pim_use_src_cmd_worker(struct vty
*vty
, const char *source
)
5886 struct in_addr source_addr
;
5887 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5889 result
= inet_pton(AF_INET
, source
, &source_addr
);
5891 vty_out(vty
, "%% Bad source address %s: errno=%d: %s%s",
5892 source
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
5896 result
= pim_update_source_set(ifp
, source_addr
);
5900 case PIM_IFACE_NOT_FOUND
:
5901 vty_out(vty
, "Pim not enabled on this interface%s", VTY_NEWLINE
);
5903 case PIM_UPDATE_SOURCE_DUP
:
5904 vty_out(vty
, "%% Source already set to %s%s", source
, VTY_NEWLINE
);
5907 vty_out(vty
, "%% Source set failed%s", VTY_NEWLINE
);
5910 return result
?CMD_WARNING
:CMD_SUCCESS
;
5913 DEFUN (interface_pim_use_source
,
5914 interface_pim_use_source_cmd
,
5915 "ip pim use-source A.B.C.D",
5917 "pim multicast routing\n"
5918 "Configure primary IP address\n"
5919 "source ip address\n")
5921 return interface_pim_use_src_cmd_worker (vty
, argv
[3]->arg
);
5924 DEFUN (interface_no_pim_use_source
,
5925 interface_no_pim_use_source_cmd
,
5926 "no ip pim use-source",
5929 "pim multicast routing\n"
5930 "Delete source IP address\n")
5932 return interface_pim_use_src_cmd_worker (vty
, "0.0.0.0");
5936 ip_msdp_peer_cmd_worker (struct vty
*vty
, const char *peer
, const char *local
)
5938 enum pim_msdp_err result
;
5939 struct in_addr peer_addr
;
5940 struct in_addr local_addr
;
5942 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
5944 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s%s",
5945 peer
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
5949 result
= inet_pton(AF_INET
, local
, &local_addr
);
5951 vty_out(vty
, "%% Bad source address %s: errno=%d: %s%s",
5952 local
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
5956 result
= pim_msdp_peer_add(peer_addr
, local_addr
, "default", NULL
/* mp_p */);
5958 case PIM_MSDP_ERR_NONE
:
5960 case PIM_MSDP_ERR_OOM
:
5961 vty_out(vty
, "%% Out of memory%s", VTY_NEWLINE
);
5963 case PIM_MSDP_ERR_PEER_EXISTS
:
5964 vty_out(vty
, "%% Peer exists%s", VTY_NEWLINE
);
5966 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
5967 vty_out(vty
, "%% Only one mesh-group allowed currently%s", VTY_NEWLINE
);
5970 vty_out(vty
, "%% peer add failed%s", VTY_NEWLINE
);
5973 return result
?CMD_WARNING
:CMD_SUCCESS
;
5976 DEFUN_HIDDEN (ip_msdp_peer
,
5978 "ip msdp peer A.B.C.D source A.B.C.D",
5981 "Configure MSDP peer\n"
5983 "Source address for TCP connection\n"
5984 "local ip address\n")
5986 return ip_msdp_peer_cmd_worker (vty
, argv
[3]->arg
, argv
[5]->arg
);
5990 ip_no_msdp_peer_cmd_worker (struct vty
*vty
, const char *peer
)
5992 enum pim_msdp_err result
;
5993 struct in_addr peer_addr
;
5995 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
5997 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s%s",
5998 peer
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
6002 result
= pim_msdp_peer_del(peer_addr
);
6004 case PIM_MSDP_ERR_NONE
:
6006 case PIM_MSDP_ERR_NO_PEER
:
6007 vty_out(vty
, "%% Peer does not exist%s", VTY_NEWLINE
);
6010 vty_out(vty
, "%% peer del failed%s", VTY_NEWLINE
);
6013 return result
?CMD_WARNING
:CMD_SUCCESS
;
6016 DEFUN_HIDDEN (no_ip_msdp_peer
,
6017 no_ip_msdp_peer_cmd
,
6018 "no ip msdp peer A.B.C.D",
6022 "Delete MSDP peer\n"
6023 "peer ip address\n")
6025 return ip_no_msdp_peer_cmd_worker (vty
, argv
[4]->arg
);
6029 ip_msdp_mesh_group_member_cmd_worker(struct vty
*vty
, const char *mg
, const char *mbr
)
6031 enum pim_msdp_err result
;
6032 struct in_addr mbr_ip
;
6034 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
6036 vty_out(vty
, "%% Bad member address %s: errno=%d: %s%s",
6037 mbr
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
6041 result
= pim_msdp_mg_mbr_add(mg
, mbr_ip
);
6043 case PIM_MSDP_ERR_NONE
:
6045 case PIM_MSDP_ERR_OOM
:
6046 vty_out(vty
, "%% Out of memory%s", VTY_NEWLINE
);
6048 case PIM_MSDP_ERR_MG_MBR_EXISTS
:
6049 vty_out(vty
, "%% mesh-group member exists%s", VTY_NEWLINE
);
6051 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
6052 vty_out(vty
, "%% Only one mesh-group allowed currently%s", VTY_NEWLINE
);
6055 vty_out(vty
, "%% member add failed%s", VTY_NEWLINE
);
6058 return result
?CMD_WARNING
:CMD_SUCCESS
;
6061 DEFUN (ip_msdp_mesh_group_member
,
6062 ip_msdp_mesh_group_member_cmd
,
6063 "ip msdp mesh-group WORD member A.B.C.D",
6066 "Configure MSDP mesh-group\n"
6068 "mesh group member\n"
6069 "peer ip address\n")
6071 return ip_msdp_mesh_group_member_cmd_worker(vty
, argv
[3]->arg
, argv
[5]->arg
);
6075 ip_no_msdp_mesh_group_member_cmd_worker(struct vty
*vty
, const char *mg
, const char *mbr
)
6077 enum pim_msdp_err result
;
6078 struct in_addr mbr_ip
;
6080 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
6082 vty_out(vty
, "%% Bad member address %s: errno=%d: %s%s",
6083 mbr
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
6087 result
= pim_msdp_mg_mbr_del(mg
, mbr_ip
);
6089 case PIM_MSDP_ERR_NONE
:
6091 case PIM_MSDP_ERR_NO_MG
:
6092 vty_out(vty
, "%% mesh-group does not exist%s", VTY_NEWLINE
);
6094 case PIM_MSDP_ERR_NO_MG_MBR
:
6095 vty_out(vty
, "%% mesh-group member does not exist%s", VTY_NEWLINE
);
6098 vty_out(vty
, "%% mesh-group member del failed%s", VTY_NEWLINE
);
6101 return result
?CMD_WARNING
:CMD_SUCCESS
;
6103 DEFUN (no_ip_msdp_mesh_group_member
,
6104 no_ip_msdp_mesh_group_member_cmd
,
6105 "no ip msdp mesh-group WORD member A.B.C.D",
6109 "Delete MSDP mesh-group member\n"
6111 "mesh group member\n"
6112 "peer ip address\n")
6114 return ip_no_msdp_mesh_group_member_cmd_worker(vty
, argv
[4]->arg
, argv
[6]->arg
);
6118 ip_msdp_mesh_group_source_cmd_worker(struct vty
*vty
, const char *mg
, const char *src
)
6120 enum pim_msdp_err result
;
6121 struct in_addr src_ip
;
6123 result
= inet_pton(AF_INET
, src
, &src_ip
);
6125 vty_out(vty
, "%% Bad source address %s: errno=%d: %s%s",
6126 src
, errno
, safe_strerror(errno
), VTY_NEWLINE
);
6130 result
= pim_msdp_mg_src_add(mg
, src_ip
);
6132 case PIM_MSDP_ERR_NONE
:
6134 case PIM_MSDP_ERR_OOM
:
6135 vty_out(vty
, "%% Out of memory%s", VTY_NEWLINE
);
6137 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
6138 vty_out(vty
, "%% Only one mesh-group allowed currently%s", VTY_NEWLINE
);
6141 vty_out(vty
, "%% source add failed%s", VTY_NEWLINE
);
6144 return result
?CMD_WARNING
:CMD_SUCCESS
;
6148 DEFUN (ip_msdp_mesh_group_source
,
6149 ip_msdp_mesh_group_source_cmd
,
6150 "ip msdp mesh-group WORD source A.B.C.D",
6153 "Configure MSDP mesh-group\n"
6155 "mesh group local address\n"
6156 "source ip address for the TCP connection\n")
6158 return ip_msdp_mesh_group_source_cmd_worker(vty
, argv
[3]->arg
, argv
[5]->arg
);
6162 ip_no_msdp_mesh_group_source_cmd_worker(struct vty
*vty
, const char *mg
)
6164 enum pim_msdp_err result
;
6166 result
= pim_msdp_mg_src_del(mg
);
6168 case PIM_MSDP_ERR_NONE
:
6170 case PIM_MSDP_ERR_NO_MG
:
6171 vty_out(vty
, "%% mesh-group does not exist%s", VTY_NEWLINE
);
6174 vty_out(vty
, "%% mesh-group source del failed%s", VTY_NEWLINE
);
6177 return result
?CMD_WARNING
:CMD_SUCCESS
;
6181 ip_no_msdp_mesh_group_cmd_worker(struct vty
*vty
, const char *mg
)
6183 enum pim_msdp_err result
;
6185 result
= pim_msdp_mg_del(mg
);
6187 case PIM_MSDP_ERR_NONE
:
6189 case PIM_MSDP_ERR_NO_MG
:
6190 vty_out(vty
, "%% mesh-group does not exist%s", VTY_NEWLINE
);
6193 vty_out(vty
, "%% mesh-group source del failed%s", VTY_NEWLINE
);
6196 return result
? CMD_WARNING
: CMD_SUCCESS
;
6199 DEFUN (no_ip_msdp_mesh_group_source
,
6200 no_ip_msdp_mesh_group_source_cmd
,
6201 "no ip msdp mesh-group WORD source [A.B.C.D]",
6205 "Delete MSDP mesh-group source\n"
6207 "mesh group source\n"
6208 "mesh group local address\n")
6211 return ip_no_msdp_mesh_group_cmd_worker(vty
, argv
[6]->arg
);
6213 return ip_no_msdp_mesh_group_source_cmd_worker(vty
, argv
[4]->arg
);
6217 print_empty_json_obj(struct vty
*vty
)
6220 json
= json_object_new_object();
6221 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
6222 json_object_free(json
);
6226 ip_msdp_show_mesh_group(struct vty
*vty
, u_char uj
)
6228 struct listnode
*mbrnode
;
6229 struct pim_msdp_mg_mbr
*mbr
;
6230 struct pim_msdp_mg
*mg
= msdp
->mg
;
6231 char mbr_str
[INET_ADDRSTRLEN
];
6232 char src_str
[INET_ADDRSTRLEN
];
6233 char state_str
[PIM_MSDP_STATE_STRLEN
];
6234 enum pim_msdp_peer_state state
;
6235 json_object
*json
= NULL
;
6236 json_object
*json_mg_row
= NULL
;
6237 json_object
*json_members
= NULL
;
6238 json_object
*json_row
= NULL
;
6242 print_empty_json_obj(vty
);
6246 pim_inet4_dump("<source?>", mg
->src_ip
, src_str
, sizeof(src_str
));
6248 json
= json_object_new_object();
6249 /* currently there is only one mesh group but we should still make
6250 * it a dict with mg-name as key */
6251 json_mg_row
= json_object_new_object();
6252 json_object_string_add(json_mg_row
, "name", mg
->mesh_group_name
);
6253 json_object_string_add(json_mg_row
, "source", src_str
);
6255 vty_out(vty
, "Mesh group : %s%s", mg
->mesh_group_name
, VTY_NEWLINE
);
6256 vty_out(vty
, " Source : %s%s", src_str
, VTY_NEWLINE
);
6257 vty_out(vty
, " Member State%s", VTY_NEWLINE
);
6260 for (ALL_LIST_ELEMENTS_RO(mg
->mbr_list
, mbrnode
, mbr
)) {
6261 pim_inet4_dump("<mbr?>", mbr
->mbr_ip
, mbr_str
, sizeof(mbr_str
));
6263 state
= mbr
->mp
->state
;
6265 state
= PIM_MSDP_DISABLED
;
6267 pim_msdp_state_dump(state
, state_str
, sizeof(state_str
));
6269 json_row
= json_object_new_object();
6270 json_object_string_add(json_row
, "member", mbr_str
);
6271 json_object_string_add(json_row
, "state", state_str
);
6272 if (!json_members
) {
6273 json_members
= json_object_new_object();
6274 json_object_object_add(json_mg_row
, "members", json_members
);
6276 json_object_object_add(json_members
, mbr_str
, json_row
);
6278 vty_out(vty
, " %-15s %11s%s",
6279 mbr_str
, state_str
, VTY_NEWLINE
);
6284 json_object_object_add(json
, mg
->mesh_group_name
, json_mg_row
);
6285 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
6286 json_object_free(json
);
6290 DEFUN (show_ip_msdp_mesh_group
,
6291 show_ip_msdp_mesh_group_cmd
,
6292 "show ip msdp mesh-group [json]",
6296 "MSDP mesh-group information\n"
6297 "JavaScript Object Notation\n")
6299 u_char uj
= use_json(argc
, argv
);
6300 ip_msdp_show_mesh_group(vty
, uj
);
6306 ip_msdp_show_peers(struct vty
*vty
, u_char uj
)
6308 struct listnode
*mpnode
;
6309 struct pim_msdp_peer
*mp
;
6310 char peer_str
[INET_ADDRSTRLEN
];
6311 char local_str
[INET_ADDRSTRLEN
];
6312 char state_str
[PIM_MSDP_STATE_STRLEN
];
6313 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
6315 json_object
*json
= NULL
;
6316 json_object
*json_row
= NULL
;
6320 json
= json_object_new_object();
6322 vty_out(vty
, "Peer Local State Uptime SaCnt%s", VTY_NEWLINE
);
6325 for (ALL_LIST_ELEMENTS_RO(msdp
->peer_list
, mpnode
, mp
)) {
6326 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
6327 now
= pim_time_monotonic_sec();
6328 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- mp
->uptime
);
6330 strcpy(timebuf
, "-");
6332 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
6333 pim_inet4_dump("<local?>", mp
->local
, local_str
, sizeof(local_str
));
6334 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
6336 json_row
= json_object_new_object();
6337 json_object_string_add(json_row
, "peer", peer_str
);
6338 json_object_string_add(json_row
, "local", local_str
);
6339 json_object_string_add(json_row
, "state", state_str
);
6340 json_object_string_add(json_row
, "upTime", timebuf
);
6341 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
6342 json_object_object_add(json
, peer_str
, json_row
);
6344 vty_out(vty
, "%-15s %15s %11s %8s %6d%s",
6345 peer_str
, local_str
, state_str
,
6346 timebuf
, mp
->sa_cnt
, VTY_NEWLINE
);
6351 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
6352 json_object_free(json
);
6357 ip_msdp_show_peers_detail(struct vty
*vty
, const char *peer
, u_char uj
)
6359 struct listnode
*mpnode
;
6360 struct pim_msdp_peer
*mp
;
6361 char peer_str
[INET_ADDRSTRLEN
];
6362 char local_str
[INET_ADDRSTRLEN
];
6363 char state_str
[PIM_MSDP_STATE_STRLEN
];
6364 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
6365 char katimer
[PIM_MSDP_TIMER_STRLEN
];
6366 char crtimer
[PIM_MSDP_TIMER_STRLEN
];
6367 char holdtimer
[PIM_MSDP_TIMER_STRLEN
];
6369 json_object
*json
= NULL
;
6370 json_object
*json_row
= NULL
;
6373 json
= json_object_new_object();
6376 for (ALL_LIST_ELEMENTS_RO(msdp
->peer_list
, mpnode
, mp
)) {
6377 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
6378 if (strcmp(peer
, "detail") &&
6379 strcmp(peer
, peer_str
))
6382 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
6383 now
= pim_time_monotonic_sec();
6384 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- mp
->uptime
);
6386 strcpy(timebuf
, "-");
6388 pim_inet4_dump("<local?>", mp
->local
, local_str
, sizeof(local_str
));
6389 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
6390 pim_time_timer_to_hhmmss(katimer
, sizeof(katimer
), mp
->ka_timer
);
6391 pim_time_timer_to_hhmmss(crtimer
, sizeof(crtimer
), mp
->cr_timer
);
6392 pim_time_timer_to_hhmmss(holdtimer
, sizeof(holdtimer
), mp
->hold_timer
);
6395 json_row
= json_object_new_object();
6396 json_object_string_add(json_row
, "peer", peer_str
);
6397 json_object_string_add(json_row
, "local", local_str
);
6398 json_object_string_add(json_row
, "meshGroupName", mp
->mesh_group_name
);
6399 json_object_string_add(json_row
, "state", state_str
);
6400 json_object_string_add(json_row
, "upTime", timebuf
);
6401 json_object_string_add(json_row
, "keepAliveTimer", katimer
);
6402 json_object_string_add(json_row
, "connRetryTimer", crtimer
);
6403 json_object_string_add(json_row
, "holdTimer", holdtimer
);
6404 json_object_string_add(json_row
, "lastReset", mp
->last_reset
);
6405 json_object_int_add(json_row
, "connAttempts", mp
->conn_attempts
);
6406 json_object_int_add(json_row
, "establishedChanges", mp
->est_flaps
);
6407 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
6408 json_object_int_add(json_row
, "kaSent", mp
->ka_tx_cnt
);
6409 json_object_int_add(json_row
, "kaRcvd", mp
->ka_rx_cnt
);
6410 json_object_int_add(json_row
, "saSent", mp
->sa_tx_cnt
);
6411 json_object_int_add(json_row
, "saRcvd", mp
->sa_rx_cnt
);
6412 json_object_object_add(json
, peer_str
, json_row
);
6414 vty_out(vty
, "Peer : %s%s", peer_str
, VTY_NEWLINE
);
6415 vty_out(vty
, " Local : %s%s", local_str
, VTY_NEWLINE
);
6416 vty_out(vty
, " Mesh Group : %s%s", mp
->mesh_group_name
, VTY_NEWLINE
);
6417 vty_out(vty
, " State : %s%s", state_str
, VTY_NEWLINE
);
6418 vty_out(vty
, " Uptime : %s%s", timebuf
, VTY_NEWLINE
);
6420 vty_out(vty
, " Keepalive Timer : %s%s", katimer
, VTY_NEWLINE
);
6421 vty_out(vty
, " Conn Retry Timer : %s%s", crtimer
, VTY_NEWLINE
);
6422 vty_out(vty
, " Hold Timer : %s%s", holdtimer
, VTY_NEWLINE
);
6423 vty_out(vty
, " Last Reset : %s%s", mp
->last_reset
, VTY_NEWLINE
);
6424 vty_out(vty
, " Conn Attempts : %d%s", mp
->conn_attempts
, VTY_NEWLINE
);
6425 vty_out(vty
, " Established Changes : %d%s", mp
->est_flaps
, VTY_NEWLINE
);
6426 vty_out(vty
, " SA Count : %d%s", mp
->sa_cnt
, VTY_NEWLINE
);
6427 vty_out(vty
, " Statistics :%s", VTY_NEWLINE
);
6428 vty_out(vty
, " Sent Rcvd%s", VTY_NEWLINE
);
6429 vty_out(vty
, " Keepalives : %10d %10d%s",
6430 mp
->ka_tx_cnt
, mp
->ka_rx_cnt
, VTY_NEWLINE
);
6431 vty_out(vty
, " SAs : %10d %10d%s",
6432 mp
->sa_tx_cnt
, mp
->sa_rx_cnt
, VTY_NEWLINE
);
6433 vty_out(vty
, "%s", VTY_NEWLINE
);
6438 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
6439 json_object_free(json
);
6443 DEFUN (show_ip_msdp_peer_detail
,
6444 show_ip_msdp_peer_detail_cmd
,
6445 "show ip msdp peer [detail|A.B.C.D] [json]",
6449 "MSDP peer information\n"
6452 "JavaScript Object Notation\n")
6454 u_char uj
= use_json(argc
, argv
);
6459 ip_msdp_show_peers_detail(vty
, argv
[4]->arg
, uj
);
6461 ip_msdp_show_peers(vty
, uj
);
6467 ip_msdp_show_sa(struct vty
*vty
, u_char uj
)
6469 struct listnode
*sanode
;
6470 struct pim_msdp_sa
*sa
;
6471 char src_str
[INET_ADDRSTRLEN
];
6472 char grp_str
[INET_ADDRSTRLEN
];
6473 char rp_str
[INET_ADDRSTRLEN
];
6474 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
6478 json_object
*json
= NULL
;
6479 json_object
*json_group
= NULL
;
6480 json_object
*json_row
= NULL
;
6483 json
= json_object_new_object();
6485 vty_out(vty
, "Source Group RP Local SPT Uptime%s", VTY_NEWLINE
);
6488 for (ALL_LIST_ELEMENTS_RO(msdp
->sa_list
, sanode
, sa
)) {
6489 now
= pim_time_monotonic_sec();
6490 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
6491 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
6492 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
6493 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
6494 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
6496 strcpy(spt_str
, "yes");
6498 strcpy(spt_str
, "no");
6501 strcpy(rp_str
, "-");
6502 strcpy(spt_str
, "-");
6504 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
6505 strcpy(local_str
, "yes");
6507 strcpy(local_str
, "no");
6510 json_object_object_get_ex(json
, grp_str
, &json_group
);
6513 json_group
= json_object_new_object();
6514 json_object_object_add(json
, grp_str
, json_group
);
6517 json_row
= json_object_new_object();
6518 json_object_string_add(json_row
, "source", src_str
);
6519 json_object_string_add(json_row
, "group", grp_str
);
6520 json_object_string_add(json_row
, "rp", rp_str
);
6521 json_object_string_add(json_row
, "local", local_str
);
6522 json_object_string_add(json_row
, "sptSetup", spt_str
);
6523 json_object_string_add(json_row
, "upTime", timebuf
);
6524 json_object_object_add(json_group
, src_str
, json_row
);
6526 vty_out(vty
, "%-15s %15s %15s %5c %3c %8s%s",
6527 src_str
, grp_str
, rp_str
, local_str
[0], spt_str
[0], timebuf
, VTY_NEWLINE
);
6533 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
6534 json_object_free(json
);
6539 ip_msdp_show_sa_entry_detail(struct pim_msdp_sa
*sa
, const char *src_str
,
6540 const char *grp_str
, struct vty
*vty
,
6541 u_char uj
, json_object
*json
)
6543 char rp_str
[INET_ADDRSTRLEN
];
6544 char peer_str
[INET_ADDRSTRLEN
];
6545 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
6548 char statetimer
[PIM_MSDP_TIMER_STRLEN
];
6550 json_object
*json_group
= NULL
;
6551 json_object
*json_row
= NULL
;
6553 now
= pim_time_monotonic_sec();
6554 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
6555 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
6556 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
6557 pim_inet4_dump("<peer?>", sa
->peer
, peer_str
, sizeof(peer_str
));
6559 strcpy(spt_str
, "yes");
6561 strcpy(spt_str
, "no");
6564 strcpy(rp_str
, "-");
6565 strcpy(peer_str
, "-");
6566 strcpy(spt_str
, "-");
6568 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
6569 strcpy(local_str
, "yes");
6571 strcpy(local_str
, "no");
6573 pim_time_timer_to_hhmmss(statetimer
, sizeof(statetimer
), sa
->sa_state_timer
);
6575 json_object_object_get_ex(json
, grp_str
, &json_group
);
6578 json_group
= json_object_new_object();
6579 json_object_object_add(json
, grp_str
, json_group
);
6582 json_row
= json_object_new_object();
6583 json_object_string_add(json_row
, "source", src_str
);
6584 json_object_string_add(json_row
, "group", grp_str
);
6585 json_object_string_add(json_row
, "rp", rp_str
);
6586 json_object_string_add(json_row
, "local", local_str
);
6587 json_object_string_add(json_row
, "sptSetup", spt_str
);
6588 json_object_string_add(json_row
, "upTime", timebuf
);
6589 json_object_string_add(json_row
, "stateTimer", statetimer
);
6590 json_object_object_add(json_group
, src_str
, json_row
);
6592 vty_out(vty
, "SA : %s%s", sa
->sg_str
, VTY_NEWLINE
);
6593 vty_out(vty
, " RP : %s%s", rp_str
, VTY_NEWLINE
);
6594 vty_out(vty
, " Peer : %s%s", peer_str
, VTY_NEWLINE
);
6595 vty_out(vty
, " Local : %s%s", local_str
, VTY_NEWLINE
);
6596 vty_out(vty
, " SPT Setup : %s%s", spt_str
, VTY_NEWLINE
);
6597 vty_out(vty
, " Uptime : %s%s", timebuf
, VTY_NEWLINE
);
6598 vty_out(vty
, " State Timer : %s%s", statetimer
, VTY_NEWLINE
);
6599 vty_out(vty
, "%s", VTY_NEWLINE
);
6604 ip_msdp_show_sa_detail(struct vty
*vty
, u_char uj
)
6606 struct listnode
*sanode
;
6607 struct pim_msdp_sa
*sa
;
6608 char src_str
[INET_ADDRSTRLEN
];
6609 char grp_str
[INET_ADDRSTRLEN
];
6610 json_object
*json
= NULL
;
6613 json
= json_object_new_object();
6616 for (ALL_LIST_ELEMENTS_RO(msdp
->sa_list
, sanode
, sa
)) {
6617 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
6618 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
6619 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
, uj
, json
);
6623 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
6624 json_object_free(json
);
6628 DEFUN (show_ip_msdp_sa_detail
,
6629 show_ip_msdp_sa_detail_cmd
,
6630 "show ip msdp sa detail [json]",
6634 "MSDP active-source information\n"
6636 "JavaScript Object Notation\n")
6638 u_char uj
= use_json(argc
, argv
);
6639 ip_msdp_show_sa_detail(vty
, uj
);
6645 ip_msdp_show_sa_addr(struct vty
*vty
, const char *addr
, u_char uj
)
6647 struct listnode
*sanode
;
6648 struct pim_msdp_sa
*sa
;
6649 char src_str
[INET_ADDRSTRLEN
];
6650 char grp_str
[INET_ADDRSTRLEN
];
6651 json_object
*json
= NULL
;
6654 json
= json_object_new_object();
6657 for (ALL_LIST_ELEMENTS_RO(msdp
->sa_list
, sanode
, sa
)) {
6658 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
6659 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
6660 if (!strcmp(addr
, src_str
) || !strcmp(addr
, grp_str
)) {
6661 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
, uj
, json
);
6666 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
6667 json_object_free(json
);
6672 ip_msdp_show_sa_sg(struct vty
*vty
, const char *src
, const char *grp
, u_char uj
)
6674 struct listnode
*sanode
;
6675 struct pim_msdp_sa
*sa
;
6676 char src_str
[INET_ADDRSTRLEN
];
6677 char grp_str
[INET_ADDRSTRLEN
];
6678 json_object
*json
= NULL
;
6681 json
= json_object_new_object();
6684 for (ALL_LIST_ELEMENTS_RO(msdp
->sa_list
, sanode
, sa
)) {
6685 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
6686 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
6687 if (!strcmp(src
, src_str
) && !strcmp(grp
, grp_str
)) {
6688 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
, uj
, json
);
6693 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
6694 json_object_free(json
);
6698 DEFUN (show_ip_msdp_sa_sg
,
6699 show_ip_msdp_sa_sg_cmd
,
6700 "show ip msdp sa [A.B.C.D [A.B.C.D]] [json]",
6704 "MSDP active-source information\n"
6705 "source or group ip\n"
6707 "JavaScript Object Notation\n")
6709 u_char uj
= use_json(argc
, argv
);
6712 char *src_ip
= argv_find (argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
++]->arg
: NULL
;
6713 char *grp_ip
= idx
< argc
&& argv_find (argv
, argc
, "A.B.C.D", &idx
) ?
6714 argv
[idx
]->arg
: NULL
;
6716 if (src_ip
&& grp_ip
)
6717 ip_msdp_show_sa_sg(vty
, src_ip
, grp_ip
, uj
);
6719 ip_msdp_show_sa_addr(vty
, src_ip
, uj
);
6721 ip_msdp_show_sa(vty
, uj
);
6728 install_node (&pim_global_node
, pim_global_config_write
); /* PIM_NODE */
6729 install_node (&interface_node
, pim_interface_config_write
); /* INTERFACE_NODE */
6732 install_node (&debug_node
, pim_debug_config_write
);
6734 install_element (CONFIG_NODE
, &ip_multicast_routing_cmd
);
6735 install_element (CONFIG_NODE
, &no_ip_multicast_routing_cmd
);
6736 install_element (CONFIG_NODE
, &ip_pim_rp_cmd
);
6737 install_element (CONFIG_NODE
, &no_ip_pim_rp_cmd
);
6738 install_element (CONFIG_NODE
, &ip_pim_rp_prefix_list_cmd
);
6739 install_element (CONFIG_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
6740 install_element (CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_cmd
);
6741 install_element (CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_name_cmd
);
6742 install_element (CONFIG_NODE
, &ip_pim_ssm_prefix_list_cmd
);
6743 install_element (CONFIG_NODE
, &ip_pim_register_suppress_cmd
);
6744 install_element (CONFIG_NODE
, &no_ip_pim_register_suppress_cmd
);
6745 install_element (CONFIG_NODE
, &ip_pim_spt_switchover_infinity_cmd
);
6746 install_element (CONFIG_NODE
, &ip_pim_spt_switchover_infinity_plist_cmd
);
6747 install_element (CONFIG_NODE
, &no_ip_pim_spt_switchover_infinity_cmd
);
6748 install_element (CONFIG_NODE
, &no_ip_pim_spt_switchover_infinity_plist_cmd
);
6749 install_element (CONFIG_NODE
, &ip_pim_joinprune_time_cmd
);
6750 install_element (CONFIG_NODE
, &no_ip_pim_joinprune_time_cmd
);
6751 install_element (CONFIG_NODE
, &ip_pim_keep_alive_cmd
);
6752 install_element (CONFIG_NODE
, &no_ip_pim_keep_alive_cmd
);
6753 install_element (CONFIG_NODE
, &ip_pim_packets_cmd
);
6754 install_element (CONFIG_NODE
, &no_ip_pim_packets_cmd
);
6755 install_element (CONFIG_NODE
, &ip_pim_v6_secondary_cmd
);
6756 install_element (CONFIG_NODE
, &no_ip_pim_v6_secondary_cmd
);
6757 install_element (CONFIG_NODE
, &ip_ssmpingd_cmd
);
6758 install_element (CONFIG_NODE
, &no_ip_ssmpingd_cmd
);
6759 install_element (CONFIG_NODE
, &ip_msdp_peer_cmd
);
6760 install_element (CONFIG_NODE
, &no_ip_msdp_peer_cmd
);
6761 install_element (CONFIG_NODE
, &ip_pim_ecmp_cmd
);
6762 install_element (CONFIG_NODE
, &no_ip_pim_ecmp_cmd
);
6763 install_element (CONFIG_NODE
, &ip_pim_ecmp_rebalance_cmd
);
6764 install_element (CONFIG_NODE
, &no_ip_pim_ecmp_rebalance_cmd
);
6766 install_element (INTERFACE_NODE
, &interface_ip_igmp_cmd
);
6767 install_element (INTERFACE_NODE
, &interface_no_ip_igmp_cmd
);
6768 install_element (INTERFACE_NODE
, &interface_ip_igmp_join_cmd
);
6769 install_element (INTERFACE_NODE
, &interface_no_ip_igmp_join_cmd
);
6770 install_element (INTERFACE_NODE
, &interface_ip_igmp_version_cmd
);
6771 install_element (INTERFACE_NODE
, &interface_no_ip_igmp_version_cmd
);
6772 install_element (INTERFACE_NODE
, &interface_ip_igmp_query_interval_cmd
);
6773 install_element (INTERFACE_NODE
, &interface_no_ip_igmp_query_interval_cmd
);
6774 install_element (INTERFACE_NODE
, &interface_ip_igmp_query_max_response_time_cmd
);
6775 install_element (INTERFACE_NODE
, &interface_no_ip_igmp_query_max_response_time_cmd
);
6776 install_element (INTERFACE_NODE
, &interface_ip_igmp_query_max_response_time_dsec_cmd
);
6777 install_element (INTERFACE_NODE
, &interface_no_ip_igmp_query_max_response_time_dsec_cmd
);
6778 install_element (INTERFACE_NODE
, &interface_ip_pim_ssm_cmd
);
6779 install_element (INTERFACE_NODE
, &interface_no_ip_pim_ssm_cmd
);
6780 install_element (INTERFACE_NODE
, &interface_ip_pim_sm_cmd
);
6781 install_element (INTERFACE_NODE
, &interface_no_ip_pim_sm_cmd
);
6782 install_element (INTERFACE_NODE
, &interface_ip_pim_drprio_cmd
);
6783 install_element (INTERFACE_NODE
, &interface_no_ip_pim_drprio_cmd
);
6784 install_element (INTERFACE_NODE
, &interface_ip_pim_hello_cmd
);
6785 install_element (INTERFACE_NODE
, &interface_no_ip_pim_hello_cmd
);
6787 // Static mroutes NEB
6788 install_element (INTERFACE_NODE
, &interface_ip_mroute_cmd
);
6789 install_element (INTERFACE_NODE
, &interface_ip_mroute_source_cmd
);
6790 install_element (INTERFACE_NODE
, &interface_no_ip_mroute_cmd
);
6791 install_element (INTERFACE_NODE
, &interface_no_ip_mroute_source_cmd
);
6793 install_element (VIEW_NODE
, &show_ip_igmp_interface_cmd
);
6794 install_element (VIEW_NODE
, &show_ip_igmp_join_cmd
);
6795 install_element (VIEW_NODE
, &show_ip_igmp_groups_cmd
);
6796 install_element (VIEW_NODE
, &show_ip_igmp_groups_retransmissions_cmd
);
6797 install_element (VIEW_NODE
, &show_ip_igmp_sources_cmd
);
6798 install_element (VIEW_NODE
, &show_ip_igmp_sources_retransmissions_cmd
);
6799 install_element (VIEW_NODE
, &show_ip_pim_assert_cmd
);
6800 install_element (VIEW_NODE
, &show_ip_pim_assert_internal_cmd
);
6801 install_element (VIEW_NODE
, &show_ip_pim_assert_metric_cmd
);
6802 install_element (VIEW_NODE
, &show_ip_pim_assert_winner_metric_cmd
);
6803 install_element (VIEW_NODE
, &show_ip_pim_interface_traffic_cmd
);
6804 install_element (VIEW_NODE
, &show_ip_pim_interface_cmd
);
6805 install_element (VIEW_NODE
, &show_ip_pim_join_cmd
);
6806 install_element (VIEW_NODE
, &show_ip_pim_local_membership_cmd
);
6807 install_element (VIEW_NODE
, &show_ip_pim_neighbor_cmd
);
6808 install_element (VIEW_NODE
, &show_ip_pim_rpf_cmd
);
6809 install_element (VIEW_NODE
, &show_ip_pim_secondary_cmd
);
6810 install_element (VIEW_NODE
, &show_ip_pim_state_cmd
);
6811 install_element (VIEW_NODE
, &show_ip_pim_upstream_cmd
);
6812 install_element (VIEW_NODE
, &show_ip_pim_upstream_join_desired_cmd
);
6813 install_element (VIEW_NODE
, &show_ip_pim_upstream_rpf_cmd
);
6814 install_element (VIEW_NODE
, &show_ip_pim_rp_cmd
);
6815 install_element (VIEW_NODE
, &show_ip_multicast_cmd
);
6816 install_element (VIEW_NODE
, &show_ip_mroute_cmd
);
6817 install_element (VIEW_NODE
, &show_ip_mroute_count_cmd
);
6818 install_element (VIEW_NODE
, &show_ip_rib_cmd
);
6819 install_element (VIEW_NODE
, &show_ip_ssmpingd_cmd
);
6820 install_element (VIEW_NODE
, &show_debugging_pim_cmd
);
6821 install_element (VIEW_NODE
, &show_ip_pim_nexthop_cmd
);
6822 install_element (VIEW_NODE
, &show_ip_pim_nexthop_lookup_cmd
);
6824 install_element (ENABLE_NODE
, &clear_ip_interfaces_cmd
);
6825 install_element (ENABLE_NODE
, &clear_ip_igmp_interfaces_cmd
);
6826 install_element (ENABLE_NODE
, &clear_ip_mroute_cmd
);
6827 install_element (ENABLE_NODE
, &clear_ip_pim_interfaces_cmd
);
6828 install_element (ENABLE_NODE
, &clear_ip_pim_interface_traffic_cmd
);
6829 install_element (ENABLE_NODE
, &clear_ip_pim_oil_cmd
);
6831 install_element (ENABLE_NODE
, &debug_igmp_cmd
);
6832 install_element (ENABLE_NODE
, &no_debug_igmp_cmd
);
6833 install_element (ENABLE_NODE
, &debug_igmp_events_cmd
);
6834 install_element (ENABLE_NODE
, &no_debug_igmp_events_cmd
);
6835 install_element (ENABLE_NODE
, &debug_igmp_packets_cmd
);
6836 install_element (ENABLE_NODE
, &no_debug_igmp_packets_cmd
);
6837 install_element (ENABLE_NODE
, &debug_igmp_trace_cmd
);
6838 install_element (ENABLE_NODE
, &no_debug_igmp_trace_cmd
);
6839 install_element (ENABLE_NODE
, &debug_mroute_cmd
);
6840 install_element (ENABLE_NODE
, &debug_mroute_detail_cmd
);
6841 install_element (ENABLE_NODE
, &no_debug_mroute_cmd
);
6842 install_element (ENABLE_NODE
, &no_debug_mroute_detail_cmd
);
6843 install_element (ENABLE_NODE
, &debug_static_cmd
);
6844 install_element (ENABLE_NODE
, &no_debug_static_cmd
);
6845 install_element (ENABLE_NODE
, &debug_pim_cmd
);
6846 install_element (ENABLE_NODE
, &no_debug_pim_cmd
);
6847 install_element (ENABLE_NODE
, &debug_pim_events_cmd
);
6848 install_element (ENABLE_NODE
, &no_debug_pim_events_cmd
);
6849 install_element (ENABLE_NODE
, &debug_pim_packets_cmd
);
6850 install_element (ENABLE_NODE
, &no_debug_pim_packets_cmd
);
6851 install_element (ENABLE_NODE
, &debug_pim_packetdump_send_cmd
);
6852 install_element (ENABLE_NODE
, &no_debug_pim_packetdump_send_cmd
);
6853 install_element (ENABLE_NODE
, &debug_pim_packetdump_recv_cmd
);
6854 install_element (ENABLE_NODE
, &no_debug_pim_packetdump_recv_cmd
);
6855 install_element (ENABLE_NODE
, &debug_pim_trace_cmd
);
6856 install_element (ENABLE_NODE
, &no_debug_pim_trace_cmd
);
6857 install_element (ENABLE_NODE
, &debug_ssmpingd_cmd
);
6858 install_element (ENABLE_NODE
, &no_debug_ssmpingd_cmd
);
6859 install_element (ENABLE_NODE
, &debug_pim_zebra_cmd
);
6860 install_element (ENABLE_NODE
, &no_debug_pim_zebra_cmd
);
6861 install_element (ENABLE_NODE
, &debug_msdp_cmd
);
6862 install_element (ENABLE_NODE
, &no_debug_msdp_cmd
);
6863 install_element (ENABLE_NODE
, &undebug_msdp_cmd
);
6864 install_element (ENABLE_NODE
, &debug_msdp_events_cmd
);
6865 install_element (ENABLE_NODE
, &no_debug_msdp_events_cmd
);
6866 install_element (ENABLE_NODE
, &undebug_msdp_events_cmd
);
6867 install_element (ENABLE_NODE
, &debug_msdp_packets_cmd
);
6868 install_element (ENABLE_NODE
, &no_debug_msdp_packets_cmd
);
6869 install_element (ENABLE_NODE
, &undebug_msdp_packets_cmd
);
6871 install_element (CONFIG_NODE
, &debug_igmp_cmd
);
6872 install_element (CONFIG_NODE
, &no_debug_igmp_cmd
);
6873 install_element (CONFIG_NODE
, &debug_igmp_events_cmd
);
6874 install_element (CONFIG_NODE
, &no_debug_igmp_events_cmd
);
6875 install_element (CONFIG_NODE
, &debug_igmp_packets_cmd
);
6876 install_element (CONFIG_NODE
, &no_debug_igmp_packets_cmd
);
6877 install_element (CONFIG_NODE
, &debug_igmp_trace_cmd
);
6878 install_element (CONFIG_NODE
, &no_debug_igmp_trace_cmd
);
6879 install_element (CONFIG_NODE
, &debug_mroute_cmd
);
6880 install_element (CONFIG_NODE
, &debug_mroute_detail_cmd
);
6881 install_element (CONFIG_NODE
, &no_debug_mroute_cmd
);
6882 install_element (CONFIG_NODE
, &no_debug_mroute_detail_cmd
);
6883 install_element (CONFIG_NODE
, &debug_static_cmd
);
6884 install_element (CONFIG_NODE
, &no_debug_static_cmd
);
6885 install_element (CONFIG_NODE
, &debug_pim_cmd
);
6886 install_element (CONFIG_NODE
, &no_debug_pim_cmd
);
6887 install_element (CONFIG_NODE
, &debug_pim_events_cmd
);
6888 install_element (CONFIG_NODE
, &no_debug_pim_events_cmd
);
6889 install_element (CONFIG_NODE
, &debug_pim_packets_cmd
);
6890 install_element (CONFIG_NODE
, &no_debug_pim_packets_cmd
);
6891 install_element (CONFIG_NODE
, &debug_pim_trace_cmd
);
6892 install_element (CONFIG_NODE
, &no_debug_pim_trace_cmd
);
6893 install_element (CONFIG_NODE
, &debug_ssmpingd_cmd
);
6894 install_element (CONFIG_NODE
, &no_debug_ssmpingd_cmd
);
6895 install_element (CONFIG_NODE
, &debug_pim_zebra_cmd
);
6896 install_element (CONFIG_NODE
, &no_debug_pim_zebra_cmd
);
6897 install_element (CONFIG_NODE
, &debug_msdp_cmd
);
6898 install_element (CONFIG_NODE
, &no_debug_msdp_cmd
);
6899 install_element (CONFIG_NODE
, &undebug_msdp_cmd
);
6900 install_element (CONFIG_NODE
, &debug_msdp_events_cmd
);
6901 install_element (CONFIG_NODE
, &no_debug_msdp_events_cmd
);
6902 install_element (CONFIG_NODE
, &undebug_msdp_events_cmd
);
6903 install_element (CONFIG_NODE
, &debug_msdp_packets_cmd
);
6904 install_element (CONFIG_NODE
, &no_debug_msdp_packets_cmd
);
6905 install_element (CONFIG_NODE
, &undebug_msdp_packets_cmd
);
6906 install_element (CONFIG_NODE
, &ip_msdp_mesh_group_member_cmd
);
6907 install_element (CONFIG_NODE
, &no_ip_msdp_mesh_group_member_cmd
);
6908 install_element (CONFIG_NODE
, &ip_msdp_mesh_group_source_cmd
);
6909 install_element (CONFIG_NODE
, &no_ip_msdp_mesh_group_source_cmd
);
6910 install_element (VIEW_NODE
, &show_ip_msdp_peer_detail_cmd
);
6911 install_element (VIEW_NODE
, &show_ip_msdp_sa_detail_cmd
);
6912 install_element (VIEW_NODE
, &show_ip_msdp_sa_sg_cmd
);
6913 install_element (VIEW_NODE
, &show_ip_msdp_mesh_group_cmd
);
6914 install_element (VIEW_NODE
, &show_ip_pim_ssm_range_cmd
);
6915 install_element (VIEW_NODE
, &show_ip_pim_group_type_cmd
);
6916 install_element (INTERFACE_NODE
, &interface_pim_use_source_cmd
);
6917 install_element (INTERFACE_NODE
, &interface_no_pim_use_source_cmd
);