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"
63 static struct cmd_node pim_global_node
= {
64 PIM_NODE
, "", 1 /* vtysh ? yes */
67 static struct cmd_node interface_node
= {
68 INTERFACE_NODE
, "%s(config-if)# ", 1 /* vtysh ? yes */
71 static struct cmd_node debug_node
= {DEBUG_NODE
, "", 1};
73 static void pim_if_membership_clear(struct interface
*ifp
)
75 struct pim_interface
*pim_ifp
;
80 if (PIM_IF_TEST_PIM(pim_ifp
->options
)
81 && PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
85 pim_ifchannel_membership_clear(ifp
);
89 When PIM is disabled on interface, IGMPv3 local membership
90 information is not injected into PIM interface state.
92 The function pim_if_membership_refresh() fetches all IGMPv3 local
93 membership information into PIM. It is intented to be called
94 whenever PIM is enabled on the interface in order to collect missed
95 local membership information.
97 static void pim_if_membership_refresh(struct interface
*ifp
)
99 struct pim_interface
*pim_ifp
;
100 struct listnode
*sock_node
;
101 struct igmp_sock
*igmp
;
106 if (!PIM_IF_TEST_PIM(pim_ifp
->options
))
108 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
))
112 First clear off membership from all PIM (S,G) entries on the
116 pim_ifchannel_membership_clear(ifp
);
119 Then restore PIM (S,G) membership from all IGMPv3 (S,G) entries on
123 /* scan igmp sockets */
124 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
125 struct listnode
*grpnode
;
126 struct igmp_group
*grp
;
128 /* scan igmp groups */
129 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grpnode
,
131 struct listnode
*srcnode
;
132 struct igmp_source
*src
;
134 /* scan group sources */
135 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
,
138 if (IGMP_SOURCE_TEST_FORWARDING(
139 src
->source_flags
)) {
143 sizeof(struct prefix_sg
));
144 sg
.src
= src
->source_addr
;
145 sg
.grp
= grp
->group_addr
;
146 pim_ifchannel_local_membership_add(ifp
,
150 } /* scan group sources */
151 } /* scan igmp groups */
152 } /* scan igmp sockets */
155 Finally delete every PIM (S,G) entry lacking all state info
158 pim_ifchannel_delete_on_noinfo(ifp
);
161 static void pim_show_assert(struct pim_instance
*pim
, struct vty
*vty
)
163 struct pim_interface
*pim_ifp
;
164 struct pim_ifchannel
*ch
;
165 struct listnode
*ch_node
;
166 struct in_addr ifaddr
;
169 now
= pim_time_monotonic_sec();
172 "Interface Address Source Group State Winner Uptime Timer\n");
174 for (ALL_LIST_ELEMENTS_RO(pim
->ifchannel_list
, ch_node
, ch
)) {
175 char ch_src_str
[INET_ADDRSTRLEN
];
176 char ch_grp_str
[INET_ADDRSTRLEN
];
177 char winner_str
[INET_ADDRSTRLEN
];
181 pim_ifp
= ch
->interface
->info
;
186 ifaddr
= pim_ifp
->primary_address
;
188 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
,
190 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
,
192 pim_inet4_dump("<assrt_win?>", ch
->ifassert_winner
, winner_str
,
195 pim_time_uptime(uptime
, sizeof(uptime
),
196 now
- ch
->ifassert_creation
);
197 pim_time_timer_to_mmss(timer
, sizeof(timer
),
198 ch
->t_ifassert_timer
);
200 vty_out(vty
, "%-9s %-15s %-15s %-15s %-6s %-15s %-8s %-5s\n",
201 ch
->interface
->name
, inet_ntoa(ifaddr
), ch_src_str
,
203 pim_ifchannel_ifassert_name(ch
->ifassert_state
),
204 winner_str
, uptime
, timer
);
205 } /* scan interface channels */
208 static void pim_show_assert_internal(struct pim_instance
*pim
, struct vty
*vty
)
210 struct pim_interface
*pim_ifp
;
211 struct listnode
*ch_node
;
212 struct pim_ifchannel
*ch
;
213 struct in_addr ifaddr
;
217 "ECA: Evaluate CouldAssert\n"
218 "ATD: AssertTrackingDesired\n"
219 "eATD: Evaluate AssertTrackingDesired\n\n");
222 "Interface Address Source Group CA eCA ATD eATD\n");
224 for (ALL_LIST_ELEMENTS_RO(pim
->ifchannel_list
, ch_node
, ch
)) {
225 pim_ifp
= ch
->interface
->info
;
230 ifaddr
= pim_ifp
->primary_address
;
232 char ch_src_str
[INET_ADDRSTRLEN
];
233 char ch_grp_str
[INET_ADDRSTRLEN
];
235 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
,
237 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
,
239 vty_out(vty
, "%-9s %-15s %-15s %-15s %-3s %-3s %-3s %-4s\n",
240 ch
->interface
->name
, inet_ntoa(ifaddr
), ch_src_str
,
242 PIM_IF_FLAG_TEST_COULD_ASSERT(ch
->flags
) ? "yes" : "no",
243 pim_macro_ch_could_assert_eval(ch
) ? "yes" : "no",
244 PIM_IF_FLAG_TEST_ASSERT_TRACKING_DESIRED(ch
->flags
)
247 pim_macro_assert_tracking_desired_eval(ch
) ? "yes"
249 } /* scan interface channels */
252 static void pim_show_assert_metric(struct pim_instance
*pim
, struct vty
*vty
)
254 struct pim_interface
*pim_ifp
;
255 struct listnode
*ch_node
;
256 struct pim_ifchannel
*ch
;
257 struct in_addr ifaddr
;
260 "Interface Address Source Group RPT Pref Metric Address \n");
262 for (ALL_LIST_ELEMENTS_RO(pim
->ifchannel_list
, ch_node
, ch
)) {
263 pim_ifp
= ch
->interface
->info
;
268 ifaddr
= pim_ifp
->primary_address
;
270 char ch_src_str
[INET_ADDRSTRLEN
];
271 char ch_grp_str
[INET_ADDRSTRLEN
];
272 char addr_str
[INET_ADDRSTRLEN
];
273 struct pim_assert_metric am
;
275 am
= pim_macro_spt_assert_metric(&ch
->upstream
->rpf
,
276 pim_ifp
->primary_address
);
278 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
,
280 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
,
282 pim_inet4_dump("<addr?>", am
.ip_address
, addr_str
,
285 vty_out(vty
, "%-9s %-15s %-15s %-15s %-3s %4u %6u %-15s\n",
286 ch
->interface
->name
, inet_ntoa(ifaddr
), ch_src_str
,
287 ch_grp_str
, am
.rpt_bit_flag
? "yes" : "no",
288 am
.metric_preference
, am
.route_metric
, addr_str
);
289 } /* scan interface channels */
292 static void pim_show_assert_winner_metric(struct pim_instance
*pim
,
295 struct pim_interface
*pim_ifp
;
296 struct listnode
*ch_node
;
297 struct pim_ifchannel
*ch
;
298 struct in_addr ifaddr
;
301 "Interface Address Source Group RPT Pref Metric Address \n");
303 for (ALL_LIST_ELEMENTS_RO(pim
->ifchannel_list
, ch_node
, ch
)) {
304 pim_ifp
= ch
->interface
->info
;
309 ifaddr
= pim_ifp
->primary_address
;
311 char ch_src_str
[INET_ADDRSTRLEN
];
312 char ch_grp_str
[INET_ADDRSTRLEN
];
313 char addr_str
[INET_ADDRSTRLEN
];
314 struct pim_assert_metric
*am
;
318 am
= &ch
->ifassert_winner_metric
;
320 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
,
322 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
,
324 pim_inet4_dump("<addr?>", am
->ip_address
, addr_str
,
327 if (am
->metric_preference
== PIM_ASSERT_METRIC_PREFERENCE_MAX
)
328 snprintf(pref_str
, sizeof(pref_str
), "INFI");
330 snprintf(pref_str
, sizeof(pref_str
), "%4u",
331 am
->metric_preference
);
333 if (am
->route_metric
== PIM_ASSERT_ROUTE_METRIC_MAX
)
334 snprintf(metr_str
, sizeof(metr_str
), "INFI");
336 snprintf(metr_str
, sizeof(metr_str
), "%6u",
339 vty_out(vty
, "%-9s %-15s %-15s %-15s %-3s %-4s %-6s %-15s\n",
340 ch
->interface
->name
, inet_ntoa(ifaddr
), ch_src_str
,
341 ch_grp_str
, am
->rpt_bit_flag
? "yes" : "no", pref_str
,
343 } /* scan interface channels */
346 static void json_object_pim_ifp_add(struct json_object
*json
,
347 struct interface
*ifp
)
349 struct pim_interface
*pim_ifp
;
352 json_object_string_add(json
, "name", ifp
->name
);
353 json_object_string_add(json
, "state", if_is_up(ifp
) ? "up" : "down");
354 json_object_string_add(json
, "address",
355 inet_ntoa(pim_ifp
->primary_address
));
356 json_object_int_add(json
, "index", ifp
->ifindex
);
358 if (if_is_multicast(ifp
))
359 json_object_boolean_true_add(json
, "flagMulticast");
361 if (if_is_broadcast(ifp
))
362 json_object_boolean_true_add(json
, "flagBroadcast");
364 if (ifp
->flags
& IFF_ALLMULTI
)
365 json_object_boolean_true_add(json
, "flagAllMulticast");
367 if (ifp
->flags
& IFF_PROMISC
)
368 json_object_boolean_true_add(json
, "flagPromiscuous");
370 if (PIM_IF_IS_DELETED(ifp
))
371 json_object_boolean_true_add(json
, "flagDeleted");
373 if (pim_if_lan_delay_enabled(ifp
))
374 json_object_boolean_true_add(json
, "lanDelayEnabled");
377 static void pim_show_membership(struct pim_instance
*pim
, struct vty
*vty
,
380 struct pim_interface
*pim_ifp
;
381 struct listnode
*ch_node
;
382 struct pim_ifchannel
*ch
;
384 json_object
*json
= NULL
;
385 json_object
*json_iface
= NULL
;
386 json_object
*json_row
= NULL
;
387 json_object
*json_tmp
= NULL
;
389 json
= json_object_new_object();
391 for (ALL_LIST_ELEMENTS_RO(pim
->ifchannel_list
, ch_node
, ch
)) {
393 pim_ifp
= ch
->interface
->info
;
398 char ch_src_str
[INET_ADDRSTRLEN
];
399 char ch_grp_str
[INET_ADDRSTRLEN
];
401 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
,
403 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
,
406 json_object_object_get_ex(json
, ch
->interface
->name
,
410 json_iface
= json_object_new_object();
411 json_object_pim_ifp_add(json_iface
, ch
->interface
);
412 json_object_object_add(json
, ch
->interface
->name
,
416 json_row
= json_object_new_object();
417 json_object_string_add(json_row
, "source", ch_src_str
);
418 json_object_string_add(json_row
, "group", ch_grp_str
);
419 json_object_string_add(
420 json_row
, "localMembership",
421 ch
->local_ifmembership
== PIM_IFMEMBERSHIP_NOINFO
424 json_object_object_add(json_iface
, ch_grp_str
, json_row
);
425 } /* scan interface channels */
428 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
429 json
, JSON_C_TO_STRING_PRETTY
));
432 "Interface Address Source Group Membership\n");
435 * Example of the json data we are traversing
441 * "address":"10.1.20.1",
443 * "flagMulticast":true,
444 * "flagBroadcast":true,
445 * "lanDelayEnabled":true,
448 * "group":"226.10.10.10",
449 * "localMembership":"INCLUDE"
455 /* foreach interface */
456 json_object_object_foreach(json
, key
, val
)
459 /* Find all of the keys where the val is an object. In
461 * above the only one is 226.10.10.10
463 json_object_object_foreach(val
, if_field_key
,
466 type
= json_object_get_type(if_field_val
);
468 if (type
== json_type_object
) {
469 vty_out(vty
, "%-9s ", key
);
471 json_object_object_get_ex(
472 val
, "address", &json_tmp
);
473 vty_out(vty
, "%-15s ",
474 json_object_get_string(
477 json_object_object_get_ex(if_field_val
,
480 vty_out(vty
, "%-15s ",
481 json_object_get_string(
485 vty_out(vty
, "%-15s ", if_field_key
);
487 json_object_object_get_ex(
488 if_field_val
, "localMembership",
490 vty_out(vty
, "%-10s\n",
491 json_object_get_string(
498 json_object_free(json
);
501 static void pim_print_ifp_flags(struct vty
*vty
, struct interface
*ifp
,
504 vty_out(vty
, "Flags\n");
505 vty_out(vty
, "-----\n");
506 vty_out(vty
, "All Multicast : %s\n",
507 (ifp
->flags
& IFF_ALLMULTI
) ? "yes" : "no");
508 vty_out(vty
, "Broadcast : %s\n",
509 if_is_broadcast(ifp
) ? "yes" : "no");
510 vty_out(vty
, "Deleted : %s\n",
511 PIM_IF_IS_DELETED(ifp
) ? "yes" : "no");
512 vty_out(vty
, "Interface Index : %d\n", ifp
->ifindex
);
513 vty_out(vty
, "Multicast : %s\n",
514 if_is_multicast(ifp
) ? "yes" : "no");
515 vty_out(vty
, "Multicast Loop : %d\n", mloop
);
516 vty_out(vty
, "Promiscuous : %s\n",
517 (ifp
->flags
& IFF_PROMISC
) ? "yes" : "no");
522 static void igmp_show_interfaces(struct vty
*vty
, u_char uj
)
524 struct listnode
*node
;
525 struct interface
*ifp
;
527 json_object
*json
= NULL
;
528 json_object
*json_row
= NULL
;
530 now
= pim_time_monotonic_sec();
533 json
= json_object_new_object();
536 "Interface State Address V Querier Query Timer Uptime\n");
538 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pimg
->vrf_id
), node
, ifp
)) {
539 struct pim_interface
*pim_ifp
;
540 struct listnode
*sock_node
;
541 struct igmp_sock
*igmp
;
548 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
551 char query_hhmmss
[10];
553 pim_time_uptime(uptime
, sizeof(uptime
),
554 now
- igmp
->sock_creation
);
555 pim_time_timer_to_hhmmss(query_hhmmss
,
556 sizeof(query_hhmmss
),
557 igmp
->t_igmp_query_timer
);
560 json_row
= json_object_new_object();
561 json_object_pim_ifp_add(json_row
, ifp
);
562 json_object_string_add(json_row
, "upTime",
564 json_object_int_add(json_row
, "version",
565 pim_ifp
->igmp_version
);
567 if (igmp
->t_igmp_query_timer
) {
568 json_object_boolean_true_add(json_row
,
570 json_object_string_add(json_row
,
575 json_object_object_add(json
, ifp
->name
,
580 "%-9s %5s %15s %d %7s %11s %8s\n",
582 if_is_up(ifp
) ? "up" : "down",
583 inet_ntoa(igmp
->ifaddr
),
584 pim_ifp
->igmp_version
,
585 igmp
->t_igmp_query_timer
? "local"
587 query_hhmmss
, uptime
);
593 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
594 json
, JSON_C_TO_STRING_PRETTY
));
595 json_object_free(json
);
599 static void igmp_show_interfaces_single(struct vty
*vty
, const char *ifname
,
602 struct igmp_sock
*igmp
;
603 struct interface
*ifp
;
604 struct listnode
*node
;
605 struct listnode
*sock_node
;
606 struct pim_interface
*pim_ifp
;
608 char query_hhmmss
[10];
609 char other_hhmmss
[10];
610 int found_ifname
= 0;
613 long gmi_msec
; /* Group Membership Interval */
616 long oqpi_msec
; /* Other Querier Present Interval */
620 json_object
*json
= NULL
;
621 json_object
*json_row
= NULL
;
624 json
= json_object_new_object();
626 now
= pim_time_monotonic_sec();
628 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pimg
->vrf_id
), node
, ifp
)) {
634 if (strcmp(ifname
, "detail") && strcmp(ifname
, ifp
->name
))
637 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
640 pim_time_uptime(uptime
, sizeof(uptime
),
641 now
- igmp
->sock_creation
);
642 pim_time_timer_to_hhmmss(query_hhmmss
,
643 sizeof(query_hhmmss
),
644 igmp
->t_igmp_query_timer
);
645 pim_time_timer_to_hhmmss(other_hhmmss
,
646 sizeof(other_hhmmss
),
647 igmp
->t_other_querier_timer
);
649 gmi_msec
= PIM_IGMP_GMI_MSEC(
650 igmp
->querier_robustness_variable
,
651 igmp
->querier_query_interval
,
652 pim_ifp
->igmp_query_max_response_time_dsec
);
655 pim_ifp
->igmp_default_query_interval
);
657 oqpi_msec
= PIM_IGMP_OQPI_MSEC(
658 igmp
->querier_robustness_variable
,
659 igmp
->querier_query_interval
,
660 pim_ifp
->igmp_query_max_response_time_dsec
);
662 lmqt_msec
= PIM_IGMP_LMQT_MSEC(
663 pim_ifp
->igmp_query_max_response_time_dsec
,
664 igmp
->querier_robustness_variable
);
668 igmp
->querier_robustness_variable
,
669 igmp
->querier_query_interval
,
670 pim_ifp
->igmp_query_max_response_time_dsec
)
673 qri_msec
= pim_ifp
->igmp_query_max_response_time_dsec
675 mloop
= pim_socket_mcastloop_get(pim_ifp
->pim_sock_fd
);
678 json_row
= json_object_new_object();
679 json_object_pim_ifp_add(json_row
, ifp
);
680 json_object_string_add(json_row
, "upTime",
682 json_object_string_add(json_row
, "querier",
683 igmp
->t_igmp_query_timer
686 json_object_int_add(json_row
, "queryStartCount",
687 igmp
->startup_query_count
);
688 json_object_string_add(json_row
,
691 json_object_string_add(json_row
,
694 json_object_int_add(json_row
, "version",
695 pim_ifp
->igmp_version
);
698 "timerGroupMembershipIntervalMsec",
700 json_object_int_add(json_row
,
701 "timerLastMemberQueryMsec",
705 "timerOlderHostPresentIntervalMsec",
709 "timerOtherQuerierPresentIntervalMsec",
712 json_row
, "timerQueryInterval",
713 igmp
->querier_query_interval
);
716 "timerQueryResponseIntervalMsec",
719 json_row
, "timerRobustnessVariable",
720 igmp
->querier_robustness_variable
);
721 json_object_int_add(json_row
,
722 "timerStartupQueryInterval",
725 json_object_object_add(json
, ifp
->name
,
729 vty_out(vty
, "Interface : %s\n", ifp
->name
);
730 vty_out(vty
, "State : %s\n",
731 if_is_up(ifp
) ? "up" : "down");
732 vty_out(vty
, "Address : %s\n",
733 inet_ntoa(pim_ifp
->primary_address
));
734 vty_out(vty
, "Uptime : %s\n", uptime
);
735 vty_out(vty
, "Version : %d\n",
736 pim_ifp
->igmp_version
);
740 vty_out(vty
, "Querier\n");
741 vty_out(vty
, "-------\n");
742 vty_out(vty
, "Querier : %s\n",
743 igmp
->t_igmp_query_timer
? "local"
745 vty_out(vty
, "Start Count : %d\n",
746 igmp
->startup_query_count
);
747 vty_out(vty
, "Query Timer : %s\n",
749 vty_out(vty
, "Other Timer : %s\n",
754 vty_out(vty
, "Timers\n");
755 vty_out(vty
, "------\n");
757 "Group Membership Interval : %lis\n",
760 "Last Member Query Time : %lis\n",
763 "Older Host Present Interval : %lis\n",
766 "Other Querier Present Interval : %lis\n",
769 "Query Interval : %ds\n",
770 igmp
->querier_query_interval
);
772 "Query Response Interval : %lis\n",
775 "Robustness Variable : %d\n",
776 igmp
->querier_robustness_variable
);
778 "Startup Query Interval : %ds\n",
783 pim_print_ifp_flags(vty
, ifp
, mloop
);
789 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
790 json
, JSON_C_TO_STRING_PRETTY
));
791 json_object_free(json
);
794 vty_out(vty
, "%% No such interface\n");
798 static void igmp_show_interface_join(struct vty
*vty
)
800 struct listnode
*node
;
801 struct interface
*ifp
;
804 now
= pim_time_monotonic_sec();
807 "Interface Address Source Group Socket Uptime \n");
809 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pimg
->vrf_id
), node
, ifp
)) {
810 struct pim_interface
*pim_ifp
;
811 struct listnode
*join_node
;
812 struct igmp_join
*ij
;
813 struct in_addr pri_addr
;
814 char pri_addr_str
[INET_ADDRSTRLEN
];
821 if (!pim_ifp
->igmp_join_list
)
824 pri_addr
= pim_find_primary_addr(ifp
);
825 pim_inet4_dump("<pri?>", pri_addr
, pri_addr_str
,
826 sizeof(pri_addr_str
));
828 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_join_list
, join_node
,
830 char group_str
[INET_ADDRSTRLEN
];
831 char source_str
[INET_ADDRSTRLEN
];
834 pim_time_uptime(uptime
, sizeof(uptime
),
835 now
- ij
->sock_creation
);
836 pim_inet4_dump("<grp?>", ij
->group_addr
, group_str
,
838 pim_inet4_dump("<src?>", ij
->source_addr
, source_str
,
841 vty_out(vty
, "%-9s %-15s %-15s %-15s %6d %8s\n",
842 ifp
->name
, pri_addr_str
, source_str
, group_str
,
843 ij
->sock_fd
, uptime
);
844 } /* for (pim_ifp->igmp_join_list) */
849 static void pim_show_interfaces_single(struct vty
*vty
, const char *ifname
,
852 struct in_addr ifaddr
;
853 struct interface
*ifp
;
854 struct listnode
*neighnode
;
855 struct listnode
*node
;
856 struct listnode
*upnode
;
857 struct pim_interface
*pim_ifp
;
858 struct pim_neighbor
*neigh
;
859 struct pim_upstream
*up
;
861 char dr_str
[INET_ADDRSTRLEN
];
864 char grp_str
[INET_ADDRSTRLEN
];
865 char hello_period
[10];
866 char hello_timer
[10];
867 char neigh_src_str
[INET_ADDRSTRLEN
];
868 char src_str
[INET_ADDRSTRLEN
];
869 char stat_uptime
[10];
872 int found_ifname
= 0;
874 json_object
*json
= NULL
;
875 json_object
*json_row
= NULL
;
876 json_object
*json_pim_neighbor
= NULL
;
877 json_object
*json_pim_neighbors
= NULL
;
878 json_object
*json_group
= NULL
;
879 json_object
*json_group_source
= NULL
;
880 json_object
*json_fhr_sources
= NULL
;
881 struct pim_secondary_addr
*sec_addr
;
882 struct listnode
*sec_node
;
884 now
= pim_time_monotonic_sec();
887 json
= json_object_new_object();
889 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pimg
->vrf_id
), node
, ifp
)) {
895 if (pim_ifp
->pim_sock_fd
< 0)
898 if (strcmp(ifname
, "detail") && strcmp(ifname
, ifp
->name
))
902 ifaddr
= pim_ifp
->primary_address
;
903 pim_inet4_dump("<dr?>", pim_ifp
->pim_dr_addr
, dr_str
,
905 pim_time_uptime_begin(dr_uptime
, sizeof(dr_uptime
), now
,
906 pim_ifp
->pim_dr_election_last
);
907 pim_time_timer_to_hhmmss(hello_timer
, sizeof(hello_timer
),
908 pim_ifp
->t_pim_hello_timer
);
909 pim_time_mmss(hello_period
, sizeof(hello_period
),
910 pim_ifp
->pim_hello_period
);
911 pim_time_uptime(stat_uptime
, sizeof(stat_uptime
),
912 now
- pim_ifp
->pim_ifstat_start
);
913 mloop
= pim_socket_mcastloop_get(pim_ifp
->pim_sock_fd
);
916 char pbuf
[PREFIX2STR_BUFFER
];
917 json_row
= json_object_new_object();
918 json_object_pim_ifp_add(json_row
, ifp
);
920 if (pim_ifp
->update_source
.s_addr
!= INADDR_ANY
) {
921 json_object_string_add(
922 json_row
, "useSource",
923 inet_ntoa(pim_ifp
->update_source
));
925 if (pim_ifp
->sec_addr_list
) {
926 json_object
*sec_list
= NULL
;
928 sec_list
= json_object_new_array();
929 for (ALL_LIST_ELEMENTS_RO(
930 pim_ifp
->sec_addr_list
, sec_node
,
932 json_object_array_add(
934 json_object_new_string(
940 json_object_object_add(json_row
,
941 "secondaryAddressList",
946 if (pim_ifp
->pim_neighbor_list
->count
) {
947 json_pim_neighbors
= json_object_new_object();
949 for (ALL_LIST_ELEMENTS_RO(
950 pim_ifp
->pim_neighbor_list
,
953 json_object_new_object();
954 pim_inet4_dump("<src?>",
957 sizeof(neigh_src_str
));
958 pim_time_uptime(uptime
, sizeof(uptime
),
959 now
- neigh
->creation
);
960 pim_time_timer_to_hhmmss(
961 expire
, sizeof(expire
),
962 neigh
->t_expire_timer
);
964 json_object_string_add(
965 json_pim_neighbor
, "address",
967 json_object_string_add(
968 json_pim_neighbor
, "upTime",
970 json_object_string_add(
971 json_pim_neighbor
, "holdtime",
974 json_object_object_add(
980 json_object_object_add(json_row
, "neighbors",
984 json_object_string_add(json_row
, "drAddress", dr_str
);
985 json_object_int_add(json_row
, "drPriority",
986 pim_ifp
->pim_dr_priority
);
987 json_object_string_add(json_row
, "drUptime", dr_uptime
);
988 json_object_int_add(json_row
, "drElections",
989 pim_ifp
->pim_dr_election_count
);
990 json_object_int_add(json_row
, "drChanges",
991 pim_ifp
->pim_dr_election_changes
);
994 for (ALL_LIST_ELEMENTS_RO(pimg
->upstream_list
, upnode
,
996 if (ifp
== up
->rpf
.source_nexthop
.interface
) {
998 & PIM_UPSTREAM_FLAG_MASK_FHR
) {
999 if (!json_fhr_sources
) {
1001 json_object_new_object();
1004 pim_inet4_dump("<src?>",
1008 pim_inet4_dump("<grp?>",
1013 uptime
, sizeof(uptime
),
1014 now
- up
->state_transition
);
1016 /* Does this group live in
1017 * json_fhr_sources? If not
1019 json_object_object_get_ex(
1021 grp_str
, &json_group
);
1025 json_object_new_object();
1026 json_object_object_add(
1033 json_object_new_object();
1034 json_object_string_add(
1037 json_object_string_add(
1040 json_object_string_add(
1043 json_object_object_add(
1044 json_group
, src_str
,
1050 if (json_fhr_sources
) {
1051 json_object_object_add(json_row
,
1056 json_object_int_add(json_row
, "helloPeriod",
1057 pim_ifp
->pim_hello_period
);
1058 json_object_string_add(json_row
, "helloTimer",
1060 json_object_string_add(json_row
, "helloStatStart",
1062 json_object_int_add(json_row
, "helloReceived",
1063 pim_ifp
->pim_ifstat_hello_recv
);
1064 json_object_int_add(json_row
, "helloReceivedFailed",
1065 pim_ifp
->pim_ifstat_hello_recvfail
);
1066 json_object_int_add(json_row
, "helloSend",
1067 pim_ifp
->pim_ifstat_hello_sent
);
1068 json_object_int_add(json_row
, "hellosendFailed",
1069 pim_ifp
->pim_ifstat_hello_sendfail
);
1070 json_object_int_add(json_row
, "helloGenerationId",
1071 pim_ifp
->pim_generation_id
);
1072 json_object_int_add(json_row
, "flagMulticastLoop",
1075 json_object_int_add(
1076 json_row
, "effectivePropagationDelay",
1077 pim_if_effective_propagation_delay_msec(ifp
));
1078 json_object_int_add(
1079 json_row
, "effectiveOverrideInterval",
1080 pim_if_effective_override_interval_msec(ifp
));
1081 json_object_int_add(
1082 json_row
, "joinPruneOverrideInterval",
1083 pim_if_jp_override_interval_msec(ifp
));
1085 json_object_int_add(
1086 json_row
, "propagationDelay",
1087 pim_ifp
->pim_propagation_delay_msec
);
1088 json_object_int_add(
1089 json_row
, "propagationDelayHighest",
1090 pim_ifp
->pim_neighbors_highest_propagation_delay_msec
);
1091 json_object_int_add(
1092 json_row
, "overrideInterval",
1093 pim_ifp
->pim_override_interval_msec
);
1094 json_object_int_add(
1095 json_row
, "overrideIntervalHighest",
1096 pim_ifp
->pim_neighbors_highest_override_interval_msec
);
1097 json_object_object_add(json
, ifp
->name
, json_row
);
1100 vty_out(vty
, "Interface : %s\n", ifp
->name
);
1101 vty_out(vty
, "State : %s\n",
1102 if_is_up(ifp
) ? "up" : "down");
1103 if (pim_ifp
->update_source
.s_addr
!= INADDR_ANY
) {
1104 vty_out(vty
, "Use Source : %s\n",
1105 inet_ntoa(pim_ifp
->update_source
));
1107 if (pim_ifp
->sec_addr_list
) {
1108 char pbuf
[PREFIX2STR_BUFFER
];
1109 vty_out(vty
, "Address : %s (primary)\n",
1111 for (ALL_LIST_ELEMENTS_RO(
1112 pim_ifp
->sec_addr_list
, sec_node
,
1114 vty_out(vty
, " %s\n",
1115 prefix2str(&sec_addr
->addr
,
1116 pbuf
, sizeof(pbuf
)));
1119 vty_out(vty
, "Address : %s\n",
1127 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
,
1128 neighnode
, neigh
)) {
1131 vty_out(vty
, "PIM Neighbors\n");
1132 vty_out(vty
, "-------------\n");
1136 pim_inet4_dump("<src?>", neigh
->source_addr
,
1138 sizeof(neigh_src_str
));
1139 pim_time_uptime(uptime
, sizeof(uptime
),
1140 now
- neigh
->creation
);
1141 pim_time_timer_to_hhmmss(expire
, sizeof(expire
),
1142 neigh
->t_expire_timer
);
1144 "%-15s : up for %s, holdtime expires in %s\n",
1145 neigh_src_str
, uptime
, expire
);
1148 if (!print_header
) {
1153 vty_out(vty
, "Designated Router\n");
1154 vty_out(vty
, "-----------------\n");
1155 vty_out(vty
, "Address : %s\n", dr_str
);
1156 vty_out(vty
, "Priority : %d\n",
1157 pim_ifp
->pim_dr_priority
);
1158 vty_out(vty
, "Uptime : %s\n", dr_uptime
);
1159 vty_out(vty
, "Elections : %d\n",
1160 pim_ifp
->pim_dr_election_count
);
1161 vty_out(vty
, "Changes : %d\n",
1162 pim_ifp
->pim_dr_election_changes
);
1168 for (ALL_LIST_ELEMENTS_RO(pimg
->upstream_list
, upnode
,
1170 if (strcmp(ifp
->name
, up
->rpf
.source_nexthop
1174 & PIM_UPSTREAM_FLAG_MASK_FHR
) {
1178 "FHR - First Hop Router\n");
1180 "----------------------\n");
1184 pim_inet4_dump("<src?>",
1188 pim_inet4_dump("<grp?>",
1193 uptime
, sizeof(uptime
),
1194 now
- up
->state_transition
);
1196 "%s : %s is a source, uptime is %s\n",
1203 if (!print_header
) {
1208 vty_out(vty
, "Hellos\n");
1209 vty_out(vty
, "------\n");
1210 vty_out(vty
, "Period : %d\n",
1211 pim_ifp
->pim_hello_period
);
1212 vty_out(vty
, "Timer : %s\n", hello_timer
);
1213 vty_out(vty
, "StatStart : %s\n", stat_uptime
);
1214 vty_out(vty
, "Receive : %d\n",
1215 pim_ifp
->pim_ifstat_hello_recv
);
1216 vty_out(vty
, "Receive Failed : %d\n",
1217 pim_ifp
->pim_ifstat_hello_recvfail
);
1218 vty_out(vty
, "Send : %d\n",
1219 pim_ifp
->pim_ifstat_hello_sent
);
1220 vty_out(vty
, "Send Failed : %d\n",
1221 pim_ifp
->pim_ifstat_hello_sendfail
);
1222 vty_out(vty
, "Generation ID : %08x\n",
1223 pim_ifp
->pim_generation_id
);
1227 pim_print_ifp_flags(vty
, ifp
, mloop
);
1229 vty_out(vty
, "Join Prune Interval\n");
1230 vty_out(vty
, "-------------------\n");
1231 vty_out(vty
, "LAN Delay : %s\n",
1232 pim_if_lan_delay_enabled(ifp
) ? "yes" : "no");
1233 vty_out(vty
, "Effective Propagation Delay : %d msec\n",
1234 pim_if_effective_propagation_delay_msec(ifp
));
1235 vty_out(vty
, "Effective Override Interval : %d msec\n",
1236 pim_if_effective_override_interval_msec(ifp
));
1237 vty_out(vty
, "Join Prune Override Interval : %d msec\n",
1238 pim_if_jp_override_interval_msec(ifp
));
1242 vty_out(vty
, "LAN Prune Delay\n");
1243 vty_out(vty
, "---------------\n");
1244 vty_out(vty
, "Propagation Delay : %d msec\n",
1245 pim_ifp
->pim_propagation_delay_msec
);
1246 vty_out(vty
, "Propagation Delay (Highest) : %d msec\n",
1247 pim_ifp
->pim_neighbors_highest_propagation_delay_msec
);
1248 vty_out(vty
, "Override Interval : %d msec\n",
1249 pim_ifp
->pim_override_interval_msec
);
1250 vty_out(vty
, "Override Interval (Highest) : %d msec\n",
1251 pim_ifp
->pim_neighbors_highest_override_interval_msec
);
1258 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1259 json
, JSON_C_TO_STRING_PRETTY
));
1260 json_object_free(json
);
1263 vty_out(vty
, "%% No such interface\n");
1267 static void pim_show_interfaces(struct vty
*vty
, u_char uj
)
1269 struct interface
*ifp
;
1270 struct listnode
*node
;
1271 struct listnode
*upnode
;
1272 struct pim_interface
*pim_ifp
;
1273 struct pim_upstream
*up
;
1276 int pim_ifchannels
= 0;
1277 json_object
*json
= NULL
;
1278 json_object
*json_row
= NULL
;
1279 json_object
*json_tmp
;
1281 json
= json_object_new_object();
1283 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pimg
->vrf_id
), node
, ifp
)) {
1284 pim_ifp
= ifp
->info
;
1289 if (pim_ifp
->pim_sock_fd
< 0)
1292 pim_nbrs
= pim_ifp
->pim_neighbor_list
->count
;
1293 pim_ifchannels
= pim_ifp
->pim_ifchannel_list
->count
;
1296 for (ALL_LIST_ELEMENTS_RO(pimg
->upstream_list
, upnode
, up
))
1297 if (ifp
== up
->rpf
.source_nexthop
.interface
)
1298 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
)
1301 json_row
= json_object_new_object();
1302 json_object_pim_ifp_add(json_row
, ifp
);
1303 json_object_int_add(json_row
, "pimNeighbors", pim_nbrs
);
1304 json_object_int_add(json_row
, "pimIfChannels", pim_ifchannels
);
1305 json_object_int_add(json_row
, "firstHopRouter", fhr
);
1306 json_object_string_add(json_row
, "pimDesignatedRouter",
1307 inet_ntoa(pim_ifp
->pim_dr_addr
));
1309 if (pim_ifp
->pim_dr_addr
.s_addr
1310 == pim_ifp
->primary_address
.s_addr
)
1311 json_object_boolean_true_add(
1312 json_row
, "pimDesignatedRouterLocal");
1314 json_object_object_add(json
, ifp
->name
, json_row
);
1318 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1319 json
, JSON_C_TO_STRING_PRETTY
));
1322 "Interface State Address PIM Nbrs PIM DR FHR IfChannels\n");
1324 json_object_object_foreach(json
, key
, val
)
1326 vty_out(vty
, "%-9s ", key
);
1328 json_object_object_get_ex(val
, "state", &json_tmp
);
1329 vty_out(vty
, "%5s ", json_object_get_string(json_tmp
));
1331 json_object_object_get_ex(val
, "address", &json_tmp
);
1332 vty_out(vty
, "%15s ",
1333 json_object_get_string(json_tmp
));
1335 json_object_object_get_ex(val
, "pimNeighbors",
1337 vty_out(vty
, "%8d ", json_object_get_int(json_tmp
));
1339 if (json_object_object_get_ex(
1340 val
, "pimDesignatedRouterLocal",
1342 vty_out(vty
, "%15s ", "local");
1344 json_object_object_get_ex(
1345 val
, "pimDesignatedRouter", &json_tmp
);
1346 vty_out(vty
, "%15s ",
1347 json_object_get_string(json_tmp
));
1350 json_object_object_get_ex(val
, "firstHopRouter",
1352 vty_out(vty
, "%3d ", json_object_get_int(json_tmp
));
1354 json_object_object_get_ex(val
, "pimIfChannels",
1356 vty_out(vty
, "%9d\n", json_object_get_int(json_tmp
));
1360 json_object_free(json
);
1363 static void pim_show_interface_traffic(struct vty
*vty
, u_char uj
)
1365 struct interface
*ifp
= NULL
;
1366 struct pim_interface
*pim_ifp
= NULL
;
1367 struct listnode
*node
= NULL
;
1368 json_object
*json
= NULL
;
1369 json_object
*json_row
= NULL
;
1372 json
= json_object_new_object();
1375 vty_out(vty
, "%-12s%-17s%-17s%-17s%-17s%-17s%-17s\n",
1376 "Interface", " HELLO", " JOIN", " PRUNE",
1377 " REGISTER", " REGISTER-STOP", " ASSERT");
1378 vty_out(vty
, "%-10s%-18s%-17s%-17s%-17s%-17s%-17s\n", "",
1379 " Rx/Tx", " Rx/Tx", " Rx/Tx", " Rx/Tx",
1380 " Rx/Tx", " Rx/Tx");
1382 "---------------------------------------------------------------------------------------------------------------\n");
1385 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pimg
->vrf_id
), node
, ifp
)) {
1386 pim_ifp
= ifp
->info
;
1391 if (pim_ifp
->pim_sock_fd
< 0)
1394 json_row
= json_object_new_object();
1395 json_object_pim_ifp_add(json_row
, ifp
);
1396 json_object_int_add(json_row
, "helloRx",
1397 pim_ifp
->pim_ifstat_hello_recv
);
1398 json_object_int_add(json_row
, "helloTx",
1399 pim_ifp
->pim_ifstat_hello_sent
);
1400 json_object_int_add(json_row
, "joinRx",
1401 pim_ifp
->pim_ifstat_join_recv
);
1402 json_object_int_add(json_row
, "joinTx",
1403 pim_ifp
->pim_ifstat_join_send
);
1404 json_object_int_add(json_row
, "registerRx",
1405 pim_ifp
->pim_ifstat_reg_recv
);
1406 json_object_int_add(json_row
, "registerTx",
1407 pim_ifp
->pim_ifstat_reg_recv
);
1408 json_object_int_add(json_row
, "registerStopRx",
1409 pim_ifp
->pim_ifstat_reg_stop_recv
);
1410 json_object_int_add(json_row
, "registerStopTx",
1411 pim_ifp
->pim_ifstat_reg_stop_send
);
1412 json_object_int_add(json_row
, "assertRx",
1413 pim_ifp
->pim_ifstat_assert_recv
);
1414 json_object_int_add(json_row
, "assertTx",
1415 pim_ifp
->pim_ifstat_assert_send
);
1417 json_object_object_add(json
, ifp
->name
, json_row
);
1420 "%-10s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u \n",
1421 ifp
->name
, pim_ifp
->pim_ifstat_hello_recv
,
1422 pim_ifp
->pim_ifstat_hello_sent
,
1423 pim_ifp
->pim_ifstat_join_recv
,
1424 pim_ifp
->pim_ifstat_join_send
,
1425 pim_ifp
->pim_ifstat_prune_recv
,
1426 pim_ifp
->pim_ifstat_prune_send
,
1427 pim_ifp
->pim_ifstat_reg_recv
,
1428 pim_ifp
->pim_ifstat_reg_send
,
1429 pim_ifp
->pim_ifstat_reg_stop_recv
,
1430 pim_ifp
->pim_ifstat_reg_stop_send
,
1431 pim_ifp
->pim_ifstat_assert_recv
,
1432 pim_ifp
->pim_ifstat_assert_send
);
1436 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1437 json
, JSON_C_TO_STRING_PRETTY
));
1438 json_object_free(json
);
1442 static void pim_show_interface_traffic_single(struct vty
*vty
,
1443 const char *ifname
, u_char uj
)
1445 struct interface
*ifp
= NULL
;
1446 struct pim_interface
*pim_ifp
= NULL
;
1447 struct listnode
*node
= NULL
;
1448 json_object
*json
= NULL
;
1449 json_object
*json_row
= NULL
;
1450 uint8_t found_ifname
= 0;
1453 json
= json_object_new_object();
1456 vty_out(vty
, "%-12s%-17s%-17s%-17s%-17s%-17s%-17s\n",
1457 "Interface", " HELLO", " JOIN", " PRUNE",
1458 " REGISTER", " REGISTER-STOP", " ASSERT");
1459 vty_out(vty
, "%-10s%-18s%-17s%-17s%-17s%-17s%-17s\n", "",
1460 " Rx/Tx", " Rx/Tx", " Rx/Tx", " Rx/Tx",
1461 " Rx/Tx", " Rx/Tx");
1463 "---------------------------------------------------------------------------------------------------------------\n");
1466 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pimg
->vrf_id
), node
, ifp
)) {
1467 if (strcmp(ifname
, ifp
->name
))
1470 pim_ifp
= ifp
->info
;
1475 if (pim_ifp
->pim_sock_fd
< 0)
1480 json_row
= json_object_new_object();
1481 json_object_pim_ifp_add(json_row
, ifp
);
1482 json_object_int_add(json_row
, "helloRx",
1483 pim_ifp
->pim_ifstat_hello_recv
);
1484 json_object_int_add(json_row
, "helloTx",
1485 pim_ifp
->pim_ifstat_hello_sent
);
1486 json_object_int_add(json_row
, "joinRx",
1487 pim_ifp
->pim_ifstat_join_recv
);
1488 json_object_int_add(json_row
, "joinTx",
1489 pim_ifp
->pim_ifstat_join_send
);
1490 json_object_int_add(json_row
, "registerRx",
1491 pim_ifp
->pim_ifstat_reg_recv
);
1492 json_object_int_add(json_row
, "registerTx",
1493 pim_ifp
->pim_ifstat_reg_recv
);
1494 json_object_int_add(json_row
, "registerStopRx",
1495 pim_ifp
->pim_ifstat_reg_stop_recv
);
1496 json_object_int_add(json_row
, "registerStopTx",
1497 pim_ifp
->pim_ifstat_reg_stop_send
);
1498 json_object_int_add(json_row
, "assertRx",
1499 pim_ifp
->pim_ifstat_assert_recv
);
1500 json_object_int_add(json_row
, "assertTx",
1501 pim_ifp
->pim_ifstat_assert_send
);
1503 json_object_object_add(json
, ifp
->name
, json_row
);
1506 "%-10s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u \n",
1507 ifp
->name
, pim_ifp
->pim_ifstat_hello_recv
,
1508 pim_ifp
->pim_ifstat_hello_sent
,
1509 pim_ifp
->pim_ifstat_join_recv
,
1510 pim_ifp
->pim_ifstat_join_send
,
1511 pim_ifp
->pim_ifstat_prune_recv
,
1512 pim_ifp
->pim_ifstat_prune_send
,
1513 pim_ifp
->pim_ifstat_reg_recv
,
1514 pim_ifp
->pim_ifstat_reg_send
,
1515 pim_ifp
->pim_ifstat_reg_stop_recv
,
1516 pim_ifp
->pim_ifstat_reg_stop_send
,
1517 pim_ifp
->pim_ifstat_assert_recv
,
1518 pim_ifp
->pim_ifstat_assert_send
);
1522 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1523 json
, JSON_C_TO_STRING_PRETTY
));
1524 json_object_free(json
);
1527 vty_out(vty
, "%% No such interface\n");
1531 static void pim_show_join(struct pim_instance
*pim
, struct vty
*vty
, u_char uj
)
1533 struct pim_interface
*pim_ifp
;
1534 struct in_addr ifaddr
;
1535 struct listnode
*ch_node
;
1536 struct pim_ifchannel
*ch
;
1538 json_object
*json
= NULL
;
1539 json_object
*json_iface
= NULL
;
1540 json_object
*json_row
= NULL
;
1541 json_object
*json_grp
= NULL
;
1543 now
= pim_time_monotonic_sec();
1546 json
= json_object_new_object();
1549 "Interface Address Source Group State Uptime Expire Prune\n");
1551 for (ALL_LIST_ELEMENTS_RO(pim
->ifchannel_list
, ch_node
, ch
)) {
1553 pim_ifp
= ch
->interface
->info
;
1558 ifaddr
= pim_ifp
->primary_address
;
1560 char ch_src_str
[INET_ADDRSTRLEN
];
1561 char ch_grp_str
[INET_ADDRSTRLEN
];
1566 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
,
1567 sizeof(ch_src_str
));
1568 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
,
1569 sizeof(ch_grp_str
));
1571 pim_time_uptime_begin(uptime
, sizeof(uptime
), now
,
1572 ch
->ifjoin_creation
);
1573 pim_time_timer_to_mmss(expire
, sizeof(expire
),
1574 ch
->t_ifjoin_expiry_timer
);
1575 pim_time_timer_to_mmss(prune
, sizeof(prune
),
1576 ch
->t_ifjoin_prune_pending_timer
);
1579 json_object_object_get_ex(json
, ch
->interface
->name
,
1583 json_iface
= json_object_new_object();
1584 json_object_pim_ifp_add(json_iface
,
1586 json_object_object_add(
1587 json
, ch
->interface
->name
, json_iface
);
1590 json_row
= json_object_new_object();
1591 json_object_string_add(json_row
, "source", ch_src_str
);
1592 json_object_string_add(json_row
, "group", ch_grp_str
);
1593 json_object_string_add(json_row
, "upTime", uptime
);
1594 json_object_string_add(json_row
, "expire", expire
);
1595 json_object_string_add(json_row
, "prune", prune
);
1596 json_object_string_add(
1597 json_row
, "channelJoinName",
1598 pim_ifchannel_ifjoin_name(ch
->ifjoin_state
,
1600 if (PIM_IF_FLAG_TEST_S_G_RPT(ch
->flags
))
1601 json_object_int_add(json_row
, "SGRpt", 1);
1603 json_object_object_get_ex(json_iface
, ch_grp_str
,
1606 json_grp
= json_object_new_object();
1607 json_object_object_add(json_grp
, ch_src_str
,
1609 json_object_object_add(json_iface
, ch_grp_str
,
1612 json_object_object_add(json_grp
, ch_src_str
,
1616 "%-9s %-15s %-15s %-15s %-6s %8s %-6s %5s\n",
1617 ch
->interface
->name
, inet_ntoa(ifaddr
),
1618 ch_src_str
, ch_grp_str
,
1619 pim_ifchannel_ifjoin_name(ch
->ifjoin_state
,
1621 uptime
, expire
, prune
);
1623 } /* scan interface channels */
1626 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1627 json
, JSON_C_TO_STRING_PRETTY
));
1628 json_object_free(json
);
1632 static void pim_show_neighbors_single(struct vty
*vty
, const char *neighbor
,
1635 struct listnode
*node
;
1636 struct listnode
*neighnode
;
1637 struct interface
*ifp
;
1638 struct pim_interface
*pim_ifp
;
1639 struct pim_neighbor
*neigh
;
1641 int found_neighbor
= 0;
1642 int option_address_list
;
1643 int option_dr_priority
;
1644 int option_generation_id
;
1645 int option_holdtime
;
1646 int option_lan_prune_delay
;
1650 char neigh_src_str
[INET_ADDRSTRLEN
];
1652 json_object
*json
= NULL
;
1653 json_object
*json_ifp
= NULL
;
1654 json_object
*json_row
= NULL
;
1656 now
= pim_time_monotonic_sec();
1659 json
= json_object_new_object();
1661 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pimg
->vrf_id
), node
, ifp
)) {
1662 pim_ifp
= ifp
->info
;
1667 if (pim_ifp
->pim_sock_fd
< 0)
1670 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
1672 pim_inet4_dump("<src?>", neigh
->source_addr
,
1673 neigh_src_str
, sizeof(neigh_src_str
));
1676 * The user can specify either the interface name or the
1678 * If this pim_ifp matches neither then skip.
1680 if (strcmp(neighbor
, "detail")
1681 && strcmp(neighbor
, ifp
->name
)
1682 && strcmp(neighbor
, neigh_src_str
))
1686 pim_time_uptime(uptime
, sizeof(uptime
),
1687 now
- neigh
->creation
);
1688 pim_time_timer_to_hhmmss(expire
, sizeof(expire
),
1689 neigh
->t_expire_timer
);
1691 option_address_list
= 0;
1692 option_dr_priority
= 0;
1693 option_generation_id
= 0;
1694 option_holdtime
= 0;
1695 option_lan_prune_delay
= 0;
1698 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1699 PIM_OPTION_MASK_ADDRESS_LIST
))
1700 option_address_list
= 1;
1702 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1703 PIM_OPTION_MASK_DR_PRIORITY
))
1704 option_dr_priority
= 1;
1706 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1707 PIM_OPTION_MASK_GENERATION_ID
))
1708 option_generation_id
= 1;
1710 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1711 PIM_OPTION_MASK_HOLDTIME
))
1712 option_holdtime
= 1;
1714 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1715 PIM_OPTION_MASK_LAN_PRUNE_DELAY
))
1716 option_lan_prune_delay
= 1;
1718 if (PIM_OPTION_IS_SET(
1719 neigh
->hello_options
,
1720 PIM_OPTION_MASK_CAN_DISABLE_JOIN_SUPPRESSION
))
1725 /* Does this ifp live in json? If not create
1727 json_object_object_get_ex(json
, ifp
->name
,
1731 json_ifp
= json_object_new_object();
1732 json_object_pim_ifp_add(json_ifp
, ifp
);
1733 json_object_object_add(json
, ifp
->name
,
1737 json_row
= json_object_new_object();
1738 json_object_string_add(json_row
, "interface",
1740 json_object_string_add(json_row
, "address",
1742 json_object_string_add(json_row
, "upTime",
1744 json_object_string_add(json_row
, "holdtime",
1746 json_object_int_add(json_row
, "drPriority",
1747 neigh
->dr_priority
);
1748 json_object_int_add(json_row
, "generationId",
1749 neigh
->generation_id
);
1751 if (option_address_list
)
1752 json_object_boolean_true_add(
1754 "helloOptionAddressList");
1756 if (option_dr_priority
)
1757 json_object_boolean_true_add(
1759 "helloOptionDrPriority");
1761 if (option_generation_id
)
1762 json_object_boolean_true_add(
1764 "helloOptionGenerationId");
1766 if (option_holdtime
)
1767 json_object_boolean_true_add(
1769 "helloOptionHoldtime");
1771 if (option_lan_prune_delay
)
1772 json_object_boolean_true_add(
1774 "helloOptionLanPruneDelay");
1777 json_object_boolean_true_add(
1778 json_row
, "helloOptionTBit");
1780 json_object_object_add(json_ifp
, neigh_src_str
,
1784 vty_out(vty
, "Interface : %s\n", ifp
->name
);
1785 vty_out(vty
, "Neighbor : %s\n", neigh_src_str
);
1793 " DR Priority : %d\n",
1794 neigh
->dr_priority
);
1796 " Generation ID : %08x\n",
1797 neigh
->generation_id
);
1799 " Override Interval (msec) : %d\n",
1800 neigh
->override_interval_msec
);
1802 " Propagation Delay (msec) : %d\n",
1803 neigh
->propagation_delay_msec
);
1805 " Hello Option - Address List : %s\n",
1806 option_address_list
? "yes" : "no");
1808 " Hello Option - DR Priority : %s\n",
1809 option_dr_priority
? "yes" : "no");
1811 " Hello Option - Generation ID : %s\n",
1812 option_generation_id
? "yes" : "no");
1814 " Hello Option - Holdtime : %s\n",
1815 option_holdtime
? "yes" : "no");
1817 " Hello Option - LAN Prune Delay : %s\n",
1818 option_lan_prune_delay
? "yes" : "no");
1820 " Hello Option - T-bit : %s\n",
1821 option_t_bit
? "yes" : "no");
1822 pim_bfd_show_info(vty
, neigh
->bfd_info
,
1830 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1831 json
, JSON_C_TO_STRING_PRETTY
));
1832 json_object_free(json
);
1835 if (!found_neighbor
)
1837 "%% No such interface or neighbor\n");
1842 static void pim_show_state(struct pim_instance
*pim
, struct vty
*vty
,
1843 const char *src_or_group
, const char *group
,
1846 struct channel_oil
*c_oil
;
1847 struct listnode
*node
;
1848 json_object
*json
= NULL
;
1849 json_object
*json_group
= NULL
;
1850 json_object
*json_ifp_in
= NULL
;
1851 json_object
*json_ifp_out
= NULL
;
1852 json_object
*json_source
= NULL
;
1855 now
= pim_time_monotonic_sec();
1858 json
= json_object_new_object();
1861 "Codes: J -> Pim Join, I -> IGMP Report, S -> Source, * -> Inherited from (*,G)");
1863 "\nInstalled Source Group IIF OIL\n");
1866 for (ALL_LIST_ELEMENTS_RO(pim_channel_oil_list
, node
, c_oil
)) {
1867 char grp_str
[INET_ADDRSTRLEN
];
1868 char src_str
[INET_ADDRSTRLEN
];
1869 char in_ifname
[INTERFACE_NAMSIZ
+ 1];
1870 char out_ifname
[INTERFACE_NAMSIZ
+ 1];
1872 struct interface
*ifp_in
;
1875 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, grp_str
,
1877 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, src_str
,
1879 ifp_in
= pim_if_find_by_vif_index(pim
, c_oil
->oil
.mfcc_parent
);
1882 strcpy(in_ifname
, ifp_in
->name
);
1884 strcpy(in_ifname
, "<iif?>");
1887 if (strcmp(src_or_group
, src_str
)
1888 && strcmp(src_or_group
, grp_str
))
1891 if (group
&& strcmp(group
, grp_str
))
1897 /* Find the group, create it if it doesn't exist */
1898 json_object_object_get_ex(json
, grp_str
, &json_group
);
1901 json_group
= json_object_new_object();
1902 json_object_object_add(json
, grp_str
,
1906 /* Find the source nested under the group, create it if
1907 * it doesn't exist */
1908 json_object_object_get_ex(json_group
, src_str
,
1912 json_source
= json_object_new_object();
1913 json_object_object_add(json_group
, src_str
,
1917 /* Find the inbound interface nested under the source,
1918 * create it if it doesn't exist */
1919 json_object_object_get_ex(json_source
, in_ifname
,
1923 json_ifp_in
= json_object_new_object();
1924 json_object_object_add(json_source
, in_ifname
,
1926 json_object_int_add(json_source
, "Installed",
1928 json_object_int_add(json_source
, "RefCount",
1929 c_oil
->oil_ref_count
);
1930 json_object_int_add(json_source
, "OilListSize",
1932 json_object_int_add(
1933 json_source
, "OilRescan",
1934 c_oil
->oil_inherited_rescan
);
1935 json_object_int_add(json_source
, "LastUsed",
1936 c_oil
->cc
.lastused
);
1937 json_object_int_add(json_source
, "PacketCount",
1939 json_object_int_add(json_source
, "ByteCount",
1941 json_object_int_add(json_source
,
1943 c_oil
->cc
.wrong_if
);
1946 vty_out(vty
, "%-9d %-15s %-15s %-7s ",
1947 c_oil
->installed
, src_str
, grp_str
,
1951 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
1953 struct interface
*ifp_out
;
1954 char oif_uptime
[10];
1957 ttl
= c_oil
->oil
.mfcc_ttls
[oif_vif_index
];
1961 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
1963 oif_uptime
, sizeof(oif_uptime
),
1964 now
- c_oil
->oif_creation
[oif_vif_index
]);
1967 strcpy(out_ifname
, ifp_out
->name
);
1969 strcpy(out_ifname
, "<oif?>");
1972 json_ifp_out
= json_object_new_object();
1973 json_object_string_add(json_ifp_out
, "source",
1975 json_object_string_add(json_ifp_out
, "group",
1977 json_object_string_add(json_ifp_out
,
1980 json_object_string_add(json_ifp_out
,
1981 "outboundInterface",
1983 json_object_int_add(json_ifp_out
, "installed",
1986 json_object_object_add(json_ifp_in
, out_ifname
,
1991 vty_out(vty
, "%s(%c%c%c%c)", out_ifname
,
1992 (c_oil
->oif_flags
[oif_vif_index
]
1993 & PIM_OIF_FLAG_PROTO_IGMP
)
1996 (c_oil
->oif_flags
[oif_vif_index
]
1997 & PIM_OIF_FLAG_PROTO_PIM
)
2000 (c_oil
->oif_flags
[oif_vif_index
]
2001 & PIM_OIF_FLAG_PROTO_SOURCE
)
2004 (c_oil
->oif_flags
[oif_vif_index
]
2005 & PIM_OIF_FLAG_PROTO_STAR
)
2009 vty_out(vty
, ", %s(%c%c%c%c)",
2011 (c_oil
->oif_flags
[oif_vif_index
]
2012 & PIM_OIF_FLAG_PROTO_IGMP
)
2015 (c_oil
->oif_flags
[oif_vif_index
]
2016 & PIM_OIF_FLAG_PROTO_PIM
)
2019 (c_oil
->oif_flags
[oif_vif_index
]
2020 & PIM_OIF_FLAG_PROTO_SOURCE
)
2023 (c_oil
->oif_flags
[oif_vif_index
]
2024 & PIM_OIF_FLAG_PROTO_STAR
)
2036 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2037 json
, JSON_C_TO_STRING_PRETTY
));
2038 json_object_free(json
);
2044 static void pim_show_neighbors(struct vty
*vty
, u_char uj
)
2046 struct listnode
*node
;
2047 struct listnode
*neighnode
;
2048 struct interface
*ifp
;
2049 struct pim_interface
*pim_ifp
;
2050 struct pim_neighbor
*neigh
;
2054 char neigh_src_str
[INET_ADDRSTRLEN
];
2055 json_object
*json
= NULL
;
2056 json_object
*json_ifp_rows
= NULL
;
2057 json_object
*json_row
= NULL
;
2059 now
= pim_time_monotonic_sec();
2062 json
= json_object_new_object();
2065 "Interface Neighbor Uptime Holdtime DR Pri\n");
2068 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pimg
->vrf_id
), node
, ifp
)) {
2069 pim_ifp
= ifp
->info
;
2074 if (pim_ifp
->pim_sock_fd
< 0)
2078 json_ifp_rows
= json_object_new_object();
2080 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
2082 pim_inet4_dump("<src?>", neigh
->source_addr
,
2083 neigh_src_str
, sizeof(neigh_src_str
));
2084 pim_time_uptime(uptime
, sizeof(uptime
),
2085 now
- neigh
->creation
);
2086 pim_time_timer_to_hhmmss(expire
, sizeof(expire
),
2087 neigh
->t_expire_timer
);
2090 json_row
= json_object_new_object();
2091 json_object_string_add(json_row
, "interface",
2093 json_object_string_add(json_row
, "neighbor",
2095 json_object_string_add(json_row
, "upTime",
2097 json_object_string_add(json_row
, "holdTime",
2099 json_object_int_add(json_row
, "holdTimeMax",
2101 json_object_int_add(json_row
, "drPriority",
2102 neigh
->dr_priority
);
2103 json_object_object_add(json_ifp_rows
,
2104 neigh_src_str
, json_row
);
2107 vty_out(vty
, "%-9s %15s %8s %8s %6d\n",
2108 ifp
->name
, neigh_src_str
, uptime
,
2109 expire
, neigh
->dr_priority
);
2114 json_object_object_add(json
, ifp
->name
, json_ifp_rows
);
2115 json_ifp_rows
= NULL
;
2120 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2121 json
, JSON_C_TO_STRING_PRETTY
));
2122 json_object_free(json
);
2126 static void pim_show_neighbors_secondary(struct vty
*vty
)
2128 struct listnode
*node
;
2129 struct interface
*ifp
;
2132 "Interface Address Neighbor Secondary \n");
2134 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pimg
->vrf_id
), node
, ifp
)) {
2135 struct pim_interface
*pim_ifp
;
2136 struct in_addr ifaddr
;
2137 struct listnode
*neighnode
;
2138 struct pim_neighbor
*neigh
;
2140 pim_ifp
= ifp
->info
;
2145 if (pim_ifp
->pim_sock_fd
< 0)
2148 ifaddr
= pim_ifp
->primary_address
;
2150 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
2152 char neigh_src_str
[INET_ADDRSTRLEN
];
2153 struct listnode
*prefix_node
;
2156 if (!neigh
->prefix_list
)
2159 pim_inet4_dump("<src?>", neigh
->source_addr
,
2160 neigh_src_str
, sizeof(neigh_src_str
));
2162 for (ALL_LIST_ELEMENTS_RO(neigh
->prefix_list
,
2164 char neigh_sec_str
[PREFIX2STR_BUFFER
];
2166 prefix2str(p
, neigh_sec_str
,
2167 sizeof(neigh_sec_str
));
2169 vty_out(vty
, "%-9s %-15s %-15s %-15s\n",
2170 ifp
->name
, inet_ntoa(ifaddr
),
2171 neigh_src_str
, neigh_sec_str
);
2177 static void json_object_pim_upstream_add(json_object
*json
,
2178 struct pim_upstream
*up
)
2180 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED
)
2181 json_object_boolean_true_add(json
, "drJoinDesired");
2183 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED_UPDATED
)
2184 json_object_boolean_true_add(json
, "drJoinDesiredUpdated");
2186 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
)
2187 json_object_boolean_true_add(json
, "firstHopRouter");
2189 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_IGMP
)
2190 json_object_boolean_true_add(json
, "sourceIgmp");
2192 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_PIM
)
2193 json_object_boolean_true_add(json
, "sourcePim");
2195 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_STREAM
)
2196 json_object_boolean_true_add(json
, "sourceStream");
2198 /* XXX: need to print ths flag in the plain text display as well */
2199 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_MSDP
)
2200 json_object_boolean_true_add(json
, "sourceMsdp");
2204 pim_upstream_state2brief_str(enum pim_upstream_state join_state
,
2207 switch (join_state
) {
2208 case PIM_UPSTREAM_NOTJOINED
:
2209 strcpy(state_str
, "NotJ");
2211 case PIM_UPSTREAM_JOINED
:
2212 strcpy(state_str
, "J");
2215 strcpy(state_str
, "Unk");
2220 static const char *pim_reg_state2brief_str(enum pim_reg_state reg_state
,
2223 switch (reg_state
) {
2224 case PIM_REG_NOINFO
:
2225 strcpy(state_str
, "RegNI");
2228 strcpy(state_str
, "RegJ");
2230 case PIM_REG_JOIN_PENDING
:
2232 strcpy(state_str
, "RegP");
2235 strcpy(state_str
, "Unk");
2240 static void pim_show_upstream(struct vty
*vty
, u_char uj
)
2242 struct listnode
*upnode
;
2243 struct pim_upstream
*up
;
2245 json_object
*json
= NULL
;
2246 json_object
*json_group
= NULL
;
2247 json_object
*json_row
= NULL
;
2249 now
= pim_time_monotonic_sec();
2252 json
= json_object_new_object();
2255 "Iif Source Group State Uptime JoinTimer RSTimer KATimer RefCnt\n");
2257 for (ALL_LIST_ELEMENTS_RO(pimg
->upstream_list
, upnode
, up
)) {
2258 char src_str
[INET_ADDRSTRLEN
];
2259 char grp_str
[INET_ADDRSTRLEN
];
2261 char join_timer
[10];
2264 char msdp_reg_timer
[10];
2265 char state_str
[PIM_REG_STATE_STR_LEN
];
2267 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2268 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2269 pim_time_uptime(uptime
, sizeof(uptime
),
2270 now
- up
->state_transition
);
2271 pim_time_timer_to_hhmmss(join_timer
, sizeof(join_timer
),
2275 * If we have a J/P timer for the neighbor display that
2277 if (!up
->t_join_timer
) {
2278 struct pim_neighbor
*nbr
;
2280 nbr
= pim_neighbor_find(
2281 up
->rpf
.source_nexthop
.interface
,
2282 up
->rpf
.rpf_addr
.u
.prefix4
);
2284 pim_time_timer_to_hhmmss(join_timer
,
2289 pim_time_timer_to_hhmmss(rs_timer
, sizeof(rs_timer
),
2291 pim_time_timer_to_hhmmss(ka_timer
, sizeof(ka_timer
),
2293 pim_time_timer_to_hhmmss(msdp_reg_timer
, sizeof(msdp_reg_timer
),
2294 up
->t_msdp_reg_timer
);
2296 pim_upstream_state2brief_str(up
->join_state
, state_str
);
2297 if (up
->reg_state
!= PIM_REG_NOINFO
) {
2298 char tmp_str
[PIM_REG_STATE_STR_LEN
];
2300 sprintf(state_str
+ strlen(state_str
), ",%s",
2301 pim_reg_state2brief_str(up
->reg_state
,
2306 json_object_object_get_ex(json
, grp_str
, &json_group
);
2309 json_group
= json_object_new_object();
2310 json_object_object_add(json
, grp_str
,
2314 json_row
= json_object_new_object();
2315 json_object_pim_upstream_add(json_row
, up
);
2316 json_object_string_add(
2317 json_row
, "inboundInterface",
2318 up
->rpf
.source_nexthop
.interface
->name
);
2319 json_object_string_add(json_row
, "source", src_str
);
2320 json_object_string_add(json_row
, "group", grp_str
);
2321 json_object_string_add(json_row
, "state", state_str
);
2322 json_object_string_add(
2323 json_row
, "joinState",
2324 pim_upstream_state2str(up
->join_state
));
2325 json_object_string_add(
2326 json_row
, "regState",
2327 pim_reg_state2str(up
->reg_state
, state_str
));
2328 json_object_string_add(json_row
, "upTime", uptime
);
2329 json_object_string_add(json_row
, "joinTimer",
2331 json_object_string_add(json_row
, "resetTimer",
2333 json_object_string_add(json_row
, "keepaliveTimer",
2335 json_object_string_add(json_row
, "msdpRegTimer",
2337 json_object_int_add(json_row
, "refCount",
2339 json_object_int_add(json_row
, "sptBit", up
->sptbit
);
2340 json_object_object_add(json_group
, src_str
, json_row
);
2343 "%-10s%-15s %-15s %-11s %-8s %-9s %-9s %-9s %6d\n",
2344 up
->rpf
.source_nexthop
.interface
->name
, src_str
,
2345 grp_str
, state_str
, uptime
, join_timer
,
2346 rs_timer
, ka_timer
, up
->ref_count
);
2351 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2352 json
, JSON_C_TO_STRING_PRETTY
));
2353 json_object_free(json
);
2357 static void pim_show_join_desired(struct pim_instance
*pim
, struct vty
*vty
,
2360 struct listnode
*chnode
;
2361 struct pim_interface
*pim_ifp
;
2362 struct pim_ifchannel
*ch
;
2363 char src_str
[INET_ADDRSTRLEN
];
2364 char grp_str
[INET_ADDRSTRLEN
];
2365 json_object
*json
= NULL
;
2366 json_object
*json_group
= NULL
;
2367 json_object
*json_row
= NULL
;
2370 json
= json_object_new_object();
2373 "Interface Source Group LostAssert Joins PimInclude JoinDesired EvalJD\n");
2375 /* scan per-interface (S,G) state */
2376 for (ALL_LIST_ELEMENTS_RO(pim
->ifchannel_list
, chnode
, ch
)) {
2377 /* scan all interfaces */
2378 pim_ifp
= ch
->interface
->info
;
2382 struct pim_upstream
*up
= ch
->upstream
;
2384 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2385 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2388 json_object_object_get_ex(json
, grp_str
, &json_group
);
2391 json_group
= json_object_new_object();
2392 json_object_object_add(json
, grp_str
,
2396 json_row
= json_object_new_object();
2397 json_object_pim_upstream_add(json_row
, up
);
2398 json_object_string_add(json_row
, "interface",
2399 ch
->interface
->name
);
2400 json_object_string_add(json_row
, "source", src_str
);
2401 json_object_string_add(json_row
, "group", grp_str
);
2403 if (pim_macro_ch_lost_assert(ch
))
2404 json_object_boolean_true_add(json_row
,
2407 if (pim_macro_chisin_joins(ch
))
2408 json_object_boolean_true_add(json_row
, "joins");
2410 if (pim_macro_chisin_pim_include(ch
))
2411 json_object_boolean_true_add(json_row
,
2414 if (pim_upstream_evaluate_join_desired(pimg
, up
))
2415 json_object_boolean_true_add(
2416 json_row
, "evaluateJoinDesired");
2418 json_object_object_add(json_group
, src_str
, json_row
);
2422 "%-9s %-15s %-15s %-10s %-5s %-10s %-11s %-6s\n",
2423 ch
->interface
->name
, src_str
, grp_str
,
2424 pim_macro_ch_lost_assert(ch
) ? "yes" : "no",
2425 pim_macro_chisin_joins(ch
) ? "yes" : "no",
2426 pim_macro_chisin_pim_include(ch
) ? "yes" : "no",
2427 PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED(
2431 pim_upstream_evaluate_join_desired(pimg
, up
)
2438 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2439 json
, JSON_C_TO_STRING_PRETTY
));
2440 json_object_free(json
);
2444 static void pim_show_upstream_rpf(struct vty
*vty
, u_char uj
)
2446 struct listnode
*upnode
;
2447 struct pim_upstream
*up
;
2448 json_object
*json
= NULL
;
2449 json_object
*json_group
= NULL
;
2450 json_object
*json_row
= NULL
;
2453 json
= json_object_new_object();
2456 "Source Group RpfIface RibNextHop RpfAddress \n");
2458 for (ALL_LIST_ELEMENTS_RO(pimg
->upstream_list
, upnode
, up
)) {
2459 char src_str
[INET_ADDRSTRLEN
];
2460 char grp_str
[INET_ADDRSTRLEN
];
2461 char rpf_nexthop_str
[PREFIX_STRLEN
];
2462 char rpf_addr_str
[PREFIX_STRLEN
];
2463 struct pim_rpf
*rpf
;
2464 const char *rpf_ifname
;
2468 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2469 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2470 pim_addr_dump("<nexthop?>",
2471 &rpf
->source_nexthop
.mrib_nexthop_addr
,
2472 rpf_nexthop_str
, sizeof(rpf_nexthop_str
));
2473 pim_addr_dump("<rpf?>", &rpf
->rpf_addr
, rpf_addr_str
,
2474 sizeof(rpf_addr_str
));
2476 rpf_ifname
= rpf
->source_nexthop
.interface
? rpf
->source_nexthop
.interface
->name
: "<ifname?>";
2479 json_object_object_get_ex(json
, grp_str
, &json_group
);
2482 json_group
= json_object_new_object();
2483 json_object_object_add(json
, grp_str
,
2487 json_row
= json_object_new_object();
2488 json_object_pim_upstream_add(json_row
, up
);
2489 json_object_string_add(json_row
, "source", src_str
);
2490 json_object_string_add(json_row
, "group", grp_str
);
2491 json_object_string_add(json_row
, "rpfInterface",
2493 json_object_string_add(json_row
, "ribNexthop",
2495 json_object_string_add(json_row
, "rpfAddress",
2497 json_object_object_add(json_group
, src_str
, json_row
);
2499 vty_out(vty
, "%-15s %-15s %-8s %-15s %-15s\n", src_str
,
2500 grp_str
, rpf_ifname
, rpf_nexthop_str
,
2506 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2507 json
, JSON_C_TO_STRING_PRETTY
));
2508 json_object_free(json
);
2512 static void show_rpf_refresh_stats(struct vty
*vty
, time_t now
,
2515 char refresh_uptime
[10];
2517 pim_time_uptime_begin(refresh_uptime
, sizeof(refresh_uptime
), now
,
2518 qpim_rpf_cache_refresh_last
);
2521 json_object_int_add(json
, "rpfCacheRefreshDelayMsecs",
2522 qpim_rpf_cache_refresh_delay_msec
);
2523 json_object_int_add(
2524 json
, "rpfCacheRefreshTimer",
2525 pim_time_timer_remain_msec(qpim_rpf_cache_refresher
));
2526 json_object_int_add(json
, "rpfCacheRefreshRequests",
2527 qpim_rpf_cache_refresh_requests
);
2528 json_object_int_add(json
, "rpfCacheRefreshEvents",
2529 qpim_rpf_cache_refresh_events
);
2530 json_object_string_add(json
, "rpfCacheRefreshLast",
2532 json_object_int_add(json
, "nexthopLookups",
2533 qpim_nexthop_lookups
);
2534 json_object_int_add(json
, "nexthopLookupsAvoided",
2535 nexthop_lookups_avoided
);
2538 "RPF Cache Refresh Delay: %ld msecs\n"
2539 "RPF Cache Refresh Timer: %ld msecs\n"
2540 "RPF Cache Refresh Requests: %lld\n"
2541 "RPF Cache Refresh Events: %lld\n"
2542 "RPF Cache Refresh Last: %s\n"
2543 "Nexthop Lookups: %lld\n"
2544 "Nexthop Lookups Avoided: %lld\n",
2545 qpim_rpf_cache_refresh_delay_msec
,
2546 pim_time_timer_remain_msec(qpim_rpf_cache_refresher
),
2547 (long long)qpim_rpf_cache_refresh_requests
,
2548 (long long)qpim_rpf_cache_refresh_events
,
2549 refresh_uptime
, (long long)qpim_nexthop_lookups
,
2550 (long long)nexthop_lookups_avoided
);
2554 static void show_scan_oil_stats(struct vty
*vty
, time_t now
)
2556 char uptime_scan_oil
[10];
2557 char uptime_mroute_add
[10];
2558 char uptime_mroute_del
[10];
2560 pim_time_uptime_begin(uptime_scan_oil
, sizeof(uptime_scan_oil
), now
,
2561 qpim_scan_oil_last
);
2562 pim_time_uptime_begin(uptime_mroute_add
, sizeof(uptime_mroute_add
), now
,
2563 pimg
->mroute_add_last
);
2564 pim_time_uptime_begin(uptime_mroute_del
, sizeof(uptime_mroute_del
), now
,
2565 pimg
->mroute_del_last
);
2568 "Scan OIL - Last: %s Events: %lld\n"
2569 "MFC Add - Last: %s Events: %lld\n"
2570 "MFC Del - Last: %s Events: %lld\n",
2571 uptime_scan_oil
, (long long)qpim_scan_oil_events
,
2572 uptime_mroute_add
, (long long)pimg
->mroute_add_events
,
2573 uptime_mroute_del
, (long long)pimg
->mroute_del_events
);
2576 static void pim_show_rpf(struct vty
*vty
, u_char uj
)
2578 struct listnode
*up_node
;
2579 struct pim_upstream
*up
;
2580 time_t now
= pim_time_monotonic_sec();
2581 json_object
*json
= NULL
;
2582 json_object
*json_group
= NULL
;
2583 json_object
*json_row
= NULL
;
2586 json
= json_object_new_object();
2587 show_rpf_refresh_stats(vty
, now
, json
);
2589 show_rpf_refresh_stats(vty
, now
, json
);
2592 "Source Group RpfIface RpfAddress RibNextHop Metric Pref\n");
2595 for (ALL_LIST_ELEMENTS_RO(pimg
->upstream_list
, up_node
, up
)) {
2596 char src_str
[INET_ADDRSTRLEN
];
2597 char grp_str
[INET_ADDRSTRLEN
];
2598 char rpf_addr_str
[PREFIX_STRLEN
];
2599 char rib_nexthop_str
[PREFIX_STRLEN
];
2600 const char *rpf_ifname
;
2601 struct pim_rpf
*rpf
= &up
->rpf
;
2603 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2604 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2605 pim_addr_dump("<rpf?>", &rpf
->rpf_addr
, rpf_addr_str
,
2606 sizeof(rpf_addr_str
));
2607 pim_addr_dump("<nexthop?>",
2608 &rpf
->source_nexthop
.mrib_nexthop_addr
,
2609 rib_nexthop_str
, sizeof(rib_nexthop_str
));
2611 rpf_ifname
= rpf
->source_nexthop
.interface
? rpf
->source_nexthop
.interface
->name
: "<ifname?>";
2614 json_object_object_get_ex(json
, grp_str
, &json_group
);
2617 json_group
= json_object_new_object();
2618 json_object_object_add(json
, grp_str
,
2622 json_row
= json_object_new_object();
2623 json_object_string_add(json_row
, "source", src_str
);
2624 json_object_string_add(json_row
, "group", grp_str
);
2625 json_object_string_add(json_row
, "rpfInterface",
2627 json_object_string_add(json_row
, "rpfAddress",
2629 json_object_string_add(json_row
, "ribNexthop",
2631 json_object_int_add(
2632 json_row
, "routeMetric",
2633 rpf
->source_nexthop
.mrib_route_metric
);
2634 json_object_int_add(
2635 json_row
, "routePreference",
2636 rpf
->source_nexthop
.mrib_metric_preference
);
2637 json_object_object_add(json_group
, src_str
, json_row
);
2640 vty_out(vty
, "%-15s %-15s %-8s %-15s %-15s %6d %4d\n",
2641 src_str
, grp_str
, rpf_ifname
, rpf_addr_str
,
2643 rpf
->source_nexthop
.mrib_route_metric
,
2644 rpf
->source_nexthop
.mrib_metric_preference
);
2649 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2650 json
, JSON_C_TO_STRING_PRETTY
));
2651 json_object_free(json
);
2655 static int pim_print_pnc_cache_walkcb(struct hash_backet
*backet
, void *arg
)
2657 struct pim_nexthop_cache
*pnc
= backet
->data
;
2658 struct vty
*vty
= arg
;
2659 struct nexthop
*nh_node
= NULL
;
2660 ifindex_t first_ifindex
;
2661 struct interface
*ifp
= NULL
;
2666 for (nh_node
= pnc
->nexthop
; nh_node
; nh_node
= nh_node
->next
) {
2667 first_ifindex
= nh_node
->ifindex
;
2668 ifp
= if_lookup_by_index(first_ifindex
, pimg
->vrf_id
);
2670 vty_out(vty
, "%-15s ", inet_ntoa(pnc
->rpf
.rpf_addr
.u
.prefix4
));
2671 vty_out(vty
, "%-14s ", ifp
? ifp
->name
: "NULL");
2672 vty_out(vty
, "%s ", inet_ntoa(nh_node
->gate
.ipv4
));
2678 static void pim_show_nexthop(struct vty
*vty
)
2681 if (pimg
&& !pimg
->rpf_hash
) {
2682 vty_out(vty
, "no nexthop cache \n");
2686 vty_out(vty
, "Number of registered addresses: %lu \n",
2687 pimg
->rpf_hash
->count
);
2688 vty_out(vty
, "Address Interface Nexthop\n");
2689 vty_out(vty
, "-------------------------------------------\n");
2691 hash_walk(pimg
->rpf_hash
, pim_print_pnc_cache_walkcb
, vty
);
2694 static void igmp_show_groups(struct vty
*vty
, u_char uj
)
2696 struct listnode
*ifnode
;
2697 struct interface
*ifp
;
2699 json_object
*json
= NULL
;
2700 json_object
*json_iface
= NULL
;
2701 json_object
*json_row
= NULL
;
2703 now
= pim_time_monotonic_sec();
2706 json
= json_object_new_object();
2709 "Interface Address Group Mode Timer Srcs V Uptime \n");
2711 /* scan interfaces */
2712 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pimg
->vrf_id
), ifnode
, ifp
)) {
2713 struct pim_interface
*pim_ifp
= ifp
->info
;
2714 struct listnode
*sock_node
;
2715 struct igmp_sock
*igmp
;
2720 /* scan igmp sockets */
2721 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
2723 char ifaddr_str
[INET_ADDRSTRLEN
];
2724 struct listnode
*grpnode
;
2725 struct igmp_group
*grp
;
2727 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
2728 sizeof(ifaddr_str
));
2730 /* scan igmp groups */
2731 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
2733 char group_str
[INET_ADDRSTRLEN
];
2737 pim_inet4_dump("<group?>", grp
->group_addr
,
2738 group_str
, sizeof(group_str
));
2739 pim_time_timer_to_hhmmss(hhmmss
, sizeof(hhmmss
),
2740 grp
->t_group_timer
);
2741 pim_time_uptime(uptime
, sizeof(uptime
),
2742 now
- grp
->group_creation
);
2745 json_object_object_get_ex(
2746 json
, ifp
->name
, &json_iface
);
2750 json_object_new_object();
2751 json_object_pim_ifp_add(
2753 json_object_object_add(
2758 json_row
= json_object_new_object();
2759 json_object_string_add(
2760 json_row
, "source", ifaddr_str
);
2761 json_object_string_add(
2762 json_row
, "group", group_str
);
2764 if (grp
->igmp_version
== 3)
2765 json_object_string_add(
2767 grp
->group_filtermode_isexcl
2771 json_object_string_add(json_row
,
2773 json_object_int_add(
2774 json_row
, "sourcesCount",
2775 grp
->group_source_list
2777 grp
->group_source_list
)
2779 json_object_int_add(json_row
, "version",
2781 json_object_string_add(
2782 json_row
, "uptime", uptime
);
2783 json_object_object_add(json_iface
,
2789 "%-9s %-15s %-15s %4s %8s %4d %d %8s\n",
2790 ifp
->name
, ifaddr_str
,
2792 grp
->igmp_version
== 3
2793 ? (grp
->group_filtermode_isexcl
2798 grp
->group_source_list
2800 grp
->group_source_list
)
2802 grp
->igmp_version
, uptime
);
2804 } /* scan igmp groups */
2805 } /* scan igmp sockets */
2806 } /* scan interfaces */
2809 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2810 json
, JSON_C_TO_STRING_PRETTY
));
2811 json_object_free(json
);
2815 static void igmp_show_group_retransmission(struct vty
*vty
)
2817 struct listnode
*ifnode
;
2818 struct interface
*ifp
;
2821 "Interface Address Group RetTimer Counter RetSrcs\n");
2823 /* scan interfaces */
2824 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pimg
->vrf_id
), ifnode
, ifp
)) {
2825 struct pim_interface
*pim_ifp
= ifp
->info
;
2826 struct listnode
*sock_node
;
2827 struct igmp_sock
*igmp
;
2832 /* scan igmp sockets */
2833 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
2835 char ifaddr_str
[INET_ADDRSTRLEN
];
2836 struct listnode
*grpnode
;
2837 struct igmp_group
*grp
;
2839 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
2840 sizeof(ifaddr_str
));
2842 /* scan igmp groups */
2843 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
2845 char group_str
[INET_ADDRSTRLEN
];
2846 char grp_retr_mmss
[10];
2847 struct listnode
*src_node
;
2848 struct igmp_source
*src
;
2849 int grp_retr_sources
= 0;
2851 pim_inet4_dump("<group?>", grp
->group_addr
,
2852 group_str
, sizeof(group_str
));
2853 pim_time_timer_to_mmss(
2854 grp_retr_mmss
, sizeof(grp_retr_mmss
),
2855 grp
->t_group_query_retransmit_timer
);
2858 /* count group sources with retransmission state
2860 for (ALL_LIST_ELEMENTS_RO(
2861 grp
->group_source_list
, src_node
,
2863 if (src
->source_query_retransmit_count
2869 vty_out(vty
, "%-9s %-15s %-15s %-8s %7d %7d\n",
2870 ifp
->name
, ifaddr_str
, group_str
,
2872 grp
->group_specific_query_retransmit_count
,
2875 } /* scan igmp groups */
2876 } /* scan igmp sockets */
2877 } /* scan interfaces */
2880 static void igmp_show_sources(struct vty
*vty
)
2882 struct listnode
*ifnode
;
2883 struct interface
*ifp
;
2886 now
= pim_time_monotonic_sec();
2889 "Interface Address Group Source Timer Fwd Uptime \n");
2891 /* scan interfaces */
2892 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pimg
->vrf_id
), ifnode
, ifp
)) {
2893 struct pim_interface
*pim_ifp
= ifp
->info
;
2894 struct listnode
*sock_node
;
2895 struct igmp_sock
*igmp
;
2900 /* scan igmp sockets */
2901 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
2903 char ifaddr_str
[INET_ADDRSTRLEN
];
2904 struct listnode
*grpnode
;
2905 struct igmp_group
*grp
;
2907 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
2908 sizeof(ifaddr_str
));
2910 /* scan igmp groups */
2911 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
2913 char group_str
[INET_ADDRSTRLEN
];
2914 struct listnode
*srcnode
;
2915 struct igmp_source
*src
;
2917 pim_inet4_dump("<group?>", grp
->group_addr
,
2918 group_str
, sizeof(group_str
));
2920 /* scan group sources */
2921 for (ALL_LIST_ELEMENTS_RO(
2922 grp
->group_source_list
, srcnode
,
2924 char source_str
[INET_ADDRSTRLEN
];
2929 "<source?>", src
->source_addr
,
2930 source_str
, sizeof(source_str
));
2932 pim_time_timer_to_mmss(
2934 src
->t_source_timer
);
2937 uptime
, sizeof(uptime
),
2938 now
- src
->source_creation
);
2941 "%-9s %-15s %-15s %-15s %5s %3s %8s\n",
2942 ifp
->name
, ifaddr_str
,
2943 group_str
, source_str
, mmss
,
2944 IGMP_SOURCE_TEST_FORWARDING(
2950 } /* scan group sources */
2951 } /* scan igmp groups */
2952 } /* scan igmp sockets */
2953 } /* scan interfaces */
2956 static void igmp_show_source_retransmission(struct vty
*vty
)
2958 struct listnode
*ifnode
;
2959 struct interface
*ifp
;
2962 "Interface Address Group Source Counter\n");
2964 /* scan interfaces */
2965 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pimg
->vrf_id
), ifnode
, ifp
)) {
2966 struct pim_interface
*pim_ifp
= ifp
->info
;
2967 struct listnode
*sock_node
;
2968 struct igmp_sock
*igmp
;
2973 /* scan igmp sockets */
2974 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
2976 char ifaddr_str
[INET_ADDRSTRLEN
];
2977 struct listnode
*grpnode
;
2978 struct igmp_group
*grp
;
2980 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
2981 sizeof(ifaddr_str
));
2983 /* scan igmp groups */
2984 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
2986 char group_str
[INET_ADDRSTRLEN
];
2987 struct listnode
*srcnode
;
2988 struct igmp_source
*src
;
2990 pim_inet4_dump("<group?>", grp
->group_addr
,
2991 group_str
, sizeof(group_str
));
2993 /* scan group sources */
2994 for (ALL_LIST_ELEMENTS_RO(
2995 grp
->group_source_list
, srcnode
,
2997 char source_str
[INET_ADDRSTRLEN
];
3000 "<source?>", src
->source_addr
,
3001 source_str
, sizeof(source_str
));
3004 "%-9s %-15s %-15s %-15s %7d\n",
3005 ifp
->name
, ifaddr_str
,
3006 group_str
, source_str
,
3007 src
->source_query_retransmit_count
);
3009 } /* scan group sources */
3010 } /* scan igmp groups */
3011 } /* scan igmp sockets */
3012 } /* scan interfaces */
3015 static void clear_igmp_interfaces()
3017 struct listnode
*ifnode
;
3018 struct listnode
*ifnextnode
;
3019 struct interface
*ifp
;
3021 for (ALL_LIST_ELEMENTS(vrf_iflist(pimg
->vrf_id
), ifnode
, ifnextnode
,
3023 pim_if_addr_del_all_igmp(ifp
);
3026 for (ALL_LIST_ELEMENTS(vrf_iflist(pimg
->vrf_id
), ifnode
, ifnextnode
,
3028 pim_if_addr_add_all(ifp
);
3032 static void clear_pim_interfaces()
3034 struct listnode
*ifnode
;
3035 struct listnode
*ifnextnode
;
3036 struct interface
*ifp
;
3038 for (ALL_LIST_ELEMENTS(vrf_iflist(pimg
->vrf_id
), ifnode
, ifnextnode
,
3041 pim_neighbor_delete_all(ifp
, "interface cleared");
3046 static void clear_interfaces()
3048 clear_igmp_interfaces();
3049 clear_pim_interfaces();
3052 DEFUN (clear_ip_interfaces
,
3053 clear_ip_interfaces_cmd
,
3054 "clear ip interfaces",
3057 "Reset interfaces\n")
3064 DEFUN (clear_ip_igmp_interfaces
,
3065 clear_ip_igmp_interfaces_cmd
,
3066 "clear ip igmp interfaces",
3070 "Reset IGMP interfaces\n")
3072 clear_igmp_interfaces();
3077 static void mroute_add_all()
3079 struct listnode
*node
;
3080 struct channel_oil
*c_oil
;
3082 for (ALL_LIST_ELEMENTS_RO(pim_channel_oil_list
, node
, c_oil
)) {
3083 if (pim_mroute_add(c_oil
, __PRETTY_FUNCTION__
)) {
3084 /* just log warning */
3085 char source_str
[INET_ADDRSTRLEN
];
3086 char group_str
[INET_ADDRSTRLEN
];
3087 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
,
3088 source_str
, sizeof(source_str
));
3089 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
,
3090 group_str
, sizeof(group_str
));
3091 zlog_warn("%s %s: (S,G)=(%s,%s) failure writing MFC",
3092 __FILE__
, __PRETTY_FUNCTION__
, source_str
,
3098 static void mroute_del_all()
3100 struct listnode
*node
;
3101 struct channel_oil
*c_oil
;
3103 for (ALL_LIST_ELEMENTS_RO(pim_channel_oil_list
, node
, c_oil
)) {
3104 if (pim_mroute_del(c_oil
, __PRETTY_FUNCTION__
)) {
3105 /* just log warning */
3106 char source_str
[INET_ADDRSTRLEN
];
3107 char group_str
[INET_ADDRSTRLEN
];
3108 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
,
3109 source_str
, sizeof(source_str
));
3110 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
,
3111 group_str
, sizeof(group_str
));
3112 zlog_warn("%s %s: (S,G)=(%s,%s) failure clearing MFC",
3113 __FILE__
, __PRETTY_FUNCTION__
, source_str
,
3119 DEFUN (clear_ip_mroute
,
3120 clear_ip_mroute_cmd
,
3124 "Reset multicast routes\n")
3132 DEFUN (clear_ip_pim_interfaces
,
3133 clear_ip_pim_interfaces_cmd
,
3134 "clear ip pim interfaces",
3138 "Reset PIM interfaces\n")
3140 clear_pim_interfaces();
3145 DEFUN (clear_ip_pim_interface_traffic
,
3146 clear_ip_pim_interface_traffic_cmd
,
3147 "clear ip pim interface traffic",
3150 "PIM clear commands\n"
3151 "Reset PIM interfaces\n"
3152 "Reset Protocol Packet counters\n")
3154 struct listnode
*ifnode
= NULL
;
3155 struct listnode
*ifnextnode
= NULL
;
3156 struct interface
*ifp
= NULL
;
3157 struct pim_interface
*pim_ifp
= NULL
;
3159 for (ALL_LIST_ELEMENTS(vrf_iflist(pimg
->vrf_id
), ifnode
, ifnextnode
,
3161 pim_ifp
= ifp
->info
;
3166 pim_ifp
->pim_ifstat_hello_recv
= 0;
3167 pim_ifp
->pim_ifstat_hello_sent
= 0;
3168 pim_ifp
->pim_ifstat_join_recv
= 0;
3169 pim_ifp
->pim_ifstat_join_send
= 0;
3170 pim_ifp
->pim_ifstat_prune_recv
= 0;
3171 pim_ifp
->pim_ifstat_prune_send
= 0;
3172 pim_ifp
->pim_ifstat_reg_recv
= 0;
3173 pim_ifp
->pim_ifstat_reg_send
= 0;
3174 pim_ifp
->pim_ifstat_reg_stop_recv
= 0;
3175 pim_ifp
->pim_ifstat_reg_stop_send
= 0;
3176 pim_ifp
->pim_ifstat_assert_recv
= 0;
3177 pim_ifp
->pim_ifstat_assert_send
= 0;
3183 DEFUN (clear_ip_pim_oil
,
3184 clear_ip_pim_oil_cmd
,
3189 "Rescan PIM OIL (output interface list)\n")
3196 DEFUN (show_ip_igmp_interface
,
3197 show_ip_igmp_interface_cmd
,
3198 "show ip igmp interface [detail|WORD] [json]",
3202 "IGMP interface information\n"
3205 "JavaScript Object Notation\n")
3207 u_char uj
= use_json(argc
, argv
);
3210 if (argv_find(argv
, argc
, "detail", &idx
)
3211 || argv_find(argv
, argc
, "WORD", &idx
))
3212 igmp_show_interfaces_single(vty
, argv
[idx
]->arg
, uj
);
3214 igmp_show_interfaces(vty
, uj
);
3219 DEFUN (show_ip_igmp_join
,
3220 show_ip_igmp_join_cmd
,
3221 "show ip igmp join",
3225 "IGMP static join information\n")
3227 igmp_show_interface_join(vty
);
3232 DEFUN (show_ip_igmp_groups
,
3233 show_ip_igmp_groups_cmd
,
3234 "show ip igmp groups [json]",
3239 "JavaScript Object Notation\n")
3241 u_char uj
= use_json(argc
, argv
);
3242 igmp_show_groups(vty
, uj
);
3247 DEFUN (show_ip_igmp_groups_retransmissions
,
3248 show_ip_igmp_groups_retransmissions_cmd
,
3249 "show ip igmp groups retransmissions",
3254 "IGMP group retransmissions\n")
3256 igmp_show_group_retransmission(vty
);
3261 DEFUN (show_ip_igmp_sources
,
3262 show_ip_igmp_sources_cmd
,
3263 "show ip igmp sources",
3269 igmp_show_sources(vty
);
3274 DEFUN (show_ip_igmp_sources_retransmissions
,
3275 show_ip_igmp_sources_retransmissions_cmd
,
3276 "show ip igmp sources retransmissions",
3281 "IGMP source retransmissions\n")
3283 igmp_show_source_retransmission(vty
);
3288 DEFUN (show_ip_pim_assert
,
3289 show_ip_pim_assert_cmd
,
3290 "show ip pim assert",
3294 "PIM interface assert\n")
3296 pim_show_assert(pimg
, vty
);
3301 DEFUN (show_ip_pim_assert_internal
,
3302 show_ip_pim_assert_internal_cmd
,
3303 "show ip pim assert-internal",
3307 "PIM interface internal assert state\n")
3309 pim_show_assert_internal(pimg
, vty
);
3314 DEFUN (show_ip_pim_assert_metric
,
3315 show_ip_pim_assert_metric_cmd
,
3316 "show ip pim assert-metric",
3320 "PIM interface assert metric\n")
3322 pim_show_assert_metric(pimg
, vty
);
3327 DEFUN (show_ip_pim_assert_winner_metric
,
3328 show_ip_pim_assert_winner_metric_cmd
,
3329 "show ip pim assert-winner-metric",
3333 "PIM interface assert winner metric\n")
3335 pim_show_assert_winner_metric(pimg
, vty
);
3340 DEFUN (show_ip_pim_interface
,
3341 show_ip_pim_interface_cmd
,
3342 "show ip pim interface [detail|WORD] [json]",
3346 "PIM interface information\n"
3349 "JavaScript Object Notation\n")
3351 u_char uj
= use_json(argc
, argv
);
3354 if (argv_find(argv
, argc
, "WORD", &idx
)
3355 || argv_find(argv
, argc
, "detail", &idx
))
3356 pim_show_interfaces_single(vty
, argv
[idx
]->arg
, uj
);
3359 pim_show_interfaces(vty
, uj
);
3364 DEFUN (show_ip_pim_join
,
3365 show_ip_pim_join_cmd
,
3366 "show ip pim join [json]",
3370 "PIM interface join information\n"
3373 u_char uj
= use_json(argc
, argv
);
3374 pim_show_join(pimg
, vty
, uj
);
3379 DEFUN (show_ip_pim_local_membership
,
3380 show_ip_pim_local_membership_cmd
,
3381 "show ip pim local-membership [json]",
3385 "PIM interface local-membership\n"
3388 u_char uj
= use_json(argc
, argv
);
3389 pim_show_membership(pimg
, vty
, uj
);
3394 DEFUN (show_ip_pim_neighbor
,
3395 show_ip_pim_neighbor_cmd
,
3396 "show ip pim neighbor [detail|WORD] [json]",
3400 "PIM neighbor information\n"
3402 "Name of interface or neighbor\n"
3403 "JavaScript Object Notation\n")
3405 u_char uj
= use_json(argc
, argv
);
3408 if (argv_find(argv
, argc
, "detail", &idx
)
3409 || argv_find(argv
, argc
, "WORD", &idx
))
3410 pim_show_neighbors_single(vty
, argv
[idx
]->arg
, uj
);
3412 pim_show_neighbors(vty
, uj
);
3417 DEFUN (show_ip_pim_secondary
,
3418 show_ip_pim_secondary_cmd
,
3419 "show ip pim secondary",
3423 "PIM neighbor addresses\n")
3425 pim_show_neighbors_secondary(vty
);
3430 DEFUN (show_ip_pim_state
,
3431 show_ip_pim_state_cmd
,
3432 "show ip pim state [A.B.C.D [A.B.C.D]] [json]",
3436 "PIM state information\n"
3437 "Unicast or Multicast address\n"
3438 "Multicast address\n"
3439 "JavaScript Object Notation\n")
3441 const char *src_or_group
= NULL
;
3442 const char *group
= NULL
;
3443 u_char uj
= use_json(argc
, argv
);
3448 src_or_group
= argv
[4]->arg
;
3449 group
= argv
[5]->arg
;
3450 } else if (argc
== 5)
3451 src_or_group
= argv
[4]->arg
;
3453 pim_show_state(pimg
, vty
, src_or_group
, group
, uj
);
3458 DEFUN (show_ip_pim_upstream
,
3459 show_ip_pim_upstream_cmd
,
3460 "show ip pim upstream [json]",
3464 "PIM upstream information\n"
3465 "JavaScript Object Notation\n")
3467 u_char uj
= use_json(argc
, argv
);
3468 pim_show_upstream(vty
, uj
);
3473 DEFUN (show_ip_pim_upstream_join_desired
,
3474 show_ip_pim_upstream_join_desired_cmd
,
3475 "show ip pim upstream-join-desired [json]",
3479 "PIM upstream join-desired\n"
3480 "JavaScript Object Notation\n")
3482 u_char uj
= use_json(argc
, argv
);
3483 pim_show_join_desired(pimg
, vty
, uj
);
3488 DEFUN (show_ip_pim_upstream_rpf
,
3489 show_ip_pim_upstream_rpf_cmd
,
3490 "show ip pim upstream-rpf [json]",
3494 "PIM upstream source rpf\n"
3495 "JavaScript Object Notation\n")
3497 u_char uj
= use_json(argc
, argv
);
3498 pim_show_upstream_rpf(vty
, uj
);
3503 DEFUN (show_ip_pim_rp
,
3505 "show ip pim rp-info [json]",
3509 "PIM RP information\n"
3510 "JavaScript Object Notation\n")
3512 u_char uj
= use_json(argc
, argv
);
3513 pim_rp_show_information(pimg
, vty
, uj
);
3518 DEFUN (show_ip_pim_rpf
,
3519 show_ip_pim_rpf_cmd
,
3520 "show ip pim rpf [json]",
3524 "PIM cached source rpf information\n"
3525 "JavaScript Object Notation\n")
3527 u_char uj
= use_json(argc
, argv
);
3528 pim_show_rpf(vty
, uj
);
3533 DEFUN (show_ip_pim_nexthop
,
3534 show_ip_pim_nexthop_cmd
,
3535 "show ip pim nexthop",
3539 "PIM cached nexthop rpf information\n")
3541 pim_show_nexthop(vty
);
3546 DEFUN (show_ip_pim_nexthop_lookup
,
3547 show_ip_pim_nexthop_lookup_cmd
,
3548 "show ip pim nexthop-lookup A.B.C.D A.B.C.D",
3552 "PIM cached nexthop rpf lookup\n"
3553 "Source/RP address\n"
3554 "Multicast Group address\n")
3556 struct pim_nexthop_cache pnc
;
3557 struct prefix nht_p
;
3559 struct in_addr src_addr
, grp_addr
;
3560 struct in_addr vif_source
;
3561 const char *addr_str
, *addr_str1
;
3563 struct pim_nexthop nexthop
;
3564 char nexthop_addr_str
[PREFIX_STRLEN
];
3565 char grp_str
[PREFIX_STRLEN
];
3567 addr_str
= argv
[4]->arg
;
3568 result
= inet_pton(AF_INET
, addr_str
, &src_addr
);
3570 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
3571 errno
, safe_strerror(errno
));
3575 if (pim_is_group_224_4(src_addr
)) {
3577 "Invalid argument. Expected Valid Source Address.\n");
3581 addr_str1
= argv
[5]->arg
;
3582 result
= inet_pton(AF_INET
, addr_str1
, &grp_addr
);
3584 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
3585 errno
, safe_strerror(errno
));
3589 if (!pim_is_group_224_4(grp_addr
)) {
3591 "Invalid argument. Expected Valid Multicast Group Address.\n");
3595 if (!pim_rp_set_upstream_addr(pimg
, &vif_source
, src_addr
, grp_addr
))
3598 memset(&pnc
, 0, sizeof(struct pim_nexthop_cache
));
3599 nht_p
.family
= AF_INET
;
3600 nht_p
.prefixlen
= IPV4_MAX_BITLEN
;
3601 nht_p
.u
.prefix4
= vif_source
;
3602 grp
.family
= AF_INET
;
3603 grp
.prefixlen
= IPV4_MAX_BITLEN
;
3604 grp
.u
.prefix4
= grp_addr
;
3605 memset(&nexthop
, 0, sizeof(nexthop
));
3607 if (pim_find_or_track_nexthop(pimg
, &nht_p
, NULL
, NULL
, &pnc
))
3608 pim_ecmp_nexthop_search(pimg
, &pnc
, &nexthop
, &nht_p
, &grp
, 0);
3610 pim_ecmp_nexthop_lookup(pimg
, &nexthop
, vif_source
, &nht_p
,
3613 pim_addr_dump("<grp?>", &grp
, grp_str
, sizeof(grp_str
));
3614 pim_addr_dump("<nexthop?>", &nexthop
.mrib_nexthop_addr
,
3615 nexthop_addr_str
, sizeof(nexthop_addr_str
));
3616 vty_out(vty
, "Group %s --- Nexthop %s Interface %s \n", grp_str
,
3617 nexthop_addr_str
, nexthop
.interface
->name
);
3622 DEFUN (show_ip_pim_interface_traffic
,
3623 show_ip_pim_interface_traffic_cmd
,
3624 "show ip pim interface traffic [WORD] [json]",
3628 "PIM interface information\n"
3629 "Protocol Packet counters\n"
3631 "JavaScript Object Notation\n")
3633 u_char uj
= use_json(argc
, argv
);
3636 if (argv_find(argv
, argc
, "WORD", &idx
))
3637 pim_show_interface_traffic_single(vty
, argv
[idx
]->arg
, uj
);
3639 pim_show_interface_traffic(vty
, uj
);
3644 static void show_multicast_interfaces(struct vty
*vty
)
3646 struct listnode
*node
;
3647 struct interface
*ifp
;
3648 struct pim_instance
*pim
;
3654 "Interface Address ifi Vif PktsIn PktsOut BytesIn BytesOut VRF\n");
3656 RB_FOREACH(vrf
, vrf_name_head
, &vrfs_by_name
)
3662 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim
->vrf_id
), node
, ifp
)) {
3663 struct pim_interface
*pim_ifp
;
3664 struct in_addr ifaddr
;
3665 struct sioc_vif_req vreq
;
3667 pim_ifp
= ifp
->info
;
3672 memset(&vreq
, 0, sizeof(vreq
));
3673 vreq
.vifi
= pim_ifp
->mroute_vif_index
;
3675 if (ioctl(pim
->mroute_socket
, SIOCGETVIFCNT
, &vreq
)) {
3677 "ioctl(SIOCGETVIFCNT=%lu) failure for interface %s vif_index=%d: errno=%d: %s",
3678 (unsigned long)SIOCGETVIFCNT
, ifp
->name
,
3679 pim_ifp
->mroute_vif_index
, errno
,
3680 safe_strerror(errno
));
3683 ifaddr
= pim_ifp
->primary_address
;
3686 "%-12s %-15s %3d %3d %7lu %7lu %10lu %10lu %s\n",
3687 ifp
->name
, inet_ntoa(ifaddr
), ifp
->ifindex
,
3688 pim_ifp
->mroute_vif_index
,
3689 (unsigned long)vreq
.icount
,
3690 (unsigned long)vreq
.ocount
,
3691 (unsigned long)vreq
.ibytes
,
3692 (unsigned long)vreq
.obytes
, vrf
->name
);
3697 DEFUN (show_ip_multicast
,
3698 show_ip_multicast_cmd
,
3699 "show ip multicast",
3702 "Multicast global information\n")
3705 struct pim_instance
*pim
;
3706 time_t now
= pim_time_monotonic_sec();
3710 vty_out(vty
, "Mroute socket descriptor:");
3712 RB_FOREACH(vrf
, vrf_name_head
, &vrfs_by_name
)
3718 vty_out(vty
, " %d(%s)", pim
->mroute_socket
, pim
->vrf
->name
);
3722 pim_time_uptime(uptime
, sizeof(uptime
),
3723 now
- pimg
->mroute_socket_creation
);
3724 vty_out(vty
, "Mroute socket uptime: %s\n", uptime
);
3728 pim_zebra_zclient_update(vty
);
3729 pim_zlookup_show_ip_multicast(vty
);
3732 vty_out(vty
, "Maximum highest VifIndex: %d\n", PIM_MAX_USABLE_VIFS
);
3735 vty_out(vty
, "Upstream Join Timer: %d secs\n", qpim_t_periodic
);
3736 vty_out(vty
, "Join/Prune Holdtime: %d secs\n", PIM_JP_HOLDTIME
);
3737 vty_out(vty
, "PIM ECMP: %s\n", qpim_ecmp_enable
? "Enable" : "Disable");
3738 vty_out(vty
, "PIM ECMP Rebalance: %s\n",
3739 qpim_ecmp_rebalance_enable
? "Enable" : "Disable");
3743 show_rpf_refresh_stats(vty
, now
, NULL
);
3747 show_scan_oil_stats(vty
, now
);
3749 show_multicast_interfaces(vty
);
3754 static void show_mroute(struct pim_instance
*pim
, struct vty
*vty
, u_char uj
)
3756 struct listnode
*node
;
3757 struct channel_oil
*c_oil
;
3758 struct static_route
*s_route
;
3760 json_object
*json
= NULL
;
3761 json_object
*json_group
= NULL
;
3762 json_object
*json_source
= NULL
;
3763 json_object
*json_oil
= NULL
;
3764 json_object
*json_ifp_out
= NULL
;
3767 char grp_str
[INET_ADDRSTRLEN
];
3768 char src_str
[INET_ADDRSTRLEN
];
3769 char in_ifname
[INTERFACE_NAMSIZ
+ 1];
3770 char out_ifname
[INTERFACE_NAMSIZ
+ 1];
3772 struct interface
*ifp_in
;
3776 json
= json_object_new_object();
3779 "Source Group Proto Input Output TTL Uptime\n");
3782 now
= pim_time_monotonic_sec();
3784 /* print list of PIM and IGMP routes */
3785 for (ALL_LIST_ELEMENTS_RO(pim_channel_oil_list
, node
, c_oil
)) {
3788 if (!c_oil
->installed
&& !uj
)
3791 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, grp_str
,
3793 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, src_str
,
3795 ifp_in
= pim_if_find_by_vif_index(pim
, c_oil
->oil
.mfcc_parent
);
3798 strcpy(in_ifname
, ifp_in
->name
);
3800 strcpy(in_ifname
, "<iif?>");
3804 /* Find the group, create it if it doesn't exist */
3805 json_object_object_get_ex(json
, grp_str
, &json_group
);
3808 json_group
= json_object_new_object();
3809 json_object_object_add(json
, grp_str
,
3813 /* Find the source nested under the group, create it if
3814 * it doesn't exist */
3815 json_object_object_get_ex(json_group
, src_str
,
3819 json_source
= json_object_new_object();
3820 json_object_object_add(json_group
, src_str
,
3824 /* Find the inbound interface nested under the source,
3825 * create it if it doesn't exist */
3826 json_object_int_add(json_source
, "installed",
3828 json_object_int_add(json_source
, "refCount",
3829 c_oil
->oil_ref_count
);
3830 json_object_int_add(json_source
, "oilSize",
3832 json_object_int_add(json_source
, "OilInheritedRescan",
3833 c_oil
->oil_inherited_rescan
);
3834 json_object_string_add(json_source
, "iif", in_ifname
);
3838 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
3840 struct interface
*ifp_out
;
3841 char oif_uptime
[10];
3844 ttl
= c_oil
->oil
.mfcc_ttls
[oif_vif_index
];
3848 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
3850 oif_uptime
, sizeof(oif_uptime
),
3851 now
- c_oil
->oif_creation
[oif_vif_index
]);
3855 strcpy(out_ifname
, ifp_out
->name
);
3857 strcpy(out_ifname
, "<oif?>");
3860 json_ifp_out
= json_object_new_object();
3861 json_object_string_add(json_ifp_out
, "source",
3863 json_object_string_add(json_ifp_out
, "group",
3866 if (c_oil
->oif_flags
[oif_vif_index
]
3867 & PIM_OIF_FLAG_PROTO_PIM
)
3868 json_object_boolean_true_add(
3869 json_ifp_out
, "protocolPim");
3871 if (c_oil
->oif_flags
[oif_vif_index
]
3872 & PIM_OIF_FLAG_PROTO_IGMP
)
3873 json_object_boolean_true_add(
3874 json_ifp_out
, "protocolIgmp");
3876 if (c_oil
->oif_flags
[oif_vif_index
]
3877 & PIM_OIF_FLAG_PROTO_SOURCE
)
3878 json_object_boolean_true_add(
3879 json_ifp_out
, "protocolSource");
3881 if (c_oil
->oif_flags
[oif_vif_index
]
3882 & PIM_OIF_FLAG_PROTO_STAR
)
3883 json_object_boolean_true_add(
3885 "protocolInherited");
3887 json_object_string_add(json_ifp_out
,
3890 json_object_int_add(json_ifp_out
, "iVifI",
3891 c_oil
->oil
.mfcc_parent
);
3892 json_object_string_add(json_ifp_out
,
3893 "outboundInterface",
3895 json_object_int_add(json_ifp_out
, "oVifI",
3897 json_object_int_add(json_ifp_out
, "ttl", ttl
);
3898 json_object_string_add(json_ifp_out
, "upTime",
3901 json_oil
= json_object_new_object();
3902 json_object_object_add(json_source
,
3905 json_object_object_add(json_oil
, out_ifname
,
3908 if (c_oil
->oif_flags
[oif_vif_index
]
3909 & PIM_OIF_FLAG_PROTO_PIM
) {
3910 strcpy(proto
, "PIM");
3913 if (c_oil
->oif_flags
[oif_vif_index
]
3914 & PIM_OIF_FLAG_PROTO_IGMP
) {
3915 strcpy(proto
, "IGMP");
3918 if (c_oil
->oif_flags
[oif_vif_index
]
3919 & PIM_OIF_FLAG_PROTO_SOURCE
) {
3920 strcpy(proto
, "SRC");
3923 if (c_oil
->oif_flags
[oif_vif_index
]
3924 & PIM_OIF_FLAG_PROTO_STAR
) {
3925 strcpy(proto
, "STAR");
3929 "%-15s %-15s %-6s %-10s %-10s %-3d %8s\n",
3930 src_str
, grp_str
, proto
, in_ifname
,
3931 out_ifname
, ttl
, oif_uptime
);
3936 in_ifname
[0] = '\0';
3942 if (!uj
&& !found_oif
) {
3943 vty_out(vty
, "%-15s %-15s %-6s %-10s %-10s %-3d %8s\n",
3944 src_str
, grp_str
, "none", in_ifname
, "none", 0,
3949 /* Print list of static routes */
3950 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, s_route
)) {
3953 if (!s_route
->c_oil
.installed
)
3956 pim_inet4_dump("<group?>", s_route
->group
, grp_str
,
3958 pim_inet4_dump("<source?>", s_route
->source
, src_str
,
3960 ifp_in
= pim_if_find_by_vif_index(pim
, s_route
->iif
);
3964 strcpy(in_ifname
, ifp_in
->name
);
3966 strcpy(in_ifname
, "<iif?>");
3970 /* Find the group, create it if it doesn't exist */
3971 json_object_object_get_ex(json
, grp_str
, &json_group
);
3974 json_group
= json_object_new_object();
3975 json_object_object_add(json
, grp_str
,
3979 /* Find the source nested under the group, create it if
3980 * it doesn't exist */
3981 json_object_object_get_ex(json_group
, src_str
,
3985 json_source
= json_object_new_object();
3986 json_object_object_add(json_group
, src_str
,
3990 json_object_string_add(json_source
, "iif", in_ifname
);
3993 strcpy(proto
, "STATIC");
3996 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
3998 struct interface
*ifp_out
;
3999 char oif_uptime
[10];
4002 ttl
= s_route
->oif_ttls
[oif_vif_index
];
4006 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
4008 oif_uptime
, sizeof(oif_uptime
),
4011 .oif_creation
[oif_vif_index
]);
4015 strcpy(out_ifname
, ifp_out
->name
);
4017 strcpy(out_ifname
, "<oif?>");
4020 json_ifp_out
= json_object_new_object();
4021 json_object_string_add(json_ifp_out
, "source",
4023 json_object_string_add(json_ifp_out
, "group",
4025 json_object_boolean_true_add(json_ifp_out
,
4027 json_object_string_add(json_ifp_out
,
4030 json_object_int_add(
4031 json_ifp_out
, "iVifI",
4032 s_route
->c_oil
.oil
.mfcc_parent
);
4033 json_object_string_add(json_ifp_out
,
4034 "outboundInterface",
4036 json_object_int_add(json_ifp_out
, "oVifI",
4038 json_object_int_add(json_ifp_out
, "ttl", ttl
);
4039 json_object_string_add(json_ifp_out
, "upTime",
4042 json_oil
= json_object_new_object();
4043 json_object_object_add(json_source
,
4046 json_object_object_add(json_oil
, out_ifname
,
4050 "%-15s %-15s %-6s %-10s %-10s %-3d %8s %s\n",
4051 src_str
, grp_str
, proto
, in_ifname
,
4052 out_ifname
, ttl
, oif_uptime
,
4057 in_ifname
[0] = '\0';
4063 if (!uj
&& !found_oif
) {
4065 "%-15s %-15s %-6s %-10s %-10s %-3d %8s %s\n",
4066 src_str
, grp_str
, proto
, in_ifname
, "none", 0,
4067 "--:--:--", pim
->vrf
->name
);
4072 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4073 json
, JSON_C_TO_STRING_PRETTY
));
4074 json_object_free(json
);
4078 DEFUN (show_ip_mroute
,
4080 "show ip mroute [json]",
4086 u_char uj
= use_json(argc
, argv
);
4087 show_mroute(pimg
, vty
, uj
);
4091 static void show_mroute_count(struct vty
*vty
)
4093 struct listnode
*node
;
4094 struct channel_oil
*c_oil
;
4095 struct static_route
*s_route
;
4096 struct pim_instance
*pim
;
4102 "Source Group LastUsed Packets Bytes WrongIf \n");
4104 /* Print PIM and IGMP route counts */
4105 for (ALL_LIST_ELEMENTS_RO(pim_channel_oil_list
, node
, c_oil
)) {
4106 char group_str
[INET_ADDRSTRLEN
];
4107 char source_str
[INET_ADDRSTRLEN
];
4109 if (!c_oil
->installed
)
4112 pim_mroute_update_counters(c_oil
);
4114 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, group_str
,
4116 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, source_str
,
4117 sizeof(source_str
));
4119 vty_out(vty
, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
4120 source_str
, group_str
, c_oil
->cc
.lastused
/ 100,
4121 c_oil
->cc
.pktcnt
, c_oil
->cc
.bytecnt
,
4122 c_oil
->cc
.wrong_if
);
4125 /* Print static route counts */
4126 RB_FOREACH(vrf
, vrf_name_head
, &vrfs_by_name
)
4132 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, s_route
)) {
4133 char group_str
[INET_ADDRSTRLEN
];
4134 char source_str
[INET_ADDRSTRLEN
];
4136 if (!s_route
->c_oil
.installed
)
4139 pim_mroute_update_counters(&s_route
->c_oil
);
4141 pim_inet4_dump("<group?>",
4142 s_route
->c_oil
.oil
.mfcc_mcastgrp
,
4143 group_str
, sizeof(group_str
));
4144 pim_inet4_dump("<source?>",
4145 s_route
->c_oil
.oil
.mfcc_origin
,
4146 source_str
, sizeof(source_str
));
4149 "%-15s %-15s %-8llu %-7ld %-10ld %-7ld %s\n",
4150 source_str
, group_str
,
4151 s_route
->c_oil
.cc
.lastused
,
4152 s_route
->c_oil
.cc
.pktcnt
,
4153 s_route
->c_oil
.cc
.bytecnt
,
4154 s_route
->c_oil
.cc
.wrong_if
, vrf
->name
);
4159 DEFUN (show_ip_mroute_count
,
4160 show_ip_mroute_count_cmd
,
4161 "show ip mroute count",
4165 "Route and packet count data\n")
4167 show_mroute_count(vty
);
4173 "show ip rib A.B.C.D",
4177 "Unicast address\n")
4180 struct in_addr addr
;
4181 const char *addr_str
;
4182 struct pim_nexthop nexthop
;
4183 char nexthop_addr_str
[PREFIX_STRLEN
];
4186 memset(&nexthop
, 0, sizeof(nexthop
));
4187 addr_str
= argv
[idx_ipv4
]->arg
;
4188 result
= inet_pton(AF_INET
, addr_str
, &addr
);
4190 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
4191 errno
, safe_strerror(errno
));
4195 if (pim_nexthop_lookup(pimg
, &nexthop
, addr
, 0)) {
4197 "Failure querying RIB nexthop for unicast address %s\n",
4203 "Address NextHop Interface Metric Preference\n");
4205 pim_addr_dump("<nexthop?>", &nexthop
.mrib_nexthop_addr
,
4206 nexthop_addr_str
, sizeof(nexthop_addr_str
));
4208 vty_out(vty
, "%-15s %-15s %-9s %6d %10d\n", addr_str
, nexthop_addr_str
,
4209 nexthop
.interface
? nexthop
.interface
->name
: "<ifname?>",
4210 nexthop
.mrib_route_metric
, nexthop
.mrib_metric_preference
);
4215 static void show_ssmpingd(struct vty
*vty
)
4217 struct listnode
*node
;
4218 struct ssmpingd_sock
*ss
;
4222 "Source Socket Address Port Uptime Requests\n");
4224 if (!qpim_ssmpingd_list
)
4227 now
= pim_time_monotonic_sec();
4229 for (ALL_LIST_ELEMENTS_RO(qpim_ssmpingd_list
, node
, ss
)) {
4230 char source_str
[INET_ADDRSTRLEN
];
4232 struct sockaddr_in bind_addr
;
4233 socklen_t len
= sizeof(bind_addr
);
4234 char bind_addr_str
[INET_ADDRSTRLEN
];
4236 pim_inet4_dump("<src?>", ss
->source_addr
, source_str
,
4237 sizeof(source_str
));
4239 if (pim_socket_getsockname(
4240 ss
->sock_fd
, (struct sockaddr
*)&bind_addr
, &len
)) {
4242 "%% Failure reading socket name for ssmpingd source %s on fd=%d\n",
4243 source_str
, ss
->sock_fd
);
4246 pim_inet4_dump("<addr?>", bind_addr
.sin_addr
, bind_addr_str
,
4247 sizeof(bind_addr_str
));
4248 pim_time_uptime(ss_uptime
, sizeof(ss_uptime
),
4249 now
- ss
->creation
);
4251 vty_out(vty
, "%-15s %6d %-15s %5d %8s %8lld\n", source_str
,
4252 ss
->sock_fd
, bind_addr_str
, ntohs(bind_addr
.sin_port
),
4253 ss_uptime
, (long long)ss
->requests
);
4257 DEFUN (show_ip_ssmpingd
,
4258 show_ip_ssmpingd_cmd
,
4268 static int pim_rp_cmd_worker(struct vty
*vty
, const char *rp
, const char *group
,
4273 result
= pim_rp_new(pimg
, rp
, group
, plist
);
4275 if (result
== PIM_MALLOC_FAIL
) {
4276 vty_out(vty
, "%% Out of memory\n");
4277 return CMD_WARNING_CONFIG_FAILED
;
4280 if (result
== PIM_GROUP_BAD_ADDRESS
) {
4281 vty_out(vty
, "%% Bad group address specified: %s\n", group
);
4282 return CMD_WARNING_CONFIG_FAILED
;
4285 if (result
== PIM_RP_BAD_ADDRESS
) {
4286 vty_out(vty
, "%% Bad RP address specified: %s\n", rp
);
4287 return CMD_WARNING_CONFIG_FAILED
;
4290 if (result
== PIM_RP_NO_PATH
) {
4291 vty_out(vty
, "%% No Path to RP address specified: %s\n", rp
);
4292 return CMD_WARNING_CONFIG_FAILED
;
4295 if (result
== PIM_GROUP_OVERLAP
) {
4296 vty_out(vty
, "%% Group range specified cannot overlap\n");
4297 return CMD_WARNING_CONFIG_FAILED
;
4300 if (result
== PIM_GROUP_PFXLIST_OVERLAP
) {
4302 "%% This group is already covered by a RP prefix-list\n");
4303 return CMD_WARNING_CONFIG_FAILED
;
4306 if (result
== PIM_RP_PFXLIST_IN_USE
) {
4308 "%% The same prefix-list cannot be applied to multiple RPs\n");
4309 return CMD_WARNING_CONFIG_FAILED
;
4315 static int pim_cmd_spt_switchover(enum pim_spt_switchover spt
,
4318 pimg
->spt
.switchover
= spt
;
4320 switch (pimg
->spt
.switchover
) {
4321 case PIM_SPT_IMMEDIATE
:
4322 if (pimg
->spt
.plist
)
4323 XFREE(MTYPE_PIM_SPT_PLIST_NAME
, pimg
->spt
.plist
);
4325 pim_upstream_add_lhr_star_pimreg(pimg
);
4327 case PIM_SPT_INFINITY
:
4328 pim_upstream_remove_lhr_star_pimreg(pimg
, plist
);
4330 if (pimg
->spt
.plist
)
4331 XFREE(MTYPE_PIM_SPT_PLIST_NAME
, pimg
->spt
.plist
);
4335 XSTRDUP(MTYPE_PIM_SPT_PLIST_NAME
, plist
);
4342 DEFUN (ip_pim_spt_switchover_infinity
,
4343 ip_pim_spt_switchover_infinity_cmd
,
4344 "ip pim spt-switchover infinity-and-beyond",
4348 "Never switch to SPT Tree\n")
4350 return pim_cmd_spt_switchover(PIM_SPT_INFINITY
, NULL
);
4353 DEFUN (ip_pim_spt_switchover_infinity_plist
,
4354 ip_pim_spt_switchover_infinity_plist_cmd
,
4355 "ip pim spt-switchover infinity-and-beyond prefix-list WORD",
4359 "Never switch to SPT Tree\n"
4360 "Prefix-List to control which groups to switch\n"
4361 "Prefix-List name\n")
4363 return pim_cmd_spt_switchover(PIM_SPT_INFINITY
, argv
[5]->arg
);
4366 DEFUN (no_ip_pim_spt_switchover_infinity
,
4367 no_ip_pim_spt_switchover_infinity_cmd
,
4368 "no ip pim spt-switchover infinity-and-beyond",
4373 "Never switch to SPT Tree\n")
4375 return pim_cmd_spt_switchover(PIM_SPT_IMMEDIATE
, NULL
);
4378 DEFUN (no_ip_pim_spt_switchover_infinity_plist
,
4379 no_ip_pim_spt_switchover_infinity_plist_cmd
,
4380 "no ip pim spt-switchover infinity-and-beyond prefix-list WORD",
4385 "Never switch to SPT Tree\n"
4386 "Prefix-List to control which groups to switch\n"
4387 "Prefix-List name\n")
4389 return pim_cmd_spt_switchover(PIM_SPT_IMMEDIATE
, NULL
);
4392 DEFUN (ip_pim_joinprune_time
,
4393 ip_pim_joinprune_time_cmd
,
4394 "ip pim join-prune-interval (60-600)",
4396 "pim multicast routing\n"
4397 "Join Prune Send Interval\n"
4400 qpim_t_periodic
= atoi(argv
[3]->arg
);
4404 DEFUN (no_ip_pim_joinprune_time
,
4405 no_ip_pim_joinprune_time_cmd
,
4406 "no ip pim join-prune-interval (60-600)",
4409 "pim multicast routing\n"
4410 "Join Prune Send Interval\n"
4413 qpim_t_periodic
= PIM_DEFAULT_T_PERIODIC
;
4417 DEFUN (ip_pim_register_suppress
,
4418 ip_pim_register_suppress_cmd
,
4419 "ip pim register-suppress-time (5-60000)",
4421 "pim multicast routing\n"
4422 "Register Suppress Timer\n"
4425 qpim_register_suppress_time
= atoi(argv
[3]->arg
);
4429 DEFUN (no_ip_pim_register_suppress
,
4430 no_ip_pim_register_suppress_cmd
,
4431 "no ip pim register-suppress-time (5-60000)",
4434 "pim multicast routing\n"
4435 "Register Suppress Timer\n"
4438 qpim_register_suppress_time
= PIM_REGISTER_SUPPRESSION_TIME_DEFAULT
;
4442 DEFUN (ip_pim_keep_alive
,
4443 ip_pim_keep_alive_cmd
,
4444 "ip pim keep-alive-timer (31-60000)",
4446 "pim multicast routing\n"
4447 "Keep alive Timer\n"
4450 qpim_keep_alive_time
= atoi(argv
[3]->arg
);
4454 DEFUN (no_ip_pim_keep_alive
,
4455 no_ip_pim_keep_alive_cmd
,
4456 "no ip pim keep-alive-timer (31-60000)",
4459 "pim multicast routing\n"
4460 "Keep alive Timer\n"
4463 qpim_keep_alive_time
= PIM_KEEPALIVE_PERIOD
;
4467 DEFUN (ip_pim_packets
,
4469 "ip pim packets (1-100)",
4471 "pim multicast routing\n"
4472 "packets to process at one time per fd\n"
4473 "Number of packets\n")
4475 qpim_packet_process
= atoi(argv
[3]->arg
);
4479 DEFUN (no_ip_pim_packets
,
4480 no_ip_pim_packets_cmd
,
4481 "no ip pim packets (1-100)",
4484 "pim multicast routing\n"
4485 "packets to process at one time per fd\n"
4486 "Number of packets\n")
4488 qpim_packet_process
= PIM_DEFAULT_PACKET_PROCESS
;
4492 DEFUN (ip_pim_v6_secondary
,
4493 ip_pim_v6_secondary_cmd
,
4494 "ip pim send-v6-secondary",
4496 "pim multicast routing\n"
4497 "Send v6 secondary addresses\n")
4499 pimg
->send_v6_secondary
= 1;
4504 DEFUN (no_ip_pim_v6_secondary
,
4505 no_ip_pim_v6_secondary_cmd
,
4506 "no ip pim send-v6-secondary",
4509 "pim multicast routing\n"
4510 "Send v6 secondary addresses\n")
4512 pimg
->send_v6_secondary
= 0;
4519 "ip pim rp A.B.C.D [A.B.C.D/M]",
4521 "pim multicast routing\n"
4523 "ip address of RP\n"
4524 "Group Address range to cover\n")
4528 if (argc
== (idx_ipv4
+ 1))
4529 return pim_rp_cmd_worker(vty
, argv
[idx_ipv4
]->arg
, NULL
, NULL
);
4531 return pim_rp_cmd_worker(vty
, argv
[idx_ipv4
]->arg
,
4532 argv
[idx_ipv4
+ 1]->arg
, NULL
);
4535 DEFUN (ip_pim_rp_prefix_list
,
4536 ip_pim_rp_prefix_list_cmd
,
4537 "ip pim rp A.B.C.D prefix-list WORD",
4539 "pim multicast routing\n"
4541 "ip address of RP\n"
4542 "group prefix-list filter\n"
4543 "Name of a prefix-list\n")
4545 return pim_rp_cmd_worker(vty
, argv
[3]->arg
, NULL
, argv
[5]->arg
);
4548 static int pim_no_rp_cmd_worker(struct vty
*vty
, const char *rp
,
4549 const char *group
, const char *plist
)
4551 int result
= pim_rp_del(pimg
, rp
, group
, plist
);
4553 if (result
== PIM_GROUP_BAD_ADDRESS
) {
4554 vty_out(vty
, "%% Bad group address specified: %s\n", group
);
4555 return CMD_WARNING_CONFIG_FAILED
;
4558 if (result
== PIM_RP_BAD_ADDRESS
) {
4559 vty_out(vty
, "%% Bad RP address specified: %s\n", rp
);
4560 return CMD_WARNING_CONFIG_FAILED
;
4563 if (result
== PIM_RP_NOT_FOUND
) {
4564 vty_out(vty
, "%% Unable to find specified RP\n");
4565 return CMD_WARNING_CONFIG_FAILED
;
4571 DEFUN (no_ip_pim_rp
,
4573 "no ip pim rp A.B.C.D [A.B.C.D/M]",
4576 "pim multicast routing\n"
4578 "ip address of RP\n"
4579 "Group Address range to cover\n")
4581 int idx_ipv4
= 4, idx_group
= 0;
4583 if (argv_find(argv
, argc
, "A.B.C.D/M", &idx_group
))
4584 return pim_no_rp_cmd_worker(vty
, argv
[idx_ipv4
]->arg
,
4585 argv
[idx_group
]->arg
, NULL
);
4587 return pim_no_rp_cmd_worker(vty
, argv
[idx_ipv4
]->arg
, NULL
,
4591 DEFUN (no_ip_pim_rp_prefix_list
,
4592 no_ip_pim_rp_prefix_list_cmd
,
4593 "no ip pim rp A.B.C.D prefix-list WORD",
4596 "pim multicast routing\n"
4598 "ip address of RP\n"
4599 "group prefix-list filter\n"
4600 "Name of a prefix-list\n")
4602 return pim_no_rp_cmd_worker(vty
, argv
[4]->arg
, NULL
, argv
[6]->arg
);
4605 static int pim_ssm_cmd_worker(struct vty
*vty
, const char *plist
)
4607 int result
= pim_ssm_range_set(pimg
->vrf_id
, plist
);
4609 if (result
== PIM_SSM_ERR_NONE
)
4613 case PIM_SSM_ERR_NO_VRF
:
4614 vty_out(vty
, "%% VRF doesn't exist\n");
4616 case PIM_SSM_ERR_DUP
:
4617 vty_out(vty
, "%% duplicate config\n");
4620 vty_out(vty
, "%% ssm range config failed\n");
4623 return CMD_WARNING_CONFIG_FAILED
;
4626 DEFUN (ip_pim_ssm_prefix_list
,
4627 ip_pim_ssm_prefix_list_cmd
,
4628 "ip pim ssm prefix-list WORD",
4630 "pim multicast routing\n"
4631 "Source Specific Multicast\n"
4632 "group range prefix-list filter\n"
4633 "Name of a prefix-list\n")
4635 return pim_ssm_cmd_worker(vty
, argv
[0]->arg
);
4638 DEFUN (no_ip_pim_ssm_prefix_list
,
4639 no_ip_pim_ssm_prefix_list_cmd
,
4640 "no ip pim ssm prefix-list",
4643 "pim multicast routing\n"
4644 "Source Specific Multicast\n"
4645 "group range prefix-list filter\n")
4647 return pim_ssm_cmd_worker(vty
, NULL
);
4650 DEFUN (no_ip_pim_ssm_prefix_list_name
,
4651 no_ip_pim_ssm_prefix_list_name_cmd
,
4652 "no ip pim ssm prefix-list WORD",
4655 "pim multicast routing\n"
4656 "Source Specific Multicast\n"
4657 "group range prefix-list filter\n"
4658 "Name of a prefix-list\n")
4660 struct pim_ssm
*ssm
= pimg
->ssm_info
;
4662 if (ssm
->plist_name
&& !strcmp(ssm
->plist_name
, argv
[0]->arg
))
4663 return pim_ssm_cmd_worker(vty
, NULL
);
4665 vty_out(vty
, "%% pim ssm prefix-list %s doesn't exist\n", argv
[0]->arg
);
4667 return CMD_WARNING_CONFIG_FAILED
;
4670 static void ip_pim_ssm_show_group_range(struct vty
*vty
, u_char uj
)
4672 struct pim_ssm
*ssm
= pimg
->ssm_info
;
4673 const char *range_str
=
4674 ssm
->plist_name
? ssm
->plist_name
: PIM_SSM_STANDARD_RANGE
;
4678 json
= json_object_new_object();
4679 json_object_string_add(json
, "ssmGroups", range_str
);
4680 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4681 json
, JSON_C_TO_STRING_PRETTY
));
4682 json_object_free(json
);
4684 vty_out(vty
, "SSM group range : %s\n", range_str
);
4687 DEFUN (show_ip_pim_ssm_range
,
4688 show_ip_pim_ssm_range_cmd
,
4689 "show ip pim group-type [json]",
4694 "JavaScript Object Notation\n")
4696 u_char uj
= use_json(argc
, argv
);
4697 ip_pim_ssm_show_group_range(vty
, uj
);
4702 static void ip_pim_ssm_show_group_type(struct vty
*vty
, u_char uj
,
4705 struct in_addr group_addr
;
4706 const char *type_str
;
4709 result
= inet_pton(AF_INET
, group
, &group_addr
);
4711 type_str
= "invalid";
4713 if (pim_is_group_224_4(group_addr
))
4714 type_str
= pim_is_grp_ssm(group_addr
) ? "SSM" : "ASM";
4716 type_str
= "not-multicast";
4721 json
= json_object_new_object();
4722 json_object_string_add(json
, "groupType", type_str
);
4723 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4724 json
, JSON_C_TO_STRING_PRETTY
));
4725 json_object_free(json
);
4727 vty_out(vty
, "Group type : %s\n", type_str
);
4730 DEFUN (show_ip_pim_group_type
,
4731 show_ip_pim_group_type_cmd
,
4732 "show ip pim group-type A.B.C.D [json]",
4736 "multicast group type\n"
4738 "JavaScript Object Notation\n")
4740 u_char uj
= use_json(argc
, argv
);
4741 ip_pim_ssm_show_group_type(vty
, uj
, argv
[0]->arg
);
4746 DEFUN_HIDDEN (ip_multicast_routing
,
4747 ip_multicast_routing_cmd
,
4748 "ip multicast-routing",
4750 "Enable IP multicast forwarding\n")
4755 DEFUN_HIDDEN (no_ip_multicast_routing
,
4756 no_ip_multicast_routing_cmd
,
4757 "no ip multicast-routing",
4760 "Enable IP multicast forwarding\n")
4763 "Command is Disabled and will be removed in a future version\n");
4769 "ip ssmpingd [A.B.C.D]",
4776 struct in_addr source_addr
;
4777 const char *source_str
= (argc
== 3) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
4779 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
4781 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n",
4782 source_str
, errno
, safe_strerror(errno
));
4783 return CMD_WARNING_CONFIG_FAILED
;
4786 result
= pim_ssmpingd_start(source_addr
);
4788 vty_out(vty
, "%% Failure starting ssmpingd for source %s: %d\n",
4789 source_str
, result
);
4790 return CMD_WARNING_CONFIG_FAILED
;
4796 DEFUN (no_ip_ssmpingd
,
4798 "no ip ssmpingd [A.B.C.D]",
4806 struct in_addr source_addr
;
4807 const char *source_str
= (argc
== 4) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
4809 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
4811 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n",
4812 source_str
, errno
, safe_strerror(errno
));
4813 return CMD_WARNING_CONFIG_FAILED
;
4816 result
= pim_ssmpingd_stop(source_addr
);
4818 vty_out(vty
, "%% Failure stopping ssmpingd for source %s: %d\n",
4819 source_str
, result
);
4820 return CMD_WARNING_CONFIG_FAILED
;
4830 "pim multicast routing\n"
4831 "Enable PIM ECMP \n")
4833 qpim_ecmp_enable
= 1;
4838 DEFUN (no_ip_pim_ecmp
,
4843 "pim multicast routing\n"
4844 "Disable PIM ECMP \n")
4846 qpim_ecmp_enable
= 0;
4851 DEFUN (ip_pim_ecmp_rebalance
,
4852 ip_pim_ecmp_rebalance_cmd
,
4853 "ip pim ecmp rebalance",
4855 "pim multicast routing\n"
4856 "Enable PIM ECMP \n"
4857 "Enable PIM ECMP Rebalance\n")
4859 qpim_ecmp_enable
= 1;
4860 qpim_ecmp_rebalance_enable
= 1;
4865 DEFUN (no_ip_pim_ecmp_rebalance
,
4866 no_ip_pim_ecmp_rebalance_cmd
,
4867 "no ip pim ecmp rebalance",
4870 "pim multicast routing\n"
4871 "Disable PIM ECMP \n"
4872 "Disable PIM ECMP Rebalance\n")
4874 qpim_ecmp_rebalance_enable
= 0;
4879 static int pim_cmd_igmp_start(struct vty
*vty
, struct interface
*ifp
)
4881 struct pim_interface
*pim_ifp
;
4882 uint8_t need_startup
= 0;
4884 pim_ifp
= ifp
->info
;
4887 pim_ifp
= pim_if_new(ifp
, 1 /* igmp=true */, 0 /* pim=false */);
4889 vty_out(vty
, "Could not enable IGMP on interface %s\n",
4891 return CMD_WARNING_CONFIG_FAILED
;
4895 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
4896 PIM_IF_DO_IGMP(pim_ifp
->options
);
4901 /* 'ip igmp' executed multiple times, with need_startup
4902 avoid multiple if add all and membership refresh */
4904 pim_if_addr_add_all(ifp
);
4905 pim_if_membership_refresh(ifp
);
4911 DEFUN (interface_ip_igmp
,
4912 interface_ip_igmp_cmd
,
4917 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4919 return pim_cmd_igmp_start(vty
, ifp
);
4922 DEFUN (interface_no_ip_igmp
,
4923 interface_no_ip_igmp_cmd
,
4929 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4930 struct pim_interface
*pim_ifp
= ifp
->info
;
4935 PIM_IF_DONT_IGMP(pim_ifp
->options
);
4937 pim_if_membership_clear(ifp
);
4939 pim_if_addr_del_all_igmp(ifp
);
4941 if (!PIM_IF_TEST_PIM(pim_ifp
->options
)) {
4948 DEFUN (interface_ip_igmp_join
,
4949 interface_ip_igmp_join_cmd
,
4950 "ip igmp join A.B.C.D A.B.C.D",
4953 "IGMP join multicast group\n"
4954 "Multicast group address\n"
4957 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4960 const char *group_str
;
4961 const char *source_str
;
4962 struct in_addr group_addr
;
4963 struct in_addr source_addr
;
4967 group_str
= argv
[idx_ipv4
]->arg
;
4968 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
4970 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", group_str
,
4971 errno
, safe_strerror(errno
));
4972 return CMD_WARNING_CONFIG_FAILED
;
4975 /* Source address */
4976 source_str
= argv
[idx_ipv4_2
]->arg
;
4977 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
4979 vty_out(vty
, "Bad source address %s: errno=%d: %s\n",
4980 source_str
, errno
, safe_strerror(errno
));
4981 return CMD_WARNING_CONFIG_FAILED
;
4984 result
= pim_if_igmp_join_add(ifp
, group_addr
, source_addr
);
4987 "%% Failure joining IGMP group %s source %s on interface %s: %d\n",
4988 group_str
, source_str
, ifp
->name
, result
);
4989 return CMD_WARNING_CONFIG_FAILED
;
4995 DEFUN (interface_no_ip_igmp_join
,
4996 interface_no_ip_igmp_join_cmd
,
4997 "no ip igmp join A.B.C.D A.B.C.D",
5001 "IGMP join multicast group\n"
5002 "Multicast group address\n"
5005 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5008 const char *group_str
;
5009 const char *source_str
;
5010 struct in_addr group_addr
;
5011 struct in_addr source_addr
;
5015 group_str
= argv
[idx_ipv4
]->arg
;
5016 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
5018 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", group_str
,
5019 errno
, safe_strerror(errno
));
5020 return CMD_WARNING_CONFIG_FAILED
;
5023 /* Source address */
5024 source_str
= argv
[idx_ipv4_2
]->arg
;
5025 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
5027 vty_out(vty
, "Bad source address %s: errno=%d: %s\n",
5028 source_str
, errno
, safe_strerror(errno
));
5029 return CMD_WARNING_CONFIG_FAILED
;
5032 result
= pim_if_igmp_join_del(ifp
, group_addr
, source_addr
);
5035 "%% Failure leaving IGMP group %s source %s on interface %s: %d\n",
5036 group_str
, source_str
, ifp
->name
, result
);
5037 return CMD_WARNING_CONFIG_FAILED
;
5044 CLI reconfiguration affects the interface level (struct pim_interface).
5045 This function propagates the reconfiguration to every active socket
5048 static void igmp_sock_query_interval_reconfig(struct igmp_sock
*igmp
)
5050 struct interface
*ifp
;
5051 struct pim_interface
*pim_ifp
;
5055 /* other querier present? */
5057 if (igmp
->t_other_querier_timer
)
5060 /* this is the querier */
5062 zassert(igmp
->interface
);
5063 zassert(igmp
->interface
->info
);
5065 ifp
= igmp
->interface
;
5066 pim_ifp
= ifp
->info
;
5068 if (PIM_DEBUG_IGMP_TRACE
) {
5069 char ifaddr_str
[INET_ADDRSTRLEN
];
5070 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
5071 sizeof(ifaddr_str
));
5072 zlog_debug("%s: Querier %s on %s reconfig query_interval=%d",
5073 __PRETTY_FUNCTION__
, ifaddr_str
, ifp
->name
,
5074 pim_ifp
->igmp_default_query_interval
);
5078 igmp_startup_mode_on() will reset QQI:
5080 igmp->querier_query_interval = pim_ifp->igmp_default_query_interval;
5082 igmp_startup_mode_on(igmp
);
5085 static void igmp_sock_query_reschedule(struct igmp_sock
*igmp
)
5087 if (igmp
->t_igmp_query_timer
) {
5088 /* other querier present */
5089 zassert(igmp
->t_igmp_query_timer
);
5090 zassert(!igmp
->t_other_querier_timer
);
5092 pim_igmp_general_query_off(igmp
);
5093 pim_igmp_general_query_on(igmp
);
5095 zassert(igmp
->t_igmp_query_timer
);
5096 zassert(!igmp
->t_other_querier_timer
);
5098 /* this is the querier */
5100 zassert(!igmp
->t_igmp_query_timer
);
5101 zassert(igmp
->t_other_querier_timer
);
5103 pim_igmp_other_querier_timer_off(igmp
);
5104 pim_igmp_other_querier_timer_on(igmp
);
5106 zassert(!igmp
->t_igmp_query_timer
);
5107 zassert(igmp
->t_other_querier_timer
);
5111 static void change_query_interval(struct pim_interface
*pim_ifp
,
5114 struct listnode
*sock_node
;
5115 struct igmp_sock
*igmp
;
5117 pim_ifp
->igmp_default_query_interval
= query_interval
;
5119 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
5120 igmp_sock_query_interval_reconfig(igmp
);
5121 igmp_sock_query_reschedule(igmp
);
5125 static void change_query_max_response_time(struct pim_interface
*pim_ifp
,
5126 int query_max_response_time_dsec
)
5128 struct listnode
*sock_node
;
5129 struct igmp_sock
*igmp
;
5131 pim_ifp
->igmp_query_max_response_time_dsec
=
5132 query_max_response_time_dsec
;
5135 Below we modify socket/group/source timers in order to quickly
5136 reflect the change. Otherwise, those timers would eventually catch
5140 /* scan all sockets */
5141 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
5142 struct listnode
*grp_node
;
5143 struct igmp_group
*grp
;
5145 /* reschedule socket general query */
5146 igmp_sock_query_reschedule(igmp
);
5148 /* scan socket groups */
5149 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grp_node
,
5151 struct listnode
*src_node
;
5152 struct igmp_source
*src
;
5154 /* reset group timers for groups in EXCLUDE mode */
5155 if (grp
->group_filtermode_isexcl
) {
5156 igmp_group_reset_gmi(grp
);
5159 /* scan group sources */
5160 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
,
5163 /* reset source timers for sources with running
5165 if (src
->t_source_timer
) {
5166 igmp_source_reset_gmi(igmp
, grp
, src
);
5173 #define IGMP_QUERY_INTERVAL_MIN (1)
5174 #define IGMP_QUERY_INTERVAL_MAX (1800)
5176 DEFUN (interface_ip_igmp_query_interval
,
5177 interface_ip_igmp_query_interval_cmd
,
5178 "ip igmp query-interval (1-1800)",
5181 IFACE_IGMP_QUERY_INTERVAL_STR
5182 "Query interval in seconds\n")
5184 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5185 struct pim_interface
*pim_ifp
= ifp
->info
;
5187 int query_interval_dsec
;
5191 ret
= pim_cmd_igmp_start(vty
, ifp
);
5192 if (ret
!= CMD_SUCCESS
)
5194 pim_ifp
= ifp
->info
;
5197 query_interval
= atoi(argv
[3]->arg
);
5198 query_interval_dsec
= 10 * query_interval
;
5201 It seems we don't need to check bounds since command.c does it
5202 already, but we verify them anyway for extra safety.
5204 if (query_interval
< IGMP_QUERY_INTERVAL_MIN
) {
5206 "General query interval %d lower than minimum %d\n",
5207 query_interval
, IGMP_QUERY_INTERVAL_MIN
);
5208 return CMD_WARNING_CONFIG_FAILED
;
5210 if (query_interval
> IGMP_QUERY_INTERVAL_MAX
) {
5212 "General query interval %d higher than maximum %d\n",
5213 query_interval
, IGMP_QUERY_INTERVAL_MAX
);
5214 return CMD_WARNING_CONFIG_FAILED
;
5217 if (query_interval_dsec
<= pim_ifp
->igmp_query_max_response_time_dsec
) {
5219 "Can't set general query interval %d dsec <= query max response time %d dsec.\n",
5220 query_interval_dsec
,
5221 pim_ifp
->igmp_query_max_response_time_dsec
);
5222 return CMD_WARNING_CONFIG_FAILED
;
5225 change_query_interval(pim_ifp
, query_interval
);
5230 DEFUN (interface_no_ip_igmp_query_interval
,
5231 interface_no_ip_igmp_query_interval_cmd
,
5232 "no ip igmp query-interval",
5236 IFACE_IGMP_QUERY_INTERVAL_STR
)
5238 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5239 struct pim_interface
*pim_ifp
= ifp
->info
;
5240 int default_query_interval_dsec
;
5245 default_query_interval_dsec
= IGMP_GENERAL_QUERY_INTERVAL
* 10;
5247 if (default_query_interval_dsec
5248 <= pim_ifp
->igmp_query_max_response_time_dsec
) {
5250 "Can't set default general query interval %d dsec <= query max response time %d dsec.\n",
5251 default_query_interval_dsec
,
5252 pim_ifp
->igmp_query_max_response_time_dsec
);
5253 return CMD_WARNING_CONFIG_FAILED
;
5256 change_query_interval(pim_ifp
, IGMP_GENERAL_QUERY_INTERVAL
);
5261 DEFUN (interface_ip_igmp_version
,
5262 interface_ip_igmp_version_cmd
,
5263 "ip igmp version (2-3)",
5267 "IGMP version number\n")
5269 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5270 struct pim_interface
*pim_ifp
= ifp
->info
;
5271 int igmp_version
, old_version
= 0;
5275 ret
= pim_cmd_igmp_start(vty
, ifp
);
5276 if (ret
!= CMD_SUCCESS
)
5278 pim_ifp
= ifp
->info
;
5281 igmp_version
= atoi(argv
[3]->arg
);
5282 old_version
= pim_ifp
->igmp_version
;
5283 pim_ifp
->igmp_version
= igmp_version
;
5285 // Check if IGMP is Enabled otherwise, enable on interface
5286 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
5287 PIM_IF_DO_IGMP(pim_ifp
->options
);
5288 pim_if_addr_add_all(ifp
);
5289 pim_if_membership_refresh(ifp
);
5290 old_version
= igmp_version
; // avoid refreshing membership
5293 /* Current and new version is different refresh existing
5294 membership. Going from 3 -> 2 or 2 -> 3. */
5295 if (old_version
!= igmp_version
)
5296 pim_if_membership_refresh(ifp
);
5301 DEFUN (interface_no_ip_igmp_version
,
5302 interface_no_ip_igmp_version_cmd
,
5303 "no ip igmp version (2-3)",
5308 "IGMP version number\n")
5310 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5311 struct pim_interface
*pim_ifp
= ifp
->info
;
5316 pim_ifp
->igmp_version
= IGMP_DEFAULT_VERSION
;
5321 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
5322 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
5324 DEFUN (interface_ip_igmp_query_max_response_time
,
5325 interface_ip_igmp_query_max_response_time_cmd
,
5326 "ip igmp query-max-response-time (10-250)",
5329 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
5330 "Query response value in deci-seconds\n")
5332 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5333 struct pim_interface
*pim_ifp
= ifp
->info
;
5334 int query_max_response_time
;
5338 ret
= pim_cmd_igmp_start(vty
, ifp
);
5339 if (ret
!= CMD_SUCCESS
)
5341 pim_ifp
= ifp
->info
;
5344 query_max_response_time
= atoi(argv
[3]->arg
);
5346 if (query_max_response_time
5347 >= pim_ifp
->igmp_default_query_interval
* 10) {
5349 "Can't set query max response time %d sec >= general query interval %d sec\n",
5350 query_max_response_time
,
5351 pim_ifp
->igmp_default_query_interval
);
5352 return CMD_WARNING_CONFIG_FAILED
;
5355 change_query_max_response_time(pim_ifp
, query_max_response_time
);
5360 DEFUN (interface_no_ip_igmp_query_max_response_time
,
5361 interface_no_ip_igmp_query_max_response_time_cmd
,
5362 "no ip igmp query-max-response-time (10-250)",
5366 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
5367 "Time for response in deci-seconds\n")
5369 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5370 struct pim_interface
*pim_ifp
= ifp
->info
;
5375 change_query_max_response_time(pim_ifp
,
5376 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
5381 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
5382 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
5384 DEFUN_HIDDEN (interface_ip_igmp_query_max_response_time_dsec
,
5385 interface_ip_igmp_query_max_response_time_dsec_cmd
,
5386 "ip igmp query-max-response-time-dsec (10-250)",
5389 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
5390 "Query response value in deciseconds\n")
5392 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5393 struct pim_interface
*pim_ifp
= ifp
->info
;
5394 int query_max_response_time_dsec
;
5395 int default_query_interval_dsec
;
5399 ret
= pim_cmd_igmp_start(vty
, ifp
);
5400 if (ret
!= CMD_SUCCESS
)
5402 pim_ifp
= ifp
->info
;
5405 query_max_response_time_dsec
= atoi(argv
[4]->arg
);
5407 default_query_interval_dsec
= 10 * pim_ifp
->igmp_default_query_interval
;
5409 if (query_max_response_time_dsec
>= default_query_interval_dsec
) {
5411 "Can't set query max response time %d dsec >= general query interval %d dsec\n",
5412 query_max_response_time_dsec
,
5413 default_query_interval_dsec
);
5414 return CMD_WARNING_CONFIG_FAILED
;
5417 change_query_max_response_time(pim_ifp
, query_max_response_time_dsec
);
5422 DEFUN_HIDDEN (interface_no_ip_igmp_query_max_response_time_dsec
,
5423 interface_no_ip_igmp_query_max_response_time_dsec_cmd
,
5424 "no ip igmp query-max-response-time-dsec",
5428 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
)
5430 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5431 struct pim_interface
*pim_ifp
= ifp
->info
;
5436 change_query_max_response_time(pim_ifp
,
5437 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
5442 DEFUN (interface_ip_pim_drprio
,
5443 interface_ip_pim_drprio_cmd
,
5444 "ip pim drpriority (1-4294967295)",
5447 "Set the Designated Router Election Priority\n"
5448 "Value of the new DR Priority\n")
5450 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5452 struct pim_interface
*pim_ifp
= ifp
->info
;
5453 uint32_t old_dr_prio
;
5456 vty_out(vty
, "Please enable PIM on interface, first\n");
5457 return CMD_WARNING_CONFIG_FAILED
;
5460 old_dr_prio
= pim_ifp
->pim_dr_priority
;
5462 pim_ifp
->pim_dr_priority
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
5464 if (old_dr_prio
!= pim_ifp
->pim_dr_priority
) {
5465 if (pim_if_dr_election(ifp
))
5466 pim_hello_restart_now(ifp
);
5472 DEFUN (interface_no_ip_pim_drprio
,
5473 interface_no_ip_pim_drprio_cmd
,
5474 "no ip pim drpriority [(1-4294967295)]",
5478 "Revert the Designated Router Priority to default\n"
5479 "Old Value of the Priority\n")
5481 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5482 struct pim_interface
*pim_ifp
= ifp
->info
;
5485 vty_out(vty
, "Pim not enabled on this interface\n");
5486 return CMD_WARNING_CONFIG_FAILED
;
5489 if (pim_ifp
->pim_dr_priority
!= PIM_DEFAULT_DR_PRIORITY
) {
5490 pim_ifp
->pim_dr_priority
= PIM_DEFAULT_DR_PRIORITY
;
5491 if (pim_if_dr_election(ifp
))
5492 pim_hello_restart_now(ifp
);
5498 static int pim_cmd_interface_add(struct interface
*ifp
)
5500 struct pim_interface
*pim_ifp
= ifp
->info
;
5503 pim_ifp
= pim_if_new(ifp
, 0 /* igmp=false */, 1 /* pim=true */);
5508 PIM_IF_DO_PIM(pim_ifp
->options
);
5511 pim_if_addr_add_all(ifp
);
5512 pim_if_membership_refresh(ifp
);
5516 DEFUN_HIDDEN (interface_ip_pim_ssm
,
5517 interface_ip_pim_ssm_cmd
,
5523 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5525 if (!pim_cmd_interface_add(ifp
)) {
5526 vty_out(vty
, "Could not enable PIM SM on interface\n");
5527 return CMD_WARNING_CONFIG_FAILED
;
5531 "WARN: Enabled PIM SM on interface; configure PIM SSM "
5532 "range if needed\n");
5536 DEFUN (interface_ip_pim_sm
,
5537 interface_ip_pim_sm_cmd
,
5543 struct pim_interface
*pim_ifp
;
5545 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5546 if (!pim_cmd_interface_add(ifp
)) {
5547 vty_out(vty
, "Could not enable PIM SM on interface\n");
5548 return CMD_WARNING_CONFIG_FAILED
;
5551 pim_ifp
= ifp
->info
;
5553 pim_if_create_pimreg(pim_ifp
->pim
);
5558 static int pim_cmd_interface_delete(struct interface
*ifp
)
5560 struct pim_interface
*pim_ifp
= ifp
->info
;
5565 PIM_IF_DONT_PIM(pim_ifp
->options
);
5567 pim_if_membership_clear(ifp
);
5570 pim_sock_delete() removes all neighbors from
5571 pim_ifp->pim_neighbor_list.
5573 pim_sock_delete(ifp
, "pim unconfigured on interface");
5575 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
5576 pim_if_addr_del_all(ifp
);
5583 DEFUN_HIDDEN (interface_no_ip_pim_ssm
,
5584 interface_no_ip_pim_ssm_cmd
,
5591 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5592 if (!pim_cmd_interface_delete(ifp
)) {
5593 vty_out(vty
, "Unable to delete interface information\n");
5594 return CMD_WARNING_CONFIG_FAILED
;
5600 DEFUN (interface_no_ip_pim_sm
,
5601 interface_no_ip_pim_sm_cmd
,
5608 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5609 if (!pim_cmd_interface_delete(ifp
)) {
5610 vty_out(vty
, "Unable to delete interface information\n");
5611 return CMD_WARNING_CONFIG_FAILED
;
5617 DEFUN (interface_ip_mroute
,
5618 interface_ip_mroute_cmd
,
5619 "ip mroute INTERFACE A.B.C.D",
5621 "Add multicast route\n"
5622 "Outgoing interface name\n"
5625 VTY_DECLVAR_CONTEXT(interface
, iif
);
5626 struct pim_interface
*pim_ifp
;
5627 struct pim_instance
*pim
;
5628 int idx_interface
= 2;
5630 struct interface
*oif
;
5631 const char *oifname
;
5632 const char *grp_str
;
5633 struct in_addr grp_addr
;
5634 struct in_addr src_addr
;
5637 pim_ifp
= iif
->info
;
5640 oifname
= argv
[idx_interface
]->arg
;
5641 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
5643 vty_out(vty
, "No such interface name %s\n", oifname
);
5647 grp_str
= argv
[idx_ipv4
]->arg
;
5648 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
5650 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
5651 errno
, safe_strerror(errno
));
5655 src_addr
.s_addr
= INADDR_ANY
;
5657 if (pim_static_add(pim
, iif
, oif
, grp_addr
, src_addr
)) {
5658 vty_out(vty
, "Failed to add route\n");
5665 DEFUN (interface_ip_mroute_source
,
5666 interface_ip_mroute_source_cmd
,
5667 "ip mroute INTERFACE A.B.C.D A.B.C.D",
5669 "Add multicast route\n"
5670 "Outgoing interface name\n"
5674 VTY_DECLVAR_CONTEXT(interface
, iif
);
5675 struct pim_interface
*pim_ifp
;
5676 struct pim_instance
*pim
;
5677 int idx_interface
= 2;
5680 struct interface
*oif
;
5681 const char *oifname
;
5682 const char *grp_str
;
5683 struct in_addr grp_addr
;
5684 const char *src_str
;
5685 struct in_addr src_addr
;
5688 pim_ifp
= iif
->info
;
5691 oifname
= argv
[idx_interface
]->arg
;
5692 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
5694 vty_out(vty
, "No such interface name %s\n", oifname
);
5698 grp_str
= argv
[idx_ipv4
]->arg
;
5699 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
5701 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
5702 errno
, safe_strerror(errno
));
5706 src_str
= argv
[idx_ipv4_2
]->arg
;
5707 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
5709 vty_out(vty
, "Bad source address %s: errno=%d: %s\n", src_str
,
5710 errno
, safe_strerror(errno
));
5714 if (pim_static_add(pim
, iif
, oif
, grp_addr
, src_addr
)) {
5715 vty_out(vty
, "Failed to add route\n");
5722 DEFUN (interface_no_ip_mroute
,
5723 interface_no_ip_mroute_cmd
,
5724 "no ip mroute INTERFACE A.B.C.D",
5727 "Add multicast route\n"
5728 "Outgoing interface name\n"
5731 VTY_DECLVAR_CONTEXT(interface
, iif
);
5732 struct pim_interface
*pim_ifp
;
5733 struct pim_instance
*pim
;
5734 int idx_interface
= 3;
5736 struct interface
*oif
;
5737 const char *oifname
;
5738 const char *grp_str
;
5739 struct in_addr grp_addr
;
5740 struct in_addr src_addr
;
5743 pim_ifp
= iif
->info
;
5746 oifname
= argv
[idx_interface
]->arg
;
5747 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
5749 vty_out(vty
, "No such interface name %s\n", oifname
);
5753 grp_str
= argv
[idx_ipv4
]->arg
;
5754 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
5756 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
5757 errno
, safe_strerror(errno
));
5761 src_addr
.s_addr
= INADDR_ANY
;
5763 if (pim_static_del(pim
, iif
, oif
, grp_addr
, src_addr
)) {
5764 vty_out(vty
, "Failed to remove route\n");
5771 DEFUN (interface_no_ip_mroute_source
,
5772 interface_no_ip_mroute_source_cmd
,
5773 "no ip mroute INTERFACE A.B.C.D A.B.C.D",
5776 "Add multicast route\n"
5777 "Outgoing interface name\n"
5781 VTY_DECLVAR_CONTEXT(interface
, iif
);
5782 struct pim_interface
*pim_ifp
;
5783 struct pim_instance
*pim
;
5784 int idx_interface
= 3;
5787 struct interface
*oif
;
5788 const char *oifname
;
5789 const char *grp_str
;
5790 struct in_addr grp_addr
;
5791 const char *src_str
;
5792 struct in_addr src_addr
;
5795 pim_ifp
= iif
->info
;
5798 oifname
= argv
[idx_interface
]->arg
;
5799 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
5801 vty_out(vty
, "No such interface name %s\n", oifname
);
5805 grp_str
= argv
[idx_ipv4
]->arg
;
5806 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
5808 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
5809 errno
, safe_strerror(errno
));
5813 src_str
= argv
[idx_ipv4_2
]->arg
;
5814 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
5816 vty_out(vty
, "Bad source address %s: errno=%d: %s\n", src_str
,
5817 errno
, safe_strerror(errno
));
5821 if (pim_static_del(pim
, iif
, oif
, grp_addr
, src_addr
)) {
5822 vty_out(vty
, "Failed to remove route\n");
5829 DEFUN (interface_ip_pim_hello
,
5830 interface_ip_pim_hello_cmd
,
5831 "ip pim hello (1-180) [(1-180)]",
5835 IFACE_PIM_HELLO_TIME_STR
5836 IFACE_PIM_HELLO_HOLD_STR
)
5838 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5841 struct pim_interface
*pim_ifp
= ifp
->info
;
5844 if (!pim_cmd_interface_add(ifp
)) {
5845 vty_out(vty
, "Could not enable PIM SM on interface\n");
5846 return CMD_WARNING_CONFIG_FAILED
;
5850 pim_ifp
= ifp
->info
;
5851 pim_ifp
->pim_hello_period
= strtol(argv
[idx_time
]->arg
, NULL
, 10);
5853 if (argc
== idx_hold
+ 1)
5854 pim_ifp
->pim_default_holdtime
=
5855 strtol(argv
[idx_hold
]->arg
, NULL
, 10);
5861 DEFUN (interface_no_ip_pim_hello
,
5862 interface_no_ip_pim_hello_cmd
,
5863 "no ip pim hello [(1-180) (1-180)]",
5868 IFACE_PIM_HELLO_TIME_STR
5869 IFACE_PIM_HELLO_HOLD_STR
)
5871 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5872 struct pim_interface
*pim_ifp
= ifp
->info
;
5875 vty_out(vty
, "Pim not enabled on this interface\n");
5876 return CMD_WARNING_CONFIG_FAILED
;
5879 pim_ifp
->pim_hello_period
= PIM_DEFAULT_HELLO_PERIOD
;
5880 pim_ifp
->pim_default_holdtime
= -1;
5891 PIM_DO_DEBUG_IGMP_EVENTS
;
5892 PIM_DO_DEBUG_IGMP_PACKETS
;
5893 PIM_DO_DEBUG_IGMP_TRACE
;
5897 DEFUN (no_debug_igmp
,
5904 PIM_DONT_DEBUG_IGMP_EVENTS
;
5905 PIM_DONT_DEBUG_IGMP_PACKETS
;
5906 PIM_DONT_DEBUG_IGMP_TRACE
;
5911 DEFUN (debug_igmp_events
,
5912 debug_igmp_events_cmd
,
5913 "debug igmp events",
5916 DEBUG_IGMP_EVENTS_STR
)
5918 PIM_DO_DEBUG_IGMP_EVENTS
;
5922 DEFUN (no_debug_igmp_events
,
5923 no_debug_igmp_events_cmd
,
5924 "no debug igmp events",
5928 DEBUG_IGMP_EVENTS_STR
)
5930 PIM_DONT_DEBUG_IGMP_EVENTS
;
5935 DEFUN (debug_igmp_packets
,
5936 debug_igmp_packets_cmd
,
5937 "debug igmp packets",
5940 DEBUG_IGMP_PACKETS_STR
)
5942 PIM_DO_DEBUG_IGMP_PACKETS
;
5946 DEFUN (no_debug_igmp_packets
,
5947 no_debug_igmp_packets_cmd
,
5948 "no debug igmp packets",
5952 DEBUG_IGMP_PACKETS_STR
)
5954 PIM_DONT_DEBUG_IGMP_PACKETS
;
5959 DEFUN (debug_igmp_trace
,
5960 debug_igmp_trace_cmd
,
5964 DEBUG_IGMP_TRACE_STR
)
5966 PIM_DO_DEBUG_IGMP_TRACE
;
5970 DEFUN (no_debug_igmp_trace
,
5971 no_debug_igmp_trace_cmd
,
5972 "no debug igmp trace",
5976 DEBUG_IGMP_TRACE_STR
)
5978 PIM_DONT_DEBUG_IGMP_TRACE
;
5983 DEFUN (debug_mroute
,
5989 PIM_DO_DEBUG_MROUTE
;
5993 DEFUN (debug_mroute_detail
,
5994 debug_mroute_detail_cmd
,
5995 "debug mroute detail",
6000 PIM_DO_DEBUG_MROUTE_DETAIL
;
6004 DEFUN (no_debug_mroute
,
6005 no_debug_mroute_cmd
,
6011 PIM_DONT_DEBUG_MROUTE
;
6015 DEFUN (no_debug_mroute_detail
,
6016 no_debug_mroute_detail_cmd
,
6017 "no debug mroute detail",
6023 PIM_DONT_DEBUG_MROUTE_DETAIL
;
6027 DEFUN (debug_static
,
6033 PIM_DO_DEBUG_STATIC
;
6037 DEFUN (no_debug_static
,
6038 no_debug_static_cmd
,
6044 PIM_DONT_DEBUG_STATIC
;
6055 PIM_DO_DEBUG_PIM_EVENTS
;
6056 PIM_DO_DEBUG_PIM_PACKETS
;
6057 PIM_DO_DEBUG_PIM_TRACE
;
6058 PIM_DO_DEBUG_MSDP_EVENTS
;
6059 PIM_DO_DEBUG_MSDP_PACKETS
;
6063 DEFUN (no_debug_pim
,
6070 PIM_DONT_DEBUG_PIM_EVENTS
;
6071 PIM_DONT_DEBUG_PIM_PACKETS
;
6072 PIM_DONT_DEBUG_PIM_TRACE
;
6073 PIM_DONT_DEBUG_MSDP_EVENTS
;
6074 PIM_DONT_DEBUG_MSDP_PACKETS
;
6076 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
6077 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
6083 DEFUN (debug_pim_events
,
6084 debug_pim_events_cmd
,
6088 DEBUG_PIM_EVENTS_STR
)
6090 PIM_DO_DEBUG_PIM_EVENTS
;
6094 DEFUN (no_debug_pim_events
,
6095 no_debug_pim_events_cmd
,
6096 "no debug pim events",
6100 DEBUG_PIM_EVENTS_STR
)
6102 PIM_DONT_DEBUG_PIM_EVENTS
;
6106 DEFUN (debug_pim_packets
,
6107 debug_pim_packets_cmd
,
6108 "debug pim packets [<hello|joins|register>]",
6111 DEBUG_PIM_PACKETS_STR
6112 DEBUG_PIM_HELLO_PACKETS_STR
6113 DEBUG_PIM_J_P_PACKETS_STR
6114 DEBUG_PIM_PIM_REG_PACKETS_STR
)
6117 if (argv_find(argv
, argc
, "hello", &idx
)) {
6118 PIM_DO_DEBUG_PIM_HELLO
;
6119 vty_out(vty
, "PIM Hello debugging is on\n");
6120 } else if (argv_find(argv
, argc
, "joins", &idx
)) {
6121 PIM_DO_DEBUG_PIM_J_P
;
6122 vty_out(vty
, "PIM Join/Prune debugging is on\n");
6123 } else if (argv_find(argv
, argc
, "register", &idx
)) {
6124 PIM_DO_DEBUG_PIM_REG
;
6125 vty_out(vty
, "PIM Register debugging is on\n");
6127 PIM_DO_DEBUG_PIM_PACKETS
;
6128 vty_out(vty
, "PIM Packet debugging is on \n");
6133 DEFUN (no_debug_pim_packets
,
6134 no_debug_pim_packets_cmd
,
6135 "no debug pim packets [<hello|joins|register>]",
6139 DEBUG_PIM_PACKETS_STR
6140 DEBUG_PIM_HELLO_PACKETS_STR
6141 DEBUG_PIM_J_P_PACKETS_STR
6142 DEBUG_PIM_PIM_REG_PACKETS_STR
)
6145 if (argv_find(argv
, argc
, "hello", &idx
)) {
6146 PIM_DONT_DEBUG_PIM_HELLO
;
6147 vty_out(vty
, "PIM Hello debugging is off \n");
6148 } else if (argv_find(argv
, argc
, "joins", &idx
)) {
6149 PIM_DONT_DEBUG_PIM_J_P
;
6150 vty_out(vty
, "PIM Join/Prune debugging is off \n");
6151 } else if (argv_find(argv
, argc
, "register", &idx
)) {
6152 PIM_DONT_DEBUG_PIM_REG
;
6153 vty_out(vty
, "PIM Register debugging is off\n");
6155 PIM_DONT_DEBUG_PIM_PACKETS
;
6161 DEFUN (debug_pim_packetdump_send
,
6162 debug_pim_packetdump_send_cmd
,
6163 "debug pim packet-dump send",
6166 DEBUG_PIM_PACKETDUMP_STR
6167 DEBUG_PIM_PACKETDUMP_SEND_STR
)
6169 PIM_DO_DEBUG_PIM_PACKETDUMP_SEND
;
6173 DEFUN (no_debug_pim_packetdump_send
,
6174 no_debug_pim_packetdump_send_cmd
,
6175 "no debug pim packet-dump send",
6179 DEBUG_PIM_PACKETDUMP_STR
6180 DEBUG_PIM_PACKETDUMP_SEND_STR
)
6182 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
6187 DEFUN (debug_pim_packetdump_recv
,
6188 debug_pim_packetdump_recv_cmd
,
6189 "debug pim packet-dump receive",
6192 DEBUG_PIM_PACKETDUMP_STR
6193 DEBUG_PIM_PACKETDUMP_RECV_STR
)
6195 PIM_DO_DEBUG_PIM_PACKETDUMP_RECV
;
6199 DEFUN (no_debug_pim_packetdump_recv
,
6200 no_debug_pim_packetdump_recv_cmd
,
6201 "no debug pim packet-dump receive",
6205 DEBUG_PIM_PACKETDUMP_STR
6206 DEBUG_PIM_PACKETDUMP_RECV_STR
)
6208 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
6213 DEFUN (debug_pim_trace
,
6214 debug_pim_trace_cmd
,
6218 DEBUG_PIM_TRACE_STR
)
6220 PIM_DO_DEBUG_PIM_TRACE
;
6224 DEFUN (no_debug_pim_trace
,
6225 no_debug_pim_trace_cmd
,
6226 "no debug pim trace",
6230 DEBUG_PIM_TRACE_STR
)
6232 PIM_DONT_DEBUG_PIM_TRACE
;
6237 DEFUN (debug_ssmpingd
,
6243 PIM_DO_DEBUG_SSMPINGD
;
6247 DEFUN (no_debug_ssmpingd
,
6248 no_debug_ssmpingd_cmd
,
6249 "no debug ssmpingd",
6254 PIM_DONT_DEBUG_SSMPINGD
;
6259 DEFUN (debug_pim_zebra
,
6260 debug_pim_zebra_cmd
,
6264 DEBUG_PIM_ZEBRA_STR
)
6270 DEFUN (no_debug_pim_zebra
,
6271 no_debug_pim_zebra_cmd
,
6272 "no debug pim zebra",
6276 DEBUG_PIM_ZEBRA_STR
)
6278 PIM_DONT_DEBUG_ZEBRA
;
6289 PIM_DO_DEBUG_MSDP_EVENTS
;
6290 PIM_DO_DEBUG_MSDP_PACKETS
;
6294 DEFUN (no_debug_msdp
,
6301 PIM_DONT_DEBUG_MSDP_EVENTS
;
6302 PIM_DONT_DEBUG_MSDP_PACKETS
;
6306 ALIAS(no_debug_msdp
, undebug_msdp_cmd
, "undebug msdp",
6307 UNDEBUG_STR DEBUG_MSDP_STR
)
6309 DEFUN (debug_msdp_events
,
6310 debug_msdp_events_cmd
,
6311 "debug msdp events",
6314 DEBUG_MSDP_EVENTS_STR
)
6316 PIM_DO_DEBUG_MSDP_EVENTS
;
6320 DEFUN (no_debug_msdp_events
,
6321 no_debug_msdp_events_cmd
,
6322 "no debug msdp events",
6326 DEBUG_MSDP_EVENTS_STR
)
6328 PIM_DONT_DEBUG_MSDP_EVENTS
;
6332 ALIAS(no_debug_msdp_events
, undebug_msdp_events_cmd
, "undebug msdp events",
6333 UNDEBUG_STR DEBUG_MSDP_STR DEBUG_MSDP_EVENTS_STR
)
6335 DEFUN (debug_msdp_packets
,
6336 debug_msdp_packets_cmd
,
6337 "debug msdp packets",
6340 DEBUG_MSDP_PACKETS_STR
)
6342 PIM_DO_DEBUG_MSDP_PACKETS
;
6346 DEFUN (no_debug_msdp_packets
,
6347 no_debug_msdp_packets_cmd
,
6348 "no debug msdp packets",
6352 DEBUG_MSDP_PACKETS_STR
)
6354 PIM_DONT_DEBUG_MSDP_PACKETS
;
6358 ALIAS(no_debug_msdp_packets
, undebug_msdp_packets_cmd
, "undebug msdp packets",
6359 UNDEBUG_STR DEBUG_MSDP_STR DEBUG_MSDP_PACKETS_STR
)
6361 DEFUN (show_debugging_pim
,
6362 show_debugging_pim_cmd
,
6363 "show debugging pim",
6368 pim_debug_config_write(vty
);
6372 static int interface_pim_use_src_cmd_worker(struct vty
*vty
, const char *source
)
6375 struct in_addr source_addr
;
6376 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6378 result
= inet_pton(AF_INET
, source
, &source_addr
);
6380 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", source
,
6381 errno
, safe_strerror(errno
));
6382 return CMD_WARNING_CONFIG_FAILED
;
6385 result
= pim_update_source_set(ifp
, source_addr
);
6389 case PIM_IFACE_NOT_FOUND
:
6390 vty_out(vty
, "Pim not enabled on this interface\n");
6392 case PIM_UPDATE_SOURCE_DUP
:
6393 vty_out(vty
, "%% Source already set to %s\n", source
);
6396 vty_out(vty
, "%% Source set failed\n");
6399 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
6402 DEFUN (interface_pim_use_source
,
6403 interface_pim_use_source_cmd
,
6404 "ip pim use-source A.B.C.D",
6406 "pim multicast routing\n"
6407 "Configure primary IP address\n"
6408 "source ip address\n")
6410 return interface_pim_use_src_cmd_worker(vty
, argv
[3]->arg
);
6413 DEFUN (interface_no_pim_use_source
,
6414 interface_no_pim_use_source_cmd
,
6415 "no ip pim use-source",
6418 "pim multicast routing\n"
6419 "Delete source IP address\n")
6421 return interface_pim_use_src_cmd_worker(vty
, "0.0.0.0");
6429 "Enables BFD support\n")
6431 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6432 struct pim_interface
*pim_ifp
= ifp
->info
;
6433 struct bfd_info
*bfd_info
= NULL
;
6437 bfd_info
= pim_ifp
->bfd_info
;
6439 if (!bfd_info
|| !CHECK_FLAG(bfd_info
->flags
, BFD_FLAG_PARAM_CFG
))
6440 pim_bfd_if_param_set(ifp
, BFD_DEF_MIN_RX
, BFD_DEF_MIN_TX
,
6441 BFD_DEF_DETECT_MULT
, 1);
6446 DEFUN (no_ip_pim_bfd
,
6452 "Disables BFD support\n")
6454 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6455 struct pim_interface
*pim_ifp
= ifp
->info
;
6460 if (pim_ifp
->bfd_info
) {
6461 pim_bfd_reg_dereg_all_nbr(ifp
, ZEBRA_BFD_DEST_DEREGISTER
);
6462 bfd_info_free(&(pim_ifp
->bfd_info
));
6468 DEFUN (ip_pim_bfd_param
,
6469 ip_pim_bfd_param_cmd
,
6470 "ip pim bfd (2-255) (50-60000) (50-60000)",
6473 "Enables BFD support\n"
6474 "Detect Multiplier\n"
6475 "Required min receive interval\n"
6476 "Desired min transmit interval\n")
6478 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6480 int idx_number_2
= 4;
6481 int idx_number_3
= 5;
6488 if ((ret
= bfd_validate_param(
6489 vty
, argv
[idx_number
]->arg
, argv
[idx_number_2
]->arg
,
6490 argv
[idx_number_3
]->arg
, &dm_val
, &rx_val
, &tx_val
))
6494 pim_bfd_if_param_set(ifp
, rx_val
, tx_val
, dm_val
, 0);
6499 ALIAS(no_ip_pim_bfd
, no_ip_pim_bfd_param_cmd
,
6500 "no ip pim bfd (2-255) (50-60000) (50-60000)", NO_STR IP_STR PIM_STR
6501 "Enables BFD support\n"
6502 "Detect Multiplier\n"
6503 "Required min receive interval\n"
6504 "Desired min transmit interval\n")
6506 static int ip_msdp_peer_cmd_worker(struct vty
*vty
, const char *peer
,
6509 enum pim_msdp_err result
;
6510 struct in_addr peer_addr
;
6511 struct in_addr local_addr
;
6513 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
6515 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s\n", peer
,
6516 errno
, safe_strerror(errno
));
6517 return CMD_WARNING_CONFIG_FAILED
;
6520 result
= inet_pton(AF_INET
, local
, &local_addr
);
6522 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", local
,
6523 errno
, safe_strerror(errno
));
6524 return CMD_WARNING_CONFIG_FAILED
;
6527 result
= pim_msdp_peer_add(peer_addr
, local_addr
, "default",
6530 case PIM_MSDP_ERR_NONE
:
6532 case PIM_MSDP_ERR_OOM
:
6533 vty_out(vty
, "%% Out of memory\n");
6535 case PIM_MSDP_ERR_PEER_EXISTS
:
6536 vty_out(vty
, "%% Peer exists\n");
6538 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
6539 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
6542 vty_out(vty
, "%% peer add failed\n");
6545 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
6548 DEFUN_HIDDEN (ip_msdp_peer
,
6550 "ip msdp peer A.B.C.D source A.B.C.D",
6553 "Configure MSDP peer\n"
6555 "Source address for TCP connection\n"
6556 "local ip address\n")
6558 return ip_msdp_peer_cmd_worker(vty
, argv
[3]->arg
, argv
[5]->arg
);
6561 static int ip_no_msdp_peer_cmd_worker(struct vty
*vty
, const char *peer
)
6563 enum pim_msdp_err result
;
6564 struct in_addr peer_addr
;
6566 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
6568 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s\n", peer
,
6569 errno
, safe_strerror(errno
));
6570 return CMD_WARNING_CONFIG_FAILED
;
6573 result
= pim_msdp_peer_del(peer_addr
);
6575 case PIM_MSDP_ERR_NONE
:
6577 case PIM_MSDP_ERR_NO_PEER
:
6578 vty_out(vty
, "%% Peer does not exist\n");
6581 vty_out(vty
, "%% peer del failed\n");
6584 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
6587 DEFUN_HIDDEN (no_ip_msdp_peer
,
6588 no_ip_msdp_peer_cmd
,
6589 "no ip msdp peer A.B.C.D",
6593 "Delete MSDP peer\n"
6594 "peer ip address\n")
6596 return ip_no_msdp_peer_cmd_worker(vty
, argv
[4]->arg
);
6599 static int ip_msdp_mesh_group_member_cmd_worker(struct vty
*vty
, const char *mg
,
6602 enum pim_msdp_err result
;
6603 struct in_addr mbr_ip
;
6605 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
6607 vty_out(vty
, "%% Bad member address %s: errno=%d: %s\n", mbr
,
6608 errno
, safe_strerror(errno
));
6609 return CMD_WARNING_CONFIG_FAILED
;
6612 result
= pim_msdp_mg_mbr_add(mg
, mbr_ip
);
6614 case PIM_MSDP_ERR_NONE
:
6616 case PIM_MSDP_ERR_OOM
:
6617 vty_out(vty
, "%% Out of memory\n");
6619 case PIM_MSDP_ERR_MG_MBR_EXISTS
:
6620 vty_out(vty
, "%% mesh-group member exists\n");
6622 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
6623 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
6626 vty_out(vty
, "%% member add failed\n");
6629 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
6632 DEFUN (ip_msdp_mesh_group_member
,
6633 ip_msdp_mesh_group_member_cmd
,
6634 "ip msdp mesh-group WORD member A.B.C.D",
6637 "Configure MSDP mesh-group\n"
6639 "mesh group member\n"
6640 "peer ip address\n")
6642 return ip_msdp_mesh_group_member_cmd_worker(vty
, argv
[3]->arg
,
6646 static int ip_no_msdp_mesh_group_member_cmd_worker(struct vty
*vty
,
6650 enum pim_msdp_err result
;
6651 struct in_addr mbr_ip
;
6653 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
6655 vty_out(vty
, "%% Bad member address %s: errno=%d: %s\n", mbr
,
6656 errno
, safe_strerror(errno
));
6657 return CMD_WARNING_CONFIG_FAILED
;
6660 result
= pim_msdp_mg_mbr_del(mg
, mbr_ip
);
6662 case PIM_MSDP_ERR_NONE
:
6664 case PIM_MSDP_ERR_NO_MG
:
6665 vty_out(vty
, "%% mesh-group does not exist\n");
6667 case PIM_MSDP_ERR_NO_MG_MBR
:
6668 vty_out(vty
, "%% mesh-group member does not exist\n");
6671 vty_out(vty
, "%% mesh-group member del failed\n");
6674 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
6676 DEFUN (no_ip_msdp_mesh_group_member
,
6677 no_ip_msdp_mesh_group_member_cmd
,
6678 "no ip msdp mesh-group WORD member A.B.C.D",
6682 "Delete MSDP mesh-group member\n"
6684 "mesh group member\n"
6685 "peer ip address\n")
6687 return ip_no_msdp_mesh_group_member_cmd_worker(vty
, argv
[4]->arg
,
6691 static int ip_msdp_mesh_group_source_cmd_worker(struct vty
*vty
, const char *mg
,
6694 enum pim_msdp_err result
;
6695 struct in_addr src_ip
;
6697 result
= inet_pton(AF_INET
, src
, &src_ip
);
6699 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", src
,
6700 errno
, safe_strerror(errno
));
6701 return CMD_WARNING_CONFIG_FAILED
;
6704 result
= pim_msdp_mg_src_add(mg
, src_ip
);
6706 case PIM_MSDP_ERR_NONE
:
6708 case PIM_MSDP_ERR_OOM
:
6709 vty_out(vty
, "%% Out of memory\n");
6711 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
6712 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
6715 vty_out(vty
, "%% source add failed\n");
6718 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
6722 DEFUN (ip_msdp_mesh_group_source
,
6723 ip_msdp_mesh_group_source_cmd
,
6724 "ip msdp mesh-group WORD source A.B.C.D",
6727 "Configure MSDP mesh-group\n"
6729 "mesh group local address\n"
6730 "source ip address for the TCP connection\n")
6732 return ip_msdp_mesh_group_source_cmd_worker(vty
, argv
[3]->arg
,
6736 static int ip_no_msdp_mesh_group_source_cmd_worker(struct vty
*vty
,
6739 enum pim_msdp_err result
;
6741 result
= pim_msdp_mg_src_del(mg
);
6743 case PIM_MSDP_ERR_NONE
:
6745 case PIM_MSDP_ERR_NO_MG
:
6746 vty_out(vty
, "%% mesh-group does not exist\n");
6749 vty_out(vty
, "%% mesh-group source del failed\n");
6752 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
6755 static int ip_no_msdp_mesh_group_cmd_worker(struct vty
*vty
, const char *mg
)
6757 enum pim_msdp_err result
;
6759 result
= pim_msdp_mg_del(mg
);
6761 case PIM_MSDP_ERR_NONE
:
6763 case PIM_MSDP_ERR_NO_MG
:
6764 vty_out(vty
, "%% mesh-group does not exist\n");
6767 vty_out(vty
, "%% mesh-group source del failed\n");
6770 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
6773 DEFUN (no_ip_msdp_mesh_group_source
,
6774 no_ip_msdp_mesh_group_source_cmd
,
6775 "no ip msdp mesh-group WORD source [A.B.C.D]",
6779 "Delete MSDP mesh-group source\n"
6781 "mesh group source\n"
6782 "mesh group local address\n")
6785 return ip_no_msdp_mesh_group_cmd_worker(vty
, argv
[6]->arg
);
6787 return ip_no_msdp_mesh_group_source_cmd_worker(vty
,
6791 static void print_empty_json_obj(struct vty
*vty
)
6794 json
= json_object_new_object();
6795 vty_out(vty
, "%s\n",
6796 json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
));
6797 json_object_free(json
);
6800 static void ip_msdp_show_mesh_group(struct vty
*vty
, u_char uj
)
6802 struct listnode
*mbrnode
;
6803 struct pim_msdp_mg_mbr
*mbr
;
6804 struct pim_msdp_mg
*mg
= msdp
->mg
;
6805 char mbr_str
[INET_ADDRSTRLEN
];
6806 char src_str
[INET_ADDRSTRLEN
];
6807 char state_str
[PIM_MSDP_STATE_STRLEN
];
6808 enum pim_msdp_peer_state state
;
6809 json_object
*json
= NULL
;
6810 json_object
*json_mg_row
= NULL
;
6811 json_object
*json_members
= NULL
;
6812 json_object
*json_row
= NULL
;
6816 print_empty_json_obj(vty
);
6820 pim_inet4_dump("<source?>", mg
->src_ip
, src_str
, sizeof(src_str
));
6822 json
= json_object_new_object();
6823 /* currently there is only one mesh group but we should still
6825 * it a dict with mg-name as key */
6826 json_mg_row
= json_object_new_object();
6827 json_object_string_add(json_mg_row
, "name",
6828 mg
->mesh_group_name
);
6829 json_object_string_add(json_mg_row
, "source", src_str
);
6831 vty_out(vty
, "Mesh group : %s\n", mg
->mesh_group_name
);
6832 vty_out(vty
, " Source : %s\n", src_str
);
6833 vty_out(vty
, " Member State\n");
6836 for (ALL_LIST_ELEMENTS_RO(mg
->mbr_list
, mbrnode
, mbr
)) {
6837 pim_inet4_dump("<mbr?>", mbr
->mbr_ip
, mbr_str
, sizeof(mbr_str
));
6839 state
= mbr
->mp
->state
;
6841 state
= PIM_MSDP_DISABLED
;
6843 pim_msdp_state_dump(state
, state_str
, sizeof(state_str
));
6845 json_row
= json_object_new_object();
6846 json_object_string_add(json_row
, "member", mbr_str
);
6847 json_object_string_add(json_row
, "state", state_str
);
6848 if (!json_members
) {
6849 json_members
= json_object_new_object();
6850 json_object_object_add(json_mg_row
, "members",
6853 json_object_object_add(json_members
, mbr_str
, json_row
);
6855 vty_out(vty
, " %-15s %11s\n", mbr_str
, state_str
);
6860 json_object_object_add(json
, mg
->mesh_group_name
, json_mg_row
);
6861 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
6862 json
, JSON_C_TO_STRING_PRETTY
));
6863 json_object_free(json
);
6867 DEFUN (show_ip_msdp_mesh_group
,
6868 show_ip_msdp_mesh_group_cmd
,
6869 "show ip msdp mesh-group [json]",
6873 "MSDP mesh-group information\n"
6874 "JavaScript Object Notation\n")
6876 u_char uj
= use_json(argc
, argv
);
6877 ip_msdp_show_mesh_group(vty
, uj
);
6882 static void ip_msdp_show_peers(struct vty
*vty
, u_char uj
)
6884 struct listnode
*mpnode
;
6885 struct pim_msdp_peer
*mp
;
6886 char peer_str
[INET_ADDRSTRLEN
];
6887 char local_str
[INET_ADDRSTRLEN
];
6888 char state_str
[PIM_MSDP_STATE_STRLEN
];
6889 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
6891 json_object
*json
= NULL
;
6892 json_object
*json_row
= NULL
;
6896 json
= json_object_new_object();
6899 "Peer Local State Uptime SaCnt\n");
6902 for (ALL_LIST_ELEMENTS_RO(msdp
->peer_list
, mpnode
, mp
)) {
6903 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
6904 now
= pim_time_monotonic_sec();
6905 pim_time_uptime(timebuf
, sizeof(timebuf
),
6908 strcpy(timebuf
, "-");
6910 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
6911 pim_inet4_dump("<local?>", mp
->local
, local_str
,
6913 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
6915 json_row
= json_object_new_object();
6916 json_object_string_add(json_row
, "peer", peer_str
);
6917 json_object_string_add(json_row
, "local", local_str
);
6918 json_object_string_add(json_row
, "state", state_str
);
6919 json_object_string_add(json_row
, "upTime", timebuf
);
6920 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
6921 json_object_object_add(json
, peer_str
, json_row
);
6923 vty_out(vty
, "%-15s %15s %11s %8s %6d\n", peer_str
,
6924 local_str
, state_str
, timebuf
, mp
->sa_cnt
);
6929 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
6930 json
, JSON_C_TO_STRING_PRETTY
));
6931 json_object_free(json
);
6935 static void ip_msdp_show_peers_detail(struct vty
*vty
, const char *peer
,
6938 struct listnode
*mpnode
;
6939 struct pim_msdp_peer
*mp
;
6940 char peer_str
[INET_ADDRSTRLEN
];
6941 char local_str
[INET_ADDRSTRLEN
];
6942 char state_str
[PIM_MSDP_STATE_STRLEN
];
6943 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
6944 char katimer
[PIM_MSDP_TIMER_STRLEN
];
6945 char crtimer
[PIM_MSDP_TIMER_STRLEN
];
6946 char holdtimer
[PIM_MSDP_TIMER_STRLEN
];
6948 json_object
*json
= NULL
;
6949 json_object
*json_row
= NULL
;
6952 json
= json_object_new_object();
6955 for (ALL_LIST_ELEMENTS_RO(msdp
->peer_list
, mpnode
, mp
)) {
6956 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
6957 if (strcmp(peer
, "detail") && strcmp(peer
, peer_str
))
6960 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
6961 now
= pim_time_monotonic_sec();
6962 pim_time_uptime(timebuf
, sizeof(timebuf
),
6965 strcpy(timebuf
, "-");
6967 pim_inet4_dump("<local?>", mp
->local
, local_str
,
6969 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
6970 pim_time_timer_to_hhmmss(katimer
, sizeof(katimer
),
6972 pim_time_timer_to_hhmmss(crtimer
, sizeof(crtimer
),
6974 pim_time_timer_to_hhmmss(holdtimer
, sizeof(holdtimer
),
6978 json_row
= json_object_new_object();
6979 json_object_string_add(json_row
, "peer", peer_str
);
6980 json_object_string_add(json_row
, "local", local_str
);
6981 json_object_string_add(json_row
, "meshGroupName",
6982 mp
->mesh_group_name
);
6983 json_object_string_add(json_row
, "state", state_str
);
6984 json_object_string_add(json_row
, "upTime", timebuf
);
6985 json_object_string_add(json_row
, "keepAliveTimer",
6987 json_object_string_add(json_row
, "connRetryTimer",
6989 json_object_string_add(json_row
, "holdTimer",
6991 json_object_string_add(json_row
, "lastReset",
6993 json_object_int_add(json_row
, "connAttempts",
6995 json_object_int_add(json_row
, "establishedChanges",
6997 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
6998 json_object_int_add(json_row
, "kaSent", mp
->ka_tx_cnt
);
6999 json_object_int_add(json_row
, "kaRcvd", mp
->ka_rx_cnt
);
7000 json_object_int_add(json_row
, "saSent", mp
->sa_tx_cnt
);
7001 json_object_int_add(json_row
, "saRcvd", mp
->sa_rx_cnt
);
7002 json_object_object_add(json
, peer_str
, json_row
);
7004 vty_out(vty
, "Peer : %s\n", peer_str
);
7005 vty_out(vty
, " Local : %s\n", local_str
);
7006 vty_out(vty
, " Mesh Group : %s\n",
7007 mp
->mesh_group_name
);
7008 vty_out(vty
, " State : %s\n", state_str
);
7009 vty_out(vty
, " Uptime : %s\n", timebuf
);
7011 vty_out(vty
, " Keepalive Timer : %s\n", katimer
);
7012 vty_out(vty
, " Conn Retry Timer : %s\n", crtimer
);
7013 vty_out(vty
, " Hold Timer : %s\n", holdtimer
);
7014 vty_out(vty
, " Last Reset : %s\n",
7016 vty_out(vty
, " Conn Attempts : %d\n",
7018 vty_out(vty
, " Established Changes : %d\n",
7020 vty_out(vty
, " SA Count : %d\n",
7022 vty_out(vty
, " Statistics :\n");
7025 vty_out(vty
, " Keepalives : %10d %10d\n",
7026 mp
->ka_tx_cnt
, mp
->ka_rx_cnt
);
7027 vty_out(vty
, " SAs : %10d %10d\n",
7028 mp
->sa_tx_cnt
, mp
->sa_rx_cnt
);
7034 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
7035 json
, JSON_C_TO_STRING_PRETTY
));
7036 json_object_free(json
);
7040 DEFUN (show_ip_msdp_peer_detail
,
7041 show_ip_msdp_peer_detail_cmd
,
7042 "show ip msdp peer [detail|A.B.C.D] [json]",
7046 "MSDP peer information\n"
7049 "JavaScript Object Notation\n")
7051 u_char uj
= use_json(argc
, argv
);
7056 ip_msdp_show_peers_detail(vty
, argv
[4]->arg
, uj
);
7058 ip_msdp_show_peers(vty
, uj
);
7063 static void ip_msdp_show_sa(struct vty
*vty
, u_char uj
)
7065 struct listnode
*sanode
;
7066 struct pim_msdp_sa
*sa
;
7067 char src_str
[INET_ADDRSTRLEN
];
7068 char grp_str
[INET_ADDRSTRLEN
];
7069 char rp_str
[INET_ADDRSTRLEN
];
7070 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
7074 json_object
*json
= NULL
;
7075 json_object
*json_group
= NULL
;
7076 json_object
*json_row
= NULL
;
7079 json
= json_object_new_object();
7082 "Source Group RP Local SPT Uptime\n");
7085 for (ALL_LIST_ELEMENTS_RO(msdp
->sa_list
, sanode
, sa
)) {
7086 now
= pim_time_monotonic_sec();
7087 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
7088 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
7089 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
7090 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
7091 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
7093 strcpy(spt_str
, "yes");
7095 strcpy(spt_str
, "no");
7098 strcpy(rp_str
, "-");
7099 strcpy(spt_str
, "-");
7101 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
7102 strcpy(local_str
, "yes");
7104 strcpy(local_str
, "no");
7107 json_object_object_get_ex(json
, grp_str
, &json_group
);
7110 json_group
= json_object_new_object();
7111 json_object_object_add(json
, grp_str
,
7115 json_row
= json_object_new_object();
7116 json_object_string_add(json_row
, "source", src_str
);
7117 json_object_string_add(json_row
, "group", grp_str
);
7118 json_object_string_add(json_row
, "rp", rp_str
);
7119 json_object_string_add(json_row
, "local", local_str
);
7120 json_object_string_add(json_row
, "sptSetup", spt_str
);
7121 json_object_string_add(json_row
, "upTime", timebuf
);
7122 json_object_object_add(json_group
, src_str
, json_row
);
7124 vty_out(vty
, "%-15s %15s %15s %5c %3c %8s\n",
7125 src_str
, grp_str
, rp_str
, local_str
[0],
7126 spt_str
[0], timebuf
);
7132 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
7133 json
, JSON_C_TO_STRING_PRETTY
));
7134 json_object_free(json
);
7138 static void ip_msdp_show_sa_entry_detail(struct pim_msdp_sa
*sa
,
7139 const char *src_str
,
7140 const char *grp_str
, struct vty
*vty
,
7141 u_char uj
, json_object
*json
)
7143 char rp_str
[INET_ADDRSTRLEN
];
7144 char peer_str
[INET_ADDRSTRLEN
];
7145 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
7148 char statetimer
[PIM_MSDP_TIMER_STRLEN
];
7150 json_object
*json_group
= NULL
;
7151 json_object
*json_row
= NULL
;
7153 now
= pim_time_monotonic_sec();
7154 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
7155 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
7156 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
7157 pim_inet4_dump("<peer?>", sa
->peer
, peer_str
, sizeof(peer_str
));
7159 strcpy(spt_str
, "yes");
7161 strcpy(spt_str
, "no");
7164 strcpy(rp_str
, "-");
7165 strcpy(peer_str
, "-");
7166 strcpy(spt_str
, "-");
7168 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
7169 strcpy(local_str
, "yes");
7171 strcpy(local_str
, "no");
7173 pim_time_timer_to_hhmmss(statetimer
, sizeof(statetimer
),
7174 sa
->sa_state_timer
);
7176 json_object_object_get_ex(json
, grp_str
, &json_group
);
7179 json_group
= json_object_new_object();
7180 json_object_object_add(json
, grp_str
, json_group
);
7183 json_row
= json_object_new_object();
7184 json_object_string_add(json_row
, "source", src_str
);
7185 json_object_string_add(json_row
, "group", grp_str
);
7186 json_object_string_add(json_row
, "rp", rp_str
);
7187 json_object_string_add(json_row
, "local", local_str
);
7188 json_object_string_add(json_row
, "sptSetup", spt_str
);
7189 json_object_string_add(json_row
, "upTime", timebuf
);
7190 json_object_string_add(json_row
, "stateTimer", statetimer
);
7191 json_object_object_add(json_group
, src_str
, json_row
);
7193 vty_out(vty
, "SA : %s\n", sa
->sg_str
);
7194 vty_out(vty
, " RP : %s\n", rp_str
);
7195 vty_out(vty
, " Peer : %s\n", peer_str
);
7196 vty_out(vty
, " Local : %s\n", local_str
);
7197 vty_out(vty
, " SPT Setup : %s\n", spt_str
);
7198 vty_out(vty
, " Uptime : %s\n", timebuf
);
7199 vty_out(vty
, " State Timer : %s\n", statetimer
);
7204 static void ip_msdp_show_sa_detail(struct vty
*vty
, u_char uj
)
7206 struct listnode
*sanode
;
7207 struct pim_msdp_sa
*sa
;
7208 char src_str
[INET_ADDRSTRLEN
];
7209 char grp_str
[INET_ADDRSTRLEN
];
7210 json_object
*json
= NULL
;
7213 json
= json_object_new_object();
7216 for (ALL_LIST_ELEMENTS_RO(msdp
->sa_list
, sanode
, sa
)) {
7217 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
7218 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
7219 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
, uj
,
7224 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
7225 json
, JSON_C_TO_STRING_PRETTY
));
7226 json_object_free(json
);
7230 DEFUN (show_ip_msdp_sa_detail
,
7231 show_ip_msdp_sa_detail_cmd
,
7232 "show ip msdp sa detail [json]",
7236 "MSDP active-source information\n"
7238 "JavaScript Object Notation\n")
7240 u_char uj
= use_json(argc
, argv
);
7241 ip_msdp_show_sa_detail(vty
, uj
);
7246 static void ip_msdp_show_sa_addr(struct vty
*vty
, const char *addr
, u_char uj
)
7248 struct listnode
*sanode
;
7249 struct pim_msdp_sa
*sa
;
7250 char src_str
[INET_ADDRSTRLEN
];
7251 char grp_str
[INET_ADDRSTRLEN
];
7252 json_object
*json
= NULL
;
7255 json
= json_object_new_object();
7258 for (ALL_LIST_ELEMENTS_RO(msdp
->sa_list
, sanode
, sa
)) {
7259 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
7260 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
7261 if (!strcmp(addr
, src_str
) || !strcmp(addr
, grp_str
)) {
7262 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
,
7268 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
7269 json
, JSON_C_TO_STRING_PRETTY
));
7270 json_object_free(json
);
7274 static void ip_msdp_show_sa_sg(struct vty
*vty
, const char *src
,
7275 const char *grp
, u_char uj
)
7277 struct listnode
*sanode
;
7278 struct pim_msdp_sa
*sa
;
7279 char src_str
[INET_ADDRSTRLEN
];
7280 char grp_str
[INET_ADDRSTRLEN
];
7281 json_object
*json
= NULL
;
7284 json
= json_object_new_object();
7287 for (ALL_LIST_ELEMENTS_RO(msdp
->sa_list
, sanode
, sa
)) {
7288 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
7289 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
7290 if (!strcmp(src
, src_str
) && !strcmp(grp
, grp_str
)) {
7291 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
,
7297 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
7298 json
, JSON_C_TO_STRING_PRETTY
));
7299 json_object_free(json
);
7303 DEFUN (show_ip_msdp_sa_sg
,
7304 show_ip_msdp_sa_sg_cmd
,
7305 "show ip msdp sa [A.B.C.D [A.B.C.D]] [json]",
7309 "MSDP active-source information\n"
7310 "source or group ip\n"
7312 "JavaScript Object Notation\n")
7314 u_char uj
= use_json(argc
, argv
);
7317 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
++]->arg
7319 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
)
7323 if (src_ip
&& grp_ip
)
7324 ip_msdp_show_sa_sg(vty
, src_ip
, grp_ip
, uj
);
7326 ip_msdp_show_sa_addr(vty
, src_ip
, uj
);
7328 ip_msdp_show_sa(vty
, uj
);
7335 install_node(&pim_global_node
, pim_global_config_write
); /* PIM_NODE */
7336 install_node(&interface_node
,
7337 pim_interface_config_write
); /* INTERFACE_NODE */
7340 install_node(&debug_node
, pim_debug_config_write
);
7342 install_element(CONFIG_NODE
, &ip_multicast_routing_cmd
);
7343 install_element(CONFIG_NODE
, &no_ip_multicast_routing_cmd
);
7344 install_element(CONFIG_NODE
, &ip_pim_rp_cmd
);
7345 install_element(CONFIG_NODE
, &no_ip_pim_rp_cmd
);
7346 install_element(CONFIG_NODE
, &ip_pim_rp_prefix_list_cmd
);
7347 install_element(CONFIG_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
7348 install_element(CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_cmd
);
7349 install_element(CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_name_cmd
);
7350 install_element(CONFIG_NODE
, &ip_pim_ssm_prefix_list_cmd
);
7351 install_element(CONFIG_NODE
, &ip_pim_register_suppress_cmd
);
7352 install_element(CONFIG_NODE
, &no_ip_pim_register_suppress_cmd
);
7353 install_element(CONFIG_NODE
, &ip_pim_spt_switchover_infinity_cmd
);
7354 install_element(CONFIG_NODE
, &ip_pim_spt_switchover_infinity_plist_cmd
);
7355 install_element(CONFIG_NODE
, &no_ip_pim_spt_switchover_infinity_cmd
);
7356 install_element(CONFIG_NODE
,
7357 &no_ip_pim_spt_switchover_infinity_plist_cmd
);
7358 install_element(CONFIG_NODE
, &ip_pim_joinprune_time_cmd
);
7359 install_element(CONFIG_NODE
, &no_ip_pim_joinprune_time_cmd
);
7360 install_element(CONFIG_NODE
, &ip_pim_keep_alive_cmd
);
7361 install_element(CONFIG_NODE
, &no_ip_pim_keep_alive_cmd
);
7362 install_element(CONFIG_NODE
, &ip_pim_packets_cmd
);
7363 install_element(CONFIG_NODE
, &no_ip_pim_packets_cmd
);
7364 install_element(CONFIG_NODE
, &ip_pim_v6_secondary_cmd
);
7365 install_element(CONFIG_NODE
, &no_ip_pim_v6_secondary_cmd
);
7366 install_element(CONFIG_NODE
, &ip_ssmpingd_cmd
);
7367 install_element(CONFIG_NODE
, &no_ip_ssmpingd_cmd
);
7368 install_element(CONFIG_NODE
, &ip_msdp_peer_cmd
);
7369 install_element(CONFIG_NODE
, &no_ip_msdp_peer_cmd
);
7370 install_element(CONFIG_NODE
, &ip_pim_ecmp_cmd
);
7371 install_element(CONFIG_NODE
, &no_ip_pim_ecmp_cmd
);
7372 install_element(CONFIG_NODE
, &ip_pim_ecmp_rebalance_cmd
);
7373 install_element(CONFIG_NODE
, &no_ip_pim_ecmp_rebalance_cmd
);
7375 install_element(INTERFACE_NODE
, &interface_ip_igmp_cmd
);
7376 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_cmd
);
7377 install_element(INTERFACE_NODE
, &interface_ip_igmp_join_cmd
);
7378 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_join_cmd
);
7379 install_element(INTERFACE_NODE
, &interface_ip_igmp_version_cmd
);
7380 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_version_cmd
);
7381 install_element(INTERFACE_NODE
, &interface_ip_igmp_query_interval_cmd
);
7382 install_element(INTERFACE_NODE
,
7383 &interface_no_ip_igmp_query_interval_cmd
);
7384 install_element(INTERFACE_NODE
,
7385 &interface_ip_igmp_query_max_response_time_cmd
);
7386 install_element(INTERFACE_NODE
,
7387 &interface_no_ip_igmp_query_max_response_time_cmd
);
7388 install_element(INTERFACE_NODE
,
7389 &interface_ip_igmp_query_max_response_time_dsec_cmd
);
7390 install_element(INTERFACE_NODE
,
7391 &interface_no_ip_igmp_query_max_response_time_dsec_cmd
);
7392 install_element(INTERFACE_NODE
, &interface_ip_pim_ssm_cmd
);
7393 install_element(INTERFACE_NODE
, &interface_no_ip_pim_ssm_cmd
);
7394 install_element(INTERFACE_NODE
, &interface_ip_pim_sm_cmd
);
7395 install_element(INTERFACE_NODE
, &interface_no_ip_pim_sm_cmd
);
7396 install_element(INTERFACE_NODE
, &interface_ip_pim_drprio_cmd
);
7397 install_element(INTERFACE_NODE
, &interface_no_ip_pim_drprio_cmd
);
7398 install_element(INTERFACE_NODE
, &interface_ip_pim_hello_cmd
);
7399 install_element(INTERFACE_NODE
, &interface_no_ip_pim_hello_cmd
);
7401 // Static mroutes NEB
7402 install_element(INTERFACE_NODE
, &interface_ip_mroute_cmd
);
7403 install_element(INTERFACE_NODE
, &interface_ip_mroute_source_cmd
);
7404 install_element(INTERFACE_NODE
, &interface_no_ip_mroute_cmd
);
7405 install_element(INTERFACE_NODE
, &interface_no_ip_mroute_source_cmd
);
7407 install_element(VIEW_NODE
, &show_ip_igmp_interface_cmd
);
7408 install_element(VIEW_NODE
, &show_ip_igmp_join_cmd
);
7409 install_element(VIEW_NODE
, &show_ip_igmp_groups_cmd
);
7410 install_element(VIEW_NODE
, &show_ip_igmp_groups_retransmissions_cmd
);
7411 install_element(VIEW_NODE
, &show_ip_igmp_sources_cmd
);
7412 install_element(VIEW_NODE
, &show_ip_igmp_sources_retransmissions_cmd
);
7413 install_element(VIEW_NODE
, &show_ip_pim_assert_cmd
);
7414 install_element(VIEW_NODE
, &show_ip_pim_assert_internal_cmd
);
7415 install_element(VIEW_NODE
, &show_ip_pim_assert_metric_cmd
);
7416 install_element(VIEW_NODE
, &show_ip_pim_assert_winner_metric_cmd
);
7417 install_element(VIEW_NODE
, &show_ip_pim_interface_traffic_cmd
);
7418 install_element(VIEW_NODE
, &show_ip_pim_interface_cmd
);
7419 install_element(VIEW_NODE
, &show_ip_pim_join_cmd
);
7420 install_element(VIEW_NODE
, &show_ip_pim_local_membership_cmd
);
7421 install_element(VIEW_NODE
, &show_ip_pim_neighbor_cmd
);
7422 install_element(VIEW_NODE
, &show_ip_pim_rpf_cmd
);
7423 install_element(VIEW_NODE
, &show_ip_pim_secondary_cmd
);
7424 install_element(VIEW_NODE
, &show_ip_pim_state_cmd
);
7425 install_element(VIEW_NODE
, &show_ip_pim_upstream_cmd
);
7426 install_element(VIEW_NODE
, &show_ip_pim_upstream_join_desired_cmd
);
7427 install_element(VIEW_NODE
, &show_ip_pim_upstream_rpf_cmd
);
7428 install_element(VIEW_NODE
, &show_ip_pim_rp_cmd
);
7429 install_element(VIEW_NODE
, &show_ip_multicast_cmd
);
7430 install_element(VIEW_NODE
, &show_ip_mroute_cmd
);
7431 install_element(VIEW_NODE
, &show_ip_mroute_count_cmd
);
7432 install_element(VIEW_NODE
, &show_ip_rib_cmd
);
7433 install_element(VIEW_NODE
, &show_ip_ssmpingd_cmd
);
7434 install_element(VIEW_NODE
, &show_debugging_pim_cmd
);
7435 install_element(VIEW_NODE
, &show_ip_pim_nexthop_cmd
);
7436 install_element(VIEW_NODE
, &show_ip_pim_nexthop_lookup_cmd
);
7438 install_element(ENABLE_NODE
, &clear_ip_interfaces_cmd
);
7439 install_element(ENABLE_NODE
, &clear_ip_igmp_interfaces_cmd
);
7440 install_element(ENABLE_NODE
, &clear_ip_mroute_cmd
);
7441 install_element(ENABLE_NODE
, &clear_ip_pim_interfaces_cmd
);
7442 install_element(ENABLE_NODE
, &clear_ip_pim_interface_traffic_cmd
);
7443 install_element(ENABLE_NODE
, &clear_ip_pim_oil_cmd
);
7445 install_element(ENABLE_NODE
, &debug_igmp_cmd
);
7446 install_element(ENABLE_NODE
, &no_debug_igmp_cmd
);
7447 install_element(ENABLE_NODE
, &debug_igmp_events_cmd
);
7448 install_element(ENABLE_NODE
, &no_debug_igmp_events_cmd
);
7449 install_element(ENABLE_NODE
, &debug_igmp_packets_cmd
);
7450 install_element(ENABLE_NODE
, &no_debug_igmp_packets_cmd
);
7451 install_element(ENABLE_NODE
, &debug_igmp_trace_cmd
);
7452 install_element(ENABLE_NODE
, &no_debug_igmp_trace_cmd
);
7453 install_element(ENABLE_NODE
, &debug_mroute_cmd
);
7454 install_element(ENABLE_NODE
, &debug_mroute_detail_cmd
);
7455 install_element(ENABLE_NODE
, &no_debug_mroute_cmd
);
7456 install_element(ENABLE_NODE
, &no_debug_mroute_detail_cmd
);
7457 install_element(ENABLE_NODE
, &debug_static_cmd
);
7458 install_element(ENABLE_NODE
, &no_debug_static_cmd
);
7459 install_element(ENABLE_NODE
, &debug_pim_cmd
);
7460 install_element(ENABLE_NODE
, &no_debug_pim_cmd
);
7461 install_element(ENABLE_NODE
, &debug_pim_events_cmd
);
7462 install_element(ENABLE_NODE
, &no_debug_pim_events_cmd
);
7463 install_element(ENABLE_NODE
, &debug_pim_packets_cmd
);
7464 install_element(ENABLE_NODE
, &no_debug_pim_packets_cmd
);
7465 install_element(ENABLE_NODE
, &debug_pim_packetdump_send_cmd
);
7466 install_element(ENABLE_NODE
, &no_debug_pim_packetdump_send_cmd
);
7467 install_element(ENABLE_NODE
, &debug_pim_packetdump_recv_cmd
);
7468 install_element(ENABLE_NODE
, &no_debug_pim_packetdump_recv_cmd
);
7469 install_element(ENABLE_NODE
, &debug_pim_trace_cmd
);
7470 install_element(ENABLE_NODE
, &no_debug_pim_trace_cmd
);
7471 install_element(ENABLE_NODE
, &debug_ssmpingd_cmd
);
7472 install_element(ENABLE_NODE
, &no_debug_ssmpingd_cmd
);
7473 install_element(ENABLE_NODE
, &debug_pim_zebra_cmd
);
7474 install_element(ENABLE_NODE
, &no_debug_pim_zebra_cmd
);
7475 install_element(ENABLE_NODE
, &debug_msdp_cmd
);
7476 install_element(ENABLE_NODE
, &no_debug_msdp_cmd
);
7477 install_element(ENABLE_NODE
, &undebug_msdp_cmd
);
7478 install_element(ENABLE_NODE
, &debug_msdp_events_cmd
);
7479 install_element(ENABLE_NODE
, &no_debug_msdp_events_cmd
);
7480 install_element(ENABLE_NODE
, &undebug_msdp_events_cmd
);
7481 install_element(ENABLE_NODE
, &debug_msdp_packets_cmd
);
7482 install_element(ENABLE_NODE
, &no_debug_msdp_packets_cmd
);
7483 install_element(ENABLE_NODE
, &undebug_msdp_packets_cmd
);
7485 install_element(CONFIG_NODE
, &debug_igmp_cmd
);
7486 install_element(CONFIG_NODE
, &no_debug_igmp_cmd
);
7487 install_element(CONFIG_NODE
, &debug_igmp_events_cmd
);
7488 install_element(CONFIG_NODE
, &no_debug_igmp_events_cmd
);
7489 install_element(CONFIG_NODE
, &debug_igmp_packets_cmd
);
7490 install_element(CONFIG_NODE
, &no_debug_igmp_packets_cmd
);
7491 install_element(CONFIG_NODE
, &debug_igmp_trace_cmd
);
7492 install_element(CONFIG_NODE
, &no_debug_igmp_trace_cmd
);
7493 install_element(CONFIG_NODE
, &debug_mroute_cmd
);
7494 install_element(CONFIG_NODE
, &debug_mroute_detail_cmd
);
7495 install_element(CONFIG_NODE
, &no_debug_mroute_cmd
);
7496 install_element(CONFIG_NODE
, &no_debug_mroute_detail_cmd
);
7497 install_element(CONFIG_NODE
, &debug_static_cmd
);
7498 install_element(CONFIG_NODE
, &no_debug_static_cmd
);
7499 install_element(CONFIG_NODE
, &debug_pim_cmd
);
7500 install_element(CONFIG_NODE
, &no_debug_pim_cmd
);
7501 install_element(CONFIG_NODE
, &debug_pim_events_cmd
);
7502 install_element(CONFIG_NODE
, &no_debug_pim_events_cmd
);
7503 install_element(CONFIG_NODE
, &debug_pim_packets_cmd
);
7504 install_element(CONFIG_NODE
, &no_debug_pim_packets_cmd
);
7505 install_element(CONFIG_NODE
, &debug_pim_trace_cmd
);
7506 install_element(CONFIG_NODE
, &no_debug_pim_trace_cmd
);
7507 install_element(CONFIG_NODE
, &debug_ssmpingd_cmd
);
7508 install_element(CONFIG_NODE
, &no_debug_ssmpingd_cmd
);
7509 install_element(CONFIG_NODE
, &debug_pim_zebra_cmd
);
7510 install_element(CONFIG_NODE
, &no_debug_pim_zebra_cmd
);
7511 install_element(CONFIG_NODE
, &debug_msdp_cmd
);
7512 install_element(CONFIG_NODE
, &no_debug_msdp_cmd
);
7513 install_element(CONFIG_NODE
, &undebug_msdp_cmd
);
7514 install_element(CONFIG_NODE
, &debug_msdp_events_cmd
);
7515 install_element(CONFIG_NODE
, &no_debug_msdp_events_cmd
);
7516 install_element(CONFIG_NODE
, &undebug_msdp_events_cmd
);
7517 install_element(CONFIG_NODE
, &debug_msdp_packets_cmd
);
7518 install_element(CONFIG_NODE
, &no_debug_msdp_packets_cmd
);
7519 install_element(CONFIG_NODE
, &undebug_msdp_packets_cmd
);
7520 install_element(CONFIG_NODE
, &ip_msdp_mesh_group_member_cmd
);
7521 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_member_cmd
);
7522 install_element(CONFIG_NODE
, &ip_msdp_mesh_group_source_cmd
);
7523 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_source_cmd
);
7524 install_element(VIEW_NODE
, &show_ip_msdp_peer_detail_cmd
);
7525 install_element(VIEW_NODE
, &show_ip_msdp_sa_detail_cmd
);
7526 install_element(VIEW_NODE
, &show_ip_msdp_sa_sg_cmd
);
7527 install_element(VIEW_NODE
, &show_ip_msdp_mesh_group_cmd
);
7528 install_element(VIEW_NODE
, &show_ip_pim_ssm_range_cmd
);
7529 install_element(VIEW_NODE
, &show_ip_pim_group_type_cmd
);
7530 install_element(INTERFACE_NODE
, &interface_pim_use_source_cmd
);
7531 install_element(INTERFACE_NODE
, &interface_no_pim_use_source_cmd
);
7532 /* Install BFD command */
7533 install_element(INTERFACE_NODE
, &ip_pim_bfd_cmd
);
7534 install_element(INTERFACE_NODE
, &ip_pim_bfd_param_cmd
);
7535 install_element(INTERFACE_NODE
, &no_ip_pim_bfd_cmd
);
7536 install_element(INTERFACE_NODE
, &no_ip_pim_bfd_param_cmd
);