1 /* Router advertisement
2 * Copyright (C) 2005 6WIND <jean-mickael.guerin@6wind.com>
3 * Copyright (C) 1999 Kunihiro Ishiguro
5 * This file is part of GNU Zebra.
7 * GNU Zebra is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2, or (at your option) any
12 * GNU Zebra is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with GNU Zebra; see the file COPYING. If not, write to the Free
19 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
35 #include "zebra/interface.h"
36 #include "zebra/rtadv.h"
37 #include "zebra/debug.h"
38 #include "zebra/rib.h"
39 #include "zebra/zserv.h"
41 extern struct zebra_privs_t zserv_privs
;
43 #if defined (HAVE_IPV6) && defined (RTADV)
46 #include <netinet/icmp6.h>
49 /* If RFC2133 definition is used. */
50 #ifndef IPV6_JOIN_GROUP
51 #define IPV6_JOIN_GROUP IPV6_ADD_MEMBERSHIP
53 #ifndef IPV6_LEAVE_GROUP
54 #define IPV6_LEAVE_GROUP IPV6_DROP_MEMBERSHIP
57 #define ALLNODE "ff02::1"
58 #define ALLROUTER "ff02::2"
60 extern struct zebra_t zebrad
;
62 enum rtadv_event
{RTADV_START
, RTADV_STOP
, RTADV_TIMER
,
63 RTADV_TIMER_MSEC
, RTADV_READ
};
65 static void rtadv_event (enum rtadv_event
, int);
67 static int if_join_all_router (int, struct interface
*);
68 static int if_leave_all_router (int, struct interface
*);
70 /* Structure which hold status of router advertisement. */
76 int adv_msec_if_count
;
78 struct thread
*ra_read
;
79 struct thread
*ra_timer
;
82 struct rtadv
*rtadv
= NULL
;
87 return XCALLOC (MTYPE_TMP
, sizeof (struct rtadv
));
91 rtadv_free (struct rtadv
*rtadv
)
93 XFREE (MTYPE_TMP
, rtadv
);
97 rtadv_recv_packet (int sock
, u_char
*buf
, int buflen
,
98 struct sockaddr_in6
*from
, unsigned int *ifindex
,
104 struct cmsghdr
*cmsgptr
;
109 /* Fill in message and iovec. */
110 msg
.msg_name
= (void *) from
;
111 msg
.msg_namelen
= sizeof (struct sockaddr_in6
);
114 msg
.msg_control
= (void *) adata
;
115 msg
.msg_controllen
= sizeof adata
;
117 iov
.iov_len
= buflen
;
119 /* If recvmsg fail return minus value. */
120 ret
= recvmsg (sock
, &msg
, 0);
124 for (cmsgptr
= ZCMSG_FIRSTHDR(&msg
); cmsgptr
!= NULL
;
125 cmsgptr
= CMSG_NXTHDR(&msg
, cmsgptr
))
127 /* I want interface index which this packet comes from. */
128 if (cmsgptr
->cmsg_level
== IPPROTO_IPV6
&&
129 cmsgptr
->cmsg_type
== IPV6_PKTINFO
)
131 struct in6_pktinfo
*ptr
;
133 ptr
= (struct in6_pktinfo
*) CMSG_DATA (cmsgptr
);
134 *ifindex
= ptr
->ipi6_ifindex
;
135 memcpy(&dst
, &ptr
->ipi6_addr
, sizeof(ptr
->ipi6_addr
));
138 /* Incoming packet's hop limit. */
139 if (cmsgptr
->cmsg_level
== IPPROTO_IPV6
&&
140 cmsgptr
->cmsg_type
== IPV6_HOPLIMIT
)
141 *hoplimit
= *((int *) CMSG_DATA (cmsgptr
));
146 #define RTADV_MSG_SIZE 4096
148 /* Send router advertisement packet. */
150 rtadv_send_packet (int sock
, struct interface
*ifp
)
154 struct cmsghdr
*cmsgptr
;
155 struct in6_pktinfo
*pkt
;
156 struct sockaddr_in6 addr
;
157 #ifdef HAVE_STRUCT_SOCKADDR_DL
158 struct sockaddr_dl
*sdl
;
159 #endif /* HAVE_STRUCT_SOCKADDR_DL */
160 static void *adata
= NULL
;
161 unsigned char buf
[RTADV_MSG_SIZE
];
162 struct nd_router_advert
*rtadv
;
165 struct zebra_if
*zif
;
166 struct rtadv_prefix
*rprefix
;
167 u_char all_nodes_addr
[] = {0xff,0x02,0,0,0,0,0,0,0,0,0,0,0,0,0,1};
168 struct listnode
*node
;
171 * Allocate control message bufffer. This is dynamic because
172 * CMSG_SPACE is not guaranteed not to call a function. Note that
173 * the size will be different on different architectures due to
174 * differing alignment rules.
178 /* XXX Free on shutdown. */
179 adata
= malloc(CMSG_SPACE(sizeof(struct in6_pktinfo
)));
182 zlog_err("rtadv_send_packet: can't malloc control data\n");
185 /* Logging of packet. */
186 if (IS_ZEBRA_DEBUG_PACKET
)
187 zlog_debug ("Router advertisement send to %s", ifp
->name
);
189 /* Fill in sockaddr_in6. */
190 memset (&addr
, 0, sizeof (struct sockaddr_in6
));
191 addr
.sin6_family
= AF_INET6
;
193 addr
.sin6_len
= sizeof (struct sockaddr_in6
);
194 #endif /* SIN6_LEN */
195 addr
.sin6_port
= htons (IPPROTO_ICMPV6
);
196 memcpy (&addr
.sin6_addr
, all_nodes_addr
, sizeof (struct in6_addr
));
198 /* Fetch interface information. */
201 /* Make router advertisement message. */
202 rtadv
= (struct nd_router_advert
*) buf
;
204 rtadv
->nd_ra_type
= ND_ROUTER_ADVERT
;
205 rtadv
->nd_ra_code
= 0;
206 rtadv
->nd_ra_cksum
= 0;
208 rtadv
->nd_ra_curhoplimit
= 64;
210 /* RFC4191: Default Router Preference is 0 if Router Lifetime is 0. */
211 rtadv
->nd_ra_flags_reserved
=
212 zif
->rtadv
.AdvDefaultLifetime
== 0 ? 0 : zif
->rtadv
.DefaultPreference
;
213 rtadv
->nd_ra_flags_reserved
<<= 3;
215 if (zif
->rtadv
.AdvManagedFlag
)
216 rtadv
->nd_ra_flags_reserved
|= ND_RA_FLAG_MANAGED
;
217 if (zif
->rtadv
.AdvOtherConfigFlag
)
218 rtadv
->nd_ra_flags_reserved
|= ND_RA_FLAG_OTHER
;
219 if (zif
->rtadv
.AdvHomeAgentFlag
)
220 rtadv
->nd_ra_flags_reserved
|= ND_RA_FLAG_HOME_AGENT
;
221 rtadv
->nd_ra_router_lifetime
= htons (zif
->rtadv
.AdvDefaultLifetime
);
222 rtadv
->nd_ra_reachable
= htonl (zif
->rtadv
.AdvReachableTime
);
223 rtadv
->nd_ra_retransmit
= htonl (0);
225 len
= sizeof (struct nd_router_advert
);
227 if (zif
->rtadv
.AdvHomeAgentFlag
)
229 struct nd_opt_homeagent_info
*ndopt_hai
=
230 (struct nd_opt_homeagent_info
*)(buf
+ len
);
231 ndopt_hai
->nd_opt_hai_type
= ND_OPT_HA_INFORMATION
;
232 ndopt_hai
->nd_opt_hai_len
= 1;
233 ndopt_hai
->nd_opt_hai_reserved
= 0;
234 ndopt_hai
->nd_opt_hai_preference
= htons(zif
->rtadv
.HomeAgentPreference
);
235 ndopt_hai
->nd_opt_hai_lifetime
= htons(zif
->rtadv
.HomeAgentLifetime
);
236 len
+= sizeof(struct nd_opt_homeagent_info
);
239 if (zif
->rtadv
.AdvIntervalOption
)
241 struct nd_opt_adv_interval
*ndopt_adv
=
242 (struct nd_opt_adv_interval
*)(buf
+ len
);
243 ndopt_adv
->nd_opt_ai_type
= ND_OPT_ADV_INTERVAL
;
244 ndopt_adv
->nd_opt_ai_len
= 1;
245 ndopt_adv
->nd_opt_ai_reserved
= 0;
246 ndopt_adv
->nd_opt_ai_interval
= htonl(zif
->rtadv
.MaxRtrAdvInterval
);
247 len
+= sizeof(struct nd_opt_adv_interval
);
250 /* Fill in prefix. */
251 for (ALL_LIST_ELEMENTS_RO (zif
->rtadv
.AdvPrefixList
, node
, rprefix
))
253 struct nd_opt_prefix_info
*pinfo
;
255 pinfo
= (struct nd_opt_prefix_info
*) (buf
+ len
);
257 pinfo
->nd_opt_pi_type
= ND_OPT_PREFIX_INFORMATION
;
258 pinfo
->nd_opt_pi_len
= 4;
259 pinfo
->nd_opt_pi_prefix_len
= rprefix
->prefix
.prefixlen
;
261 pinfo
->nd_opt_pi_flags_reserved
= 0;
262 if (rprefix
->AdvOnLinkFlag
)
263 pinfo
->nd_opt_pi_flags_reserved
|= ND_OPT_PI_FLAG_ONLINK
;
264 if (rprefix
->AdvAutonomousFlag
)
265 pinfo
->nd_opt_pi_flags_reserved
|= ND_OPT_PI_FLAG_AUTO
;
266 if (rprefix
->AdvRouterAddressFlag
)
267 pinfo
->nd_opt_pi_flags_reserved
|= ND_OPT_PI_FLAG_RADDR
;
269 pinfo
->nd_opt_pi_valid_time
= htonl (rprefix
->AdvValidLifetime
);
270 pinfo
->nd_opt_pi_preferred_time
= htonl (rprefix
->AdvPreferredLifetime
);
271 pinfo
->nd_opt_pi_reserved2
= 0;
273 memcpy (&pinfo
->nd_opt_pi_prefix
, &rprefix
->prefix
.u
.prefix6
,
274 sizeof (struct in6_addr
));
278 u_char buf
[INET6_ADDRSTRLEN
];
280 zlog_debug ("DEBUG %s", inet_ntop (AF_INET6
, &pinfo
->nd_opt_pi_prefix
,
281 buf
, INET6_ADDRSTRLEN
));
286 len
+= sizeof (struct nd_opt_prefix_info
);
289 /* Hardware address. */
290 #ifdef HAVE_STRUCT_SOCKADDR_DL
292 if (sdl
!= NULL
&& sdl
->sdl_alen
!= 0)
294 buf
[len
++] = ND_OPT_SOURCE_LINKADDR
;
295 buf
[len
++] = (sdl
->sdl_alen
+ 2) >> 3;
297 memcpy (buf
+ len
, LLADDR (sdl
), sdl
->sdl_alen
);
298 len
+= sdl
->sdl_alen
;
301 if (ifp
->hw_addr_len
!= 0)
303 buf
[len
++] = ND_OPT_SOURCE_LINKADDR
;
304 buf
[len
++] = (ifp
->hw_addr_len
+ 2) >> 3;
306 memcpy (buf
+ len
, ifp
->hw_addr
, ifp
->hw_addr_len
);
307 len
+= ifp
->hw_addr_len
;
309 #endif /* HAVE_STRUCT_SOCKADDR_DL */
311 msg
.msg_name
= (void *) &addr
;
312 msg
.msg_namelen
= sizeof (struct sockaddr_in6
);
315 msg
.msg_control
= (void *) adata
;
316 msg
.msg_controllen
= CMSG_SPACE(sizeof(struct in6_pktinfo
));
321 cmsgptr
= ZCMSG_FIRSTHDR(&msg
);
322 cmsgptr
->cmsg_len
= CMSG_LEN(sizeof(struct in6_pktinfo
));
323 cmsgptr
->cmsg_level
= IPPROTO_IPV6
;
324 cmsgptr
->cmsg_type
= IPV6_PKTINFO
;
326 pkt
= (struct in6_pktinfo
*) CMSG_DATA (cmsgptr
);
327 memset (&pkt
->ipi6_addr
, 0, sizeof (struct in6_addr
));
328 pkt
->ipi6_ifindex
= ifp
->ifindex
;
330 ret
= sendmsg (sock
, &msg
, 0);
333 zlog_err ("rtadv_send_packet: sendmsg %d (%s)\n",
334 errno
, safe_strerror(errno
));
339 rtadv_timer (struct thread
*thread
)
341 struct listnode
*node
, *nnode
;
342 struct interface
*ifp
;
343 struct zebra_if
*zif
;
346 rtadv
->ra_timer
= NULL
;
347 if (rtadv
->adv_msec_if_count
== 0)
349 period
= 1000; /* 1 s */
350 rtadv_event (RTADV_TIMER
, 1 /* 1 s */);
354 period
= 10; /* 10 ms */
355 rtadv_event (RTADV_TIMER_MSEC
, 10 /* 10 ms */);
358 for (ALL_LIST_ELEMENTS (iflist
, node
, nnode
, ifp
))
360 if (if_is_loopback (ifp
))
365 if (zif
->rtadv
.AdvSendAdvertisements
)
367 zif
->rtadv
.AdvIntervalTimer
-= period
;
368 if (zif
->rtadv
.AdvIntervalTimer
<= 0)
370 zif
->rtadv
.AdvIntervalTimer
= zif
->rtadv
.MaxRtrAdvInterval
;
371 rtadv_send_packet (rtadv
->sock
, ifp
);
379 rtadv_process_solicit (struct interface
*ifp
)
381 zlog_info ("Router solicitation received on %s", ifp
->name
);
383 rtadv_send_packet (rtadv
->sock
, ifp
);
387 rtadv_process_advert (void)
389 zlog_info ("Router advertisement received");
393 rtadv_process_packet (u_char
*buf
, unsigned int len
, unsigned int ifindex
, int hoplimit
)
395 struct icmp6_hdr
*icmph
;
396 struct interface
*ifp
;
397 struct zebra_if
*zif
;
399 /* Interface search. */
400 ifp
= if_lookup_by_index (ifindex
);
403 zlog_warn ("Unknown interface index: %d", ifindex
);
407 if (if_is_loopback (ifp
))
410 /* Check interface configuration. */
412 if (! zif
->rtadv
.AdvSendAdvertisements
)
415 /* ICMP message length check. */
416 if (len
< sizeof (struct icmp6_hdr
))
418 zlog_warn ("Invalid ICMPV6 packet length: %d", len
);
422 icmph
= (struct icmp6_hdr
*) buf
;
424 /* ICMP message type check. */
425 if (icmph
->icmp6_type
!= ND_ROUTER_SOLICIT
&&
426 icmph
->icmp6_type
!= ND_ROUTER_ADVERT
)
428 zlog_warn ("Unwanted ICMPV6 message type: %d", icmph
->icmp6_type
);
432 /* Hoplimit check. */
433 if (hoplimit
>= 0 && hoplimit
!= 255)
435 zlog_warn ("Invalid hoplimit %d for router advertisement ICMP packet",
440 /* Check ICMP message type. */
441 if (icmph
->icmp6_type
== ND_ROUTER_SOLICIT
)
442 rtadv_process_solicit (ifp
);
443 else if (icmph
->icmp6_type
== ND_ROUTER_ADVERT
)
444 rtadv_process_advert ();
450 rtadv_read (struct thread
*thread
)
454 u_char buf
[RTADV_MSG_SIZE
];
455 struct sockaddr_in6 from
;
456 unsigned int ifindex
;
459 sock
= THREAD_FD (thread
);
460 rtadv
->ra_read
= NULL
;
462 /* Register myself. */
463 rtadv_event (RTADV_READ
, sock
);
465 len
= rtadv_recv_packet (sock
, buf
, BUFSIZ
, &from
, &ifindex
, &hoplimit
);
469 zlog_warn ("router solicitation recv failed: %s.", safe_strerror (errno
));
473 rtadv_process_packet (buf
, (unsigned)len
, ifindex
, hoplimit
);
479 rtadv_make_socket (void)
483 struct icmp6_filter filter
;
485 if ( zserv_privs
.change (ZPRIVS_RAISE
) )
486 zlog_err ("rtadv_make_socket: could not raise privs, %s",
487 safe_strerror (errno
) );
489 sock
= socket (AF_INET6
, SOCK_RAW
, IPPROTO_ICMPV6
);
491 if ( zserv_privs
.change (ZPRIVS_LOWER
) )
492 zlog_err ("rtadv_make_socket: could not lower privs, %s",
493 safe_strerror (errno
) );
495 /* When we can't make ICMPV6 socket simply back. Router
496 advertisement feature will not be supported. */
500 ret
= setsockopt_ipv6_pktinfo (sock
, 1);
503 ret
= setsockopt_ipv6_multicast_loop (sock
, 0);
506 ret
= setsockopt_ipv6_unicast_hops (sock
, 255);
509 ret
= setsockopt_ipv6_multicast_hops (sock
, 255);
512 ret
= setsockopt_ipv6_hoplimit (sock
, 1);
516 ICMP6_FILTER_SETBLOCKALL(&filter
);
517 ICMP6_FILTER_SETPASS (ND_ROUTER_SOLICIT
, &filter
);
518 ICMP6_FILTER_SETPASS (ND_ROUTER_ADVERT
, &filter
);
520 ret
= setsockopt (sock
, IPPROTO_ICMPV6
, ICMP6_FILTER
, &filter
,
521 sizeof (struct icmp6_filter
));
524 zlog_info ("ICMP6_FILTER set fail: %s", safe_strerror (errno
));
531 static struct rtadv_prefix
*
532 rtadv_prefix_new (void)
534 return XCALLOC (MTYPE_RTADV_PREFIX
, sizeof (struct rtadv_prefix
));
538 rtadv_prefix_free (struct rtadv_prefix
*rtadv_prefix
)
540 XFREE (MTYPE_RTADV_PREFIX
, rtadv_prefix
);
543 static struct rtadv_prefix
*
544 rtadv_prefix_lookup (struct list
*rplist
, struct prefix
*p
)
546 struct listnode
*node
;
547 struct rtadv_prefix
*rprefix
;
549 for (ALL_LIST_ELEMENTS_RO (rplist
, node
, rprefix
))
550 if (prefix_same (&rprefix
->prefix
, p
))
555 static struct rtadv_prefix
*
556 rtadv_prefix_get (struct list
*rplist
, struct prefix
*p
)
558 struct rtadv_prefix
*rprefix
;
560 rprefix
= rtadv_prefix_lookup (rplist
, p
);
564 rprefix
= rtadv_prefix_new ();
565 memcpy (&rprefix
->prefix
, p
, sizeof (struct prefix
));
566 listnode_add (rplist
, rprefix
);
572 rtadv_prefix_set (struct zebra_if
*zif
, struct rtadv_prefix
*rp
)
574 struct rtadv_prefix
*rprefix
;
576 rprefix
= rtadv_prefix_get (zif
->rtadv
.AdvPrefixList
, &rp
->prefix
);
578 /* Set parameters. */
579 rprefix
->AdvValidLifetime
= rp
->AdvValidLifetime
;
580 rprefix
->AdvPreferredLifetime
= rp
->AdvPreferredLifetime
;
581 rprefix
->AdvOnLinkFlag
= rp
->AdvOnLinkFlag
;
582 rprefix
->AdvAutonomousFlag
= rp
->AdvAutonomousFlag
;
583 rprefix
->AdvRouterAddressFlag
= rp
->AdvRouterAddressFlag
;
587 rtadv_prefix_reset (struct zebra_if
*zif
, struct rtadv_prefix
*rp
)
589 struct rtadv_prefix
*rprefix
;
591 rprefix
= rtadv_prefix_lookup (zif
->rtadv
.AdvPrefixList
, &rp
->prefix
);
594 listnode_delete (zif
->rtadv
.AdvPrefixList
, (void *) rprefix
);
595 rtadv_prefix_free (rprefix
);
602 DEFUN (ipv6_nd_suppress_ra
,
603 ipv6_nd_suppress_ra_cmd
,
604 "ipv6 nd suppress-ra",
605 "Interface IPv6 config commands\n"
606 "Neighbor discovery\n"
607 "Suppress Router Advertisement\n")
609 struct interface
*ifp
;
610 struct zebra_if
*zif
;
615 if (if_is_loopback (ifp
))
617 vty_out (vty
, "Invalid interface%s", VTY_NEWLINE
);
621 if (zif
->rtadv
.AdvSendAdvertisements
)
623 zif
->rtadv
.AdvSendAdvertisements
= 0;
624 zif
->rtadv
.AdvIntervalTimer
= 0;
625 rtadv
->adv_if_count
--;
627 if_leave_all_router (rtadv
->sock
, ifp
);
629 if (rtadv
->adv_if_count
== 0)
630 rtadv_event (RTADV_STOP
, 0);
636 DEFUN (no_ipv6_nd_suppress_ra
,
637 no_ipv6_nd_suppress_ra_cmd
,
638 "no ipv6 nd suppress-ra",
640 "Interface IPv6 config commands\n"
641 "Neighbor discovery\n"
642 "Suppress Router Advertisement\n")
644 struct interface
*ifp
;
645 struct zebra_if
*zif
;
650 if (if_is_loopback (ifp
))
652 vty_out (vty
, "Invalid interface%s", VTY_NEWLINE
);
656 if (! zif
->rtadv
.AdvSendAdvertisements
)
658 zif
->rtadv
.AdvSendAdvertisements
= 1;
659 zif
->rtadv
.AdvIntervalTimer
= 0;
660 rtadv
->adv_if_count
++;
662 if_join_all_router (rtadv
->sock
, ifp
);
664 if (rtadv
->adv_if_count
== 1)
665 rtadv_event (RTADV_START
, rtadv
->sock
);
671 DEFUN (ipv6_nd_ra_interval_msec
,
672 ipv6_nd_ra_interval_msec_cmd
,
673 "ipv6 nd ra-interval msec MILLISECONDS",
674 "Interface IPv6 config commands\n"
675 "Neighbor discovery\n"
676 "Router Advertisement interval\n"
677 "Router Advertisement interval in milliseconds\n")
680 struct interface
*ifp
;
681 struct zebra_if
*zif
;
683 ifp
= (struct interface
*) vty
->index
;
686 interval
= atoi (argv
[0]);
690 vty_out (vty
, "Invalid Router Advertisement Interval%s", VTY_NEWLINE
);
694 if (zif
->rtadv
.MaxRtrAdvInterval
% 1000)
695 rtadv
->adv_msec_if_count
--;
698 rtadv
->adv_msec_if_count
++;
700 zif
->rtadv
.MaxRtrAdvInterval
= interval
;
701 zif
->rtadv
.MinRtrAdvInterval
= 0.33 * interval
;
702 zif
->rtadv
.AdvIntervalTimer
= 0;
707 DEFUN (ipv6_nd_ra_interval
,
708 ipv6_nd_ra_interval_cmd
,
709 "ipv6 nd ra-interval SECONDS",
710 "Interface IPv6 config commands\n"
711 "Neighbor discovery\n"
712 "Router Advertisement interval\n"
713 "Router Advertisement interval in seconds\n")
716 struct interface
*ifp
;
717 struct zebra_if
*zif
;
719 ifp
= (struct interface
*) vty
->index
;
722 interval
= atoi (argv
[0]);
726 vty_out (vty
, "Invalid Router Advertisement Interval%s", VTY_NEWLINE
);
730 if (zif
->rtadv
.MaxRtrAdvInterval
% 1000)
731 rtadv
->adv_msec_if_count
--;
733 /* convert to milliseconds */
734 interval
= interval
* 1000;
736 zif
->rtadv
.MaxRtrAdvInterval
= interval
;
737 zif
->rtadv
.MinRtrAdvInterval
= 0.33 * interval
;
738 zif
->rtadv
.AdvIntervalTimer
= 0;
743 DEFUN (no_ipv6_nd_ra_interval
,
744 no_ipv6_nd_ra_interval_cmd
,
745 "no ipv6 nd ra-interval",
747 "Interface IPv6 config commands\n"
748 "Neighbor discovery\n"
749 "Router Advertisement interval\n")
751 struct interface
*ifp
;
752 struct zebra_if
*zif
;
754 ifp
= (struct interface
*) vty
->index
;
757 if (zif
->rtadv
.MaxRtrAdvInterval
% 1000)
758 rtadv
->adv_msec_if_count
--;
760 zif
->rtadv
.MaxRtrAdvInterval
= RTADV_MAX_RTR_ADV_INTERVAL
;
761 zif
->rtadv
.MinRtrAdvInterval
= RTADV_MIN_RTR_ADV_INTERVAL
;
762 zif
->rtadv
.AdvIntervalTimer
= zif
->rtadv
.MaxRtrAdvInterval
;
767 DEFUN (ipv6_nd_ra_lifetime
,
768 ipv6_nd_ra_lifetime_cmd
,
769 "ipv6 nd ra-lifetime SECONDS",
770 "Interface IPv6 config commands\n"
771 "Neighbor discovery\n"
773 "Router lifetime in seconds\n")
776 struct interface
*ifp
;
777 struct zebra_if
*zif
;
779 ifp
= (struct interface
*) vty
->index
;
782 lifetime
= atoi (argv
[0]);
784 if (lifetime
< 0 || lifetime
> 0xffff)
786 vty_out (vty
, "Invalid Router Lifetime%s", VTY_NEWLINE
);
790 zif
->rtadv
.AdvDefaultLifetime
= lifetime
;
795 DEFUN (no_ipv6_nd_ra_lifetime
,
796 no_ipv6_nd_ra_lifetime_cmd
,
797 "no ipv6 nd ra-lifetime",
799 "Interface IPv6 config commands\n"
800 "Neighbor discovery\n"
803 struct interface
*ifp
;
804 struct zebra_if
*zif
;
806 ifp
= (struct interface
*) vty
->index
;
809 zif
->rtadv
.AdvDefaultLifetime
= RTADV_ADV_DEFAULT_LIFETIME
;
814 DEFUN (ipv6_nd_reachable_time
,
815 ipv6_nd_reachable_time_cmd
,
816 "ipv6 nd reachable-time MILLISECONDS",
817 "Interface IPv6 config commands\n"
818 "Neighbor discovery\n"
820 "Reachable time in milliseconds\n")
823 struct interface
*ifp
;
824 struct zebra_if
*zif
;
826 ifp
= (struct interface
*) vty
->index
;
829 rtime
= (u_int32_t
) atol (argv
[0]);
831 if (rtime
> RTADV_MAX_REACHABLE_TIME
)
833 vty_out (vty
, "Invalid Reachable time%s", VTY_NEWLINE
);
837 zif
->rtadv
.AdvReachableTime
= rtime
;
842 DEFUN (no_ipv6_nd_reachable_time
,
843 no_ipv6_nd_reachable_time_cmd
,
844 "no ipv6 nd reachable-time",
846 "Interface IPv6 config commands\n"
847 "Neighbor discovery\n"
850 struct interface
*ifp
;
851 struct zebra_if
*zif
;
853 ifp
= (struct interface
*) vty
->index
;
856 zif
->rtadv
.AdvReachableTime
= 0;
861 DEFUN (ipv6_nd_homeagent_preference
,
862 ipv6_nd_homeagent_preference_cmd
,
863 "ipv6 nd home-agent-preference PREFERENCE",
864 "Interface IPv6 config commands\n"
865 "Neighbor discovery\n"
866 "Home Agent preference\n"
867 "Home Agent preference value 0..65535\n")
870 struct interface
*ifp
;
871 struct zebra_if
*zif
;
873 ifp
= (struct interface
*) vty
->index
;
876 hapref
= (u_int32_t
) atol (argv
[0]);
880 vty_out (vty
, "Invalid Home Agent preference%s", VTY_NEWLINE
);
884 zif
->rtadv
.HomeAgentPreference
= hapref
;
889 DEFUN (no_ipv6_nd_homeagent_preference
,
890 no_ipv6_nd_homeagent_preference_cmd
,
891 "no ipv6 nd home-agent-preference",
893 "Interface IPv6 config commands\n"
894 "Neighbor discovery\n"
895 "Home Agent preference\n")
897 struct interface
*ifp
;
898 struct zebra_if
*zif
;
900 ifp
= (struct interface
*) vty
->index
;
903 zif
->rtadv
.HomeAgentPreference
= 0;
908 DEFUN (ipv6_nd_homeagent_lifetime
,
909 ipv6_nd_homeagent_lifetime_cmd
,
910 "ipv6 nd home-agent-lifetime SECONDS",
911 "Interface IPv6 config commands\n"
912 "Neighbor discovery\n"
913 "Home Agent lifetime\n"
914 "Home Agent lifetime in seconds\n")
917 struct interface
*ifp
;
918 struct zebra_if
*zif
;
920 ifp
= (struct interface
*) vty
->index
;
923 ha_ltime
= (u_int32_t
) atol (argv
[0]);
925 if (ha_ltime
> RTADV_MAX_HALIFETIME
)
927 vty_out (vty
, "Invalid Home Agent Lifetime time%s", VTY_NEWLINE
);
931 zif
->rtadv
.HomeAgentLifetime
= ha_ltime
;
936 DEFUN (no_ipv6_nd_homeagent_lifetime
,
937 no_ipv6_nd_homeagent_lifetime_cmd
,
938 "no ipv6 nd home-agent-lifetime",
940 "Interface IPv6 config commands\n"
941 "Neighbor discovery\n"
942 "Home Agent lifetime\n")
944 struct interface
*ifp
;
945 struct zebra_if
*zif
;
947 ifp
= (struct interface
*) vty
->index
;
950 zif
->rtadv
.HomeAgentLifetime
= 0;
955 DEFUN (ipv6_nd_managed_config_flag
,
956 ipv6_nd_managed_config_flag_cmd
,
957 "ipv6 nd managed-config-flag",
958 "Interface IPv6 config commands\n"
959 "Neighbor discovery\n"
960 "Managed address configuration flag\n")
962 struct interface
*ifp
;
963 struct zebra_if
*zif
;
965 ifp
= (struct interface
*) vty
->index
;
968 zif
->rtadv
.AdvManagedFlag
= 1;
973 DEFUN (no_ipv6_nd_managed_config_flag
,
974 no_ipv6_nd_managed_config_flag_cmd
,
975 "no ipv6 nd managed-config-flag",
977 "Interface IPv6 config commands\n"
978 "Neighbor discovery\n"
979 "Managed address configuration flag\n")
981 struct interface
*ifp
;
982 struct zebra_if
*zif
;
984 ifp
= (struct interface
*) vty
->index
;
987 zif
->rtadv
.AdvManagedFlag
= 0;
992 DEFUN (ipv6_nd_homeagent_config_flag
,
993 ipv6_nd_homeagent_config_flag_cmd
,
994 "ipv6 nd home-agent-config-flag",
995 "Interface IPv6 config commands\n"
996 "Neighbor discovery\n"
997 "Home Agent configuration flag\n")
999 struct interface
*ifp
;
1000 struct zebra_if
*zif
;
1002 ifp
= (struct interface
*) vty
->index
;
1005 zif
->rtadv
.AdvHomeAgentFlag
= 1;
1010 DEFUN (no_ipv6_nd_homeagent_config_flag
,
1011 no_ipv6_nd_homeagent_config_flag_cmd
,
1012 "no ipv6 nd home-agent-config-flag",
1014 "Interface IPv6 config commands\n"
1015 "Neighbor discovery\n"
1016 "Home Agent configuration flag\n")
1018 struct interface
*ifp
;
1019 struct zebra_if
*zif
;
1021 ifp
= (struct interface
*) vty
->index
;
1024 zif
->rtadv
.AdvHomeAgentFlag
= 0;
1029 DEFUN (ipv6_nd_adv_interval_config_option
,
1030 ipv6_nd_adv_interval_config_option_cmd
,
1031 "ipv6 nd adv-interval-option",
1032 "Interface IPv6 config commands\n"
1033 "Neighbor discovery\n"
1034 "Advertisement Interval Option\n")
1036 struct interface
*ifp
;
1037 struct zebra_if
*zif
;
1039 ifp
= (struct interface
*) vty
->index
;
1042 zif
->rtadv
.AdvIntervalOption
= 1;
1047 DEFUN (no_ipv6_nd_adv_interval_config_option
,
1048 no_ipv6_nd_adv_interval_config_option_cmd
,
1049 "no ipv6 nd adv-interval-option",
1051 "Interface IPv6 config commands\n"
1052 "Neighbor discovery\n"
1053 "Advertisement Interval Option\n")
1055 struct interface
*ifp
;
1056 struct zebra_if
*zif
;
1058 ifp
= (struct interface
*) vty
->index
;
1061 zif
->rtadv
.AdvIntervalOption
= 0;
1066 DEFUN (ipv6_nd_other_config_flag
,
1067 ipv6_nd_other_config_flag_cmd
,
1068 "ipv6 nd other-config-flag",
1069 "Interface IPv6 config commands\n"
1070 "Neighbor discovery\n"
1071 "Other statefull configuration flag\n")
1073 struct interface
*ifp
;
1074 struct zebra_if
*zif
;
1076 ifp
= (struct interface
*) vty
->index
;
1079 zif
->rtadv
.AdvOtherConfigFlag
= 1;
1084 DEFUN (no_ipv6_nd_other_config_flag
,
1085 no_ipv6_nd_other_config_flag_cmd
,
1086 "no ipv6 nd other-config-flag",
1088 "Interface IPv6 config commands\n"
1089 "Neighbor discovery\n"
1090 "Other statefull configuration flag\n")
1092 struct interface
*ifp
;
1093 struct zebra_if
*zif
;
1095 ifp
= (struct interface
*) vty
->index
;
1098 zif
->rtadv
.AdvOtherConfigFlag
= 0;
1103 DEFUN (ipv6_nd_prefix
,
1105 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1106 "(<0-4294967295>|infinite) (off-link|) (no-autoconfig|) (router-address|)",
1107 "Interface IPv6 config commands\n"
1108 "Neighbor discovery\n"
1109 "Prefix information\n"
1111 "Valid lifetime in seconds\n"
1112 "Infinite valid lifetime\n"
1113 "Preferred lifetime in seconds\n"
1114 "Infinite preferred lifetime\n"
1115 "Do not use prefix for onlink determination\n"
1116 "Do not use prefix for autoconfiguration\n"
1117 "Set Router Address flag\n")
1122 struct interface
*ifp
;
1123 struct zebra_if
*zebra_if
;
1124 struct rtadv_prefix rp
;
1126 ifp
= (struct interface
*) vty
->index
;
1127 zebra_if
= ifp
->info
;
1129 ret
= str2prefix_ipv6 (argv
[0], (struct prefix_ipv6
*) &rp
.prefix
);
1132 vty_out (vty
, "Malformed IPv6 prefix%s", VTY_NEWLINE
);
1135 rp
.AdvOnLinkFlag
= 1;
1136 rp
.AdvAutonomousFlag
= 1;
1137 rp
.AdvRouterAddressFlag
= 0;
1138 rp
.AdvValidLifetime
= RTADV_VALID_LIFETIME
;
1139 rp
.AdvPreferredLifetime
= RTADV_PREFERRED_LIFETIME
;
1143 if ((isdigit(argv
[1][0])) || strncmp (argv
[1], "i", 1) == 0)
1145 if ( strncmp (argv
[1], "i", 1) == 0)
1146 rp
.AdvValidLifetime
= UINT32_MAX
;
1148 rp
.AdvValidLifetime
= (u_int32_t
) strtoll (argv
[1],
1151 if ( strncmp (argv
[2], "i", 1) == 0)
1152 rp
.AdvPreferredLifetime
= UINT32_MAX
;
1154 rp
.AdvPreferredLifetime
= (u_int32_t
) strtoll (argv
[2],
1157 if (rp
.AdvPreferredLifetime
> rp
.AdvValidLifetime
)
1159 vty_out (vty
, "Invalid preferred lifetime%s", VTY_NEWLINE
);
1162 cursor
= cursor
+ 2;
1166 for (i
= cursor
; i
< argc
; i
++)
1168 if (strncmp (argv
[i
], "of", 2) == 0)
1169 rp
.AdvOnLinkFlag
= 0;
1170 if (strncmp (argv
[i
], "no", 2) == 0)
1171 rp
.AdvAutonomousFlag
= 0;
1172 if (strncmp (argv
[i
], "ro", 2) == 0)
1173 rp
.AdvRouterAddressFlag
= 1;
1178 rtadv_prefix_set (zebra_if
, &rp
);
1183 ALIAS (ipv6_nd_prefix
,
1184 ipv6_nd_prefix_val_nortaddr_cmd
,
1185 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1186 "(<0-4294967295>|infinite) (off-link|) (no-autoconfig|)",
1187 "Interface IPv6 config commands\n"
1188 "Neighbor discovery\n"
1189 "Prefix information\n"
1191 "Valid lifetime in seconds\n"
1192 "Infinite valid lifetime\n"
1193 "Preferred lifetime in seconds\n"
1194 "Infinite preferred lifetime\n"
1195 "Do not use prefix for onlink determination\n"
1196 "Do not use prefix for autoconfiguration\n")
1198 ALIAS (ipv6_nd_prefix
,
1199 ipv6_nd_prefix_val_rev_cmd
,
1200 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1201 "(<0-4294967295>|infinite) (no-autoconfig|) (off-link|)",
1202 "Interface IPv6 config commands\n"
1203 "Neighbor discovery\n"
1204 "Prefix information\n"
1206 "Valid lifetime in seconds\n"
1207 "Infinite valid lifetime\n"
1208 "Preferred lifetime in seconds\n"
1209 "Infinite preferred lifetime\n"
1210 "Do not use prefix for autoconfiguration\n"
1211 "Do not use prefix for onlink determination\n")
1213 ALIAS (ipv6_nd_prefix
,
1214 ipv6_nd_prefix_val_rev_rtaddr_cmd
,
1215 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1216 "(<0-4294967295>|infinite) (no-autoconfig|) (off-link|) (router-address|)",
1217 "Interface IPv6 config commands\n"
1218 "Neighbor discovery\n"
1219 "Prefix information\n"
1221 "Valid lifetime in seconds\n"
1222 "Infinite valid lifetime\n"
1223 "Preferred lifetime in seconds\n"
1224 "Infinite preferred lifetime\n"
1225 "Do not use prefix for autoconfiguration\n"
1226 "Do not use prefix for onlink determination\n"
1227 "Set Router Address flag\n")
1229 ALIAS (ipv6_nd_prefix
,
1230 ipv6_nd_prefix_val_noauto_cmd
,
1231 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1232 "(<0-4294967295>|infinite) (no-autoconfig|)",
1233 "Interface IPv6 config commands\n"
1234 "Neighbor discovery\n"
1235 "Prefix information\n"
1237 "Valid lifetime in seconds\n"
1238 "Infinite valid lifetime\n"
1239 "Preferred lifetime in seconds\n"
1240 "Infinite preferred lifetime\n"
1241 "Do not use prefix for autoconfiguration")
1243 ALIAS (ipv6_nd_prefix
,
1244 ipv6_nd_prefix_val_offlink_cmd
,
1245 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1246 "(<0-4294967295>|infinite) (off-link|)",
1247 "Interface IPv6 config commands\n"
1248 "Neighbor discovery\n"
1249 "Prefix information\n"
1251 "Valid lifetime in seconds\n"
1252 "Infinite valid lifetime\n"
1253 "Preferred lifetime in seconds\n"
1254 "Infinite preferred lifetime\n"
1255 "Do not use prefix for onlink determination\n")
1257 ALIAS (ipv6_nd_prefix
,
1258 ipv6_nd_prefix_val_rtaddr_cmd
,
1259 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1260 "(<0-4294967295>|infinite) (router-address|)",
1261 "Interface IPv6 config commands\n"
1262 "Neighbor discovery\n"
1263 "Prefix information\n"
1265 "Valid lifetime in seconds\n"
1266 "Infinite valid lifetime\n"
1267 "Preferred lifetime in seconds\n"
1268 "Infinite preferred lifetime\n"
1269 "Set Router Address flag\n")
1271 ALIAS (ipv6_nd_prefix
,
1272 ipv6_nd_prefix_val_cmd
,
1273 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1274 "(<0-4294967295>|infinite)",
1275 "Interface IPv6 config commands\n"
1276 "Neighbor discovery\n"
1277 "Prefix information\n"
1279 "Valid lifetime in seconds\n"
1280 "Infinite valid lifetime\n"
1281 "Preferred lifetime in seconds\n"
1282 "Infinite preferred lifetime\n")
1284 ALIAS (ipv6_nd_prefix
,
1285 ipv6_nd_prefix_noval_cmd
,
1286 "ipv6 nd prefix X:X::X:X/M (no-autoconfig|) (off-link|)",
1287 "Interface IPv6 config commands\n"
1288 "Neighbor discovery\n"
1289 "Prefix information\n"
1291 "Do not use prefix for autoconfiguration\n"
1292 "Do not use prefix for onlink determination\n")
1294 ALIAS (ipv6_nd_prefix
,
1295 ipv6_nd_prefix_noval_rev_cmd
,
1296 "ipv6 nd prefix X:X::X:X/M (off-link|) (no-autoconfig|)",
1297 "Interface IPv6 config commands\n"
1298 "Neighbor discovery\n"
1299 "Prefix information\n"
1301 "Do not use prefix for onlink determination\n"
1302 "Do not use prefix for autoconfiguration\n")
1304 ALIAS (ipv6_nd_prefix
,
1305 ipv6_nd_prefix_noval_noauto_cmd
,
1306 "ipv6 nd prefix X:X::X:X/M (no-autoconfig|)",
1307 "Interface IPv6 config commands\n"
1308 "Neighbor discovery\n"
1309 "Prefix information\n"
1311 "Do not use prefix for autoconfiguration\n")
1313 ALIAS (ipv6_nd_prefix
,
1314 ipv6_nd_prefix_noval_offlink_cmd
,
1315 "ipv6 nd prefix X:X::X:X/M (off-link|)",
1316 "Interface IPv6 config commands\n"
1317 "Neighbor discovery\n"
1318 "Prefix information\n"
1320 "Do not use prefix for onlink determination\n")
1322 ALIAS (ipv6_nd_prefix
,
1323 ipv6_nd_prefix_noval_rtaddr_cmd
,
1324 "ipv6 nd prefix X:X::X:X/M (router-address|)",
1325 "Interface IPv6 config commands\n"
1326 "Neighbor discovery\n"
1327 "Prefix information\n"
1329 "Set Router Address flag\n")
1331 ALIAS (ipv6_nd_prefix
,
1332 ipv6_nd_prefix_prefix_cmd
,
1333 "ipv6 nd prefix X:X::X:X/M",
1334 "Interface IPv6 config commands\n"
1335 "Neighbor discovery\n"
1336 "Prefix information\n"
1339 DEFUN (no_ipv6_nd_prefix
,
1340 no_ipv6_nd_prefix_cmd
,
1341 "no ipv6 nd prefix IPV6PREFIX",
1343 "Interface IPv6 config commands\n"
1344 "Neighbor discovery\n"
1345 "Prefix information\n"
1349 struct interface
*ifp
;
1350 struct zebra_if
*zebra_if
;
1351 struct rtadv_prefix rp
;
1353 ifp
= (struct interface
*) vty
->index
;
1354 zebra_if
= ifp
->info
;
1356 ret
= str2prefix_ipv6 (argv
[0], (struct prefix_ipv6
*) &rp
.prefix
);
1359 vty_out (vty
, "Malformed IPv6 prefix%s", VTY_NEWLINE
);
1363 ret
= rtadv_prefix_reset (zebra_if
, &rp
);
1366 vty_out (vty
, "Non-exist IPv6 prefix%s", VTY_NEWLINE
);
1373 DEFUN (ipv6_nd_router_preference
,
1374 ipv6_nd_router_preference_cmd
,
1375 "ipv6 nd router-preference (high|medium|low)",
1376 "Interface IPv6 config commands\n"
1377 "Neighbor discovery\n"
1378 "Default router preference\n"
1379 "High default router preference\n"
1380 "Low default router preference\n"
1381 "Medium default router preference (default)\n")
1383 struct interface
*ifp
;
1384 struct zebra_if
*zif
;
1387 ifp
= (struct interface
*) vty
->index
;
1390 while (0 != rtadv_pref_strs
[i
])
1392 if (strncmp (argv
[0], rtadv_pref_strs
[i
], 1) == 0)
1394 zif
->rtadv
.DefaultPreference
= i
;
1400 return CMD_ERR_NO_MATCH
;
1403 DEFUN (no_ipv6_nd_router_preference
,
1404 no_ipv6_nd_router_preference_cmd
,
1405 "no ipv6 nd router-preference",
1407 "Interface IPv6 config commands\n"
1408 "Neighbor discovery\n"
1409 "Default router preference\n")
1411 struct interface
*ifp
;
1412 struct zebra_if
*zif
;
1414 ifp
= (struct interface
*) vty
->index
;
1417 zif
->rtadv
.DefaultPreference
= RTADV_PREF_MEDIUM
; /* Default per RFC4191. */
1422 /* Write configuration about router advertisement. */
1424 rtadv_config_write (struct vty
*vty
, struct interface
*ifp
)
1426 struct zebra_if
*zif
;
1427 struct listnode
*node
;
1428 struct rtadv_prefix
*rprefix
;
1429 u_char buf
[INET6_ADDRSTRLEN
];
1437 if (! if_is_loopback (ifp
))
1439 if (zif
->rtadv
.AdvSendAdvertisements
)
1440 vty_out (vty
, " no ipv6 nd suppress-ra%s", VTY_NEWLINE
);
1442 vty_out (vty
, " ipv6 nd suppress-ra%s", VTY_NEWLINE
);
1446 interval
= zif
->rtadv
.MaxRtrAdvInterval
;
1447 if (interval
% 1000)
1448 vty_out (vty
, " ipv6 nd ra-interval msec %d%s", interval
,
1451 if (interval
!= RTADV_MAX_RTR_ADV_INTERVAL
)
1452 vty_out (vty
, " ipv6 nd ra-interval %d%s", interval
/ 1000,
1455 if (zif
->rtadv
.AdvDefaultLifetime
!= RTADV_ADV_DEFAULT_LIFETIME
)
1456 vty_out (vty
, " ipv6 nd ra-lifetime %d%s", zif
->rtadv
.AdvDefaultLifetime
,
1459 if (zif
->rtadv
.AdvReachableTime
)
1460 vty_out (vty
, " ipv6 nd reachable-time %d%s", zif
->rtadv
.AdvReachableTime
,
1463 if (zif
->rtadv
.AdvManagedFlag
)
1464 vty_out (vty
, " ipv6 nd managed-config-flag%s", VTY_NEWLINE
);
1466 if (zif
->rtadv
.AdvOtherConfigFlag
)
1467 vty_out (vty
, " ipv6 nd other-config-flag%s", VTY_NEWLINE
);
1469 if (zif
->rtadv
.DefaultPreference
!= RTADV_PREF_MEDIUM
)
1470 vty_out (vty
, " ipv6 nd router-preference %s%s",
1471 rtadv_pref_strs
[zif
->rtadv
.DefaultPreference
],
1474 for (ALL_LIST_ELEMENTS_RO (zif
->rtadv
.AdvPrefixList
, node
, rprefix
))
1476 vty_out (vty
, " ipv6 nd prefix %s/%d",
1477 inet_ntop (AF_INET6
, &rprefix
->prefix
.u
.prefix6
,
1478 (char *) buf
, INET6_ADDRSTRLEN
),
1479 rprefix
->prefix
.prefixlen
);
1480 if ((rprefix
->AdvValidLifetime
!= RTADV_VALID_LIFETIME
) ||
1481 (rprefix
->AdvPreferredLifetime
!= RTADV_PREFERRED_LIFETIME
))
1483 if (rprefix
->AdvValidLifetime
== UINT32_MAX
)
1484 vty_out (vty
, " infinite");
1486 vty_out (vty
, " %u", rprefix
->AdvValidLifetime
);
1487 if (rprefix
->AdvPreferredLifetime
== UINT32_MAX
)
1488 vty_out (vty
, " infinite");
1490 vty_out (vty
, " %u", rprefix
->AdvPreferredLifetime
);
1492 if (!rprefix
->AdvOnLinkFlag
)
1493 vty_out (vty
, " off-link");
1494 if (!rprefix
->AdvAutonomousFlag
)
1495 vty_out (vty
, " no-autoconfig");
1496 if (rprefix
->AdvRouterAddressFlag
)
1497 vty_out (vty
, " router-address");
1498 vty_out (vty
, "%s", VTY_NEWLINE
);
1504 rtadv_event (enum rtadv_event event
, int val
)
1509 if (! rtadv
->ra_read
)
1510 rtadv
->ra_read
= thread_add_read (zebrad
.master
, rtadv_read
, NULL
, val
);
1511 if (! rtadv
->ra_timer
)
1512 rtadv
->ra_timer
= thread_add_event (zebrad
.master
, rtadv_timer
,
1516 if (rtadv
->ra_timer
)
1518 thread_cancel (rtadv
->ra_timer
);
1519 rtadv
->ra_timer
= NULL
;
1523 thread_cancel (rtadv
->ra_read
);
1524 rtadv
->ra_read
= NULL
;
1528 if (! rtadv
->ra_timer
)
1529 rtadv
->ra_timer
= thread_add_timer (zebrad
.master
, rtadv_timer
, NULL
,
1532 case RTADV_TIMER_MSEC
:
1533 if (! rtadv
->ra_timer
)
1534 rtadv
->ra_timer
= thread_add_timer_msec (zebrad
.master
, rtadv_timer
,
1538 if (! rtadv
->ra_read
)
1539 rtadv
->ra_read
= thread_add_read (zebrad
.master
, rtadv_read
, NULL
, val
);
1552 sock
= rtadv_make_socket ();
1556 rtadv
= rtadv_new ();
1559 install_element (INTERFACE_NODE
, &ipv6_nd_suppress_ra_cmd
);
1560 install_element (INTERFACE_NODE
, &no_ipv6_nd_suppress_ra_cmd
);
1561 install_element (INTERFACE_NODE
, &ipv6_nd_ra_interval_cmd
);
1562 install_element (INTERFACE_NODE
, &ipv6_nd_ra_interval_msec_cmd
);
1563 install_element (INTERFACE_NODE
, &no_ipv6_nd_ra_interval_cmd
);
1564 install_element (INTERFACE_NODE
, &ipv6_nd_ra_lifetime_cmd
);
1565 install_element (INTERFACE_NODE
, &no_ipv6_nd_ra_lifetime_cmd
);
1566 install_element (INTERFACE_NODE
, &ipv6_nd_reachable_time_cmd
);
1567 install_element (INTERFACE_NODE
, &no_ipv6_nd_reachable_time_cmd
);
1568 install_element (INTERFACE_NODE
, &ipv6_nd_managed_config_flag_cmd
);
1569 install_element (INTERFACE_NODE
, &no_ipv6_nd_managed_config_flag_cmd
);
1570 install_element (INTERFACE_NODE
, &ipv6_nd_other_config_flag_cmd
);
1571 install_element (INTERFACE_NODE
, &no_ipv6_nd_other_config_flag_cmd
);
1572 install_element (INTERFACE_NODE
, &ipv6_nd_homeagent_config_flag_cmd
);
1573 install_element (INTERFACE_NODE
, &no_ipv6_nd_homeagent_config_flag_cmd
);
1574 install_element (INTERFACE_NODE
, &ipv6_nd_homeagent_preference_cmd
);
1575 install_element (INTERFACE_NODE
, &no_ipv6_nd_homeagent_preference_cmd
);
1576 install_element (INTERFACE_NODE
, &ipv6_nd_homeagent_lifetime_cmd
);
1577 install_element (INTERFACE_NODE
, &no_ipv6_nd_homeagent_lifetime_cmd
);
1578 install_element (INTERFACE_NODE
, &ipv6_nd_adv_interval_config_option_cmd
);
1579 install_element (INTERFACE_NODE
, &no_ipv6_nd_adv_interval_config_option_cmd
);
1580 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_cmd
);
1581 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_val_rev_rtaddr_cmd
);
1582 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_val_nortaddr_cmd
);
1583 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_val_rev_cmd
);
1584 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_val_noauto_cmd
);
1585 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_val_offlink_cmd
);
1586 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_val_rtaddr_cmd
);
1587 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_val_cmd
);
1588 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_noval_cmd
);
1589 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_noval_rev_cmd
);
1590 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_noval_noauto_cmd
);
1591 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_noval_offlink_cmd
);
1592 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_noval_rtaddr_cmd
);
1593 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_prefix_cmd
);
1594 install_element (INTERFACE_NODE
, &no_ipv6_nd_prefix_cmd
);
1595 install_element (INTERFACE_NODE
, &ipv6_nd_router_preference_cmd
);
1596 install_element (INTERFACE_NODE
, &no_ipv6_nd_router_preference_cmd
);
1600 if_join_all_router (int sock
, struct interface
*ifp
)
1604 struct ipv6_mreq mreq
;
1606 memset (&mreq
, 0, sizeof (struct ipv6_mreq
));
1607 inet_pton (AF_INET6
, ALLROUTER
, &mreq
.ipv6mr_multiaddr
);
1608 mreq
.ipv6mr_interface
= ifp
->ifindex
;
1610 ret
= setsockopt (sock
, IPPROTO_IPV6
, IPV6_JOIN_GROUP
,
1611 (char *) &mreq
, sizeof mreq
);
1613 zlog_warn ("can't setsockopt IPV6_JOIN_GROUP: %s", safe_strerror (errno
));
1615 zlog_info ("rtadv: %s join to all-routers multicast group", ifp
->name
);
1621 if_leave_all_router (int sock
, struct interface
*ifp
)
1625 struct ipv6_mreq mreq
;
1627 memset (&mreq
, 0, sizeof (struct ipv6_mreq
));
1628 inet_pton (AF_INET6
, ALLROUTER
, &mreq
.ipv6mr_multiaddr
);
1629 mreq
.ipv6mr_interface
= ifp
->ifindex
;
1631 ret
= setsockopt (sock
, IPPROTO_IPV6
, IPV6_LEAVE_GROUP
,
1632 (char *) &mreq
, sizeof mreq
);
1634 zlog_warn ("can't setsockopt IPV6_LEAVE_GROUP: %s", safe_strerror (errno
));
1636 zlog_info ("rtadv: %s leave from all-routers multicast group", ifp
->name
);
1647 #endif /* RTADV && HAVE_IPV6 */