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
34 #include "pim_mroute.h"
36 #include "pim_iface.h"
38 #include "pim_mroute.h"
41 #include "pim_igmpv3.h"
46 #include "pim_neighbor.h"
48 #include "pim_ifchannel.h"
49 #include "pim_hello.h"
51 #include "pim_upstream.h"
53 #include "pim_macro.h"
54 #include "pim_ssmpingd.h"
55 #include "pim_zebra.h"
56 #include "pim_static.h"
58 #include "pim_zlookup.h"
65 static struct cmd_node interface_node
= {
66 INTERFACE_NODE
, "%s(config-if)# ", 1 /* vtysh ? yes */
69 static struct cmd_node debug_node
= {DEBUG_NODE
, "", 1};
71 static struct vrf
*pim_cmd_lookup_vrf(struct vty
*vty
, struct cmd_token
*argv
[],
72 const int argc
, int *idx
)
76 if (argv_find(argv
, argc
, "NAME", idx
))
77 vrf
= vrf_lookup_by_name(argv
[*idx
]->arg
);
79 vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
82 vty_out(vty
, "Specified VRF: %s does not exist\n",
88 static void pim_if_membership_clear(struct interface
*ifp
)
90 struct pim_interface
*pim_ifp
;
95 if (PIM_IF_TEST_PIM(pim_ifp
->options
)
96 && PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
100 pim_ifchannel_membership_clear(ifp
);
104 When PIM is disabled on interface, IGMPv3 local membership
105 information is not injected into PIM interface state.
107 The function pim_if_membership_refresh() fetches all IGMPv3 local
108 membership information into PIM. It is intented to be called
109 whenever PIM is enabled on the interface in order to collect missed
110 local membership information.
112 static void pim_if_membership_refresh(struct interface
*ifp
)
114 struct pim_interface
*pim_ifp
;
115 struct listnode
*sock_node
;
116 struct igmp_sock
*igmp
;
121 if (!PIM_IF_TEST_PIM(pim_ifp
->options
))
123 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
))
127 First clear off membership from all PIM (S,G) entries on the
131 pim_ifchannel_membership_clear(ifp
);
134 Then restore PIM (S,G) membership from all IGMPv3 (S,G) entries on
138 /* scan igmp sockets */
139 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
140 struct listnode
*grpnode
;
141 struct igmp_group
*grp
;
143 /* scan igmp groups */
144 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grpnode
,
146 struct listnode
*srcnode
;
147 struct igmp_source
*src
;
149 /* scan group sources */
150 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
,
153 if (IGMP_SOURCE_TEST_FORWARDING(
154 src
->source_flags
)) {
158 sizeof(struct prefix_sg
));
159 sg
.src
= src
->source_addr
;
160 sg
.grp
= grp
->group_addr
;
161 pim_ifchannel_local_membership_add(ifp
,
165 } /* scan group sources */
166 } /* scan igmp groups */
167 } /* scan igmp sockets */
170 Finally delete every PIM (S,G) entry lacking all state info
173 pim_ifchannel_delete_on_noinfo(ifp
);
176 static void pim_show_assert_helper(struct vty
*vty
,
177 struct pim_interface
*pim_ifp
,
178 struct pim_ifchannel
*ch
, time_t now
)
180 char ch_src_str
[INET_ADDRSTRLEN
];
181 char ch_grp_str
[INET_ADDRSTRLEN
];
182 char winner_str
[INET_ADDRSTRLEN
];
183 struct in_addr ifaddr
;
187 ifaddr
= pim_ifp
->primary_address
;
189 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
190 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
191 pim_inet4_dump("<assrt_win?>", ch
->ifassert_winner
, winner_str
,
194 pim_time_uptime(uptime
, sizeof(uptime
), now
- ch
->ifassert_creation
);
195 pim_time_timer_to_mmss(timer
, sizeof(timer
), ch
->t_ifassert_timer
);
197 vty_out(vty
, "%-9s %-15s %-15s %-15s %-6s %-15s %-8s %-5s\n",
198 ch
->interface
->name
, inet_ntoa(ifaddr
), ch_src_str
, ch_grp_str
,
199 pim_ifchannel_ifassert_name(ch
->ifassert_state
), winner_str
,
203 static void pim_show_assert(struct pim_instance
*pim
, struct vty
*vty
)
205 struct pim_interface
*pim_ifp
;
206 struct pim_ifchannel
*ch
;
207 struct interface
*ifp
;
210 now
= pim_time_monotonic_sec();
213 "Interface Address Source Group State Winner Uptime Timer\n");
215 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
220 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
221 pim_show_assert_helper(vty
, pim_ifp
, ch
, now
);
222 } /* scan interface channels */
226 static void pim_show_assert_internal_helper(struct vty
*vty
,
227 struct pim_interface
*pim_ifp
,
228 struct pim_ifchannel
*ch
)
230 char ch_src_str
[INET_ADDRSTRLEN
];
231 char ch_grp_str
[INET_ADDRSTRLEN
];
232 struct in_addr ifaddr
;
234 ifaddr
= pim_ifp
->primary_address
;
236 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
237 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
238 vty_out(vty
, "%-9s %-15s %-15s %-15s %-3s %-3s %-3s %-4s\n",
239 ch
->interface
->name
, inet_ntoa(ifaddr
), ch_src_str
, ch_grp_str
,
240 PIM_IF_FLAG_TEST_COULD_ASSERT(ch
->flags
) ? "yes" : "no",
241 pim_macro_ch_could_assert_eval(ch
) ? "yes" : "no",
242 PIM_IF_FLAG_TEST_ASSERT_TRACKING_DESIRED(ch
->flags
) ? "yes"
244 pim_macro_assert_tracking_desired_eval(ch
) ? "yes" : "no");
247 static void pim_show_assert_internal(struct pim_instance
*pim
, struct vty
*vty
)
249 struct pim_interface
*pim_ifp
;
250 struct pim_ifchannel
*ch
;
251 struct interface
*ifp
;
255 "ECA: Evaluate CouldAssert\n"
256 "ATD: AssertTrackingDesired\n"
257 "eATD: Evaluate AssertTrackingDesired\n\n");
260 "Interface Address Source Group CA eCA ATD eATD\n");
261 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
266 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
267 pim_show_assert_internal_helper(vty
, pim_ifp
, ch
);
268 } /* scan interface channels */
272 static void pim_show_assert_metric_helper(struct vty
*vty
,
273 struct pim_interface
*pim_ifp
,
274 struct pim_ifchannel
*ch
)
276 char ch_src_str
[INET_ADDRSTRLEN
];
277 char ch_grp_str
[INET_ADDRSTRLEN
];
278 char addr_str
[INET_ADDRSTRLEN
];
279 struct pim_assert_metric am
;
280 struct in_addr ifaddr
;
282 ifaddr
= pim_ifp
->primary_address
;
284 am
= pim_macro_spt_assert_metric(&ch
->upstream
->rpf
,
285 pim_ifp
->primary_address
);
287 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
288 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
289 pim_inet4_dump("<addr?>", am
.ip_address
, addr_str
, sizeof(addr_str
));
291 vty_out(vty
, "%-9s %-15s %-15s %-15s %-3s %4u %6u %-15s\n",
292 ch
->interface
->name
, inet_ntoa(ifaddr
), ch_src_str
, ch_grp_str
,
293 am
.rpt_bit_flag
? "yes" : "no", am
.metric_preference
,
294 am
.route_metric
, addr_str
);
297 static void pim_show_assert_metric(struct pim_instance
*pim
, struct vty
*vty
)
299 struct pim_interface
*pim_ifp
;
300 struct pim_ifchannel
*ch
;
301 struct interface
*ifp
;
304 "Interface Address Source Group RPT Pref Metric Address \n");
306 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
311 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
312 pim_show_assert_metric_helper(vty
, pim_ifp
, ch
);
313 } /* scan interface channels */
317 static void pim_show_assert_winner_metric_helper(struct vty
*vty
,
318 struct pim_interface
*pim_ifp
,
319 struct pim_ifchannel
*ch
)
321 char ch_src_str
[INET_ADDRSTRLEN
];
322 char ch_grp_str
[INET_ADDRSTRLEN
];
323 char addr_str
[INET_ADDRSTRLEN
];
324 struct pim_assert_metric
*am
;
325 struct in_addr ifaddr
;
329 ifaddr
= pim_ifp
->primary_address
;
331 am
= &ch
->ifassert_winner_metric
;
333 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
334 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
335 pim_inet4_dump("<addr?>", am
->ip_address
, addr_str
, sizeof(addr_str
));
337 if (am
->metric_preference
== PIM_ASSERT_METRIC_PREFERENCE_MAX
)
338 snprintf(pref_str
, sizeof(pref_str
), "INFI");
340 snprintf(pref_str
, sizeof(pref_str
), "%4u",
341 am
->metric_preference
);
343 if (am
->route_metric
== PIM_ASSERT_ROUTE_METRIC_MAX
)
344 snprintf(metr_str
, sizeof(metr_str
), "INFI");
346 snprintf(metr_str
, sizeof(metr_str
), "%6u", am
->route_metric
);
348 vty_out(vty
, "%-9s %-15s %-15s %-15s %-3s %-4s %-6s %-15s\n",
349 ch
->interface
->name
, inet_ntoa(ifaddr
), ch_src_str
, ch_grp_str
,
350 am
->rpt_bit_flag
? "yes" : "no", pref_str
, metr_str
, addr_str
);
353 static void pim_show_assert_winner_metric(struct pim_instance
*pim
,
356 struct pim_interface
*pim_ifp
;
357 struct pim_ifchannel
*ch
;
358 struct interface
*ifp
;
361 "Interface Address Source Group RPT Pref Metric Address \n");
363 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
368 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
369 pim_show_assert_winner_metric_helper(vty
, pim_ifp
, ch
);
370 } /* scan interface channels */
374 static void json_object_pim_ifp_add(struct json_object
*json
,
375 struct interface
*ifp
)
377 struct pim_interface
*pim_ifp
;
380 json_object_string_add(json
, "name", ifp
->name
);
381 json_object_string_add(json
, "state", if_is_up(ifp
) ? "up" : "down");
382 json_object_string_add(json
, "address",
383 inet_ntoa(pim_ifp
->primary_address
));
384 json_object_int_add(json
, "index", ifp
->ifindex
);
386 if (if_is_multicast(ifp
))
387 json_object_boolean_true_add(json
, "flagMulticast");
389 if (if_is_broadcast(ifp
))
390 json_object_boolean_true_add(json
, "flagBroadcast");
392 if (ifp
->flags
& IFF_ALLMULTI
)
393 json_object_boolean_true_add(json
, "flagAllMulticast");
395 if (ifp
->flags
& IFF_PROMISC
)
396 json_object_boolean_true_add(json
, "flagPromiscuous");
398 if (PIM_IF_IS_DELETED(ifp
))
399 json_object_boolean_true_add(json
, "flagDeleted");
401 if (pim_if_lan_delay_enabled(ifp
))
402 json_object_boolean_true_add(json
, "lanDelayEnabled");
405 static void pim_show_membership_helper(struct vty
*vty
,
406 struct pim_interface
*pim_ifp
,
407 struct pim_ifchannel
*ch
,
408 struct json_object
*json
)
410 char ch_src_str
[INET_ADDRSTRLEN
];
411 char ch_grp_str
[INET_ADDRSTRLEN
];
412 json_object
*json_iface
= NULL
;
413 json_object
*json_row
= NULL
;
415 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
416 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
418 json_object_object_get_ex(json
, ch
->interface
->name
, &json_iface
);
420 json_iface
= json_object_new_object();
421 json_object_pim_ifp_add(json_iface
, ch
->interface
);
422 json_object_object_add(json
, ch
->interface
->name
, json_iface
);
425 json_row
= json_object_new_object();
426 json_object_string_add(json_row
, "source", ch_src_str
);
427 json_object_string_add(json_row
, "group", ch_grp_str
);
428 json_object_string_add(json_row
, "localMembership",
429 ch
->local_ifmembership
== PIM_IFMEMBERSHIP_NOINFO
432 json_object_object_add(json_iface
, ch_grp_str
, json_row
);
434 static void pim_show_membership(struct pim_instance
*pim
, struct vty
*vty
,
437 struct pim_interface
*pim_ifp
;
438 struct pim_ifchannel
*ch
;
439 struct interface
*ifp
;
441 json_object
*json
= NULL
;
442 json_object
*json_tmp
= NULL
;
444 json
= json_object_new_object();
446 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
451 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
452 pim_show_membership_helper(vty
, pim_ifp
, ch
, json
);
453 } /* scan interface channels */
457 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
458 json
, JSON_C_TO_STRING_PRETTY
));
461 "Interface Address Source Group Membership\n");
464 * Example of the json data we are traversing
470 * "address":"10.1.20.1",
472 * "flagMulticast":true,
473 * "flagBroadcast":true,
474 * "lanDelayEnabled":true,
477 * "group":"226.10.10.10",
478 * "localMembership":"INCLUDE"
484 /* foreach interface */
485 json_object_object_foreach(json
, key
, val
)
488 /* Find all of the keys where the val is an object. In
490 * above the only one is 226.10.10.10
492 json_object_object_foreach(val
, if_field_key
,
495 type
= json_object_get_type(if_field_val
);
497 if (type
== json_type_object
) {
498 vty_out(vty
, "%-9s ", key
);
500 json_object_object_get_ex(
501 val
, "address", &json_tmp
);
502 vty_out(vty
, "%-15s ",
503 json_object_get_string(
506 json_object_object_get_ex(if_field_val
,
509 vty_out(vty
, "%-15s ",
510 json_object_get_string(
514 vty_out(vty
, "%-15s ", if_field_key
);
516 json_object_object_get_ex(
517 if_field_val
, "localMembership",
519 vty_out(vty
, "%-10s\n",
520 json_object_get_string(
527 json_object_free(json
);
530 static void pim_print_ifp_flags(struct vty
*vty
, struct interface
*ifp
,
533 vty_out(vty
, "Flags\n");
534 vty_out(vty
, "-----\n");
535 vty_out(vty
, "All Multicast : %s\n",
536 (ifp
->flags
& IFF_ALLMULTI
) ? "yes" : "no");
537 vty_out(vty
, "Broadcast : %s\n",
538 if_is_broadcast(ifp
) ? "yes" : "no");
539 vty_out(vty
, "Deleted : %s\n",
540 PIM_IF_IS_DELETED(ifp
) ? "yes" : "no");
541 vty_out(vty
, "Interface Index : %d\n", ifp
->ifindex
);
542 vty_out(vty
, "Multicast : %s\n",
543 if_is_multicast(ifp
) ? "yes" : "no");
544 vty_out(vty
, "Multicast Loop : %d\n", mloop
);
545 vty_out(vty
, "Promiscuous : %s\n",
546 (ifp
->flags
& IFF_PROMISC
) ? "yes" : "no");
551 static void igmp_show_interfaces(struct pim_instance
*pim
, struct vty
*vty
,
554 struct interface
*ifp
;
556 json_object
*json
= NULL
;
557 json_object
*json_row
= NULL
;
559 now
= pim_time_monotonic_sec();
562 json
= json_object_new_object();
565 "Interface State Address V Querier Query Timer Uptime\n");
567 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
568 struct pim_interface
*pim_ifp
;
569 struct listnode
*sock_node
;
570 struct igmp_sock
*igmp
;
577 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
580 char query_hhmmss
[10];
582 pim_time_uptime(uptime
, sizeof(uptime
),
583 now
- igmp
->sock_creation
);
584 pim_time_timer_to_hhmmss(query_hhmmss
,
585 sizeof(query_hhmmss
),
586 igmp
->t_igmp_query_timer
);
589 json_row
= json_object_new_object();
590 json_object_pim_ifp_add(json_row
, ifp
);
591 json_object_string_add(json_row
, "upTime",
593 json_object_int_add(json_row
, "version",
594 pim_ifp
->igmp_version
);
596 if (igmp
->t_igmp_query_timer
) {
597 json_object_boolean_true_add(json_row
,
599 json_object_string_add(json_row
,
604 json_object_object_add(json
, ifp
->name
,
607 if (igmp
->mtrace_only
) {
608 json_object_boolean_true_add(
609 json_row
, "mtraceOnly");
613 "%-9s %5s %15s %d %7s %11s %8s\n",
616 ? (igmp
->mtrace_only
? "mtrc"
619 inet_ntoa(igmp
->ifaddr
),
620 pim_ifp
->igmp_version
,
621 igmp
->t_igmp_query_timer
? "local"
623 query_hhmmss
, uptime
);
629 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
630 json
, JSON_C_TO_STRING_PRETTY
));
631 json_object_free(json
);
635 static void igmp_show_interfaces_single(struct pim_instance
*pim
,
636 struct vty
*vty
, const char *ifname
,
639 struct igmp_sock
*igmp
;
640 struct interface
*ifp
;
641 struct listnode
*sock_node
;
642 struct pim_interface
*pim_ifp
;
644 char query_hhmmss
[10];
645 char other_hhmmss
[10];
646 int found_ifname
= 0;
649 long gmi_msec
; /* Group Membership Interval */
652 long oqpi_msec
; /* Other Querier Present Interval */
656 json_object
*json
= NULL
;
657 json_object
*json_row
= NULL
;
660 json
= json_object_new_object();
662 now
= pim_time_monotonic_sec();
664 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
670 if (strcmp(ifname
, "detail") && strcmp(ifname
, ifp
->name
))
673 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
676 pim_time_uptime(uptime
, sizeof(uptime
),
677 now
- igmp
->sock_creation
);
678 pim_time_timer_to_hhmmss(query_hhmmss
,
679 sizeof(query_hhmmss
),
680 igmp
->t_igmp_query_timer
);
681 pim_time_timer_to_hhmmss(other_hhmmss
,
682 sizeof(other_hhmmss
),
683 igmp
->t_other_querier_timer
);
685 gmi_msec
= PIM_IGMP_GMI_MSEC(
686 igmp
->querier_robustness_variable
,
687 igmp
->querier_query_interval
,
688 pim_ifp
->igmp_query_max_response_time_dsec
);
691 pim_ifp
->igmp_default_query_interval
);
693 oqpi_msec
= PIM_IGMP_OQPI_MSEC(
694 igmp
->querier_robustness_variable
,
695 igmp
->querier_query_interval
,
696 pim_ifp
->igmp_query_max_response_time_dsec
);
698 lmqt_msec
= PIM_IGMP_LMQT_MSEC(
699 pim_ifp
->igmp_query_max_response_time_dsec
,
700 igmp
->querier_robustness_variable
);
704 igmp
->querier_robustness_variable
,
705 igmp
->querier_query_interval
,
706 pim_ifp
->igmp_query_max_response_time_dsec
)
709 qri_msec
= pim_ifp
->igmp_query_max_response_time_dsec
711 if (pim_ifp
->pim_sock_fd
>= 0)
712 mloop
= pim_socket_mcastloop_get(
713 pim_ifp
->pim_sock_fd
);
718 json_row
= json_object_new_object();
719 json_object_pim_ifp_add(json_row
, ifp
);
720 json_object_string_add(json_row
, "upTime",
722 json_object_string_add(json_row
, "querier",
723 igmp
->t_igmp_query_timer
726 json_object_int_add(json_row
, "queryStartCount",
727 igmp
->startup_query_count
);
728 json_object_string_add(json_row
,
731 json_object_string_add(json_row
,
734 json_object_int_add(json_row
, "version",
735 pim_ifp
->igmp_version
);
738 "timerGroupMembershipIntervalMsec",
740 json_object_int_add(json_row
,
741 "timerLastMemberQueryMsec",
745 "timerOlderHostPresentIntervalMsec",
749 "timerOtherQuerierPresentIntervalMsec",
752 json_row
, "timerQueryInterval",
753 igmp
->querier_query_interval
);
756 "timerQueryResponseIntervalMsec",
759 json_row
, "timerRobustnessVariable",
760 igmp
->querier_robustness_variable
);
761 json_object_int_add(json_row
,
762 "timerStartupQueryInterval",
765 json_object_object_add(json
, ifp
->name
,
768 if (igmp
->mtrace_only
) {
769 json_object_boolean_true_add(
770 json_row
, "mtraceOnly");
773 vty_out(vty
, "Interface : %s\n", ifp
->name
);
774 vty_out(vty
, "State : %s\n",
776 ? (igmp
->mtrace_only
? "mtrace"
779 vty_out(vty
, "Address : %s\n",
780 inet_ntoa(pim_ifp
->primary_address
));
781 vty_out(vty
, "Uptime : %s\n", uptime
);
782 vty_out(vty
, "Version : %d\n",
783 pim_ifp
->igmp_version
);
787 vty_out(vty
, "Querier\n");
788 vty_out(vty
, "-------\n");
789 vty_out(vty
, "Querier : %s\n",
790 igmp
->t_igmp_query_timer
? "local"
792 vty_out(vty
, "Start Count : %d\n",
793 igmp
->startup_query_count
);
794 vty_out(vty
, "Query Timer : %s\n",
796 vty_out(vty
, "Other Timer : %s\n",
801 vty_out(vty
, "Timers\n");
802 vty_out(vty
, "------\n");
804 "Group Membership Interval : %lis\n",
807 "Last Member Query Time : %lis\n",
810 "Older Host Present Interval : %lis\n",
813 "Other Querier Present Interval : %lis\n",
816 "Query Interval : %ds\n",
817 igmp
->querier_query_interval
);
819 "Query Response Interval : %lis\n",
822 "Robustness Variable : %d\n",
823 igmp
->querier_robustness_variable
);
825 "Startup Query Interval : %ds\n",
830 pim_print_ifp_flags(vty
, ifp
, mloop
);
836 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
837 json
, JSON_C_TO_STRING_PRETTY
));
838 json_object_free(json
);
841 vty_out(vty
, "%% No such interface\n");
845 static void igmp_show_interface_join(struct pim_instance
*pim
, struct vty
*vty
)
847 struct interface
*ifp
;
850 now
= pim_time_monotonic_sec();
853 "Interface Address Source Group Socket Uptime \n");
855 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
856 struct pim_interface
*pim_ifp
;
857 struct listnode
*join_node
;
858 struct igmp_join
*ij
;
859 struct in_addr pri_addr
;
860 char pri_addr_str
[INET_ADDRSTRLEN
];
867 if (!pim_ifp
->igmp_join_list
)
870 pri_addr
= pim_find_primary_addr(ifp
);
871 pim_inet4_dump("<pri?>", pri_addr
, pri_addr_str
,
872 sizeof(pri_addr_str
));
874 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_join_list
, join_node
,
876 char group_str
[INET_ADDRSTRLEN
];
877 char source_str
[INET_ADDRSTRLEN
];
880 pim_time_uptime(uptime
, sizeof(uptime
),
881 now
- ij
->sock_creation
);
882 pim_inet4_dump("<grp?>", ij
->group_addr
, group_str
,
884 pim_inet4_dump("<src?>", ij
->source_addr
, source_str
,
887 vty_out(vty
, "%-9s %-15s %-15s %-15s %6d %8s\n",
888 ifp
->name
, pri_addr_str
, source_str
, group_str
,
889 ij
->sock_fd
, uptime
);
890 } /* for (pim_ifp->igmp_join_list) */
895 static void pim_show_interfaces_single(struct pim_instance
*pim
,
896 struct vty
*vty
, const char *ifname
,
899 struct in_addr ifaddr
;
900 struct interface
*ifp
;
901 struct listnode
*neighnode
;
902 struct listnode
*upnode
;
903 struct pim_interface
*pim_ifp
;
904 struct pim_neighbor
*neigh
;
905 struct pim_upstream
*up
;
907 char dr_str
[INET_ADDRSTRLEN
];
910 char grp_str
[INET_ADDRSTRLEN
];
911 char hello_period
[10];
912 char hello_timer
[10];
913 char neigh_src_str
[INET_ADDRSTRLEN
];
914 char src_str
[INET_ADDRSTRLEN
];
915 char stat_uptime
[10];
918 int found_ifname
= 0;
920 json_object
*json
= NULL
;
921 json_object
*json_row
= NULL
;
922 json_object
*json_pim_neighbor
= NULL
;
923 json_object
*json_pim_neighbors
= NULL
;
924 json_object
*json_group
= NULL
;
925 json_object
*json_group_source
= NULL
;
926 json_object
*json_fhr_sources
= NULL
;
927 struct pim_secondary_addr
*sec_addr
;
928 struct listnode
*sec_node
;
930 now
= pim_time_monotonic_sec();
933 json
= json_object_new_object();
935 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
941 if (strcmp(ifname
, "detail") && strcmp(ifname
, ifp
->name
))
945 ifaddr
= pim_ifp
->primary_address
;
946 pim_inet4_dump("<dr?>", pim_ifp
->pim_dr_addr
, dr_str
,
948 pim_time_uptime_begin(dr_uptime
, sizeof(dr_uptime
), now
,
949 pim_ifp
->pim_dr_election_last
);
950 pim_time_timer_to_hhmmss(hello_timer
, sizeof(hello_timer
),
951 pim_ifp
->t_pim_hello_timer
);
952 pim_time_mmss(hello_period
, sizeof(hello_period
),
953 pim_ifp
->pim_hello_period
);
954 pim_time_uptime(stat_uptime
, sizeof(stat_uptime
),
955 now
- pim_ifp
->pim_ifstat_start
);
956 if (pim_ifp
->pim_sock_fd
>= 0)
957 mloop
= pim_socket_mcastloop_get(pim_ifp
->pim_sock_fd
);
962 char pbuf
[PREFIX2STR_BUFFER
];
963 json_row
= json_object_new_object();
964 json_object_pim_ifp_add(json_row
, ifp
);
966 if (pim_ifp
->update_source
.s_addr
!= INADDR_ANY
) {
967 json_object_string_add(
968 json_row
, "useSource",
969 inet_ntoa(pim_ifp
->update_source
));
971 if (pim_ifp
->sec_addr_list
) {
972 json_object
*sec_list
= NULL
;
974 sec_list
= json_object_new_array();
975 for (ALL_LIST_ELEMENTS_RO(
976 pim_ifp
->sec_addr_list
, sec_node
,
978 json_object_array_add(
980 json_object_new_string(
986 json_object_object_add(json_row
,
987 "secondaryAddressList",
992 if (pim_ifp
->pim_neighbor_list
->count
) {
993 json_pim_neighbors
= json_object_new_object();
995 for (ALL_LIST_ELEMENTS_RO(
996 pim_ifp
->pim_neighbor_list
,
999 json_object_new_object();
1000 pim_inet4_dump("<src?>",
1003 sizeof(neigh_src_str
));
1004 pim_time_uptime(uptime
, sizeof(uptime
),
1005 now
- neigh
->creation
);
1006 pim_time_timer_to_hhmmss(
1007 expire
, sizeof(expire
),
1008 neigh
->t_expire_timer
);
1010 json_object_string_add(
1011 json_pim_neighbor
, "address",
1013 json_object_string_add(
1014 json_pim_neighbor
, "upTime",
1016 json_object_string_add(
1017 json_pim_neighbor
, "holdtime",
1020 json_object_object_add(
1026 json_object_object_add(json_row
, "neighbors",
1027 json_pim_neighbors
);
1030 json_object_string_add(json_row
, "drAddress", dr_str
);
1031 json_object_int_add(json_row
, "drPriority",
1032 pim_ifp
->pim_dr_priority
);
1033 json_object_string_add(json_row
, "drUptime", dr_uptime
);
1034 json_object_int_add(json_row
, "drElections",
1035 pim_ifp
->pim_dr_election_count
);
1036 json_object_int_add(json_row
, "drChanges",
1037 pim_ifp
->pim_dr_election_changes
);
1040 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
,
1042 if (ifp
!= up
->rpf
.source_nexthop
.interface
)
1045 if (!(up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
))
1048 if (!json_fhr_sources
)
1050 json_object_new_object();
1052 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
,
1054 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
,
1056 pim_time_uptime(uptime
, sizeof(uptime
),
1057 now
- up
->state_transition
);
1060 * Does this group live in json_fhr_sources?
1063 json_object_object_get_ex(json_fhr_sources
,
1064 grp_str
, &json_group
);
1067 json_group
= json_object_new_object();
1068 json_object_object_add(json_fhr_sources
,
1073 json_group_source
= json_object_new_object();
1074 json_object_string_add(json_group_source
,
1076 json_object_string_add(json_group_source
,
1078 json_object_string_add(json_group_source
,
1080 json_object_object_add(json_group
, src_str
,
1084 if (json_fhr_sources
) {
1085 json_object_object_add(json_row
,
1090 json_object_int_add(json_row
, "helloPeriod",
1091 pim_ifp
->pim_hello_period
);
1092 json_object_string_add(json_row
, "helloTimer",
1094 json_object_string_add(json_row
, "helloStatStart",
1096 json_object_int_add(json_row
, "helloReceived",
1097 pim_ifp
->pim_ifstat_hello_recv
);
1098 json_object_int_add(json_row
, "helloReceivedFailed",
1099 pim_ifp
->pim_ifstat_hello_recvfail
);
1100 json_object_int_add(json_row
, "helloSend",
1101 pim_ifp
->pim_ifstat_hello_sent
);
1102 json_object_int_add(json_row
, "hellosendFailed",
1103 pim_ifp
->pim_ifstat_hello_sendfail
);
1104 json_object_int_add(json_row
, "helloGenerationId",
1105 pim_ifp
->pim_generation_id
);
1106 json_object_int_add(json_row
, "flagMulticastLoop",
1109 json_object_int_add(
1110 json_row
, "effectivePropagationDelay",
1111 pim_if_effective_propagation_delay_msec(ifp
));
1112 json_object_int_add(
1113 json_row
, "effectiveOverrideInterval",
1114 pim_if_effective_override_interval_msec(ifp
));
1115 json_object_int_add(
1116 json_row
, "joinPruneOverrideInterval",
1117 pim_if_jp_override_interval_msec(ifp
));
1119 json_object_int_add(
1120 json_row
, "propagationDelay",
1121 pim_ifp
->pim_propagation_delay_msec
);
1122 json_object_int_add(
1123 json_row
, "propagationDelayHighest",
1124 pim_ifp
->pim_neighbors_highest_propagation_delay_msec
);
1125 json_object_int_add(
1126 json_row
, "overrideInterval",
1127 pim_ifp
->pim_override_interval_msec
);
1128 json_object_int_add(
1129 json_row
, "overrideIntervalHighest",
1130 pim_ifp
->pim_neighbors_highest_override_interval_msec
);
1131 json_object_object_add(json
, ifp
->name
, json_row
);
1134 vty_out(vty
, "Interface : %s\n", ifp
->name
);
1135 vty_out(vty
, "State : %s\n",
1136 if_is_up(ifp
) ? "up" : "down");
1137 if (pim_ifp
->update_source
.s_addr
!= INADDR_ANY
) {
1138 vty_out(vty
, "Use Source : %s\n",
1139 inet_ntoa(pim_ifp
->update_source
));
1141 if (pim_ifp
->sec_addr_list
) {
1142 char pbuf
[PREFIX2STR_BUFFER
];
1143 vty_out(vty
, "Address : %s (primary)\n",
1145 for (ALL_LIST_ELEMENTS_RO(
1146 pim_ifp
->sec_addr_list
, sec_node
,
1148 vty_out(vty
, " %s\n",
1149 prefix2str(&sec_addr
->addr
,
1150 pbuf
, sizeof(pbuf
)));
1153 vty_out(vty
, "Address : %s\n",
1161 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
,
1162 neighnode
, neigh
)) {
1165 vty_out(vty
, "PIM Neighbors\n");
1166 vty_out(vty
, "-------------\n");
1170 pim_inet4_dump("<src?>", neigh
->source_addr
,
1172 sizeof(neigh_src_str
));
1173 pim_time_uptime(uptime
, sizeof(uptime
),
1174 now
- neigh
->creation
);
1175 pim_time_timer_to_hhmmss(expire
, sizeof(expire
),
1176 neigh
->t_expire_timer
);
1178 "%-15s : up for %s, holdtime expires in %s\n",
1179 neigh_src_str
, uptime
, expire
);
1182 if (!print_header
) {
1187 vty_out(vty
, "Designated Router\n");
1188 vty_out(vty
, "-----------------\n");
1189 vty_out(vty
, "Address : %s\n", dr_str
);
1190 vty_out(vty
, "Priority : %d\n",
1191 pim_ifp
->pim_dr_priority
);
1192 vty_out(vty
, "Uptime : %s\n", dr_uptime
);
1193 vty_out(vty
, "Elections : %d\n",
1194 pim_ifp
->pim_dr_election_count
);
1195 vty_out(vty
, "Changes : %d\n",
1196 pim_ifp
->pim_dr_election_changes
);
1202 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
,
1205 if (strcmp(ifp
->name
,
1206 up
->rpf
.source_nexthop
1211 if (!(up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
))
1216 "FHR - First Hop Router\n");
1218 "----------------------\n");
1222 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
,
1224 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
,
1226 pim_time_uptime(uptime
, sizeof(uptime
),
1227 now
- up
->state_transition
);
1229 "%s : %s is a source, uptime is %s\n",
1230 grp_str
, src_str
, uptime
);
1233 if (!print_header
) {
1238 vty_out(vty
, "Hellos\n");
1239 vty_out(vty
, "------\n");
1240 vty_out(vty
, "Period : %d\n",
1241 pim_ifp
->pim_hello_period
);
1242 vty_out(vty
, "Timer : %s\n", hello_timer
);
1243 vty_out(vty
, "StatStart : %s\n", stat_uptime
);
1244 vty_out(vty
, "Receive : %d\n",
1245 pim_ifp
->pim_ifstat_hello_recv
);
1246 vty_out(vty
, "Receive Failed : %d\n",
1247 pim_ifp
->pim_ifstat_hello_recvfail
);
1248 vty_out(vty
, "Send : %d\n",
1249 pim_ifp
->pim_ifstat_hello_sent
);
1250 vty_out(vty
, "Send Failed : %d\n",
1251 pim_ifp
->pim_ifstat_hello_sendfail
);
1252 vty_out(vty
, "Generation ID : %08x\n",
1253 pim_ifp
->pim_generation_id
);
1257 pim_print_ifp_flags(vty
, ifp
, mloop
);
1259 vty_out(vty
, "Join Prune Interval\n");
1260 vty_out(vty
, "-------------------\n");
1261 vty_out(vty
, "LAN Delay : %s\n",
1262 pim_if_lan_delay_enabled(ifp
) ? "yes" : "no");
1263 vty_out(vty
, "Effective Propagation Delay : %d msec\n",
1264 pim_if_effective_propagation_delay_msec(ifp
));
1265 vty_out(vty
, "Effective Override Interval : %d msec\n",
1266 pim_if_effective_override_interval_msec(ifp
));
1267 vty_out(vty
, "Join Prune Override Interval : %d msec\n",
1268 pim_if_jp_override_interval_msec(ifp
));
1272 vty_out(vty
, "LAN Prune Delay\n");
1273 vty_out(vty
, "---------------\n");
1274 vty_out(vty
, "Propagation Delay : %d msec\n",
1275 pim_ifp
->pim_propagation_delay_msec
);
1276 vty_out(vty
, "Propagation Delay (Highest) : %d msec\n",
1277 pim_ifp
->pim_neighbors_highest_propagation_delay_msec
);
1278 vty_out(vty
, "Override Interval : %d msec\n",
1279 pim_ifp
->pim_override_interval_msec
);
1280 vty_out(vty
, "Override Interval (Highest) : %d msec\n",
1281 pim_ifp
->pim_neighbors_highest_override_interval_msec
);
1288 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1289 json
, JSON_C_TO_STRING_PRETTY
));
1290 json_object_free(json
);
1293 vty_out(vty
, "%% No such interface\n");
1297 static void pim_show_interfaces(struct pim_instance
*pim
, struct vty
*vty
,
1300 struct interface
*ifp
;
1301 struct listnode
*upnode
;
1302 struct pim_interface
*pim_ifp
;
1303 struct pim_upstream
*up
;
1306 int pim_ifchannels
= 0;
1307 json_object
*json
= NULL
;
1308 json_object
*json_row
= NULL
;
1309 json_object
*json_tmp
;
1311 json
= json_object_new_object();
1313 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1314 pim_ifp
= ifp
->info
;
1319 pim_nbrs
= pim_ifp
->pim_neighbor_list
->count
;
1320 pim_ifchannels
= pim_if_ifchannel_count(pim_ifp
);
1323 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
, up
))
1324 if (ifp
== up
->rpf
.source_nexthop
.interface
)
1325 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
)
1328 json_row
= json_object_new_object();
1329 json_object_pim_ifp_add(json_row
, ifp
);
1330 json_object_int_add(json_row
, "pimNeighbors", pim_nbrs
);
1331 json_object_int_add(json_row
, "pimIfChannels", pim_ifchannels
);
1332 json_object_int_add(json_row
, "firstHopRouterCount", fhr
);
1333 json_object_string_add(json_row
, "pimDesignatedRouter",
1334 inet_ntoa(pim_ifp
->pim_dr_addr
));
1336 if (pim_ifp
->pim_dr_addr
.s_addr
1337 == pim_ifp
->primary_address
.s_addr
)
1338 json_object_boolean_true_add(
1339 json_row
, "pimDesignatedRouterLocal");
1341 json_object_object_add(json
, ifp
->name
, json_row
);
1345 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1346 json
, JSON_C_TO_STRING_PRETTY
));
1349 "Interface State Address PIM Nbrs PIM DR FHR IfChannels\n");
1351 json_object_object_foreach(json
, key
, val
)
1353 vty_out(vty
, "%-9s ", key
);
1355 json_object_object_get_ex(val
, "state", &json_tmp
);
1356 vty_out(vty
, "%5s ", json_object_get_string(json_tmp
));
1358 json_object_object_get_ex(val
, "address", &json_tmp
);
1359 vty_out(vty
, "%15s ",
1360 json_object_get_string(json_tmp
));
1362 json_object_object_get_ex(val
, "pimNeighbors",
1364 vty_out(vty
, "%8d ", json_object_get_int(json_tmp
));
1366 if (json_object_object_get_ex(
1367 val
, "pimDesignatedRouterLocal",
1369 vty_out(vty
, "%15s ", "local");
1371 json_object_object_get_ex(
1372 val
, "pimDesignatedRouter", &json_tmp
);
1373 vty_out(vty
, "%15s ",
1374 json_object_get_string(json_tmp
));
1377 json_object_object_get_ex(val
, "firstHopRouter",
1379 vty_out(vty
, "%3d ", json_object_get_int(json_tmp
));
1381 json_object_object_get_ex(val
, "pimIfChannels",
1383 vty_out(vty
, "%9d\n", json_object_get_int(json_tmp
));
1387 json_object_free(json
);
1390 static void pim_show_interface_traffic(struct pim_instance
*pim
,
1391 struct vty
*vty
, u_char uj
)
1393 struct interface
*ifp
= NULL
;
1394 struct pim_interface
*pim_ifp
= NULL
;
1395 json_object
*json
= NULL
;
1396 json_object
*json_row
= NULL
;
1399 json
= json_object_new_object();
1402 vty_out(vty
, "%-12s%-17s%-17s%-17s%-17s%-17s%-17s\n",
1403 "Interface", " HELLO", " JOIN", " PRUNE",
1404 " REGISTER", " REGISTER-STOP", " ASSERT");
1405 vty_out(vty
, "%-10s%-18s%-17s%-17s%-17s%-17s%-17s\n", "",
1406 " Rx/Tx", " Rx/Tx", " Rx/Tx", " Rx/Tx",
1407 " Rx/Tx", " Rx/Tx");
1409 "---------------------------------------------------------------------------------------------------------------\n");
1412 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1413 pim_ifp
= ifp
->info
;
1418 if (pim_ifp
->pim_sock_fd
< 0)
1421 json_row
= json_object_new_object();
1422 json_object_pim_ifp_add(json_row
, ifp
);
1423 json_object_int_add(json_row
, "helloRx",
1424 pim_ifp
->pim_ifstat_hello_recv
);
1425 json_object_int_add(json_row
, "helloTx",
1426 pim_ifp
->pim_ifstat_hello_sent
);
1427 json_object_int_add(json_row
, "joinRx",
1428 pim_ifp
->pim_ifstat_join_recv
);
1429 json_object_int_add(json_row
, "joinTx",
1430 pim_ifp
->pim_ifstat_join_send
);
1431 json_object_int_add(json_row
, "registerRx",
1432 pim_ifp
->pim_ifstat_reg_recv
);
1433 json_object_int_add(json_row
, "registerTx",
1434 pim_ifp
->pim_ifstat_reg_recv
);
1435 json_object_int_add(json_row
, "registerStopRx",
1436 pim_ifp
->pim_ifstat_reg_stop_recv
);
1437 json_object_int_add(json_row
, "registerStopTx",
1438 pim_ifp
->pim_ifstat_reg_stop_send
);
1439 json_object_int_add(json_row
, "assertRx",
1440 pim_ifp
->pim_ifstat_assert_recv
);
1441 json_object_int_add(json_row
, "assertTx",
1442 pim_ifp
->pim_ifstat_assert_send
);
1444 json_object_object_add(json
, ifp
->name
, json_row
);
1447 "%-10s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u \n",
1448 ifp
->name
, pim_ifp
->pim_ifstat_hello_recv
,
1449 pim_ifp
->pim_ifstat_hello_sent
,
1450 pim_ifp
->pim_ifstat_join_recv
,
1451 pim_ifp
->pim_ifstat_join_send
,
1452 pim_ifp
->pim_ifstat_prune_recv
,
1453 pim_ifp
->pim_ifstat_prune_send
,
1454 pim_ifp
->pim_ifstat_reg_recv
,
1455 pim_ifp
->pim_ifstat_reg_send
,
1456 pim_ifp
->pim_ifstat_reg_stop_recv
,
1457 pim_ifp
->pim_ifstat_reg_stop_send
,
1458 pim_ifp
->pim_ifstat_assert_recv
,
1459 pim_ifp
->pim_ifstat_assert_send
);
1463 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1464 json
, JSON_C_TO_STRING_PRETTY
));
1465 json_object_free(json
);
1469 static void pim_show_interface_traffic_single(struct pim_instance
*pim
,
1471 const char *ifname
, u_char uj
)
1473 struct interface
*ifp
= NULL
;
1474 struct pim_interface
*pim_ifp
= NULL
;
1475 json_object
*json
= NULL
;
1476 json_object
*json_row
= NULL
;
1477 uint8_t found_ifname
= 0;
1480 json
= json_object_new_object();
1483 vty_out(vty
, "%-12s%-17s%-17s%-17s%-17s%-17s%-17s\n",
1484 "Interface", " HELLO", " JOIN", " PRUNE",
1485 " REGISTER", " REGISTER-STOP", " ASSERT");
1486 vty_out(vty
, "%-10s%-18s%-17s%-17s%-17s%-17s%-17s\n", "",
1487 " Rx/Tx", " Rx/Tx", " Rx/Tx", " Rx/Tx",
1488 " Rx/Tx", " Rx/Tx");
1490 "---------------------------------------------------------------------------------------------------------------\n");
1493 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1494 if (strcmp(ifname
, ifp
->name
))
1497 pim_ifp
= ifp
->info
;
1502 if (pim_ifp
->pim_sock_fd
< 0)
1507 json_row
= json_object_new_object();
1508 json_object_pim_ifp_add(json_row
, ifp
);
1509 json_object_int_add(json_row
, "helloRx",
1510 pim_ifp
->pim_ifstat_hello_recv
);
1511 json_object_int_add(json_row
, "helloTx",
1512 pim_ifp
->pim_ifstat_hello_sent
);
1513 json_object_int_add(json_row
, "joinRx",
1514 pim_ifp
->pim_ifstat_join_recv
);
1515 json_object_int_add(json_row
, "joinTx",
1516 pim_ifp
->pim_ifstat_join_send
);
1517 json_object_int_add(json_row
, "registerRx",
1518 pim_ifp
->pim_ifstat_reg_recv
);
1519 json_object_int_add(json_row
, "registerTx",
1520 pim_ifp
->pim_ifstat_reg_recv
);
1521 json_object_int_add(json_row
, "registerStopRx",
1522 pim_ifp
->pim_ifstat_reg_stop_recv
);
1523 json_object_int_add(json_row
, "registerStopTx",
1524 pim_ifp
->pim_ifstat_reg_stop_send
);
1525 json_object_int_add(json_row
, "assertRx",
1526 pim_ifp
->pim_ifstat_assert_recv
);
1527 json_object_int_add(json_row
, "assertTx",
1528 pim_ifp
->pim_ifstat_assert_send
);
1530 json_object_object_add(json
, ifp
->name
, json_row
);
1533 "%-10s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u \n",
1534 ifp
->name
, pim_ifp
->pim_ifstat_hello_recv
,
1535 pim_ifp
->pim_ifstat_hello_sent
,
1536 pim_ifp
->pim_ifstat_join_recv
,
1537 pim_ifp
->pim_ifstat_join_send
,
1538 pim_ifp
->pim_ifstat_prune_recv
,
1539 pim_ifp
->pim_ifstat_prune_send
,
1540 pim_ifp
->pim_ifstat_reg_recv
,
1541 pim_ifp
->pim_ifstat_reg_send
,
1542 pim_ifp
->pim_ifstat_reg_stop_recv
,
1543 pim_ifp
->pim_ifstat_reg_stop_send
,
1544 pim_ifp
->pim_ifstat_assert_recv
,
1545 pim_ifp
->pim_ifstat_assert_send
);
1549 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1550 json
, JSON_C_TO_STRING_PRETTY
));
1551 json_object_free(json
);
1554 vty_out(vty
, "%% No such interface\n");
1558 static void pim_show_join_helper(struct vty
*vty
, struct pim_interface
*pim_ifp
,
1559 struct pim_ifchannel
*ch
, json_object
*json
,
1560 time_t now
, u_char uj
)
1562 char ch_src_str
[INET_ADDRSTRLEN
];
1563 char ch_grp_str
[INET_ADDRSTRLEN
];
1564 json_object
*json_iface
= NULL
;
1565 json_object
*json_row
= NULL
;
1566 json_object
*json_grp
= NULL
;
1567 struct in_addr ifaddr
;
1572 ifaddr
= pim_ifp
->primary_address
;
1574 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
1575 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
1577 pim_time_uptime_begin(uptime
, sizeof(uptime
), now
, ch
->ifjoin_creation
);
1578 pim_time_timer_to_mmss(expire
, sizeof(expire
),
1579 ch
->t_ifjoin_expiry_timer
);
1580 pim_time_timer_to_mmss(prune
, sizeof(prune
),
1581 ch
->t_ifjoin_prune_pending_timer
);
1584 json_object_object_get_ex(json
, ch
->interface
->name
,
1588 json_iface
= json_object_new_object();
1589 json_object_pim_ifp_add(json_iface
, ch
->interface
);
1590 json_object_object_add(json
, ch
->interface
->name
,
1594 json_row
= json_object_new_object();
1595 json_object_string_add(json_row
, "source", ch_src_str
);
1596 json_object_string_add(json_row
, "group", ch_grp_str
);
1597 json_object_string_add(json_row
, "upTime", uptime
);
1598 json_object_string_add(json_row
, "expire", expire
);
1599 json_object_string_add(json_row
, "prune", prune
);
1600 json_object_string_add(
1601 json_row
, "channelJoinName",
1602 pim_ifchannel_ifjoin_name(ch
->ifjoin_state
, ch
->flags
));
1603 if (PIM_IF_FLAG_TEST_S_G_RPT(ch
->flags
))
1604 json_object_int_add(json_row
, "SGRpt", 1);
1606 json_object_object_get_ex(json_iface
, ch_grp_str
, &json_grp
);
1608 json_grp
= json_object_new_object();
1609 json_object_object_add(json_grp
, ch_src_str
, json_row
);
1610 json_object_object_add(json_iface
, ch_grp_str
,
1613 json_object_object_add(json_grp
, ch_src_str
, json_row
);
1615 vty_out(vty
, "%-9s %-15s %-15s %-15s %-10s %8s %-6s %5s\n",
1616 ch
->interface
->name
, inet_ntoa(ifaddr
), ch_src_str
,
1618 pim_ifchannel_ifjoin_name(ch
->ifjoin_state
, ch
->flags
),
1619 uptime
, expire
, prune
);
1623 static void pim_show_join(struct pim_instance
*pim
, struct vty
*vty
, u_char uj
)
1625 struct pim_interface
*pim_ifp
;
1626 struct pim_ifchannel
*ch
;
1627 struct interface
*ifp
;
1629 json_object
*json
= NULL
;
1631 now
= pim_time_monotonic_sec();
1634 json
= json_object_new_object();
1637 "Interface Address Source Group State Uptime Expire Prune\n");
1639 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1640 pim_ifp
= ifp
->info
;
1644 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
1645 pim_show_join_helper(vty
, pim_ifp
, ch
, json
, now
, uj
);
1646 } /* scan interface channels */
1650 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1651 json
, JSON_C_TO_STRING_PRETTY
));
1652 json_object_free(json
);
1656 static void pim_show_neighbors_single(struct pim_instance
*pim
, struct vty
*vty
,
1657 const char *neighbor
, u_char uj
)
1659 struct listnode
*neighnode
;
1660 struct interface
*ifp
;
1661 struct pim_interface
*pim_ifp
;
1662 struct pim_neighbor
*neigh
;
1664 int found_neighbor
= 0;
1665 int option_address_list
;
1666 int option_dr_priority
;
1667 int option_generation_id
;
1668 int option_holdtime
;
1669 int option_lan_prune_delay
;
1673 char neigh_src_str
[INET_ADDRSTRLEN
];
1675 json_object
*json
= NULL
;
1676 json_object
*json_ifp
= NULL
;
1677 json_object
*json_row
= NULL
;
1679 now
= pim_time_monotonic_sec();
1682 json
= json_object_new_object();
1684 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1685 pim_ifp
= ifp
->info
;
1690 if (pim_ifp
->pim_sock_fd
< 0)
1693 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
1695 pim_inet4_dump("<src?>", neigh
->source_addr
,
1696 neigh_src_str
, sizeof(neigh_src_str
));
1699 * The user can specify either the interface name or the
1701 * If this pim_ifp matches neither then skip.
1703 if (strcmp(neighbor
, "detail")
1704 && strcmp(neighbor
, ifp
->name
)
1705 && strcmp(neighbor
, neigh_src_str
))
1709 pim_time_uptime(uptime
, sizeof(uptime
),
1710 now
- neigh
->creation
);
1711 pim_time_timer_to_hhmmss(expire
, sizeof(expire
),
1712 neigh
->t_expire_timer
);
1714 option_address_list
= 0;
1715 option_dr_priority
= 0;
1716 option_generation_id
= 0;
1717 option_holdtime
= 0;
1718 option_lan_prune_delay
= 0;
1721 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1722 PIM_OPTION_MASK_ADDRESS_LIST
))
1723 option_address_list
= 1;
1725 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1726 PIM_OPTION_MASK_DR_PRIORITY
))
1727 option_dr_priority
= 1;
1729 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1730 PIM_OPTION_MASK_GENERATION_ID
))
1731 option_generation_id
= 1;
1733 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1734 PIM_OPTION_MASK_HOLDTIME
))
1735 option_holdtime
= 1;
1737 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1738 PIM_OPTION_MASK_LAN_PRUNE_DELAY
))
1739 option_lan_prune_delay
= 1;
1741 if (PIM_OPTION_IS_SET(
1742 neigh
->hello_options
,
1743 PIM_OPTION_MASK_CAN_DISABLE_JOIN_SUPPRESSION
))
1748 /* Does this ifp live in json? If not create
1750 json_object_object_get_ex(json
, ifp
->name
,
1754 json_ifp
= json_object_new_object();
1755 json_object_pim_ifp_add(json_ifp
, ifp
);
1756 json_object_object_add(json
, ifp
->name
,
1760 json_row
= json_object_new_object();
1761 json_object_string_add(json_row
, "interface",
1763 json_object_string_add(json_row
, "address",
1765 json_object_string_add(json_row
, "upTime",
1767 json_object_string_add(json_row
, "holdtime",
1769 json_object_int_add(json_row
, "drPriority",
1770 neigh
->dr_priority
);
1771 json_object_int_add(json_row
, "generationId",
1772 neigh
->generation_id
);
1774 if (option_address_list
)
1775 json_object_boolean_true_add(
1777 "helloOptionAddressList");
1779 if (option_dr_priority
)
1780 json_object_boolean_true_add(
1782 "helloOptionDrPriority");
1784 if (option_generation_id
)
1785 json_object_boolean_true_add(
1787 "helloOptionGenerationId");
1789 if (option_holdtime
)
1790 json_object_boolean_true_add(
1792 "helloOptionHoldtime");
1794 if (option_lan_prune_delay
)
1795 json_object_boolean_true_add(
1797 "helloOptionLanPruneDelay");
1800 json_object_boolean_true_add(
1801 json_row
, "helloOptionTBit");
1803 json_object_object_add(json_ifp
, neigh_src_str
,
1807 vty_out(vty
, "Interface : %s\n", ifp
->name
);
1808 vty_out(vty
, "Neighbor : %s\n", neigh_src_str
);
1816 " DR Priority : %d\n",
1817 neigh
->dr_priority
);
1819 " Generation ID : %08x\n",
1820 neigh
->generation_id
);
1822 " Override Interval (msec) : %d\n",
1823 neigh
->override_interval_msec
);
1825 " Propagation Delay (msec) : %d\n",
1826 neigh
->propagation_delay_msec
);
1828 " Hello Option - Address List : %s\n",
1829 option_address_list
? "yes" : "no");
1831 " Hello Option - DR Priority : %s\n",
1832 option_dr_priority
? "yes" : "no");
1834 " Hello Option - Generation ID : %s\n",
1835 option_generation_id
? "yes" : "no");
1837 " Hello Option - Holdtime : %s\n",
1838 option_holdtime
? "yes" : "no");
1840 " Hello Option - LAN Prune Delay : %s\n",
1841 option_lan_prune_delay
? "yes" : "no");
1843 " Hello Option - T-bit : %s\n",
1844 option_t_bit
? "yes" : "no");
1845 pim_bfd_show_info(vty
, neigh
->bfd_info
,
1853 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1854 json
, JSON_C_TO_STRING_PRETTY
));
1855 json_object_free(json
);
1858 if (!found_neighbor
)
1860 "%% No such interface or neighbor\n");
1865 static void pim_show_state(struct pim_instance
*pim
, struct vty
*vty
,
1866 const char *src_or_group
, const char *group
,
1869 struct channel_oil
*c_oil
;
1870 struct listnode
*node
;
1871 json_object
*json
= NULL
;
1872 json_object
*json_group
= NULL
;
1873 json_object
*json_ifp_in
= NULL
;
1874 json_object
*json_ifp_out
= NULL
;
1875 json_object
*json_source
= NULL
;
1878 now
= pim_time_monotonic_sec();
1881 json
= json_object_new_object();
1884 "Codes: J -> Pim Join, I -> IGMP Report, S -> Source, * -> Inherited from (*,G)");
1886 "\nInstalled Source Group IIF OIL\n");
1889 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
1890 char grp_str
[INET_ADDRSTRLEN
];
1891 char src_str
[INET_ADDRSTRLEN
];
1892 char in_ifname
[INTERFACE_NAMSIZ
+ 1];
1893 char out_ifname
[INTERFACE_NAMSIZ
+ 1];
1895 struct interface
*ifp_in
;
1898 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, grp_str
,
1900 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, src_str
,
1902 ifp_in
= pim_if_find_by_vif_index(pim
, c_oil
->oil
.mfcc_parent
);
1905 strcpy(in_ifname
, ifp_in
->name
);
1907 strcpy(in_ifname
, "<iif?>");
1910 if (strcmp(src_or_group
, src_str
)
1911 && strcmp(src_or_group
, grp_str
))
1914 if (group
&& strcmp(group
, grp_str
))
1920 /* Find the group, create it if it doesn't exist */
1921 json_object_object_get_ex(json
, grp_str
, &json_group
);
1924 json_group
= json_object_new_object();
1925 json_object_object_add(json
, grp_str
,
1929 /* Find the source nested under the group, create it if
1930 * it doesn't exist */
1931 json_object_object_get_ex(json_group
, src_str
,
1935 json_source
= json_object_new_object();
1936 json_object_object_add(json_group
, src_str
,
1940 /* Find the inbound interface nested under the source,
1941 * create it if it doesn't exist */
1942 json_object_object_get_ex(json_source
, in_ifname
,
1946 json_ifp_in
= json_object_new_object();
1947 json_object_object_add(json_source
, in_ifname
,
1949 json_object_int_add(json_source
, "Installed",
1951 json_object_int_add(json_source
, "RefCount",
1952 c_oil
->oil_ref_count
);
1953 json_object_int_add(json_source
, "OilListSize",
1955 json_object_int_add(
1956 json_source
, "OilRescan",
1957 c_oil
->oil_inherited_rescan
);
1958 json_object_int_add(json_source
, "LastUsed",
1959 c_oil
->cc
.lastused
);
1960 json_object_int_add(json_source
, "PacketCount",
1962 json_object_int_add(json_source
, "ByteCount",
1964 json_object_int_add(json_source
,
1966 c_oil
->cc
.wrong_if
);
1969 vty_out(vty
, "%-9d %-15s %-15s %-7s ",
1970 c_oil
->installed
, src_str
, grp_str
,
1974 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
1976 struct interface
*ifp_out
;
1977 char oif_uptime
[10];
1980 ttl
= c_oil
->oil
.mfcc_ttls
[oif_vif_index
];
1984 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
1986 oif_uptime
, sizeof(oif_uptime
),
1987 now
- c_oil
->oif_creation
[oif_vif_index
]);
1990 strcpy(out_ifname
, ifp_out
->name
);
1992 strcpy(out_ifname
, "<oif?>");
1995 json_ifp_out
= json_object_new_object();
1996 json_object_string_add(json_ifp_out
, "source",
1998 json_object_string_add(json_ifp_out
, "group",
2000 json_object_string_add(json_ifp_out
,
2003 json_object_string_add(json_ifp_out
,
2004 "outboundInterface",
2006 json_object_int_add(json_ifp_out
, "installed",
2009 json_object_object_add(json_ifp_in
, out_ifname
,
2014 vty_out(vty
, "%s(%c%c%c%c)", out_ifname
,
2015 (c_oil
->oif_flags
[oif_vif_index
]
2016 & PIM_OIF_FLAG_PROTO_IGMP
)
2019 (c_oil
->oif_flags
[oif_vif_index
]
2020 & PIM_OIF_FLAG_PROTO_PIM
)
2023 (c_oil
->oif_flags
[oif_vif_index
]
2024 & PIM_OIF_FLAG_PROTO_SOURCE
)
2027 (c_oil
->oif_flags
[oif_vif_index
]
2028 & PIM_OIF_FLAG_PROTO_STAR
)
2032 vty_out(vty
, ", %s(%c%c%c%c)",
2034 (c_oil
->oif_flags
[oif_vif_index
]
2035 & PIM_OIF_FLAG_PROTO_IGMP
)
2038 (c_oil
->oif_flags
[oif_vif_index
]
2039 & PIM_OIF_FLAG_PROTO_PIM
)
2042 (c_oil
->oif_flags
[oif_vif_index
]
2043 & PIM_OIF_FLAG_PROTO_SOURCE
)
2046 (c_oil
->oif_flags
[oif_vif_index
]
2047 & PIM_OIF_FLAG_PROTO_STAR
)
2059 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2060 json
, JSON_C_TO_STRING_PRETTY
));
2061 json_object_free(json
);
2067 static void pim_show_neighbors(struct pim_instance
*pim
, struct vty
*vty
,
2070 struct listnode
*neighnode
;
2071 struct interface
*ifp
;
2072 struct pim_interface
*pim_ifp
;
2073 struct pim_neighbor
*neigh
;
2077 char neigh_src_str
[INET_ADDRSTRLEN
];
2078 json_object
*json
= NULL
;
2079 json_object
*json_ifp_rows
= NULL
;
2080 json_object
*json_row
= NULL
;
2082 now
= pim_time_monotonic_sec();
2085 json
= json_object_new_object();
2088 "Interface Neighbor Uptime Holdtime DR Pri\n");
2091 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2092 pim_ifp
= ifp
->info
;
2097 if (pim_ifp
->pim_sock_fd
< 0)
2101 json_ifp_rows
= json_object_new_object();
2103 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
2105 pim_inet4_dump("<src?>", neigh
->source_addr
,
2106 neigh_src_str
, sizeof(neigh_src_str
));
2107 pim_time_uptime(uptime
, sizeof(uptime
),
2108 now
- neigh
->creation
);
2109 pim_time_timer_to_hhmmss(expire
, sizeof(expire
),
2110 neigh
->t_expire_timer
);
2113 json_row
= json_object_new_object();
2114 json_object_string_add(json_row
, "interface",
2116 json_object_string_add(json_row
, "neighbor",
2118 json_object_string_add(json_row
, "upTime",
2120 json_object_string_add(json_row
, "holdTime",
2122 json_object_int_add(json_row
, "holdTimeMax",
2124 json_object_int_add(json_row
, "drPriority",
2125 neigh
->dr_priority
);
2126 json_object_object_add(json_ifp_rows
,
2127 neigh_src_str
, json_row
);
2130 vty_out(vty
, "%-9s %15s %8s %8s %6d\n",
2131 ifp
->name
, neigh_src_str
, uptime
,
2132 expire
, neigh
->dr_priority
);
2137 json_object_object_add(json
, ifp
->name
, json_ifp_rows
);
2138 json_ifp_rows
= NULL
;
2143 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2144 json
, JSON_C_TO_STRING_PRETTY
));
2145 json_object_free(json
);
2149 static void pim_show_neighbors_secondary(struct pim_instance
*pim
,
2152 struct interface
*ifp
;
2155 "Interface Address Neighbor Secondary \n");
2157 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2158 struct pim_interface
*pim_ifp
;
2159 struct in_addr ifaddr
;
2160 struct listnode
*neighnode
;
2161 struct pim_neighbor
*neigh
;
2163 pim_ifp
= ifp
->info
;
2168 if (pim_ifp
->pim_sock_fd
< 0)
2171 ifaddr
= pim_ifp
->primary_address
;
2173 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
2175 char neigh_src_str
[INET_ADDRSTRLEN
];
2176 struct listnode
*prefix_node
;
2179 if (!neigh
->prefix_list
)
2182 pim_inet4_dump("<src?>", neigh
->source_addr
,
2183 neigh_src_str
, sizeof(neigh_src_str
));
2185 for (ALL_LIST_ELEMENTS_RO(neigh
->prefix_list
,
2187 char neigh_sec_str
[PREFIX2STR_BUFFER
];
2189 prefix2str(p
, neigh_sec_str
,
2190 sizeof(neigh_sec_str
));
2192 vty_out(vty
, "%-9s %-15s %-15s %-15s\n",
2193 ifp
->name
, inet_ntoa(ifaddr
),
2194 neigh_src_str
, neigh_sec_str
);
2200 static void json_object_pim_upstream_add(json_object
*json
,
2201 struct pim_upstream
*up
)
2203 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED
)
2204 json_object_boolean_true_add(json
, "drJoinDesired");
2206 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED_UPDATED
)
2207 json_object_boolean_true_add(json
, "drJoinDesiredUpdated");
2209 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
)
2210 json_object_boolean_true_add(json
, "firstHopRouter");
2212 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_IGMP
)
2213 json_object_boolean_true_add(json
, "sourceIgmp");
2215 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_PIM
)
2216 json_object_boolean_true_add(json
, "sourcePim");
2218 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_STREAM
)
2219 json_object_boolean_true_add(json
, "sourceStream");
2221 /* XXX: need to print ths flag in the plain text display as well */
2222 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_MSDP
)
2223 json_object_boolean_true_add(json
, "sourceMsdp");
2227 pim_upstream_state2brief_str(enum pim_upstream_state join_state
,
2230 switch (join_state
) {
2231 case PIM_UPSTREAM_NOTJOINED
:
2232 strcpy(state_str
, "NotJ");
2234 case PIM_UPSTREAM_JOINED
:
2235 strcpy(state_str
, "J");
2238 strcpy(state_str
, "Unk");
2243 static const char *pim_reg_state2brief_str(enum pim_reg_state reg_state
,
2246 switch (reg_state
) {
2247 case PIM_REG_NOINFO
:
2248 strcpy(state_str
, "RegNI");
2251 strcpy(state_str
, "RegJ");
2253 case PIM_REG_JOIN_PENDING
:
2255 strcpy(state_str
, "RegP");
2258 strcpy(state_str
, "Unk");
2263 static void pim_show_upstream(struct pim_instance
*pim
, struct vty
*vty
,
2266 struct listnode
*upnode
;
2267 struct pim_upstream
*up
;
2269 json_object
*json
= NULL
;
2270 json_object
*json_group
= NULL
;
2271 json_object
*json_row
= NULL
;
2273 now
= pim_time_monotonic_sec();
2276 json
= json_object_new_object();
2279 "Iif Source Group State Uptime JoinTimer RSTimer KATimer RefCnt\n");
2281 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
, up
)) {
2282 char src_str
[INET_ADDRSTRLEN
];
2283 char grp_str
[INET_ADDRSTRLEN
];
2285 char join_timer
[10];
2288 char msdp_reg_timer
[10];
2289 char state_str
[PIM_REG_STATE_STR_LEN
];
2291 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2292 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2293 pim_time_uptime(uptime
, sizeof(uptime
),
2294 now
- up
->state_transition
);
2295 pim_time_timer_to_hhmmss(join_timer
, sizeof(join_timer
),
2299 * If we have a J/P timer for the neighbor display that
2301 if (!up
->t_join_timer
) {
2302 struct pim_neighbor
*nbr
;
2304 nbr
= pim_neighbor_find(
2305 up
->rpf
.source_nexthop
.interface
,
2306 up
->rpf
.rpf_addr
.u
.prefix4
);
2308 pim_time_timer_to_hhmmss(join_timer
,
2313 pim_time_timer_to_hhmmss(rs_timer
, sizeof(rs_timer
),
2315 pim_time_timer_to_hhmmss(ka_timer
, sizeof(ka_timer
),
2317 pim_time_timer_to_hhmmss(msdp_reg_timer
, sizeof(msdp_reg_timer
),
2318 up
->t_msdp_reg_timer
);
2320 pim_upstream_state2brief_str(up
->join_state
, state_str
);
2321 if (up
->reg_state
!= PIM_REG_NOINFO
) {
2322 char tmp_str
[PIM_REG_STATE_STR_LEN
];
2324 sprintf(state_str
+ strlen(state_str
), ",%s",
2325 pim_reg_state2brief_str(up
->reg_state
,
2330 json_object_object_get_ex(json
, grp_str
, &json_group
);
2333 json_group
= json_object_new_object();
2334 json_object_object_add(json
, grp_str
,
2338 json_row
= json_object_new_object();
2339 json_object_pim_upstream_add(json_row
, up
);
2340 json_object_string_add(
2341 json_row
, "inboundInterface",
2342 up
->rpf
.source_nexthop
.interface
->name
);
2345 * The RPF address we use is slightly different
2346 * based upon what we are looking up.
2347 * If we have a S, list that unless
2348 * we are the FHR, else we just put
2349 * the RP as the rpfAddress
2351 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
2352 || up
->sg
.src
.s_addr
== INADDR_ANY
) {
2353 char rpf
[PREFIX_STRLEN
];
2354 struct pim_rpf
*rpg
;
2356 rpg
= RP(pim
, up
->sg
.grp
);
2357 pim_inet4_dump("<rpf?>",
2358 rpg
->rpf_addr
.u
.prefix4
, rpf
,
2360 json_object_string_add(json_row
, "rpfAddress",
2363 json_object_string_add(json_row
, "rpfAddress",
2367 json_object_string_add(json_row
, "source", src_str
);
2368 json_object_string_add(json_row
, "group", grp_str
);
2369 json_object_string_add(json_row
, "state", state_str
);
2370 json_object_string_add(
2371 json_row
, "joinState",
2372 pim_upstream_state2str(up
->join_state
));
2373 json_object_string_add(
2374 json_row
, "regState",
2375 pim_reg_state2str(up
->reg_state
, state_str
));
2376 json_object_string_add(json_row
, "upTime", uptime
);
2377 json_object_string_add(json_row
, "joinTimer",
2379 json_object_string_add(json_row
, "resetTimer",
2381 json_object_string_add(json_row
, "keepaliveTimer",
2383 json_object_string_add(json_row
, "msdpRegTimer",
2385 json_object_int_add(json_row
, "refCount",
2387 json_object_int_add(json_row
, "sptBit", up
->sptbit
);
2388 json_object_object_add(json_group
, src_str
, json_row
);
2391 "%-10s%-15s %-15s %-11s %-8s %-9s %-9s %-9s %6d\n",
2392 up
->rpf
.source_nexthop
.interface
->name
, src_str
,
2393 grp_str
, state_str
, uptime
, join_timer
,
2394 rs_timer
, ka_timer
, up
->ref_count
);
2399 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2400 json
, JSON_C_TO_STRING_PRETTY
));
2401 json_object_free(json
);
2405 static void pim_show_join_desired_helper(struct pim_instance
*pim
,
2407 struct pim_interface
*pim_ifp
,
2408 struct pim_ifchannel
*ch
,
2409 json_object
*json
, u_char uj
)
2411 struct pim_upstream
*up
= ch
->upstream
;
2412 json_object
*json_group
= NULL
;
2413 char src_str
[INET_ADDRSTRLEN
];
2414 char grp_str
[INET_ADDRSTRLEN
];
2415 json_object
*json_row
= NULL
;
2417 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2418 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2421 json_object_object_get_ex(json
, grp_str
, &json_group
);
2424 json_group
= json_object_new_object();
2425 json_object_object_add(json
, grp_str
, json_group
);
2428 json_row
= json_object_new_object();
2429 json_object_pim_upstream_add(json_row
, up
);
2430 json_object_string_add(json_row
, "interface",
2431 ch
->interface
->name
);
2432 json_object_string_add(json_row
, "source", src_str
);
2433 json_object_string_add(json_row
, "group", grp_str
);
2435 if (pim_macro_ch_lost_assert(ch
))
2436 json_object_boolean_true_add(json_row
, "lostAssert");
2438 if (pim_macro_chisin_joins(ch
))
2439 json_object_boolean_true_add(json_row
, "joins");
2441 if (pim_macro_chisin_pim_include(ch
))
2442 json_object_boolean_true_add(json_row
, "pimInclude");
2444 if (pim_upstream_evaluate_join_desired(pim
, up
))
2445 json_object_boolean_true_add(json_row
,
2446 "evaluateJoinDesired");
2448 json_object_object_add(json_group
, src_str
, json_row
);
2451 vty_out(vty
, "%-9s %-15s %-15s %-10s %-5s %-10s %-11s %-6s\n",
2452 ch
->interface
->name
, src_str
, grp_str
,
2453 pim_macro_ch_lost_assert(ch
) ? "yes" : "no",
2454 pim_macro_chisin_joins(ch
) ? "yes" : "no",
2455 pim_macro_chisin_pim_include(ch
) ? "yes" : "no",
2456 PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED(up
->flags
)
2459 pim_upstream_evaluate_join_desired(pim
, up
) ? "yes"
2464 static void pim_show_join_desired(struct pim_instance
*pim
, struct vty
*vty
,
2467 struct pim_interface
*pim_ifp
;
2468 struct pim_ifchannel
*ch
;
2469 struct interface
*ifp
;
2471 json_object
*json
= NULL
;
2474 json
= json_object_new_object();
2477 "Interface Source Group LostAssert Joins PimInclude JoinDesired EvalJD\n");
2479 /* scan per-interface (S,G) state */
2480 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2481 pim_ifp
= ifp
->info
;
2486 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
2487 /* scan all interfaces */
2488 pim_show_join_desired_helper(pim
, vty
, pim_ifp
, ch
,
2494 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2495 json
, JSON_C_TO_STRING_PRETTY
));
2496 json_object_free(json
);
2500 static void pim_show_upstream_rpf(struct pim_instance
*pim
, struct vty
*vty
,
2503 struct listnode
*upnode
;
2504 struct pim_upstream
*up
;
2505 json_object
*json
= NULL
;
2506 json_object
*json_group
= NULL
;
2507 json_object
*json_row
= NULL
;
2510 json
= json_object_new_object();
2513 "Source Group RpfIface RibNextHop RpfAddress \n");
2515 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, upnode
, up
)) {
2516 char src_str
[INET_ADDRSTRLEN
];
2517 char grp_str
[INET_ADDRSTRLEN
];
2518 char rpf_nexthop_str
[PREFIX_STRLEN
];
2519 char rpf_addr_str
[PREFIX_STRLEN
];
2520 struct pim_rpf
*rpf
;
2521 const char *rpf_ifname
;
2525 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2526 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2527 pim_addr_dump("<nexthop?>",
2528 &rpf
->source_nexthop
.mrib_nexthop_addr
,
2529 rpf_nexthop_str
, sizeof(rpf_nexthop_str
));
2530 pim_addr_dump("<rpf?>", &rpf
->rpf_addr
, rpf_addr_str
,
2531 sizeof(rpf_addr_str
));
2533 rpf_ifname
= rpf
->source_nexthop
.interface
? rpf
->source_nexthop
.interface
->name
: "<ifname?>";
2536 json_object_object_get_ex(json
, grp_str
, &json_group
);
2539 json_group
= json_object_new_object();
2540 json_object_object_add(json
, grp_str
,
2544 json_row
= json_object_new_object();
2545 json_object_pim_upstream_add(json_row
, up
);
2546 json_object_string_add(json_row
, "source", src_str
);
2547 json_object_string_add(json_row
, "group", grp_str
);
2548 json_object_string_add(json_row
, "rpfInterface",
2550 json_object_string_add(json_row
, "ribNexthop",
2552 json_object_string_add(json_row
, "rpfAddress",
2554 json_object_object_add(json_group
, src_str
, json_row
);
2556 vty_out(vty
, "%-15s %-15s %-8s %-15s %-15s\n", src_str
,
2557 grp_str
, rpf_ifname
, rpf_nexthop_str
,
2563 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2564 json
, JSON_C_TO_STRING_PRETTY
));
2565 json_object_free(json
);
2569 static void show_rpf_refresh_stats(struct vty
*vty
, time_t now
,
2572 char refresh_uptime
[10];
2574 pim_time_uptime_begin(refresh_uptime
, sizeof(refresh_uptime
), now
,
2575 qpim_rpf_cache_refresh_last
);
2578 json_object_int_add(json
, "rpfCacheRefreshDelayMsecs",
2579 qpim_rpf_cache_refresh_delay_msec
);
2580 json_object_int_add(
2581 json
, "rpfCacheRefreshTimer",
2582 pim_time_timer_remain_msec(qpim_rpf_cache_refresher
));
2583 json_object_int_add(json
, "rpfCacheRefreshRequests",
2584 qpim_rpf_cache_refresh_requests
);
2585 json_object_int_add(json
, "rpfCacheRefreshEvents",
2586 qpim_rpf_cache_refresh_events
);
2587 json_object_string_add(json
, "rpfCacheRefreshLast",
2589 json_object_int_add(json
, "nexthopLookups",
2590 qpim_nexthop_lookups
);
2591 json_object_int_add(json
, "nexthopLookupsAvoided",
2592 nexthop_lookups_avoided
);
2595 "RPF Cache Refresh Delay: %ld msecs\n"
2596 "RPF Cache Refresh Timer: %ld msecs\n"
2597 "RPF Cache Refresh Requests: %lld\n"
2598 "RPF Cache Refresh Events: %lld\n"
2599 "RPF Cache Refresh Last: %s\n"
2600 "Nexthop Lookups: %lld\n"
2601 "Nexthop Lookups Avoided: %lld\n",
2602 qpim_rpf_cache_refresh_delay_msec
,
2603 pim_time_timer_remain_msec(qpim_rpf_cache_refresher
),
2604 (long long)qpim_rpf_cache_refresh_requests
,
2605 (long long)qpim_rpf_cache_refresh_events
,
2606 refresh_uptime
, (long long)qpim_nexthop_lookups
,
2607 (long long)nexthop_lookups_avoided
);
2611 static void show_scan_oil_stats(struct pim_instance
*pim
, struct vty
*vty
,
2614 char uptime_scan_oil
[10];
2615 char uptime_mroute_add
[10];
2616 char uptime_mroute_del
[10];
2618 pim_time_uptime_begin(uptime_scan_oil
, sizeof(uptime_scan_oil
), now
,
2619 qpim_scan_oil_last
);
2620 pim_time_uptime_begin(uptime_mroute_add
, sizeof(uptime_mroute_add
), now
,
2621 pim
->mroute_add_last
);
2622 pim_time_uptime_begin(uptime_mroute_del
, sizeof(uptime_mroute_del
), now
,
2623 pim
->mroute_del_last
);
2626 "Scan OIL - Last: %s Events: %lld\n"
2627 "MFC Add - Last: %s Events: %lld\n"
2628 "MFC Del - Last: %s Events: %lld\n",
2629 uptime_scan_oil
, (long long)qpim_scan_oil_events
,
2630 uptime_mroute_add
, (long long)pim
->mroute_add_events
,
2631 uptime_mroute_del
, (long long)pim
->mroute_del_events
);
2634 static void pim_show_rpf(struct pim_instance
*pim
, struct vty
*vty
, u_char uj
)
2636 struct listnode
*up_node
;
2637 struct pim_upstream
*up
;
2638 time_t now
= pim_time_monotonic_sec();
2639 json_object
*json
= NULL
;
2640 json_object
*json_group
= NULL
;
2641 json_object
*json_row
= NULL
;
2644 json
= json_object_new_object();
2645 show_rpf_refresh_stats(vty
, now
, json
);
2647 show_rpf_refresh_stats(vty
, now
, json
);
2650 "Source Group RpfIface RpfAddress RibNextHop Metric Pref\n");
2653 for (ALL_LIST_ELEMENTS_RO(pim
->upstream_list
, up_node
, up
)) {
2654 char src_str
[INET_ADDRSTRLEN
];
2655 char grp_str
[INET_ADDRSTRLEN
];
2656 char rpf_addr_str
[PREFIX_STRLEN
];
2657 char rib_nexthop_str
[PREFIX_STRLEN
];
2658 const char *rpf_ifname
;
2659 struct pim_rpf
*rpf
= &up
->rpf
;
2661 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2662 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2663 pim_addr_dump("<rpf?>", &rpf
->rpf_addr
, rpf_addr_str
,
2664 sizeof(rpf_addr_str
));
2665 pim_addr_dump("<nexthop?>",
2666 &rpf
->source_nexthop
.mrib_nexthop_addr
,
2667 rib_nexthop_str
, sizeof(rib_nexthop_str
));
2669 rpf_ifname
= rpf
->source_nexthop
.interface
? rpf
->source_nexthop
.interface
->name
: "<ifname?>";
2672 json_object_object_get_ex(json
, grp_str
, &json_group
);
2675 json_group
= json_object_new_object();
2676 json_object_object_add(json
, grp_str
,
2680 json_row
= json_object_new_object();
2681 json_object_string_add(json_row
, "source", src_str
);
2682 json_object_string_add(json_row
, "group", grp_str
);
2683 json_object_string_add(json_row
, "rpfInterface",
2685 json_object_string_add(json_row
, "rpfAddress",
2687 json_object_string_add(json_row
, "ribNexthop",
2689 json_object_int_add(
2690 json_row
, "routeMetric",
2691 rpf
->source_nexthop
.mrib_route_metric
);
2692 json_object_int_add(
2693 json_row
, "routePreference",
2694 rpf
->source_nexthop
.mrib_metric_preference
);
2695 json_object_object_add(json_group
, src_str
, json_row
);
2698 vty_out(vty
, "%-15s %-15s %-8s %-15s %-15s %6d %4d\n",
2699 src_str
, grp_str
, rpf_ifname
, rpf_addr_str
,
2701 rpf
->source_nexthop
.mrib_route_metric
,
2702 rpf
->source_nexthop
.mrib_metric_preference
);
2707 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2708 json
, JSON_C_TO_STRING_PRETTY
));
2709 json_object_free(json
);
2713 struct pnc_cache_walk_data
{
2715 struct pim_instance
*pim
;
2718 static int pim_print_pnc_cache_walkcb(struct hash_backet
*backet
, void *arg
)
2720 struct pim_nexthop_cache
*pnc
= backet
->data
;
2721 struct pnc_cache_walk_data
*cwd
= arg
;
2722 struct vty
*vty
= cwd
->vty
;
2723 struct pim_instance
*pim
= cwd
->pim
;
2724 struct nexthop
*nh_node
= NULL
;
2725 ifindex_t first_ifindex
;
2726 struct interface
*ifp
= NULL
;
2731 for (nh_node
= pnc
->nexthop
; nh_node
; nh_node
= nh_node
->next
) {
2732 first_ifindex
= nh_node
->ifindex
;
2733 ifp
= if_lookup_by_index(first_ifindex
, pim
->vrf_id
);
2735 vty_out(vty
, "%-15s ", inet_ntoa(pnc
->rpf
.rpf_addr
.u
.prefix4
));
2736 vty_out(vty
, "%-14s ", ifp
? ifp
->name
: "NULL");
2737 vty_out(vty
, "%s ", inet_ntoa(nh_node
->gate
.ipv4
));
2743 static void pim_show_nexthop(struct pim_instance
*pim
, struct vty
*vty
)
2745 struct pnc_cache_walk_data cwd
;
2749 vty_out(vty
, "Number of registered addresses: %lu\n",
2750 pim
->rpf_hash
->count
);
2751 vty_out(vty
, "Address Interface Nexthop\n");
2752 vty_out(vty
, "-------------------------------------------\n");
2754 hash_walk(pim
->rpf_hash
, pim_print_pnc_cache_walkcb
, &cwd
);
2757 static void igmp_show_groups(struct pim_instance
*pim
, struct vty
*vty
,
2760 struct interface
*ifp
;
2762 json_object
*json
= NULL
;
2763 json_object
*json_iface
= NULL
;
2764 json_object
*json_row
= NULL
;
2766 now
= pim_time_monotonic_sec();
2769 json
= json_object_new_object();
2772 "Interface Address Group Mode Timer Srcs V Uptime \n");
2774 /* scan interfaces */
2775 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2776 struct pim_interface
*pim_ifp
= ifp
->info
;
2777 struct listnode
*sock_node
;
2778 struct igmp_sock
*igmp
;
2783 /* scan igmp sockets */
2784 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
2786 char ifaddr_str
[INET_ADDRSTRLEN
];
2787 struct listnode
*grpnode
;
2788 struct igmp_group
*grp
;
2790 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
2791 sizeof(ifaddr_str
));
2793 /* scan igmp groups */
2794 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
2796 char group_str
[INET_ADDRSTRLEN
];
2800 pim_inet4_dump("<group?>", grp
->group_addr
,
2801 group_str
, sizeof(group_str
));
2802 pim_time_timer_to_hhmmss(hhmmss
, sizeof(hhmmss
),
2803 grp
->t_group_timer
);
2804 pim_time_uptime(uptime
, sizeof(uptime
),
2805 now
- grp
->group_creation
);
2808 json_object_object_get_ex(
2809 json
, ifp
->name
, &json_iface
);
2813 json_object_new_object();
2814 json_object_pim_ifp_add(
2816 json_object_object_add(
2821 json_row
= json_object_new_object();
2822 json_object_string_add(
2823 json_row
, "source", ifaddr_str
);
2824 json_object_string_add(
2825 json_row
, "group", group_str
);
2827 if (grp
->igmp_version
== 3)
2828 json_object_string_add(
2830 grp
->group_filtermode_isexcl
2834 json_object_string_add(json_row
,
2836 json_object_int_add(
2837 json_row
, "sourcesCount",
2838 grp
->group_source_list
2840 grp
->group_source_list
)
2842 json_object_int_add(json_row
, "version",
2844 json_object_string_add(
2845 json_row
, "uptime", uptime
);
2846 json_object_object_add(json_iface
,
2852 "%-9s %-15s %-15s %4s %8s %4d %d %8s\n",
2853 ifp
->name
, ifaddr_str
,
2855 grp
->igmp_version
== 3
2856 ? (grp
->group_filtermode_isexcl
2861 grp
->group_source_list
2863 grp
->group_source_list
)
2865 grp
->igmp_version
, uptime
);
2867 } /* scan igmp groups */
2868 } /* scan igmp sockets */
2869 } /* scan interfaces */
2872 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2873 json
, JSON_C_TO_STRING_PRETTY
));
2874 json_object_free(json
);
2878 static void igmp_show_group_retransmission(struct pim_instance
*pim
,
2881 struct interface
*ifp
;
2884 "Interface Address Group RetTimer Counter RetSrcs\n");
2886 /* scan interfaces */
2887 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2888 struct pim_interface
*pim_ifp
= ifp
->info
;
2889 struct listnode
*sock_node
;
2890 struct igmp_sock
*igmp
;
2895 /* scan igmp sockets */
2896 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
2898 char ifaddr_str
[INET_ADDRSTRLEN
];
2899 struct listnode
*grpnode
;
2900 struct igmp_group
*grp
;
2902 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
2903 sizeof(ifaddr_str
));
2905 /* scan igmp groups */
2906 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
2908 char group_str
[INET_ADDRSTRLEN
];
2909 char grp_retr_mmss
[10];
2910 struct listnode
*src_node
;
2911 struct igmp_source
*src
;
2912 int grp_retr_sources
= 0;
2914 pim_inet4_dump("<group?>", grp
->group_addr
,
2915 group_str
, sizeof(group_str
));
2916 pim_time_timer_to_mmss(
2917 grp_retr_mmss
, sizeof(grp_retr_mmss
),
2918 grp
->t_group_query_retransmit_timer
);
2921 /* count group sources with retransmission state
2923 for (ALL_LIST_ELEMENTS_RO(
2924 grp
->group_source_list
, src_node
,
2926 if (src
->source_query_retransmit_count
2932 vty_out(vty
, "%-9s %-15s %-15s %-8s %7d %7d\n",
2933 ifp
->name
, ifaddr_str
, group_str
,
2935 grp
->group_specific_query_retransmit_count
,
2938 } /* scan igmp groups */
2939 } /* scan igmp sockets */
2940 } /* scan interfaces */
2943 static void igmp_show_sources(struct pim_instance
*pim
, struct vty
*vty
)
2945 struct interface
*ifp
;
2948 now
= pim_time_monotonic_sec();
2951 "Interface Address Group Source Timer Fwd Uptime \n");
2953 /* scan interfaces */
2954 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2955 struct pim_interface
*pim_ifp
= ifp
->info
;
2956 struct listnode
*sock_node
;
2957 struct igmp_sock
*igmp
;
2962 /* scan igmp sockets */
2963 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
2965 char ifaddr_str
[INET_ADDRSTRLEN
];
2966 struct listnode
*grpnode
;
2967 struct igmp_group
*grp
;
2969 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
2970 sizeof(ifaddr_str
));
2972 /* scan igmp groups */
2973 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
2975 char group_str
[INET_ADDRSTRLEN
];
2976 struct listnode
*srcnode
;
2977 struct igmp_source
*src
;
2979 pim_inet4_dump("<group?>", grp
->group_addr
,
2980 group_str
, sizeof(group_str
));
2982 /* scan group sources */
2983 for (ALL_LIST_ELEMENTS_RO(
2984 grp
->group_source_list
, srcnode
,
2986 char source_str
[INET_ADDRSTRLEN
];
2991 "<source?>", src
->source_addr
,
2992 source_str
, sizeof(source_str
));
2994 pim_time_timer_to_mmss(
2996 src
->t_source_timer
);
2999 uptime
, sizeof(uptime
),
3000 now
- src
->source_creation
);
3003 "%-9s %-15s %-15s %-15s %5s %3s %8s\n",
3004 ifp
->name
, ifaddr_str
,
3005 group_str
, source_str
, mmss
,
3006 IGMP_SOURCE_TEST_FORWARDING(
3012 } /* scan group sources */
3013 } /* scan igmp groups */
3014 } /* scan igmp sockets */
3015 } /* scan interfaces */
3018 static void igmp_show_source_retransmission(struct pim_instance
*pim
,
3021 struct interface
*ifp
;
3024 "Interface Address Group Source Counter\n");
3026 /* scan interfaces */
3027 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3028 struct pim_interface
*pim_ifp
= ifp
->info
;
3029 struct listnode
*sock_node
;
3030 struct igmp_sock
*igmp
;
3035 /* scan igmp sockets */
3036 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3038 char ifaddr_str
[INET_ADDRSTRLEN
];
3039 struct listnode
*grpnode
;
3040 struct igmp_group
*grp
;
3042 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3043 sizeof(ifaddr_str
));
3045 /* scan igmp groups */
3046 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3048 char group_str
[INET_ADDRSTRLEN
];
3049 struct listnode
*srcnode
;
3050 struct igmp_source
*src
;
3052 pim_inet4_dump("<group?>", grp
->group_addr
,
3053 group_str
, sizeof(group_str
));
3055 /* scan group sources */
3056 for (ALL_LIST_ELEMENTS_RO(
3057 grp
->group_source_list
, srcnode
,
3059 char source_str
[INET_ADDRSTRLEN
];
3062 "<source?>", src
->source_addr
,
3063 source_str
, sizeof(source_str
));
3066 "%-9s %-15s %-15s %-15s %7d\n",
3067 ifp
->name
, ifaddr_str
,
3068 group_str
, source_str
,
3069 src
->source_query_retransmit_count
);
3071 } /* scan group sources */
3072 } /* scan igmp groups */
3073 } /* scan igmp sockets */
3074 } /* scan interfaces */
3077 static void clear_igmp_interfaces(struct pim_instance
*pim
)
3079 struct interface
*ifp
;
3081 FOR_ALL_INTERFACES (pim
->vrf
, ifp
)
3082 pim_if_addr_del_all_igmp(ifp
);
3084 FOR_ALL_INTERFACES (pim
->vrf
, ifp
)
3085 pim_if_addr_add_all(ifp
);
3088 static void clear_pim_interfaces(struct pim_instance
*pim
)
3090 struct interface
*ifp
;
3092 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3094 pim_neighbor_delete_all(ifp
, "interface cleared");
3099 static void clear_interfaces(struct pim_instance
*pim
)
3101 clear_igmp_interfaces(pim
);
3102 clear_pim_interfaces(pim
);
3105 #define PIM_GET_PIM_INTERFACE(pim_ifp, ifp) \
3106 pim_ifp = ifp->info; \
3109 "%% Enable PIM and/or IGMP on this interface first\n"); \
3110 return CMD_WARNING_CONFIG_FAILED; \
3113 DEFUN (clear_ip_interfaces
,
3114 clear_ip_interfaces_cmd
,
3115 "clear ip interfaces [vrf NAME]",
3118 "Reset interfaces\n"
3122 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3127 clear_interfaces(vrf
->info
);
3132 DEFUN (clear_ip_igmp_interfaces
,
3133 clear_ip_igmp_interfaces_cmd
,
3134 "clear ip igmp [vrf NAME] interfaces",
3139 "Reset IGMP interfaces\n")
3142 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3147 clear_igmp_interfaces(vrf
->info
);
3152 static void mroute_add_all(struct pim_instance
*pim
)
3154 struct listnode
*node
;
3155 struct channel_oil
*c_oil
;
3157 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
3158 if (pim_mroute_add(c_oil
, __PRETTY_FUNCTION__
)) {
3159 /* just log warning */
3160 char source_str
[INET_ADDRSTRLEN
];
3161 char group_str
[INET_ADDRSTRLEN
];
3162 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
,
3163 source_str
, sizeof(source_str
));
3164 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
,
3165 group_str
, sizeof(group_str
));
3166 zlog_warn("%s %s: (S,G)=(%s,%s) failure writing MFC",
3167 __FILE__
, __PRETTY_FUNCTION__
, source_str
,
3173 static void mroute_del_all(struct pim_instance
*pim
)
3175 struct listnode
*node
;
3176 struct channel_oil
*c_oil
;
3178 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
3179 if (pim_mroute_del(c_oil
, __PRETTY_FUNCTION__
)) {
3180 /* just log warning */
3181 char source_str
[INET_ADDRSTRLEN
];
3182 char group_str
[INET_ADDRSTRLEN
];
3183 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
,
3184 source_str
, sizeof(source_str
));
3185 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
,
3186 group_str
, sizeof(group_str
));
3187 zlog_warn("%s %s: (S,G)=(%s,%s) failure clearing MFC",
3188 __FILE__
, __PRETTY_FUNCTION__
, source_str
,
3194 DEFUN (clear_ip_mroute
,
3195 clear_ip_mroute_cmd
,
3196 "clear ip mroute [vrf NAME]",
3199 "Reset multicast routes\n"
3203 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3208 mroute_del_all(vrf
->info
);
3209 mroute_add_all(vrf
->info
);
3214 DEFUN (clear_ip_pim_interfaces
,
3215 clear_ip_pim_interfaces_cmd
,
3216 "clear ip pim [vrf NAME] interfaces",
3221 "Reset PIM interfaces\n")
3224 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3229 clear_pim_interfaces(vrf
->info
);
3234 DEFUN (clear_ip_pim_interface_traffic
,
3235 clear_ip_pim_interface_traffic_cmd
,
3236 "clear ip pim [vrf NAME] interface traffic",
3239 "PIM clear commands\n"
3241 "Reset PIM interfaces\n"
3242 "Reset Protocol Packet counters\n")
3245 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3246 struct interface
*ifp
= NULL
;
3247 struct pim_interface
*pim_ifp
= NULL
;
3252 FOR_ALL_INTERFACES (vrf
, ifp
) {
3253 pim_ifp
= ifp
->info
;
3258 pim_ifp
->pim_ifstat_hello_recv
= 0;
3259 pim_ifp
->pim_ifstat_hello_sent
= 0;
3260 pim_ifp
->pim_ifstat_join_recv
= 0;
3261 pim_ifp
->pim_ifstat_join_send
= 0;
3262 pim_ifp
->pim_ifstat_prune_recv
= 0;
3263 pim_ifp
->pim_ifstat_prune_send
= 0;
3264 pim_ifp
->pim_ifstat_reg_recv
= 0;
3265 pim_ifp
->pim_ifstat_reg_send
= 0;
3266 pim_ifp
->pim_ifstat_reg_stop_recv
= 0;
3267 pim_ifp
->pim_ifstat_reg_stop_send
= 0;
3268 pim_ifp
->pim_ifstat_assert_recv
= 0;
3269 pim_ifp
->pim_ifstat_assert_send
= 0;
3275 DEFUN (clear_ip_pim_oil
,
3276 clear_ip_pim_oil_cmd
,
3277 "clear ip pim [vrf NAME] oil",
3282 "Rescan PIM OIL (output interface list)\n")
3285 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3290 pim_scan_oil(vrf
->info
);
3295 DEFUN (show_ip_igmp_interface
,
3296 show_ip_igmp_interface_cmd
,
3297 "show ip igmp [vrf NAME] interface [detail|WORD] [json]",
3302 "IGMP interface information\n"
3308 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3309 u_char uj
= use_json(argc
, argv
);
3314 if (argv_find(argv
, argc
, "detail", &idx
)
3315 || argv_find(argv
, argc
, "WORD", &idx
))
3316 igmp_show_interfaces_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
3318 igmp_show_interfaces(vrf
->info
, vty
, uj
);
3323 DEFUN (show_ip_igmp_interface_vrf_all
,
3324 show_ip_igmp_interface_vrf_all_cmd
,
3325 "show ip igmp vrf all interface [detail|WORD] [json]",
3330 "IGMP interface information\n"
3336 u_char uj
= use_json(argc
, argv
);
3342 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3346 vty_out(vty
, " \"%s\": ", vrf
->name
);
3349 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3350 if (argv_find(argv
, argc
, "detail", &idx
)
3351 || argv_find(argv
, argc
, "WORD", &idx
))
3352 igmp_show_interfaces_single(vrf
->info
, vty
,
3353 argv
[idx
]->arg
, uj
);
3355 igmp_show_interfaces(vrf
->info
, vty
, uj
);
3358 vty_out(vty
, "}\n");
3363 DEFUN (show_ip_igmp_join
,
3364 show_ip_igmp_join_cmd
,
3365 "show ip igmp [vrf NAME] join",
3370 "IGMP static join information\n")
3373 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3378 igmp_show_interface_join(vrf
->info
, vty
);
3383 DEFUN (show_ip_igmp_join_vrf_all
,
3384 show_ip_igmp_join_vrf_all_cmd
,
3385 "show ip igmp vrf all join",
3390 "IGMP static join information\n")
3392 u_char uj
= use_json(argc
, argv
);
3398 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3402 vty_out(vty
, " \"%s\": ", vrf
->name
);
3405 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3406 igmp_show_interface_join(vrf
->info
, vty
);
3409 vty_out(vty
, "}\n");
3414 DEFUN (show_ip_igmp_groups
,
3415 show_ip_igmp_groups_cmd
,
3416 "show ip igmp [vrf NAME] groups [json]",
3425 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3426 u_char uj
= use_json(argc
, argv
);
3431 igmp_show_groups(vrf
->info
, vty
, uj
);
3436 DEFUN (show_ip_igmp_groups_vrf_all
,
3437 show_ip_igmp_groups_vrf_all_cmd
,
3438 "show ip igmp vrf all groups [json]",
3446 u_char uj
= use_json(argc
, argv
);
3452 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3456 vty_out(vty
, " \"%s\": ", vrf
->name
);
3459 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3460 igmp_show_groups(vrf
->info
, vty
, uj
);
3463 vty_out(vty
, "}\n");
3468 DEFUN (show_ip_igmp_groups_retransmissions
,
3469 show_ip_igmp_groups_retransmissions_cmd
,
3470 "show ip igmp [vrf NAME] groups retransmissions",
3476 "IGMP group retransmissions\n")
3479 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3484 igmp_show_group_retransmission(vrf
->info
, vty
);
3489 DEFUN (show_ip_igmp_sources
,
3490 show_ip_igmp_sources_cmd
,
3491 "show ip igmp [vrf NAME] sources",
3499 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3504 igmp_show_sources(vrf
->info
, vty
);
3509 DEFUN (show_ip_igmp_sources_retransmissions
,
3510 show_ip_igmp_sources_retransmissions_cmd
,
3511 "show ip igmp [vrf NAME] sources retransmissions",
3517 "IGMP source retransmissions\n")
3520 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3525 igmp_show_source_retransmission(vrf
->info
, vty
);
3530 DEFUN (show_ip_pim_assert
,
3531 show_ip_pim_assert_cmd
,
3532 "show ip pim [vrf NAME] assert",
3537 "PIM interface assert\n")
3540 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3545 pim_show_assert(vrf
->info
, vty
);
3550 DEFUN (show_ip_pim_assert_internal
,
3551 show_ip_pim_assert_internal_cmd
,
3552 "show ip pim [vrf NAME] assert-internal",
3557 "PIM interface internal assert state\n")
3560 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3565 pim_show_assert_internal(vrf
->info
, vty
);
3570 DEFUN (show_ip_pim_assert_metric
,
3571 show_ip_pim_assert_metric_cmd
,
3572 "show ip pim [vrf NAME] assert-metric",
3577 "PIM interface assert metric\n")
3580 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3585 pim_show_assert_metric(vrf
->info
, vty
);
3590 DEFUN (show_ip_pim_assert_winner_metric
,
3591 show_ip_pim_assert_winner_metric_cmd
,
3592 "show ip pim [vrf NAME] assert-winner-metric",
3597 "PIM interface assert winner metric\n")
3600 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3605 pim_show_assert_winner_metric(vrf
->info
, vty
);
3610 DEFUN (show_ip_pim_interface
,
3611 show_ip_pim_interface_cmd
,
3612 "show ip pim [vrf NAME] interface [detail|WORD] [json]",
3617 "PIM interface information\n"
3623 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3624 u_char uj
= use_json(argc
, argv
);
3629 if (argv_find(argv
, argc
, "WORD", &idx
)
3630 || argv_find(argv
, argc
, "detail", &idx
))
3631 pim_show_interfaces_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
3633 pim_show_interfaces(vrf
->info
, vty
, uj
);
3638 DEFUN (show_ip_pim_interface_vrf_all
,
3639 show_ip_pim_interface_vrf_all_cmd
,
3640 "show ip pim vrf all interface [detail|WORD] [json]",
3645 "PIM interface information\n"
3651 u_char uj
= use_json(argc
, argv
);
3657 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3661 vty_out(vty
, " \"%s\": ", vrf
->name
);
3664 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3665 if (argv_find(argv
, argc
, "WORD", &idx
)
3666 || argv_find(argv
, argc
, "detail", &idx
))
3667 pim_show_interfaces_single(vrf
->info
, vty
,
3668 argv
[idx
]->arg
, uj
);
3670 pim_show_interfaces(vrf
->info
, vty
, uj
);
3673 vty_out(vty
, "}\n");
3678 DEFUN (show_ip_pim_join
,
3679 show_ip_pim_join_cmd
,
3680 "show ip pim [vrf NAME] join [json]",
3685 "PIM interface join information\n"
3689 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3690 u_char uj
= use_json(argc
, argv
);
3695 pim_show_join(vrf
->info
, vty
, uj
);
3700 DEFUN (show_ip_pim_join_vrf_all
,
3701 show_ip_pim_join_vrf_all_cmd
,
3702 "show ip pim vrf all join [json]",
3707 "PIM interface join information\n"
3710 u_char uj
= use_json(argc
, argv
);
3716 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3720 vty_out(vty
, " \"%s\": ", vrf
->name
);
3723 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3724 pim_show_join(vrf
->info
, vty
, uj
);
3727 vty_out(vty
, "}\n");
3732 DEFUN (show_ip_pim_local_membership
,
3733 show_ip_pim_local_membership_cmd
,
3734 "show ip pim [vrf NAME] local-membership [json]",
3739 "PIM interface local-membership\n"
3743 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3744 u_char uj
= use_json(argc
, argv
);
3749 pim_show_membership(vrf
->info
, vty
, uj
);
3754 DEFUN (show_ip_pim_neighbor
,
3755 show_ip_pim_neighbor_cmd
,
3756 "show ip pim [vrf NAME] neighbor [detail|WORD] [json]",
3761 "PIM neighbor information\n"
3763 "Name of interface or neighbor\n"
3767 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3768 u_char uj
= use_json(argc
, argv
);
3773 if (argv_find(argv
, argc
, "detail", &idx
)
3774 || argv_find(argv
, argc
, "WORD", &idx
))
3775 pim_show_neighbors_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
3777 pim_show_neighbors(vrf
->info
, vty
, uj
);
3782 DEFUN (show_ip_pim_neighbor_vrf_all
,
3783 show_ip_pim_neighbor_vrf_all_cmd
,
3784 "show ip pim vrf all neighbor [detail|WORD] [json]",
3789 "PIM neighbor information\n"
3791 "Name of interface or neighbor\n"
3795 u_char uj
= use_json(argc
, argv
);
3801 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3805 vty_out(vty
, " \"%s\": ", vrf
->name
);
3808 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3809 if (argv_find(argv
, argc
, "detail", &idx
)
3810 || argv_find(argv
, argc
, "WORD", &idx
))
3811 pim_show_neighbors_single(vrf
->info
, vty
,
3812 argv
[idx
]->arg
, uj
);
3814 pim_show_neighbors(vrf
->info
, vty
, uj
);
3817 vty_out(vty
, "}\n");
3822 DEFUN (show_ip_pim_secondary
,
3823 show_ip_pim_secondary_cmd
,
3824 "show ip pim [vrf NAME] secondary",
3829 "PIM neighbor addresses\n")
3832 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3837 pim_show_neighbors_secondary(vrf
->info
, vty
);
3842 DEFUN (show_ip_pim_state
,
3843 show_ip_pim_state_cmd
,
3844 "show ip pim [vrf NAME] state [A.B.C.D [A.B.C.D]] [json]",
3849 "PIM state information\n"
3850 "Unicast or Multicast address\n"
3851 "Multicast address\n"
3854 const char *src_or_group
= NULL
;
3855 const char *group
= NULL
;
3857 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3858 u_char uj
= use_json(argc
, argv
);
3866 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)) {
3867 src_or_group
= argv
[idx
]->arg
;
3869 group
= argv
[idx
+ 1]->arg
;
3872 pim_show_state(vrf
->info
, vty
, src_or_group
, group
, uj
);
3877 DEFUN (show_ip_pim_state_vrf_all
,
3878 show_ip_pim_state_vrf_all_cmd
,
3879 "show ip pim vrf all state [A.B.C.D [A.B.C.D]] [json]",
3884 "PIM state information\n"
3885 "Unicast or Multicast address\n"
3886 "Multicast address\n"
3889 const char *src_or_group
= NULL
;
3890 const char *group
= NULL
;
3892 u_char uj
= use_json(argc
, argv
);
3901 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)) {
3902 src_or_group
= argv
[idx
]->arg
;
3904 group
= argv
[idx
+ 1]->arg
;
3907 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3911 vty_out(vty
, " \"%s\": ", vrf
->name
);
3914 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3915 pim_show_state(vrf
->info
, vty
, src_or_group
, group
, uj
);
3918 vty_out(vty
, "}\n");
3923 DEFUN (show_ip_pim_upstream
,
3924 show_ip_pim_upstream_cmd
,
3925 "show ip pim [vrf NAME] upstream [json]",
3930 "PIM upstream information\n"
3934 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3935 u_char uj
= use_json(argc
, argv
);
3940 pim_show_upstream(vrf
->info
, vty
, uj
);
3945 DEFUN (show_ip_pim_upstream_vrf_all
,
3946 show_ip_pim_upstream_vrf_all_cmd
,
3947 "show ip pim vrf all upstream [json]",
3952 "PIM upstream information\n"
3955 u_char uj
= use_json(argc
, argv
);
3961 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3965 vty_out(vty
, " \"%s\": ", vrf
->name
);
3968 vty_out(vty
, "VRF: %s\n", vrf
->name
);
3969 pim_show_upstream(vrf
->info
, vty
, uj
);
3975 DEFUN (show_ip_pim_upstream_join_desired
,
3976 show_ip_pim_upstream_join_desired_cmd
,
3977 "show ip pim [vrf NAME] upstream-join-desired [json]",
3982 "PIM upstream join-desired\n"
3986 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3987 u_char uj
= use_json(argc
, argv
);
3992 pim_show_join_desired(vrf
->info
, vty
, uj
);
3997 DEFUN (show_ip_pim_upstream_rpf
,
3998 show_ip_pim_upstream_rpf_cmd
,
3999 "show ip pim [vrf NAME] upstream-rpf [json]",
4004 "PIM upstream source rpf\n"
4008 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4009 u_char uj
= use_json(argc
, argv
);
4014 pim_show_upstream_rpf(vrf
->info
, vty
, uj
);
4019 DEFUN (show_ip_pim_rp
,
4021 "show ip pim [vrf NAME] rp-info [json]",
4026 "PIM RP information\n"
4030 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4031 u_char uj
= use_json(argc
, argv
);
4036 pim_rp_show_information(vrf
->info
, vty
, uj
);
4041 DEFUN (show_ip_pim_rp_vrf_all
,
4042 show_ip_pim_rp_vrf_all_cmd
,
4043 "show ip pim vrf all rp-info [json]",
4048 "PIM RP information\n"
4051 u_char uj
= use_json(argc
, argv
);
4057 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4061 vty_out(vty
, " \"%s\": ", vrf
->name
);
4064 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4065 pim_rp_show_information(vrf
->info
, vty
, uj
);
4068 vty_out(vty
, "}\n");
4073 DEFUN (show_ip_pim_rpf
,
4074 show_ip_pim_rpf_cmd
,
4075 "show ip pim [vrf NAME] rpf [json]",
4080 "PIM cached source rpf information\n"
4084 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4085 u_char uj
= use_json(argc
, argv
);
4090 pim_show_rpf(vrf
->info
, vty
, uj
);
4095 DEFUN (show_ip_pim_rpf_vrf_all
,
4096 show_ip_pim_rpf_vrf_all_cmd
,
4097 "show ip pim vrf all rpf [json]",
4102 "PIM cached source rpf information\n"
4105 u_char uj
= use_json(argc
, argv
);
4111 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4115 vty_out(vty
, " \"%s\": ", vrf
->name
);
4118 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4119 pim_show_rpf(vrf
->info
, vty
, uj
);
4122 vty_out(vty
, "}\n");
4127 DEFUN (show_ip_pim_nexthop
,
4128 show_ip_pim_nexthop_cmd
,
4129 "show ip pim [vrf NAME] nexthop",
4134 "PIM cached nexthop rpf information\n")
4137 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4142 pim_show_nexthop(vrf
->info
, vty
);
4147 DEFUN (show_ip_pim_nexthop_lookup
,
4148 show_ip_pim_nexthop_lookup_cmd
,
4149 "show ip pim [vrf NAME] nexthop-lookup A.B.C.D A.B.C.D",
4154 "PIM cached nexthop rpf lookup\n"
4155 "Source/RP address\n"
4156 "Multicast Group address\n")
4158 struct pim_nexthop_cache pnc
;
4159 struct prefix nht_p
;
4161 struct in_addr src_addr
, grp_addr
;
4162 struct in_addr vif_source
;
4163 const char *addr_str
, *addr_str1
;
4165 struct pim_nexthop nexthop
;
4166 char nexthop_addr_str
[PREFIX_STRLEN
];
4167 char grp_str
[PREFIX_STRLEN
];
4169 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4174 argv_find(argv
, argc
, "A.B.C.D", &idx
);
4175 addr_str
= argv
[idx
]->arg
;
4176 result
= inet_pton(AF_INET
, addr_str
, &src_addr
);
4178 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
4179 errno
, safe_strerror(errno
));
4183 if (pim_is_group_224_4(src_addr
)) {
4185 "Invalid argument. Expected Valid Source Address.\n");
4189 addr_str1
= argv
[idx
+ 1]->arg
;
4190 result
= inet_pton(AF_INET
, addr_str1
, &grp_addr
);
4192 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
4193 errno
, safe_strerror(errno
));
4197 if (!pim_is_group_224_4(grp_addr
)) {
4199 "Invalid argument. Expected Valid Multicast Group Address.\n");
4203 if (!pim_rp_set_upstream_addr(vrf
->info
, &vif_source
, src_addr
,
4207 memset(&pnc
, 0, sizeof(struct pim_nexthop_cache
));
4208 nht_p
.family
= AF_INET
;
4209 nht_p
.prefixlen
= IPV4_MAX_BITLEN
;
4210 nht_p
.u
.prefix4
= vif_source
;
4211 grp
.family
= AF_INET
;
4212 grp
.prefixlen
= IPV4_MAX_BITLEN
;
4213 grp
.u
.prefix4
= grp_addr
;
4214 memset(&nexthop
, 0, sizeof(nexthop
));
4216 if (pim_find_or_track_nexthop(vrf
->info
, &nht_p
, NULL
, NULL
, &pnc
))
4217 result
= pim_ecmp_nexthop_search(vrf
->info
, &pnc
, &nexthop
,
4220 result
= pim_ecmp_nexthop_lookup(vrf
->info
, &nexthop
,
4221 vif_source
, &nht_p
, &grp
, 0);
4225 "Nexthop Lookup failed, no usable routes returned.\n");
4229 pim_addr_dump("<grp?>", &grp
, grp_str
, sizeof(grp_str
));
4230 pim_addr_dump("<nexthop?>", &nexthop
.mrib_nexthop_addr
,
4231 nexthop_addr_str
, sizeof(nexthop_addr_str
));
4232 vty_out(vty
, "Group %s --- Nexthop %s Interface %s \n", grp_str
,
4233 nexthop_addr_str
, nexthop
.interface
->name
);
4238 DEFUN (show_ip_pim_interface_traffic
,
4239 show_ip_pim_interface_traffic_cmd
,
4240 "show ip pim [vrf NAME] interface traffic [WORD] [json]",
4245 "PIM interface information\n"
4246 "Protocol Packet counters\n"
4251 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4252 u_char uj
= use_json(argc
, argv
);
4257 if (argv_find(argv
, argc
, "WORD", &idx
))
4258 pim_show_interface_traffic_single(vrf
->info
, vty
,
4259 argv
[idx
]->arg
, uj
);
4261 pim_show_interface_traffic(vrf
->info
, vty
, uj
);
4266 static void show_multicast_interfaces(struct pim_instance
*pim
, struct vty
*vty
)
4268 struct interface
*ifp
;
4273 "Interface Address ifi Vif PktsIn PktsOut BytesIn BytesOut\n");
4275 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
4276 struct pim_interface
*pim_ifp
;
4277 struct in_addr ifaddr
;
4278 struct sioc_vif_req vreq
;
4280 pim_ifp
= ifp
->info
;
4285 memset(&vreq
, 0, sizeof(vreq
));
4286 vreq
.vifi
= pim_ifp
->mroute_vif_index
;
4288 if (ioctl(pim
->mroute_socket
, SIOCGETVIFCNT
, &vreq
)) {
4290 "ioctl(SIOCGETVIFCNT=%lu) failure for interface %s vif_index=%d: errno=%d: %s",
4291 (unsigned long)SIOCGETVIFCNT
, ifp
->name
,
4292 pim_ifp
->mroute_vif_index
, errno
,
4293 safe_strerror(errno
));
4296 ifaddr
= pim_ifp
->primary_address
;
4298 vty_out(vty
, "%-12s %-15s %3d %3d %7lu %7lu %10lu %10lu\n",
4299 ifp
->name
, inet_ntoa(ifaddr
), ifp
->ifindex
,
4300 pim_ifp
->mroute_vif_index
, (unsigned long)vreq
.icount
,
4301 (unsigned long)vreq
.ocount
, (unsigned long)vreq
.ibytes
,
4302 (unsigned long)vreq
.obytes
);
4306 static void pim_cmd_show_ip_multicast_helper(struct pim_instance
*pim
,
4309 struct vrf
*vrf
= pim
->vrf
;
4310 time_t now
= pim_time_monotonic_sec();
4315 vty_out(vty
, "Mroute socket descriptor:");
4317 vty_out(vty
, " %d(%s)\n", pim
->mroute_socket
, vrf
->name
);
4319 pim_time_uptime(uptime
, sizeof(uptime
),
4320 now
- pim
->mroute_socket_creation
);
4321 vty_out(vty
, "Mroute socket uptime: %s\n", uptime
);
4325 pim_zebra_zclient_update(vty
);
4326 pim_zlookup_show_ip_multicast(vty
);
4329 vty_out(vty
, "Maximum highest VifIndex: %d\n", PIM_MAX_USABLE_VIFS
);
4332 vty_out(vty
, "Upstream Join Timer: %d secs\n", qpim_t_periodic
);
4333 vty_out(vty
, "Join/Prune Holdtime: %d secs\n", PIM_JP_HOLDTIME
);
4334 vty_out(vty
, "PIM ECMP: %s\n", qpim_ecmp_enable
? "Enable" : "Disable");
4335 vty_out(vty
, "PIM ECMP Rebalance: %s\n",
4336 qpim_ecmp_rebalance_enable
? "Enable" : "Disable");
4340 show_rpf_refresh_stats(vty
, now
, NULL
);
4344 show_scan_oil_stats(pim
, vty
, now
);
4346 show_multicast_interfaces(pim
, vty
);
4349 DEFUN (show_ip_multicast
,
4350 show_ip_multicast_cmd
,
4351 "show ip multicast [vrf NAME]",
4355 "Multicast global information\n")
4358 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4363 pim_cmd_show_ip_multicast_helper(vrf
->info
, vty
);
4368 DEFUN (show_ip_multicast_vrf_all
,
4369 show_ip_multicast_vrf_all_cmd
,
4370 "show ip multicast vrf all",
4374 "Multicast global information\n")
4376 u_char uj
= use_json(argc
, argv
);
4382 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4386 vty_out(vty
, " \"%s\": ", vrf
->name
);
4389 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4390 pim_cmd_show_ip_multicast_helper(vrf
->info
, vty
);
4393 vty_out(vty
, "}\n");
4398 static void show_mroute(struct pim_instance
*pim
, struct vty
*vty
, bool fill
,
4401 struct listnode
*node
;
4402 struct channel_oil
*c_oil
;
4403 struct static_route
*s_route
;
4405 json_object
*json
= NULL
;
4406 json_object
*json_group
= NULL
;
4407 json_object
*json_source
= NULL
;
4408 json_object
*json_oil
= NULL
;
4409 json_object
*json_ifp_out
= NULL
;
4412 char grp_str
[INET_ADDRSTRLEN
];
4413 char src_str
[INET_ADDRSTRLEN
];
4414 char in_ifname
[INTERFACE_NAMSIZ
+ 1];
4415 char out_ifname
[INTERFACE_NAMSIZ
+ 1];
4417 struct interface
*ifp_in
;
4421 json
= json_object_new_object();
4424 "Source Group Proto Input Output TTL Uptime\n");
4427 now
= pim_time_monotonic_sec();
4429 /* print list of PIM and IGMP routes */
4430 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
4433 if (!c_oil
->installed
&& !uj
)
4436 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, grp_str
,
4438 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, src_str
,
4440 ifp_in
= pim_if_find_by_vif_index(pim
, c_oil
->oil
.mfcc_parent
);
4443 strcpy(in_ifname
, ifp_in
->name
);
4445 strcpy(in_ifname
, "<iif?>");
4449 /* Find the group, create it if it doesn't exist */
4450 json_object_object_get_ex(json
, grp_str
, &json_group
);
4453 json_group
= json_object_new_object();
4454 json_object_object_add(json
, grp_str
,
4458 /* Find the source nested under the group, create it if
4459 * it doesn't exist */
4460 json_object_object_get_ex(json_group
, src_str
,
4464 json_source
= json_object_new_object();
4465 json_object_object_add(json_group
, src_str
,
4469 /* Find the inbound interface nested under the source,
4470 * create it if it doesn't exist */
4471 json_object_int_add(json_source
, "installed",
4473 json_object_int_add(json_source
, "refCount",
4474 c_oil
->oil_ref_count
);
4475 json_object_int_add(json_source
, "oilSize",
4477 json_object_int_add(json_source
, "OilInheritedRescan",
4478 c_oil
->oil_inherited_rescan
);
4479 json_object_string_add(json_source
, "iif", in_ifname
);
4483 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
4485 struct interface
*ifp_out
;
4486 char oif_uptime
[10];
4489 ttl
= c_oil
->oil
.mfcc_ttls
[oif_vif_index
];
4493 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
4495 oif_uptime
, sizeof(oif_uptime
),
4496 now
- c_oil
->oif_creation
[oif_vif_index
]);
4500 strcpy(out_ifname
, ifp_out
->name
);
4502 strcpy(out_ifname
, "<oif?>");
4505 json_ifp_out
= json_object_new_object();
4506 json_object_string_add(json_ifp_out
, "source",
4508 json_object_string_add(json_ifp_out
, "group",
4511 if (c_oil
->oif_flags
[oif_vif_index
]
4512 & PIM_OIF_FLAG_PROTO_PIM
)
4513 json_object_boolean_true_add(
4514 json_ifp_out
, "protocolPim");
4516 if (c_oil
->oif_flags
[oif_vif_index
]
4517 & PIM_OIF_FLAG_PROTO_IGMP
)
4518 json_object_boolean_true_add(
4519 json_ifp_out
, "protocolIgmp");
4521 if (c_oil
->oif_flags
[oif_vif_index
]
4522 & PIM_OIF_FLAG_PROTO_SOURCE
)
4523 json_object_boolean_true_add(
4524 json_ifp_out
, "protocolSource");
4526 if (c_oil
->oif_flags
[oif_vif_index
]
4527 & PIM_OIF_FLAG_PROTO_STAR
)
4528 json_object_boolean_true_add(
4530 "protocolInherited");
4532 json_object_string_add(json_ifp_out
,
4535 json_object_int_add(json_ifp_out
, "iVifI",
4536 c_oil
->oil
.mfcc_parent
);
4537 json_object_string_add(json_ifp_out
,
4538 "outboundInterface",
4540 json_object_int_add(json_ifp_out
, "oVifI",
4542 json_object_int_add(json_ifp_out
, "ttl", ttl
);
4543 json_object_string_add(json_ifp_out
, "upTime",
4546 json_oil
= json_object_new_object();
4547 json_object_object_add(json_source
,
4550 json_object_object_add(json_oil
, out_ifname
,
4553 if (c_oil
->oif_flags
[oif_vif_index
]
4554 & PIM_OIF_FLAG_PROTO_PIM
) {
4555 strcpy(proto
, "PIM");
4558 if (c_oil
->oif_flags
[oif_vif_index
]
4559 & PIM_OIF_FLAG_PROTO_IGMP
) {
4560 strcpy(proto
, "IGMP");
4563 if (c_oil
->oif_flags
[oif_vif_index
]
4564 & PIM_OIF_FLAG_PROTO_SOURCE
) {
4565 strcpy(proto
, "SRC");
4568 if (c_oil
->oif_flags
[oif_vif_index
]
4569 & PIM_OIF_FLAG_PROTO_STAR
) {
4570 strcpy(proto
, "STAR");
4574 "%-15s %-15s %-6s %-10s %-10s %-3d %8s\n",
4575 src_str
, grp_str
, proto
, in_ifname
,
4576 out_ifname
, ttl
, oif_uptime
);
4581 in_ifname
[0] = '\0';
4587 if (!uj
&& !found_oif
) {
4588 vty_out(vty
, "%-15s %-15s %-6s %-10s %-10s %-3d %8s\n",
4589 src_str
, grp_str
, "none", in_ifname
, "none", 0,
4594 /* Print list of static routes */
4595 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, s_route
)) {
4598 if (!s_route
->c_oil
.installed
)
4601 pim_inet4_dump("<group?>", s_route
->group
, grp_str
,
4603 pim_inet4_dump("<source?>", s_route
->source
, src_str
,
4605 ifp_in
= pim_if_find_by_vif_index(pim
, s_route
->iif
);
4609 strcpy(in_ifname
, ifp_in
->name
);
4611 strcpy(in_ifname
, "<iif?>");
4615 /* Find the group, create it if it doesn't exist */
4616 json_object_object_get_ex(json
, grp_str
, &json_group
);
4619 json_group
= json_object_new_object();
4620 json_object_object_add(json
, grp_str
,
4624 /* Find the source nested under the group, create it if
4625 * it doesn't exist */
4626 json_object_object_get_ex(json_group
, src_str
,
4630 json_source
= json_object_new_object();
4631 json_object_object_add(json_group
, src_str
,
4635 json_object_string_add(json_source
, "iif", in_ifname
);
4638 strcpy(proto
, "STATIC");
4641 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
4643 struct interface
*ifp_out
;
4644 char oif_uptime
[10];
4647 ttl
= s_route
->oif_ttls
[oif_vif_index
];
4651 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
4653 oif_uptime
, sizeof(oif_uptime
),
4656 .oif_creation
[oif_vif_index
]);
4660 strcpy(out_ifname
, ifp_out
->name
);
4662 strcpy(out_ifname
, "<oif?>");
4665 json_ifp_out
= json_object_new_object();
4666 json_object_string_add(json_ifp_out
, "source",
4668 json_object_string_add(json_ifp_out
, "group",
4670 json_object_boolean_true_add(json_ifp_out
,
4672 json_object_string_add(json_ifp_out
,
4675 json_object_int_add(
4676 json_ifp_out
, "iVifI",
4677 s_route
->c_oil
.oil
.mfcc_parent
);
4678 json_object_string_add(json_ifp_out
,
4679 "outboundInterface",
4681 json_object_int_add(json_ifp_out
, "oVifI",
4683 json_object_int_add(json_ifp_out
, "ttl", ttl
);
4684 json_object_string_add(json_ifp_out
, "upTime",
4687 json_oil
= json_object_new_object();
4688 json_object_object_add(json_source
,
4691 json_object_object_add(json_oil
, out_ifname
,
4695 "%-15s %-15s %-6s %-10s %-10s %-3d %8s %s\n",
4696 src_str
, grp_str
, proto
, in_ifname
,
4697 out_ifname
, ttl
, oif_uptime
,
4699 if (first
&& !fill
) {
4702 in_ifname
[0] = '\0';
4708 if (!uj
&& !found_oif
) {
4710 "%-15s %-15s %-6s %-10s %-10s %-3d %8s %s\n",
4711 src_str
, grp_str
, proto
, in_ifname
, "none", 0,
4712 "--:--:--", pim
->vrf
->name
);
4717 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4718 json
, JSON_C_TO_STRING_PRETTY
));
4719 json_object_free(json
);
4723 DEFUN (show_ip_mroute
,
4725 "show ip mroute [vrf NAME] [fill] [json]",
4730 "Fill in Assumed data\n"
4733 u_char uj
= use_json(argc
, argv
);
4736 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4741 if (argv_find(argv
, argc
, "fill", &idx
))
4744 show_mroute(vrf
->info
, vty
, fill
, uj
);
4748 DEFUN (show_ip_mroute_vrf_all
,
4749 show_ip_mroute_vrf_all_cmd
,
4750 "show ip mroute vrf all [fill] [json]",
4755 "Fill in Assumed data\n"
4758 u_char uj
= use_json(argc
, argv
);
4764 if (argv_find(argv
, argc
, "fill", &idx
))
4769 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4773 vty_out(vty
, " \"%s\": ", vrf
->name
);
4776 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4777 show_mroute(vrf
->info
, vty
, fill
, uj
);
4780 vty_out(vty
, "}\n");
4785 static void show_mroute_count(struct pim_instance
*pim
, struct vty
*vty
)
4787 struct listnode
*node
;
4788 struct channel_oil
*c_oil
;
4789 struct static_route
*s_route
;
4794 "Source Group LastUsed Packets Bytes WrongIf \n");
4796 /* Print PIM and IGMP route counts */
4797 for (ALL_LIST_ELEMENTS_RO(pim
->channel_oil_list
, node
, c_oil
)) {
4798 char group_str
[INET_ADDRSTRLEN
];
4799 char source_str
[INET_ADDRSTRLEN
];
4801 if (!c_oil
->installed
)
4804 pim_mroute_update_counters(c_oil
);
4806 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, group_str
,
4808 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, source_str
,
4809 sizeof(source_str
));
4811 vty_out(vty
, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
4812 source_str
, group_str
, c_oil
->cc
.lastused
/ 100,
4813 c_oil
->cc
.pktcnt
, c_oil
->cc
.bytecnt
,
4814 c_oil
->cc
.wrong_if
);
4817 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, s_route
)) {
4818 char group_str
[INET_ADDRSTRLEN
];
4819 char source_str
[INET_ADDRSTRLEN
];
4821 if (!s_route
->c_oil
.installed
)
4824 pim_mroute_update_counters(&s_route
->c_oil
);
4826 pim_inet4_dump("<group?>", s_route
->c_oil
.oil
.mfcc_mcastgrp
,
4827 group_str
, sizeof(group_str
));
4828 pim_inet4_dump("<source?>", s_route
->c_oil
.oil
.mfcc_origin
,
4829 source_str
, sizeof(source_str
));
4831 vty_out(vty
, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
4832 source_str
, group_str
, s_route
->c_oil
.cc
.lastused
,
4833 s_route
->c_oil
.cc
.pktcnt
, s_route
->c_oil
.cc
.bytecnt
,
4834 s_route
->c_oil
.cc
.wrong_if
);
4838 DEFUN (show_ip_mroute_count
,
4839 show_ip_mroute_count_cmd
,
4840 "show ip mroute [vrf NAME] count",
4845 "Route and packet count data\n")
4848 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4853 show_mroute_count(vrf
->info
, vty
);
4857 DEFUN (show_ip_mroute_count_vrf_all
,
4858 show_ip_mroute_count_vrf_all_cmd
,
4859 "show ip mroute vrf all count",
4864 "Route and packet count data\n")
4866 u_char uj
= use_json(argc
, argv
);
4872 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4876 vty_out(vty
, " \"%s\": ", vrf
->name
);
4879 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4880 show_mroute_count(vrf
->info
, vty
);
4883 vty_out(vty
, "}\n");
4890 "show ip rib [vrf NAME] A.B.C.D",
4895 "Unicast address\n")
4898 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4899 struct in_addr addr
;
4900 const char *addr_str
;
4901 struct pim_nexthop nexthop
;
4902 char nexthop_addr_str
[PREFIX_STRLEN
];
4908 memset(&nexthop
, 0, sizeof(nexthop
));
4909 argv_find(argv
, argc
, "A.B.C.D", &idx
);
4910 addr_str
= argv
[idx
]->arg
;
4911 result
= inet_pton(AF_INET
, addr_str
, &addr
);
4913 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
4914 errno
, safe_strerror(errno
));
4918 if (pim_nexthop_lookup(vrf
->info
, &nexthop
, addr
, 0)) {
4920 "Failure querying RIB nexthop for unicast address %s\n",
4926 "Address NextHop Interface Metric Preference\n");
4928 pim_addr_dump("<nexthop?>", &nexthop
.mrib_nexthop_addr
,
4929 nexthop_addr_str
, sizeof(nexthop_addr_str
));
4931 vty_out(vty
, "%-15s %-15s %-9s %6d %10d\n", addr_str
, nexthop_addr_str
,
4932 nexthop
.interface
? nexthop
.interface
->name
: "<ifname?>",
4933 nexthop
.mrib_route_metric
, nexthop
.mrib_metric_preference
);
4938 static void show_ssmpingd(struct pim_instance
*pim
, struct vty
*vty
)
4940 struct listnode
*node
;
4941 struct ssmpingd_sock
*ss
;
4945 "Source Socket Address Port Uptime Requests\n");
4947 if (!pim
->ssmpingd_list
)
4950 now
= pim_time_monotonic_sec();
4952 for (ALL_LIST_ELEMENTS_RO(pim
->ssmpingd_list
, node
, ss
)) {
4953 char source_str
[INET_ADDRSTRLEN
];
4955 struct sockaddr_in bind_addr
;
4956 socklen_t len
= sizeof(bind_addr
);
4957 char bind_addr_str
[INET_ADDRSTRLEN
];
4959 pim_inet4_dump("<src?>", ss
->source_addr
, source_str
,
4960 sizeof(source_str
));
4962 if (pim_socket_getsockname(
4963 ss
->sock_fd
, (struct sockaddr
*)&bind_addr
, &len
)) {
4965 "%% Failure reading socket name for ssmpingd source %s on fd=%d\n",
4966 source_str
, ss
->sock_fd
);
4969 pim_inet4_dump("<addr?>", bind_addr
.sin_addr
, bind_addr_str
,
4970 sizeof(bind_addr_str
));
4971 pim_time_uptime(ss_uptime
, sizeof(ss_uptime
),
4972 now
- ss
->creation
);
4974 vty_out(vty
, "%-15s %6d %-15s %5d %8s %8lld\n", source_str
,
4975 ss
->sock_fd
, bind_addr_str
, ntohs(bind_addr
.sin_port
),
4976 ss_uptime
, (long long)ss
->requests
);
4980 DEFUN (show_ip_ssmpingd
,
4981 show_ip_ssmpingd_cmd
,
4982 "show ip ssmpingd [vrf NAME]",
4989 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4994 show_ssmpingd(vrf
->info
, vty
);
4998 static int pim_rp_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
4999 const char *rp
, const char *group
,
5004 result
= pim_rp_new(pim
, rp
, group
, plist
);
5006 if (result
== PIM_MALLOC_FAIL
) {
5007 vty_out(vty
, "%% Out of memory\n");
5008 return CMD_WARNING_CONFIG_FAILED
;
5011 if (result
== PIM_GROUP_BAD_ADDRESS
) {
5012 vty_out(vty
, "%% Bad group address specified: %s\n", group
);
5013 return CMD_WARNING_CONFIG_FAILED
;
5016 if (result
== PIM_RP_BAD_ADDRESS
) {
5017 vty_out(vty
, "%% Bad RP address specified: %s\n", rp
);
5018 return CMD_WARNING_CONFIG_FAILED
;
5021 if (result
== PIM_RP_NO_PATH
) {
5022 vty_out(vty
, "%% No Path to RP address specified: %s\n", rp
);
5026 if (result
== PIM_GROUP_OVERLAP
) {
5028 "%% Group range specified cannot exact match another\n");
5029 return CMD_WARNING_CONFIG_FAILED
;
5032 if (result
== PIM_GROUP_PFXLIST_OVERLAP
) {
5034 "%% This group is already covered by a RP prefix-list\n");
5035 return CMD_WARNING_CONFIG_FAILED
;
5038 if (result
== PIM_RP_PFXLIST_IN_USE
) {
5040 "%% The same prefix-list cannot be applied to multiple RPs\n");
5041 return CMD_WARNING_CONFIG_FAILED
;
5047 static int pim_cmd_spt_switchover(struct pim_instance
*pim
,
5048 enum pim_spt_switchover spt
,
5051 pim
->spt
.switchover
= spt
;
5053 switch (pim
->spt
.switchover
) {
5054 case PIM_SPT_IMMEDIATE
:
5056 XFREE(MTYPE_PIM_SPT_PLIST_NAME
, pim
->spt
.plist
);
5058 pim_upstream_add_lhr_star_pimreg(pim
);
5060 case PIM_SPT_INFINITY
:
5061 pim_upstream_remove_lhr_star_pimreg(pim
, plist
);
5064 XFREE(MTYPE_PIM_SPT_PLIST_NAME
, pim
->spt
.plist
);
5068 XSTRDUP(MTYPE_PIM_SPT_PLIST_NAME
, plist
);
5075 DEFUN (ip_pim_spt_switchover_infinity
,
5076 ip_pim_spt_switchover_infinity_cmd
,
5077 "ip pim spt-switchover infinity-and-beyond",
5081 "Never switch to SPT Tree\n")
5083 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5084 return pim_cmd_spt_switchover(pim
, PIM_SPT_INFINITY
, NULL
);
5087 DEFUN (ip_pim_spt_switchover_infinity_plist
,
5088 ip_pim_spt_switchover_infinity_plist_cmd
,
5089 "ip pim spt-switchover infinity-and-beyond prefix-list WORD",
5093 "Never switch to SPT Tree\n"
5094 "Prefix-List to control which groups to switch\n"
5095 "Prefix-List name\n")
5097 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5098 return pim_cmd_spt_switchover(pim
, PIM_SPT_INFINITY
, argv
[5]->arg
);
5101 DEFUN (no_ip_pim_spt_switchover_infinity
,
5102 no_ip_pim_spt_switchover_infinity_cmd
,
5103 "no ip pim spt-switchover infinity-and-beyond",
5108 "Never switch to SPT Tree\n")
5110 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5111 return pim_cmd_spt_switchover(pim
, PIM_SPT_IMMEDIATE
, NULL
);
5114 DEFUN (no_ip_pim_spt_switchover_infinity_plist
,
5115 no_ip_pim_spt_switchover_infinity_plist_cmd
,
5116 "no ip pim spt-switchover infinity-and-beyond prefix-list WORD",
5121 "Never switch to SPT Tree\n"
5122 "Prefix-List to control which groups to switch\n"
5123 "Prefix-List name\n")
5125 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5126 return pim_cmd_spt_switchover(pim
, PIM_SPT_IMMEDIATE
, NULL
);
5129 DEFUN (ip_pim_joinprune_time
,
5130 ip_pim_joinprune_time_cmd
,
5131 "ip pim join-prune-interval (60-600)",
5133 "pim multicast routing\n"
5134 "Join Prune Send Interval\n"
5137 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5138 qpim_t_periodic
= atoi(argv
[3]->arg
);
5142 DEFUN (no_ip_pim_joinprune_time
,
5143 no_ip_pim_joinprune_time_cmd
,
5144 "no ip pim join-prune-interval (60-600)",
5147 "pim multicast routing\n"
5148 "Join Prune Send Interval\n"
5151 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5152 qpim_t_periodic
= PIM_DEFAULT_T_PERIODIC
;
5156 DEFUN (ip_pim_register_suppress
,
5157 ip_pim_register_suppress_cmd
,
5158 "ip pim register-suppress-time (5-60000)",
5160 "pim multicast routing\n"
5161 "Register Suppress Timer\n"
5164 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5165 qpim_register_suppress_time
= atoi(argv
[3]->arg
);
5169 DEFUN (no_ip_pim_register_suppress
,
5170 no_ip_pim_register_suppress_cmd
,
5171 "no ip pim register-suppress-time (5-60000)",
5174 "pim multicast routing\n"
5175 "Register Suppress Timer\n"
5178 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5179 qpim_register_suppress_time
= PIM_REGISTER_SUPPRESSION_TIME_DEFAULT
;
5183 DEFUN (ip_pim_rp_keep_alive
,
5184 ip_pim_rp_keep_alive_cmd
,
5185 "ip pim rp keep-alive-timer (31-60000)",
5187 "pim multicast routing\n"
5189 "Keep alive Timer\n"
5192 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5193 pim
->rp_keep_alive_time
= atoi(argv
[4]->arg
);
5197 DEFUN (no_ip_pim_rp_keep_alive
,
5198 no_ip_pim_rp_keep_alive_cmd
,
5199 "no ip pim rp keep-alive-timer (31-60000)",
5202 "pim multicast routing\n"
5204 "Keep alive Timer\n"
5207 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5208 pim
->rp_keep_alive_time
= PIM_KEEPALIVE_PERIOD
;
5212 DEFUN (ip_pim_keep_alive
,
5213 ip_pim_keep_alive_cmd
,
5214 "ip pim keep-alive-timer (31-60000)",
5216 "pim multicast routing\n"
5217 "Keep alive Timer\n"
5220 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5221 pim
->keep_alive_time
= atoi(argv
[3]->arg
);
5225 DEFUN (no_ip_pim_keep_alive
,
5226 no_ip_pim_keep_alive_cmd
,
5227 "no ip pim keep-alive-timer (31-60000)",
5230 "pim multicast routing\n"
5231 "Keep alive Timer\n"
5234 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5235 pim
->keep_alive_time
= PIM_KEEPALIVE_PERIOD
;
5239 DEFUN (ip_pim_packets
,
5241 "ip pim packets (1-100)",
5243 "pim multicast routing\n"
5244 "packets to process at one time per fd\n"
5245 "Number of packets\n")
5247 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5248 qpim_packet_process
= atoi(argv
[3]->arg
);
5252 DEFUN (no_ip_pim_packets
,
5253 no_ip_pim_packets_cmd
,
5254 "no ip pim packets (1-100)",
5257 "pim multicast routing\n"
5258 "packets to process at one time per fd\n"
5259 "Number of packets\n")
5261 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5262 qpim_packet_process
= PIM_DEFAULT_PACKET_PROCESS
;
5266 DEFUN (ip_pim_v6_secondary
,
5267 ip_pim_v6_secondary_cmd
,
5268 "ip pim send-v6-secondary",
5270 "pim multicast routing\n"
5271 "Send v6 secondary addresses\n")
5273 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5274 pim
->send_v6_secondary
= 1;
5279 DEFUN (no_ip_pim_v6_secondary
,
5280 no_ip_pim_v6_secondary_cmd
,
5281 "no ip pim send-v6-secondary",
5284 "pim multicast routing\n"
5285 "Send v6 secondary addresses\n")
5287 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5288 pim
->send_v6_secondary
= 0;
5295 "ip pim rp A.B.C.D [A.B.C.D/M]",
5297 "pim multicast routing\n"
5299 "ip address of RP\n"
5300 "Group Address range to cover\n")
5302 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5305 if (argc
== (idx_ipv4
+ 1))
5306 return pim_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
, NULL
,
5309 return pim_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
,
5310 argv
[idx_ipv4
+ 1]->arg
, NULL
);
5313 DEFUN (ip_pim_rp_prefix_list
,
5314 ip_pim_rp_prefix_list_cmd
,
5315 "ip pim rp A.B.C.D prefix-list WORD",
5317 "pim multicast routing\n"
5319 "ip address of RP\n"
5320 "group prefix-list filter\n"
5321 "Name of a prefix-list\n")
5323 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5324 return pim_rp_cmd_worker(pim
, vty
, argv
[3]->arg
, NULL
, argv
[5]->arg
);
5327 static int pim_no_rp_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
5328 const char *rp
, const char *group
,
5331 int result
= pim_rp_del(pim
, rp
, group
, plist
);
5333 if (result
== PIM_GROUP_BAD_ADDRESS
) {
5334 vty_out(vty
, "%% Bad group address specified: %s\n", group
);
5335 return CMD_WARNING_CONFIG_FAILED
;
5338 if (result
== PIM_RP_BAD_ADDRESS
) {
5339 vty_out(vty
, "%% Bad RP address specified: %s\n", rp
);
5340 return CMD_WARNING_CONFIG_FAILED
;
5343 if (result
== PIM_RP_NOT_FOUND
) {
5344 vty_out(vty
, "%% Unable to find specified RP\n");
5345 return CMD_WARNING_CONFIG_FAILED
;
5351 DEFUN (no_ip_pim_rp
,
5353 "no ip pim rp A.B.C.D [A.B.C.D/M]",
5356 "pim multicast routing\n"
5358 "ip address of RP\n"
5359 "Group Address range to cover\n")
5361 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5362 int idx_ipv4
= 4, idx_group
= 0;
5364 if (argv_find(argv
, argc
, "A.B.C.D/M", &idx_group
))
5365 return pim_no_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
,
5366 argv
[idx_group
]->arg
, NULL
);
5368 return pim_no_rp_cmd_worker(pim
, vty
, argv
[idx_ipv4
]->arg
, NULL
,
5372 DEFUN (no_ip_pim_rp_prefix_list
,
5373 no_ip_pim_rp_prefix_list_cmd
,
5374 "no ip pim rp A.B.C.D prefix-list WORD",
5377 "pim multicast routing\n"
5379 "ip address of RP\n"
5380 "group prefix-list filter\n"
5381 "Name of a prefix-list\n")
5383 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5384 return pim_no_rp_cmd_worker(pim
, vty
, argv
[4]->arg
, NULL
, argv
[6]->arg
);
5387 static int pim_ssm_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
5390 int result
= pim_ssm_range_set(pim
, pim
->vrf_id
, plist
);
5392 if (result
== PIM_SSM_ERR_NONE
)
5396 case PIM_SSM_ERR_NO_VRF
:
5397 vty_out(vty
, "%% VRF doesn't exist\n");
5399 case PIM_SSM_ERR_DUP
:
5400 vty_out(vty
, "%% duplicate config\n");
5403 vty_out(vty
, "%% ssm range config failed\n");
5406 return CMD_WARNING_CONFIG_FAILED
;
5409 DEFUN (ip_pim_ssm_prefix_list
,
5410 ip_pim_ssm_prefix_list_cmd
,
5411 "ip pim ssm prefix-list WORD",
5413 "pim multicast routing\n"
5414 "Source Specific Multicast\n"
5415 "group range prefix-list filter\n"
5416 "Name of a prefix-list\n")
5418 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5419 return pim_ssm_cmd_worker(pim
, vty
, argv
[4]->arg
);
5422 DEFUN (no_ip_pim_ssm_prefix_list
,
5423 no_ip_pim_ssm_prefix_list_cmd
,
5424 "no ip pim ssm prefix-list",
5427 "pim multicast routing\n"
5428 "Source Specific Multicast\n"
5429 "group range prefix-list filter\n")
5431 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5432 return pim_ssm_cmd_worker(pim
, vty
, NULL
);
5435 DEFUN (no_ip_pim_ssm_prefix_list_name
,
5436 no_ip_pim_ssm_prefix_list_name_cmd
,
5437 "no ip pim ssm prefix-list WORD",
5440 "pim multicast routing\n"
5441 "Source Specific Multicast\n"
5442 "group range prefix-list filter\n"
5443 "Name of a prefix-list\n")
5445 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5446 struct pim_ssm
*ssm
= pim
->ssm_info
;
5448 if (ssm
->plist_name
&& !strcmp(ssm
->plist_name
, argv
[5]->arg
))
5449 return pim_ssm_cmd_worker(pim
, vty
, NULL
);
5451 vty_out(vty
, "%% pim ssm prefix-list %s doesn't exist\n", argv
[5]->arg
);
5453 return CMD_WARNING_CONFIG_FAILED
;
5456 static void ip_pim_ssm_show_group_range(struct pim_instance
*pim
,
5457 struct vty
*vty
, u_char uj
)
5459 struct pim_ssm
*ssm
= pim
->ssm_info
;
5460 const char *range_str
=
5461 ssm
->plist_name
? ssm
->plist_name
: PIM_SSM_STANDARD_RANGE
;
5465 json
= json_object_new_object();
5466 json_object_string_add(json
, "ssmGroups", range_str
);
5467 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
5468 json
, JSON_C_TO_STRING_PRETTY
));
5469 json_object_free(json
);
5471 vty_out(vty
, "SSM group range : %s\n", range_str
);
5474 DEFUN (show_ip_pim_ssm_range
,
5475 show_ip_pim_ssm_range_cmd
,
5476 "show ip pim [vrf NAME] group-type [json]",
5485 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5486 u_char uj
= use_json(argc
, argv
);
5491 ip_pim_ssm_show_group_range(vrf
->info
, vty
, uj
);
5496 static void ip_pim_ssm_show_group_type(struct pim_instance
*pim
,
5497 struct vty
*vty
, u_char uj
,
5500 struct in_addr group_addr
;
5501 const char *type_str
;
5504 result
= inet_pton(AF_INET
, group
, &group_addr
);
5506 type_str
= "invalid";
5508 if (pim_is_group_224_4(group_addr
))
5510 pim_is_grp_ssm(pim
, group_addr
) ? "SSM" : "ASM";
5512 type_str
= "not-multicast";
5517 json
= json_object_new_object();
5518 json_object_string_add(json
, "groupType", type_str
);
5519 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
5520 json
, JSON_C_TO_STRING_PRETTY
));
5521 json_object_free(json
);
5523 vty_out(vty
, "Group type : %s\n", type_str
);
5526 DEFUN (show_ip_pim_group_type
,
5527 show_ip_pim_group_type_cmd
,
5528 "show ip pim [vrf NAME] group-type A.B.C.D [json]",
5533 "multicast group type\n"
5538 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5539 u_char uj
= use_json(argc
, argv
);
5544 argv_find(argv
, argc
, "A.B.C.D", &idx
);
5545 ip_pim_ssm_show_group_type(vrf
->info
, vty
, uj
, argv
[idx
]->arg
);
5550 DEFUN_HIDDEN (ip_multicast_routing
,
5551 ip_multicast_routing_cmd
,
5552 "ip multicast-routing",
5554 "Enable IP multicast forwarding\n")
5559 DEFUN_HIDDEN (no_ip_multicast_routing
,
5560 no_ip_multicast_routing_cmd
,
5561 "no ip multicast-routing",
5564 "Enable IP multicast forwarding\n")
5567 "Command is Disabled and will be removed in a future version\n");
5573 "ip ssmpingd [A.B.C.D]",
5578 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5581 struct in_addr source_addr
;
5582 const char *source_str
= (argc
== 3) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
5584 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
5586 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n",
5587 source_str
, errno
, safe_strerror(errno
));
5588 return CMD_WARNING_CONFIG_FAILED
;
5591 result
= pim_ssmpingd_start(pim
, source_addr
);
5593 vty_out(vty
, "%% Failure starting ssmpingd for source %s: %d\n",
5594 source_str
, result
);
5595 return CMD_WARNING_CONFIG_FAILED
;
5601 DEFUN (no_ip_ssmpingd
,
5603 "no ip ssmpingd [A.B.C.D]",
5609 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5612 struct in_addr source_addr
;
5613 const char *source_str
= (argc
== 4) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
5615 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
5617 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n",
5618 source_str
, errno
, safe_strerror(errno
));
5619 return CMD_WARNING_CONFIG_FAILED
;
5622 result
= pim_ssmpingd_stop(pim
, source_addr
);
5624 vty_out(vty
, "%% Failure stopping ssmpingd for source %s: %d\n",
5625 source_str
, result
);
5626 return CMD_WARNING_CONFIG_FAILED
;
5636 "pim multicast routing\n"
5637 "Enable PIM ECMP \n")
5639 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5640 qpim_ecmp_enable
= 1;
5645 DEFUN (no_ip_pim_ecmp
,
5650 "pim multicast routing\n"
5651 "Disable PIM ECMP \n")
5653 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5654 qpim_ecmp_enable
= 0;
5659 DEFUN (ip_pim_ecmp_rebalance
,
5660 ip_pim_ecmp_rebalance_cmd
,
5661 "ip pim ecmp rebalance",
5663 "pim multicast routing\n"
5664 "Enable PIM ECMP \n"
5665 "Enable PIM ECMP Rebalance\n")
5667 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5668 qpim_ecmp_enable
= 1;
5669 qpim_ecmp_rebalance_enable
= 1;
5674 DEFUN (no_ip_pim_ecmp_rebalance
,
5675 no_ip_pim_ecmp_rebalance_cmd
,
5676 "no ip pim ecmp rebalance",
5679 "pim multicast routing\n"
5680 "Disable PIM ECMP \n"
5681 "Disable PIM ECMP Rebalance\n")
5683 PIM_DECLVAR_CONTEXT(vrf
, pim
);
5684 qpim_ecmp_rebalance_enable
= 0;
5689 static int pim_cmd_igmp_start(struct vty
*vty
, struct interface
*ifp
)
5691 struct pim_interface
*pim_ifp
;
5692 uint8_t need_startup
= 0;
5694 pim_ifp
= ifp
->info
;
5697 pim_ifp
= pim_if_new(ifp
, 1 /* igmp=true */, 0 /* pim=false */);
5699 vty_out(vty
, "Could not enable IGMP on interface %s\n",
5701 return CMD_WARNING_CONFIG_FAILED
;
5705 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
5706 PIM_IF_DO_IGMP(pim_ifp
->options
);
5711 /* 'ip igmp' executed multiple times, with need_startup
5712 avoid multiple if add all and membership refresh */
5714 pim_if_addr_add_all(ifp
);
5715 pim_if_membership_refresh(ifp
);
5721 DEFUN (interface_ip_igmp
,
5722 interface_ip_igmp_cmd
,
5727 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5729 return pim_cmd_igmp_start(vty
, ifp
);
5732 DEFUN (interface_no_ip_igmp
,
5733 interface_no_ip_igmp_cmd
,
5739 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5740 struct pim_interface
*pim_ifp
= ifp
->info
;
5745 PIM_IF_DONT_IGMP(pim_ifp
->options
);
5747 pim_if_membership_clear(ifp
);
5749 pim_if_addr_del_all_igmp(ifp
);
5751 if (!PIM_IF_TEST_PIM(pim_ifp
->options
)) {
5758 DEFUN (interface_ip_igmp_join
,
5759 interface_ip_igmp_join_cmd
,
5760 "ip igmp join A.B.C.D A.B.C.D",
5763 "IGMP join multicast group\n"
5764 "Multicast group address\n"
5767 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5770 const char *group_str
;
5771 const char *source_str
;
5772 struct in_addr group_addr
;
5773 struct in_addr source_addr
;
5777 group_str
= argv
[idx_ipv4
]->arg
;
5778 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
5780 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", group_str
,
5781 errno
, safe_strerror(errno
));
5782 return CMD_WARNING_CONFIG_FAILED
;
5785 /* Source address */
5786 source_str
= argv
[idx_ipv4_2
]->arg
;
5787 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
5789 vty_out(vty
, "Bad source address %s: errno=%d: %s\n",
5790 source_str
, errno
, safe_strerror(errno
));
5791 return CMD_WARNING_CONFIG_FAILED
;
5794 CMD_FERR_RETURN(pim_if_igmp_join_add(ifp
, group_addr
, source_addr
),
5795 "Failure joining IGMP group: $ERR");
5800 DEFUN (interface_no_ip_igmp_join
,
5801 interface_no_ip_igmp_join_cmd
,
5802 "no ip igmp join A.B.C.D A.B.C.D",
5806 "IGMP join multicast group\n"
5807 "Multicast group address\n"
5810 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5813 const char *group_str
;
5814 const char *source_str
;
5815 struct in_addr group_addr
;
5816 struct in_addr source_addr
;
5820 group_str
= argv
[idx_ipv4
]->arg
;
5821 result
= inet_pton(AF_INET
, group_str
, &group_addr
);
5823 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", group_str
,
5824 errno
, safe_strerror(errno
));
5825 return CMD_WARNING_CONFIG_FAILED
;
5828 /* Source address */
5829 source_str
= argv
[idx_ipv4_2
]->arg
;
5830 result
= inet_pton(AF_INET
, source_str
, &source_addr
);
5832 vty_out(vty
, "Bad source address %s: errno=%d: %s\n",
5833 source_str
, errno
, safe_strerror(errno
));
5834 return CMD_WARNING_CONFIG_FAILED
;
5837 result
= pim_if_igmp_join_del(ifp
, group_addr
, source_addr
);
5840 "%% Failure leaving IGMP group %s source %s on interface %s: %d\n",
5841 group_str
, source_str
, ifp
->name
, result
);
5842 return CMD_WARNING_CONFIG_FAILED
;
5849 CLI reconfiguration affects the interface level (struct pim_interface).
5850 This function propagates the reconfiguration to every active socket
5853 static void igmp_sock_query_interval_reconfig(struct igmp_sock
*igmp
)
5855 struct interface
*ifp
;
5856 struct pim_interface
*pim_ifp
;
5860 /* other querier present? */
5862 if (igmp
->t_other_querier_timer
)
5865 /* this is the querier */
5867 zassert(igmp
->interface
);
5868 zassert(igmp
->interface
->info
);
5870 ifp
= igmp
->interface
;
5871 pim_ifp
= ifp
->info
;
5873 if (PIM_DEBUG_IGMP_TRACE
) {
5874 char ifaddr_str
[INET_ADDRSTRLEN
];
5875 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
5876 sizeof(ifaddr_str
));
5877 zlog_debug("%s: Querier %s on %s reconfig query_interval=%d",
5878 __PRETTY_FUNCTION__
, ifaddr_str
, ifp
->name
,
5879 pim_ifp
->igmp_default_query_interval
);
5883 igmp_startup_mode_on() will reset QQI:
5885 igmp->querier_query_interval = pim_ifp->igmp_default_query_interval;
5887 igmp_startup_mode_on(igmp
);
5890 static void igmp_sock_query_reschedule(struct igmp_sock
*igmp
)
5892 if (igmp
->t_igmp_query_timer
) {
5893 /* other querier present */
5894 zassert(igmp
->t_igmp_query_timer
);
5895 zassert(!igmp
->t_other_querier_timer
);
5897 pim_igmp_general_query_off(igmp
);
5898 pim_igmp_general_query_on(igmp
);
5900 zassert(igmp
->t_igmp_query_timer
);
5901 zassert(!igmp
->t_other_querier_timer
);
5903 /* this is the querier */
5905 zassert(!igmp
->t_igmp_query_timer
);
5906 zassert(igmp
->t_other_querier_timer
);
5908 pim_igmp_other_querier_timer_off(igmp
);
5909 pim_igmp_other_querier_timer_on(igmp
);
5911 zassert(!igmp
->t_igmp_query_timer
);
5912 zassert(igmp
->t_other_querier_timer
);
5916 static void change_query_interval(struct pim_interface
*pim_ifp
,
5919 struct listnode
*sock_node
;
5920 struct igmp_sock
*igmp
;
5922 pim_ifp
->igmp_default_query_interval
= query_interval
;
5924 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
5925 igmp_sock_query_interval_reconfig(igmp
);
5926 igmp_sock_query_reschedule(igmp
);
5930 static void change_query_max_response_time(struct pim_interface
*pim_ifp
,
5931 int query_max_response_time_dsec
)
5933 struct listnode
*sock_node
;
5934 struct igmp_sock
*igmp
;
5936 pim_ifp
->igmp_query_max_response_time_dsec
=
5937 query_max_response_time_dsec
;
5940 Below we modify socket/group/source timers in order to quickly
5941 reflect the change. Otherwise, those timers would eventually catch
5945 /* scan all sockets */
5946 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
, igmp
)) {
5947 struct listnode
*grp_node
;
5948 struct igmp_group
*grp
;
5950 /* reschedule socket general query */
5951 igmp_sock_query_reschedule(igmp
);
5953 /* scan socket groups */
5954 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
, grp_node
,
5956 struct listnode
*src_node
;
5957 struct igmp_source
*src
;
5959 /* reset group timers for groups in EXCLUDE mode */
5960 if (grp
->group_filtermode_isexcl
) {
5961 igmp_group_reset_gmi(grp
);
5964 /* scan group sources */
5965 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
,
5968 /* reset source timers for sources with running
5970 if (src
->t_source_timer
) {
5971 igmp_source_reset_gmi(igmp
, grp
, src
);
5978 #define IGMP_QUERY_INTERVAL_MIN (1)
5979 #define IGMP_QUERY_INTERVAL_MAX (1800)
5981 DEFUN (interface_ip_igmp_query_interval
,
5982 interface_ip_igmp_query_interval_cmd
,
5983 "ip igmp query-interval (1-1800)",
5986 IFACE_IGMP_QUERY_INTERVAL_STR
5987 "Query interval in seconds\n")
5989 VTY_DECLVAR_CONTEXT(interface
, ifp
);
5990 struct pim_interface
*pim_ifp
= ifp
->info
;
5992 int query_interval_dsec
;
5996 ret
= pim_cmd_igmp_start(vty
, ifp
);
5997 if (ret
!= CMD_SUCCESS
)
5999 pim_ifp
= ifp
->info
;
6002 query_interval
= atoi(argv
[3]->arg
);
6003 query_interval_dsec
= 10 * query_interval
;
6006 It seems we don't need to check bounds since command.c does it
6007 already, but we verify them anyway for extra safety.
6009 if (query_interval
< IGMP_QUERY_INTERVAL_MIN
) {
6011 "General query interval %d lower than minimum %d\n",
6012 query_interval
, IGMP_QUERY_INTERVAL_MIN
);
6013 return CMD_WARNING_CONFIG_FAILED
;
6015 if (query_interval
> IGMP_QUERY_INTERVAL_MAX
) {
6017 "General query interval %d higher than maximum %d\n",
6018 query_interval
, IGMP_QUERY_INTERVAL_MAX
);
6019 return CMD_WARNING_CONFIG_FAILED
;
6022 if (query_interval_dsec
<= pim_ifp
->igmp_query_max_response_time_dsec
) {
6024 "Can't set general query interval %d dsec <= query max response time %d dsec.\n",
6025 query_interval_dsec
,
6026 pim_ifp
->igmp_query_max_response_time_dsec
);
6027 return CMD_WARNING_CONFIG_FAILED
;
6030 change_query_interval(pim_ifp
, query_interval
);
6035 DEFUN (interface_no_ip_igmp_query_interval
,
6036 interface_no_ip_igmp_query_interval_cmd
,
6037 "no ip igmp query-interval",
6041 IFACE_IGMP_QUERY_INTERVAL_STR
)
6043 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6044 struct pim_interface
*pim_ifp
= ifp
->info
;
6045 int default_query_interval_dsec
;
6050 default_query_interval_dsec
= IGMP_GENERAL_QUERY_INTERVAL
* 10;
6052 if (default_query_interval_dsec
6053 <= pim_ifp
->igmp_query_max_response_time_dsec
) {
6055 "Can't set default general query interval %d dsec <= query max response time %d dsec.\n",
6056 default_query_interval_dsec
,
6057 pim_ifp
->igmp_query_max_response_time_dsec
);
6058 return CMD_WARNING_CONFIG_FAILED
;
6061 change_query_interval(pim_ifp
, IGMP_GENERAL_QUERY_INTERVAL
);
6066 DEFUN (interface_ip_igmp_version
,
6067 interface_ip_igmp_version_cmd
,
6068 "ip igmp version (2-3)",
6072 "IGMP version number\n")
6074 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6075 struct pim_interface
*pim_ifp
= ifp
->info
;
6076 int igmp_version
, old_version
= 0;
6080 ret
= pim_cmd_igmp_start(vty
, ifp
);
6081 if (ret
!= CMD_SUCCESS
)
6083 pim_ifp
= ifp
->info
;
6086 igmp_version
= atoi(argv
[3]->arg
);
6087 old_version
= pim_ifp
->igmp_version
;
6088 pim_ifp
->igmp_version
= igmp_version
;
6090 // Check if IGMP is Enabled otherwise, enable on interface
6091 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
6092 PIM_IF_DO_IGMP(pim_ifp
->options
);
6093 pim_if_addr_add_all(ifp
);
6094 pim_if_membership_refresh(ifp
);
6095 old_version
= igmp_version
;
6096 // avoid refreshing membership again.
6098 /* Current and new version is different refresh existing
6099 membership. Going from 3 -> 2 or 2 -> 3. */
6100 if (old_version
!= igmp_version
)
6101 pim_if_membership_refresh(ifp
);
6106 DEFUN (interface_no_ip_igmp_version
,
6107 interface_no_ip_igmp_version_cmd
,
6108 "no ip igmp version (2-3)",
6113 "IGMP version number\n")
6115 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6116 struct pim_interface
*pim_ifp
= ifp
->info
;
6121 pim_ifp
->igmp_version
= IGMP_DEFAULT_VERSION
;
6126 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
6127 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
6129 DEFUN (interface_ip_igmp_query_max_response_time
,
6130 interface_ip_igmp_query_max_response_time_cmd
,
6131 "ip igmp query-max-response-time (10-250)",
6134 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
6135 "Query response value in deci-seconds\n")
6137 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6138 struct pim_interface
*pim_ifp
= ifp
->info
;
6139 int query_max_response_time
;
6143 ret
= pim_cmd_igmp_start(vty
, ifp
);
6144 if (ret
!= CMD_SUCCESS
)
6146 pim_ifp
= ifp
->info
;
6149 query_max_response_time
= atoi(argv
[3]->arg
);
6151 if (query_max_response_time
6152 >= pim_ifp
->igmp_default_query_interval
* 10) {
6154 "Can't set query max response time %d sec >= general query interval %d sec\n",
6155 query_max_response_time
,
6156 pim_ifp
->igmp_default_query_interval
);
6157 return CMD_WARNING_CONFIG_FAILED
;
6160 change_query_max_response_time(pim_ifp
, query_max_response_time
);
6165 DEFUN (interface_no_ip_igmp_query_max_response_time
,
6166 interface_no_ip_igmp_query_max_response_time_cmd
,
6167 "no ip igmp query-max-response-time (10-250)",
6171 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
6172 "Time for response in deci-seconds\n")
6174 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6175 struct pim_interface
*pim_ifp
= ifp
->info
;
6180 change_query_max_response_time(pim_ifp
,
6181 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
6186 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
6187 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
6189 DEFUN_HIDDEN (interface_ip_igmp_query_max_response_time_dsec
,
6190 interface_ip_igmp_query_max_response_time_dsec_cmd
,
6191 "ip igmp query-max-response-time-dsec (10-250)",
6194 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
6195 "Query response value in deciseconds\n")
6197 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6198 struct pim_interface
*pim_ifp
= ifp
->info
;
6199 int query_max_response_time_dsec
;
6200 int default_query_interval_dsec
;
6204 ret
= pim_cmd_igmp_start(vty
, ifp
);
6205 if (ret
!= CMD_SUCCESS
)
6207 pim_ifp
= ifp
->info
;
6210 query_max_response_time_dsec
= atoi(argv
[4]->arg
);
6212 default_query_interval_dsec
= 10 * pim_ifp
->igmp_default_query_interval
;
6214 if (query_max_response_time_dsec
>= default_query_interval_dsec
) {
6216 "Can't set query max response time %d dsec >= general query interval %d dsec\n",
6217 query_max_response_time_dsec
,
6218 default_query_interval_dsec
);
6219 return CMD_WARNING_CONFIG_FAILED
;
6222 change_query_max_response_time(pim_ifp
, query_max_response_time_dsec
);
6227 DEFUN_HIDDEN (interface_no_ip_igmp_query_max_response_time_dsec
,
6228 interface_no_ip_igmp_query_max_response_time_dsec_cmd
,
6229 "no ip igmp query-max-response-time-dsec",
6233 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
)
6235 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6236 struct pim_interface
*pim_ifp
= ifp
->info
;
6241 change_query_max_response_time(pim_ifp
,
6242 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
6247 DEFUN (interface_ip_pim_drprio
,
6248 interface_ip_pim_drprio_cmd
,
6249 "ip pim drpriority (1-4294967295)",
6252 "Set the Designated Router Election Priority\n"
6253 "Value of the new DR Priority\n")
6255 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6257 struct pim_interface
*pim_ifp
= ifp
->info
;
6258 uint32_t old_dr_prio
;
6261 vty_out(vty
, "Please enable PIM on interface, first\n");
6262 return CMD_WARNING_CONFIG_FAILED
;
6265 old_dr_prio
= pim_ifp
->pim_dr_priority
;
6267 pim_ifp
->pim_dr_priority
= strtol(argv
[idx_number
]->arg
, NULL
, 10);
6269 if (old_dr_prio
!= pim_ifp
->pim_dr_priority
) {
6270 if (pim_if_dr_election(ifp
))
6271 pim_hello_restart_now(ifp
);
6277 DEFUN (interface_no_ip_pim_drprio
,
6278 interface_no_ip_pim_drprio_cmd
,
6279 "no ip pim drpriority [(1-4294967295)]",
6283 "Revert the Designated Router Priority to default\n"
6284 "Old Value of the Priority\n")
6286 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6287 struct pim_interface
*pim_ifp
= ifp
->info
;
6290 vty_out(vty
, "Pim not enabled on this interface\n");
6291 return CMD_WARNING_CONFIG_FAILED
;
6294 if (pim_ifp
->pim_dr_priority
!= PIM_DEFAULT_DR_PRIORITY
) {
6295 pim_ifp
->pim_dr_priority
= PIM_DEFAULT_DR_PRIORITY
;
6296 if (pim_if_dr_election(ifp
))
6297 pim_hello_restart_now(ifp
);
6303 static int pim_cmd_interface_add(struct interface
*ifp
)
6305 struct pim_interface
*pim_ifp
= ifp
->info
;
6308 pim_ifp
= pim_if_new(ifp
, 0 /* igmp=false */, 1 /* pim=true */);
6313 PIM_IF_DO_PIM(pim_ifp
->options
);
6316 pim_if_addr_add_all(ifp
);
6317 pim_if_membership_refresh(ifp
);
6321 DEFUN_HIDDEN (interface_ip_pim_ssm
,
6322 interface_ip_pim_ssm_cmd
,
6328 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6330 if (!pim_cmd_interface_add(ifp
)) {
6331 vty_out(vty
, "Could not enable PIM SM on interface\n");
6332 return CMD_WARNING_CONFIG_FAILED
;
6336 "WARN: Enabled PIM SM on interface; configure PIM SSM "
6337 "range if needed\n");
6341 DEFUN (interface_ip_pim_sm
,
6342 interface_ip_pim_sm_cmd
,
6348 struct pim_interface
*pim_ifp
;
6350 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6351 if (!pim_cmd_interface_add(ifp
)) {
6352 vty_out(vty
, "Could not enable PIM SM on interface\n");
6353 return CMD_WARNING_CONFIG_FAILED
;
6356 pim_ifp
= ifp
->info
;
6358 pim_if_create_pimreg(pim_ifp
->pim
);
6363 static int pim_cmd_interface_delete(struct interface
*ifp
)
6365 struct pim_interface
*pim_ifp
= ifp
->info
;
6370 PIM_IF_DONT_PIM(pim_ifp
->options
);
6372 pim_if_membership_clear(ifp
);
6375 pim_sock_delete() removes all neighbors from
6376 pim_ifp->pim_neighbor_list.
6378 pim_sock_delete(ifp
, "pim unconfigured on interface");
6380 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
6381 pim_if_addr_del_all(ifp
);
6388 DEFUN_HIDDEN (interface_no_ip_pim_ssm
,
6389 interface_no_ip_pim_ssm_cmd
,
6396 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6397 if (!pim_cmd_interface_delete(ifp
)) {
6398 vty_out(vty
, "Unable to delete interface information\n");
6399 return CMD_WARNING_CONFIG_FAILED
;
6405 DEFUN (interface_no_ip_pim_sm
,
6406 interface_no_ip_pim_sm_cmd
,
6413 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6414 if (!pim_cmd_interface_delete(ifp
)) {
6415 vty_out(vty
, "Unable to delete interface information\n");
6416 return CMD_WARNING_CONFIG_FAILED
;
6423 DEFUN(interface_ip_pim_boundary_oil
,
6424 interface_ip_pim_boundary_oil_cmd
,
6425 "ip multicast boundary oil WORD",
6427 "Generic multicast configuration options\n"
6428 "Define multicast boundary\n"
6429 "Filter OIL by group using prefix list\n"
6430 "Prefix list to filter OIL with\n")
6432 VTY_DECLVAR_CONTEXT(interface
, iif
);
6433 struct pim_interface
*pim_ifp
;
6436 argv_find(argv
, argc
, "WORD", &idx
);
6438 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6440 if (pim_ifp
->boundary_oil_plist
)
6441 XFREE(MTYPE_PIM_INTERFACE
, pim_ifp
->boundary_oil_plist
);
6443 pim_ifp
->boundary_oil_plist
=
6444 XSTRDUP(MTYPE_PIM_INTERFACE
, argv
[idx
]->arg
);
6446 /* Interface will be pruned from OIL on next Join */
6450 DEFUN(interface_no_ip_pim_boundary_oil
,
6451 interface_no_ip_pim_boundary_oil_cmd
,
6452 "no ip multicast boundary oil [WORD]",
6455 "Generic multicast configuration options\n"
6456 "Define multicast boundary\n"
6457 "Filter OIL by group using prefix list\n"
6458 "Prefix list to filter OIL with\n")
6460 VTY_DECLVAR_CONTEXT(interface
, iif
);
6461 struct pim_interface
*pim_ifp
;
6464 argv_find(argv
, argc
, "WORD", &idx
);
6466 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6468 if (pim_ifp
->boundary_oil_plist
)
6469 XFREE(MTYPE_PIM_INTERFACE
, pim_ifp
->boundary_oil_plist
);
6474 DEFUN (interface_ip_mroute
,
6475 interface_ip_mroute_cmd
,
6476 "ip mroute INTERFACE A.B.C.D",
6478 "Add multicast route\n"
6479 "Outgoing interface name\n"
6482 VTY_DECLVAR_CONTEXT(interface
, iif
);
6483 struct pim_interface
*pim_ifp
;
6484 struct pim_instance
*pim
;
6485 int idx_interface
= 2;
6487 struct interface
*oif
;
6488 const char *oifname
;
6489 const char *grp_str
;
6490 struct in_addr grp_addr
;
6491 struct in_addr src_addr
;
6494 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6497 oifname
= argv
[idx_interface
]->arg
;
6498 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
6500 vty_out(vty
, "No such interface name %s\n", oifname
);
6504 grp_str
= argv
[idx_ipv4
]->arg
;
6505 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
6507 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
6508 errno
, safe_strerror(errno
));
6512 src_addr
.s_addr
= INADDR_ANY
;
6514 if (pim_static_add(pim
, iif
, oif
, grp_addr
, src_addr
)) {
6515 vty_out(vty
, "Failed to add route\n");
6522 DEFUN (interface_ip_mroute_source
,
6523 interface_ip_mroute_source_cmd
,
6524 "ip mroute INTERFACE A.B.C.D A.B.C.D",
6526 "Add multicast route\n"
6527 "Outgoing interface name\n"
6531 VTY_DECLVAR_CONTEXT(interface
, iif
);
6532 struct pim_interface
*pim_ifp
;
6533 struct pim_instance
*pim
;
6534 int idx_interface
= 2;
6537 struct interface
*oif
;
6538 const char *oifname
;
6539 const char *grp_str
;
6540 struct in_addr grp_addr
;
6541 const char *src_str
;
6542 struct in_addr src_addr
;
6545 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6548 oifname
= argv
[idx_interface
]->arg
;
6549 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
6551 vty_out(vty
, "No such interface name %s\n", oifname
);
6555 grp_str
= argv
[idx_ipv4
]->arg
;
6556 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
6558 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
6559 errno
, safe_strerror(errno
));
6563 src_str
= argv
[idx_ipv4_2
]->arg
;
6564 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
6566 vty_out(vty
, "Bad source address %s: errno=%d: %s\n", src_str
,
6567 errno
, safe_strerror(errno
));
6571 if (pim_static_add(pim
, iif
, oif
, grp_addr
, src_addr
)) {
6572 vty_out(vty
, "Failed to add route\n");
6579 DEFUN (interface_no_ip_mroute
,
6580 interface_no_ip_mroute_cmd
,
6581 "no ip mroute INTERFACE A.B.C.D",
6584 "Add multicast route\n"
6585 "Outgoing interface name\n"
6588 VTY_DECLVAR_CONTEXT(interface
, iif
);
6589 struct pim_interface
*pim_ifp
;
6590 struct pim_instance
*pim
;
6591 int idx_interface
= 3;
6593 struct interface
*oif
;
6594 const char *oifname
;
6595 const char *grp_str
;
6596 struct in_addr grp_addr
;
6597 struct in_addr src_addr
;
6600 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6603 oifname
= argv
[idx_interface
]->arg
;
6604 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
6606 vty_out(vty
, "No such interface name %s\n", oifname
);
6610 grp_str
= argv
[idx_ipv4
]->arg
;
6611 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
6613 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
6614 errno
, safe_strerror(errno
));
6618 src_addr
.s_addr
= INADDR_ANY
;
6620 if (pim_static_del(pim
, iif
, oif
, grp_addr
, src_addr
)) {
6621 vty_out(vty
, "Failed to remove route\n");
6628 DEFUN (interface_no_ip_mroute_source
,
6629 interface_no_ip_mroute_source_cmd
,
6630 "no ip mroute INTERFACE A.B.C.D A.B.C.D",
6633 "Add multicast route\n"
6634 "Outgoing interface name\n"
6638 VTY_DECLVAR_CONTEXT(interface
, iif
);
6639 struct pim_interface
*pim_ifp
;
6640 struct pim_instance
*pim
;
6641 int idx_interface
= 3;
6644 struct interface
*oif
;
6645 const char *oifname
;
6646 const char *grp_str
;
6647 struct in_addr grp_addr
;
6648 const char *src_str
;
6649 struct in_addr src_addr
;
6652 PIM_GET_PIM_INTERFACE(pim_ifp
, iif
);
6655 oifname
= argv
[idx_interface
]->arg
;
6656 oif
= if_lookup_by_name(oifname
, pim
->vrf_id
);
6658 vty_out(vty
, "No such interface name %s\n", oifname
);
6662 grp_str
= argv
[idx_ipv4
]->arg
;
6663 result
= inet_pton(AF_INET
, grp_str
, &grp_addr
);
6665 vty_out(vty
, "Bad group address %s: errno=%d: %s\n", grp_str
,
6666 errno
, safe_strerror(errno
));
6670 src_str
= argv
[idx_ipv4_2
]->arg
;
6671 result
= inet_pton(AF_INET
, src_str
, &src_addr
);
6673 vty_out(vty
, "Bad source address %s: errno=%d: %s\n", src_str
,
6674 errno
, safe_strerror(errno
));
6678 if (pim_static_del(pim
, iif
, oif
, grp_addr
, src_addr
)) {
6679 vty_out(vty
, "Failed to remove route\n");
6686 DEFUN (interface_ip_pim_hello
,
6687 interface_ip_pim_hello_cmd
,
6688 "ip pim hello (1-180) [(1-180)]",
6692 IFACE_PIM_HELLO_TIME_STR
6693 IFACE_PIM_HELLO_HOLD_STR
)
6695 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6698 struct pim_interface
*pim_ifp
= ifp
->info
;
6701 if (!pim_cmd_interface_add(ifp
)) {
6702 vty_out(vty
, "Could not enable PIM SM on interface\n");
6703 return CMD_WARNING_CONFIG_FAILED
;
6707 pim_ifp
= ifp
->info
;
6708 pim_ifp
->pim_hello_period
= strtol(argv
[idx_time
]->arg
, NULL
, 10);
6710 if (argc
== idx_hold
+ 1)
6711 pim_ifp
->pim_default_holdtime
=
6712 strtol(argv
[idx_hold
]->arg
, NULL
, 10);
6717 DEFUN (interface_no_ip_pim_hello
,
6718 interface_no_ip_pim_hello_cmd
,
6719 "no ip pim hello [(1-180) (1-180)]",
6724 IFACE_PIM_HELLO_TIME_STR
6725 IFACE_PIM_HELLO_HOLD_STR
)
6727 VTY_DECLVAR_CONTEXT(interface
, ifp
);
6728 struct pim_interface
*pim_ifp
= ifp
->info
;
6731 vty_out(vty
, "Pim not enabled on this interface\n");
6732 return CMD_WARNING_CONFIG_FAILED
;
6735 pim_ifp
->pim_hello_period
= PIM_DEFAULT_HELLO_PERIOD
;
6736 pim_ifp
->pim_default_holdtime
= -1;
6747 PIM_DO_DEBUG_IGMP_EVENTS
;
6748 PIM_DO_DEBUG_IGMP_PACKETS
;
6749 PIM_DO_DEBUG_IGMP_TRACE
;
6753 DEFUN (no_debug_igmp
,
6760 PIM_DONT_DEBUG_IGMP_EVENTS
;
6761 PIM_DONT_DEBUG_IGMP_PACKETS
;
6762 PIM_DONT_DEBUG_IGMP_TRACE
;
6767 DEFUN (debug_igmp_events
,
6768 debug_igmp_events_cmd
,
6769 "debug igmp events",
6772 DEBUG_IGMP_EVENTS_STR
)
6774 PIM_DO_DEBUG_IGMP_EVENTS
;
6778 DEFUN (no_debug_igmp_events
,
6779 no_debug_igmp_events_cmd
,
6780 "no debug igmp events",
6784 DEBUG_IGMP_EVENTS_STR
)
6786 PIM_DONT_DEBUG_IGMP_EVENTS
;
6791 DEFUN (debug_igmp_packets
,
6792 debug_igmp_packets_cmd
,
6793 "debug igmp packets",
6796 DEBUG_IGMP_PACKETS_STR
)
6798 PIM_DO_DEBUG_IGMP_PACKETS
;
6802 DEFUN (no_debug_igmp_packets
,
6803 no_debug_igmp_packets_cmd
,
6804 "no debug igmp packets",
6808 DEBUG_IGMP_PACKETS_STR
)
6810 PIM_DONT_DEBUG_IGMP_PACKETS
;
6815 DEFUN (debug_igmp_trace
,
6816 debug_igmp_trace_cmd
,
6820 DEBUG_IGMP_TRACE_STR
)
6822 PIM_DO_DEBUG_IGMP_TRACE
;
6826 DEFUN (no_debug_igmp_trace
,
6827 no_debug_igmp_trace_cmd
,
6828 "no debug igmp trace",
6832 DEBUG_IGMP_TRACE_STR
)
6834 PIM_DONT_DEBUG_IGMP_TRACE
;
6839 DEFUN (debug_mroute
,
6845 PIM_DO_DEBUG_MROUTE
;
6849 DEFUN (debug_mroute_detail
,
6850 debug_mroute_detail_cmd
,
6851 "debug mroute detail",
6856 PIM_DO_DEBUG_MROUTE_DETAIL
;
6860 DEFUN (no_debug_mroute
,
6861 no_debug_mroute_cmd
,
6867 PIM_DONT_DEBUG_MROUTE
;
6871 DEFUN (no_debug_mroute_detail
,
6872 no_debug_mroute_detail_cmd
,
6873 "no debug mroute detail",
6879 PIM_DONT_DEBUG_MROUTE_DETAIL
;
6883 DEFUN (debug_static
,
6889 PIM_DO_DEBUG_STATIC
;
6893 DEFUN (no_debug_static
,
6894 no_debug_static_cmd
,
6900 PIM_DONT_DEBUG_STATIC
;
6911 PIM_DO_DEBUG_PIM_EVENTS
;
6912 PIM_DO_DEBUG_PIM_PACKETS
;
6913 PIM_DO_DEBUG_PIM_TRACE
;
6914 PIM_DO_DEBUG_MSDP_EVENTS
;
6915 PIM_DO_DEBUG_MSDP_PACKETS
;
6919 DEFUN (no_debug_pim
,
6926 PIM_DONT_DEBUG_PIM_EVENTS
;
6927 PIM_DONT_DEBUG_PIM_PACKETS
;
6928 PIM_DONT_DEBUG_PIM_TRACE
;
6929 PIM_DONT_DEBUG_MSDP_EVENTS
;
6930 PIM_DONT_DEBUG_MSDP_PACKETS
;
6932 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
6933 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
6938 DEFUN (debug_pim_nht
,
6943 "Nexthop Tracking\n")
6945 PIM_DO_DEBUG_PIM_NHT
;
6949 DEFUN (no_debug_pim_nht
,
6950 no_debug_pim_nht_cmd
,
6955 "Nexthop Tracking\n")
6957 PIM_DONT_DEBUG_PIM_NHT
;
6961 DEFUN (debug_pim_nht_rp
,
6962 debug_pim_nht_rp_cmd
,
6966 "Nexthop Tracking\n"
6967 "RP Nexthop Tracking\n")
6969 PIM_DO_DEBUG_PIM_NHT_RP
;
6973 DEFUN (no_debug_pim_nht_rp
,
6974 no_debug_pim_nht_rp_cmd
,
6975 "no debug pim nht rp",
6979 "Nexthop Tracking\n"
6980 "RP Nexthop Tracking\n")
6982 PIM_DONT_DEBUG_PIM_NHT_RP
;
6986 DEFUN (debug_pim_events
,
6987 debug_pim_events_cmd
,
6991 DEBUG_PIM_EVENTS_STR
)
6993 PIM_DO_DEBUG_PIM_EVENTS
;
6997 DEFUN (no_debug_pim_events
,
6998 no_debug_pim_events_cmd
,
6999 "no debug pim events",
7003 DEBUG_PIM_EVENTS_STR
)
7005 PIM_DONT_DEBUG_PIM_EVENTS
;
7009 DEFUN (debug_pim_packets
,
7010 debug_pim_packets_cmd
,
7011 "debug pim packets [<hello|joins|register>]",
7014 DEBUG_PIM_PACKETS_STR
7015 DEBUG_PIM_HELLO_PACKETS_STR
7016 DEBUG_PIM_J_P_PACKETS_STR
7017 DEBUG_PIM_PIM_REG_PACKETS_STR
)
7020 if (argv_find(argv
, argc
, "hello", &idx
)) {
7021 PIM_DO_DEBUG_PIM_HELLO
;
7022 vty_out(vty
, "PIM Hello debugging is on\n");
7023 } else if (argv_find(argv
, argc
, "joins", &idx
)) {
7024 PIM_DO_DEBUG_PIM_J_P
;
7025 vty_out(vty
, "PIM Join/Prune debugging is on\n");
7026 } else if (argv_find(argv
, argc
, "register", &idx
)) {
7027 PIM_DO_DEBUG_PIM_REG
;
7028 vty_out(vty
, "PIM Register debugging is on\n");
7030 PIM_DO_DEBUG_PIM_PACKETS
;
7031 vty_out(vty
, "PIM Packet debugging is on \n");
7036 DEFUN (no_debug_pim_packets
,
7037 no_debug_pim_packets_cmd
,
7038 "no debug pim packets [<hello|joins|register>]",
7042 DEBUG_PIM_PACKETS_STR
7043 DEBUG_PIM_HELLO_PACKETS_STR
7044 DEBUG_PIM_J_P_PACKETS_STR
7045 DEBUG_PIM_PIM_REG_PACKETS_STR
)
7048 if (argv_find(argv
, argc
, "hello", &idx
)) {
7049 PIM_DONT_DEBUG_PIM_HELLO
;
7050 vty_out(vty
, "PIM Hello debugging is off \n");
7051 } else if (argv_find(argv
, argc
, "joins", &idx
)) {
7052 PIM_DONT_DEBUG_PIM_J_P
;
7053 vty_out(vty
, "PIM Join/Prune debugging is off \n");
7054 } else if (argv_find(argv
, argc
, "register", &idx
)) {
7055 PIM_DONT_DEBUG_PIM_REG
;
7056 vty_out(vty
, "PIM Register debugging is off\n");
7058 PIM_DONT_DEBUG_PIM_PACKETS
;
7064 DEFUN (debug_pim_packetdump_send
,
7065 debug_pim_packetdump_send_cmd
,
7066 "debug pim packet-dump send",
7069 DEBUG_PIM_PACKETDUMP_STR
7070 DEBUG_PIM_PACKETDUMP_SEND_STR
)
7072 PIM_DO_DEBUG_PIM_PACKETDUMP_SEND
;
7076 DEFUN (no_debug_pim_packetdump_send
,
7077 no_debug_pim_packetdump_send_cmd
,
7078 "no debug pim packet-dump send",
7082 DEBUG_PIM_PACKETDUMP_STR
7083 DEBUG_PIM_PACKETDUMP_SEND_STR
)
7085 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
7089 DEFUN (debug_pim_packetdump_recv
,
7090 debug_pim_packetdump_recv_cmd
,
7091 "debug pim packet-dump receive",
7094 DEBUG_PIM_PACKETDUMP_STR
7095 DEBUG_PIM_PACKETDUMP_RECV_STR
)
7097 PIM_DO_DEBUG_PIM_PACKETDUMP_RECV
;
7101 DEFUN (no_debug_pim_packetdump_recv
,
7102 no_debug_pim_packetdump_recv_cmd
,
7103 "no debug pim packet-dump receive",
7107 DEBUG_PIM_PACKETDUMP_STR
7108 DEBUG_PIM_PACKETDUMP_RECV_STR
)
7110 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
7114 DEFUN (debug_pim_trace
,
7115 debug_pim_trace_cmd
,
7119 DEBUG_PIM_TRACE_STR
)
7121 PIM_DO_DEBUG_PIM_TRACE
;
7125 DEFUN (debug_pim_trace_detail
,
7126 debug_pim_trace_detail_cmd
,
7127 "debug pim trace detail",
7131 "Detailed Information\n")
7133 PIM_DO_DEBUG_PIM_TRACE_DETAIL
;
7137 DEFUN (no_debug_pim_trace
,
7138 no_debug_pim_trace_cmd
,
7139 "no debug pim trace",
7143 DEBUG_PIM_TRACE_STR
)
7145 PIM_DONT_DEBUG_PIM_TRACE
;
7149 DEFUN (no_debug_pim_trace_detail
,
7150 no_debug_pim_trace_detail_cmd
,
7151 "no debug pim trace detail",
7156 "Detailed Information\n")
7158 PIM_DONT_DEBUG_PIM_TRACE_DETAIL
;
7162 DEFUN (debug_ssmpingd
,
7168 PIM_DO_DEBUG_SSMPINGD
;
7172 DEFUN (no_debug_ssmpingd
,
7173 no_debug_ssmpingd_cmd
,
7174 "no debug ssmpingd",
7179 PIM_DONT_DEBUG_SSMPINGD
;
7183 DEFUN (debug_pim_zebra
,
7184 debug_pim_zebra_cmd
,
7188 DEBUG_PIM_ZEBRA_STR
)
7194 DEFUN (no_debug_pim_zebra
,
7195 no_debug_pim_zebra_cmd
,
7196 "no debug pim zebra",
7200 DEBUG_PIM_ZEBRA_STR
)
7202 PIM_DONT_DEBUG_ZEBRA
;
7212 PIM_DO_DEBUG_MSDP_EVENTS
;
7213 PIM_DO_DEBUG_MSDP_PACKETS
;
7217 DEFUN (no_debug_msdp
,
7224 PIM_DONT_DEBUG_MSDP_EVENTS
;
7225 PIM_DONT_DEBUG_MSDP_PACKETS
;
7229 ALIAS(no_debug_msdp
, undebug_msdp_cmd
, "undebug msdp",
7230 UNDEBUG_STR DEBUG_MSDP_STR
)
7232 DEFUN (debug_msdp_events
,
7233 debug_msdp_events_cmd
,
7234 "debug msdp events",
7237 DEBUG_MSDP_EVENTS_STR
)
7239 PIM_DO_DEBUG_MSDP_EVENTS
;
7243 DEFUN (no_debug_msdp_events
,
7244 no_debug_msdp_events_cmd
,
7245 "no debug msdp events",
7249 DEBUG_MSDP_EVENTS_STR
)
7251 PIM_DONT_DEBUG_MSDP_EVENTS
;
7255 ALIAS(no_debug_msdp_events
, undebug_msdp_events_cmd
, "undebug msdp events",
7256 UNDEBUG_STR DEBUG_MSDP_STR DEBUG_MSDP_EVENTS_STR
)
7258 DEFUN (debug_msdp_packets
,
7259 debug_msdp_packets_cmd
,
7260 "debug msdp packets",
7263 DEBUG_MSDP_PACKETS_STR
)
7265 PIM_DO_DEBUG_MSDP_PACKETS
;
7269 DEFUN (no_debug_msdp_packets
,
7270 no_debug_msdp_packets_cmd
,
7271 "no debug msdp packets",
7275 DEBUG_MSDP_PACKETS_STR
)
7277 PIM_DONT_DEBUG_MSDP_PACKETS
;
7281 ALIAS(no_debug_msdp_packets
, undebug_msdp_packets_cmd
, "undebug msdp packets",
7282 UNDEBUG_STR DEBUG_MSDP_STR DEBUG_MSDP_PACKETS_STR
)
7284 DEFUN (debug_mtrace
,
7290 PIM_DO_DEBUG_MTRACE
;
7294 DEFUN (no_debug_mtrace
,
7295 no_debug_mtrace_cmd
,
7301 PIM_DONT_DEBUG_MTRACE
;
7305 DEFUN_NOSH (show_debugging_pim
,
7306 show_debugging_pim_cmd
,
7307 "show debugging [pim]",
7312 vty_out(vty
, "PIM debugging status\n");
7314 pim_debug_config_write(vty
);
7319 static int interface_pim_use_src_cmd_worker(struct vty
*vty
, const char *source
)
7322 struct in_addr source_addr
;
7323 int ret
= CMD_SUCCESS
;
7324 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7326 result
= inet_pton(AF_INET
, source
, &source_addr
);
7328 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", source
,
7329 errno
, safe_strerror(errno
));
7330 return CMD_WARNING_CONFIG_FAILED
;
7333 result
= pim_update_source_set(ifp
, source_addr
);
7337 case PIM_IFACE_NOT_FOUND
:
7338 ret
= CMD_WARNING_CONFIG_FAILED
;
7339 vty_out(vty
, "Pim not enabled on this interface\n");
7341 case PIM_UPDATE_SOURCE_DUP
:
7343 vty_out(vty
, "%% Source already set to %s\n", source
);
7346 ret
= CMD_WARNING_CONFIG_FAILED
;
7347 vty_out(vty
, "%% Source set failed\n");
7353 DEFUN (interface_pim_use_source
,
7354 interface_pim_use_source_cmd
,
7355 "ip pim use-source A.B.C.D",
7357 "pim multicast routing\n"
7358 "Configure primary IP address\n"
7359 "source ip address\n")
7361 return interface_pim_use_src_cmd_worker(vty
, argv
[3]->arg
);
7364 DEFUN (interface_no_pim_use_source
,
7365 interface_no_pim_use_source_cmd
,
7366 "no ip pim use-source [A.B.C.D]",
7369 "pim multicast routing\n"
7370 "Delete source IP address\n"
7371 "source ip address\n")
7373 return interface_pim_use_src_cmd_worker(vty
, "0.0.0.0");
7381 "Enables BFD support\n")
7383 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7384 struct pim_interface
*pim_ifp
= ifp
->info
;
7385 struct bfd_info
*bfd_info
= NULL
;
7388 if (!pim_cmd_interface_add(ifp
)) {
7389 vty_out(vty
, "Could not enable PIM SM on interface\n");
7393 pim_ifp
= ifp
->info
;
7395 bfd_info
= pim_ifp
->bfd_info
;
7397 if (!bfd_info
|| !CHECK_FLAG(bfd_info
->flags
, BFD_FLAG_PARAM_CFG
))
7398 pim_bfd_if_param_set(ifp
, BFD_DEF_MIN_RX
, BFD_DEF_MIN_TX
,
7399 BFD_DEF_DETECT_MULT
, 1);
7404 DEFUN (no_ip_pim_bfd
,
7410 "Disables BFD support\n")
7412 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7413 struct pim_interface
*pim_ifp
= ifp
->info
;
7416 vty_out(vty
, "Pim not enabled on this interface\n");
7420 if (pim_ifp
->bfd_info
) {
7421 pim_bfd_reg_dereg_all_nbr(ifp
, ZEBRA_BFD_DEST_DEREGISTER
);
7422 bfd_info_free(&(pim_ifp
->bfd_info
));
7428 DEFUN (ip_pim_bfd_param
,
7429 ip_pim_bfd_param_cmd
,
7430 "ip pim bfd (2-255) (50-60000) (50-60000)",
7433 "Enables BFD support\n"
7434 "Detect Multiplier\n"
7435 "Required min receive interval\n"
7436 "Desired min transmit interval\n")
7438 VTY_DECLVAR_CONTEXT(interface
, ifp
);
7440 int idx_number_2
= 4;
7441 int idx_number_3
= 5;
7446 struct pim_interface
*pim_ifp
= ifp
->info
;
7449 if (!pim_cmd_interface_add(ifp
)) {
7450 vty_out(vty
, "Could not enable PIM SM on interface\n");
7455 if ((ret
= bfd_validate_param(
7456 vty
, argv
[idx_number
]->arg
, argv
[idx_number_2
]->arg
,
7457 argv
[idx_number_3
]->arg
, &dm_val
, &rx_val
, &tx_val
))
7461 pim_bfd_if_param_set(ifp
, rx_val
, tx_val
, dm_val
, 0);
7466 ALIAS(no_ip_pim_bfd
, no_ip_pim_bfd_param_cmd
,
7467 "no ip pim bfd (2-255) (50-60000) (50-60000)", NO_STR IP_STR PIM_STR
7468 "Enables BFD support\n"
7469 "Detect Multiplier\n"
7470 "Required min receive interval\n"
7471 "Desired min transmit interval\n")
7473 static int ip_msdp_peer_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
7474 const char *peer
, const char *local
)
7476 enum pim_msdp_err result
;
7477 struct in_addr peer_addr
;
7478 struct in_addr local_addr
;
7479 int ret
= CMD_SUCCESS
;
7481 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
7483 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s\n", peer
,
7484 errno
, safe_strerror(errno
));
7485 return CMD_WARNING_CONFIG_FAILED
;
7488 result
= inet_pton(AF_INET
, local
, &local_addr
);
7490 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", local
,
7491 errno
, safe_strerror(errno
));
7492 return CMD_WARNING_CONFIG_FAILED
;
7495 result
= pim_msdp_peer_add(pim
, peer_addr
, local_addr
, "default",
7498 case PIM_MSDP_ERR_NONE
:
7500 case PIM_MSDP_ERR_OOM
:
7501 ret
= CMD_WARNING_CONFIG_FAILED
;
7502 vty_out(vty
, "%% Out of memory\n");
7504 case PIM_MSDP_ERR_PEER_EXISTS
:
7506 vty_out(vty
, "%% Peer exists\n");
7508 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
7509 ret
= CMD_WARNING_CONFIG_FAILED
;
7510 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
7513 ret
= CMD_WARNING_CONFIG_FAILED
;
7514 vty_out(vty
, "%% peer add failed\n");
7520 DEFUN_HIDDEN (ip_msdp_peer
,
7522 "ip msdp peer A.B.C.D source A.B.C.D",
7525 "Configure MSDP peer\n"
7527 "Source address for TCP connection\n"
7528 "local ip address\n")
7530 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7531 return ip_msdp_peer_cmd_worker(pim
, vty
, argv
[3]->arg
, argv
[5]->arg
);
7534 static int ip_no_msdp_peer_cmd_worker(struct pim_instance
*pim
, struct vty
*vty
,
7537 enum pim_msdp_err result
;
7538 struct in_addr peer_addr
;
7540 result
= inet_pton(AF_INET
, peer
, &peer_addr
);
7542 vty_out(vty
, "%% Bad peer address %s: errno=%d: %s\n", peer
,
7543 errno
, safe_strerror(errno
));
7544 return CMD_WARNING_CONFIG_FAILED
;
7547 result
= pim_msdp_peer_del(pim
, peer_addr
);
7549 case PIM_MSDP_ERR_NONE
:
7551 case PIM_MSDP_ERR_NO_PEER
:
7552 vty_out(vty
, "%% Peer does not exist\n");
7555 vty_out(vty
, "%% peer del failed\n");
7558 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7561 DEFUN_HIDDEN (no_ip_msdp_peer
,
7562 no_ip_msdp_peer_cmd
,
7563 "no ip msdp peer A.B.C.D",
7567 "Delete MSDP peer\n"
7568 "peer ip address\n")
7570 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7571 return ip_no_msdp_peer_cmd_worker(pim
, vty
, argv
[4]->arg
);
7574 static int ip_msdp_mesh_group_member_cmd_worker(struct pim_instance
*pim
,
7575 struct vty
*vty
, const char *mg
,
7578 enum pim_msdp_err result
;
7579 struct in_addr mbr_ip
;
7580 int ret
= CMD_SUCCESS
;
7582 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
7584 vty_out(vty
, "%% Bad member address %s: errno=%d: %s\n", mbr
,
7585 errno
, safe_strerror(errno
));
7586 return CMD_WARNING_CONFIG_FAILED
;
7589 result
= pim_msdp_mg_mbr_add(pim
, mg
, mbr_ip
);
7591 case PIM_MSDP_ERR_NONE
:
7593 case PIM_MSDP_ERR_OOM
:
7594 ret
= CMD_WARNING_CONFIG_FAILED
;
7595 vty_out(vty
, "%% Out of memory\n");
7597 case PIM_MSDP_ERR_MG_MBR_EXISTS
:
7599 vty_out(vty
, "%% mesh-group member exists\n");
7601 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
7602 ret
= CMD_WARNING_CONFIG_FAILED
;
7603 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
7606 ret
= CMD_WARNING_CONFIG_FAILED
;
7607 vty_out(vty
, "%% member add failed\n");
7613 DEFUN (ip_msdp_mesh_group_member
,
7614 ip_msdp_mesh_group_member_cmd
,
7615 "ip msdp mesh-group WORD member A.B.C.D",
7618 "Configure MSDP mesh-group\n"
7620 "mesh group member\n"
7621 "peer ip address\n")
7623 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7624 return ip_msdp_mesh_group_member_cmd_worker(pim
, vty
, argv
[3]->arg
,
7628 static int ip_no_msdp_mesh_group_member_cmd_worker(struct pim_instance
*pim
,
7633 enum pim_msdp_err result
;
7634 struct in_addr mbr_ip
;
7636 result
= inet_pton(AF_INET
, mbr
, &mbr_ip
);
7638 vty_out(vty
, "%% Bad member address %s: errno=%d: %s\n", mbr
,
7639 errno
, safe_strerror(errno
));
7640 return CMD_WARNING_CONFIG_FAILED
;
7643 result
= pim_msdp_mg_mbr_del(pim
, mg
, mbr_ip
);
7645 case PIM_MSDP_ERR_NONE
:
7647 case PIM_MSDP_ERR_NO_MG
:
7648 vty_out(vty
, "%% mesh-group does not exist\n");
7650 case PIM_MSDP_ERR_NO_MG_MBR
:
7651 vty_out(vty
, "%% mesh-group member does not exist\n");
7654 vty_out(vty
, "%% mesh-group member del failed\n");
7657 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7659 DEFUN (no_ip_msdp_mesh_group_member
,
7660 no_ip_msdp_mesh_group_member_cmd
,
7661 "no ip msdp mesh-group WORD member A.B.C.D",
7665 "Delete MSDP mesh-group member\n"
7667 "mesh group member\n"
7668 "peer ip address\n")
7670 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7671 return ip_no_msdp_mesh_group_member_cmd_worker(pim
, vty
, argv
[4]->arg
,
7675 static int ip_msdp_mesh_group_source_cmd_worker(struct pim_instance
*pim
,
7676 struct vty
*vty
, const char *mg
,
7679 enum pim_msdp_err result
;
7680 struct in_addr src_ip
;
7682 result
= inet_pton(AF_INET
, src
, &src_ip
);
7684 vty_out(vty
, "%% Bad source address %s: errno=%d: %s\n", src
,
7685 errno
, safe_strerror(errno
));
7686 return CMD_WARNING_CONFIG_FAILED
;
7689 result
= pim_msdp_mg_src_add(pim
, mg
, src_ip
);
7691 case PIM_MSDP_ERR_NONE
:
7693 case PIM_MSDP_ERR_OOM
:
7694 vty_out(vty
, "%% Out of memory\n");
7696 case PIM_MSDP_ERR_MAX_MESH_GROUPS
:
7697 vty_out(vty
, "%% Only one mesh-group allowed currently\n");
7700 vty_out(vty
, "%% source add failed\n");
7703 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7707 DEFUN (ip_msdp_mesh_group_source
,
7708 ip_msdp_mesh_group_source_cmd
,
7709 "ip msdp mesh-group WORD source A.B.C.D",
7712 "Configure MSDP mesh-group\n"
7714 "mesh group local address\n"
7715 "source ip address for the TCP connection\n")
7717 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7718 return ip_msdp_mesh_group_source_cmd_worker(pim
, vty
, argv
[3]->arg
,
7722 static int ip_no_msdp_mesh_group_source_cmd_worker(struct pim_instance
*pim
,
7726 enum pim_msdp_err result
;
7728 result
= pim_msdp_mg_src_del(pim
, mg
);
7730 case PIM_MSDP_ERR_NONE
:
7732 case PIM_MSDP_ERR_NO_MG
:
7733 vty_out(vty
, "%% mesh-group does not exist\n");
7736 vty_out(vty
, "%% mesh-group source del failed\n");
7739 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7742 static int ip_no_msdp_mesh_group_cmd_worker(struct pim_instance
*pim
,
7743 struct vty
*vty
, const char *mg
)
7745 enum pim_msdp_err result
;
7747 result
= pim_msdp_mg_del(pim
, mg
);
7749 case PIM_MSDP_ERR_NONE
:
7751 case PIM_MSDP_ERR_NO_MG
:
7752 vty_out(vty
, "%% mesh-group does not exist\n");
7755 vty_out(vty
, "%% mesh-group source del failed\n");
7758 return result
? CMD_WARNING_CONFIG_FAILED
: CMD_SUCCESS
;
7761 DEFUN (no_ip_msdp_mesh_group_source
,
7762 no_ip_msdp_mesh_group_source_cmd
,
7763 "no ip msdp mesh-group WORD source [A.B.C.D]",
7767 "Delete MSDP mesh-group source\n"
7769 "mesh group source\n"
7770 "mesh group local address\n")
7772 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7774 return ip_no_msdp_mesh_group_cmd_worker(pim
, vty
, argv
[6]->arg
);
7776 return ip_no_msdp_mesh_group_source_cmd_worker(pim
, vty
,
7780 static void print_empty_json_obj(struct vty
*vty
)
7783 json
= json_object_new_object();
7784 vty_out(vty
, "%s\n",
7785 json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
));
7786 json_object_free(json
);
7789 static void ip_msdp_show_mesh_group(struct pim_instance
*pim
, struct vty
*vty
,
7792 struct listnode
*mbrnode
;
7793 struct pim_msdp_mg_mbr
*mbr
;
7794 struct pim_msdp_mg
*mg
= pim
->msdp
.mg
;
7795 char mbr_str
[INET_ADDRSTRLEN
];
7796 char src_str
[INET_ADDRSTRLEN
];
7797 char state_str
[PIM_MSDP_STATE_STRLEN
];
7798 enum pim_msdp_peer_state state
;
7799 json_object
*json
= NULL
;
7800 json_object
*json_mg_row
= NULL
;
7801 json_object
*json_members
= NULL
;
7802 json_object
*json_row
= NULL
;
7806 print_empty_json_obj(vty
);
7810 pim_inet4_dump("<source?>", mg
->src_ip
, src_str
, sizeof(src_str
));
7812 json
= json_object_new_object();
7813 /* currently there is only one mesh group but we should still
7815 * it a dict with mg-name as key */
7816 json_mg_row
= json_object_new_object();
7817 json_object_string_add(json_mg_row
, "name",
7818 mg
->mesh_group_name
);
7819 json_object_string_add(json_mg_row
, "source", src_str
);
7821 vty_out(vty
, "Mesh group : %s\n", mg
->mesh_group_name
);
7822 vty_out(vty
, " Source : %s\n", src_str
);
7823 vty_out(vty
, " Member State\n");
7826 for (ALL_LIST_ELEMENTS_RO(mg
->mbr_list
, mbrnode
, mbr
)) {
7827 pim_inet4_dump("<mbr?>", mbr
->mbr_ip
, mbr_str
, sizeof(mbr_str
));
7829 state
= mbr
->mp
->state
;
7831 state
= PIM_MSDP_DISABLED
;
7833 pim_msdp_state_dump(state
, state_str
, sizeof(state_str
));
7835 json_row
= json_object_new_object();
7836 json_object_string_add(json_row
, "member", mbr_str
);
7837 json_object_string_add(json_row
, "state", state_str
);
7838 if (!json_members
) {
7839 json_members
= json_object_new_object();
7840 json_object_object_add(json_mg_row
, "members",
7843 json_object_object_add(json_members
, mbr_str
, json_row
);
7845 vty_out(vty
, " %-15s %11s\n", mbr_str
, state_str
);
7850 json_object_object_add(json
, mg
->mesh_group_name
, json_mg_row
);
7851 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
7852 json
, JSON_C_TO_STRING_PRETTY
));
7853 json_object_free(json
);
7857 DEFUN (show_ip_msdp_mesh_group
,
7858 show_ip_msdp_mesh_group_cmd
,
7859 "show ip msdp [vrf NAME] mesh-group [json]",
7864 "MSDP mesh-group information\n"
7867 u_char uj
= use_json(argc
, argv
);
7869 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
7874 ip_msdp_show_mesh_group(vrf
->info
, vty
, uj
);
7879 DEFUN (show_ip_msdp_mesh_group_vrf_all
,
7880 show_ip_msdp_mesh_group_vrf_all_cmd
,
7881 "show ip msdp vrf all mesh-group [json]",
7886 "MSDP mesh-group information\n"
7889 u_char uj
= use_json(argc
, argv
);
7895 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
7899 vty_out(vty
, " \"%s\": ", vrf
->name
);
7902 vty_out(vty
, "VRF: %s\n", vrf
->name
);
7903 ip_msdp_show_mesh_group(vrf
->info
, vty
, uj
);
7906 vty_out(vty
, "}\n");
7911 static void ip_msdp_show_peers(struct pim_instance
*pim
, struct vty
*vty
,
7914 struct listnode
*mpnode
;
7915 struct pim_msdp_peer
*mp
;
7916 char peer_str
[INET_ADDRSTRLEN
];
7917 char local_str
[INET_ADDRSTRLEN
];
7918 char state_str
[PIM_MSDP_STATE_STRLEN
];
7919 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
7921 json_object
*json
= NULL
;
7922 json_object
*json_row
= NULL
;
7926 json
= json_object_new_object();
7929 "Peer Local State Uptime SaCnt\n");
7932 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.peer_list
, mpnode
, mp
)) {
7933 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
7934 now
= pim_time_monotonic_sec();
7935 pim_time_uptime(timebuf
, sizeof(timebuf
),
7938 strcpy(timebuf
, "-");
7940 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
7941 pim_inet4_dump("<local?>", mp
->local
, local_str
,
7943 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
7945 json_row
= json_object_new_object();
7946 json_object_string_add(json_row
, "peer", peer_str
);
7947 json_object_string_add(json_row
, "local", local_str
);
7948 json_object_string_add(json_row
, "state", state_str
);
7949 json_object_string_add(json_row
, "upTime", timebuf
);
7950 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
7951 json_object_object_add(json
, peer_str
, json_row
);
7953 vty_out(vty
, "%-15s %15s %11s %8s %6d\n", peer_str
,
7954 local_str
, state_str
, timebuf
, mp
->sa_cnt
);
7959 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
7960 json
, JSON_C_TO_STRING_PRETTY
));
7961 json_object_free(json
);
7965 static void ip_msdp_show_peers_detail(struct pim_instance
*pim
, struct vty
*vty
,
7966 const char *peer
, u_char uj
)
7968 struct listnode
*mpnode
;
7969 struct pim_msdp_peer
*mp
;
7970 char peer_str
[INET_ADDRSTRLEN
];
7971 char local_str
[INET_ADDRSTRLEN
];
7972 char state_str
[PIM_MSDP_STATE_STRLEN
];
7973 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
7974 char katimer
[PIM_MSDP_TIMER_STRLEN
];
7975 char crtimer
[PIM_MSDP_TIMER_STRLEN
];
7976 char holdtimer
[PIM_MSDP_TIMER_STRLEN
];
7978 json_object
*json
= NULL
;
7979 json_object
*json_row
= NULL
;
7982 json
= json_object_new_object();
7985 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.peer_list
, mpnode
, mp
)) {
7986 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
7987 if (strcmp(peer
, "detail") && strcmp(peer
, peer_str
))
7990 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
7991 now
= pim_time_monotonic_sec();
7992 pim_time_uptime(timebuf
, sizeof(timebuf
),
7995 strcpy(timebuf
, "-");
7997 pim_inet4_dump("<local?>", mp
->local
, local_str
,
7999 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
8000 pim_time_timer_to_hhmmss(katimer
, sizeof(katimer
),
8002 pim_time_timer_to_hhmmss(crtimer
, sizeof(crtimer
),
8004 pim_time_timer_to_hhmmss(holdtimer
, sizeof(holdtimer
),
8008 json_row
= json_object_new_object();
8009 json_object_string_add(json_row
, "peer", peer_str
);
8010 json_object_string_add(json_row
, "local", local_str
);
8011 json_object_string_add(json_row
, "meshGroupName",
8012 mp
->mesh_group_name
);
8013 json_object_string_add(json_row
, "state", state_str
);
8014 json_object_string_add(json_row
, "upTime", timebuf
);
8015 json_object_string_add(json_row
, "keepAliveTimer",
8017 json_object_string_add(json_row
, "connRetryTimer",
8019 json_object_string_add(json_row
, "holdTimer",
8021 json_object_string_add(json_row
, "lastReset",
8023 json_object_int_add(json_row
, "connAttempts",
8025 json_object_int_add(json_row
, "establishedChanges",
8027 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
8028 json_object_int_add(json_row
, "kaSent", mp
->ka_tx_cnt
);
8029 json_object_int_add(json_row
, "kaRcvd", mp
->ka_rx_cnt
);
8030 json_object_int_add(json_row
, "saSent", mp
->sa_tx_cnt
);
8031 json_object_int_add(json_row
, "saRcvd", mp
->sa_rx_cnt
);
8032 json_object_object_add(json
, peer_str
, json_row
);
8034 vty_out(vty
, "Peer : %s\n", peer_str
);
8035 vty_out(vty
, " Local : %s\n", local_str
);
8036 vty_out(vty
, " Mesh Group : %s\n",
8037 mp
->mesh_group_name
);
8038 vty_out(vty
, " State : %s\n", state_str
);
8039 vty_out(vty
, " Uptime : %s\n", timebuf
);
8041 vty_out(vty
, " Keepalive Timer : %s\n", katimer
);
8042 vty_out(vty
, " Conn Retry Timer : %s\n", crtimer
);
8043 vty_out(vty
, " Hold Timer : %s\n", holdtimer
);
8044 vty_out(vty
, " Last Reset : %s\n",
8046 vty_out(vty
, " Conn Attempts : %d\n",
8048 vty_out(vty
, " Established Changes : %d\n",
8050 vty_out(vty
, " SA Count : %d\n",
8052 vty_out(vty
, " Statistics :\n");
8055 vty_out(vty
, " Keepalives : %10d %10d\n",
8056 mp
->ka_tx_cnt
, mp
->ka_rx_cnt
);
8057 vty_out(vty
, " SAs : %10d %10d\n",
8058 mp
->sa_tx_cnt
, mp
->sa_rx_cnt
);
8064 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8065 json
, JSON_C_TO_STRING_PRETTY
));
8066 json_object_free(json
);
8070 DEFUN (show_ip_msdp_peer_detail
,
8071 show_ip_msdp_peer_detail_cmd
,
8072 "show ip msdp [vrf NAME] peer [detail|A.B.C.D] [json]",
8077 "MSDP peer information\n"
8082 u_char uj
= use_json(argc
, argv
);
8084 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
8091 if (argv_find(argv
, argc
, "detail", &idx
))
8092 arg
= argv
[idx
]->text
;
8093 else if (argv_find(argv
, argc
, "A.B.C.D", &idx
))
8094 arg
= argv
[idx
]->arg
;
8097 ip_msdp_show_peers_detail(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
8099 ip_msdp_show_peers(vrf
->info
, vty
, uj
);
8104 DEFUN (show_ip_msdp_peer_detail_vrf_all
,
8105 show_ip_msdp_peer_detail_vrf_all_cmd
,
8106 "show ip msdp vrf all peer [detail|A.B.C.D] [json]",
8111 "MSDP peer information\n"
8117 u_char uj
= use_json(argc
, argv
);
8123 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
8127 vty_out(vty
, " \"%s\": ", vrf
->name
);
8130 vty_out(vty
, "VRF: %s\n", vrf
->name
);
8131 if (argv_find(argv
, argc
, "detail", &idx
)
8132 || argv_find(argv
, argc
, "A.B.C.D", &idx
))
8133 ip_msdp_show_peers_detail(vrf
->info
, vty
,
8134 argv
[idx
]->arg
, uj
);
8136 ip_msdp_show_peers(vrf
->info
, vty
, uj
);
8139 vty_out(vty
, "}\n");
8144 static void ip_msdp_show_sa(struct pim_instance
*pim
, struct vty
*vty
,
8147 struct listnode
*sanode
;
8148 struct pim_msdp_sa
*sa
;
8149 char src_str
[INET_ADDRSTRLEN
];
8150 char grp_str
[INET_ADDRSTRLEN
];
8151 char rp_str
[INET_ADDRSTRLEN
];
8152 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
8156 json_object
*json
= NULL
;
8157 json_object
*json_group
= NULL
;
8158 json_object
*json_row
= NULL
;
8161 json
= json_object_new_object();
8164 "Source Group RP Local SPT Uptime\n");
8167 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
8168 now
= pim_time_monotonic_sec();
8169 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
8170 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
8171 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
8172 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
8173 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
8175 strcpy(spt_str
, "yes");
8177 strcpy(spt_str
, "no");
8180 strcpy(rp_str
, "-");
8181 strcpy(spt_str
, "-");
8183 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
8184 strcpy(local_str
, "yes");
8186 strcpy(local_str
, "no");
8189 json_object_object_get_ex(json
, grp_str
, &json_group
);
8192 json_group
= json_object_new_object();
8193 json_object_object_add(json
, grp_str
,
8197 json_row
= json_object_new_object();
8198 json_object_string_add(json_row
, "source", src_str
);
8199 json_object_string_add(json_row
, "group", grp_str
);
8200 json_object_string_add(json_row
, "rp", rp_str
);
8201 json_object_string_add(json_row
, "local", local_str
);
8202 json_object_string_add(json_row
, "sptSetup", spt_str
);
8203 json_object_string_add(json_row
, "upTime", timebuf
);
8204 json_object_object_add(json_group
, src_str
, json_row
);
8206 vty_out(vty
, "%-15s %15s %15s %5c %3c %8s\n",
8207 src_str
, grp_str
, rp_str
, local_str
[0],
8208 spt_str
[0], timebuf
);
8213 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8214 json
, JSON_C_TO_STRING_PRETTY
));
8215 json_object_free(json
);
8219 static void ip_msdp_show_sa_entry_detail(struct pim_msdp_sa
*sa
,
8220 const char *src_str
,
8221 const char *grp_str
, struct vty
*vty
,
8222 u_char uj
, json_object
*json
)
8224 char rp_str
[INET_ADDRSTRLEN
];
8225 char peer_str
[INET_ADDRSTRLEN
];
8226 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
8229 char statetimer
[PIM_MSDP_TIMER_STRLEN
];
8231 json_object
*json_group
= NULL
;
8232 json_object
*json_row
= NULL
;
8234 now
= pim_time_monotonic_sec();
8235 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
8236 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
8237 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
8238 pim_inet4_dump("<peer?>", sa
->peer
, peer_str
, sizeof(peer_str
));
8240 strcpy(spt_str
, "yes");
8242 strcpy(spt_str
, "no");
8245 strcpy(rp_str
, "-");
8246 strcpy(peer_str
, "-");
8247 strcpy(spt_str
, "-");
8249 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
8250 strcpy(local_str
, "yes");
8252 strcpy(local_str
, "no");
8254 pim_time_timer_to_hhmmss(statetimer
, sizeof(statetimer
),
8255 sa
->sa_state_timer
);
8257 json_object_object_get_ex(json
, grp_str
, &json_group
);
8260 json_group
= json_object_new_object();
8261 json_object_object_add(json
, grp_str
, json_group
);
8264 json_row
= json_object_new_object();
8265 json_object_string_add(json_row
, "source", src_str
);
8266 json_object_string_add(json_row
, "group", grp_str
);
8267 json_object_string_add(json_row
, "rp", rp_str
);
8268 json_object_string_add(json_row
, "local", local_str
);
8269 json_object_string_add(json_row
, "sptSetup", spt_str
);
8270 json_object_string_add(json_row
, "upTime", timebuf
);
8271 json_object_string_add(json_row
, "stateTimer", statetimer
);
8272 json_object_object_add(json_group
, src_str
, json_row
);
8274 vty_out(vty
, "SA : %s\n", sa
->sg_str
);
8275 vty_out(vty
, " RP : %s\n", rp_str
);
8276 vty_out(vty
, " Peer : %s\n", peer_str
);
8277 vty_out(vty
, " Local : %s\n", local_str
);
8278 vty_out(vty
, " SPT Setup : %s\n", spt_str
);
8279 vty_out(vty
, " Uptime : %s\n", timebuf
);
8280 vty_out(vty
, " State Timer : %s\n", statetimer
);
8285 static void ip_msdp_show_sa_detail(struct pim_instance
*pim
, struct vty
*vty
,
8288 struct listnode
*sanode
;
8289 struct pim_msdp_sa
*sa
;
8290 char src_str
[INET_ADDRSTRLEN
];
8291 char grp_str
[INET_ADDRSTRLEN
];
8292 json_object
*json
= NULL
;
8295 json
= json_object_new_object();
8298 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
8299 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
8300 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
8301 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
, uj
,
8306 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8307 json
, JSON_C_TO_STRING_PRETTY
));
8308 json_object_free(json
);
8312 DEFUN (show_ip_msdp_sa_detail
,
8313 show_ip_msdp_sa_detail_cmd
,
8314 "show ip msdp [vrf NAME] sa detail [json]",
8319 "MSDP active-source information\n"
8323 u_char uj
= use_json(argc
, argv
);
8325 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
8330 ip_msdp_show_sa_detail(vrf
->info
, vty
, uj
);
8335 DEFUN (show_ip_msdp_sa_detail_vrf_all
,
8336 show_ip_msdp_sa_detail_vrf_all_cmd
,
8337 "show ip msdp vrf all sa detail [json]",
8342 "MSDP active-source information\n"
8346 u_char uj
= use_json(argc
, argv
);
8352 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
8356 vty_out(vty
, " \"%s\": ", vrf
->name
);
8359 vty_out(vty
, "VRF: %s\n", vrf
->name
);
8360 ip_msdp_show_sa_detail(vrf
->info
, vty
, uj
);
8363 vty_out(vty
, "}\n");
8368 static void ip_msdp_show_sa_addr(struct pim_instance
*pim
, struct vty
*vty
,
8369 const char *addr
, u_char uj
)
8371 struct listnode
*sanode
;
8372 struct pim_msdp_sa
*sa
;
8373 char src_str
[INET_ADDRSTRLEN
];
8374 char grp_str
[INET_ADDRSTRLEN
];
8375 json_object
*json
= NULL
;
8378 json
= json_object_new_object();
8381 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
8382 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
8383 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
8384 if (!strcmp(addr
, src_str
) || !strcmp(addr
, grp_str
)) {
8385 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
,
8391 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8392 json
, JSON_C_TO_STRING_PRETTY
));
8393 json_object_free(json
);
8397 static void ip_msdp_show_sa_sg(struct pim_instance
*pim
, struct vty
*vty
,
8398 const char *src
, const char *grp
, u_char uj
)
8400 struct listnode
*sanode
;
8401 struct pim_msdp_sa
*sa
;
8402 char src_str
[INET_ADDRSTRLEN
];
8403 char grp_str
[INET_ADDRSTRLEN
];
8404 json_object
*json
= NULL
;
8407 json
= json_object_new_object();
8410 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
8411 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
8412 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
8413 if (!strcmp(src
, src_str
) && !strcmp(grp
, grp_str
)) {
8414 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
,
8420 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8421 json
, JSON_C_TO_STRING_PRETTY
));
8422 json_object_free(json
);
8426 DEFUN (show_ip_msdp_sa_sg
,
8427 show_ip_msdp_sa_sg_cmd
,
8428 "show ip msdp [vrf NAME] sa [A.B.C.D [A.B.C.D]] [json]",
8433 "MSDP active-source information\n"
8434 "source or group ip\n"
8438 u_char uj
= use_json(argc
, argv
);
8442 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
8447 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
++]->arg
8449 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
)
8453 if (src_ip
&& grp_ip
)
8454 ip_msdp_show_sa_sg(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
8456 ip_msdp_show_sa_addr(vrf
->info
, vty
, src_ip
, uj
);
8458 ip_msdp_show_sa(vrf
->info
, vty
, uj
);
8463 DEFUN (show_ip_msdp_sa_sg_vrf_all
,
8464 show_ip_msdp_sa_sg_vrf_all_cmd
,
8465 "show ip msdp vrf all sa [A.B.C.D [A.B.C.D]] [json]",
8470 "MSDP active-source information\n"
8471 "source or group ip\n"
8475 u_char uj
= use_json(argc
, argv
);
8480 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
++]->arg
8482 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
)
8488 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
8492 vty_out(vty
, " \"%s\": ", vrf
->name
);
8495 vty_out(vty
, "VRF: %s\n", vrf
->name
);
8497 if (src_ip
&& grp_ip
)
8498 ip_msdp_show_sa_sg(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
8500 ip_msdp_show_sa_addr(vrf
->info
, vty
, src_ip
, uj
);
8502 ip_msdp_show_sa(vrf
->info
, vty
, uj
);
8505 vty_out(vty
, "}\n");
8511 void pim_cmd_init(void)
8513 install_node(&interface_node
,
8514 pim_interface_config_write
); /* INTERFACE_NODE */
8517 install_node(&debug_node
, pim_debug_config_write
);
8519 install_element(CONFIG_NODE
, &ip_multicast_routing_cmd
);
8520 install_element(CONFIG_NODE
, &no_ip_multicast_routing_cmd
);
8521 install_element(CONFIG_NODE
, &ip_pim_rp_cmd
);
8522 install_element(VRF_NODE
, &ip_pim_rp_cmd
);
8523 install_element(CONFIG_NODE
, &no_ip_pim_rp_cmd
);
8524 install_element(VRF_NODE
, &no_ip_pim_rp_cmd
);
8525 install_element(CONFIG_NODE
, &ip_pim_rp_prefix_list_cmd
);
8526 install_element(VRF_NODE
, &ip_pim_rp_prefix_list_cmd
);
8527 install_element(CONFIG_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
8528 install_element(VRF_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
8529 install_element(CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_cmd
);
8530 install_element(VRF_NODE
, &no_ip_pim_ssm_prefix_list_cmd
);
8531 install_element(CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_name_cmd
);
8532 install_element(VRF_NODE
, &no_ip_pim_ssm_prefix_list_name_cmd
);
8533 install_element(CONFIG_NODE
, &ip_pim_ssm_prefix_list_cmd
);
8534 install_element(VRF_NODE
, &ip_pim_ssm_prefix_list_cmd
);
8535 install_element(CONFIG_NODE
, &ip_pim_register_suppress_cmd
);
8536 install_element(VRF_NODE
, &ip_pim_register_suppress_cmd
);
8537 install_element(CONFIG_NODE
, &no_ip_pim_register_suppress_cmd
);
8538 install_element(VRF_NODE
, &no_ip_pim_register_suppress_cmd
);
8539 install_element(CONFIG_NODE
, &ip_pim_spt_switchover_infinity_cmd
);
8540 install_element(VRF_NODE
, &ip_pim_spt_switchover_infinity_cmd
);
8541 install_element(CONFIG_NODE
, &ip_pim_spt_switchover_infinity_plist_cmd
);
8542 install_element(VRF_NODE
, &ip_pim_spt_switchover_infinity_plist_cmd
);
8543 install_element(CONFIG_NODE
, &no_ip_pim_spt_switchover_infinity_cmd
);
8544 install_element(VRF_NODE
, &no_ip_pim_spt_switchover_infinity_cmd
);
8545 install_element(CONFIG_NODE
,
8546 &no_ip_pim_spt_switchover_infinity_plist_cmd
);
8547 install_element(VRF_NODE
, &no_ip_pim_spt_switchover_infinity_plist_cmd
);
8548 install_element(CONFIG_NODE
, &ip_pim_joinprune_time_cmd
);
8549 install_element(VRF_NODE
, &ip_pim_joinprune_time_cmd
);
8550 install_element(CONFIG_NODE
, &no_ip_pim_joinprune_time_cmd
);
8551 install_element(VRF_NODE
, &no_ip_pim_joinprune_time_cmd
);
8552 install_element(CONFIG_NODE
, &ip_pim_keep_alive_cmd
);
8553 install_element(VRF_NODE
, &ip_pim_keep_alive_cmd
);
8554 install_element(CONFIG_NODE
, &ip_pim_rp_keep_alive_cmd
);
8555 install_element(VRF_NODE
, &ip_pim_rp_keep_alive_cmd
);
8556 install_element(CONFIG_NODE
, &no_ip_pim_keep_alive_cmd
);
8557 install_element(VRF_NODE
, &no_ip_pim_keep_alive_cmd
);
8558 install_element(CONFIG_NODE
, &no_ip_pim_rp_keep_alive_cmd
);
8559 install_element(VRF_NODE
, &no_ip_pim_rp_keep_alive_cmd
);
8560 install_element(CONFIG_NODE
, &ip_pim_packets_cmd
);
8561 install_element(VRF_NODE
, &ip_pim_packets_cmd
);
8562 install_element(CONFIG_NODE
, &no_ip_pim_packets_cmd
);
8563 install_element(VRF_NODE
, &no_ip_pim_packets_cmd
);
8564 install_element(CONFIG_NODE
, &ip_pim_v6_secondary_cmd
);
8565 install_element(VRF_NODE
, &ip_pim_v6_secondary_cmd
);
8566 install_element(CONFIG_NODE
, &no_ip_pim_v6_secondary_cmd
);
8567 install_element(VRF_NODE
, &no_ip_pim_v6_secondary_cmd
);
8568 install_element(CONFIG_NODE
, &ip_ssmpingd_cmd
);
8569 install_element(VRF_NODE
, &ip_ssmpingd_cmd
);
8570 install_element(CONFIG_NODE
, &no_ip_ssmpingd_cmd
);
8571 install_element(VRF_NODE
, &no_ip_ssmpingd_cmd
);
8572 install_element(CONFIG_NODE
, &ip_msdp_peer_cmd
);
8573 install_element(VRF_NODE
, &ip_msdp_peer_cmd
);
8574 install_element(CONFIG_NODE
, &no_ip_msdp_peer_cmd
);
8575 install_element(VRF_NODE
, &no_ip_msdp_peer_cmd
);
8576 install_element(CONFIG_NODE
, &ip_pim_ecmp_cmd
);
8577 install_element(VRF_NODE
, &ip_pim_ecmp_cmd
);
8578 install_element(CONFIG_NODE
, &no_ip_pim_ecmp_cmd
);
8579 install_element(VRF_NODE
, &no_ip_pim_ecmp_cmd
);
8580 install_element(CONFIG_NODE
, &ip_pim_ecmp_rebalance_cmd
);
8581 install_element(VRF_NODE
, &ip_pim_ecmp_rebalance_cmd
);
8582 install_element(CONFIG_NODE
, &no_ip_pim_ecmp_rebalance_cmd
);
8583 install_element(VRF_NODE
, &no_ip_pim_ecmp_rebalance_cmd
);
8585 install_element(INTERFACE_NODE
, &interface_ip_igmp_cmd
);
8586 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_cmd
);
8587 install_element(INTERFACE_NODE
, &interface_ip_igmp_join_cmd
);
8588 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_join_cmd
);
8589 install_element(INTERFACE_NODE
, &interface_ip_igmp_version_cmd
);
8590 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_version_cmd
);
8591 install_element(INTERFACE_NODE
, &interface_ip_igmp_query_interval_cmd
);
8592 install_element(INTERFACE_NODE
,
8593 &interface_no_ip_igmp_query_interval_cmd
);
8594 install_element(INTERFACE_NODE
,
8595 &interface_ip_igmp_query_max_response_time_cmd
);
8596 install_element(INTERFACE_NODE
,
8597 &interface_no_ip_igmp_query_max_response_time_cmd
);
8598 install_element(INTERFACE_NODE
,
8599 &interface_ip_igmp_query_max_response_time_dsec_cmd
);
8600 install_element(INTERFACE_NODE
,
8601 &interface_no_ip_igmp_query_max_response_time_dsec_cmd
);
8602 install_element(INTERFACE_NODE
, &interface_ip_pim_ssm_cmd
);
8603 install_element(INTERFACE_NODE
, &interface_no_ip_pim_ssm_cmd
);
8604 install_element(INTERFACE_NODE
, &interface_ip_pim_sm_cmd
);
8605 install_element(INTERFACE_NODE
, &interface_no_ip_pim_sm_cmd
);
8606 install_element(INTERFACE_NODE
, &interface_ip_pim_drprio_cmd
);
8607 install_element(INTERFACE_NODE
, &interface_no_ip_pim_drprio_cmd
);
8608 install_element(INTERFACE_NODE
, &interface_ip_pim_hello_cmd
);
8609 install_element(INTERFACE_NODE
, &interface_no_ip_pim_hello_cmd
);
8610 install_element(INTERFACE_NODE
, &interface_ip_pim_boundary_oil_cmd
);
8611 install_element(INTERFACE_NODE
, &interface_no_ip_pim_boundary_oil_cmd
);
8613 // Static mroutes NEB
8614 install_element(INTERFACE_NODE
, &interface_ip_mroute_cmd
);
8615 install_element(INTERFACE_NODE
, &interface_ip_mroute_source_cmd
);
8616 install_element(INTERFACE_NODE
, &interface_no_ip_mroute_cmd
);
8617 install_element(INTERFACE_NODE
, &interface_no_ip_mroute_source_cmd
);
8619 install_element(VIEW_NODE
, &show_ip_igmp_interface_cmd
);
8620 install_element(VIEW_NODE
, &show_ip_igmp_interface_vrf_all_cmd
);
8621 install_element(VIEW_NODE
, &show_ip_igmp_join_cmd
);
8622 install_element(VIEW_NODE
, &show_ip_igmp_join_vrf_all_cmd
);
8623 install_element(VIEW_NODE
, &show_ip_igmp_groups_cmd
);
8624 install_element(VIEW_NODE
, &show_ip_igmp_groups_vrf_all_cmd
);
8625 install_element(VIEW_NODE
, &show_ip_igmp_groups_retransmissions_cmd
);
8626 install_element(VIEW_NODE
, &show_ip_igmp_sources_cmd
);
8627 install_element(VIEW_NODE
, &show_ip_igmp_sources_retransmissions_cmd
);
8628 install_element(VIEW_NODE
, &show_ip_pim_assert_cmd
);
8629 install_element(VIEW_NODE
, &show_ip_pim_assert_internal_cmd
);
8630 install_element(VIEW_NODE
, &show_ip_pim_assert_metric_cmd
);
8631 install_element(VIEW_NODE
, &show_ip_pim_assert_winner_metric_cmd
);
8632 install_element(VIEW_NODE
, &show_ip_pim_interface_traffic_cmd
);
8633 install_element(VIEW_NODE
, &show_ip_pim_interface_cmd
);
8634 install_element(VIEW_NODE
, &show_ip_pim_interface_vrf_all_cmd
);
8635 install_element(VIEW_NODE
, &show_ip_pim_join_cmd
);
8636 install_element(VIEW_NODE
, &show_ip_pim_join_vrf_all_cmd
);
8637 install_element(VIEW_NODE
, &show_ip_pim_local_membership_cmd
);
8638 install_element(VIEW_NODE
, &show_ip_pim_neighbor_cmd
);
8639 install_element(VIEW_NODE
, &show_ip_pim_neighbor_vrf_all_cmd
);
8640 install_element(VIEW_NODE
, &show_ip_pim_rpf_cmd
);
8641 install_element(VIEW_NODE
, &show_ip_pim_rpf_vrf_all_cmd
);
8642 install_element(VIEW_NODE
, &show_ip_pim_secondary_cmd
);
8643 install_element(VIEW_NODE
, &show_ip_pim_state_cmd
);
8644 install_element(VIEW_NODE
, &show_ip_pim_state_vrf_all_cmd
);
8645 install_element(VIEW_NODE
, &show_ip_pim_upstream_cmd
);
8646 install_element(VIEW_NODE
, &show_ip_pim_upstream_vrf_all_cmd
);
8647 install_element(VIEW_NODE
, &show_ip_pim_upstream_join_desired_cmd
);
8648 install_element(VIEW_NODE
, &show_ip_pim_upstream_rpf_cmd
);
8649 install_element(VIEW_NODE
, &show_ip_pim_rp_cmd
);
8650 install_element(VIEW_NODE
, &show_ip_pim_rp_vrf_all_cmd
);
8651 install_element(VIEW_NODE
, &show_ip_multicast_cmd
);
8652 install_element(VIEW_NODE
, &show_ip_multicast_vrf_all_cmd
);
8653 install_element(VIEW_NODE
, &show_ip_mroute_cmd
);
8654 install_element(VIEW_NODE
, &show_ip_mroute_vrf_all_cmd
);
8655 install_element(VIEW_NODE
, &show_ip_mroute_count_cmd
);
8656 install_element(VIEW_NODE
, &show_ip_mroute_count_vrf_all_cmd
);
8657 install_element(VIEW_NODE
, &show_ip_rib_cmd
);
8658 install_element(VIEW_NODE
, &show_ip_ssmpingd_cmd
);
8659 install_element(VIEW_NODE
, &show_debugging_pim_cmd
);
8660 install_element(VIEW_NODE
, &show_ip_pim_nexthop_cmd
);
8661 install_element(VIEW_NODE
, &show_ip_pim_nexthop_lookup_cmd
);
8663 install_element(ENABLE_NODE
, &clear_ip_interfaces_cmd
);
8664 install_element(ENABLE_NODE
, &clear_ip_igmp_interfaces_cmd
);
8665 install_element(ENABLE_NODE
, &clear_ip_mroute_cmd
);
8666 install_element(ENABLE_NODE
, &clear_ip_pim_interfaces_cmd
);
8667 install_element(ENABLE_NODE
, &clear_ip_pim_interface_traffic_cmd
);
8668 install_element(ENABLE_NODE
, &clear_ip_pim_oil_cmd
);
8670 install_element(ENABLE_NODE
, &debug_igmp_cmd
);
8671 install_element(ENABLE_NODE
, &no_debug_igmp_cmd
);
8672 install_element(ENABLE_NODE
, &debug_igmp_events_cmd
);
8673 install_element(ENABLE_NODE
, &no_debug_igmp_events_cmd
);
8674 install_element(ENABLE_NODE
, &debug_igmp_packets_cmd
);
8675 install_element(ENABLE_NODE
, &no_debug_igmp_packets_cmd
);
8676 install_element(ENABLE_NODE
, &debug_igmp_trace_cmd
);
8677 install_element(ENABLE_NODE
, &no_debug_igmp_trace_cmd
);
8678 install_element(ENABLE_NODE
, &debug_mroute_cmd
);
8679 install_element(ENABLE_NODE
, &debug_mroute_detail_cmd
);
8680 install_element(ENABLE_NODE
, &no_debug_mroute_cmd
);
8681 install_element(ENABLE_NODE
, &no_debug_mroute_detail_cmd
);
8682 install_element(ENABLE_NODE
, &debug_static_cmd
);
8683 install_element(ENABLE_NODE
, &no_debug_static_cmd
);
8684 install_element(ENABLE_NODE
, &debug_pim_cmd
);
8685 install_element(ENABLE_NODE
, &no_debug_pim_cmd
);
8686 install_element(ENABLE_NODE
, &debug_pim_nht_cmd
);
8687 install_element(ENABLE_NODE
, &no_debug_pim_nht_cmd
);
8688 install_element(ENABLE_NODE
, &debug_pim_nht_rp_cmd
);
8689 install_element(ENABLE_NODE
, &no_debug_pim_nht_rp_cmd
);
8690 install_element(ENABLE_NODE
, &debug_pim_events_cmd
);
8691 install_element(ENABLE_NODE
, &no_debug_pim_events_cmd
);
8692 install_element(ENABLE_NODE
, &debug_pim_packets_cmd
);
8693 install_element(ENABLE_NODE
, &no_debug_pim_packets_cmd
);
8694 install_element(ENABLE_NODE
, &debug_pim_packetdump_send_cmd
);
8695 install_element(ENABLE_NODE
, &no_debug_pim_packetdump_send_cmd
);
8696 install_element(ENABLE_NODE
, &debug_pim_packetdump_recv_cmd
);
8697 install_element(ENABLE_NODE
, &no_debug_pim_packetdump_recv_cmd
);
8698 install_element(ENABLE_NODE
, &debug_pim_trace_cmd
);
8699 install_element(ENABLE_NODE
, &no_debug_pim_trace_cmd
);
8700 install_element(ENABLE_NODE
, &debug_pim_trace_detail_cmd
);
8701 install_element(ENABLE_NODE
, &no_debug_pim_trace_detail_cmd
);
8702 install_element(ENABLE_NODE
, &debug_ssmpingd_cmd
);
8703 install_element(ENABLE_NODE
, &no_debug_ssmpingd_cmd
);
8704 install_element(ENABLE_NODE
, &debug_pim_zebra_cmd
);
8705 install_element(ENABLE_NODE
, &no_debug_pim_zebra_cmd
);
8706 install_element(ENABLE_NODE
, &debug_msdp_cmd
);
8707 install_element(ENABLE_NODE
, &no_debug_msdp_cmd
);
8708 install_element(ENABLE_NODE
, &undebug_msdp_cmd
);
8709 install_element(ENABLE_NODE
, &debug_msdp_events_cmd
);
8710 install_element(ENABLE_NODE
, &no_debug_msdp_events_cmd
);
8711 install_element(ENABLE_NODE
, &undebug_msdp_events_cmd
);
8712 install_element(ENABLE_NODE
, &debug_msdp_packets_cmd
);
8713 install_element(ENABLE_NODE
, &no_debug_msdp_packets_cmd
);
8714 install_element(ENABLE_NODE
, &undebug_msdp_packets_cmd
);
8715 install_element(ENABLE_NODE
, &debug_mtrace_cmd
);
8716 install_element(ENABLE_NODE
, &no_debug_mtrace_cmd
);
8718 install_element(CONFIG_NODE
, &debug_igmp_cmd
);
8719 install_element(CONFIG_NODE
, &no_debug_igmp_cmd
);
8720 install_element(CONFIG_NODE
, &debug_igmp_events_cmd
);
8721 install_element(CONFIG_NODE
, &no_debug_igmp_events_cmd
);
8722 install_element(CONFIG_NODE
, &debug_igmp_packets_cmd
);
8723 install_element(CONFIG_NODE
, &no_debug_igmp_packets_cmd
);
8724 install_element(CONFIG_NODE
, &debug_igmp_trace_cmd
);
8725 install_element(CONFIG_NODE
, &no_debug_igmp_trace_cmd
);
8726 install_element(CONFIG_NODE
, &debug_mroute_cmd
);
8727 install_element(CONFIG_NODE
, &debug_mroute_detail_cmd
);
8728 install_element(CONFIG_NODE
, &no_debug_mroute_cmd
);
8729 install_element(CONFIG_NODE
, &no_debug_mroute_detail_cmd
);
8730 install_element(CONFIG_NODE
, &debug_static_cmd
);
8731 install_element(CONFIG_NODE
, &no_debug_static_cmd
);
8732 install_element(CONFIG_NODE
, &debug_pim_cmd
);
8733 install_element(CONFIG_NODE
, &no_debug_pim_cmd
);
8734 install_element(CONFIG_NODE
, &debug_pim_nht_cmd
);
8735 install_element(CONFIG_NODE
, &no_debug_pim_nht_cmd
);
8736 install_element(CONFIG_NODE
, &debug_pim_nht_rp_cmd
);
8737 install_element(CONFIG_NODE
, &no_debug_pim_nht_rp_cmd
);
8738 install_element(CONFIG_NODE
, &debug_pim_events_cmd
);
8739 install_element(CONFIG_NODE
, &no_debug_pim_events_cmd
);
8740 install_element(CONFIG_NODE
, &debug_pim_packets_cmd
);
8741 install_element(CONFIG_NODE
, &no_debug_pim_packets_cmd
);
8742 install_element(CONFIG_NODE
, &debug_pim_trace_cmd
);
8743 install_element(CONFIG_NODE
, &no_debug_pim_trace_cmd
);
8744 install_element(CONFIG_NODE
, &debug_pim_trace_detail_cmd
);
8745 install_element(CONFIG_NODE
, &no_debug_pim_trace_detail_cmd
);
8746 install_element(CONFIG_NODE
, &debug_ssmpingd_cmd
);
8747 install_element(CONFIG_NODE
, &no_debug_ssmpingd_cmd
);
8748 install_element(CONFIG_NODE
, &debug_pim_zebra_cmd
);
8749 install_element(CONFIG_NODE
, &no_debug_pim_zebra_cmd
);
8750 install_element(CONFIG_NODE
, &debug_msdp_cmd
);
8751 install_element(CONFIG_NODE
, &no_debug_msdp_cmd
);
8752 install_element(CONFIG_NODE
, &undebug_msdp_cmd
);
8753 install_element(CONFIG_NODE
, &debug_msdp_events_cmd
);
8754 install_element(CONFIG_NODE
, &no_debug_msdp_events_cmd
);
8755 install_element(CONFIG_NODE
, &undebug_msdp_events_cmd
);
8756 install_element(CONFIG_NODE
, &debug_msdp_packets_cmd
);
8757 install_element(CONFIG_NODE
, &no_debug_msdp_packets_cmd
);
8758 install_element(CONFIG_NODE
, &undebug_msdp_packets_cmd
);
8759 install_element(CONFIG_NODE
, &debug_mtrace_cmd
);
8760 install_element(CONFIG_NODE
, &no_debug_mtrace_cmd
);
8762 install_element(CONFIG_NODE
, &ip_msdp_mesh_group_member_cmd
);
8763 install_element(VRF_NODE
, &ip_msdp_mesh_group_member_cmd
);
8764 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_member_cmd
);
8765 install_element(VRF_NODE
, &no_ip_msdp_mesh_group_member_cmd
);
8766 install_element(CONFIG_NODE
, &ip_msdp_mesh_group_source_cmd
);
8767 install_element(VRF_NODE
, &ip_msdp_mesh_group_source_cmd
);
8768 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_source_cmd
);
8769 install_element(VRF_NODE
, &no_ip_msdp_mesh_group_source_cmd
);
8770 install_element(VIEW_NODE
, &show_ip_msdp_peer_detail_cmd
);
8771 install_element(VIEW_NODE
, &show_ip_msdp_peer_detail_vrf_all_cmd
);
8772 install_element(VIEW_NODE
, &show_ip_msdp_sa_detail_cmd
);
8773 install_element(VIEW_NODE
, &show_ip_msdp_sa_detail_vrf_all_cmd
);
8774 install_element(VIEW_NODE
, &show_ip_msdp_sa_sg_cmd
);
8775 install_element(VIEW_NODE
, &show_ip_msdp_sa_sg_vrf_all_cmd
);
8776 install_element(VIEW_NODE
, &show_ip_msdp_mesh_group_cmd
);
8777 install_element(VIEW_NODE
, &show_ip_msdp_mesh_group_vrf_all_cmd
);
8778 install_element(VIEW_NODE
, &show_ip_pim_ssm_range_cmd
);
8779 install_element(VIEW_NODE
, &show_ip_pim_group_type_cmd
);
8780 install_element(INTERFACE_NODE
, &interface_pim_use_source_cmd
);
8781 install_element(INTERFACE_NODE
, &interface_no_pim_use_source_cmd
);
8782 /* Install BFD command */
8783 install_element(INTERFACE_NODE
, &ip_pim_bfd_cmd
);
8784 install_element(INTERFACE_NODE
, &ip_pim_bfd_param_cmd
);
8785 install_element(INTERFACE_NODE
, &no_ip_pim_bfd_cmd
);
8786 install_element(INTERFACE_NODE
, &no_ip_pim_bfd_param_cmd
);