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(pimg
->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(pimg
->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(pimg
->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(pimg
->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(pimg
->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 pim_instance
*pim
, struct vty
*vty
)
4217 struct listnode
*node
;
4218 struct ssmpingd_sock
*ss
;
4222 "Source Socket Address Port Uptime Requests\n");
4224 if (!pim
->ssmpingd_list
)
4227 now
= pim_time_monotonic_sec();
4229 for (ALL_LIST_ELEMENTS_RO(pim
->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
,
4264 show_ssmpingd(pimg
, vty
);
4268 static int pim_rp_cmd_worker(struct vty
*vty
, struct pim_instance
*pim
,
4269 const char *rp
, const char *group
,
4274 result
= pim_rp_new(pim
, rp
, group
, plist
);
4276 if (result
== PIM_MALLOC_FAIL
) {
4277 vty_out(vty
, "%% Out of memory\n");
4278 return CMD_WARNING_CONFIG_FAILED
;
4281 if (result
== PIM_GROUP_BAD_ADDRESS
) {
4282 vty_out(vty
, "%% Bad group address specified: %s\n", group
);
4283 return CMD_WARNING_CONFIG_FAILED
;
4286 if (result
== PIM_RP_BAD_ADDRESS
) {
4287 vty_out(vty
, "%% Bad RP address specified: %s\n", rp
);
4288 return CMD_WARNING_CONFIG_FAILED
;
4291 if (result
== PIM_RP_NO_PATH
) {
4292 vty_out(vty
, "%% No Path to RP address specified: %s\n", rp
);
4293 return CMD_WARNING_CONFIG_FAILED
;
4296 if (result
== PIM_GROUP_OVERLAP
) {
4297 vty_out(vty
, "%% Group range specified cannot overlap\n");
4298 return CMD_WARNING_CONFIG_FAILED
;
4301 if (result
== PIM_GROUP_PFXLIST_OVERLAP
) {
4303 "%% This group is already covered by a RP prefix-list\n");
4304 return CMD_WARNING_CONFIG_FAILED
;
4307 if (result
== PIM_RP_PFXLIST_IN_USE
) {
4309 "%% The same prefix-list cannot be applied to multiple RPs\n");
4310 return CMD_WARNING_CONFIG_FAILED
;
4316 static int pim_cmd_spt_switchover(enum pim_spt_switchover spt
,
4319 pimg
->spt
.switchover
= spt
;
4321 switch (pimg
->spt
.switchover
) {
4322 case PIM_SPT_IMMEDIATE
:
4323 if (pimg
->spt
.plist
)
4324 XFREE(MTYPE_PIM_SPT_PLIST_NAME
, pimg
->spt
.plist
);
4326 pim_upstream_add_lhr_star_pimreg(pimg
);
4328 case PIM_SPT_INFINITY
:
4329 pim_upstream_remove_lhr_star_pimreg(pimg
, plist
);
4331 if (pimg
->spt
.plist
)
4332 XFREE(MTYPE_PIM_SPT_PLIST_NAME
, pimg
->spt
.plist
);
4336 XSTRDUP(MTYPE_PIM_SPT_PLIST_NAME
, plist
);
4343 DEFUN (ip_pim_spt_switchover_infinity
,
4344 ip_pim_spt_switchover_infinity_cmd
,
4345 "ip pim spt-switchover infinity-and-beyond",
4349 "Never switch to SPT Tree\n")
4351 return pim_cmd_spt_switchover(PIM_SPT_INFINITY
, NULL
);
4354 DEFUN (ip_pim_spt_switchover_infinity_plist
,
4355 ip_pim_spt_switchover_infinity_plist_cmd
,
4356 "ip pim spt-switchover infinity-and-beyond prefix-list WORD",
4360 "Never switch to SPT Tree\n"
4361 "Prefix-List to control which groups to switch\n"
4362 "Prefix-List name\n")
4364 return pim_cmd_spt_switchover(PIM_SPT_INFINITY
, argv
[5]->arg
);
4367 DEFUN (no_ip_pim_spt_switchover_infinity
,
4368 no_ip_pim_spt_switchover_infinity_cmd
,
4369 "no ip pim spt-switchover infinity-and-beyond",
4374 "Never switch to SPT Tree\n")
4376 return pim_cmd_spt_switchover(PIM_SPT_IMMEDIATE
, NULL
);
4379 DEFUN (no_ip_pim_spt_switchover_infinity_plist
,
4380 no_ip_pim_spt_switchover_infinity_plist_cmd
,
4381 "no ip pim spt-switchover infinity-and-beyond prefix-list WORD",
4386 "Never switch to SPT Tree\n"
4387 "Prefix-List to control which groups to switch\n"
4388 "Prefix-List name\n")
4390 return pim_cmd_spt_switchover(PIM_SPT_IMMEDIATE
, NULL
);
4393 DEFUN (ip_pim_joinprune_time
,
4394 ip_pim_joinprune_time_cmd
,
4395 "ip pim join-prune-interval (60-600)",
4397 "pim multicast routing\n"
4398 "Join Prune Send Interval\n"
4401 qpim_t_periodic
= atoi(argv
[3]->arg
);
4405 DEFUN (no_ip_pim_joinprune_time
,
4406 no_ip_pim_joinprune_time_cmd
,
4407 "no ip pim join-prune-interval (60-600)",
4410 "pim multicast routing\n"
4411 "Join Prune Send Interval\n"
4414 qpim_t_periodic
= PIM_DEFAULT_T_PERIODIC
;
4418 DEFUN (ip_pim_register_suppress
,
4419 ip_pim_register_suppress_cmd
,
4420 "ip pim register-suppress-time (5-60000)",
4422 "pim multicast routing\n"
4423 "Register Suppress Timer\n"
4426 qpim_register_suppress_time
= atoi(argv
[3]->arg
);
4430 DEFUN (no_ip_pim_register_suppress
,
4431 no_ip_pim_register_suppress_cmd
,
4432 "no ip pim register-suppress-time (5-60000)",
4435 "pim multicast routing\n"
4436 "Register Suppress Timer\n"
4439 qpim_register_suppress_time
= PIM_REGISTER_SUPPRESSION_TIME_DEFAULT
;
4443 DEFUN (ip_pim_keep_alive
,
4444 ip_pim_keep_alive_cmd
,
4445 "ip pim keep-alive-timer (31-60000)",
4447 "pim multicast routing\n"
4448 "Keep alive Timer\n"
4451 qpim_keep_alive_time
= atoi(argv
[3]->arg
);
4455 DEFUN (no_ip_pim_keep_alive
,
4456 no_ip_pim_keep_alive_cmd
,
4457 "no ip pim keep-alive-timer (31-60000)",
4460 "pim multicast routing\n"
4461 "Keep alive Timer\n"
4464 qpim_keep_alive_time
= PIM_KEEPALIVE_PERIOD
;
4468 DEFUN (ip_pim_packets
,
4470 "ip pim packets (1-100)",
4472 "pim multicast routing\n"
4473 "packets to process at one time per fd\n"
4474 "Number of packets\n")
4476 qpim_packet_process
= atoi(argv
[3]->arg
);
4480 DEFUN (no_ip_pim_packets
,
4481 no_ip_pim_packets_cmd
,
4482 "no ip pim packets (1-100)",
4485 "pim multicast routing\n"
4486 "packets to process at one time per fd\n"
4487 "Number of packets\n")
4489 qpim_packet_process
= PIM_DEFAULT_PACKET_PROCESS
;
4493 DEFUN (ip_pim_v6_secondary
,
4494 ip_pim_v6_secondary_cmd
,
4495 "ip pim send-v6-secondary",
4497 "pim multicast routing\n"
4498 "Send v6 secondary addresses\n")
4500 pimg
->send_v6_secondary
= 1;
4505 DEFUN (no_ip_pim_v6_secondary
,
4506 no_ip_pim_v6_secondary_cmd
,
4507 "no ip pim send-v6-secondary",
4510 "pim multicast routing\n"
4511 "Send v6 secondary addresses\n")
4513 pimg
->send_v6_secondary
= 0;
4520 "ip pim rp A.B.C.D [A.B.C.D/M]",
4522 "pim multicast routing\n"
4524 "ip address of RP\n"
4525 "Group Address range to cover\n")
4527 PIM_DECLVAR_CONTEXT(vrf
, pim
);
4530 if (argc
== (idx_ipv4
+ 1))
4531 return pim_rp_cmd_worker(vty
, pim
, argv
[idx_ipv4
]->arg
, NULL
,
4534 return pim_rp_cmd_worker(vty
, pim
, argv
[idx_ipv4
]->arg
,
4535 argv
[idx_ipv4
+ 1]->arg
, NULL
);
4538 DEFUN (ip_pim_rp_prefix_list
,
4539 ip_pim_rp_prefix_list_cmd
,
4540 "ip pim rp A.B.C.D prefix-list WORD",
4542 "pim multicast routing\n"
4544 "ip address of RP\n"
4545 "group prefix-list filter\n"
4546 "Name of a prefix-list\n")
4548 return pim_rp_cmd_worker(vty
, pimg
, argv
[3]->arg
, NULL
, argv
[5]->arg
);
4551 static int pim_no_rp_cmd_worker(struct vty
*vty
, const char *rp
,
4552 const char *group
, const char *plist
)
4554 int result
= pim_rp_del(pimg
, rp
, group
, plist
);
4556 if (result
== PIM_GROUP_BAD_ADDRESS
) {
4557 vty_out(vty
, "%% Bad group address specified: %s\n", group
);
4558 return CMD_WARNING_CONFIG_FAILED
;
4561 if (result
== PIM_RP_BAD_ADDRESS
) {
4562 vty_out(vty
, "%% Bad RP address specified: %s\n", rp
);
4563 return CMD_WARNING_CONFIG_FAILED
;
4566 if (result
== PIM_RP_NOT_FOUND
) {
4567 vty_out(vty
, "%% Unable to find specified RP\n");
4568 return CMD_WARNING_CONFIG_FAILED
;
4574 DEFUN (no_ip_pim_rp
,
4576 "no ip pim rp A.B.C.D [A.B.C.D/M]",
4579 "pim multicast routing\n"
4581 "ip address of RP\n"
4582 "Group Address range to cover\n")
4584 int idx_ipv4
= 4, idx_group
= 0;
4586 if (argv_find(argv
, argc
, "A.B.C.D/M", &idx_group
))
4587 return pim_no_rp_cmd_worker(vty
, argv
[idx_ipv4
]->arg
,
4588 argv
[idx_group
]->arg
, NULL
);
4590 return pim_no_rp_cmd_worker(vty
, argv
[idx_ipv4
]->arg
, NULL
,
4594 DEFUN (no_ip_pim_rp_prefix_list
,
4595 no_ip_pim_rp_prefix_list_cmd
,
4596 "no ip pim rp A.B.C.D prefix-list WORD",
4599 "pim multicast routing\n"
4601 "ip address of RP\n"
4602 "group prefix-list filter\n"
4603 "Name of a prefix-list\n")
4605 return pim_no_rp_cmd_worker(vty
, argv
[4]->arg
, NULL
, argv
[6]->arg
);
4608 static int pim_ssm_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
4611 int result
= pim_ssm_range_set(pim
, pim
->vrf_id
, plist
);
4613 if (result
== PIM_SSM_ERR_NONE
)
4617 case PIM_SSM_ERR_NO_VRF
:
4618 vty_out(vty
, "%% VRF doesn't exist\n");
4620 case PIM_SSM_ERR_DUP
:
4621 vty_out(vty
, "%% duplicate config\n");
4624 vty_out(vty
, "%% ssm range config failed\n");
4627 return CMD_WARNING_CONFIG_FAILED
;
4630 DEFUN (ip_pim_ssm_prefix_list
,
4631 ip_pim_ssm_prefix_list_cmd
,
4632 "ip pim ssm prefix-list WORD",
4634 "pim multicast routing\n"
4635 "Source Specific Multicast\n"
4636 "group range prefix-list filter\n"
4637 "Name of a prefix-list\n")
4639 return pim_ssm_cmd_worker(pimg
, vty
, argv
[0]->arg
);
4642 DEFUN (no_ip_pim_ssm_prefix_list
,
4643 no_ip_pim_ssm_prefix_list_cmd
,
4644 "no ip pim ssm prefix-list",
4647 "pim multicast routing\n"
4648 "Source Specific Multicast\n"
4649 "group range prefix-list filter\n")
4651 return pim_ssm_cmd_worker(pimg
, vty
, NULL
);
4654 DEFUN (no_ip_pim_ssm_prefix_list_name
,
4655 no_ip_pim_ssm_prefix_list_name_cmd
,
4656 "no ip pim ssm prefix-list WORD",
4659 "pim multicast routing\n"
4660 "Source Specific Multicast\n"
4661 "group range prefix-list filter\n"
4662 "Name of a prefix-list\n")
4664 struct pim_ssm
*ssm
= pimg
->ssm_info
;
4666 if (ssm
->plist_name
&& !strcmp(ssm
->plist_name
, argv
[0]->arg
))
4667 return pim_ssm_cmd_worker(pimg
, vty
, NULL
);
4669 vty_out(vty
, "%% pim ssm prefix-list %s doesn't exist\n", argv
[0]->arg
);
4671 return CMD_WARNING_CONFIG_FAILED
;
4674 static void ip_pim_ssm_show_group_range(struct vty
*vty
, u_char uj
)
4676 struct pim_ssm
*ssm
= pimg
->ssm_info
;
4677 const char *range_str
=
4678 ssm
->plist_name
? ssm
->plist_name
: PIM_SSM_STANDARD_RANGE
;
4682 json
= json_object_new_object();
4683 json_object_string_add(json
, "ssmGroups", range_str
);
4684 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4685 json
, JSON_C_TO_STRING_PRETTY
));
4686 json_object_free(json
);
4688 vty_out(vty
, "SSM group range : %s\n", range_str
);
4691 DEFUN (show_ip_pim_ssm_range
,
4692 show_ip_pim_ssm_range_cmd
,
4693 "show ip pim group-type [json]",
4698 "JavaScript Object Notation\n")
4700 u_char uj
= use_json(argc
, argv
);
4701 ip_pim_ssm_show_group_range(vty
, uj
);
4706 static void ip_pim_ssm_show_group_type(struct vty
*vty
, u_char uj
,
4709 struct in_addr group_addr
;
4710 const char *type_str
;
4713 result
= inet_pton(AF_INET
, group
, &group_addr
);
4715 type_str
= "invalid";
4717 if (pim_is_group_224_4(group_addr
))
4718 type_str
= pim_is_grp_ssm(pimg
, group_addr
) ? "SSM"
4721 type_str
= "not-multicast";
4726 json
= json_object_new_object();
4727 json_object_string_add(json
, "groupType", type_str
);
4728 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4729 json
, JSON_C_TO_STRING_PRETTY
));
4730 json_object_free(json
);
4732 vty_out(vty
, "Group type : %s\n", type_str
);
4735 DEFUN (show_ip_pim_group_type
,
4736 show_ip_pim_group_type_cmd
,
4737 "show ip pim group-type A.B.C.D [json]",
4741 "multicast group type\n"
4743 "JavaScript Object Notation\n")
4745 u_char uj
= use_json(argc
, argv
);
4746 ip_pim_ssm_show_group_type(vty
, uj
, argv
[0]->arg
);
4751 DEFUN_HIDDEN (ip_multicast_routing
,
4752 ip_multicast_routing_cmd
,
4753 "ip multicast-routing",
4755 "Enable IP multicast forwarding\n")
4760 DEFUN_HIDDEN (no_ip_multicast_routing
,
4761 no_ip_multicast_routing_cmd
,
4762 "no ip multicast-routing",
4765 "Enable IP multicast forwarding\n")
4768 "Command is Disabled and will be removed in a future version\n");
4774 "ip ssmpingd [A.B.C.D]",
4781 struct in_addr source_addr
;
4782 const char *source_str
= (argc
== 3) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
4784 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
4786 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n",
4787 source_str
, errno
, safe_strerror(errno
));
4788 return CMD_WARNING_CONFIG_FAILED
;
4791 result
= pim_ssmpingd_start(pimg
, source_addr
);
4793 vty_out(vty
, "%% Failure starting ssmpingd for source %s: %d\n",
4794 source_str
, result
);
4795 return CMD_WARNING_CONFIG_FAILED
;
4801 DEFUN (no_ip_ssmpingd
,
4803 "no ip ssmpingd [A.B.C.D]",
4811 struct in_addr source_addr
;
4812 const char *source_str
= (argc
== 4) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
4814 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
4816 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n",
4817 source_str
, errno
, safe_strerror(errno
));
4818 return CMD_WARNING_CONFIG_FAILED
;
4821 result
= pim_ssmpingd_stop(pimg
, source_addr
);
4823 vty_out(vty
, "%% Failure stopping ssmpingd for source %s: %d\n",
4824 source_str
, result
);
4825 return CMD_WARNING_CONFIG_FAILED
;
4835 "pim multicast routing\n"
4836 "Enable PIM ECMP \n")
4838 qpim_ecmp_enable
= 1;
4843 DEFUN (no_ip_pim_ecmp
,
4848 "pim multicast routing\n"
4849 "Disable PIM ECMP \n")
4851 qpim_ecmp_enable
= 0;
4856 DEFUN (ip_pim_ecmp_rebalance
,
4857 ip_pim_ecmp_rebalance_cmd
,
4858 "ip pim ecmp rebalance",
4860 "pim multicast routing\n"
4861 "Enable PIM ECMP \n"
4862 "Enable PIM ECMP Rebalance\n")
4864 qpim_ecmp_enable
= 1;
4865 qpim_ecmp_rebalance_enable
= 1;
4870 DEFUN (no_ip_pim_ecmp_rebalance
,
4871 no_ip_pim_ecmp_rebalance_cmd
,
4872 "no ip pim ecmp rebalance",
4875 "pim multicast routing\n"
4876 "Disable PIM ECMP \n"
4877 "Disable PIM ECMP Rebalance\n")
4879 qpim_ecmp_rebalance_enable
= 0;
4884 static int pim_cmd_igmp_start(struct vty
*vty
, struct interface
*ifp
)
4886 struct pim_interface
*pim_ifp
;
4887 uint8_t need_startup
= 0;
4889 pim_ifp
= ifp
->info
;
4892 pim_ifp
= pim_if_new(ifp
, 1 /* igmp=true */, 0 /* pim=false */);
4894 vty_out(vty
, "Could not enable IGMP on interface %s\n",
4896 return CMD_WARNING_CONFIG_FAILED
;
4900 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
4901 PIM_IF_DO_IGMP(pim_ifp
->options
);
4906 /* 'ip igmp' executed multiple times, with need_startup
4907 avoid multiple if add all and membership refresh */
4909 pim_if_addr_add_all(ifp
);
4910 pim_if_membership_refresh(ifp
);
4916 DEFUN (interface_ip_igmp
,
4917 interface_ip_igmp_cmd
,
4922 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4924 return pim_cmd_igmp_start(vty
, ifp
);
4927 DEFUN (interface_no_ip_igmp
,
4928 interface_no_ip_igmp_cmd
,
4934 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4935 struct pim_interface
*pim_ifp
= ifp
->info
;
4940 PIM_IF_DONT_IGMP(pim_ifp
->options
);
4942 pim_if_membership_clear(ifp
);
4944 pim_if_addr_del_all_igmp(ifp
);
4946 if (!PIM_IF_TEST_PIM(pim_ifp
->options
)) {
4953 DEFUN (interface_ip_igmp_join
,
4954 interface_ip_igmp_join_cmd
,
4955 "ip igmp join A.B.C.D A.B.C.D",
4958 "IGMP join multicast group\n"
4959 "Multicast group address\n"
4962 VTY_DECLVAR_CONTEXT(interface
, ifp
);
4965 const char *group_str
;
4966 const char *source_str
;
4967 struct in_addr group_addr
;
4968 struct in_addr source_addr
;
4972 group_str
= argv
[idx_ipv4
]->arg
;
4973 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
4975 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", group_str
,
4976 errno
, safe_strerror(errno
));
4977 return CMD_WARNING_CONFIG_FAILED
;
4980 /* Source address */
4981 source_str
= argv
[idx_ipv4_2
]->arg
;
4982 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
4984 vty_out(vty
, "Bad source address %s: errno=%d: %s\n",
4985 source_str
, errno
, safe_strerror(errno
));
4986 return CMD_WARNING_CONFIG_FAILED
;
4989 result
= pim_if_igmp_join_add(ifp
, group_addr
, source_addr
);
4992 "%% Failure joining IGMP group %s source %s on interface %s: %d\n",
4993 group_str
, source_str
, ifp
->name
, result
);
4994 return CMD_WARNING_CONFIG_FAILED
;
5000 DEFUN (interface_no_ip_igmp_join
,
5001 interface_no_ip_igmp_join_cmd
,
5002 "no ip igmp join A.B.C.D A.B.C.D",
5006 "IGMP join multicast group\n"
5007 "Multicast group address\n"
5010 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5013 const char *group_str
;
5014 const char *source_str
;
5015 struct in_addr group_addr
;
5016 struct in_addr source_addr
;
5020 group_str
= argv
[idx_ipv4
]->arg
;
5021 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
5023 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", group_str
,
5024 errno
, safe_strerror(errno
));
5025 return CMD_WARNING_CONFIG_FAILED
;
5028 /* Source address */
5029 source_str
= argv
[idx_ipv4_2
]->arg
;
5030 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
5032 vty_out(vty
, "Bad source address %s: errno=%d: %s\n",
5033 source_str
, errno
, safe_strerror(errno
));
5034 return CMD_WARNING_CONFIG_FAILED
;
5037 result
= pim_if_igmp_join_del(ifp
, group_addr
, source_addr
);
5040 "%% Failure leaving IGMP group %s source %s on interface %s: %d\n",
5041 group_str
, source_str
, ifp
->name
, result
);
5042 return CMD_WARNING_CONFIG_FAILED
;
5049 CLI reconfiguration affects the interface level (struct pim_interface).
5050 This function propagates the reconfiguration to every active socket
5053 static void igmp_sock_query_interval_reconfig(struct igmp_sock
*igmp
)
5055 struct interface
*ifp
;
5056 struct pim_interface
*pim_ifp
;
5060 /* other querier present? */
5062 if (igmp
->t_other_querier_timer
)
5065 /* this is the querier */
5067 zassert(igmp
->interface
);
5068 zassert(igmp
->interface
->info
);
5070 ifp
= igmp
->interface
;
5071 pim_ifp
= ifp
->info
;
5073 if (PIM_DEBUG_IGMP_TRACE
) {
5074 char ifaddr_str
[INET_ADDRSTRLEN
];
5075 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
5076 sizeof(ifaddr_str
));
5077 zlog_debug("%s: Querier %s on %s reconfig query_interval=%d",
5078 __PRETTY_FUNCTION__
, ifaddr_str
, ifp
->name
,
5079 pim_ifp
->igmp_default_query_interval
);
5083 igmp_startup_mode_on() will reset QQI:
5085 igmp->querier_query_interval = pim_ifp->igmp_default_query_interval;
5087 igmp_startup_mode_on(igmp
);
5090 static void igmp_sock_query_reschedule(struct igmp_sock
*igmp
)
5092 if (igmp
->t_igmp_query_timer
) {
5093 /* other querier present */
5094 zassert(igmp
->t_igmp_query_timer
);
5095 zassert(!igmp
->t_other_querier_timer
);
5097 pim_igmp_general_query_off(igmp
);
5098 pim_igmp_general_query_on(igmp
);
5100 zassert(igmp
->t_igmp_query_timer
);
5101 zassert(!igmp
->t_other_querier_timer
);
5103 /* this is the querier */
5105 zassert(!igmp
->t_igmp_query_timer
);
5106 zassert(igmp
->t_other_querier_timer
);
5108 pim_igmp_other_querier_timer_off(igmp
);
5109 pim_igmp_other_querier_timer_on(igmp
);
5111 zassert(!igmp
->t_igmp_query_timer
);
5112 zassert(igmp
->t_other_querier_timer
);
5116 static void change_query_interval(struct pim_interface
*pim_ifp
,
5119 struct listnode
*sock_node
;
5120 struct igmp_sock
*igmp
;
5122 pim_ifp
->igmp_default_query_interval
= query_interval
;
5124 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
5125 igmp_sock_query_interval_reconfig(igmp
);
5126 igmp_sock_query_reschedule(igmp
);
5130 static void change_query_max_response_time(struct pim_interface
*pim_ifp
,
5131 int query_max_response_time_dsec
)
5133 struct listnode
*sock_node
;
5134 struct igmp_sock
*igmp
;
5136 pim_ifp
->igmp_query_max_response_time_dsec
=
5137 query_max_response_time_dsec
;
5140 Below we modify socket/group/source timers in order to quickly
5141 reflect the change. Otherwise, those timers would eventually catch
5145 /* scan all sockets */
5146 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
5147 struct listnode
*grp_node
;
5148 struct igmp_group
*grp
;
5150 /* reschedule socket general query */
5151 igmp_sock_query_reschedule(igmp
);
5153 /* scan socket groups */
5154 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grp_node
,
5156 struct listnode
*src_node
;
5157 struct igmp_source
*src
;
5159 /* reset group timers for groups in EXCLUDE mode */
5160 if (grp
->group_filtermode_isexcl
) {
5161 igmp_group_reset_gmi(grp
);
5164 /* scan group sources */
5165 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
,
5168 /* reset source timers for sources with running
5170 if (src
->t_source_timer
) {
5171 igmp_source_reset_gmi(igmp
, grp
, src
);
5178 #define IGMP_QUERY_INTERVAL_MIN (1)
5179 #define IGMP_QUERY_INTERVAL_MAX (1800)
5181 DEFUN (interface_ip_igmp_query_interval
,
5182 interface_ip_igmp_query_interval_cmd
,
5183 "ip igmp query-interval (1-1800)",
5186 IFACE_IGMP_QUERY_INTERVAL_STR
5187 "Query interval in seconds\n")
5189 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5190 struct pim_interface
*pim_ifp
= ifp
->info
;
5192 int query_interval_dsec
;
5196 ret
= pim_cmd_igmp_start(vty
, ifp
);
5197 if (ret
!= CMD_SUCCESS
)
5199 pim_ifp
= ifp
->info
;
5202 query_interval
= atoi(argv
[3]->arg
);
5203 query_interval_dsec
= 10 * query_interval
;
5206 It seems we don't need to check bounds since command.c does it
5207 already, but we verify them anyway for extra safety.
5209 if (query_interval
< IGMP_QUERY_INTERVAL_MIN
) {
5211 "General query interval %d lower than minimum %d\n",
5212 query_interval
, IGMP_QUERY_INTERVAL_MIN
);
5213 return CMD_WARNING_CONFIG_FAILED
;
5215 if (query_interval
> IGMP_QUERY_INTERVAL_MAX
) {
5217 "General query interval %d higher than maximum %d\n",
5218 query_interval
, IGMP_QUERY_INTERVAL_MAX
);
5219 return CMD_WARNING_CONFIG_FAILED
;
5222 if (query_interval_dsec
<= pim_ifp
->igmp_query_max_response_time_dsec
) {
5224 "Can't set general query interval %d dsec <= query max response time %d dsec.\n",
5225 query_interval_dsec
,
5226 pim_ifp
->igmp_query_max_response_time_dsec
);
5227 return CMD_WARNING_CONFIG_FAILED
;
5230 change_query_interval(pim_ifp
, query_interval
);
5235 DEFUN (interface_no_ip_igmp_query_interval
,
5236 interface_no_ip_igmp_query_interval_cmd
,
5237 "no ip igmp query-interval",
5241 IFACE_IGMP_QUERY_INTERVAL_STR
)
5243 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5244 struct pim_interface
*pim_ifp
= ifp
->info
;
5245 int default_query_interval_dsec
;
5250 default_query_interval_dsec
= IGMP_GENERAL_QUERY_INTERVAL
* 10;
5252 if (default_query_interval_dsec
5253 <= pim_ifp
->igmp_query_max_response_time_dsec
) {
5255 "Can't set default general query interval %d dsec <= query max response time %d dsec.\n",
5256 default_query_interval_dsec
,
5257 pim_ifp
->igmp_query_max_response_time_dsec
);
5258 return CMD_WARNING_CONFIG_FAILED
;
5261 change_query_interval(pim_ifp
, IGMP_GENERAL_QUERY_INTERVAL
);
5266 DEFUN (interface_ip_igmp_version
,
5267 interface_ip_igmp_version_cmd
,
5268 "ip igmp version (2-3)",
5272 "IGMP version number\n")
5274 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5275 struct pim_interface
*pim_ifp
= ifp
->info
;
5276 int igmp_version
, old_version
= 0;
5280 ret
= pim_cmd_igmp_start(vty
, ifp
);
5281 if (ret
!= CMD_SUCCESS
)
5283 pim_ifp
= ifp
->info
;
5286 igmp_version
= atoi(argv
[3]->arg
);
5287 old_version
= pim_ifp
->igmp_version
;
5288 pim_ifp
->igmp_version
= igmp_version
;
5290 // Check if IGMP is Enabled otherwise, enable on interface
5291 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
5292 PIM_IF_DO_IGMP(pim_ifp
->options
);
5293 pim_if_addr_add_all(ifp
);
5294 pim_if_membership_refresh(ifp
);
5295 old_version
= igmp_version
; // avoid refreshing membership
5298 /* Current and new version is different refresh existing
5299 membership. Going from 3 -> 2 or 2 -> 3. */
5300 if (old_version
!= igmp_version
)
5301 pim_if_membership_refresh(ifp
);
5306 DEFUN (interface_no_ip_igmp_version
,
5307 interface_no_ip_igmp_version_cmd
,
5308 "no ip igmp version (2-3)",
5313 "IGMP version number\n")
5315 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5316 struct pim_interface
*pim_ifp
= ifp
->info
;
5321 pim_ifp
->igmp_version
= IGMP_DEFAULT_VERSION
;
5326 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
5327 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
5329 DEFUN (interface_ip_igmp_query_max_response_time
,
5330 interface_ip_igmp_query_max_response_time_cmd
,
5331 "ip igmp query-max-response-time (10-250)",
5334 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
5335 "Query response value in deci-seconds\n")
5337 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5338 struct pim_interface
*pim_ifp
= ifp
->info
;
5339 int query_max_response_time
;
5343 ret
= pim_cmd_igmp_start(vty
, ifp
);
5344 if (ret
!= CMD_SUCCESS
)
5346 pim_ifp
= ifp
->info
;
5349 query_max_response_time
= atoi(argv
[3]->arg
);
5351 if (query_max_response_time
5352 >= pim_ifp
->igmp_default_query_interval
* 10) {
5354 "Can't set query max response time %d sec >= general query interval %d sec\n",
5355 query_max_response_time
,
5356 pim_ifp
->igmp_default_query_interval
);
5357 return CMD_WARNING_CONFIG_FAILED
;
5360 change_query_max_response_time(pim_ifp
, query_max_response_time
);
5365 DEFUN (interface_no_ip_igmp_query_max_response_time
,
5366 interface_no_ip_igmp_query_max_response_time_cmd
,
5367 "no ip igmp query-max-response-time (10-250)",
5371 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
5372 "Time for response in deci-seconds\n")
5374 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5375 struct pim_interface
*pim_ifp
= ifp
->info
;
5380 change_query_max_response_time(pim_ifp
,
5381 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
5386 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
5387 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
5389 DEFUN_HIDDEN (interface_ip_igmp_query_max_response_time_dsec
,
5390 interface_ip_igmp_query_max_response_time_dsec_cmd
,
5391 "ip igmp query-max-response-time-dsec (10-250)",
5394 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
5395 "Query response value in deciseconds\n")
5397 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5398 struct pim_interface
*pim_ifp
= ifp
->info
;
5399 int query_max_response_time_dsec
;
5400 int default_query_interval_dsec
;
5404 ret
= pim_cmd_igmp_start(vty
, ifp
);
5405 if (ret
!= CMD_SUCCESS
)
5407 pim_ifp
= ifp
->info
;
5410 query_max_response_time_dsec
= atoi(argv
[4]->arg
);
5412 default_query_interval_dsec
= 10 * pim_ifp
->igmp_default_query_interval
;
5414 if (query_max_response_time_dsec
>= default_query_interval_dsec
) {
5416 "Can't set query max response time %d dsec >= general query interval %d dsec\n",
5417 query_max_response_time_dsec
,
5418 default_query_interval_dsec
);
5419 return CMD_WARNING_CONFIG_FAILED
;
5422 change_query_max_response_time(pim_ifp
, query_max_response_time_dsec
);
5427 DEFUN_HIDDEN (interface_no_ip_igmp_query_max_response_time_dsec
,
5428 interface_no_ip_igmp_query_max_response_time_dsec_cmd
,
5429 "no ip igmp query-max-response-time-dsec",
5433 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
)
5435 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5436 struct pim_interface
*pim_ifp
= ifp
->info
;
5441 change_query_max_response_time(pim_ifp
,
5442 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
5447 DEFUN (interface_ip_pim_drprio
,
5448 interface_ip_pim_drprio_cmd
,
5449 "ip pim drpriority (1-4294967295)",
5452 "Set the Designated Router Election Priority\n"
5453 "Value of the new DR Priority\n")
5455 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5457 struct pim_interface
*pim_ifp
= ifp
->info
;
5458 uint32_t old_dr_prio
;
5461 vty_out(vty
, "Please enable PIM on interface, first\n");
5462 return CMD_WARNING_CONFIG_FAILED
;
5465 old_dr_prio
= pim_ifp
->pim_dr_priority
;
5467 pim_ifp
->pim_dr_priority
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
5469 if (old_dr_prio
!= pim_ifp
->pim_dr_priority
) {
5470 if (pim_if_dr_election(ifp
))
5471 pim_hello_restart_now(ifp
);
5477 DEFUN (interface_no_ip_pim_drprio
,
5478 interface_no_ip_pim_drprio_cmd
,
5479 "no ip pim drpriority [(1-4294967295)]",
5483 "Revert the Designated Router Priority to default\n"
5484 "Old Value of the Priority\n")
5486 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5487 struct pim_interface
*pim_ifp
= ifp
->info
;
5490 vty_out(vty
, "Pim not enabled on this interface\n");
5491 return CMD_WARNING_CONFIG_FAILED
;
5494 if (pim_ifp
->pim_dr_priority
!= PIM_DEFAULT_DR_PRIORITY
) {
5495 pim_ifp
->pim_dr_priority
= PIM_DEFAULT_DR_PRIORITY
;
5496 if (pim_if_dr_election(ifp
))
5497 pim_hello_restart_now(ifp
);
5503 static int pim_cmd_interface_add(struct interface
*ifp
)
5505 struct pim_interface
*pim_ifp
= ifp
->info
;
5508 pim_ifp
= pim_if_new(ifp
, 0 /* igmp=false */, 1 /* pim=true */);
5513 PIM_IF_DO_PIM(pim_ifp
->options
);
5516 pim_if_addr_add_all(ifp
);
5517 pim_if_membership_refresh(ifp
);
5521 DEFUN_HIDDEN (interface_ip_pim_ssm
,
5522 interface_ip_pim_ssm_cmd
,
5528 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5530 if (!pim_cmd_interface_add(ifp
)) {
5531 vty_out(vty
, "Could not enable PIM SM on interface\n");
5532 return CMD_WARNING_CONFIG_FAILED
;
5536 "WARN: Enabled PIM SM on interface; configure PIM SSM "
5537 "range if needed\n");
5541 DEFUN (interface_ip_pim_sm
,
5542 interface_ip_pim_sm_cmd
,
5548 struct pim_interface
*pim_ifp
;
5550 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5551 if (!pim_cmd_interface_add(ifp
)) {
5552 vty_out(vty
, "Could not enable PIM SM on interface\n");
5553 return CMD_WARNING_CONFIG_FAILED
;
5556 pim_ifp
= ifp
->info
;
5558 pim_if_create_pimreg(pim_ifp
->pim
);
5563 static int pim_cmd_interface_delete(struct interface
*ifp
)
5565 struct pim_interface
*pim_ifp
= ifp
->info
;
5570 PIM_IF_DONT_PIM(pim_ifp
->options
);
5572 pim_if_membership_clear(ifp
);
5575 pim_sock_delete() removes all neighbors from
5576 pim_ifp->pim_neighbor_list.
5578 pim_sock_delete(ifp
, "pim unconfigured on interface");
5580 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
5581 pim_if_addr_del_all(ifp
);
5588 DEFUN_HIDDEN (interface_no_ip_pim_ssm
,
5589 interface_no_ip_pim_ssm_cmd
,
5596 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5597 if (!pim_cmd_interface_delete(ifp
)) {
5598 vty_out(vty
, "Unable to delete interface information\n");
5599 return CMD_WARNING_CONFIG_FAILED
;
5605 DEFUN (interface_no_ip_pim_sm
,
5606 interface_no_ip_pim_sm_cmd
,
5613 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5614 if (!pim_cmd_interface_delete(ifp
)) {
5615 vty_out(vty
, "Unable to delete interface information\n");
5616 return CMD_WARNING_CONFIG_FAILED
;
5622 DEFUN (interface_ip_mroute
,
5623 interface_ip_mroute_cmd
,
5624 "ip mroute INTERFACE A.B.C.D",
5626 "Add multicast route\n"
5627 "Outgoing interface name\n"
5630 VTY_DECLVAR_CONTEXT(interface
, iif
);
5631 struct pim_interface
*pim_ifp
;
5632 struct pim_instance
*pim
;
5633 int idx_interface
= 2;
5635 struct interface
*oif
;
5636 const char *oifname
;
5637 const char *grp_str
;
5638 struct in_addr grp_addr
;
5639 struct in_addr src_addr
;
5642 pim_ifp
= iif
->info
;
5645 oifname
= argv
[idx_interface
]->arg
;
5646 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
5648 vty_out(vty
, "No such interface name %s\n", oifname
);
5652 grp_str
= argv
[idx_ipv4
]->arg
;
5653 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
5655 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
5656 errno
, safe_strerror(errno
));
5660 src_addr
.s_addr
= INADDR_ANY
;
5662 if (pim_static_add(pim
, iif
, oif
, grp_addr
, src_addr
)) {
5663 vty_out(vty
, "Failed to add route\n");
5670 DEFUN (interface_ip_mroute_source
,
5671 interface_ip_mroute_source_cmd
,
5672 "ip mroute INTERFACE A.B.C.D A.B.C.D",
5674 "Add multicast route\n"
5675 "Outgoing interface name\n"
5679 VTY_DECLVAR_CONTEXT(interface
, iif
);
5680 struct pim_interface
*pim_ifp
;
5681 struct pim_instance
*pim
;
5682 int idx_interface
= 2;
5685 struct interface
*oif
;
5686 const char *oifname
;
5687 const char *grp_str
;
5688 struct in_addr grp_addr
;
5689 const char *src_str
;
5690 struct in_addr src_addr
;
5693 pim_ifp
= iif
->info
;
5696 oifname
= argv
[idx_interface
]->arg
;
5697 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
5699 vty_out(vty
, "No such interface name %s\n", oifname
);
5703 grp_str
= argv
[idx_ipv4
]->arg
;
5704 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
5706 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
5707 errno
, safe_strerror(errno
));
5711 src_str
= argv
[idx_ipv4_2
]->arg
;
5712 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
5714 vty_out(vty
, "Bad source address %s: errno=%d: %s\n", src_str
,
5715 errno
, safe_strerror(errno
));
5719 if (pim_static_add(pim
, iif
, oif
, grp_addr
, src_addr
)) {
5720 vty_out(vty
, "Failed to add route\n");
5727 DEFUN (interface_no_ip_mroute
,
5728 interface_no_ip_mroute_cmd
,
5729 "no ip mroute INTERFACE A.B.C.D",
5732 "Add multicast route\n"
5733 "Outgoing interface name\n"
5736 VTY_DECLVAR_CONTEXT(interface
, iif
);
5737 struct pim_interface
*pim_ifp
;
5738 struct pim_instance
*pim
;
5739 int idx_interface
= 3;
5741 struct interface
*oif
;
5742 const char *oifname
;
5743 const char *grp_str
;
5744 struct in_addr grp_addr
;
5745 struct in_addr src_addr
;
5748 pim_ifp
= iif
->info
;
5751 oifname
= argv
[idx_interface
]->arg
;
5752 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
5754 vty_out(vty
, "No such interface name %s\n", oifname
);
5758 grp_str
= argv
[idx_ipv4
]->arg
;
5759 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
5761 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
5762 errno
, safe_strerror(errno
));
5766 src_addr
.s_addr
= INADDR_ANY
;
5768 if (pim_static_del(pim
, iif
, oif
, grp_addr
, src_addr
)) {
5769 vty_out(vty
, "Failed to remove route\n");
5776 DEFUN (interface_no_ip_mroute_source
,
5777 interface_no_ip_mroute_source_cmd
,
5778 "no ip mroute INTERFACE A.B.C.D A.B.C.D",
5781 "Add multicast route\n"
5782 "Outgoing interface name\n"
5786 VTY_DECLVAR_CONTEXT(interface
, iif
);
5787 struct pim_interface
*pim_ifp
;
5788 struct pim_instance
*pim
;
5789 int idx_interface
= 3;
5792 struct interface
*oif
;
5793 const char *oifname
;
5794 const char *grp_str
;
5795 struct in_addr grp_addr
;
5796 const char *src_str
;
5797 struct in_addr src_addr
;
5800 pim_ifp
= iif
->info
;
5803 oifname
= argv
[idx_interface
]->arg
;
5804 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
5806 vty_out(vty
, "No such interface name %s\n", oifname
);
5810 grp_str
= argv
[idx_ipv4
]->arg
;
5811 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
5813 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
5814 errno
, safe_strerror(errno
));
5818 src_str
= argv
[idx_ipv4_2
]->arg
;
5819 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
5821 vty_out(vty
, "Bad source address %s: errno=%d: %s\n", src_str
,
5822 errno
, safe_strerror(errno
));
5826 if (pim_static_del(pim
, iif
, oif
, grp_addr
, src_addr
)) {
5827 vty_out(vty
, "Failed to remove route\n");
5834 DEFUN (interface_ip_pim_hello
,
5835 interface_ip_pim_hello_cmd
,
5836 "ip pim hello (1-180) [(1-180)]",
5840 IFACE_PIM_HELLO_TIME_STR
5841 IFACE_PIM_HELLO_HOLD_STR
)
5843 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5846 struct pim_interface
*pim_ifp
= ifp
->info
;
5849 if (!pim_cmd_interface_add(ifp
)) {
5850 vty_out(vty
, "Could not enable PIM SM on interface\n");
5851 return CMD_WARNING_CONFIG_FAILED
;
5855 pim_ifp
= ifp
->info
;
5856 pim_ifp
->pim_hello_period
= strtol(argv
[idx_time
]->arg
, NULL
, 10);
5858 if (argc
== idx_hold
+ 1)
5859 pim_ifp
->pim_default_holdtime
=
5860 strtol(argv
[idx_hold
]->arg
, NULL
, 10);
5866 DEFUN (interface_no_ip_pim_hello
,
5867 interface_no_ip_pim_hello_cmd
,
5868 "no ip pim hello [(1-180) (1-180)]",
5873 IFACE_PIM_HELLO_TIME_STR
5874 IFACE_PIM_HELLO_HOLD_STR
)
5876 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5877 struct pim_interface
*pim_ifp
= ifp
->info
;
5880 vty_out(vty
, "Pim not enabled on this interface\n");
5881 return CMD_WARNING_CONFIG_FAILED
;
5884 pim_ifp
->pim_hello_period
= PIM_DEFAULT_HELLO_PERIOD
;
5885 pim_ifp
->pim_default_holdtime
= -1;
5896 PIM_DO_DEBUG_IGMP_EVENTS
;
5897 PIM_DO_DEBUG_IGMP_PACKETS
;
5898 PIM_DO_DEBUG_IGMP_TRACE
;
5902 DEFUN (no_debug_igmp
,
5909 PIM_DONT_DEBUG_IGMP_EVENTS
;
5910 PIM_DONT_DEBUG_IGMP_PACKETS
;
5911 PIM_DONT_DEBUG_IGMP_TRACE
;
5916 DEFUN (debug_igmp_events
,
5917 debug_igmp_events_cmd
,
5918 "debug igmp events",
5921 DEBUG_IGMP_EVENTS_STR
)
5923 PIM_DO_DEBUG_IGMP_EVENTS
;
5927 DEFUN (no_debug_igmp_events
,
5928 no_debug_igmp_events_cmd
,
5929 "no debug igmp events",
5933 DEBUG_IGMP_EVENTS_STR
)
5935 PIM_DONT_DEBUG_IGMP_EVENTS
;
5940 DEFUN (debug_igmp_packets
,
5941 debug_igmp_packets_cmd
,
5942 "debug igmp packets",
5945 DEBUG_IGMP_PACKETS_STR
)
5947 PIM_DO_DEBUG_IGMP_PACKETS
;
5951 DEFUN (no_debug_igmp_packets
,
5952 no_debug_igmp_packets_cmd
,
5953 "no debug igmp packets",
5957 DEBUG_IGMP_PACKETS_STR
)
5959 PIM_DONT_DEBUG_IGMP_PACKETS
;
5964 DEFUN (debug_igmp_trace
,
5965 debug_igmp_trace_cmd
,
5969 DEBUG_IGMP_TRACE_STR
)
5971 PIM_DO_DEBUG_IGMP_TRACE
;
5975 DEFUN (no_debug_igmp_trace
,
5976 no_debug_igmp_trace_cmd
,
5977 "no debug igmp trace",
5981 DEBUG_IGMP_TRACE_STR
)
5983 PIM_DONT_DEBUG_IGMP_TRACE
;
5988 DEFUN (debug_mroute
,
5994 PIM_DO_DEBUG_MROUTE
;
5998 DEFUN (debug_mroute_detail
,
5999 debug_mroute_detail_cmd
,
6000 "debug mroute detail",
6005 PIM_DO_DEBUG_MROUTE_DETAIL
;
6009 DEFUN (no_debug_mroute
,
6010 no_debug_mroute_cmd
,
6016 PIM_DONT_DEBUG_MROUTE
;
6020 DEFUN (no_debug_mroute_detail
,
6021 no_debug_mroute_detail_cmd
,
6022 "no debug mroute detail",
6028 PIM_DONT_DEBUG_MROUTE_DETAIL
;
6032 DEFUN (debug_static
,
6038 PIM_DO_DEBUG_STATIC
;
6042 DEFUN (no_debug_static
,
6043 no_debug_static_cmd
,
6049 PIM_DONT_DEBUG_STATIC
;
6060 PIM_DO_DEBUG_PIM_EVENTS
;
6061 PIM_DO_DEBUG_PIM_PACKETS
;
6062 PIM_DO_DEBUG_PIM_TRACE
;
6063 PIM_DO_DEBUG_MSDP_EVENTS
;
6064 PIM_DO_DEBUG_MSDP_PACKETS
;
6068 DEFUN (no_debug_pim
,
6075 PIM_DONT_DEBUG_PIM_EVENTS
;
6076 PIM_DONT_DEBUG_PIM_PACKETS
;
6077 PIM_DONT_DEBUG_PIM_TRACE
;
6078 PIM_DONT_DEBUG_MSDP_EVENTS
;
6079 PIM_DONT_DEBUG_MSDP_PACKETS
;
6081 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
6082 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
6088 DEFUN (debug_pim_events
,
6089 debug_pim_events_cmd
,
6093 DEBUG_PIM_EVENTS_STR
)
6095 PIM_DO_DEBUG_PIM_EVENTS
;
6099 DEFUN (no_debug_pim_events
,
6100 no_debug_pim_events_cmd
,
6101 "no debug pim events",
6105 DEBUG_PIM_EVENTS_STR
)
6107 PIM_DONT_DEBUG_PIM_EVENTS
;
6111 DEFUN (debug_pim_packets
,
6112 debug_pim_packets_cmd
,
6113 "debug pim packets [<hello|joins|register>]",
6116 DEBUG_PIM_PACKETS_STR
6117 DEBUG_PIM_HELLO_PACKETS_STR
6118 DEBUG_PIM_J_P_PACKETS_STR
6119 DEBUG_PIM_PIM_REG_PACKETS_STR
)
6122 if (argv_find(argv
, argc
, "hello", &idx
)) {
6123 PIM_DO_DEBUG_PIM_HELLO
;
6124 vty_out(vty
, "PIM Hello debugging is on\n");
6125 } else if (argv_find(argv
, argc
, "joins", &idx
)) {
6126 PIM_DO_DEBUG_PIM_J_P
;
6127 vty_out(vty
, "PIM Join/Prune debugging is on\n");
6128 } else if (argv_find(argv
, argc
, "register", &idx
)) {
6129 PIM_DO_DEBUG_PIM_REG
;
6130 vty_out(vty
, "PIM Register debugging is on\n");
6132 PIM_DO_DEBUG_PIM_PACKETS
;
6133 vty_out(vty
, "PIM Packet debugging is on \n");
6138 DEFUN (no_debug_pim_packets
,
6139 no_debug_pim_packets_cmd
,
6140 "no debug pim packets [<hello|joins|register>]",
6144 DEBUG_PIM_PACKETS_STR
6145 DEBUG_PIM_HELLO_PACKETS_STR
6146 DEBUG_PIM_J_P_PACKETS_STR
6147 DEBUG_PIM_PIM_REG_PACKETS_STR
)
6150 if (argv_find(argv
, argc
, "hello", &idx
)) {
6151 PIM_DONT_DEBUG_PIM_HELLO
;
6152 vty_out(vty
, "PIM Hello debugging is off \n");
6153 } else if (argv_find(argv
, argc
, "joins", &idx
)) {
6154 PIM_DONT_DEBUG_PIM_J_P
;
6155 vty_out(vty
, "PIM Join/Prune debugging is off \n");
6156 } else if (argv_find(argv
, argc
, "register", &idx
)) {
6157 PIM_DONT_DEBUG_PIM_REG
;
6158 vty_out(vty
, "PIM Register debugging is off\n");
6160 PIM_DONT_DEBUG_PIM_PACKETS
;
6166 DEFUN (debug_pim_packetdump_send
,
6167 debug_pim_packetdump_send_cmd
,
6168 "debug pim packet-dump send",
6171 DEBUG_PIM_PACKETDUMP_STR
6172 DEBUG_PIM_PACKETDUMP_SEND_STR
)
6174 PIM_DO_DEBUG_PIM_PACKETDUMP_SEND
;
6178 DEFUN (no_debug_pim_packetdump_send
,
6179 no_debug_pim_packetdump_send_cmd
,
6180 "no debug pim packet-dump send",
6184 DEBUG_PIM_PACKETDUMP_STR
6185 DEBUG_PIM_PACKETDUMP_SEND_STR
)
6187 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
6192 DEFUN (debug_pim_packetdump_recv
,
6193 debug_pim_packetdump_recv_cmd
,
6194 "debug pim packet-dump receive",
6197 DEBUG_PIM_PACKETDUMP_STR
6198 DEBUG_PIM_PACKETDUMP_RECV_STR
)
6200 PIM_DO_DEBUG_PIM_PACKETDUMP_RECV
;
6204 DEFUN (no_debug_pim_packetdump_recv
,
6205 no_debug_pim_packetdump_recv_cmd
,
6206 "no debug pim packet-dump receive",
6210 DEBUG_PIM_PACKETDUMP_STR
6211 DEBUG_PIM_PACKETDUMP_RECV_STR
)
6213 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
6218 DEFUN (debug_pim_trace
,
6219 debug_pim_trace_cmd
,
6223 DEBUG_PIM_TRACE_STR
)
6225 PIM_DO_DEBUG_PIM_TRACE
;
6229 DEFUN (no_debug_pim_trace
,
6230 no_debug_pim_trace_cmd
,
6231 "no debug pim trace",
6235 DEBUG_PIM_TRACE_STR
)
6237 PIM_DONT_DEBUG_PIM_TRACE
;
6242 DEFUN (debug_ssmpingd
,
6248 PIM_DO_DEBUG_SSMPINGD
;
6252 DEFUN (no_debug_ssmpingd
,
6253 no_debug_ssmpingd_cmd
,
6254 "no debug ssmpingd",
6259 PIM_DONT_DEBUG_SSMPINGD
;
6264 DEFUN (debug_pim_zebra
,
6265 debug_pim_zebra_cmd
,
6269 DEBUG_PIM_ZEBRA_STR
)
6275 DEFUN (no_debug_pim_zebra
,
6276 no_debug_pim_zebra_cmd
,
6277 "no debug pim zebra",
6281 DEBUG_PIM_ZEBRA_STR
)
6283 PIM_DONT_DEBUG_ZEBRA
;
6294 PIM_DO_DEBUG_MSDP_EVENTS
;
6295 PIM_DO_DEBUG_MSDP_PACKETS
;
6299 DEFUN (no_debug_msdp
,
6306 PIM_DONT_DEBUG_MSDP_EVENTS
;
6307 PIM_DONT_DEBUG_MSDP_PACKETS
;
6311 ALIAS(no_debug_msdp
, undebug_msdp_cmd
, "undebug msdp",
6312 UNDEBUG_STR DEBUG_MSDP_STR
)
6314 DEFUN (debug_msdp_events
,
6315 debug_msdp_events_cmd
,
6316 "debug msdp events",
6319 DEBUG_MSDP_EVENTS_STR
)
6321 PIM_DO_DEBUG_MSDP_EVENTS
;
6325 DEFUN (no_debug_msdp_events
,
6326 no_debug_msdp_events_cmd
,
6327 "no debug msdp events",
6331 DEBUG_MSDP_EVENTS_STR
)
6333 PIM_DONT_DEBUG_MSDP_EVENTS
;
6337 ALIAS(no_debug_msdp_events
, undebug_msdp_events_cmd
, "undebug msdp events",
6338 UNDEBUG_STR DEBUG_MSDP_STR DEBUG_MSDP_EVENTS_STR
)
6340 DEFUN (debug_msdp_packets
,
6341 debug_msdp_packets_cmd
,
6342 "debug msdp packets",
6345 DEBUG_MSDP_PACKETS_STR
)
6347 PIM_DO_DEBUG_MSDP_PACKETS
;
6351 DEFUN (no_debug_msdp_packets
,
6352 no_debug_msdp_packets_cmd
,
6353 "no debug msdp packets",
6357 DEBUG_MSDP_PACKETS_STR
)
6359 PIM_DONT_DEBUG_MSDP_PACKETS
;
6363 ALIAS(no_debug_msdp_packets
, undebug_msdp_packets_cmd
, "undebug msdp packets",
6364 UNDEBUG_STR DEBUG_MSDP_STR DEBUG_MSDP_PACKETS_STR
)
6366 DEFUN (show_debugging_pim
,
6367 show_debugging_pim_cmd
,
6368 "show debugging pim",
6373 pim_debug_config_write(vty
);
6377 static int interface_pim_use_src_cmd_worker(struct vty
*vty
, const char *source
)
6380 struct in_addr source_addr
;
6381 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6383 result
= inet_pton(AF_INET
, source
, &source_addr
);
6385 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", source
,
6386 errno
, safe_strerror(errno
));
6387 return CMD_WARNING_CONFIG_FAILED
;
6390 result
= pim_update_source_set(ifp
, source_addr
);
6394 case PIM_IFACE_NOT_FOUND
:
6395 vty_out(vty
, "Pim not enabled on this interface\n");
6397 case PIM_UPDATE_SOURCE_DUP
:
6398 vty_out(vty
, "%% Source already set to %s\n", source
);
6401 vty_out(vty
, "%% Source set failed\n");
6404 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
6407 DEFUN (interface_pim_use_source
,
6408 interface_pim_use_source_cmd
,
6409 "ip pim use-source A.B.C.D",
6411 "pim multicast routing\n"
6412 "Configure primary IP address\n"
6413 "source ip address\n")
6415 return interface_pim_use_src_cmd_worker(vty
, argv
[3]->arg
);
6418 DEFUN (interface_no_pim_use_source
,
6419 interface_no_pim_use_source_cmd
,
6420 "no ip pim use-source",
6423 "pim multicast routing\n"
6424 "Delete source IP address\n")
6426 return interface_pim_use_src_cmd_worker(vty
, "0.0.0.0");
6434 "Enables BFD support\n")
6436 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6437 struct pim_interface
*pim_ifp
= ifp
->info
;
6438 struct bfd_info
*bfd_info
= NULL
;
6442 bfd_info
= pim_ifp
->bfd_info
;
6444 if (!bfd_info
|| !CHECK_FLAG(bfd_info
->flags
, BFD_FLAG_PARAM_CFG
))
6445 pim_bfd_if_param_set(ifp
, BFD_DEF_MIN_RX
, BFD_DEF_MIN_TX
,
6446 BFD_DEF_DETECT_MULT
, 1);
6451 DEFUN (no_ip_pim_bfd
,
6457 "Disables BFD support\n")
6459 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6460 struct pim_interface
*pim_ifp
= ifp
->info
;
6465 if (pim_ifp
->bfd_info
) {
6466 pim_bfd_reg_dereg_all_nbr(ifp
, ZEBRA_BFD_DEST_DEREGISTER
);
6467 bfd_info_free(&(pim_ifp
->bfd_info
));
6473 DEFUN (ip_pim_bfd_param
,
6474 ip_pim_bfd_param_cmd
,
6475 "ip pim bfd (2-255) (50-60000) (50-60000)",
6478 "Enables BFD support\n"
6479 "Detect Multiplier\n"
6480 "Required min receive interval\n"
6481 "Desired min transmit interval\n")
6483 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6485 int idx_number_2
= 4;
6486 int idx_number_3
= 5;
6493 if ((ret
= bfd_validate_param(
6494 vty
, argv
[idx_number
]->arg
, argv
[idx_number_2
]->arg
,
6495 argv
[idx_number_3
]->arg
, &dm_val
, &rx_val
, &tx_val
))
6499 pim_bfd_if_param_set(ifp
, rx_val
, tx_val
, dm_val
, 0);
6504 ALIAS(no_ip_pim_bfd
, no_ip_pim_bfd_param_cmd
,
6505 "no ip pim bfd (2-255) (50-60000) (50-60000)", NO_STR IP_STR PIM_STR
6506 "Enables BFD support\n"
6507 "Detect Multiplier\n"
6508 "Required min receive interval\n"
6509 "Desired min transmit interval\n")
6511 static int ip_msdp_peer_cmd_worker(struct vty
*vty
, const char *peer
,
6514 enum pim_msdp_err result
;
6515 struct in_addr peer_addr
;
6516 struct in_addr local_addr
;
6518 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
6520 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s\n", peer
,
6521 errno
, safe_strerror(errno
));
6522 return CMD_WARNING_CONFIG_FAILED
;
6525 result
= inet_pton(AF_INET
, local
, &local_addr
);
6527 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", local
,
6528 errno
, safe_strerror(errno
));
6529 return CMD_WARNING_CONFIG_FAILED
;
6532 result
= pim_msdp_peer_add(pimg
, peer_addr
, local_addr
, "default",
6535 case PIM_MSDP_ERR_NONE
:
6537 case PIM_MSDP_ERR_OOM
:
6538 vty_out(vty
, "%% Out of memory\n");
6540 case PIM_MSDP_ERR_PEER_EXISTS
:
6541 vty_out(vty
, "%% Peer exists\n");
6543 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
6544 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
6547 vty_out(vty
, "%% peer add failed\n");
6550 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
6553 DEFUN_HIDDEN (ip_msdp_peer
,
6555 "ip msdp peer A.B.C.D source A.B.C.D",
6558 "Configure MSDP peer\n"
6560 "Source address for TCP connection\n"
6561 "local ip address\n")
6563 return ip_msdp_peer_cmd_worker(vty
, argv
[3]->arg
, argv
[5]->arg
);
6566 static int ip_no_msdp_peer_cmd_worker(struct vty
*vty
, const char *peer
)
6568 enum pim_msdp_err result
;
6569 struct in_addr peer_addr
;
6571 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
6573 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s\n", peer
,
6574 errno
, safe_strerror(errno
));
6575 return CMD_WARNING_CONFIG_FAILED
;
6578 result
= pim_msdp_peer_del(pimg
, peer_addr
);
6580 case PIM_MSDP_ERR_NONE
:
6582 case PIM_MSDP_ERR_NO_PEER
:
6583 vty_out(vty
, "%% Peer does not exist\n");
6586 vty_out(vty
, "%% peer del failed\n");
6589 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
6592 DEFUN_HIDDEN (no_ip_msdp_peer
,
6593 no_ip_msdp_peer_cmd
,
6594 "no ip msdp peer A.B.C.D",
6598 "Delete MSDP peer\n"
6599 "peer ip address\n")
6601 return ip_no_msdp_peer_cmd_worker(vty
, argv
[4]->arg
);
6604 static int ip_msdp_mesh_group_member_cmd_worker(struct vty
*vty
, const char *mg
,
6607 enum pim_msdp_err result
;
6608 struct in_addr mbr_ip
;
6610 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
6612 vty_out(vty
, "%% Bad member address %s: errno=%d: %s\n", mbr
,
6613 errno
, safe_strerror(errno
));
6614 return CMD_WARNING_CONFIG_FAILED
;
6617 result
= pim_msdp_mg_mbr_add(pimg
, mg
, mbr_ip
);
6619 case PIM_MSDP_ERR_NONE
:
6621 case PIM_MSDP_ERR_OOM
:
6622 vty_out(vty
, "%% Out of memory\n");
6624 case PIM_MSDP_ERR_MG_MBR_EXISTS
:
6625 vty_out(vty
, "%% mesh-group member exists\n");
6627 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
6628 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
6631 vty_out(vty
, "%% member add failed\n");
6634 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
6637 DEFUN (ip_msdp_mesh_group_member
,
6638 ip_msdp_mesh_group_member_cmd
,
6639 "ip msdp mesh-group WORD member A.B.C.D",
6642 "Configure MSDP mesh-group\n"
6644 "mesh group member\n"
6645 "peer ip address\n")
6647 return ip_msdp_mesh_group_member_cmd_worker(vty
, argv
[3]->arg
,
6651 static int ip_no_msdp_mesh_group_member_cmd_worker(struct vty
*vty
,
6655 enum pim_msdp_err result
;
6656 struct in_addr mbr_ip
;
6658 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
6660 vty_out(vty
, "%% Bad member address %s: errno=%d: %s\n", mbr
,
6661 errno
, safe_strerror(errno
));
6662 return CMD_WARNING_CONFIG_FAILED
;
6665 result
= pim_msdp_mg_mbr_del(pimg
, mg
, mbr_ip
);
6667 case PIM_MSDP_ERR_NONE
:
6669 case PIM_MSDP_ERR_NO_MG
:
6670 vty_out(vty
, "%% mesh-group does not exist\n");
6672 case PIM_MSDP_ERR_NO_MG_MBR
:
6673 vty_out(vty
, "%% mesh-group member does not exist\n");
6676 vty_out(vty
, "%% mesh-group member del failed\n");
6679 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
6681 DEFUN (no_ip_msdp_mesh_group_member
,
6682 no_ip_msdp_mesh_group_member_cmd
,
6683 "no ip msdp mesh-group WORD member A.B.C.D",
6687 "Delete MSDP mesh-group member\n"
6689 "mesh group member\n"
6690 "peer ip address\n")
6692 return ip_no_msdp_mesh_group_member_cmd_worker(vty
, argv
[4]->arg
,
6696 static int ip_msdp_mesh_group_source_cmd_worker(struct vty
*vty
, const char *mg
,
6699 enum pim_msdp_err result
;
6700 struct in_addr src_ip
;
6702 result
= inet_pton(AF_INET
, src
, &src_ip
);
6704 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", src
,
6705 errno
, safe_strerror(errno
));
6706 return CMD_WARNING_CONFIG_FAILED
;
6709 result
= pim_msdp_mg_src_add(pimg
, mg
, src_ip
);
6711 case PIM_MSDP_ERR_NONE
:
6713 case PIM_MSDP_ERR_OOM
:
6714 vty_out(vty
, "%% Out of memory\n");
6716 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
6717 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
6720 vty_out(vty
, "%% source add failed\n");
6723 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
6727 DEFUN (ip_msdp_mesh_group_source
,
6728 ip_msdp_mesh_group_source_cmd
,
6729 "ip msdp mesh-group WORD source A.B.C.D",
6732 "Configure MSDP mesh-group\n"
6734 "mesh group local address\n"
6735 "source ip address for the TCP connection\n")
6737 return ip_msdp_mesh_group_source_cmd_worker(vty
, argv
[3]->arg
,
6741 static int ip_no_msdp_mesh_group_source_cmd_worker(struct vty
*vty
,
6744 enum pim_msdp_err result
;
6746 result
= pim_msdp_mg_src_del(pimg
, mg
);
6748 case PIM_MSDP_ERR_NONE
:
6750 case PIM_MSDP_ERR_NO_MG
:
6751 vty_out(vty
, "%% mesh-group does not exist\n");
6754 vty_out(vty
, "%% mesh-group source del failed\n");
6757 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
6760 static int ip_no_msdp_mesh_group_cmd_worker(struct vty
*vty
, const char *mg
)
6762 enum pim_msdp_err result
;
6764 result
= pim_msdp_mg_del(pimg
, mg
);
6766 case PIM_MSDP_ERR_NONE
:
6768 case PIM_MSDP_ERR_NO_MG
:
6769 vty_out(vty
, "%% mesh-group does not exist\n");
6772 vty_out(vty
, "%% mesh-group source del failed\n");
6775 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
6778 DEFUN (no_ip_msdp_mesh_group_source
,
6779 no_ip_msdp_mesh_group_source_cmd
,
6780 "no ip msdp mesh-group WORD source [A.B.C.D]",
6784 "Delete MSDP mesh-group source\n"
6786 "mesh group source\n"
6787 "mesh group local address\n")
6790 return ip_no_msdp_mesh_group_cmd_worker(vty
, argv
[6]->arg
);
6792 return ip_no_msdp_mesh_group_source_cmd_worker(vty
,
6796 static void print_empty_json_obj(struct vty
*vty
)
6799 json
= json_object_new_object();
6800 vty_out(vty
, "%s\n",
6801 json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
));
6802 json_object_free(json
);
6805 static void ip_msdp_show_mesh_group(struct vty
*vty
, u_char uj
)
6807 struct listnode
*mbrnode
;
6808 struct pim_msdp_mg_mbr
*mbr
;
6809 struct pim_msdp_mg
*mg
= pimg
->msdp
.mg
;
6810 char mbr_str
[INET_ADDRSTRLEN
];
6811 char src_str
[INET_ADDRSTRLEN
];
6812 char state_str
[PIM_MSDP_STATE_STRLEN
];
6813 enum pim_msdp_peer_state state
;
6814 json_object
*json
= NULL
;
6815 json_object
*json_mg_row
= NULL
;
6816 json_object
*json_members
= NULL
;
6817 json_object
*json_row
= NULL
;
6821 print_empty_json_obj(vty
);
6825 pim_inet4_dump("<source?>", mg
->src_ip
, src_str
, sizeof(src_str
));
6827 json
= json_object_new_object();
6828 /* currently there is only one mesh group but we should still
6830 * it a dict with mg-name as key */
6831 json_mg_row
= json_object_new_object();
6832 json_object_string_add(json_mg_row
, "name",
6833 mg
->mesh_group_name
);
6834 json_object_string_add(json_mg_row
, "source", src_str
);
6836 vty_out(vty
, "Mesh group : %s\n", mg
->mesh_group_name
);
6837 vty_out(vty
, " Source : %s\n", src_str
);
6838 vty_out(vty
, " Member State\n");
6841 for (ALL_LIST_ELEMENTS_RO(mg
->mbr_list
, mbrnode
, mbr
)) {
6842 pim_inet4_dump("<mbr?>", mbr
->mbr_ip
, mbr_str
, sizeof(mbr_str
));
6844 state
= mbr
->mp
->state
;
6846 state
= PIM_MSDP_DISABLED
;
6848 pim_msdp_state_dump(state
, state_str
, sizeof(state_str
));
6850 json_row
= json_object_new_object();
6851 json_object_string_add(json_row
, "member", mbr_str
);
6852 json_object_string_add(json_row
, "state", state_str
);
6853 if (!json_members
) {
6854 json_members
= json_object_new_object();
6855 json_object_object_add(json_mg_row
, "members",
6858 json_object_object_add(json_members
, mbr_str
, json_row
);
6860 vty_out(vty
, " %-15s %11s\n", mbr_str
, state_str
);
6865 json_object_object_add(json
, mg
->mesh_group_name
, json_mg_row
);
6866 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
6867 json
, JSON_C_TO_STRING_PRETTY
));
6868 json_object_free(json
);
6872 DEFUN (show_ip_msdp_mesh_group
,
6873 show_ip_msdp_mesh_group_cmd
,
6874 "show ip msdp mesh-group [json]",
6878 "MSDP mesh-group information\n"
6879 "JavaScript Object Notation\n")
6881 u_char uj
= use_json(argc
, argv
);
6882 ip_msdp_show_mesh_group(vty
, uj
);
6887 static void ip_msdp_show_peers(struct vty
*vty
, u_char uj
)
6889 struct listnode
*mpnode
;
6890 struct pim_msdp_peer
*mp
;
6891 char peer_str
[INET_ADDRSTRLEN
];
6892 char local_str
[INET_ADDRSTRLEN
];
6893 char state_str
[PIM_MSDP_STATE_STRLEN
];
6894 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
6896 json_object
*json
= NULL
;
6897 json_object
*json_row
= NULL
;
6901 json
= json_object_new_object();
6904 "Peer Local State Uptime SaCnt\n");
6907 for (ALL_LIST_ELEMENTS_RO(pimg
->msdp
.peer_list
, mpnode
, mp
)) {
6908 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
6909 now
= pim_time_monotonic_sec();
6910 pim_time_uptime(timebuf
, sizeof(timebuf
),
6913 strcpy(timebuf
, "-");
6915 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
6916 pim_inet4_dump("<local?>", mp
->local
, local_str
,
6918 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
6920 json_row
= json_object_new_object();
6921 json_object_string_add(json_row
, "peer", peer_str
);
6922 json_object_string_add(json_row
, "local", local_str
);
6923 json_object_string_add(json_row
, "state", state_str
);
6924 json_object_string_add(json_row
, "upTime", timebuf
);
6925 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
6926 json_object_object_add(json
, peer_str
, json_row
);
6928 vty_out(vty
, "%-15s %15s %11s %8s %6d\n", peer_str
,
6929 local_str
, state_str
, timebuf
, mp
->sa_cnt
);
6934 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
6935 json
, JSON_C_TO_STRING_PRETTY
));
6936 json_object_free(json
);
6940 static void ip_msdp_show_peers_detail(struct vty
*vty
, const char *peer
,
6943 struct listnode
*mpnode
;
6944 struct pim_msdp_peer
*mp
;
6945 char peer_str
[INET_ADDRSTRLEN
];
6946 char local_str
[INET_ADDRSTRLEN
];
6947 char state_str
[PIM_MSDP_STATE_STRLEN
];
6948 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
6949 char katimer
[PIM_MSDP_TIMER_STRLEN
];
6950 char crtimer
[PIM_MSDP_TIMER_STRLEN
];
6951 char holdtimer
[PIM_MSDP_TIMER_STRLEN
];
6953 json_object
*json
= NULL
;
6954 json_object
*json_row
= NULL
;
6957 json
= json_object_new_object();
6960 for (ALL_LIST_ELEMENTS_RO(pimg
->msdp
.peer_list
, mpnode
, mp
)) {
6961 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
6962 if (strcmp(peer
, "detail") && strcmp(peer
, peer_str
))
6965 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
6966 now
= pim_time_monotonic_sec();
6967 pim_time_uptime(timebuf
, sizeof(timebuf
),
6970 strcpy(timebuf
, "-");
6972 pim_inet4_dump("<local?>", mp
->local
, local_str
,
6974 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
6975 pim_time_timer_to_hhmmss(katimer
, sizeof(katimer
),
6977 pim_time_timer_to_hhmmss(crtimer
, sizeof(crtimer
),
6979 pim_time_timer_to_hhmmss(holdtimer
, sizeof(holdtimer
),
6983 json_row
= json_object_new_object();
6984 json_object_string_add(json_row
, "peer", peer_str
);
6985 json_object_string_add(json_row
, "local", local_str
);
6986 json_object_string_add(json_row
, "meshGroupName",
6987 mp
->mesh_group_name
);
6988 json_object_string_add(json_row
, "state", state_str
);
6989 json_object_string_add(json_row
, "upTime", timebuf
);
6990 json_object_string_add(json_row
, "keepAliveTimer",
6992 json_object_string_add(json_row
, "connRetryTimer",
6994 json_object_string_add(json_row
, "holdTimer",
6996 json_object_string_add(json_row
, "lastReset",
6998 json_object_int_add(json_row
, "connAttempts",
7000 json_object_int_add(json_row
, "establishedChanges",
7002 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
7003 json_object_int_add(json_row
, "kaSent", mp
->ka_tx_cnt
);
7004 json_object_int_add(json_row
, "kaRcvd", mp
->ka_rx_cnt
);
7005 json_object_int_add(json_row
, "saSent", mp
->sa_tx_cnt
);
7006 json_object_int_add(json_row
, "saRcvd", mp
->sa_rx_cnt
);
7007 json_object_object_add(json
, peer_str
, json_row
);
7009 vty_out(vty
, "Peer : %s\n", peer_str
);
7010 vty_out(vty
, " Local : %s\n", local_str
);
7011 vty_out(vty
, " Mesh Group : %s\n",
7012 mp
->mesh_group_name
);
7013 vty_out(vty
, " State : %s\n", state_str
);
7014 vty_out(vty
, " Uptime : %s\n", timebuf
);
7016 vty_out(vty
, " Keepalive Timer : %s\n", katimer
);
7017 vty_out(vty
, " Conn Retry Timer : %s\n", crtimer
);
7018 vty_out(vty
, " Hold Timer : %s\n", holdtimer
);
7019 vty_out(vty
, " Last Reset : %s\n",
7021 vty_out(vty
, " Conn Attempts : %d\n",
7023 vty_out(vty
, " Established Changes : %d\n",
7025 vty_out(vty
, " SA Count : %d\n",
7027 vty_out(vty
, " Statistics :\n");
7030 vty_out(vty
, " Keepalives : %10d %10d\n",
7031 mp
->ka_tx_cnt
, mp
->ka_rx_cnt
);
7032 vty_out(vty
, " SAs : %10d %10d\n",
7033 mp
->sa_tx_cnt
, mp
->sa_rx_cnt
);
7039 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
7040 json
, JSON_C_TO_STRING_PRETTY
));
7041 json_object_free(json
);
7045 DEFUN (show_ip_msdp_peer_detail
,
7046 show_ip_msdp_peer_detail_cmd
,
7047 "show ip msdp peer [detail|A.B.C.D] [json]",
7051 "MSDP peer information\n"
7054 "JavaScript Object Notation\n")
7056 u_char uj
= use_json(argc
, argv
);
7061 ip_msdp_show_peers_detail(vty
, argv
[4]->arg
, uj
);
7063 ip_msdp_show_peers(vty
, uj
);
7068 static void ip_msdp_show_sa(struct vty
*vty
, u_char uj
)
7070 struct listnode
*sanode
;
7071 struct pim_msdp_sa
*sa
;
7072 char src_str
[INET_ADDRSTRLEN
];
7073 char grp_str
[INET_ADDRSTRLEN
];
7074 char rp_str
[INET_ADDRSTRLEN
];
7075 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
7079 json_object
*json
= NULL
;
7080 json_object
*json_group
= NULL
;
7081 json_object
*json_row
= NULL
;
7084 json
= json_object_new_object();
7087 "Source Group RP Local SPT Uptime\n");
7090 for (ALL_LIST_ELEMENTS_RO(pimg
->msdp
.sa_list
, sanode
, sa
)) {
7091 now
= pim_time_monotonic_sec();
7092 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
7093 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
7094 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
7095 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
7096 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
7098 strcpy(spt_str
, "yes");
7100 strcpy(spt_str
, "no");
7103 strcpy(rp_str
, "-");
7104 strcpy(spt_str
, "-");
7106 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
7107 strcpy(local_str
, "yes");
7109 strcpy(local_str
, "no");
7112 json_object_object_get_ex(json
, grp_str
, &json_group
);
7115 json_group
= json_object_new_object();
7116 json_object_object_add(json
, grp_str
,
7120 json_row
= json_object_new_object();
7121 json_object_string_add(json_row
, "source", src_str
);
7122 json_object_string_add(json_row
, "group", grp_str
);
7123 json_object_string_add(json_row
, "rp", rp_str
);
7124 json_object_string_add(json_row
, "local", local_str
);
7125 json_object_string_add(json_row
, "sptSetup", spt_str
);
7126 json_object_string_add(json_row
, "upTime", timebuf
);
7127 json_object_object_add(json_group
, src_str
, json_row
);
7129 vty_out(vty
, "%-15s %15s %15s %5c %3c %8s\n",
7130 src_str
, grp_str
, rp_str
, local_str
[0],
7131 spt_str
[0], timebuf
);
7137 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
7138 json
, JSON_C_TO_STRING_PRETTY
));
7139 json_object_free(json
);
7143 static void ip_msdp_show_sa_entry_detail(struct pim_msdp_sa
*sa
,
7144 const char *src_str
,
7145 const char *grp_str
, struct vty
*vty
,
7146 u_char uj
, json_object
*json
)
7148 char rp_str
[INET_ADDRSTRLEN
];
7149 char peer_str
[INET_ADDRSTRLEN
];
7150 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
7153 char statetimer
[PIM_MSDP_TIMER_STRLEN
];
7155 json_object
*json_group
= NULL
;
7156 json_object
*json_row
= NULL
;
7158 now
= pim_time_monotonic_sec();
7159 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
7160 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
7161 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
7162 pim_inet4_dump("<peer?>", sa
->peer
, peer_str
, sizeof(peer_str
));
7164 strcpy(spt_str
, "yes");
7166 strcpy(spt_str
, "no");
7169 strcpy(rp_str
, "-");
7170 strcpy(peer_str
, "-");
7171 strcpy(spt_str
, "-");
7173 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
7174 strcpy(local_str
, "yes");
7176 strcpy(local_str
, "no");
7178 pim_time_timer_to_hhmmss(statetimer
, sizeof(statetimer
),
7179 sa
->sa_state_timer
);
7181 json_object_object_get_ex(json
, grp_str
, &json_group
);
7184 json_group
= json_object_new_object();
7185 json_object_object_add(json
, grp_str
, json_group
);
7188 json_row
= json_object_new_object();
7189 json_object_string_add(json_row
, "source", src_str
);
7190 json_object_string_add(json_row
, "group", grp_str
);
7191 json_object_string_add(json_row
, "rp", rp_str
);
7192 json_object_string_add(json_row
, "local", local_str
);
7193 json_object_string_add(json_row
, "sptSetup", spt_str
);
7194 json_object_string_add(json_row
, "upTime", timebuf
);
7195 json_object_string_add(json_row
, "stateTimer", statetimer
);
7196 json_object_object_add(json_group
, src_str
, json_row
);
7198 vty_out(vty
, "SA : %s\n", sa
->sg_str
);
7199 vty_out(vty
, " RP : %s\n", rp_str
);
7200 vty_out(vty
, " Peer : %s\n", peer_str
);
7201 vty_out(vty
, " Local : %s\n", local_str
);
7202 vty_out(vty
, " SPT Setup : %s\n", spt_str
);
7203 vty_out(vty
, " Uptime : %s\n", timebuf
);
7204 vty_out(vty
, " State Timer : %s\n", statetimer
);
7209 static void ip_msdp_show_sa_detail(struct vty
*vty
, u_char uj
)
7211 struct listnode
*sanode
;
7212 struct pim_msdp_sa
*sa
;
7213 char src_str
[INET_ADDRSTRLEN
];
7214 char grp_str
[INET_ADDRSTRLEN
];
7215 json_object
*json
= NULL
;
7218 json
= json_object_new_object();
7221 for (ALL_LIST_ELEMENTS_RO(pimg
->msdp
.sa_list
, sanode
, sa
)) {
7222 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
7223 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
7224 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
, uj
,
7229 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
7230 json
, JSON_C_TO_STRING_PRETTY
));
7231 json_object_free(json
);
7235 DEFUN (show_ip_msdp_sa_detail
,
7236 show_ip_msdp_sa_detail_cmd
,
7237 "show ip msdp sa detail [json]",
7241 "MSDP active-source information\n"
7243 "JavaScript Object Notation\n")
7245 u_char uj
= use_json(argc
, argv
);
7246 ip_msdp_show_sa_detail(vty
, uj
);
7251 static void ip_msdp_show_sa_addr(struct vty
*vty
, const char *addr
, u_char uj
)
7253 struct listnode
*sanode
;
7254 struct pim_msdp_sa
*sa
;
7255 char src_str
[INET_ADDRSTRLEN
];
7256 char grp_str
[INET_ADDRSTRLEN
];
7257 json_object
*json
= NULL
;
7260 json
= json_object_new_object();
7263 for (ALL_LIST_ELEMENTS_RO(pimg
->msdp
.sa_list
, sanode
, sa
)) {
7264 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
7265 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
7266 if (!strcmp(addr
, src_str
) || !strcmp(addr
, grp_str
)) {
7267 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
,
7273 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
7274 json
, JSON_C_TO_STRING_PRETTY
));
7275 json_object_free(json
);
7279 static void ip_msdp_show_sa_sg(struct vty
*vty
, const char *src
,
7280 const char *grp
, u_char uj
)
7282 struct listnode
*sanode
;
7283 struct pim_msdp_sa
*sa
;
7284 char src_str
[INET_ADDRSTRLEN
];
7285 char grp_str
[INET_ADDRSTRLEN
];
7286 json_object
*json
= NULL
;
7289 json
= json_object_new_object();
7292 for (ALL_LIST_ELEMENTS_RO(pimg
->msdp
.sa_list
, sanode
, sa
)) {
7293 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
7294 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
7295 if (!strcmp(src
, src_str
) && !strcmp(grp
, grp_str
)) {
7296 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
,
7302 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
7303 json
, JSON_C_TO_STRING_PRETTY
));
7304 json_object_free(json
);
7308 DEFUN (show_ip_msdp_sa_sg
,
7309 show_ip_msdp_sa_sg_cmd
,
7310 "show ip msdp sa [A.B.C.D [A.B.C.D]] [json]",
7314 "MSDP active-source information\n"
7315 "source or group ip\n"
7317 "JavaScript Object Notation\n")
7319 u_char uj
= use_json(argc
, argv
);
7322 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
++]->arg
7324 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
)
7328 if (src_ip
&& grp_ip
)
7329 ip_msdp_show_sa_sg(vty
, src_ip
, grp_ip
, uj
);
7331 ip_msdp_show_sa_addr(vty
, src_ip
, uj
);
7333 ip_msdp_show_sa(vty
, uj
);
7340 install_node(&pim_global_node
, pim_global_config_write
); /* PIM_NODE */
7341 install_node(&interface_node
,
7342 pim_interface_config_write
); /* INTERFACE_NODE */
7345 install_node(&debug_node
, pim_debug_config_write
);
7347 install_element(CONFIG_NODE
, &ip_multicast_routing_cmd
);
7348 install_element(CONFIG_NODE
, &no_ip_multicast_routing_cmd
);
7349 install_element(CONFIG_NODE
, &ip_pim_rp_cmd
);
7350 install_element(VRF_NODE
, &ip_pim_rp_cmd
);
7351 install_element(CONFIG_NODE
, &no_ip_pim_rp_cmd
);
7352 install_element(VRF_NODE
, &no_ip_pim_rp_cmd
);
7353 install_element(CONFIG_NODE
, &ip_pim_rp_prefix_list_cmd
);
7354 install_element(CONFIG_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
7355 install_element(CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_cmd
);
7356 install_element(CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_name_cmd
);
7357 install_element(CONFIG_NODE
, &ip_pim_ssm_prefix_list_cmd
);
7358 install_element(CONFIG_NODE
, &ip_pim_register_suppress_cmd
);
7359 install_element(CONFIG_NODE
, &no_ip_pim_register_suppress_cmd
);
7360 install_element(CONFIG_NODE
, &ip_pim_spt_switchover_infinity_cmd
);
7361 install_element(CONFIG_NODE
, &ip_pim_spt_switchover_infinity_plist_cmd
);
7362 install_element(CONFIG_NODE
, &no_ip_pim_spt_switchover_infinity_cmd
);
7363 install_element(CONFIG_NODE
,
7364 &no_ip_pim_spt_switchover_infinity_plist_cmd
);
7365 install_element(CONFIG_NODE
, &ip_pim_joinprune_time_cmd
);
7366 install_element(CONFIG_NODE
, &no_ip_pim_joinprune_time_cmd
);
7367 install_element(CONFIG_NODE
, &ip_pim_keep_alive_cmd
);
7368 install_element(CONFIG_NODE
, &no_ip_pim_keep_alive_cmd
);
7369 install_element(CONFIG_NODE
, &ip_pim_packets_cmd
);
7370 install_element(CONFIG_NODE
, &no_ip_pim_packets_cmd
);
7371 install_element(CONFIG_NODE
, &ip_pim_v6_secondary_cmd
);
7372 install_element(CONFIG_NODE
, &no_ip_pim_v6_secondary_cmd
);
7373 install_element(CONFIG_NODE
, &ip_ssmpingd_cmd
);
7374 install_element(CONFIG_NODE
, &no_ip_ssmpingd_cmd
);
7375 install_element(CONFIG_NODE
, &ip_msdp_peer_cmd
);
7376 install_element(CONFIG_NODE
, &no_ip_msdp_peer_cmd
);
7377 install_element(CONFIG_NODE
, &ip_pim_ecmp_cmd
);
7378 install_element(CONFIG_NODE
, &no_ip_pim_ecmp_cmd
);
7379 install_element(CONFIG_NODE
, &ip_pim_ecmp_rebalance_cmd
);
7380 install_element(CONFIG_NODE
, &no_ip_pim_ecmp_rebalance_cmd
);
7382 install_element(INTERFACE_NODE
, &interface_ip_igmp_cmd
);
7383 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_cmd
);
7384 install_element(INTERFACE_NODE
, &interface_ip_igmp_join_cmd
);
7385 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_join_cmd
);
7386 install_element(INTERFACE_NODE
, &interface_ip_igmp_version_cmd
);
7387 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_version_cmd
);
7388 install_element(INTERFACE_NODE
, &interface_ip_igmp_query_interval_cmd
);
7389 install_element(INTERFACE_NODE
,
7390 &interface_no_ip_igmp_query_interval_cmd
);
7391 install_element(INTERFACE_NODE
,
7392 &interface_ip_igmp_query_max_response_time_cmd
);
7393 install_element(INTERFACE_NODE
,
7394 &interface_no_ip_igmp_query_max_response_time_cmd
);
7395 install_element(INTERFACE_NODE
,
7396 &interface_ip_igmp_query_max_response_time_dsec_cmd
);
7397 install_element(INTERFACE_NODE
,
7398 &interface_no_ip_igmp_query_max_response_time_dsec_cmd
);
7399 install_element(INTERFACE_NODE
, &interface_ip_pim_ssm_cmd
);
7400 install_element(INTERFACE_NODE
, &interface_no_ip_pim_ssm_cmd
);
7401 install_element(INTERFACE_NODE
, &interface_ip_pim_sm_cmd
);
7402 install_element(INTERFACE_NODE
, &interface_no_ip_pim_sm_cmd
);
7403 install_element(INTERFACE_NODE
, &interface_ip_pim_drprio_cmd
);
7404 install_element(INTERFACE_NODE
, &interface_no_ip_pim_drprio_cmd
);
7405 install_element(INTERFACE_NODE
, &interface_ip_pim_hello_cmd
);
7406 install_element(INTERFACE_NODE
, &interface_no_ip_pim_hello_cmd
);
7408 // Static mroutes NEB
7409 install_element(INTERFACE_NODE
, &interface_ip_mroute_cmd
);
7410 install_element(INTERFACE_NODE
, &interface_ip_mroute_source_cmd
);
7411 install_element(INTERFACE_NODE
, &interface_no_ip_mroute_cmd
);
7412 install_element(INTERFACE_NODE
, &interface_no_ip_mroute_source_cmd
);
7414 install_element(VIEW_NODE
, &show_ip_igmp_interface_cmd
);
7415 install_element(VIEW_NODE
, &show_ip_igmp_join_cmd
);
7416 install_element(VIEW_NODE
, &show_ip_igmp_groups_cmd
);
7417 install_element(VIEW_NODE
, &show_ip_igmp_groups_retransmissions_cmd
);
7418 install_element(VIEW_NODE
, &show_ip_igmp_sources_cmd
);
7419 install_element(VIEW_NODE
, &show_ip_igmp_sources_retransmissions_cmd
);
7420 install_element(VIEW_NODE
, &show_ip_pim_assert_cmd
);
7421 install_element(VIEW_NODE
, &show_ip_pim_assert_internal_cmd
);
7422 install_element(VIEW_NODE
, &show_ip_pim_assert_metric_cmd
);
7423 install_element(VIEW_NODE
, &show_ip_pim_assert_winner_metric_cmd
);
7424 install_element(VIEW_NODE
, &show_ip_pim_interface_traffic_cmd
);
7425 install_element(VIEW_NODE
, &show_ip_pim_interface_cmd
);
7426 install_element(VIEW_NODE
, &show_ip_pim_join_cmd
);
7427 install_element(VIEW_NODE
, &show_ip_pim_local_membership_cmd
);
7428 install_element(VIEW_NODE
, &show_ip_pim_neighbor_cmd
);
7429 install_element(VIEW_NODE
, &show_ip_pim_rpf_cmd
);
7430 install_element(VIEW_NODE
, &show_ip_pim_secondary_cmd
);
7431 install_element(VIEW_NODE
, &show_ip_pim_state_cmd
);
7432 install_element(VIEW_NODE
, &show_ip_pim_upstream_cmd
);
7433 install_element(VIEW_NODE
, &show_ip_pim_upstream_join_desired_cmd
);
7434 install_element(VIEW_NODE
, &show_ip_pim_upstream_rpf_cmd
);
7435 install_element(VIEW_NODE
, &show_ip_pim_rp_cmd
);
7436 install_element(VIEW_NODE
, &show_ip_multicast_cmd
);
7437 install_element(VIEW_NODE
, &show_ip_mroute_cmd
);
7438 install_element(VIEW_NODE
, &show_ip_mroute_count_cmd
);
7439 install_element(VIEW_NODE
, &show_ip_rib_cmd
);
7440 install_element(VIEW_NODE
, &show_ip_ssmpingd_cmd
);
7441 install_element(VIEW_NODE
, &show_debugging_pim_cmd
);
7442 install_element(VIEW_NODE
, &show_ip_pim_nexthop_cmd
);
7443 install_element(VIEW_NODE
, &show_ip_pim_nexthop_lookup_cmd
);
7445 install_element(ENABLE_NODE
, &clear_ip_interfaces_cmd
);
7446 install_element(ENABLE_NODE
, &clear_ip_igmp_interfaces_cmd
);
7447 install_element(ENABLE_NODE
, &clear_ip_mroute_cmd
);
7448 install_element(ENABLE_NODE
, &clear_ip_pim_interfaces_cmd
);
7449 install_element(ENABLE_NODE
, &clear_ip_pim_interface_traffic_cmd
);
7450 install_element(ENABLE_NODE
, &clear_ip_pim_oil_cmd
);
7452 install_element(ENABLE_NODE
, &debug_igmp_cmd
);
7453 install_element(ENABLE_NODE
, &no_debug_igmp_cmd
);
7454 install_element(ENABLE_NODE
, &debug_igmp_events_cmd
);
7455 install_element(ENABLE_NODE
, &no_debug_igmp_events_cmd
);
7456 install_element(ENABLE_NODE
, &debug_igmp_packets_cmd
);
7457 install_element(ENABLE_NODE
, &no_debug_igmp_packets_cmd
);
7458 install_element(ENABLE_NODE
, &debug_igmp_trace_cmd
);
7459 install_element(ENABLE_NODE
, &no_debug_igmp_trace_cmd
);
7460 install_element(ENABLE_NODE
, &debug_mroute_cmd
);
7461 install_element(ENABLE_NODE
, &debug_mroute_detail_cmd
);
7462 install_element(ENABLE_NODE
, &no_debug_mroute_cmd
);
7463 install_element(ENABLE_NODE
, &no_debug_mroute_detail_cmd
);
7464 install_element(ENABLE_NODE
, &debug_static_cmd
);
7465 install_element(ENABLE_NODE
, &no_debug_static_cmd
);
7466 install_element(ENABLE_NODE
, &debug_pim_cmd
);
7467 install_element(ENABLE_NODE
, &no_debug_pim_cmd
);
7468 install_element(ENABLE_NODE
, &debug_pim_events_cmd
);
7469 install_element(ENABLE_NODE
, &no_debug_pim_events_cmd
);
7470 install_element(ENABLE_NODE
, &debug_pim_packets_cmd
);
7471 install_element(ENABLE_NODE
, &no_debug_pim_packets_cmd
);
7472 install_element(ENABLE_NODE
, &debug_pim_packetdump_send_cmd
);
7473 install_element(ENABLE_NODE
, &no_debug_pim_packetdump_send_cmd
);
7474 install_element(ENABLE_NODE
, &debug_pim_packetdump_recv_cmd
);
7475 install_element(ENABLE_NODE
, &no_debug_pim_packetdump_recv_cmd
);
7476 install_element(ENABLE_NODE
, &debug_pim_trace_cmd
);
7477 install_element(ENABLE_NODE
, &no_debug_pim_trace_cmd
);
7478 install_element(ENABLE_NODE
, &debug_ssmpingd_cmd
);
7479 install_element(ENABLE_NODE
, &no_debug_ssmpingd_cmd
);
7480 install_element(ENABLE_NODE
, &debug_pim_zebra_cmd
);
7481 install_element(ENABLE_NODE
, &no_debug_pim_zebra_cmd
);
7482 install_element(ENABLE_NODE
, &debug_msdp_cmd
);
7483 install_element(ENABLE_NODE
, &no_debug_msdp_cmd
);
7484 install_element(ENABLE_NODE
, &undebug_msdp_cmd
);
7485 install_element(ENABLE_NODE
, &debug_msdp_events_cmd
);
7486 install_element(ENABLE_NODE
, &no_debug_msdp_events_cmd
);
7487 install_element(ENABLE_NODE
, &undebug_msdp_events_cmd
);
7488 install_element(ENABLE_NODE
, &debug_msdp_packets_cmd
);
7489 install_element(ENABLE_NODE
, &no_debug_msdp_packets_cmd
);
7490 install_element(ENABLE_NODE
, &undebug_msdp_packets_cmd
);
7492 install_element(CONFIG_NODE
, &debug_igmp_cmd
);
7493 install_element(CONFIG_NODE
, &no_debug_igmp_cmd
);
7494 install_element(CONFIG_NODE
, &debug_igmp_events_cmd
);
7495 install_element(CONFIG_NODE
, &no_debug_igmp_events_cmd
);
7496 install_element(CONFIG_NODE
, &debug_igmp_packets_cmd
);
7497 install_element(CONFIG_NODE
, &no_debug_igmp_packets_cmd
);
7498 install_element(CONFIG_NODE
, &debug_igmp_trace_cmd
);
7499 install_element(CONFIG_NODE
, &no_debug_igmp_trace_cmd
);
7500 install_element(CONFIG_NODE
, &debug_mroute_cmd
);
7501 install_element(CONFIG_NODE
, &debug_mroute_detail_cmd
);
7502 install_element(CONFIG_NODE
, &no_debug_mroute_cmd
);
7503 install_element(CONFIG_NODE
, &no_debug_mroute_detail_cmd
);
7504 install_element(CONFIG_NODE
, &debug_static_cmd
);
7505 install_element(CONFIG_NODE
, &no_debug_static_cmd
);
7506 install_element(CONFIG_NODE
, &debug_pim_cmd
);
7507 install_element(CONFIG_NODE
, &no_debug_pim_cmd
);
7508 install_element(CONFIG_NODE
, &debug_pim_events_cmd
);
7509 install_element(CONFIG_NODE
, &no_debug_pim_events_cmd
);
7510 install_element(CONFIG_NODE
, &debug_pim_packets_cmd
);
7511 install_element(CONFIG_NODE
, &no_debug_pim_packets_cmd
);
7512 install_element(CONFIG_NODE
, &debug_pim_trace_cmd
);
7513 install_element(CONFIG_NODE
, &no_debug_pim_trace_cmd
);
7514 install_element(CONFIG_NODE
, &debug_ssmpingd_cmd
);
7515 install_element(CONFIG_NODE
, &no_debug_ssmpingd_cmd
);
7516 install_element(CONFIG_NODE
, &debug_pim_zebra_cmd
);
7517 install_element(CONFIG_NODE
, &no_debug_pim_zebra_cmd
);
7518 install_element(CONFIG_NODE
, &debug_msdp_cmd
);
7519 install_element(CONFIG_NODE
, &no_debug_msdp_cmd
);
7520 install_element(CONFIG_NODE
, &undebug_msdp_cmd
);
7521 install_element(CONFIG_NODE
, &debug_msdp_events_cmd
);
7522 install_element(CONFIG_NODE
, &no_debug_msdp_events_cmd
);
7523 install_element(CONFIG_NODE
, &undebug_msdp_events_cmd
);
7524 install_element(CONFIG_NODE
, &debug_msdp_packets_cmd
);
7525 install_element(CONFIG_NODE
, &no_debug_msdp_packets_cmd
);
7526 install_element(CONFIG_NODE
, &undebug_msdp_packets_cmd
);
7527 install_element(CONFIG_NODE
, &ip_msdp_mesh_group_member_cmd
);
7528 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_member_cmd
);
7529 install_element(CONFIG_NODE
, &ip_msdp_mesh_group_source_cmd
);
7530 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_source_cmd
);
7531 install_element(VIEW_NODE
, &show_ip_msdp_peer_detail_cmd
);
7532 install_element(VIEW_NODE
, &show_ip_msdp_sa_detail_cmd
);
7533 install_element(VIEW_NODE
, &show_ip_msdp_sa_sg_cmd
);
7534 install_element(VIEW_NODE
, &show_ip_msdp_mesh_group_cmd
);
7535 install_element(VIEW_NODE
, &show_ip_pim_ssm_range_cmd
);
7536 install_element(VIEW_NODE
, &show_ip_pim_group_type_cmd
);
7537 install_element(INTERFACE_NODE
, &interface_pim_use_source_cmd
);
7538 install_element(INTERFACE_NODE
, &interface_no_pim_use_source_cmd
);
7539 /* Install BFD command */
7540 install_element(INTERFACE_NODE
, &ip_pim_bfd_cmd
);
7541 install_element(INTERFACE_NODE
, &ip_pim_bfd_param_cmd
);
7542 install_element(INTERFACE_NODE
, &no_ip_pim_bfd_cmd
);
7543 install_element(INTERFACE_NODE
, &no_ip_pim_bfd_param_cmd
);