3 Copyright (C) 2008 Everton da Silva Marques
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; see the file COPYING; if not, write to the
17 Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
20 $QuaggaId: $Format:%an, %ai, %h$ $
25 #include <sys/ioctl.h>
34 #include "pim_iface.h"
36 #include "pim_mroute.h"
39 #include "pim_igmpv3.h"
44 #include "pim_neighbor.h"
46 #include "pim_ifchannel.h"
47 #include "pim_hello.h"
49 #include "pim_upstream.h"
51 #include "pim_macro.h"
52 #include "pim_ssmpingd.h"
53 #include "pim_zebra.h"
54 #include "pim_static.h"
56 static struct cmd_node pim_global_node = {
62 static struct cmd_node interface_node = {
68 static void pim_if_membership_clear(struct interface *ifp)
70 struct pim_interface *pim_ifp;
75 if (PIM_IF_TEST_PIM(pim_ifp->options) &&
76 PIM_IF_TEST_IGMP(pim_ifp->options)) {
80 pim_ifchannel_membership_clear(ifp);
84 When PIM is disabled on interface, IGMPv3 local membership
85 information is not injected into PIM interface state.
87 The function pim_if_membership_refresh() fetches all IGMPv3 local
88 membership information into PIM. It is intented to be called
89 whenever PIM is enabled on the interface in order to collect missed
90 local membership information.
92 static void pim_if_membership_refresh(struct interface *ifp)
94 struct pim_interface *pim_ifp;
95 struct listnode *sock_node;
96 struct igmp_sock *igmp;
101 if (!PIM_IF_TEST_PIM(pim_ifp->options))
103 if (!PIM_IF_TEST_IGMP(pim_ifp->options))
107 First clear off membership from all PIM (S,G) entries on the
111 pim_ifchannel_membership_clear(ifp);
114 Then restore PIM (S,G) membership from all IGMPv3 (S,G) entries on
118 /* scan igmp sockets */
119 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
120 struct listnode *grpnode;
121 struct igmp_group *grp;
123 /* scan igmp groups */
124 for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grpnode, grp)) {
125 struct listnode *srcnode;
126 struct igmp_source *src;
128 /* scan group sources */
129 for (ALL_LIST_ELEMENTS_RO(grp->group_source_list, srcnode, src)) {
131 if (IGMP_SOURCE_TEST_FORWARDING(src->source_flags)) {
132 pim_ifchannel_local_membership_add(ifp,
137 } /* scan group sources */
138 } /* scan igmp groups */
139 } /* scan igmp sockets */
142 Finally delete every PIM (S,G) entry lacking all state info
145 pim_ifchannel_delete_on_noinfo(ifp);
149 static void pim_show_assert(struct vty *vty)
151 struct listnode *ifnode;
152 struct interface *ifp;
155 now = pim_time_monotonic_sec();
158 "Interface Address Source Group State Winner Uptime Timer%s",
161 for (ALL_LIST_ELEMENTS_RO(iflist, ifnode, ifp)) {
162 struct pim_interface *pim_ifp;
163 struct in_addr ifaddr;
164 struct listnode *ch_node;
165 struct pim_ifchannel *ch;
172 ifaddr = pim_ifp->primary_address;
174 for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_ifchannel_list, ch_node, ch)) {
175 char ch_src_str[100];
176 char ch_grp_str[100];
177 char winner_str[100];
181 pim_inet4_dump("<ch_src?>", ch->source_addr,
182 ch_src_str, sizeof(ch_src_str));
183 pim_inet4_dump("<ch_grp?>", ch->group_addr,
184 ch_grp_str, sizeof(ch_grp_str));
185 pim_inet4_dump("<assrt_win?>", ch->ifassert_winner,
186 winner_str, sizeof(winner_str));
188 pim_time_uptime(uptime, sizeof(uptime), now - ch->ifassert_creation);
189 pim_time_timer_to_mmss(timer, sizeof(timer),
190 ch->t_ifassert_timer);
192 vty_out(vty, "%-9s %-15s %-15s %-15s %-6s %-15s %-8s %-5s%s",
197 pim_ifchannel_ifassert_name(ch->ifassert_state),
202 } /* scan interface channels */
203 } /* scan interfaces */
206 static void pim_show_assert_internal(struct vty *vty)
208 struct listnode *ifnode;
209 struct interface *ifp;
213 "ECA: Evaluate CouldAssert%s"
214 "ATD: AssertTrackingDesired%s"
215 "eATD: Evaluate AssertTrackingDesired%s%s",
216 VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
219 "Interface Address Source Group CA eCA ATD eATD%s",
222 for (ALL_LIST_ELEMENTS_RO(iflist, ifnode, ifp)) {
223 struct pim_interface *pim_ifp;
224 struct in_addr ifaddr;
225 struct listnode *ch_node;
226 struct pim_ifchannel *ch;
233 ifaddr = pim_ifp->primary_address;
235 for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_ifchannel_list, ch_node, ch)) {
236 char ch_src_str[100];
237 char ch_grp_str[100];
239 pim_inet4_dump("<ch_src?>", ch->source_addr,
240 ch_src_str, sizeof(ch_src_str));
241 pim_inet4_dump("<ch_grp?>", ch->group_addr,
242 ch_grp_str, sizeof(ch_grp_str));
243 vty_out(vty, "%-9s %-15s %-15s %-15s %-3s %-3s %-3s %-4s%s",
248 PIM_IF_FLAG_TEST_COULD_ASSERT(ch->flags) ? "yes" : "no",
249 pim_macro_ch_could_assert_eval(ch) ? "yes" : "no",
250 PIM_IF_FLAG_TEST_ASSERT_TRACKING_DESIRED(ch->flags) ? "yes" : "no",
251 pim_macro_assert_tracking_desired_eval(ch) ? "yes" : "no",
253 } /* scan interface channels */
254 } /* scan interfaces */
257 static void pim_show_assert_metric(struct vty *vty)
259 struct listnode *ifnode;
260 struct interface *ifp;
263 "Interface Address Source Group RPT Pref Metric Address %s",
266 for (ALL_LIST_ELEMENTS_RO(iflist, ifnode, ifp)) {
267 struct pim_interface *pim_ifp;
268 struct in_addr ifaddr;
269 struct listnode *ch_node;
270 struct pim_ifchannel *ch;
277 ifaddr = pim_ifp->primary_address;
279 for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_ifchannel_list, ch_node, ch)) {
280 char ch_src_str[100];
281 char ch_grp_str[100];
283 struct pim_assert_metric am;
285 am = pim_macro_spt_assert_metric(&ch->upstream->rpf, pim_ifp->primary_address);
287 pim_inet4_dump("<ch_src?>", ch->source_addr,
288 ch_src_str, sizeof(ch_src_str));
289 pim_inet4_dump("<ch_grp?>", ch->group_addr,
290 ch_grp_str, sizeof(ch_grp_str));
291 pim_inet4_dump("<addr?>", am.ip_address,
292 addr_str, sizeof(addr_str));
294 vty_out(vty, "%-9s %-15s %-15s %-15s %-3s %4u %6u %-15s%s",
299 am.rpt_bit_flag ? "yes" : "no",
300 am.metric_preference,
304 } /* scan interface channels */
305 } /* scan interfaces */
308 static void pim_show_assert_winner_metric(struct vty *vty)
310 struct listnode *ifnode;
311 struct interface *ifp;
314 "Interface Address Source Group RPT Pref Metric Address %s",
317 for (ALL_LIST_ELEMENTS_RO(iflist, ifnode, ifp)) {
318 struct pim_interface *pim_ifp;
319 struct in_addr ifaddr;
320 struct listnode *ch_node;
321 struct pim_ifchannel *ch;
328 ifaddr = pim_ifp->primary_address;
330 for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_ifchannel_list, ch_node, ch)) {
331 char ch_src_str[100];
332 char ch_grp_str[100];
334 struct pim_assert_metric *am;
338 am = &ch->ifassert_winner_metric;
340 pim_inet4_dump("<ch_src?>", ch->source_addr,
341 ch_src_str, sizeof(ch_src_str));
342 pim_inet4_dump("<ch_grp?>", ch->group_addr,
343 ch_grp_str, sizeof(ch_grp_str));
344 pim_inet4_dump("<addr?>", am->ip_address,
345 addr_str, sizeof(addr_str));
347 if (am->metric_preference == PIM_ASSERT_METRIC_PREFERENCE_MAX)
348 snprintf(pref_str, sizeof(pref_str), "INFI");
350 snprintf(pref_str, sizeof(pref_str), "%4u", am->metric_preference);
352 if (am->route_metric == PIM_ASSERT_ROUTE_METRIC_MAX)
353 snprintf(metr_str, sizeof(metr_str), "INFI");
355 snprintf(metr_str, sizeof(metr_str), "%6u", am->route_metric);
357 vty_out(vty, "%-9s %-15s %-15s %-15s %-3s %-4s %-6s %-15s%s",
362 am->rpt_bit_flag ? "yes" : "no",
367 } /* scan interface channels */
368 } /* scan interfaces */
371 static void pim_show_membership(struct vty *vty)
373 struct listnode *ifnode;
374 struct interface *ifp;
377 "Interface Address Source Group Membership%s",
380 for (ALL_LIST_ELEMENTS_RO(iflist, ifnode, ifp)) {
381 struct pim_interface *pim_ifp;
382 struct in_addr ifaddr;
383 struct listnode *ch_node;
384 struct pim_ifchannel *ch;
391 ifaddr = pim_ifp->primary_address;
393 for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_ifchannel_list, ch_node, ch)) {
394 char ch_src_str[100];
395 char ch_grp_str[100];
397 pim_inet4_dump("<ch_src?>", ch->source_addr,
398 ch_src_str, sizeof(ch_src_str));
399 pim_inet4_dump("<ch_grp?>", ch->group_addr,
400 ch_grp_str, sizeof(ch_grp_str));
402 vty_out(vty, "%-9s %-15s %-15s %-15s %-10s%s",
407 ch->local_ifmembership == PIM_IFMEMBERSHIP_NOINFO ?
408 "NOINFO" : "INCLUDE",
410 } /* scan interface channels */
411 } /* scan interfaces */
415 static void igmp_show_interfaces(struct vty *vty)
417 struct listnode *node;
418 struct interface *ifp;
421 now = pim_time_monotonic_sec();
424 "Interface Address ifIndex Socket Uptime Multi Broad MLoop AllMu Prmsc Del%s",
427 for (ALL_LIST_ELEMENTS_RO(iflist, node, ifp)) {
428 struct pim_interface *pim_ifp;
429 struct listnode *sock_node;
430 struct igmp_sock *igmp;
437 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
441 pim_time_uptime(uptime, sizeof(uptime), now - igmp->sock_creation);
443 mloop = pim_socket_mcastloop_get(igmp->fd);
445 vty_out(vty, "%-9s %-15s %7d %6d %8s %5s %5s %5s %5s %5s %3s%s",
447 inet_ntoa(igmp->ifaddr),
451 if_is_multicast(ifp) ? "yes" : "no",
452 if_is_broadcast(ifp) ? "yes" : "no",
453 (mloop < 0) ? "?" : (mloop ? "yes" : "no"),
454 (ifp->flags & IFF_ALLMULTI) ? "yes" : "no",
455 (ifp->flags & IFF_PROMISC) ? "yes" : "no",
456 PIM_IF_IS_DELETED(ifp) ? "yes" : "no",
462 static void igmp_show_interface_join(struct vty *vty)
464 struct listnode *node;
465 struct interface *ifp;
468 now = pim_time_monotonic_sec();
471 "Interface Address Source Group Socket Uptime %s",
474 for (ALL_LIST_ELEMENTS_RO(iflist, node, ifp)) {
475 struct pim_interface *pim_ifp;
476 struct listnode *join_node;
477 struct igmp_join *ij;
478 struct in_addr pri_addr;
479 char pri_addr_str[100];
486 if (!pim_ifp->igmp_join_list)
489 pri_addr = pim_find_primary_addr(ifp);
490 pim_inet4_dump("<pri?>", pri_addr, pri_addr_str, sizeof(pri_addr_str));
492 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_join_list, join_node, ij)) {
494 char source_str[100];
497 pim_time_uptime(uptime, sizeof(uptime), now - ij->sock_creation);
498 pim_inet4_dump("<grp?>", ij->group_addr, group_str, sizeof(group_str));
499 pim_inet4_dump("<src?>", ij->source_addr, source_str, sizeof(source_str));
501 vty_out(vty, "%-9s %-15s %-15s %-15s %6d %8s%s",
509 } /* for (pim_ifp->igmp_join_list) */
515 static void show_interface_address(struct vty *vty)
517 struct listnode *ifpnode;
518 struct interface *ifp;
521 "Interface Primary Secondary %s",
524 for (ALL_LIST_ELEMENTS_RO(iflist, ifpnode, ifp)) {
525 struct listnode *ifcnode;
526 struct connected *ifc;
527 struct in_addr pri_addr;
528 char pri_addr_str[100];
530 pri_addr = pim_find_primary_addr(ifp);
532 pim_inet4_dump("<pri?>", pri_addr, pri_addr_str, sizeof(pri_addr_str));
534 for (ALL_LIST_ELEMENTS_RO(ifp->connected, ifcnode, ifc)) {
535 char sec_addr_str[100];
536 struct prefix *p = ifc->address;
538 if (p->family != AF_INET)
541 if (p->u.prefix4.s_addr == pri_addr.s_addr) {
542 sec_addr_str[0] = '\0';
545 pim_inet4_dump("<sec?>", p->u.prefix4, sec_addr_str, sizeof(sec_addr_str));
548 vty_out(vty, "%-9s %-15s %-15s%s",
557 static void pim_show_dr(struct vty *vty)
559 struct listnode *node;
560 struct interface *ifp;
563 now = pim_time_monotonic_sec();
566 "NonPri: Number of neighbors missing DR Priority hello option%s"
567 "DrPri: Designated Router Priority sent%s%s",
568 VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
570 vty_out(vty, "Interface Address DR Uptime Elections Changes NonPri DrPri%s", VTY_NEWLINE);
572 for (ALL_LIST_ELEMENTS_RO(iflist, node, ifp)) {
573 struct pim_interface *pim_ifp;
574 struct in_addr ifaddr;
583 if (pim_ifp->pim_sock_fd < 0)
586 ifaddr = pim_ifp->primary_address;
588 pim_time_uptime_begin(dr_uptime, sizeof(dr_uptime),
589 now, pim_ifp->pim_dr_election_last);
591 pim_inet4_dump("<dr?>", pim_ifp->pim_dr_addr,
592 dr_str, sizeof(dr_str));
594 vty_out(vty, "%-9s %-15s %-15s %8s %9d %7d %6d %10d%s",
599 pim_ifp->pim_dr_election_count,
600 pim_ifp->pim_dr_election_changes,
601 pim_ifp->pim_dr_num_nondrpri_neighbors,
602 pim_ifp->pim_dr_priority,
607 static void pim_show_hello(struct vty *vty)
609 struct listnode *node;
610 struct interface *ifp;
613 now = pim_time_monotonic_sec();
615 vty_out(vty, "Interface Address Period Timer StatStart Recv Rfail Send Sfail%s", VTY_NEWLINE);
617 for (ALL_LIST_ELEMENTS_RO(iflist, node, ifp)) {
618 struct pim_interface *pim_ifp;
619 struct in_addr ifaddr;
620 char hello_period[10];
621 char hello_timer[10];
622 char stat_uptime[10];
629 if (pim_ifp->pim_sock_fd < 0)
632 ifaddr = pim_ifp->primary_address;
634 pim_time_timer_to_mmss(hello_timer, sizeof(hello_timer), pim_ifp->t_pim_hello_timer);
635 pim_time_mmss(hello_period, sizeof(hello_period), pim_ifp->pim_hello_period);
636 pim_time_uptime(stat_uptime, sizeof(stat_uptime), now - pim_ifp->pim_ifstat_start);
638 vty_out(vty, "%-9s %-15s %6s %5s %9s %4u %5u %4u %5u%s",
644 pim_ifp->pim_ifstat_hello_recv,
645 pim_ifp->pim_ifstat_hello_recvfail,
646 pim_ifp->pim_ifstat_hello_sent,
647 pim_ifp->pim_ifstat_hello_sendfail,
652 static void pim_show_interfaces(struct vty *vty)
654 struct listnode *node;
655 struct interface *ifp;
658 now = pim_time_monotonic_sec();
660 vty_out(vty, "Interface Address ifIndex Socket Uptime Multi Broad MLoop AllMu Prmsc Del%s", VTY_NEWLINE);
662 for (ALL_LIST_ELEMENTS_RO(iflist, node, ifp)) {
663 struct pim_interface *pim_ifp;
664 struct in_addr ifaddr;
673 if (pim_ifp->pim_sock_fd < 0)
676 ifaddr = pim_ifp->primary_address;
678 pim_time_uptime(uptime, sizeof(uptime), now - pim_ifp->pim_sock_creation);
680 mloop = pim_socket_mcastloop_get(pim_ifp->pim_sock_fd);
682 vty_out(vty, "%-9s %-15s %7d %6d %8s %5s %5s %5s %5s %5s %3s%s",
686 pim_ifp->pim_sock_fd,
688 if_is_multicast(ifp) ? "yes" : "no",
689 if_is_broadcast(ifp) ? "yes" : "no",
690 (mloop < 0) ? "?" : (mloop ? "yes" : "no"),
691 (ifp->flags & IFF_ALLMULTI) ? "yes" : "no",
692 (ifp->flags & IFF_PROMISC) ? "yes" : "no",
693 PIM_IF_IS_DELETED(ifp) ? "yes" : "no",
698 static void pim_show_join(struct vty *vty)
700 struct listnode *ifnode;
701 struct interface *ifp;
704 now = pim_time_monotonic_sec();
707 "Interface Address Source Group State Uptime Expire Prune%s",
710 for (ALL_LIST_ELEMENTS_RO(iflist, ifnode, ifp)) {
711 struct pim_interface *pim_ifp;
712 struct in_addr ifaddr;
713 struct listnode *ch_node;
714 struct pim_ifchannel *ch;
721 ifaddr = pim_ifp->primary_address;
723 for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_ifchannel_list, ch_node, ch)) {
724 char ch_src_str[100];
725 char ch_grp_str[100];
730 pim_inet4_dump("<ch_src?>", ch->source_addr,
731 ch_src_str, sizeof(ch_src_str));
732 pim_inet4_dump("<ch_grp?>", ch->group_addr,
733 ch_grp_str, sizeof(ch_grp_str));
735 pim_time_uptime_begin(uptime, sizeof(uptime), now, ch->ifjoin_creation);
736 pim_time_timer_to_mmss(expire, sizeof(expire),
737 ch->t_ifjoin_expiry_timer);
738 pim_time_timer_to_mmss(prune, sizeof(prune),
739 ch->t_ifjoin_prune_pending_timer);
741 vty_out(vty, "%-9s %-15s %-15s %-15s %-6s %8s %-6s %5s%s",
746 pim_ifchannel_ifjoin_name(ch->ifjoin_state),
751 } /* scan interface channels */
752 } /* scan interfaces */
756 static void pim_show_neighbors(struct vty *vty)
758 struct listnode *node;
759 struct interface *ifp;
762 now = pim_time_monotonic_sec();
765 "Recv flags: H=holdtime L=lan_prune_delay P=dr_priority G=generation_id A=address_list%s"
766 " T=can_disable_join_suppression%s%s",
767 VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
769 vty_out(vty, "Interface Address Neighbor Uptime Timer Holdt DrPri GenId Recv %s", VTY_NEWLINE);
771 for (ALL_LIST_ELEMENTS_RO(iflist, node, ifp)) {
772 struct pim_interface *pim_ifp;
773 struct in_addr ifaddr;
774 struct listnode *neighnode;
775 struct pim_neighbor *neigh;
782 if (pim_ifp->pim_sock_fd < 0)
785 ifaddr = pim_ifp->primary_address;
787 for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, neighnode, neigh)) {
791 char neigh_src_str[100];
794 pim_inet4_dump("<src?>", neigh->source_addr,
795 neigh_src_str, sizeof(neigh_src_str));
796 pim_time_uptime(uptime, sizeof(uptime), now - neigh->creation);
797 pim_time_mmss(holdtime, sizeof(holdtime), neigh->holdtime);
798 pim_time_timer_to_mmss(expire, sizeof(expire), neigh->t_expire_timer);
800 recv[0] = PIM_OPTION_IS_SET(neigh->hello_options, PIM_OPTION_MASK_HOLDTIME) ? 'H' : ' ';
801 recv[1] = PIM_OPTION_IS_SET(neigh->hello_options, PIM_OPTION_MASK_LAN_PRUNE_DELAY) ? 'L' : ' ';
802 recv[2] = PIM_OPTION_IS_SET(neigh->hello_options, PIM_OPTION_MASK_DR_PRIORITY) ? 'P' : ' ';
803 recv[3] = PIM_OPTION_IS_SET(neigh->hello_options, PIM_OPTION_MASK_GENERATION_ID) ? 'G' : ' ';
804 recv[4] = PIM_OPTION_IS_SET(neigh->hello_options, PIM_OPTION_MASK_ADDRESS_LIST) ? 'A' : ' ';
805 recv[5] = PIM_OPTION_IS_SET(neigh->hello_options, PIM_OPTION_MASK_CAN_DISABLE_JOIN_SUPPRESSION) ? 'T' : ' ';
808 vty_out(vty, "%-9s %-15s %-15s %8s %5s %5s %5u %08x %6s%s",
816 neigh->generation_id,
825 static void pim_show_lan_prune_delay(struct vty *vty)
827 struct listnode *node;
828 struct interface *ifp;
831 "PrDly=propagation_delay (msec) OvInt=override_interval (msec)%s"
832 "HiDly=highest_propagation_delay (msec) HiInt=highest_override_interval (msec)%s"
833 "NoDly=number_of_non_lan_delay_neighbors%s"
834 "T=t_bit LPD=lan_prune_delay_hello_option%s%s",
835 VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
837 vty_out(vty, "Interface Address PrDly OvInt NoDly HiDly HiInt T | Neighbor LPD PrDly OvInt T%s", VTY_NEWLINE);
839 for (ALL_LIST_ELEMENTS_RO(iflist, node, ifp)) {
840 struct pim_interface *pim_ifp;
841 struct in_addr ifaddr;
842 struct listnode *neighnode;
843 struct pim_neighbor *neigh;
850 if (pim_ifp->pim_sock_fd < 0)
853 ifaddr = pim_ifp->primary_address;
855 for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, neighnode, neigh)) {
856 char neigh_src_str[100];
858 pim_inet4_dump("<src?>", neigh->source_addr,
859 neigh_src_str, sizeof(neigh_src_str));
861 vty_out(vty, "%-9s %-15s %5u %5u %5u %5u %5u %1u | %-15s %-3s %5u %5u %1u%s",
864 pim_ifp->pim_propagation_delay_msec,
865 pim_ifp->pim_override_interval_msec,
866 pim_ifp->pim_number_of_nonlandelay_neighbors,
867 pim_ifp->pim_neighbors_highest_propagation_delay_msec,
868 pim_ifp->pim_neighbors_highest_override_interval_msec,
869 PIM_FORCE_BOOLEAN(PIM_IF_TEST_PIM_CAN_DISABLE_JOIN_SUPRESSION(pim_ifp->options)),
871 PIM_OPTION_IS_SET(neigh->hello_options, PIM_OPTION_MASK_LAN_PRUNE_DELAY) ? "yes" : "no",
872 neigh->propagation_delay_msec,
873 neigh->override_interval_msec,
874 PIM_FORCE_BOOLEAN(PIM_OPTION_IS_SET(neigh->hello_options,
875 PIM_OPTION_MASK_CAN_DISABLE_JOIN_SUPPRESSION)),
882 static void pim_show_jp_override_interval(struct vty *vty)
884 struct listnode *node;
885 struct interface *ifp;
888 "EffPDelay=effective_propagation_delay (msec)%s"
889 "EffOvrInt=override_interval (msec)%s"
890 "JPOvrInt=jp_override_interval (msec)%s%s",
891 VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
893 vty_out(vty, "Interface Address LAN_Delay EffPDelay EffOvrInt JPOvrInt%s", VTY_NEWLINE);
895 for (ALL_LIST_ELEMENTS_RO(iflist, node, ifp)) {
896 struct pim_interface *pim_ifp;
897 struct in_addr ifaddr;
904 if (pim_ifp->pim_sock_fd < 0)
907 ifaddr = pim_ifp->primary_address;
909 vty_out(vty, "%-9s %-15s %-9s %9u %9u %8u%s",
912 pim_if_lan_delay_enabled(ifp) ? "enabled" : "disabled",
913 pim_if_effective_propagation_delay_msec(ifp),
914 pim_if_effective_override_interval_msec(ifp),
915 pim_if_jp_override_interval_msec(ifp),
920 static void pim_show_neighbors_secondary(struct vty *vty)
922 struct listnode *node;
923 struct interface *ifp;
925 vty_out(vty, "Interface Address Neighbor Secondary %s", VTY_NEWLINE);
927 for (ALL_LIST_ELEMENTS_RO(iflist, node, ifp)) {
928 struct pim_interface *pim_ifp;
929 struct in_addr ifaddr;
930 struct listnode *neighnode;
931 struct pim_neighbor *neigh;
938 if (pim_ifp->pim_sock_fd < 0)
941 ifaddr = pim_ifp->primary_address;
943 for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, neighnode, neigh)) {
944 char neigh_src_str[100];
945 struct listnode *prefix_node;
948 if (!neigh->prefix_list)
951 pim_inet4_dump("<src?>", neigh->source_addr,
952 neigh_src_str, sizeof(neigh_src_str));
954 for (ALL_LIST_ELEMENTS_RO(neigh->prefix_list, prefix_node, p)) {
955 char neigh_sec_str[100];
957 if (p->family != AF_INET)
960 pim_inet4_dump("<src?>", p->u.prefix4,
961 neigh_sec_str, sizeof(neigh_sec_str));
963 vty_out(vty, "%-9s %-15s %-15s %-15s%s",
974 static void pim_show_upstream(struct vty *vty)
976 struct listnode *upnode;
977 struct pim_upstream *up;
980 now = pim_time_monotonic_sec();
982 vty_out(vty, "Source Group State Uptime JoinTimer RefCnt%s", VTY_NEWLINE);
984 for (ALL_LIST_ELEMENTS_RO(qpim_upstream_list, upnode, up)) {
990 pim_inet4_dump("<src?>", up->source_addr, src_str, sizeof(src_str));
991 pim_inet4_dump("<grp?>", up->group_addr, grp_str, sizeof(grp_str));
992 pim_time_uptime(uptime, sizeof(uptime), now - up->state_transition);
993 pim_time_timer_to_hhmmss(join_timer, sizeof(join_timer), up->t_join_timer);
995 vty_out(vty, "%-15s %-15s %-5s %-8s %-9s %6d%s",
998 up->join_state == PIM_UPSTREAM_JOINED ? "Jnd" : "NtJnd",
1006 static void pim_show_join_desired(struct vty *vty)
1008 struct listnode *ifnode;
1009 struct listnode *chnode;
1010 struct interface *ifp;
1011 struct pim_interface *pim_ifp;
1012 struct pim_ifchannel *ch;
1017 "Interface Source Group LostAssert Joins PimInclude JoinDesired EvalJD%s",
1020 /* scan all interfaces */
1021 for (ALL_LIST_ELEMENTS_RO(iflist, ifnode, ifp)) {
1022 pim_ifp = ifp->info;
1026 /* scan per-interface (S,G) state */
1027 for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_ifchannel_list, chnode, ch)) {
1028 struct pim_upstream *up = ch->upstream;
1030 pim_inet4_dump("<src?>", up->source_addr, src_str, sizeof(src_str));
1031 pim_inet4_dump("<grp?>", up->group_addr, grp_str, sizeof(grp_str));
1033 vty_out(vty, "%-9s %-15s %-15s %-10s %-5s %-10s %-11s %-6s%s",
1037 pim_macro_ch_lost_assert(ch) ? "yes" : "no",
1038 pim_macro_chisin_joins(ch) ? "yes" : "no",
1039 pim_macro_chisin_pim_include(ch) ? "yes" : "no",
1040 PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED(up->flags) ? "yes" : "no",
1041 pim_upstream_evaluate_join_desired(up) ? "yes" : "no",
1047 static void pim_show_upstream_rpf(struct vty *vty)
1049 struct listnode *upnode;
1050 struct pim_upstream *up;
1053 "Source Group RpfIface RibNextHop RpfAddress %s",
1056 for (ALL_LIST_ELEMENTS_RO(qpim_upstream_list, upnode, up)) {
1059 char rpf_nexthop_str[100];
1060 char rpf_addr_str[100];
1061 struct pim_rpf *rpf;
1062 const char *rpf_ifname;
1066 pim_inet4_dump("<src?>", up->source_addr, src_str, sizeof(src_str));
1067 pim_inet4_dump("<grp?>", up->group_addr, grp_str, sizeof(grp_str));
1068 pim_inet4_dump("<nexthop?>", rpf->source_nexthop.mrib_nexthop_addr, rpf_nexthop_str, sizeof(rpf_nexthop_str));
1069 pim_inet4_dump("<rpf?>", rpf->rpf_addr, rpf_addr_str, sizeof(rpf_addr_str));
1071 rpf_ifname = rpf->source_nexthop.interface ? rpf->source_nexthop.interface->name : "<ifname?>";
1073 vty_out(vty, "%-15s %-15s %-8s %-15s %-15s%s",
1083 static void show_rpf_refresh_stats(struct vty *vty, time_t now)
1085 char refresh_uptime[10];
1087 pim_time_uptime_begin(refresh_uptime, sizeof(refresh_uptime), now, qpim_rpf_cache_refresh_last);
1090 "RPF Cache Refresh Delay: %ld msecs%s"
1091 "RPF Cache Refresh Timer: %ld msecs%s"
1092 "RPF Cache Refresh Requests: %lld%s"
1093 "RPF Cache Refresh Events: %lld%s"
1094 "RPF Cache Refresh Last: %s%s",
1095 qpim_rpf_cache_refresh_delay_msec, VTY_NEWLINE,
1096 pim_time_timer_remain_msec(qpim_rpf_cache_refresher), VTY_NEWLINE,
1097 (long long)qpim_rpf_cache_refresh_requests, VTY_NEWLINE,
1098 (long long)qpim_rpf_cache_refresh_events, VTY_NEWLINE,
1099 refresh_uptime, VTY_NEWLINE);
1102 static void show_scan_oil_stats(struct vty *vty, time_t now)
1104 char uptime_scan_oil[10];
1105 char uptime_mroute_add[10];
1106 char uptime_mroute_del[10];
1108 pim_time_uptime_begin(uptime_scan_oil, sizeof(uptime_scan_oil), now, qpim_scan_oil_last);
1109 pim_time_uptime_begin(uptime_mroute_add, sizeof(uptime_mroute_add), now, qpim_mroute_add_last);
1110 pim_time_uptime_begin(uptime_mroute_del, sizeof(uptime_mroute_del), now, qpim_mroute_del_last);
1113 "Scan OIL - Last: %s Events: %lld%s"
1114 "MFC Add - Last: %s Events: %lld%s"
1115 "MFC Del - Last: %s Events: %lld%s",
1116 uptime_scan_oil, (long long) qpim_scan_oil_events, VTY_NEWLINE,
1117 uptime_mroute_add, (long long) qpim_mroute_add_events, VTY_NEWLINE,
1118 uptime_mroute_del, (long long) qpim_mroute_del_events, VTY_NEWLINE);
1121 static void pim_show_rpf(struct vty *vty)
1123 struct listnode *up_node;
1124 struct pim_upstream *up;
1125 time_t now = pim_time_monotonic_sec();
1127 show_rpf_refresh_stats(vty, now);
1129 vty_out(vty, "%s", VTY_NEWLINE);
1132 "Source Group RpfIface RpfAddress RibNextHop Metric Pref%s",
1135 for (ALL_LIST_ELEMENTS_RO(qpim_upstream_list, up_node, up)) {
1138 char rpf_addr_str[100];
1139 char rib_nexthop_str[100];
1140 const char *rpf_ifname;
1141 struct pim_rpf *rpf = &up->rpf;
1143 pim_inet4_dump("<src?>", up->source_addr, src_str, sizeof(src_str));
1144 pim_inet4_dump("<grp?>", up->group_addr, grp_str, sizeof(grp_str));
1145 pim_inet4_dump("<rpf?>", rpf->rpf_addr, rpf_addr_str, sizeof(rpf_addr_str));
1146 pim_inet4_dump("<nexthop?>", rpf->source_nexthop.mrib_nexthop_addr, rib_nexthop_str, sizeof(rib_nexthop_str));
1148 rpf_ifname = rpf->source_nexthop.interface ? rpf->source_nexthop.interface->name : "<ifname?>";
1150 vty_out(vty, "%-15s %-15s %-8s %-15s %-15s %6d %4d%s",
1156 rpf->source_nexthop.mrib_route_metric,
1157 rpf->source_nexthop.mrib_metric_preference,
1162 static void igmp_show_querier(struct vty *vty)
1164 struct listnode *node;
1165 struct interface *ifp;
1167 vty_out(vty, "Interface Address Querier StartCount Query-Timer Other-Timer%s", VTY_NEWLINE);
1169 for (ALL_LIST_ELEMENTS_RO(iflist, node, ifp)) {
1170 struct pim_interface *pim_ifp = ifp->info;
1171 struct listnode *sock_node;
1172 struct igmp_sock *igmp;
1177 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
1178 char query_hhmmss[10];
1179 char other_hhmmss[10];
1181 pim_time_timer_to_hhmmss(query_hhmmss, sizeof(query_hhmmss), igmp->t_igmp_query_timer);
1182 pim_time_timer_to_hhmmss(other_hhmmss, sizeof(other_hhmmss), igmp->t_other_querier_timer);
1184 vty_out(vty, "%-9s %-15s %-7s %10d %11s %11s%s",
1186 inet_ntoa(igmp->ifaddr),
1187 igmp->t_igmp_query_timer ? "THIS" : "OTHER",
1188 igmp->startup_query_count,
1196 static void igmp_show_groups(struct vty *vty)
1198 struct listnode *ifnode;
1199 struct interface *ifp;
1202 now = pim_time_monotonic_sec();
1204 vty_out(vty, "Interface Address Group Mode Timer Srcs V Uptime %s", VTY_NEWLINE);
1206 /* scan interfaces */
1207 for (ALL_LIST_ELEMENTS_RO(iflist, ifnode, ifp)) {
1208 struct pim_interface *pim_ifp = ifp->info;
1209 struct listnode *sock_node;
1210 struct igmp_sock *igmp;
1215 /* scan igmp sockets */
1216 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
1217 char ifaddr_str[100];
1218 struct listnode *grpnode;
1219 struct igmp_group *grp;
1221 pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str, sizeof(ifaddr_str));
1223 /* scan igmp groups */
1224 for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grpnode, grp)) {
1225 char group_str[100];
1229 pim_inet4_dump("<group?>", grp->group_addr, group_str, sizeof(group_str));
1230 pim_time_timer_to_hhmmss(hhmmss, sizeof(hhmmss), grp->t_group_timer);
1231 pim_time_uptime(uptime, sizeof(uptime), now - grp->group_creation);
1233 vty_out(vty, "%-9s %-15s %-15s %4s %8s %4d %d %8s%s",
1237 grp->group_filtermode_isexcl ? "EXCL" : "INCL",
1239 grp->group_source_list ? listcount(grp->group_source_list) : 0,
1240 igmp_group_compat_mode(igmp, grp),
1244 } /* scan igmp groups */
1245 } /* scan igmp sockets */
1246 } /* scan interfaces */
1249 static void igmp_show_group_retransmission(struct vty *vty)
1251 struct listnode *ifnode;
1252 struct interface *ifp;
1254 vty_out(vty, "Interface Address Group RetTimer Counter RetSrcs%s", VTY_NEWLINE);
1256 /* scan interfaces */
1257 for (ALL_LIST_ELEMENTS_RO(iflist, ifnode, ifp)) {
1258 struct pim_interface *pim_ifp = ifp->info;
1259 struct listnode *sock_node;
1260 struct igmp_sock *igmp;
1265 /* scan igmp sockets */
1266 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
1267 char ifaddr_str[100];
1268 struct listnode *grpnode;
1269 struct igmp_group *grp;
1271 pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str, sizeof(ifaddr_str));
1273 /* scan igmp groups */
1274 for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grpnode, grp)) {
1275 char group_str[100];
1276 char grp_retr_mmss[10];
1277 struct listnode *src_node;
1278 struct igmp_source *src;
1279 int grp_retr_sources = 0;
1281 pim_inet4_dump("<group?>", grp->group_addr, group_str, sizeof(group_str));
1282 pim_time_timer_to_mmss(grp_retr_mmss, sizeof(grp_retr_mmss), grp->t_group_query_retransmit_timer);
1285 /* count group sources with retransmission state */
1286 for (ALL_LIST_ELEMENTS_RO(grp->group_source_list, src_node, src)) {
1287 if (src->source_query_retransmit_count > 0) {
1292 vty_out(vty, "%-9s %-15s %-15s %-8s %7d %7d%s",
1297 grp->group_specific_query_retransmit_count,
1301 } /* scan igmp groups */
1302 } /* scan igmp sockets */
1303 } /* scan interfaces */
1306 static void igmp_show_parameters(struct vty *vty)
1308 struct listnode *ifnode;
1309 struct interface *ifp;
1312 "QRV: Robustness Variable SQI: Startup Query Interval%s"
1313 "QQI: Query Interval OQPI: Other Querier Present Interval%s"
1314 "QRI: Query Response Interval LMQT: Last Member Query Time%s"
1315 "GMI: Group Membership Interval OHPI: Older Host Present Interval%s%s",
1316 VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
1319 "Interface Address QRV QQI QRI GMI SQI OQPI LMQT OHPI %s",
1322 /* scan interfaces */
1323 for (ALL_LIST_ELEMENTS_RO(iflist, ifnode, ifp)) {
1324 struct pim_interface *pim_ifp = ifp->info;
1325 struct listnode *sock_node;
1326 struct igmp_sock *igmp;
1331 /* scan igmp sockets */
1332 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
1333 char ifaddr_str[100];
1334 long gmi_dsec; /* Group Membership Interval */
1335 long oqpi_dsec; /* Other Querier Present Interval */
1341 pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str, sizeof(ifaddr_str));
1343 gmi_dsec = PIM_IGMP_GMI_MSEC(igmp->querier_robustness_variable,
1344 igmp->querier_query_interval,
1345 pim_ifp->igmp_query_max_response_time_dsec) / 100;
1347 sqi = PIM_IGMP_SQI(pim_ifp->igmp_default_query_interval);
1349 oqpi_dsec = PIM_IGMP_OQPI_MSEC(igmp->querier_robustness_variable,
1350 igmp->querier_query_interval,
1351 pim_ifp->igmp_query_max_response_time_dsec) / 100;
1353 lmqt_dsec = PIM_IGMP_LMQT_MSEC(pim_ifp->igmp_query_max_response_time_dsec,
1354 igmp->querier_robustness_variable) / 100;
1356 ohpi_dsec = PIM_IGMP_OHPI_DSEC(igmp->querier_robustness_variable,
1357 igmp->querier_query_interval,
1358 pim_ifp->igmp_query_max_response_time_dsec);
1360 qri_dsec = pim_ifp->igmp_query_max_response_time_dsec;
1363 "%-9s %-15s %3d %3d %3ld.%ld %3ld.%ld %3d %3ld.%ld %3ld.%ld %3ld.%ld%s",
1366 igmp->querier_robustness_variable,
1367 igmp->querier_query_interval,
1368 qri_dsec / 10, qri_dsec % 10,
1369 gmi_dsec / 10, gmi_dsec % 10,
1371 oqpi_dsec / 10, oqpi_dsec % 10,
1372 lmqt_dsec / 10, lmqt_dsec % 10,
1373 ohpi_dsec / 10, ohpi_dsec % 10,
1376 } /* scan igmp sockets */
1377 } /* scan interfaces */
1380 static void igmp_show_sources(struct vty *vty)
1382 struct listnode *ifnode;
1383 struct interface *ifp;
1386 now = pim_time_monotonic_sec();
1388 vty_out(vty, "Interface Address Group Source Timer Fwd Uptime %s", VTY_NEWLINE);
1390 /* scan interfaces */
1391 for (ALL_LIST_ELEMENTS_RO(iflist, ifnode, ifp)) {
1392 struct pim_interface *pim_ifp = ifp->info;
1393 struct listnode *sock_node;
1394 struct igmp_sock *igmp;
1399 /* scan igmp sockets */
1400 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
1401 char ifaddr_str[100];
1402 struct listnode *grpnode;
1403 struct igmp_group *grp;
1405 pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str, sizeof(ifaddr_str));
1407 /* scan igmp groups */
1408 for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grpnode, grp)) {
1409 char group_str[100];
1410 struct listnode *srcnode;
1411 struct igmp_source *src;
1413 pim_inet4_dump("<group?>", grp->group_addr, group_str, sizeof(group_str));
1415 /* scan group sources */
1416 for (ALL_LIST_ELEMENTS_RO(grp->group_source_list, srcnode, src)) {
1417 char source_str[100];
1421 pim_inet4_dump("<source?>", src->source_addr, source_str, sizeof(source_str));
1423 pim_time_timer_to_mmss(mmss, sizeof(mmss), src->t_source_timer);
1425 pim_time_uptime(uptime, sizeof(uptime), now - src->source_creation);
1427 vty_out(vty, "%-9s %-15s %-15s %-15s %5s %3s %8s%s",
1433 IGMP_SOURCE_TEST_FORWARDING(src->source_flags) ? "Y" : "N",
1437 } /* scan group sources */
1438 } /* scan igmp groups */
1439 } /* scan igmp sockets */
1440 } /* scan interfaces */
1443 static void igmp_show_source_retransmission(struct vty *vty)
1445 struct listnode *ifnode;
1446 struct interface *ifp;
1448 vty_out(vty, "Interface Address Group Source Counter%s", VTY_NEWLINE);
1450 /* scan interfaces */
1451 for (ALL_LIST_ELEMENTS_RO(iflist, ifnode, ifp)) {
1452 struct pim_interface *pim_ifp = ifp->info;
1453 struct listnode *sock_node;
1454 struct igmp_sock *igmp;
1459 /* scan igmp sockets */
1460 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
1461 char ifaddr_str[100];
1462 struct listnode *grpnode;
1463 struct igmp_group *grp;
1465 pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str, sizeof(ifaddr_str));
1467 /* scan igmp groups */
1468 for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grpnode, grp)) {
1469 char group_str[100];
1470 struct listnode *srcnode;
1471 struct igmp_source *src;
1473 pim_inet4_dump("<group?>", grp->group_addr, group_str, sizeof(group_str));
1475 /* scan group sources */
1476 for (ALL_LIST_ELEMENTS_RO(grp->group_source_list, srcnode, src)) {
1477 char source_str[100];
1479 pim_inet4_dump("<source?>", src->source_addr, source_str, sizeof(source_str));
1481 vty_out(vty, "%-9s %-15s %-15s %-15s %7d%s",
1486 src->source_query_retransmit_count,
1489 } /* scan group sources */
1490 } /* scan igmp groups */
1491 } /* scan igmp sockets */
1492 } /* scan interfaces */
1495 static void clear_igmp_interfaces()
1497 struct listnode *ifnode;
1498 struct listnode *ifnextnode;
1499 struct interface *ifp;
1501 for (ALL_LIST_ELEMENTS(iflist, ifnode, ifnextnode, ifp)) {
1502 pim_if_addr_del_all_igmp(ifp);
1505 for (ALL_LIST_ELEMENTS(iflist, ifnode, ifnextnode, ifp)) {
1506 pim_if_addr_add_all(ifp);
1510 static void clear_pim_interfaces()
1512 struct listnode *ifnode;
1513 struct listnode *ifnextnode;
1514 struct interface *ifp;
1516 for (ALL_LIST_ELEMENTS(iflist, ifnode, ifnextnode, ifp)) {
1518 pim_neighbor_delete_all(ifp, "interface cleared");
1523 static void clear_interfaces()
1525 clear_igmp_interfaces();
1526 clear_pim_interfaces();
1529 DEFUN (pim_interface,
1532 "Select an interface to configure\n"
1533 "Interface's name\n")
1535 struct interface *ifp;
1536 const char *ifname = argv[0];
1539 sl = strlen(ifname);
1540 if (sl > INTERFACE_NAMSIZ) {
1541 vty_out(vty, "%% Interface name %s is invalid: length exceeds "
1543 ifname, INTERFACE_NAMSIZ, VTY_NEWLINE);
1547 ifp = if_lookup_by_name_len(ifname, sl);
1549 vty_out(vty, "%% Interface %s does not exist%s", ifname, VTY_NEWLINE);
1551 /* Returning here would prevent pimd from booting when there are
1552 interface commands in pimd.conf, since all interfaces are
1553 unknown at pimd boot time (the zebra daemon has not been
1554 contacted for interface discovery). */
1556 ifp = if_get_by_name_len(ifname, sl);
1558 vty_out(vty, "%% Could not create interface %s%s", ifname, VTY_NEWLINE);
1564 vty->node = INTERFACE_NODE;
1569 DEFUN (clear_ip_interfaces,
1570 clear_ip_interfaces_cmd,
1571 "clear ip interfaces",
1574 "Reset interfaces\n")
1581 DEFUN (clear_ip_igmp_interfaces,
1582 clear_ip_igmp_interfaces_cmd,
1583 "clear ip igmp interfaces",
1587 "Reset IGMP interfaces\n")
1589 clear_igmp_interfaces();
1594 static void mroute_add_all()
1596 struct listnode *node;
1597 struct channel_oil *c_oil;
1599 for (ALL_LIST_ELEMENTS_RO(qpim_channel_oil_list, node, c_oil)) {
1600 if (pim_mroute_add(&c_oil->oil)) {
1601 /* just log warning */
1602 char source_str[100];
1603 char group_str[100];
1604 pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, source_str, sizeof(source_str));
1605 pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
1606 zlog_warn("%s %s: (S,G)=(%s,%s) failure writing MFC",
1607 __FILE__, __PRETTY_FUNCTION__,
1608 source_str, group_str);
1613 static void mroute_del_all()
1615 struct listnode *node;
1616 struct channel_oil *c_oil;
1618 for (ALL_LIST_ELEMENTS_RO(qpim_channel_oil_list, node, c_oil)) {
1619 if (pim_mroute_del(&c_oil->oil)) {
1620 /* just log warning */
1621 char source_str[100];
1622 char group_str[100];
1623 pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, source_str, sizeof(source_str));
1624 pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
1625 zlog_warn("%s %s: (S,G)=(%s,%s) failure clearing MFC",
1626 __FILE__, __PRETTY_FUNCTION__,
1627 source_str, group_str);
1632 static void static_mroute_add_all()
1634 struct listnode *node;
1635 struct static_route *s_route;
1637 for (ALL_LIST_ELEMENTS_RO(qpim_static_route_list, node, s_route)) {
1638 if (pim_mroute_add(&s_route->mc)) {
1639 /* just log warning */
1640 char source_str[100];
1641 char group_str[100];
1642 pim_inet4_dump("<source?>", s_route->mc.mfcc_origin, source_str, sizeof(source_str));
1643 pim_inet4_dump("<group?>", s_route->mc.mfcc_mcastgrp, group_str, sizeof(group_str));
1644 zlog_warn("%s %s: (S,G)=(%s,%s) failure writing MFC",
1645 __FILE__, __PRETTY_FUNCTION__,
1646 source_str, group_str);
1651 static void static_mroute_del_all()
1653 struct listnode *node;
1654 struct static_route *s_route;
1656 for (ALL_LIST_ELEMENTS_RO(qpim_static_route_list, node, s_route)) {
1657 if (pim_mroute_del(&s_route->mc)) {
1658 /* just log warning */
1659 char source_str[100];
1660 char group_str[100];
1661 pim_inet4_dump("<source?>", s_route->mc.mfcc_origin, source_str, sizeof(source_str));
1662 pim_inet4_dump("<group?>", s_route->mc.mfcc_mcastgrp, group_str, sizeof(group_str));
1663 zlog_warn("%s %s: (S,G)=(%s,%s) failure clearing MFC",
1664 __FILE__, __PRETTY_FUNCTION__,
1665 source_str, group_str);
1670 DEFUN (clear_ip_mroute,
1671 clear_ip_mroute_cmd,
1675 "Reset multicast routes\n")
1683 DEFUN (clear_ip_pim_interfaces,
1684 clear_ip_pim_interfaces_cmd,
1685 "clear ip pim interfaces",
1689 "Reset PIM interfaces\n")
1691 clear_pim_interfaces();
1696 DEFUN (clear_ip_pim_oil,
1697 clear_ip_pim_oil_cmd,
1702 "Rescan PIM OIL (output interface list)\n")
1709 DEFUN (show_ip_igmp_interface,
1710 show_ip_igmp_interface_cmd,
1711 "show ip igmp interface",
1715 "IGMP interface information\n")
1717 igmp_show_interfaces(vty);
1722 DEFUN (show_ip_igmp_join,
1723 show_ip_igmp_join_cmd,
1724 "show ip igmp join",
1728 "IGMP static join information\n")
1730 igmp_show_interface_join(vty);
1735 DEFUN (show_ip_igmp_groups,
1736 show_ip_igmp_groups_cmd,
1737 "show ip igmp groups",
1743 igmp_show_groups(vty);
1748 DEFUN (show_ip_igmp_groups_retransmissions,
1749 show_ip_igmp_groups_retransmissions_cmd,
1750 "show ip igmp groups retransmissions",
1755 "IGMP group retransmissions\n")
1757 igmp_show_group_retransmission(vty);
1762 DEFUN (show_ip_igmp_parameters,
1763 show_ip_igmp_parameters_cmd,
1764 "show ip igmp parameters",
1768 "IGMP parameters information\n")
1770 igmp_show_parameters(vty);
1775 DEFUN (show_ip_igmp_sources,
1776 show_ip_igmp_sources_cmd,
1777 "show ip igmp sources",
1783 igmp_show_sources(vty);
1788 DEFUN (show_ip_igmp_sources_retransmissions,
1789 show_ip_igmp_sources_retransmissions_cmd,
1790 "show ip igmp sources retransmissions",
1795 "IGMP source retransmissions\n")
1797 igmp_show_source_retransmission(vty);
1802 DEFUN (show_ip_igmp_querier,
1803 show_ip_igmp_querier_cmd,
1804 "show ip igmp querier",
1808 "IGMP querier information\n")
1810 igmp_show_querier(vty);
1815 DEFUN (show_ip_pim_address,
1816 show_ip_pim_address_cmd,
1817 "show ip pim address",
1821 "PIM interface address\n")
1823 show_interface_address(vty);
1828 DEFUN (show_ip_pim_assert,
1829 show_ip_pim_assert_cmd,
1830 "show ip pim assert",
1834 "PIM interface assert\n")
1836 pim_show_assert(vty);
1841 DEFUN (show_ip_pim_assert_internal,
1842 show_ip_pim_assert_internal_cmd,
1843 "show ip pim assert-internal",
1847 "PIM interface internal assert state\n")
1849 pim_show_assert_internal(vty);
1854 DEFUN (show_ip_pim_assert_metric,
1855 show_ip_pim_assert_metric_cmd,
1856 "show ip pim assert-metric",
1860 "PIM interface assert metric\n")
1862 pim_show_assert_metric(vty);
1867 DEFUN (show_ip_pim_assert_winner_metric,
1868 show_ip_pim_assert_winner_metric_cmd,
1869 "show ip pim assert-winner-metric",
1873 "PIM interface assert winner metric\n")
1875 pim_show_assert_winner_metric(vty);
1880 DEFUN (show_ip_pim_dr,
1882 "show ip pim designated-router",
1886 "PIM interface designated router\n")
1893 DEFUN (show_ip_pim_hello,
1894 show_ip_pim_hello_cmd,
1895 "show ip pim hello",
1899 "PIM interface hello information\n")
1901 pim_show_hello(vty);
1906 DEFUN (show_ip_pim_interface,
1907 show_ip_pim_interface_cmd,
1908 "show ip pim interface",
1912 "PIM interface information\n")
1914 pim_show_interfaces(vty);
1919 DEFUN (show_ip_pim_join,
1920 show_ip_pim_join_cmd,
1925 "PIM interface join information\n")
1932 DEFUN (show_ip_pim_lan_prune_delay,
1933 show_ip_pim_lan_prune_delay_cmd,
1934 "show ip pim lan-prune-delay",
1938 "PIM neighbors LAN prune delay parameters\n")
1940 pim_show_lan_prune_delay(vty);
1945 DEFUN (show_ip_pim_local_membership,
1946 show_ip_pim_local_membership_cmd,
1947 "show ip pim local-membership",
1951 "PIM interface local-membership\n")
1953 pim_show_membership(vty);
1958 DEFUN (show_ip_pim_jp_override_interval,
1959 show_ip_pim_jp_override_interval_cmd,
1960 "show ip pim jp-override-interval",
1964 "PIM interface J/P override interval\n")
1966 pim_show_jp_override_interval(vty);
1971 DEFUN (show_ip_pim_neighbor,
1972 show_ip_pim_neighbor_cmd,
1973 "show ip pim neighbor",
1977 "PIM neighbor information\n")
1979 pim_show_neighbors(vty);
1984 DEFUN (show_ip_pim_secondary,
1985 show_ip_pim_secondary_cmd,
1986 "show ip pim secondary",
1990 "PIM neighbor addresses\n")
1992 pim_show_neighbors_secondary(vty);
1997 DEFUN (show_ip_pim_upstream,
1998 show_ip_pim_upstream_cmd,
1999 "show ip pim upstream",
2003 "PIM upstream information\n")
2005 pim_show_upstream(vty);
2010 DEFUN (show_ip_pim_upstream_join_desired,
2011 show_ip_pim_upstream_join_desired_cmd,
2012 "show ip pim upstream-join-desired",
2016 "PIM upstream join-desired\n")
2018 pim_show_join_desired(vty);
2023 DEFUN (show_ip_pim_upstream_rpf,
2024 show_ip_pim_upstream_rpf_cmd,
2025 "show ip pim upstream-rpf",
2029 "PIM upstream source rpf\n")
2031 pim_show_upstream_rpf(vty);
2036 DEFUN (show_ip_pim_rpf,
2037 show_ip_pim_rpf_cmd,
2042 "PIM cached source rpf information\n")
2049 static void show_multicast_interfaces(struct vty *vty)
2051 struct listnode *node;
2052 struct interface *ifp;
2054 vty_out(vty, "%s", VTY_NEWLINE);
2056 vty_out(vty, "Interface Address ifi Vif PktsIn PktsOut BytesIn BytesOut%s",
2059 for (ALL_LIST_ELEMENTS_RO(iflist, node, ifp)) {
2060 struct pim_interface *pim_ifp;
2061 struct in_addr ifaddr;
2062 struct sioc_vif_req vreq;
2064 pim_ifp = ifp->info;
2069 memset(&vreq, 0, sizeof(vreq));
2070 vreq.vifi = pim_ifp->mroute_vif_index;
2072 if (ioctl(qpim_mroute_socket_fd, SIOCGETVIFCNT, &vreq)) {
2073 zlog_warn("ioctl(SIOCGETVIFCNT=%lu) failure for interface %s vif_index=%d: errno=%d: %s%s",
2074 (unsigned long)SIOCGETVIFCNT,
2076 pim_ifp->mroute_vif_index,
2078 safe_strerror(errno),
2082 ifaddr = pim_ifp->primary_address;
2084 vty_out(vty, "%-9s %-15s %3d %3d %7lu %7lu %10lu %10lu%s",
2088 pim_ifp->mroute_vif_index,
2097 DEFUN (show_ip_multicast,
2098 show_ip_multicast_cmd,
2099 "show ip multicast",
2102 "Multicast global information\n")
2104 time_t now = pim_time_monotonic_sec();
2106 if (PIM_MROUTE_IS_ENABLED) {
2109 vty_out(vty, "Mroute socket descriptor: %d%s",
2110 qpim_mroute_socket_fd,
2113 pim_time_uptime(uptime, sizeof(uptime), now - qpim_mroute_socket_creation);
2114 vty_out(vty, "Mroute socket uptime: %s%s",
2119 vty_out(vty, "Multicast disabled%s",
2123 vty_out(vty, "%s", VTY_NEWLINE);
2124 vty_out(vty, "Zclient update socket: ");
2125 if (qpim_zclient_update) {
2126 vty_out(vty, "%d failures=%d%s", qpim_zclient_update->sock,
2127 qpim_zclient_update->fail, VTY_NEWLINE);
2130 vty_out(vty, "<null zclient>%s", VTY_NEWLINE);
2132 vty_out(vty, "Zclient lookup socket: ");
2133 if (qpim_zclient_lookup) {
2134 vty_out(vty, "%d failures=%d%s", qpim_zclient_lookup->sock,
2135 qpim_zclient_lookup->fail, VTY_NEWLINE);
2138 vty_out(vty, "<null zclient>%s", VTY_NEWLINE);
2141 vty_out(vty, "%s", VTY_NEWLINE);
2142 vty_out(vty, "Current highest VifIndex: %d%s",
2143 qpim_mroute_oif_highest_vif_index,
2145 vty_out(vty, "Maximum highest VifIndex: %d%s",
2149 vty_out(vty, "%s", VTY_NEWLINE);
2150 vty_out(vty, "Upstream Join Timer: %d secs%s",
2153 vty_out(vty, "Join/Prune Holdtime: %d secs%s",
2157 vty_out(vty, "%s", VTY_NEWLINE);
2159 show_rpf_refresh_stats(vty, now);
2161 vty_out(vty, "%s", VTY_NEWLINE);
2163 show_scan_oil_stats(vty, now);
2165 show_multicast_interfaces(vty);
2170 static void show_mroute(struct vty *vty)
2172 struct listnode *node;
2173 struct channel_oil *c_oil;
2174 struct static_route *s_route;
2177 vty_out(vty, "Proto: I=IGMP P=PIM S=STATIC%s%s", VTY_NEWLINE, VTY_NEWLINE);
2179 vty_out(vty, "Source Group Proto Input iVifI Output oVifI TTL Uptime %s",
2182 now = pim_time_monotonic_sec();
2184 /* print list of PIM and IGMP routes */
2185 for (ALL_LIST_ELEMENTS_RO(qpim_channel_oil_list, node, c_oil)) {
2186 char group_str[100];
2187 char source_str[100];
2190 pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
2191 pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, source_str, sizeof(source_str));
2193 for (oif_vif_index = 0; oif_vif_index < MAXVIFS; ++oif_vif_index) {
2194 struct interface *ifp_in;
2195 struct interface *ifp_out;
2196 char oif_uptime[10];
2200 ttl = c_oil->oil.mfcc_ttls[oif_vif_index];
2204 ifp_in = pim_if_find_by_vif_index(c_oil->oil.mfcc_parent);
2205 ifp_out = pim_if_find_by_vif_index(oif_vif_index);
2207 pim_time_uptime(oif_uptime, sizeof(oif_uptime), now - c_oil->oif_creation[oif_vif_index]);
2210 if (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_PIM) {
2213 if (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_IGMP) {
2217 vty_out(vty, "%-15s %-15s %-5s %-5s %5d %-6s %5d %3d %8s %s",
2221 ifp_in ? ifp_in->name : "<iif?>",
2222 c_oil->oil.mfcc_parent,
2223 ifp_out ? ifp_out->name : "<oif?>",
2231 /* Print list of static routes */
2232 for (ALL_LIST_ELEMENTS_RO(qpim_static_route_list, node, s_route)) {
2233 char group_str[100];
2234 char source_str[100];
2237 pim_inet4_dump("<group?>", s_route->group, group_str, sizeof(group_str));
2238 pim_inet4_dump("<source?>", s_route->source, source_str, sizeof(source_str));
2240 for (oif_vif_index = 0; oif_vif_index < MAXVIFS; ++oif_vif_index) {
2241 struct interface *ifp_in;
2242 struct interface *ifp_out;
2243 char oif_uptime[10];
2247 ttl = s_route->oif_ttls[oif_vif_index];
2251 ifp_in = pim_if_find_by_vif_index(s_route->iif);
2252 ifp_out = pim_if_find_by_vif_index(oif_vif_index);
2254 pim_time_uptime(oif_uptime, sizeof(oif_uptime), now - s_route->creation[oif_vif_index]);
2259 vty_out(vty, "%-15s %-15s %-5s %-5s %5d %-6s %5d %3d %8s %s",
2263 ifp_in ? ifp_in->name : "<iif?>",
2265 ifp_out ? ifp_out->name : "<oif?>",
2274 DEFUN (show_ip_mroute,
2285 static void show_mroute_count(struct vty *vty)
2287 struct listnode *node;
2288 struct channel_oil *c_oil;
2289 struct static_route *s_route;
2291 vty_out(vty, "%s", VTY_NEWLINE);
2293 vty_out(vty, "Source Group Packets Bytes WrongIf %s",
2296 /* Print PIM and IGMP route counts */
2297 for (ALL_LIST_ELEMENTS_RO(qpim_channel_oil_list, node, c_oil)) {
2298 char group_str[100];
2299 char source_str[100];
2300 struct sioc_sg_req sgreq;
2302 memset(&sgreq, 0, sizeof(sgreq));
2303 sgreq.src = c_oil->oil.mfcc_origin;
2304 sgreq.grp = c_oil->oil.mfcc_mcastgrp;
2306 pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
2307 pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, source_str, sizeof(source_str));
2309 if (ioctl(qpim_mroute_socket_fd, SIOCGETSGCNT, &sgreq)) {
2312 "ioctl(SIOCGETSGCNT=%lu) failure for (S,G)=(%s,%s): errno=%d: %s%s",
2313 (unsigned long)SIOCGETSGCNT,
2322 vty_out(vty, "%-15s %-15s %7ld %10ld %7ld %s",
2331 /* Print static route counts */
2332 for (ALL_LIST_ELEMENTS_RO(qpim_static_route_list, node, s_route)) {
2333 char group_str[100];
2334 char source_str[100];
2335 struct sioc_sg_req sgreq;
2337 memset(&sgreq, 0, sizeof(sgreq));
2338 sgreq.src = s_route->mc.mfcc_origin;
2339 sgreq.grp = s_route->mc.mfcc_mcastgrp;
2341 pim_inet4_dump("<group?>", s_route->mc.mfcc_mcastgrp, group_str, sizeof(group_str));
2342 pim_inet4_dump("<source?>", s_route->mc.mfcc_origin, source_str, sizeof(source_str));
2344 if (ioctl(qpim_mroute_socket_fd, SIOCGETSGCNT, &sgreq)) {
2347 "ioctl(SIOCGETSGCNT=%lu) failure for (S,G)=(%s,%s): errno=%d: %s%s",
2348 /* note that typeof ioctl defs can vary across platforms, from
2349 * int, to unsigned int, to long unsigned int
2351 (unsigned long)SIOCGETSGCNT,
2360 vty_out(vty, "%-15s %-15s %7ld %10ld %7ld %s",
2370 DEFUN (show_ip_mroute_count,
2371 show_ip_mroute_count_cmd,
2372 "show ip mroute count",
2376 "Route and packet count data\n")
2378 show_mroute_count(vty);
2384 "show ip rib A.B.C.D",
2388 "Unicast address\n")
2390 struct in_addr addr;
2391 const char *addr_str;
2392 struct pim_nexthop nexthop;
2393 char nexthop_addr_str[100];
2397 result = inet_pton(AF_INET, addr_str, &addr);
2399 vty_out(vty, "Bad unicast address %s: errno=%d: %s%s",
2400 addr_str, errno, safe_strerror(errno), VTY_NEWLINE);
2404 if (pim_nexthop_lookup(&nexthop, addr)) {
2405 vty_out(vty, "Failure querying RIB nexthop for unicast address %s%s",
2406 addr_str, VTY_NEWLINE);
2410 vty_out(vty, "Address NextHop Interface Metric Preference%s",
2413 pim_inet4_dump("<nexthop?>", nexthop.mrib_nexthop_addr,
2414 nexthop_addr_str, sizeof(nexthop_addr_str));
2416 vty_out(vty, "%-15s %-15s %-9s %6d %10d%s",
2419 nexthop.interface ? nexthop.interface->name : "<ifname?>",
2420 nexthop.mrib_route_metric,
2421 nexthop.mrib_metric_preference,
2427 static void show_ssmpingd(struct vty *vty)
2429 struct listnode *node;
2430 struct ssmpingd_sock *ss;
2433 vty_out(vty, "Source Socket Address Port Uptime Requests%s",
2436 if (!qpim_ssmpingd_list)
2439 now = pim_time_monotonic_sec();
2441 for (ALL_LIST_ELEMENTS_RO(qpim_ssmpingd_list, node, ss)) {
2442 char source_str[100];
2444 struct sockaddr_in bind_addr;
2445 socklen_t len = sizeof(bind_addr);
2446 char bind_addr_str[100];
2448 pim_inet4_dump("<src?>", ss->source_addr, source_str, sizeof(source_str));
2450 if (pim_socket_getsockname(ss->sock_fd, (struct sockaddr *) &bind_addr, &len)) {
2451 vty_out(vty, "%% Failure reading socket name for ssmpingd source %s on fd=%d%s",
2452 source_str, ss->sock_fd, VTY_NEWLINE);
2455 pim_inet4_dump("<addr?>", bind_addr.sin_addr, bind_addr_str, sizeof(bind_addr_str));
2456 pim_time_uptime(ss_uptime, sizeof(ss_uptime), now - ss->creation);
2458 vty_out(vty, "%-15s %6d %-15s %5d %8s %8lld%s",
2462 ntohs(bind_addr.sin_port),
2464 (long long)ss->requests,
2469 DEFUN (show_ip_ssmpingd,
2470 show_ip_ssmpingd_cmd,
2480 DEFUN (ip_multicast_routing,
2481 ip_multicast_routing_cmd,
2482 PIM_CMD_IP_MULTICAST_ROUTING,
2484 "Enable IP multicast forwarding\n")
2486 pim_mroute_socket_enable();
2487 pim_if_add_vif_all();
2489 static_mroute_add_all();
2493 DEFUN (no_ip_multicast_routing,
2494 no_ip_multicast_routing_cmd,
2495 PIM_CMD_NO " " PIM_CMD_IP_MULTICAST_ROUTING,
2498 "Global IP configuration subcommands\n"
2499 "Enable IP multicast forwarding\n")
2502 static_mroute_del_all();
2503 pim_if_del_vif_all();
2504 pim_mroute_socket_disable();
2510 "ip ssmpingd [A.B.C.D]",
2516 struct in_addr source_addr;
2517 const char *source_str = (argc > 0) ? argv[0] : "0.0.0.0";
2519 result = inet_pton(AF_INET, source_str, &source_addr);
2521 vty_out(vty, "%% Bad source address %s: errno=%d: %s%s",
2522 source_str, errno, safe_strerror(errno), VTY_NEWLINE);
2526 result = pim_ssmpingd_start(source_addr);
2528 vty_out(vty, "%% Failure starting ssmpingd for source %s: %d%s",
2529 source_str, result, VTY_NEWLINE);
2536 DEFUN (no_ip_ssmpingd,
2538 "no ip ssmpingd [A.B.C.D]",
2545 struct in_addr source_addr;
2546 const char *source_str = (argc > 0) ? argv[0] : "0.0.0.0";
2548 result = inet_pton(AF_INET, source_str, &source_addr);
2550 vty_out(vty, "%% Bad source address %s: errno=%d: %s%s",
2551 source_str, errno, safe_strerror(errno), VTY_NEWLINE);
2555 result = pim_ssmpingd_stop(source_addr);
2557 vty_out(vty, "%% Failure stopping ssmpingd for source %s: %d%s",
2558 source_str, result, VTY_NEWLINE);
2565 DEFUN (interface_ip_igmp,
2566 interface_ip_igmp_cmd,
2571 struct interface *ifp;
2572 struct pim_interface *pim_ifp;
2575 pim_ifp = ifp->info;
2578 pim_ifp = pim_if_new(ifp, 1 /* igmp=true */, 0 /* pim=false */);
2580 vty_out(vty, "Could not enable IGMP on interface %s%s",
2581 ifp->name, VTY_NEWLINE);
2586 PIM_IF_DO_IGMP(pim_ifp->options);
2589 pim_if_addr_add_all(ifp);
2590 pim_if_membership_refresh(ifp);
2595 DEFUN (interface_no_ip_igmp,
2596 interface_no_ip_igmp_cmd,
2602 struct interface *ifp;
2603 struct pim_interface *pim_ifp;
2606 pim_ifp = ifp->info;
2610 PIM_IF_DONT_IGMP(pim_ifp->options);
2612 pim_if_membership_clear(ifp);
2614 pim_if_addr_del_all_igmp(ifp);
2616 if (!PIM_IF_TEST_PIM(pim_ifp->options)) {
2623 DEFUN (interface_ip_igmp_join,
2624 interface_ip_igmp_join_cmd,
2625 "ip igmp join A.B.C.D A.B.C.D",
2628 "IGMP join multicast group\n"
2629 "Multicast group address\n"
2632 struct interface *ifp;
2633 const char *group_str;
2634 const char *source_str;
2635 struct in_addr group_addr;
2636 struct in_addr source_addr;
2642 group_str = argv[0];
2643 result = inet_pton(AF_INET, group_str, &group_addr);
2645 vty_out(vty, "Bad group address %s: errno=%d: %s%s",
2646 group_str, errno, safe_strerror(errno), VTY_NEWLINE);
2650 /* Source address */
2651 source_str = argv[1];
2652 result = inet_pton(AF_INET, source_str, &source_addr);
2654 vty_out(vty, "Bad source address %s: errno=%d: %s%s",
2655 source_str, errno, safe_strerror(errno), VTY_NEWLINE);
2659 result = pim_if_igmp_join_add(ifp, group_addr, source_addr);
2661 vty_out(vty, "%% Failure joining IGMP group %s source %s on interface %s: %d%s",
2662 group_str, source_str, ifp->name, result, VTY_NEWLINE);
2669 DEFUN (interface_no_ip_igmp_join,
2670 interface_no_ip_igmp_join_cmd,
2671 "no ip igmp join A.B.C.D A.B.C.D",
2675 "IGMP join multicast group\n"
2676 "Multicast group address\n"
2679 struct interface *ifp;
2680 const char *group_str;
2681 const char *source_str;
2682 struct in_addr group_addr;
2683 struct in_addr source_addr;
2689 group_str = argv[0];
2690 result = inet_pton(AF_INET, group_str, &group_addr);
2692 vty_out(vty, "Bad group address %s: errno=%d: %s%s",
2693 group_str, errno, safe_strerror(errno), VTY_NEWLINE);
2697 /* Source address */
2698 source_str = argv[1];
2699 result = inet_pton(AF_INET, source_str, &source_addr);
2701 vty_out(vty, "Bad source address %s: errno=%d: %s%s",
2702 source_str, errno, safe_strerror(errno), VTY_NEWLINE);
2706 result = pim_if_igmp_join_del(ifp, group_addr, source_addr);
2708 vty_out(vty, "%% Failure leaving IGMP group %s source %s on interface %s: %d%s",
2709 group_str, source_str, ifp->name, result, VTY_NEWLINE);
2717 CLI reconfiguration affects the interface level (struct pim_interface).
2718 This function propagates the reconfiguration to every active socket
2721 static void igmp_sock_query_interval_reconfig(struct igmp_sock *igmp)
2723 struct interface *ifp;
2724 struct pim_interface *pim_ifp;
2728 /* other querier present? */
2730 if (igmp->t_other_querier_timer)
2733 /* this is the querier */
2735 zassert(igmp->interface);
2736 zassert(igmp->interface->info);
2738 ifp = igmp->interface;
2739 pim_ifp = ifp->info;
2741 if (PIM_DEBUG_IGMP_TRACE) {
2742 char ifaddr_str[100];
2743 pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str, sizeof(ifaddr_str));
2744 zlog_debug("%s: Querier %s on %s reconfig query_interval=%d",
2745 __PRETTY_FUNCTION__,
2748 pim_ifp->igmp_default_query_interval);
2752 igmp_startup_mode_on() will reset QQI:
2754 igmp->querier_query_interval = pim_ifp->igmp_default_query_interval;
2756 igmp_startup_mode_on(igmp);
2759 static void igmp_sock_query_reschedule(struct igmp_sock *igmp)
2761 if (igmp->t_igmp_query_timer) {
2762 /* other querier present */
2763 zassert(igmp->t_igmp_query_timer);
2764 zassert(!igmp->t_other_querier_timer);
2766 pim_igmp_general_query_off(igmp);
2767 pim_igmp_general_query_on(igmp);
2769 zassert(igmp->t_igmp_query_timer);
2770 zassert(!igmp->t_other_querier_timer);
2773 /* this is the querier */
2775 zassert(!igmp->t_igmp_query_timer);
2776 zassert(igmp->t_other_querier_timer);
2778 pim_igmp_other_querier_timer_off(igmp);
2779 pim_igmp_other_querier_timer_on(igmp);
2781 zassert(!igmp->t_igmp_query_timer);
2782 zassert(igmp->t_other_querier_timer);
2786 static void change_query_interval(struct pim_interface *pim_ifp,
2789 struct listnode *sock_node;
2790 struct igmp_sock *igmp;
2792 pim_ifp->igmp_default_query_interval = query_interval;
2794 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
2795 igmp_sock_query_interval_reconfig(igmp);
2796 igmp_sock_query_reschedule(igmp);
2800 static void change_query_max_response_time(struct pim_interface *pim_ifp,
2801 int query_max_response_time_dsec)
2803 struct listnode *sock_node;
2804 struct igmp_sock *igmp;
2806 pim_ifp->igmp_query_max_response_time_dsec = query_max_response_time_dsec;
2809 Below we modify socket/group/source timers in order to quickly
2810 reflect the change. Otherwise, those timers would eventually catch
2814 /* scan all sockets */
2815 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
2816 struct listnode *grp_node;
2817 struct igmp_group *grp;
2819 /* reschedule socket general query */
2820 igmp_sock_query_reschedule(igmp);
2822 /* scan socket groups */
2823 for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grp_node, grp)) {
2824 struct listnode *src_node;
2825 struct igmp_source *src;
2827 /* reset group timers for groups in EXCLUDE mode */
2828 if (grp->group_filtermode_isexcl) {
2829 igmp_group_reset_gmi(grp);
2832 /* scan group sources */
2833 for (ALL_LIST_ELEMENTS_RO(grp->group_source_list, src_node, src)) {
2835 /* reset source timers for sources with running timers */
2836 if (src->t_source_timer) {
2837 igmp_source_reset_gmi(igmp, grp, src);
2844 #define IGMP_QUERY_INTERVAL_MIN (1)
2845 #define IGMP_QUERY_INTERVAL_MAX (1800)
2847 DEFUN (interface_ip_igmp_query_interval,
2848 interface_ip_igmp_query_interval_cmd,
2849 PIM_CMD_IP_IGMP_QUERY_INTERVAL " <1-1800>",
2852 IFACE_IGMP_QUERY_INTERVAL_STR
2853 "Query interval in seconds\n")
2855 struct interface *ifp;
2856 struct pim_interface *pim_ifp;
2858 int query_interval_dsec;
2861 pim_ifp = ifp->info;
2865 "IGMP not enabled on interface %s. Please enable IGMP first.%s",
2871 query_interval = atoi(argv[0]);
2872 query_interval_dsec = 10 * query_interval;
2875 It seems we don't need to check bounds since command.c does it
2876 already, but we verify them anyway for extra safety.
2878 if (query_interval < IGMP_QUERY_INTERVAL_MIN) {
2879 vty_out(vty, "General query interval %d lower than minimum %d%s",
2881 IGMP_QUERY_INTERVAL_MIN,
2885 if (query_interval > IGMP_QUERY_INTERVAL_MAX) {
2886 vty_out(vty, "General query interval %d higher than maximum %d%s",
2888 IGMP_QUERY_INTERVAL_MAX,
2893 if (query_interval_dsec <= pim_ifp->igmp_query_max_response_time_dsec) {
2895 "Can't set general query interval %d dsec <= query max response time %d dsec.%s",
2896 query_interval_dsec, pim_ifp->igmp_query_max_response_time_dsec,
2901 change_query_interval(pim_ifp, query_interval);
2906 DEFUN (interface_no_ip_igmp_query_interval,
2907 interface_no_ip_igmp_query_interval_cmd,
2908 PIM_CMD_NO " " PIM_CMD_IP_IGMP_QUERY_INTERVAL,
2912 IFACE_IGMP_QUERY_INTERVAL_STR)
2914 struct interface *ifp;
2915 struct pim_interface *pim_ifp;
2916 int default_query_interval_dsec;
2919 pim_ifp = ifp->info;
2924 default_query_interval_dsec = IGMP_GENERAL_QUERY_INTERVAL * 10;
2926 if (default_query_interval_dsec <= pim_ifp->igmp_query_max_response_time_dsec) {
2928 "Can't set default general query interval %d dsec <= query max response time %d dsec.%s",
2929 default_query_interval_dsec, pim_ifp->igmp_query_max_response_time_dsec,
2934 change_query_interval(pim_ifp, IGMP_GENERAL_QUERY_INTERVAL);
2939 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN (1)
2940 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX (25)
2942 DEFUN (interface_ip_igmp_query_max_response_time,
2943 interface_ip_igmp_query_max_response_time_cmd,
2944 PIM_CMD_IP_IGMP_QUERY_MAX_RESPONSE_TIME " <1-25>",
2947 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
2948 "Query response value in seconds\n")
2950 struct interface *ifp;
2951 struct pim_interface *pim_ifp;
2952 int query_max_response_time;
2955 pim_ifp = ifp->info;
2959 "IGMP not enabled on interface %s. Please enable IGMP first.%s",
2965 query_max_response_time = atoi(argv[0]);
2968 It seems we don't need to check bounds since command.c does it
2969 already, but we verify them anyway for extra safety.
2971 if (query_max_response_time < IGMP_QUERY_MAX_RESPONSE_TIME_MIN) {
2972 vty_out(vty, "Query max response time %d sec lower than minimum %d sec%s",
2973 query_max_response_time,
2974 IGMP_QUERY_MAX_RESPONSE_TIME_MIN,
2978 if (query_max_response_time > IGMP_QUERY_MAX_RESPONSE_TIME_MAX) {
2979 vty_out(vty, "Query max response time %d sec higher than maximum %d sec%s",
2980 query_max_response_time,
2981 IGMP_QUERY_MAX_RESPONSE_TIME_MAX,
2986 if (query_max_response_time >= pim_ifp->igmp_default_query_interval) {
2988 "Can't set query max response time %d sec >= general query interval %d sec%s",
2989 query_max_response_time, pim_ifp->igmp_default_query_interval,
2994 change_query_max_response_time(pim_ifp, 10 * query_max_response_time);
2999 DEFUN (interface_no_ip_igmp_query_max_response_time,
3000 interface_no_ip_igmp_query_max_response_time_cmd,
3001 PIM_CMD_NO " " PIM_CMD_IP_IGMP_QUERY_MAX_RESPONSE_TIME,
3005 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR)
3007 struct interface *ifp;
3008 struct pim_interface *pim_ifp;
3009 int default_query_interval_dsec;
3012 pim_ifp = ifp->info;
3017 default_query_interval_dsec = 10 * pim_ifp->igmp_default_query_interval;
3019 if (IGMP_QUERY_MAX_RESPONSE_TIME_DSEC >= default_query_interval_dsec) {
3021 "Can't set default query max response time %d dsec >= general query interval %d dsec.%s",
3022 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC, default_query_interval_dsec,
3027 change_query_max_response_time(pim_ifp, IGMP_QUERY_MAX_RESPONSE_TIME_DSEC);
3032 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
3033 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
3035 DEFUN (interface_ip_igmp_query_max_response_time_dsec,
3036 interface_ip_igmp_query_max_response_time_dsec_cmd,
3037 PIM_CMD_IP_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC " <10-250>",
3040 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
3041 "Query response value in deciseconds\n")
3043 struct interface *ifp;
3044 struct pim_interface *pim_ifp;
3045 int query_max_response_time_dsec;
3046 int default_query_interval_dsec;
3049 pim_ifp = ifp->info;
3053 "IGMP not enabled on interface %s. Please enable IGMP first.%s",
3059 query_max_response_time_dsec = atoi(argv[0]);
3062 It seems we don't need to check bounds since command.c does it
3063 already, but we verify them anyway for extra safety.
3065 if (query_max_response_time_dsec < IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC) {
3066 vty_out(vty, "Query max response time %d dsec lower than minimum %d dsec%s",
3067 query_max_response_time_dsec,
3068 IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC,
3072 if (query_max_response_time_dsec > IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC) {
3073 vty_out(vty, "Query max response time %d dsec higher than maximum %d dsec%s",
3074 query_max_response_time_dsec,
3075 IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC,
3080 default_query_interval_dsec = 10 * pim_ifp->igmp_default_query_interval;
3082 if (query_max_response_time_dsec >= default_query_interval_dsec) {
3084 "Can't set query max response time %d dsec >= general query interval %d dsec%s",
3085 query_max_response_time_dsec, default_query_interval_dsec,
3090 change_query_max_response_time(pim_ifp, query_max_response_time_dsec);
3095 DEFUN (interface_no_ip_igmp_query_max_response_time_dsec,
3096 interface_no_ip_igmp_query_max_response_time_dsec_cmd,
3097 PIM_CMD_NO " " PIM_CMD_IP_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC,
3101 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR)
3103 struct interface *ifp;
3104 struct pim_interface *pim_ifp;
3105 int default_query_interval_dsec;
3108 pim_ifp = ifp->info;
3113 default_query_interval_dsec = 10 * pim_ifp->igmp_default_query_interval;
3115 if (IGMP_QUERY_MAX_RESPONSE_TIME_DSEC >= default_query_interval_dsec) {
3117 "Can't set default query max response time %d dsec >= general query interval %d dsec.%s",
3118 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC, default_query_interval_dsec,
3123 change_query_max_response_time(pim_ifp, IGMP_QUERY_MAX_RESPONSE_TIME_DSEC);
3128 DEFUN (interface_ip_pim_drprio,
3129 interface_ip_pim_drprio_cmd,
3130 "ip pim drpriority <1-4294967295>",
3133 "Set the Designated Router Election Priority\n"
3134 "Value of the new DR Priority\n")
3136 struct interface *ifp;
3137 struct pim_interface *pim_ifp;
3138 uint32_t old_dr_prio;
3141 pim_ifp = ifp->info;
3144 vty_out(vty, "Please enable PIM on interface, first%s", VTY_NEWLINE);
3148 old_dr_prio = pim_ifp->pim_dr_priority;
3150 pim_ifp->pim_dr_priority = strtol(argv[0], NULL, 10);
3152 if (old_dr_prio != pim_ifp->pim_dr_priority) {
3153 if (pim_if_dr_election(ifp))
3154 pim_hello_restart_now(ifp);
3160 DEFUN (interface_no_ip_pim_drprio,
3161 interface_no_ip_pim_drprio_cmd,
3162 "no ip pim drpriority {<1-4294967295>}",
3165 "Revert the Designated Router Priority to default\n"
3166 "Old Value of the Priority\n")
3168 struct interface *ifp;
3169 struct pim_interface *pim_ifp;
3172 pim_ifp = ifp->info;
3175 vty_out(vty, "Pim not enabled on this interface%s", VTY_NEWLINE);
3179 if (pim_ifp->pim_dr_priority != PIM_DEFAULT_DR_PRIORITY) {
3180 pim_ifp->pim_dr_priority = PIM_DEFAULT_DR_PRIORITY;
3181 if (pim_if_dr_election(ifp))
3182 pim_hello_restart_now(ifp);
3188 DEFUN (interface_ip_pim_ssm,
3189 interface_ip_pim_ssm_cmd,
3195 struct interface *ifp;
3196 struct pim_interface *pim_ifp;
3199 pim_ifp = ifp->info;
3202 pim_ifp = pim_if_new(ifp, 0 /* igmp=false */, 1 /* pim=true */);
3204 vty_out(vty, "Could not enable PIM on interface%s", VTY_NEWLINE);
3209 PIM_IF_DO_PIM(pim_ifp->options);
3212 pim_if_addr_add_all(ifp);
3213 pim_if_membership_refresh(ifp);
3218 DEFUN (interface_no_ip_pim_ssm,
3219 interface_no_ip_pim_ssm_cmd,
3226 struct interface *ifp;
3227 struct pim_interface *pim_ifp;
3230 pim_ifp = ifp->info;
3234 PIM_IF_DONT_PIM(pim_ifp->options);
3236 pim_if_membership_clear(ifp);
3239 pim_if_addr_del_all() removes all sockets from
3240 pim_ifp->igmp_socket_list.
3242 pim_if_addr_del_all(ifp);
3245 pim_sock_delete() removes all neighbors from
3246 pim_ifp->pim_neighbor_list.
3248 pim_sock_delete(ifp, "pim unconfigured on interface");
3250 if (!PIM_IF_TEST_IGMP(pim_ifp->options)) {
3257 DEFUN (interface_ip_mroute,
3258 interface_ip_mroute_cmd,
3259 "ip mroute INTERFACE A.B.C.D",
3261 "Add multicast route\n"
3262 "Outgoing interface name\n"
3265 struct interface *iif;
3266 struct interface *oif;
3267 const char *oifname;
3268 const char *grp_str;
3269 struct in_addr grp_addr;
3270 struct in_addr src_addr;
3276 oif = if_lookup_by_name(oifname);
3278 vty_out(vty, "No such interface name %s%s",
3279 oifname, VTY_NEWLINE);
3284 result = inet_pton(AF_INET, grp_str, &grp_addr);
3286 vty_out(vty, "Bad group address %s: errno=%d: %s%s",
3287 grp_str, errno, safe_strerror(errno), VTY_NEWLINE);
3291 src_addr.s_addr = INADDR_ANY;
3293 if (pim_static_add(iif, oif, grp_addr, src_addr)) {
3294 vty_out(vty, "Failed to add route%s", VTY_NEWLINE);
3301 DEFUN (interface_ip_mroute_source,
3302 interface_ip_mroute_source_cmd,
3303 "ip mroute INTERFACE A.B.C.D A.B.C.D",
3305 "Add multicast route\n"
3306 "Outgoing interface name\n"
3310 struct interface *iif;
3311 struct interface *oif;
3312 const char *oifname;
3313 const char *grp_str;
3314 struct in_addr grp_addr;
3315 const char *src_str;
3316 struct in_addr src_addr;
3322 oif = if_lookup_by_name(oifname);
3324 vty_out(vty, "No such interface name %s%s",
3325 oifname, VTY_NEWLINE);
3330 result = inet_pton(AF_INET, grp_str, &grp_addr);
3332 vty_out(vty, "Bad group address %s: errno=%d: %s%s",
3333 grp_str, errno, safe_strerror(errno), VTY_NEWLINE);
3338 result = inet_pton(AF_INET, src_str, &src_addr);
3340 vty_out(vty, "Bad source address %s: errno=%d: %s%s",
3341 src_str, errno, safe_strerror(errno), VTY_NEWLINE);
3345 if (pim_static_add(iif, oif, grp_addr, src_addr)) {
3346 vty_out(vty, "Failed to add route%s", VTY_NEWLINE);
3353 DEFUN (interface_no_ip_mroute,
3354 interface_no_ip_mroute_cmd,
3355 "no ip mroute INTERFACE A.B.C.D",
3358 "Add multicast route\n"
3359 "Outgoing interface name\n"
3362 struct interface *iif;
3363 struct interface *oif;
3364 const char *oifname;
3365 const char *grp_str;
3366 struct in_addr grp_addr;
3367 struct in_addr src_addr;
3373 oif = if_lookup_by_name(oifname);
3375 vty_out(vty, "No such interface name %s%s",
3376 oifname, VTY_NEWLINE);
3381 result = inet_pton(AF_INET, grp_str, &grp_addr);
3383 vty_out(vty, "Bad group address %s: errno=%d: %s%s",
3384 grp_str, errno, safe_strerror(errno), VTY_NEWLINE);
3388 src_addr.s_addr = INADDR_ANY;
3390 if (pim_static_del(iif, oif, grp_addr, src_addr)) {
3391 vty_out(vty, "Failed to remove route%s", VTY_NEWLINE);
3398 DEFUN (interface_no_ip_mroute_source,
3399 interface_no_ip_mroute_source_cmd,
3400 "no ip mroute INTERFACE A.B.C.D A.B.C.D",
3403 "Add multicast route\n"
3404 "Outgoing interface name\n"
3408 struct interface *iif;
3409 struct interface *oif;
3410 const char *oifname;
3411 const char *grp_str;
3412 struct in_addr grp_addr;
3413 const char *src_str;
3414 struct in_addr src_addr;
3420 oif = if_lookup_by_name(oifname);
3422 vty_out(vty, "No such interface name %s%s",
3423 oifname, VTY_NEWLINE);
3428 result = inet_pton(AF_INET, grp_str, &grp_addr);
3430 vty_out(vty, "Bad group address %s: errno=%d: %s%s",
3431 grp_str, errno, safe_strerror(errno), VTY_NEWLINE);
3436 result = inet_pton(AF_INET, src_str, &src_addr);
3438 vty_out(vty, "Bad source address %s: errno=%d: %s%s",
3439 src_str, errno, safe_strerror(errno), VTY_NEWLINE);
3443 if (pim_static_del(iif, oif, grp_addr, src_addr)) {
3444 vty_out(vty, "Failed to remove route%s", VTY_NEWLINE);
3451 DEFUN (interface_ip_pim_hello,
3452 interface_ip_pim_hello_cmd,
3453 "ip pim hello <1-180>",
3457 IFACE_PIM_HELLO_TIME_STR)
3459 struct interface *ifp;
3460 struct pim_interface *pim_ifp;
3463 pim_ifp = ifp->info;
3466 vty_out(vty, "Pim not enabled on this interface%s", VTY_NEWLINE);
3470 pim_ifp->pim_hello_period = strtol(argv[0], NULL, 10);
3473 pim_ifp->pim_default_holdtime = strtol(argv[1], NULL, 10);
3478 ALIAS (interface_ip_pim_hello,
3479 interface_ip_pim_hello_hold_cmd,
3480 "ip pim hello <1-180> <1-180>",
3484 IFACE_PIM_HELLO_TIME_STR
3485 IFACE_PIM_HELLO_HOLD_STR)
3488 DEFUN (interface_no_ip_pim_hello,
3489 interface_no_ip_pim_hello_cmd,
3490 "no ip pim hello {<1-180> <1-180>}",
3495 IFACE_PIM_HELLO_TIME_STR
3496 IFACE_PIM_HELLO_HOLD_STR)
3498 struct interface *ifp;
3499 struct pim_interface *pim_ifp;
3502 pim_ifp = ifp->info;
3505 vty_out(vty, "Pim not enabled on this interface%s", VTY_NEWLINE);
3509 pim_ifp->pim_hello_period = PIM_DEFAULT_HELLO_PERIOD;
3510 pim_ifp->pim_default_holdtime = -1;
3521 PIM_DO_DEBUG_IGMP_EVENTS;
3522 PIM_DO_DEBUG_IGMP_PACKETS;
3523 PIM_DO_DEBUG_IGMP_TRACE;
3527 DEFUN (no_debug_igmp,
3534 PIM_DONT_DEBUG_IGMP_EVENTS;
3535 PIM_DONT_DEBUG_IGMP_PACKETS;
3536 PIM_DONT_DEBUG_IGMP_TRACE;
3540 ALIAS (no_debug_igmp,
3546 DEFUN (debug_igmp_events,
3547 debug_igmp_events_cmd,
3548 "debug igmp events",
3551 DEBUG_IGMP_EVENTS_STR)
3553 PIM_DO_DEBUG_IGMP_EVENTS;
3557 DEFUN (no_debug_igmp_events,
3558 no_debug_igmp_events_cmd,
3559 "no debug igmp events",
3563 DEBUG_IGMP_EVENTS_STR)
3565 PIM_DONT_DEBUG_IGMP_EVENTS;
3569 ALIAS (no_debug_igmp_events,
3570 undebug_igmp_events_cmd,
3571 "undebug igmp events",
3574 DEBUG_IGMP_EVENTS_STR)
3576 DEFUN (debug_igmp_packets,
3577 debug_igmp_packets_cmd,
3578 "debug igmp packets",
3581 DEBUG_IGMP_PACKETS_STR)
3583 PIM_DO_DEBUG_IGMP_PACKETS;
3587 DEFUN (no_debug_igmp_packets,
3588 no_debug_igmp_packets_cmd,
3589 "no debug igmp packets",
3593 DEBUG_IGMP_PACKETS_STR)
3595 PIM_DONT_DEBUG_IGMP_PACKETS;
3599 ALIAS (no_debug_igmp_packets,
3600 undebug_igmp_packets_cmd,
3601 "undebug igmp packets",
3604 DEBUG_IGMP_PACKETS_STR)
3606 DEFUN (debug_igmp_trace,
3607 debug_igmp_trace_cmd,
3611 DEBUG_IGMP_TRACE_STR)
3613 PIM_DO_DEBUG_IGMP_TRACE;
3617 DEFUN (no_debug_igmp_trace,
3618 no_debug_igmp_trace_cmd,
3619 "no debug igmp trace",
3623 DEBUG_IGMP_TRACE_STR)
3625 PIM_DONT_DEBUG_IGMP_TRACE;
3629 ALIAS (no_debug_igmp_trace,
3630 undebug_igmp_trace_cmd,
3631 "undebug igmp trace",
3634 DEBUG_IGMP_TRACE_STR)
3636 DEFUN (debug_mroute,
3642 PIM_DO_DEBUG_MROUTE;
3646 DEFUN (no_debug_mroute,
3647 no_debug_mroute_cmd,
3653 PIM_DONT_DEBUG_MROUTE;
3657 ALIAS (no_debug_mroute,
3663 DEFUN (debug_static,
3669 PIM_DO_DEBUG_STATIC;
3673 DEFUN (no_debug_static,
3674 no_debug_static_cmd,
3680 PIM_DONT_DEBUG_STATIC;
3684 ALIAS (no_debug_static,
3696 PIM_DO_DEBUG_PIM_EVENTS;
3697 PIM_DO_DEBUG_PIM_PACKETS;
3698 PIM_DO_DEBUG_PIM_TRACE;
3702 DEFUN (no_debug_pim,
3709 PIM_DONT_DEBUG_PIM_EVENTS;
3710 PIM_DONT_DEBUG_PIM_PACKETS;
3711 PIM_DONT_DEBUG_PIM_TRACE;
3713 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND;
3714 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV;
3719 ALIAS (no_debug_pim,
3725 DEFUN (debug_pim_events,
3726 debug_pim_events_cmd,
3730 DEBUG_PIM_EVENTS_STR)
3732 PIM_DO_DEBUG_PIM_EVENTS;
3736 DEFUN (no_debug_pim_events,
3737 no_debug_pim_events_cmd,
3738 "no debug pim events",
3742 DEBUG_PIM_EVENTS_STR)
3744 PIM_DONT_DEBUG_PIM_EVENTS;
3748 ALIAS (no_debug_pim_events,
3749 undebug_pim_events_cmd,
3750 "undebug pim events",
3753 DEBUG_PIM_EVENTS_STR)
3755 DEFUN (debug_pim_packets,
3756 debug_pim_packets_cmd,
3757 "debug pim packets",
3760 DEBUG_PIM_PACKETS_STR)
3762 PIM_DO_DEBUG_PIM_PACKETS;
3763 vty_out (vty, "PIM Packet debugging is on %s", VTY_NEWLINE);
3767 DEFUN (debug_pim_packets_filter,
3768 debug_pim_packets_filter_cmd,
3769 "debug pim packets (hello|joins)",
3772 DEBUG_PIM_PACKETS_STR
3773 DEBUG_PIM_HELLO_PACKETS_STR
3774 DEBUG_PIM_J_P_PACKETS_STR)
3776 if (strncmp(argv[0],"h",1) == 0)
3778 PIM_DO_DEBUG_PIM_HELLO;
3779 vty_out (vty, "PIM Hello debugging is on %s", VTY_NEWLINE);
3781 else if (strncmp(argv[0],"j",1) == 0)
3783 PIM_DO_DEBUG_PIM_J_P;
3784 vty_out (vty, "PIM Join/Prune debugging is on %s", VTY_NEWLINE);
3789 DEFUN (no_debug_pim_packets,
3790 no_debug_pim_packets_cmd,
3791 "no debug pim packets",
3795 DEBUG_PIM_PACKETS_STR
3796 DEBUG_PIM_HELLO_PACKETS_STR
3797 DEBUG_PIM_J_P_PACKETS_STR)
3799 PIM_DONT_DEBUG_PIM_PACKETS;
3800 vty_out (vty, "PIM Packet debugging is off %s", VTY_NEWLINE);
3804 DEFUN (no_debug_pim_packets_filter,
3805 no_debug_pim_packets_filter_cmd,
3806 "no debug pim packets (hello|joins)",
3810 DEBUG_PIM_PACKETS_STR
3811 DEBUG_PIM_HELLO_PACKETS_STR
3812 DEBUG_PIM_J_P_PACKETS_STR)
3814 if (strncmp(argv[0],"h",1) == 0)
3816 PIM_DONT_DEBUG_PIM_HELLO;
3817 vty_out (vty, "PIM Hello debugging is off %s", VTY_NEWLINE);
3819 else if (strncmp(argv[0],"j",1) == 0)
3821 PIM_DONT_DEBUG_PIM_J_P;
3822 vty_out (vty, "PIM Join/Prune debugging is off %s", VTY_NEWLINE);
3827 ALIAS (no_debug_pim_packets,
3828 undebug_pim_packets_cmd,
3829 "undebug pim packets",
3832 DEBUG_PIM_PACKETS_STR)
3834 DEFUN (debug_pim_packetdump_send,
3835 debug_pim_packetdump_send_cmd,
3836 "debug pim packet-dump send",
3839 DEBUG_PIM_PACKETDUMP_STR
3840 DEBUG_PIM_PACKETDUMP_SEND_STR)
3842 PIM_DO_DEBUG_PIM_PACKETDUMP_SEND;
3846 DEFUN (no_debug_pim_packetdump_send,
3847 no_debug_pim_packetdump_send_cmd,
3848 "no debug pim packet-dump send",
3852 DEBUG_PIM_PACKETDUMP_STR
3853 DEBUG_PIM_PACKETDUMP_SEND_STR)
3855 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND;
3859 ALIAS (no_debug_pim_packetdump_send,
3860 undebug_pim_packetdump_send_cmd,
3861 "undebug pim packet-dump send",
3864 DEBUG_PIM_PACKETDUMP_STR
3865 DEBUG_PIM_PACKETDUMP_SEND_STR)
3867 DEFUN (debug_pim_packetdump_recv,
3868 debug_pim_packetdump_recv_cmd,
3869 "debug pim packet-dump receive",
3872 DEBUG_PIM_PACKETDUMP_STR
3873 DEBUG_PIM_PACKETDUMP_RECV_STR)
3875 PIM_DO_DEBUG_PIM_PACKETDUMP_RECV;
3879 DEFUN (no_debug_pim_packetdump_recv,
3880 no_debug_pim_packetdump_recv_cmd,
3881 "no debug pim packet-dump receive",
3885 DEBUG_PIM_PACKETDUMP_STR
3886 DEBUG_PIM_PACKETDUMP_RECV_STR)
3888 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV;
3892 ALIAS (no_debug_pim_packetdump_recv,
3893 undebug_pim_packetdump_recv_cmd,
3894 "undebug pim packet-dump receive",
3897 DEBUG_PIM_PACKETDUMP_STR
3898 DEBUG_PIM_PACKETDUMP_RECV_STR)
3900 DEFUN (debug_pim_trace,
3901 debug_pim_trace_cmd,
3905 DEBUG_PIM_TRACE_STR)
3907 PIM_DO_DEBUG_PIM_TRACE;
3911 DEFUN (no_debug_pim_trace,
3912 no_debug_pim_trace_cmd,
3913 "no debug pim trace",
3917 DEBUG_PIM_TRACE_STR)
3919 PIM_DONT_DEBUG_PIM_TRACE;
3923 ALIAS (no_debug_pim_trace,
3924 undebug_pim_trace_cmd,
3925 "undebug pim trace",
3928 DEBUG_PIM_TRACE_STR)
3930 DEFUN (debug_ssmpingd,
3937 PIM_DO_DEBUG_SSMPINGD;
3941 DEFUN (no_debug_ssmpingd,
3942 no_debug_ssmpingd_cmd,
3943 "no debug ssmpingd",
3949 PIM_DONT_DEBUG_SSMPINGD;
3953 ALIAS (no_debug_ssmpingd,
3954 undebug_ssmpingd_cmd,
3960 DEFUN (debug_pim_zebra,
3961 debug_pim_zebra_cmd,
3965 DEBUG_PIM_ZEBRA_STR)
3971 DEFUN (no_debug_pim_zebra,
3972 no_debug_pim_zebra_cmd,
3973 "no debug pim zebra",
3977 DEBUG_PIM_ZEBRA_STR)
3979 PIM_DONT_DEBUG_ZEBRA;
3983 ALIAS (no_debug_pim_zebra,
3984 undebug_pim_zebra_cmd,
3985 "undebug pim zebra",
3988 DEBUG_PIM_ZEBRA_STR)
3990 DEFUN (show_debugging_pim,
3991 show_debugging_pim_cmd,
3992 "show debugging pim",
3997 pim_debug_config_write(vty);
4001 static struct igmp_sock *find_igmp_sock_by_fd(int fd)
4003 struct listnode *ifnode;
4004 struct interface *ifp;
4006 /* scan all interfaces */
4007 for (ALL_LIST_ELEMENTS_RO(iflist, ifnode, ifp)) {
4008 struct pim_interface *pim_ifp;
4009 struct igmp_sock *igmp;
4014 pim_ifp = ifp->info;
4016 /* lookup igmp socket under current interface */
4017 igmp = igmp_sock_lookup_by_fd(pim_ifp->igmp_socket_list, fd);
4025 DEFUN (test_igmp_receive_report,
4026 test_igmp_receive_report_cmd,
4027 "test igmp receive report <0-65535> A.B.C.D <1-6> .LINE",
4029 "Test IGMP protocol\n"
4030 "Test IGMP message\n"
4031 "Test IGMP report\n"
4033 "IGMP group address\n"
4040 size_t ip_hlen; /* ip header length in bytes */
4045 const char *grp_str;
4046 struct in_addr grp_addr;
4047 const char *record_type_str;
4049 const char *src_str;
4051 struct igmp_sock *igmp;
4054 struct in_addr *sources;
4055 struct in_addr *src_addr;
4059 socket_fd = atoi(socket);
4060 igmp = find_igmp_sock_by_fd(socket_fd);
4062 vty_out(vty, "Could not find IGMP socket %s: fd=%d%s",
4063 socket, socket_fd, VTY_NEWLINE);
4068 result = inet_pton(AF_INET, grp_str, &grp_addr);
4070 vty_out(vty, "Bad group address %s: errno=%d: %s%s",
4071 grp_str, errno, safe_strerror(errno), VTY_NEWLINE);
4075 record_type_str = argv[2];
4076 record_type = atoi(record_type_str);
4081 ip_hdr = (struct ip *) buf;
4082 ip_hdr->ip_p = PIM_IP_PROTO_IGMP;
4083 ip_hlen = PIM_IP_HEADER_MIN_LEN; /* ip header length in bytes */
4084 ip_hdr->ip_hl = ip_hlen >> 2; /* ip header length in 4-byte words */
4085 ip_hdr->ip_src = igmp->ifaddr;
4086 ip_hdr->ip_dst = igmp->ifaddr;
4089 Build IGMP v3 report message
4091 igmp_msg = buf + ip_hlen;
4092 group_record = igmp_msg + IGMP_V3_REPORT_GROUPPRECORD_OFFSET;
4093 *igmp_msg = PIM_IGMP_V3_MEMBERSHIP_REPORT; /* type */
4094 *(uint16_t *) (igmp_msg + IGMP_V3_CHECKSUM_OFFSET) = 0; /* for computing checksum */
4095 *(uint16_t *) (igmp_msg + IGMP_V3_REPORT_NUMGROUPS_OFFSET) = htons(1); /* one group record */
4096 *(uint8_t *) (group_record + IGMP_V3_GROUP_RECORD_TYPE_OFFSET) = record_type;
4097 memcpy(group_record + IGMP_V3_GROUP_RECORD_GROUP_OFFSET, &grp_addr, sizeof(struct in_addr));
4099 /* Scan LINE sources */
4100 sources = (struct in_addr *) (group_record + IGMP_V3_GROUP_RECORD_SOURCE_OFFSET);
4102 for (argi = 3; argi < argc; ++argi,++src_addr) {
4103 src_str = argv[argi];
4104 result = inet_pton(AF_INET, src_str, src_addr);
4106 vty_out(vty, "Bad source address %s: errno=%d: %s%s",
4107 src_str, errno, safe_strerror(errno), VTY_NEWLINE);
4111 num_sources = src_addr - sources;
4113 *(uint16_t *)(group_record + IGMP_V3_GROUP_RECORD_NUMSOURCES_OFFSET) = htons(num_sources);
4115 igmp_msg_len = IGMP_V3_MSG_MIN_SIZE + (num_sources << 4); /* v3 report for one single group record */
4117 /* compute checksum */
4118 *(uint16_t *)(igmp_msg + IGMP_V3_CHECKSUM_OFFSET) = in_cksum(igmp_msg, igmp_msg_len);
4120 /* "receive" message */
4122 ip_msg_len = ip_hlen + igmp_msg_len;
4123 result = pim_igmp_packet(igmp, buf, ip_msg_len);
4125 vty_out(vty, "pim_igmp_packet(len=%d) returned: %d%s",
4126 ip_msg_len, result, VTY_NEWLINE);
4133 static int hexval(uint8_t ch)
4135 return isdigit(ch) ? (ch - '0') : (10 + tolower(ch) - 'a');
4138 DEFUN (test_pim_receive_dump,
4139 test_pim_receive_dump_cmd,
4140 "test pim receive dump INTERFACE A.B.C.D .LINE",
4142 "Test PIM protocol\n"
4143 "Test PIM message reception\n"
4144 "Test PIM packet dump reception from neighbor\n"
4146 "Neighbor address\n"
4152 size_t ip_hlen; /* ip header length in bytes */
4155 const char *neigh_str;
4156 struct in_addr neigh_addr;
4158 struct interface *ifp;
4162 /* Find interface */
4164 ifp = if_lookup_by_name(ifname);
4166 vty_out(vty, "No such interface name %s%s",
4167 ifname, VTY_NEWLINE);
4171 /* Neighbor address */
4172 neigh_str = argv[1];
4173 result = inet_pton(AF_INET, neigh_str, &neigh_addr);
4175 vty_out(vty, "Bad neighbor address %s: errno=%d: %s%s",
4176 neigh_str, errno, safe_strerror(errno), VTY_NEWLINE);
4183 ip_hdr = (struct ip *) buf;
4184 ip_hdr->ip_p = PIM_IP_PROTO_PIM;
4185 ip_hlen = PIM_IP_HEADER_MIN_LEN; /* ip header length in bytes */
4186 ip_hdr->ip_hl = ip_hlen >> 2; /* ip header length in 4-byte words */
4187 ip_hdr->ip_src = neigh_addr;
4188 ip_hdr->ip_dst = qpim_all_pim_routers_addr;
4191 Build PIM hello message
4193 pim_msg = buf + ip_hlen;
4196 /* Scan LINE dump into buffer */
4197 for (argi = 2; argi < argc; ++argi) {
4198 const char *str = argv[argi];
4199 int str_len = strlen(str);
4200 int str_last = str_len - 1;
4204 vty_out(vty, "%% Uneven hex array arg %d=%s%s",
4205 argi, str, VTY_NEWLINE);
4209 for (i = 0; i < str_last; i += 2) {
4212 uint8_t h1 = str[i];
4213 uint8_t h2 = str[i + 1];
4215 if (!isxdigit(h1) || !isxdigit(h2)) {
4216 vty_out(vty, "%% Non-hex octet %c%c at hex array arg %d=%s%s",
4217 h1, h2, argi, str, VTY_NEWLINE);
4220 octet = (hexval(h1) << 4) + hexval(h2);
4222 left = sizeof(buf) - ip_hlen - pim_msg_size;
4224 vty_out(vty, "%% Overflow buf_size=%zu buf_left=%d at hex array arg %d=%s octet %02x%s",
4225 sizeof(buf), left, argi, str, octet, VTY_NEWLINE);
4229 pim_msg[pim_msg_size++] = octet;
4233 ip_msg_len = ip_hlen + pim_msg_size;
4235 vty_out(vty, "Receiving: buf_size=%zu ip_msg_size=%d pim_msg_size=%d%s",
4236 sizeof(buf), ip_msg_len, pim_msg_size, VTY_NEWLINE);
4238 /* "receive" message */
4240 result = pim_pim_packet(ifp, buf, ip_msg_len);
4242 vty_out(vty, "%% pim_pim_packet(len=%d) returned failure: %d%s",
4243 ip_msg_len, result, VTY_NEWLINE);
4250 DEFUN (test_pim_receive_hello,
4251 test_pim_receive_hello_cmd,
4252 "test pim receive hello INTERFACE A.B.C.D <0-65535> <0-65535> <0-65535> <0-32767> <0-65535> <0-1>[LINE]",
4254 "Test PIM protocol\n"
4255 "Test PIM message reception\n"
4256 "Test PIM hello reception from neighbor\n"
4258 "Neighbor address\n"
4259 "Neighbor holdtime\n"
4260 "Neighbor DR priority\n"
4261 "Neighbor generation ID\n"
4262 "Neighbor propagation delay (msec)\n"
4263 "Neighbor override interval (msec)\n"
4264 "Neighbor LAN prune delay T-bit\n"
4265 "Neighbor secondary addresses\n")
4270 size_t ip_hlen; /* ip header length in bytes */
4274 const char *neigh_str;
4275 struct in_addr neigh_addr;
4277 struct interface *ifp;
4278 uint16_t neigh_holdtime;
4279 uint16_t neigh_propagation_delay;
4280 uint16_t neigh_override_interval;
4281 int neigh_can_disable_join_suppression;
4282 uint32_t neigh_dr_priority;
4283 uint32_t neigh_generation_id;
4287 /* Find interface */
4289 ifp = if_lookup_by_name(ifname);
4291 vty_out(vty, "No such interface name %s%s",
4292 ifname, VTY_NEWLINE);
4296 /* Neighbor address */
4297 neigh_str = argv[1];
4298 result = inet_pton(AF_INET, neigh_str, &neigh_addr);
4300 vty_out(vty, "Bad neighbor address %s: errno=%d: %s%s",
4301 neigh_str, errno, safe_strerror(errno), VTY_NEWLINE);
4305 neigh_holdtime = atoi(argv[2]);
4306 neigh_dr_priority = atoi(argv[3]);
4307 neigh_generation_id = atoi(argv[4]);
4308 neigh_propagation_delay = atoi(argv[5]);
4309 neigh_override_interval = atoi(argv[6]);
4310 neigh_can_disable_join_suppression = atoi(argv[7]);
4315 ip_hdr = (struct ip *) buf;
4316 ip_hdr->ip_p = PIM_IP_PROTO_PIM;
4317 ip_hlen = PIM_IP_HEADER_MIN_LEN; /* ip header length in bytes */
4318 ip_hdr->ip_hl = ip_hlen >> 2; /* ip header length in 4-byte words */
4319 ip_hdr->ip_src = neigh_addr;
4320 ip_hdr->ip_dst = qpim_all_pim_routers_addr;
4323 Build PIM hello message
4325 pim_msg = buf + ip_hlen;
4327 /* Scan LINE addresses */
4328 for (argi = 8; argi < argc; ++argi) {
4329 const char *sec_str = argv[argi];
4330 struct in_addr sec_addr;
4331 result = inet_pton(AF_INET, sec_str, &sec_addr);
4333 vty_out(vty, "Bad neighbor secondary address %s: errno=%d: %s%s",
4334 sec_str, errno, safe_strerror(errno), VTY_NEWLINE);
4339 "FIXME WRITEME consider neighbor secondary address %s%s",
4340 sec_str, VTY_NEWLINE);
4343 pim_tlv_size = pim_hello_build_tlv(ifp->name,
4344 pim_msg + PIM_PIM_MIN_LEN,
4345 sizeof(buf) - ip_hlen - PIM_PIM_MIN_LEN,
4348 neigh_generation_id,
4349 neigh_propagation_delay,
4350 neigh_override_interval,
4351 neigh_can_disable_join_suppression,
4352 0 /* FIXME secondary address list */);
4353 if (pim_tlv_size < 0) {
4354 vty_out(vty, "pim_hello_build_tlv() returned failure: %d%s",
4355 pim_tlv_size, VTY_NEWLINE);
4359 pim_msg_size = pim_tlv_size + PIM_PIM_MIN_LEN;
4361 pim_msg_build_header(pim_msg, pim_msg_size,
4362 PIM_MSG_TYPE_HELLO);
4364 /* "receive" message */
4366 ip_msg_len = ip_hlen + pim_msg_size;
4367 result = pim_pim_packet(ifp, buf, ip_msg_len);
4369 vty_out(vty, "pim_pim_packet(len=%d) returned failure: %d%s",
4370 ip_msg_len, result, VTY_NEWLINE);
4377 DEFUN (test_pim_receive_assert,
4378 test_pim_receive_assert_cmd,
4379 "test pim receive assert INTERFACE A.B.C.D A.B.C.D A.B.C.D <0-65535> <0-65535> <0-1>",
4381 "Test PIM protocol\n"
4382 "Test PIM message reception\n"
4383 "Test reception of PIM assert\n"
4385 "Neighbor address\n"
4386 "Assert multicast group address\n"
4387 "Assert unicast source address\n"
4388 "Assert metric preference\n"
4389 "Assert route metric\n"
4390 "Assert RPT bit flag\n")
4393 uint8_t *buf_pastend = buf + sizeof(buf);
4396 size_t ip_hlen; /* ip header length in bytes */
4399 const char *neigh_str;
4400 struct in_addr neigh_addr;
4401 const char *group_str;
4402 struct in_addr group_addr;
4403 const char *source_str;
4404 struct in_addr source_addr;
4406 struct interface *ifp;
4407 uint32_t assert_metric_preference;
4408 uint32_t assert_route_metric;
4409 uint32_t assert_rpt_bit_flag;
4413 /* Find interface */
4415 ifp = if_lookup_by_name(ifname);
4417 vty_out(vty, "No such interface name %s%s",
4418 ifname, VTY_NEWLINE);
4422 /* Neighbor address */
4423 neigh_str = argv[1];
4424 result = inet_pton(AF_INET, neigh_str, &neigh_addr);
4426 vty_out(vty, "Bad neighbor address %s: errno=%d: %s%s",
4427 neigh_str, errno, safe_strerror(errno), VTY_NEWLINE);
4432 group_str = argv[2];
4433 result = inet_pton(AF_INET, group_str, &group_addr);
4435 vty_out(vty, "Bad group address %s: errno=%d: %s%s",
4436 group_str, errno, safe_strerror(errno), VTY_NEWLINE);
4440 /* Source address */
4441 source_str = argv[3];
4442 result = inet_pton(AF_INET, source_str, &source_addr);
4444 vty_out(vty, "Bad source address %s: errno=%d: %s%s",
4445 source_str, errno, safe_strerror(errno), VTY_NEWLINE);
4449 assert_metric_preference = atoi(argv[4]);
4450 assert_route_metric = atoi(argv[5]);
4451 assert_rpt_bit_flag = atoi(argv[6]);
4453 remain = buf_pastend - buf;
4454 if (remain < (int) sizeof(struct ip)) {
4455 vty_out(vty, "No room for ip header: buf_size=%d < ip_header_size=%zu%s",
4456 remain, sizeof(struct ip), VTY_NEWLINE);
4463 ip_hdr = (struct ip *) buf;
4464 ip_hdr->ip_p = PIM_IP_PROTO_PIM;
4465 ip_hlen = PIM_IP_HEADER_MIN_LEN; /* ip header length in bytes */
4466 ip_hdr->ip_hl = ip_hlen >> 2; /* ip header length in 4-byte words */
4467 ip_hdr->ip_src = neigh_addr;
4468 ip_hdr->ip_dst = qpim_all_pim_routers_addr;
4471 Build PIM assert message
4473 pim_msg = buf + ip_hlen; /* skip ip header */
4475 pim_msg_size = pim_assert_build_msg(pim_msg, buf_pastend - pim_msg, ifp,
4476 group_addr, source_addr,
4477 assert_metric_preference,
4478 assert_route_metric,
4479 assert_rpt_bit_flag);
4480 if (pim_msg_size < 0) {
4481 vty_out(vty, "Failure building PIM assert message: size=%d%s",
4482 pim_msg_size, VTY_NEWLINE);
4486 /* "receive" message */
4488 ip_msg_len = ip_hlen + pim_msg_size;
4489 result = pim_pim_packet(ifp, buf, ip_msg_len);
4491 vty_out(vty, "pim_pim_packet(len=%d) returned failure: %d%s",
4492 ip_msg_len, result, VTY_NEWLINE);
4499 static int recv_joinprune(struct vty *vty,
4504 const uint8_t *buf_pastend = buf + sizeof(buf);
4506 uint8_t *pim_msg_curr;
4509 size_t ip_hlen; /* ip header length in bytes */
4511 uint16_t neigh_holdtime;
4512 const char *neigh_dst_str;
4513 struct in_addr neigh_dst_addr;
4514 const char *neigh_src_str;
4515 struct in_addr neigh_src_addr;
4516 const char *group_str;
4517 struct in_addr group_addr;
4518 const char *source_str;
4519 struct in_addr source_addr;
4521 struct interface *ifp;
4524 uint16_t num_joined;
4525 uint16_t num_pruned;
4527 /* Find interface */
4529 ifp = if_lookup_by_name(ifname);
4531 vty_out(vty, "No such interface name %s%s",
4532 ifname, VTY_NEWLINE);
4536 neigh_holdtime = atoi(argv[1]);
4538 /* Neighbor destination address */
4539 neigh_dst_str = argv[2];
4540 result = inet_pton(AF_INET, neigh_dst_str, &neigh_dst_addr);
4542 vty_out(vty, "Bad neighbor destination address %s: errno=%d: %s%s",
4543 neigh_dst_str, errno, safe_strerror(errno), VTY_NEWLINE);
4547 /* Neighbor source address */
4548 neigh_src_str = argv[3];
4549 result = inet_pton(AF_INET, neigh_src_str, &neigh_src_addr);
4551 vty_out(vty, "Bad neighbor source address %s: errno=%d: %s%s",
4552 neigh_src_str, errno, safe_strerror(errno), VTY_NEWLINE);
4556 /* Multicast group address */
4557 group_str = argv[4];
4558 result = inet_pton(AF_INET, group_str, &group_addr);
4560 vty_out(vty, "Bad group address %s: errno=%d: %s%s",
4561 group_str, errno, safe_strerror(errno), VTY_NEWLINE);
4565 /* Multicast source address */
4566 source_str = argv[5];
4567 result = inet_pton(AF_INET, source_str, &source_addr);
4569 vty_out(vty, "Bad source address %s: errno=%d: %s%s",
4570 source_str, errno, safe_strerror(errno), VTY_NEWLINE);
4577 ip_hdr = (struct ip *) buf;
4578 ip_hdr->ip_p = PIM_IP_PROTO_PIM;
4579 ip_hlen = PIM_IP_HEADER_MIN_LEN; /* ip header length in bytes */
4580 ip_hdr->ip_hl = ip_hlen >> 2; /* ip header length in 4-byte words */
4581 ip_hdr->ip_src = neigh_src_addr;
4582 ip_hdr->ip_dst = qpim_all_pim_routers_addr;
4587 pim_msg = buf + ip_hlen;
4589 /* skip room for pim header */
4590 pim_msg_curr = pim_msg + PIM_MSG_HEADER_LEN;
4592 remain = buf_pastend - pim_msg_curr;
4593 pim_msg_curr = pim_msg_addr_encode_ipv4_ucast(pim_msg_curr,
4596 if (!pim_msg_curr) {
4597 vty_out(vty, "Failure encoding destination address %s: space left=%d%s",
4598 neigh_dst_str, remain, VTY_NEWLINE);
4602 remain = buf_pastend - pim_msg_curr;
4604 vty_out(vty, "Group will not fit: space left=%d%s",
4605 remain, VTY_NEWLINE);
4609 *pim_msg_curr = 0; /* reserved */
4611 *pim_msg_curr = 1; /* number of groups */
4613 *((uint16_t *) pim_msg_curr) = htons(neigh_holdtime);
4617 remain = buf_pastend - pim_msg_curr;
4618 pim_msg_curr = pim_msg_addr_encode_ipv4_group(pim_msg_curr,
4621 if (!pim_msg_curr) {
4622 vty_out(vty, "Failure encoding group address %s: space left=%d%s",
4623 group_str, remain, VTY_NEWLINE);
4627 remain = buf_pastend - pim_msg_curr;
4629 vty_out(vty, "Sources will not fit: space left=%d%s",
4630 remain, VTY_NEWLINE);
4643 /* number of joined sources */
4644 *((uint16_t *) pim_msg_curr) = htons(num_joined);
4648 /* number of pruned sources */
4649 *((uint16_t *) pim_msg_curr) = htons(num_pruned);
4653 remain = buf_pastend - pim_msg_curr;
4654 pim_msg_curr = pim_msg_addr_encode_ipv4_source(pim_msg_curr,
4657 if (!pim_msg_curr) {
4658 vty_out(vty, "Failure encoding source address %s: space left=%d%s",
4659 source_str, remain, VTY_NEWLINE);
4663 /* Add PIM header */
4665 pim_msg_size = pim_msg_curr - pim_msg;
4667 pim_msg_build_header(pim_msg, pim_msg_size,
4668 PIM_MSG_TYPE_JOIN_PRUNE);
4674 ip_msg_len = ip_hlen + pim_msg_size;
4675 result = pim_pim_packet(ifp, buf, ip_msg_len);
4677 vty_out(vty, "pim_pim_packet(len=%d) returned failure: %d%s",
4678 ip_msg_len, result, VTY_NEWLINE);
4685 DEFUN (test_pim_receive_join,
4686 test_pim_receive_join_cmd,
4687 "test pim receive join INTERFACE <0-65535> A.B.C.D A.B.C.D A.B.C.D A.B.C.D",
4689 "Test PIM protocol\n"
4690 "Test PIM message reception\n"
4691 "Test PIM join reception from neighbor\n"
4693 "Neighbor holdtime\n"
4694 "Upstream neighbor unicast destination address\n"
4695 "Downstream neighbor unicast source address\n"
4696 "Multicast group address\n"
4697 "Unicast source address\n")
4699 return recv_joinprune(vty, argv, 1 /* src_is_join=true */);
4702 DEFUN (test_pim_receive_prune,
4703 test_pim_receive_prune_cmd,
4704 "test pim receive prune INTERFACE <0-65535> A.B.C.D A.B.C.D A.B.C.D A.B.C.D",
4706 "Test PIM protocol\n"
4707 "Test PIM message reception\n"
4708 "Test PIM prune reception from neighbor\n"
4710 "Neighbor holdtime\n"
4711 "Upstream neighbor unicast destination address\n"
4712 "Downstream neighbor unicast source address\n"
4713 "Multicast group address\n"
4714 "Unicast source address\n")
4716 return recv_joinprune(vty, argv, 0 /* src_is_join=false */);
4719 DEFUN (test_pim_receive_upcall,
4720 test_pim_receive_upcall_cmd,
4721 "test pim receive upcall (nocache|wrongvif|wholepkt) <0-65535> A.B.C.D A.B.C.D",
4723 "Test PIM protocol\n"
4724 "Test PIM message reception\n"
4725 "Test reception of kernel upcall\n"
4726 "NOCACHE kernel upcall\n"
4727 "WRONGVIF kernel upcall\n"
4728 "WHOLEPKT kernel upcall\n"
4729 "Input interface vif index\n"
4730 "Multicast group address\n"
4731 "Multicast source address\n")
4734 const char *upcall_type;
4735 const char *group_str;
4736 const char *source_str;
4739 upcall_type = argv[0];
4741 if (upcall_type[0] == 'n')
4742 msg.im_msgtype = IGMPMSG_NOCACHE;
4743 else if (upcall_type[1] == 'r')
4744 msg.im_msgtype = IGMPMSG_WRONGVIF;
4745 else if (upcall_type[1] == 'h')
4746 msg.im_msgtype = IGMPMSG_WHOLEPKT;
4748 vty_out(vty, "Unknown kernel upcall type: %s%s",
4749 upcall_type, VTY_NEWLINE);
4753 msg.im_vif = atoi(argv[1]);
4756 group_str = argv[2];
4757 result = inet_pton(AF_INET, group_str, &msg.im_dst);
4759 vty_out(vty, "Bad group address %s: errno=%d: %s%s",
4760 group_str, errno, safe_strerror(errno), VTY_NEWLINE);
4764 /* Source address */
4765 source_str = argv[3];
4766 result = inet_pton(AF_INET, source_str, &msg.im_src);
4768 vty_out(vty, "Bad source address %s: errno=%d: %s%s",
4769 source_str, errno, safe_strerror(errno), VTY_NEWLINE);
4773 msg.im_mbz = 0; /* Must be zero */
4775 result = pim_mroute_msg(-1, (char *) &msg, sizeof(msg));
4777 vty_out(vty, "pim_mroute_msg(len=%zu) returned failure: %d%s",
4778 sizeof(msg), result, VTY_NEWLINE);
4787 install_node (&pim_global_node, pim_global_config_write); /* PIM_NODE */
4788 install_node (&interface_node, pim_interface_config_write); /* INTERFACE_NODE */
4790 install_element (CONFIG_NODE, &ip_multicast_routing_cmd);
4791 install_element (CONFIG_NODE, &no_ip_multicast_routing_cmd);
4792 install_element (CONFIG_NODE, &ip_ssmpingd_cmd);
4793 install_element (CONFIG_NODE, &no_ip_ssmpingd_cmd);
4795 install_element (CONFIG_NODE, &interface_cmd); /* from if.h */
4797 install_element (CONFIG_NODE, &pim_interface_cmd);
4799 install_element (CONFIG_NODE, &no_interface_cmd); /* from if.h */
4801 install_default (INTERFACE_NODE);
4802 install_element (INTERFACE_NODE, &interface_ip_igmp_cmd);
4803 install_element (INTERFACE_NODE, &interface_no_ip_igmp_cmd);
4804 install_element (INTERFACE_NODE, &interface_ip_igmp_join_cmd);
4805 install_element (INTERFACE_NODE, &interface_no_ip_igmp_join_cmd);
4806 install_element (INTERFACE_NODE, &interface_ip_igmp_query_interval_cmd);
4807 install_element (INTERFACE_NODE, &interface_no_ip_igmp_query_interval_cmd);
4808 install_element (INTERFACE_NODE, &interface_ip_igmp_query_max_response_time_cmd);
4809 install_element (INTERFACE_NODE, &interface_no_ip_igmp_query_max_response_time_cmd);
4810 install_element (INTERFACE_NODE, &interface_ip_igmp_query_max_response_time_dsec_cmd);
4811 install_element (INTERFACE_NODE, &interface_no_ip_igmp_query_max_response_time_dsec_cmd);
4812 install_element (INTERFACE_NODE, &interface_ip_pim_ssm_cmd);
4813 install_element (INTERFACE_NODE, &interface_no_ip_pim_ssm_cmd);
4814 install_element (INTERFACE_NODE, &interface_ip_pim_drprio_cmd);
4815 install_element (INTERFACE_NODE, &interface_no_ip_pim_drprio_cmd);
4816 install_element (INTERFACE_NODE, &interface_ip_pim_hello_cmd);
4817 install_element (INTERFACE_NODE, &interface_ip_pim_hello_hold_cmd);
4818 install_element (INTERFACE_NODE, &interface_no_ip_pim_hello_cmd);
4820 // Static mroutes NEB
4821 install_element (INTERFACE_NODE, &interface_ip_mroute_cmd);
4822 install_element (INTERFACE_NODE, &interface_ip_mroute_source_cmd);
4823 install_element (INTERFACE_NODE, &interface_no_ip_mroute_cmd);
4824 install_element (INTERFACE_NODE, &interface_no_ip_mroute_source_cmd);
4826 install_element (VIEW_NODE, &show_ip_igmp_interface_cmd);
4827 install_element (VIEW_NODE, &show_ip_igmp_join_cmd);
4828 install_element (VIEW_NODE, &show_ip_igmp_parameters_cmd);
4829 install_element (VIEW_NODE, &show_ip_igmp_groups_cmd);
4830 install_element (VIEW_NODE, &show_ip_igmp_groups_retransmissions_cmd);
4831 install_element (VIEW_NODE, &show_ip_igmp_sources_cmd);
4832 install_element (VIEW_NODE, &show_ip_igmp_sources_retransmissions_cmd);
4833 install_element (VIEW_NODE, &show_ip_igmp_querier_cmd);
4834 install_element (VIEW_NODE, &show_ip_pim_assert_cmd);
4835 install_element (VIEW_NODE, &show_ip_pim_assert_internal_cmd);
4836 install_element (VIEW_NODE, &show_ip_pim_assert_metric_cmd);
4837 install_element (VIEW_NODE, &show_ip_pim_assert_winner_metric_cmd);
4838 install_element (VIEW_NODE, &show_ip_pim_dr_cmd);
4839 install_element (VIEW_NODE, &show_ip_pim_hello_cmd);
4840 install_element (VIEW_NODE, &show_ip_pim_interface_cmd);
4841 install_element (VIEW_NODE, &show_ip_pim_join_cmd);
4842 install_element (VIEW_NODE, &show_ip_pim_jp_override_interval_cmd);
4843 install_element (VIEW_NODE, &show_ip_pim_lan_prune_delay_cmd);
4844 install_element (VIEW_NODE, &show_ip_pim_local_membership_cmd);
4845 install_element (VIEW_NODE, &show_ip_pim_neighbor_cmd);
4846 install_element (VIEW_NODE, &show_ip_pim_rpf_cmd);
4847 install_element (VIEW_NODE, &show_ip_pim_secondary_cmd);
4848 install_element (VIEW_NODE, &show_ip_pim_upstream_cmd);
4849 install_element (VIEW_NODE, &show_ip_pim_upstream_join_desired_cmd);
4850 install_element (VIEW_NODE, &show_ip_pim_upstream_rpf_cmd);
4851 install_element (VIEW_NODE, &show_ip_multicast_cmd);
4852 install_element (VIEW_NODE, &show_ip_mroute_cmd);
4853 install_element (VIEW_NODE, &show_ip_mroute_count_cmd);
4854 install_element (VIEW_NODE, &show_ip_rib_cmd);
4855 install_element (VIEW_NODE, &show_ip_ssmpingd_cmd);
4856 install_element (VIEW_NODE, &show_debugging_pim_cmd);
4858 install_element (ENABLE_NODE, &clear_ip_interfaces_cmd);
4859 install_element (ENABLE_NODE, &clear_ip_igmp_interfaces_cmd);
4860 install_element (ENABLE_NODE, &clear_ip_mroute_cmd);
4861 install_element (ENABLE_NODE, &clear_ip_pim_interfaces_cmd);
4862 install_element (ENABLE_NODE, &clear_ip_pim_oil_cmd);
4864 install_element (ENABLE_NODE, &test_igmp_receive_report_cmd);
4865 install_element (ENABLE_NODE, &test_pim_receive_assert_cmd);
4866 install_element (ENABLE_NODE, &test_pim_receive_dump_cmd);
4867 install_element (ENABLE_NODE, &test_pim_receive_hello_cmd);
4868 install_element (ENABLE_NODE, &test_pim_receive_join_cmd);
4869 install_element (ENABLE_NODE, &test_pim_receive_prune_cmd);
4870 install_element (ENABLE_NODE, &test_pim_receive_upcall_cmd);
4872 install_element (ENABLE_NODE, &debug_igmp_cmd);
4873 install_element (ENABLE_NODE, &no_debug_igmp_cmd);
4874 install_element (ENABLE_NODE, &undebug_igmp_cmd);
4875 install_element (ENABLE_NODE, &debug_igmp_events_cmd);
4876 install_element (ENABLE_NODE, &no_debug_igmp_events_cmd);
4877 install_element (ENABLE_NODE, &undebug_igmp_events_cmd);
4878 install_element (ENABLE_NODE, &debug_igmp_packets_cmd);
4879 install_element (ENABLE_NODE, &no_debug_igmp_packets_cmd);
4880 install_element (ENABLE_NODE, &undebug_igmp_packets_cmd);
4881 install_element (ENABLE_NODE, &debug_igmp_trace_cmd);
4882 install_element (ENABLE_NODE, &no_debug_igmp_trace_cmd);
4883 install_element (ENABLE_NODE, &undebug_igmp_trace_cmd);
4884 install_element (ENABLE_NODE, &debug_mroute_cmd);
4885 install_element (ENABLE_NODE, &no_debug_mroute_cmd);
4886 install_element (ENABLE_NODE, &debug_static_cmd);
4887 install_element (ENABLE_NODE, &no_debug_static_cmd);
4888 install_element (ENABLE_NODE, &debug_pim_cmd);
4889 install_element (ENABLE_NODE, &no_debug_pim_cmd);
4890 install_element (ENABLE_NODE, &undebug_pim_cmd);
4891 install_element (ENABLE_NODE, &debug_pim_events_cmd);
4892 install_element (ENABLE_NODE, &no_debug_pim_events_cmd);
4893 install_element (ENABLE_NODE, &undebug_pim_events_cmd);
4894 install_element (ENABLE_NODE, &debug_pim_packets_cmd);
4895 install_element (ENABLE_NODE, &debug_pim_packets_filter_cmd);
4896 install_element (ENABLE_NODE, &no_debug_pim_packets_cmd);
4897 install_element (ENABLE_NODE, &no_debug_pim_packets_filter_cmd);
4898 install_element (ENABLE_NODE, &undebug_pim_packets_cmd);
4899 install_element (ENABLE_NODE, &debug_pim_packetdump_send_cmd);
4900 install_element (ENABLE_NODE, &no_debug_pim_packetdump_send_cmd);
4901 install_element (ENABLE_NODE, &undebug_pim_packetdump_send_cmd);
4902 install_element (ENABLE_NODE, &debug_pim_packetdump_recv_cmd);
4903 install_element (ENABLE_NODE, &no_debug_pim_packetdump_recv_cmd);
4904 install_element (ENABLE_NODE, &undebug_pim_packetdump_recv_cmd);
4905 install_element (ENABLE_NODE, &debug_pim_trace_cmd);
4906 install_element (ENABLE_NODE, &no_debug_pim_trace_cmd);
4907 install_element (ENABLE_NODE, &undebug_pim_trace_cmd);
4908 install_element (ENABLE_NODE, &debug_ssmpingd_cmd);
4909 install_element (ENABLE_NODE, &no_debug_ssmpingd_cmd);
4910 install_element (ENABLE_NODE, &undebug_ssmpingd_cmd);
4911 install_element (ENABLE_NODE, &debug_pim_zebra_cmd);
4912 install_element (ENABLE_NODE, &no_debug_pim_zebra_cmd);
4913 install_element (ENABLE_NODE, &undebug_pim_zebra_cmd);
4915 install_element (CONFIG_NODE, &debug_igmp_cmd);
4916 install_element (CONFIG_NODE, &no_debug_igmp_cmd);
4917 install_element (CONFIG_NODE, &undebug_igmp_cmd);
4918 install_element (CONFIG_NODE, &debug_igmp_events_cmd);
4919 install_element (CONFIG_NODE, &no_debug_igmp_events_cmd);
4920 install_element (CONFIG_NODE, &undebug_igmp_events_cmd);
4921 install_element (CONFIG_NODE, &debug_igmp_packets_cmd);
4922 install_element (CONFIG_NODE, &no_debug_igmp_packets_cmd);
4923 install_element (CONFIG_NODE, &undebug_igmp_packets_cmd);
4924 install_element (CONFIG_NODE, &debug_igmp_trace_cmd);
4925 install_element (CONFIG_NODE, &no_debug_igmp_trace_cmd);
4926 install_element (CONFIG_NODE, &undebug_igmp_trace_cmd);
4927 install_element (CONFIG_NODE, &debug_mroute_cmd);
4928 install_element (CONFIG_NODE, &no_debug_mroute_cmd);
4929 install_element (CONFIG_NODE, &debug_static_cmd);
4930 install_element (CONFIG_NODE, &no_debug_static_cmd);
4931 install_element (CONFIG_NODE, &debug_pim_cmd);
4932 install_element (CONFIG_NODE, &no_debug_pim_cmd);
4933 install_element (CONFIG_NODE, &undebug_pim_cmd);
4934 install_element (CONFIG_NODE, &debug_pim_events_cmd);
4935 install_element (CONFIG_NODE, &no_debug_pim_events_cmd);
4936 install_element (CONFIG_NODE, &undebug_pim_events_cmd);
4937 install_element (CONFIG_NODE, &debug_pim_packets_cmd);
4938 install_element (CONFIG_NODE, &debug_pim_packets_filter_cmd);
4939 install_element (CONFIG_NODE, &no_debug_pim_packets_cmd);
4940 install_element (CONFIG_NODE, &no_debug_pim_packets_filter_cmd);
4941 install_element (CONFIG_NODE, &undebug_pim_packets_cmd);
4942 install_element (CONFIG_NODE, &debug_pim_trace_cmd);
4943 install_element (CONFIG_NODE, &no_debug_pim_trace_cmd);
4944 install_element (CONFIG_NODE, &undebug_pim_trace_cmd);
4945 install_element (CONFIG_NODE, &debug_ssmpingd_cmd);
4946 install_element (CONFIG_NODE, &no_debug_ssmpingd_cmd);
4947 install_element (CONFIG_NODE, &undebug_ssmpingd_cmd);
4948 install_element (CONFIG_NODE, &debug_pim_zebra_cmd);
4949 install_element (CONFIG_NODE, &no_debug_pim_zebra_cmd);
4950 install_element (CONFIG_NODE, &undebug_pim_zebra_cmd);