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_recv_packet (int sock
, u_char
*buf
, int buflen
,
92 struct sockaddr_in6
*from
, unsigned int *ifindex
,
98 struct cmsghdr
*cmsgptr
;
103 /* Fill in message and iovec. */
104 msg
.msg_name
= (void *) from
;
105 msg
.msg_namelen
= sizeof (struct sockaddr_in6
);
108 msg
.msg_control
= (void *) adata
;
109 msg
.msg_controllen
= sizeof adata
;
111 iov
.iov_len
= buflen
;
113 /* If recvmsg fail return minus value. */
114 ret
= recvmsg (sock
, &msg
, 0);
118 for (cmsgptr
= ZCMSG_FIRSTHDR(&msg
); cmsgptr
!= NULL
;
119 cmsgptr
= CMSG_NXTHDR(&msg
, cmsgptr
))
121 /* I want interface index which this packet comes from. */
122 if (cmsgptr
->cmsg_level
== IPPROTO_IPV6
&&
123 cmsgptr
->cmsg_type
== IPV6_PKTINFO
)
125 struct in6_pktinfo
*ptr
;
127 ptr
= (struct in6_pktinfo
*) CMSG_DATA (cmsgptr
);
128 *ifindex
= ptr
->ipi6_ifindex
;
129 memcpy(&dst
, &ptr
->ipi6_addr
, sizeof(ptr
->ipi6_addr
));
132 /* Incoming packet's hop limit. */
133 if (cmsgptr
->cmsg_level
== IPPROTO_IPV6
&&
134 cmsgptr
->cmsg_type
== IPV6_HOPLIMIT
)
136 int *hoptr
= (int *) CMSG_DATA (cmsgptr
);
143 #define RTADV_MSG_SIZE 4096
145 /* Send router advertisement packet. */
147 rtadv_send_packet (int sock
, struct interface
*ifp
)
151 struct cmsghdr
*cmsgptr
;
152 struct in6_pktinfo
*pkt
;
153 struct sockaddr_in6 addr
;
154 #ifdef HAVE_STRUCT_SOCKADDR_DL
155 struct sockaddr_dl
*sdl
;
156 #endif /* HAVE_STRUCT_SOCKADDR_DL */
157 static void *adata
= NULL
;
158 unsigned char buf
[RTADV_MSG_SIZE
];
159 struct nd_router_advert
*rtadv
;
162 struct zebra_if
*zif
;
163 struct rtadv_prefix
*rprefix
;
164 u_char all_nodes_addr
[] = {0xff,0x02,0,0,0,0,0,0,0,0,0,0,0,0,0,1};
165 struct listnode
*node
;
168 * Allocate control message bufffer. This is dynamic because
169 * CMSG_SPACE is not guaranteed not to call a function. Note that
170 * the size will be different on different architectures due to
171 * differing alignment rules.
175 /* XXX Free on shutdown. */
176 adata
= malloc(CMSG_SPACE(sizeof(struct in6_pktinfo
)));
179 zlog_err("rtadv_send_packet: can't malloc control data\n");
182 /* Logging of packet. */
183 if (IS_ZEBRA_DEBUG_PACKET
)
184 zlog_debug ("Router advertisement send to %s", ifp
->name
);
186 /* Fill in sockaddr_in6. */
187 memset (&addr
, 0, sizeof (struct sockaddr_in6
));
188 addr
.sin6_family
= AF_INET6
;
190 addr
.sin6_len
= sizeof (struct sockaddr_in6
);
191 #endif /* SIN6_LEN */
192 addr
.sin6_port
= htons (IPPROTO_ICMPV6
);
193 memcpy (&addr
.sin6_addr
, all_nodes_addr
, sizeof (struct in6_addr
));
195 /* Fetch interface information. */
198 /* Make router advertisement message. */
199 rtadv
= (struct nd_router_advert
*) buf
;
201 rtadv
->nd_ra_type
= ND_ROUTER_ADVERT
;
202 rtadv
->nd_ra_code
= 0;
203 rtadv
->nd_ra_cksum
= 0;
205 rtadv
->nd_ra_curhoplimit
= 64;
207 /* RFC4191: Default Router Preference is 0 if Router Lifetime is 0. */
208 rtadv
->nd_ra_flags_reserved
=
209 zif
->rtadv
.AdvDefaultLifetime
== 0 ? 0 : zif
->rtadv
.DefaultPreference
;
210 rtadv
->nd_ra_flags_reserved
<<= 3;
212 if (zif
->rtadv
.AdvManagedFlag
)
213 rtadv
->nd_ra_flags_reserved
|= ND_RA_FLAG_MANAGED
;
214 if (zif
->rtadv
.AdvOtherConfigFlag
)
215 rtadv
->nd_ra_flags_reserved
|= ND_RA_FLAG_OTHER
;
216 if (zif
->rtadv
.AdvHomeAgentFlag
)
217 rtadv
->nd_ra_flags_reserved
|= ND_RA_FLAG_HOME_AGENT
;
218 rtadv
->nd_ra_router_lifetime
= htons (zif
->rtadv
.AdvDefaultLifetime
);
219 rtadv
->nd_ra_reachable
= htonl (zif
->rtadv
.AdvReachableTime
);
220 rtadv
->nd_ra_retransmit
= htonl (0);
222 len
= sizeof (struct nd_router_advert
);
224 if (zif
->rtadv
.AdvHomeAgentFlag
)
226 struct nd_opt_homeagent_info
*ndopt_hai
=
227 (struct nd_opt_homeagent_info
*)(buf
+ len
);
228 ndopt_hai
->nd_opt_hai_type
= ND_OPT_HA_INFORMATION
;
229 ndopt_hai
->nd_opt_hai_len
= 1;
230 ndopt_hai
->nd_opt_hai_reserved
= 0;
231 ndopt_hai
->nd_opt_hai_preference
= htons(zif
->rtadv
.HomeAgentPreference
);
232 ndopt_hai
->nd_opt_hai_lifetime
= htons(zif
->rtadv
.HomeAgentLifetime
);
233 len
+= sizeof(struct nd_opt_homeagent_info
);
236 if (zif
->rtadv
.AdvIntervalOption
)
238 struct nd_opt_adv_interval
*ndopt_adv
=
239 (struct nd_opt_adv_interval
*)(buf
+ len
);
240 ndopt_adv
->nd_opt_ai_type
= ND_OPT_ADV_INTERVAL
;
241 ndopt_adv
->nd_opt_ai_len
= 1;
242 ndopt_adv
->nd_opt_ai_reserved
= 0;
243 ndopt_adv
->nd_opt_ai_interval
= htonl(zif
->rtadv
.MaxRtrAdvInterval
);
244 len
+= sizeof(struct nd_opt_adv_interval
);
247 /* Fill in prefix. */
248 for (ALL_LIST_ELEMENTS_RO (zif
->rtadv
.AdvPrefixList
, node
, rprefix
))
250 struct nd_opt_prefix_info
*pinfo
;
252 pinfo
= (struct nd_opt_prefix_info
*) (buf
+ len
);
254 pinfo
->nd_opt_pi_type
= ND_OPT_PREFIX_INFORMATION
;
255 pinfo
->nd_opt_pi_len
= 4;
256 pinfo
->nd_opt_pi_prefix_len
= rprefix
->prefix
.prefixlen
;
258 pinfo
->nd_opt_pi_flags_reserved
= 0;
259 if (rprefix
->AdvOnLinkFlag
)
260 pinfo
->nd_opt_pi_flags_reserved
|= ND_OPT_PI_FLAG_ONLINK
;
261 if (rprefix
->AdvAutonomousFlag
)
262 pinfo
->nd_opt_pi_flags_reserved
|= ND_OPT_PI_FLAG_AUTO
;
263 if (rprefix
->AdvRouterAddressFlag
)
264 pinfo
->nd_opt_pi_flags_reserved
|= ND_OPT_PI_FLAG_RADDR
;
266 pinfo
->nd_opt_pi_valid_time
= htonl (rprefix
->AdvValidLifetime
);
267 pinfo
->nd_opt_pi_preferred_time
= htonl (rprefix
->AdvPreferredLifetime
);
268 pinfo
->nd_opt_pi_reserved2
= 0;
270 memcpy (&pinfo
->nd_opt_pi_prefix
, &rprefix
->prefix
.u
.prefix6
,
271 sizeof (struct in6_addr
));
275 u_char buf
[INET6_ADDRSTRLEN
];
277 zlog_debug ("DEBUG %s", inet_ntop (AF_INET6
, &pinfo
->nd_opt_pi_prefix
,
278 buf
, INET6_ADDRSTRLEN
));
283 len
+= sizeof (struct nd_opt_prefix_info
);
286 /* Hardware address. */
287 #ifdef HAVE_STRUCT_SOCKADDR_DL
289 if (sdl
!= NULL
&& sdl
->sdl_alen
!= 0)
291 buf
[len
++] = ND_OPT_SOURCE_LINKADDR
;
293 /* Option length should be rounded up to next octet if
294 the link address does not end on an octet boundary. */
295 buf
[len
++] = (sdl
->sdl_alen
+ 9) >> 3;
297 memcpy (buf
+ len
, LLADDR (sdl
), sdl
->sdl_alen
);
298 len
+= sdl
->sdl_alen
;
300 /* Pad option to end on an octet boundary. */
301 memset (buf
+ len
, 0, -(sdl
->sdl_alen
+ 2) & 0x7);
302 len
+= -(sdl
->sdl_alen
+ 2) & 0x7;
305 if (ifp
->hw_addr_len
!= 0)
307 buf
[len
++] = ND_OPT_SOURCE_LINKADDR
;
309 /* Option length should be rounded up to next octet if
310 the link address does not end on an octet boundary. */
311 buf
[len
++] = (ifp
->hw_addr_len
+ 9) >> 3;
313 memcpy (buf
+ len
, ifp
->hw_addr
, ifp
->hw_addr_len
);
314 len
+= ifp
->hw_addr_len
;
316 /* Pad option to end on an octet boundary. */
317 memset (buf
+ len
, 0, -(ifp
->hw_addr_len
+ 2) & 0x7);
318 len
+= -(ifp
->hw_addr_len
+ 2) & 0x7;
320 #endif /* HAVE_STRUCT_SOCKADDR_DL */
322 msg
.msg_name
= (void *) &addr
;
323 msg
.msg_namelen
= sizeof (struct sockaddr_in6
);
326 msg
.msg_control
= (void *) adata
;
327 msg
.msg_controllen
= CMSG_SPACE(sizeof(struct in6_pktinfo
));
332 cmsgptr
= ZCMSG_FIRSTHDR(&msg
);
333 cmsgptr
->cmsg_len
= CMSG_LEN(sizeof(struct in6_pktinfo
));
334 cmsgptr
->cmsg_level
= IPPROTO_IPV6
;
335 cmsgptr
->cmsg_type
= IPV6_PKTINFO
;
337 pkt
= (struct in6_pktinfo
*) CMSG_DATA (cmsgptr
);
338 memset (&pkt
->ipi6_addr
, 0, sizeof (struct in6_addr
));
339 pkt
->ipi6_ifindex
= ifp
->ifindex
;
341 ret
= sendmsg (sock
, &msg
, 0);
344 zlog_err ("rtadv_send_packet: sendmsg %d (%s)\n",
345 errno
, safe_strerror(errno
));
350 rtadv_timer (struct thread
*thread
)
352 struct listnode
*node
, *nnode
;
353 struct interface
*ifp
;
354 struct zebra_if
*zif
;
357 rtadv
->ra_timer
= NULL
;
358 if (rtadv
->adv_msec_if_count
== 0)
360 period
= 1000; /* 1 s */
361 rtadv_event (RTADV_TIMER
, 1 /* 1 s */);
365 period
= 10; /* 10 ms */
366 rtadv_event (RTADV_TIMER_MSEC
, 10 /* 10 ms */);
369 for (ALL_LIST_ELEMENTS (iflist
, node
, nnode
, ifp
))
371 if (if_is_loopback (ifp
))
376 if (zif
->rtadv
.AdvSendAdvertisements
)
378 zif
->rtadv
.AdvIntervalTimer
-= period
;
379 if (zif
->rtadv
.AdvIntervalTimer
<= 0)
381 zif
->rtadv
.AdvIntervalTimer
= zif
->rtadv
.MaxRtrAdvInterval
;
382 rtadv_send_packet (rtadv
->sock
, ifp
);
390 rtadv_process_solicit (struct interface
*ifp
)
392 zlog_info ("Router solicitation received on %s", ifp
->name
);
394 rtadv_send_packet (rtadv
->sock
, ifp
);
398 rtadv_process_advert (void)
400 zlog_info ("Router advertisement received");
404 rtadv_process_packet (u_char
*buf
, unsigned int len
, unsigned int ifindex
, int hoplimit
)
406 struct icmp6_hdr
*icmph
;
407 struct interface
*ifp
;
408 struct zebra_if
*zif
;
410 /* Interface search. */
411 ifp
= if_lookup_by_index (ifindex
);
414 zlog_warn ("Unknown interface index: %d", ifindex
);
418 if (if_is_loopback (ifp
))
421 /* Check interface configuration. */
423 if (! zif
->rtadv
.AdvSendAdvertisements
)
426 /* ICMP message length check. */
427 if (len
< sizeof (struct icmp6_hdr
))
429 zlog_warn ("Invalid ICMPV6 packet length: %d", len
);
433 icmph
= (struct icmp6_hdr
*) buf
;
435 /* ICMP message type check. */
436 if (icmph
->icmp6_type
!= ND_ROUTER_SOLICIT
&&
437 icmph
->icmp6_type
!= ND_ROUTER_ADVERT
)
439 zlog_warn ("Unwanted ICMPV6 message type: %d", icmph
->icmp6_type
);
443 /* Hoplimit check. */
444 if (hoplimit
>= 0 && hoplimit
!= 255)
446 zlog_warn ("Invalid hoplimit %d for router advertisement ICMP packet",
451 /* Check ICMP message type. */
452 if (icmph
->icmp6_type
== ND_ROUTER_SOLICIT
)
453 rtadv_process_solicit (ifp
);
454 else if (icmph
->icmp6_type
== ND_ROUTER_ADVERT
)
455 rtadv_process_advert ();
461 rtadv_read (struct thread
*thread
)
465 u_char buf
[RTADV_MSG_SIZE
];
466 struct sockaddr_in6 from
;
467 unsigned int ifindex
= 0;
470 sock
= THREAD_FD (thread
);
471 rtadv
->ra_read
= NULL
;
473 /* Register myself. */
474 rtadv_event (RTADV_READ
, sock
);
476 len
= rtadv_recv_packet (sock
, buf
, BUFSIZ
, &from
, &ifindex
, &hoplimit
);
480 zlog_warn ("router solicitation recv failed: %s.", safe_strerror (errno
));
484 rtadv_process_packet (buf
, (unsigned)len
, ifindex
, hoplimit
);
490 rtadv_make_socket (void)
494 struct icmp6_filter filter
;
496 if ( zserv_privs
.change (ZPRIVS_RAISE
) )
497 zlog_err ("rtadv_make_socket: could not raise privs, %s",
498 safe_strerror (errno
) );
500 sock
= socket (AF_INET6
, SOCK_RAW
, IPPROTO_ICMPV6
);
502 if ( zserv_privs
.change (ZPRIVS_LOWER
) )
503 zlog_err ("rtadv_make_socket: could not lower privs, %s",
504 safe_strerror (errno
) );
506 /* When we can't make ICMPV6 socket simply back. Router
507 advertisement feature will not be supported. */
511 ret
= setsockopt_ipv6_pktinfo (sock
, 1);
514 ret
= setsockopt_ipv6_multicast_loop (sock
, 0);
517 ret
= setsockopt_ipv6_unicast_hops (sock
, 255);
520 ret
= setsockopt_ipv6_multicast_hops (sock
, 255);
523 ret
= setsockopt_ipv6_hoplimit (sock
, 1);
527 ICMP6_FILTER_SETBLOCKALL(&filter
);
528 ICMP6_FILTER_SETPASS (ND_ROUTER_SOLICIT
, &filter
);
529 ICMP6_FILTER_SETPASS (ND_ROUTER_ADVERT
, &filter
);
531 ret
= setsockopt (sock
, IPPROTO_ICMPV6
, ICMP6_FILTER
, &filter
,
532 sizeof (struct icmp6_filter
));
535 zlog_info ("ICMP6_FILTER set fail: %s", safe_strerror (errno
));
542 static struct rtadv_prefix
*
543 rtadv_prefix_new (void)
545 return XCALLOC (MTYPE_RTADV_PREFIX
, sizeof (struct rtadv_prefix
));
549 rtadv_prefix_free (struct rtadv_prefix
*rtadv_prefix
)
551 XFREE (MTYPE_RTADV_PREFIX
, rtadv_prefix
);
554 static struct rtadv_prefix
*
555 rtadv_prefix_lookup (struct list
*rplist
, struct prefix
*p
)
557 struct listnode
*node
;
558 struct rtadv_prefix
*rprefix
;
560 for (ALL_LIST_ELEMENTS_RO (rplist
, node
, rprefix
))
561 if (prefix_same (&rprefix
->prefix
, p
))
566 static struct rtadv_prefix
*
567 rtadv_prefix_get (struct list
*rplist
, struct prefix
*p
)
569 struct rtadv_prefix
*rprefix
;
571 rprefix
= rtadv_prefix_lookup (rplist
, p
);
575 rprefix
= rtadv_prefix_new ();
576 memcpy (&rprefix
->prefix
, p
, sizeof (struct prefix
));
577 listnode_add (rplist
, rprefix
);
583 rtadv_prefix_set (struct zebra_if
*zif
, struct rtadv_prefix
*rp
)
585 struct rtadv_prefix
*rprefix
;
587 rprefix
= rtadv_prefix_get (zif
->rtadv
.AdvPrefixList
, &rp
->prefix
);
589 /* Set parameters. */
590 rprefix
->AdvValidLifetime
= rp
->AdvValidLifetime
;
591 rprefix
->AdvPreferredLifetime
= rp
->AdvPreferredLifetime
;
592 rprefix
->AdvOnLinkFlag
= rp
->AdvOnLinkFlag
;
593 rprefix
->AdvAutonomousFlag
= rp
->AdvAutonomousFlag
;
594 rprefix
->AdvRouterAddressFlag
= rp
->AdvRouterAddressFlag
;
598 rtadv_prefix_reset (struct zebra_if
*zif
, struct rtadv_prefix
*rp
)
600 struct rtadv_prefix
*rprefix
;
602 rprefix
= rtadv_prefix_lookup (zif
->rtadv
.AdvPrefixList
, &rp
->prefix
);
605 listnode_delete (zif
->rtadv
.AdvPrefixList
, (void *) rprefix
);
606 rtadv_prefix_free (rprefix
);
613 DEFUN (ipv6_nd_suppress_ra
,
614 ipv6_nd_suppress_ra_cmd
,
615 "ipv6 nd suppress-ra",
616 "Interface IPv6 config commands\n"
617 "Neighbor discovery\n"
618 "Suppress Router Advertisement\n")
620 struct interface
*ifp
;
621 struct zebra_if
*zif
;
626 if (if_is_loopback (ifp
))
628 vty_out (vty
, "Invalid interface%s", VTY_NEWLINE
);
632 if (zif
->rtadv
.AdvSendAdvertisements
)
634 zif
->rtadv
.AdvSendAdvertisements
= 0;
635 zif
->rtadv
.AdvIntervalTimer
= 0;
636 rtadv
->adv_if_count
--;
638 if_leave_all_router (rtadv
->sock
, ifp
);
640 if (rtadv
->adv_if_count
== 0)
641 rtadv_event (RTADV_STOP
, 0);
647 DEFUN (no_ipv6_nd_suppress_ra
,
648 no_ipv6_nd_suppress_ra_cmd
,
649 "no ipv6 nd suppress-ra",
651 "Interface IPv6 config commands\n"
652 "Neighbor discovery\n"
653 "Suppress Router Advertisement\n")
655 struct interface
*ifp
;
656 struct zebra_if
*zif
;
661 if (if_is_loopback (ifp
))
663 vty_out (vty
, "Invalid interface%s", VTY_NEWLINE
);
667 if (! zif
->rtadv
.AdvSendAdvertisements
)
669 zif
->rtadv
.AdvSendAdvertisements
= 1;
670 zif
->rtadv
.AdvIntervalTimer
= 0;
671 rtadv
->adv_if_count
++;
673 if_join_all_router (rtadv
->sock
, ifp
);
675 if (rtadv
->adv_if_count
== 1)
676 rtadv_event (RTADV_START
, rtadv
->sock
);
682 DEFUN (ipv6_nd_ra_interval_msec
,
683 ipv6_nd_ra_interval_msec_cmd
,
684 "ipv6 nd ra-interval msec MILLISECONDS",
685 "Interface IPv6 config commands\n"
686 "Neighbor discovery\n"
687 "Router Advertisement interval\n"
688 "Router Advertisement interval in milliseconds\n")
691 struct interface
*ifp
;
692 struct zebra_if
*zif
;
694 ifp
= (struct interface
*) vty
->index
;
697 interval
= atoi (argv
[0]);
701 vty_out (vty
, "Invalid Router Advertisement Interval%s", VTY_NEWLINE
);
705 if (zif
->rtadv
.MaxRtrAdvInterval
% 1000)
706 rtadv
->adv_msec_if_count
--;
709 rtadv
->adv_msec_if_count
++;
711 zif
->rtadv
.MaxRtrAdvInterval
= interval
;
712 zif
->rtadv
.MinRtrAdvInterval
= 0.33 * interval
;
713 zif
->rtadv
.AdvIntervalTimer
= 0;
718 DEFUN (ipv6_nd_ra_interval
,
719 ipv6_nd_ra_interval_cmd
,
720 "ipv6 nd ra-interval SECONDS",
721 "Interface IPv6 config commands\n"
722 "Neighbor discovery\n"
723 "Router Advertisement interval\n"
724 "Router Advertisement interval in seconds\n")
727 struct interface
*ifp
;
728 struct zebra_if
*zif
;
730 ifp
= (struct interface
*) vty
->index
;
733 interval
= atoi (argv
[0]);
737 vty_out (vty
, "Invalid Router Advertisement Interval%s", VTY_NEWLINE
);
741 if (zif
->rtadv
.MaxRtrAdvInterval
% 1000)
742 rtadv
->adv_msec_if_count
--;
744 /* convert to milliseconds */
745 interval
= interval
* 1000;
747 zif
->rtadv
.MaxRtrAdvInterval
= interval
;
748 zif
->rtadv
.MinRtrAdvInterval
= 0.33 * interval
;
749 zif
->rtadv
.AdvIntervalTimer
= 0;
754 DEFUN (no_ipv6_nd_ra_interval
,
755 no_ipv6_nd_ra_interval_cmd
,
756 "no ipv6 nd ra-interval",
758 "Interface IPv6 config commands\n"
759 "Neighbor discovery\n"
760 "Router Advertisement interval\n")
762 struct interface
*ifp
;
763 struct zebra_if
*zif
;
765 ifp
= (struct interface
*) vty
->index
;
768 if (zif
->rtadv
.MaxRtrAdvInterval
% 1000)
769 rtadv
->adv_msec_if_count
--;
771 zif
->rtadv
.MaxRtrAdvInterval
= RTADV_MAX_RTR_ADV_INTERVAL
;
772 zif
->rtadv
.MinRtrAdvInterval
= RTADV_MIN_RTR_ADV_INTERVAL
;
773 zif
->rtadv
.AdvIntervalTimer
= zif
->rtadv
.MaxRtrAdvInterval
;
778 DEFUN (ipv6_nd_ra_lifetime
,
779 ipv6_nd_ra_lifetime_cmd
,
780 "ipv6 nd ra-lifetime SECONDS",
781 "Interface IPv6 config commands\n"
782 "Neighbor discovery\n"
784 "Router lifetime in seconds\n")
787 struct interface
*ifp
;
788 struct zebra_if
*zif
;
790 ifp
= (struct interface
*) vty
->index
;
793 lifetime
= atoi (argv
[0]);
795 if (lifetime
< 0 || lifetime
> 0xffff)
797 vty_out (vty
, "Invalid Router Lifetime%s", VTY_NEWLINE
);
801 zif
->rtadv
.AdvDefaultLifetime
= lifetime
;
806 DEFUN (no_ipv6_nd_ra_lifetime
,
807 no_ipv6_nd_ra_lifetime_cmd
,
808 "no ipv6 nd ra-lifetime",
810 "Interface IPv6 config commands\n"
811 "Neighbor discovery\n"
814 struct interface
*ifp
;
815 struct zebra_if
*zif
;
817 ifp
= (struct interface
*) vty
->index
;
820 zif
->rtadv
.AdvDefaultLifetime
= RTADV_ADV_DEFAULT_LIFETIME
;
825 DEFUN (ipv6_nd_reachable_time
,
826 ipv6_nd_reachable_time_cmd
,
827 "ipv6 nd reachable-time MILLISECONDS",
828 "Interface IPv6 config commands\n"
829 "Neighbor discovery\n"
831 "Reachable time in milliseconds\n")
834 struct interface
*ifp
;
835 struct zebra_if
*zif
;
837 ifp
= (struct interface
*) vty
->index
;
840 rtime
= (u_int32_t
) atol (argv
[0]);
842 if (rtime
> RTADV_MAX_REACHABLE_TIME
)
844 vty_out (vty
, "Invalid Reachable time%s", VTY_NEWLINE
);
848 zif
->rtadv
.AdvReachableTime
= rtime
;
853 DEFUN (no_ipv6_nd_reachable_time
,
854 no_ipv6_nd_reachable_time_cmd
,
855 "no ipv6 nd reachable-time",
857 "Interface IPv6 config commands\n"
858 "Neighbor discovery\n"
861 struct interface
*ifp
;
862 struct zebra_if
*zif
;
864 ifp
= (struct interface
*) vty
->index
;
867 zif
->rtadv
.AdvReachableTime
= 0;
872 DEFUN (ipv6_nd_homeagent_preference
,
873 ipv6_nd_homeagent_preference_cmd
,
874 "ipv6 nd home-agent-preference PREFERENCE",
875 "Interface IPv6 config commands\n"
876 "Neighbor discovery\n"
877 "Home Agent preference\n"
878 "Home Agent preference value 0..65535\n")
881 struct interface
*ifp
;
882 struct zebra_if
*zif
;
884 ifp
= (struct interface
*) vty
->index
;
887 hapref
= (u_int32_t
) atol (argv
[0]);
891 vty_out (vty
, "Invalid Home Agent preference%s", VTY_NEWLINE
);
895 zif
->rtadv
.HomeAgentPreference
= hapref
;
900 DEFUN (no_ipv6_nd_homeagent_preference
,
901 no_ipv6_nd_homeagent_preference_cmd
,
902 "no ipv6 nd home-agent-preference",
904 "Interface IPv6 config commands\n"
905 "Neighbor discovery\n"
906 "Home Agent preference\n")
908 struct interface
*ifp
;
909 struct zebra_if
*zif
;
911 ifp
= (struct interface
*) vty
->index
;
914 zif
->rtadv
.HomeAgentPreference
= 0;
919 DEFUN (ipv6_nd_homeagent_lifetime
,
920 ipv6_nd_homeagent_lifetime_cmd
,
921 "ipv6 nd home-agent-lifetime SECONDS",
922 "Interface IPv6 config commands\n"
923 "Neighbor discovery\n"
924 "Home Agent lifetime\n"
925 "Home Agent lifetime in seconds\n")
928 struct interface
*ifp
;
929 struct zebra_if
*zif
;
931 ifp
= (struct interface
*) vty
->index
;
934 ha_ltime
= (u_int32_t
) atol (argv
[0]);
936 if (ha_ltime
> RTADV_MAX_HALIFETIME
)
938 vty_out (vty
, "Invalid Home Agent Lifetime time%s", VTY_NEWLINE
);
942 zif
->rtadv
.HomeAgentLifetime
= ha_ltime
;
947 DEFUN (no_ipv6_nd_homeagent_lifetime
,
948 no_ipv6_nd_homeagent_lifetime_cmd
,
949 "no ipv6 nd home-agent-lifetime",
951 "Interface IPv6 config commands\n"
952 "Neighbor discovery\n"
953 "Home Agent lifetime\n")
955 struct interface
*ifp
;
956 struct zebra_if
*zif
;
958 ifp
= (struct interface
*) vty
->index
;
961 zif
->rtadv
.HomeAgentLifetime
= 0;
966 DEFUN (ipv6_nd_managed_config_flag
,
967 ipv6_nd_managed_config_flag_cmd
,
968 "ipv6 nd managed-config-flag",
969 "Interface IPv6 config commands\n"
970 "Neighbor discovery\n"
971 "Managed address configuration flag\n")
973 struct interface
*ifp
;
974 struct zebra_if
*zif
;
976 ifp
= (struct interface
*) vty
->index
;
979 zif
->rtadv
.AdvManagedFlag
= 1;
984 DEFUN (no_ipv6_nd_managed_config_flag
,
985 no_ipv6_nd_managed_config_flag_cmd
,
986 "no ipv6 nd managed-config-flag",
988 "Interface IPv6 config commands\n"
989 "Neighbor discovery\n"
990 "Managed address configuration flag\n")
992 struct interface
*ifp
;
993 struct zebra_if
*zif
;
995 ifp
= (struct interface
*) vty
->index
;
998 zif
->rtadv
.AdvManagedFlag
= 0;
1003 DEFUN (ipv6_nd_homeagent_config_flag
,
1004 ipv6_nd_homeagent_config_flag_cmd
,
1005 "ipv6 nd home-agent-config-flag",
1006 "Interface IPv6 config commands\n"
1007 "Neighbor discovery\n"
1008 "Home Agent configuration flag\n")
1010 struct interface
*ifp
;
1011 struct zebra_if
*zif
;
1013 ifp
= (struct interface
*) vty
->index
;
1016 zif
->rtadv
.AdvHomeAgentFlag
= 1;
1021 DEFUN (no_ipv6_nd_homeagent_config_flag
,
1022 no_ipv6_nd_homeagent_config_flag_cmd
,
1023 "no ipv6 nd home-agent-config-flag",
1025 "Interface IPv6 config commands\n"
1026 "Neighbor discovery\n"
1027 "Home Agent configuration flag\n")
1029 struct interface
*ifp
;
1030 struct zebra_if
*zif
;
1032 ifp
= (struct interface
*) vty
->index
;
1035 zif
->rtadv
.AdvHomeAgentFlag
= 0;
1040 DEFUN (ipv6_nd_adv_interval_config_option
,
1041 ipv6_nd_adv_interval_config_option_cmd
,
1042 "ipv6 nd adv-interval-option",
1043 "Interface IPv6 config commands\n"
1044 "Neighbor discovery\n"
1045 "Advertisement Interval Option\n")
1047 struct interface
*ifp
;
1048 struct zebra_if
*zif
;
1050 ifp
= (struct interface
*) vty
->index
;
1053 zif
->rtadv
.AdvIntervalOption
= 1;
1058 DEFUN (no_ipv6_nd_adv_interval_config_option
,
1059 no_ipv6_nd_adv_interval_config_option_cmd
,
1060 "no ipv6 nd adv-interval-option",
1062 "Interface IPv6 config commands\n"
1063 "Neighbor discovery\n"
1064 "Advertisement Interval Option\n")
1066 struct interface
*ifp
;
1067 struct zebra_if
*zif
;
1069 ifp
= (struct interface
*) vty
->index
;
1072 zif
->rtadv
.AdvIntervalOption
= 0;
1077 DEFUN (ipv6_nd_other_config_flag
,
1078 ipv6_nd_other_config_flag_cmd
,
1079 "ipv6 nd other-config-flag",
1080 "Interface IPv6 config commands\n"
1081 "Neighbor discovery\n"
1082 "Other statefull configuration flag\n")
1084 struct interface
*ifp
;
1085 struct zebra_if
*zif
;
1087 ifp
= (struct interface
*) vty
->index
;
1090 zif
->rtadv
.AdvOtherConfigFlag
= 1;
1095 DEFUN (no_ipv6_nd_other_config_flag
,
1096 no_ipv6_nd_other_config_flag_cmd
,
1097 "no ipv6 nd other-config-flag",
1099 "Interface IPv6 config commands\n"
1100 "Neighbor discovery\n"
1101 "Other statefull configuration flag\n")
1103 struct interface
*ifp
;
1104 struct zebra_if
*zif
;
1106 ifp
= (struct interface
*) vty
->index
;
1109 zif
->rtadv
.AdvOtherConfigFlag
= 0;
1114 DEFUN (ipv6_nd_prefix
,
1116 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1117 "(<0-4294967295>|infinite) (off-link|) (no-autoconfig|) (router-address|)",
1118 "Interface IPv6 config commands\n"
1119 "Neighbor discovery\n"
1120 "Prefix information\n"
1122 "Valid lifetime in seconds\n"
1123 "Infinite valid lifetime\n"
1124 "Preferred lifetime in seconds\n"
1125 "Infinite preferred lifetime\n"
1126 "Do not use prefix for onlink determination\n"
1127 "Do not use prefix for autoconfiguration\n"
1128 "Set Router Address flag\n")
1133 struct interface
*ifp
;
1134 struct zebra_if
*zebra_if
;
1135 struct rtadv_prefix rp
;
1137 ifp
= (struct interface
*) vty
->index
;
1138 zebra_if
= ifp
->info
;
1140 ret
= str2prefix_ipv6 (argv
[0], (struct prefix_ipv6
*) &rp
.prefix
);
1143 vty_out (vty
, "Malformed IPv6 prefix%s", VTY_NEWLINE
);
1146 rp
.AdvOnLinkFlag
= 1;
1147 rp
.AdvAutonomousFlag
= 1;
1148 rp
.AdvRouterAddressFlag
= 0;
1149 rp
.AdvValidLifetime
= RTADV_VALID_LIFETIME
;
1150 rp
.AdvPreferredLifetime
= RTADV_PREFERRED_LIFETIME
;
1154 if ((isdigit(argv
[1][0])) || strncmp (argv
[1], "i", 1) == 0)
1156 if ( strncmp (argv
[1], "i", 1) == 0)
1157 rp
.AdvValidLifetime
= UINT32_MAX
;
1159 rp
.AdvValidLifetime
= (u_int32_t
) strtoll (argv
[1],
1162 if ( strncmp (argv
[2], "i", 1) == 0)
1163 rp
.AdvPreferredLifetime
= UINT32_MAX
;
1165 rp
.AdvPreferredLifetime
= (u_int32_t
) strtoll (argv
[2],
1168 if (rp
.AdvPreferredLifetime
> rp
.AdvValidLifetime
)
1170 vty_out (vty
, "Invalid preferred lifetime%s", VTY_NEWLINE
);
1173 cursor
= cursor
+ 2;
1177 for (i
= cursor
; i
< argc
; i
++)
1179 if (strncmp (argv
[i
], "of", 2) == 0)
1180 rp
.AdvOnLinkFlag
= 0;
1181 if (strncmp (argv
[i
], "no", 2) == 0)
1182 rp
.AdvAutonomousFlag
= 0;
1183 if (strncmp (argv
[i
], "ro", 2) == 0)
1184 rp
.AdvRouterAddressFlag
= 1;
1189 rtadv_prefix_set (zebra_if
, &rp
);
1194 ALIAS (ipv6_nd_prefix
,
1195 ipv6_nd_prefix_val_nortaddr_cmd
,
1196 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1197 "(<0-4294967295>|infinite) (off-link|) (no-autoconfig|)",
1198 "Interface IPv6 config commands\n"
1199 "Neighbor discovery\n"
1200 "Prefix information\n"
1202 "Valid lifetime in seconds\n"
1203 "Infinite valid lifetime\n"
1204 "Preferred lifetime in seconds\n"
1205 "Infinite preferred lifetime\n"
1206 "Do not use prefix for onlink determination\n"
1207 "Do not use prefix for autoconfiguration\n")
1209 ALIAS (ipv6_nd_prefix
,
1210 ipv6_nd_prefix_val_rev_cmd
,
1211 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1212 "(<0-4294967295>|infinite) (no-autoconfig|) (off-link|)",
1213 "Interface IPv6 config commands\n"
1214 "Neighbor discovery\n"
1215 "Prefix information\n"
1217 "Valid lifetime in seconds\n"
1218 "Infinite valid lifetime\n"
1219 "Preferred lifetime in seconds\n"
1220 "Infinite preferred lifetime\n"
1221 "Do not use prefix for autoconfiguration\n"
1222 "Do not use prefix for onlink determination\n")
1224 ALIAS (ipv6_nd_prefix
,
1225 ipv6_nd_prefix_val_rev_rtaddr_cmd
,
1226 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1227 "(<0-4294967295>|infinite) (no-autoconfig|) (off-link|) (router-address|)",
1228 "Interface IPv6 config commands\n"
1229 "Neighbor discovery\n"
1230 "Prefix information\n"
1232 "Valid lifetime in seconds\n"
1233 "Infinite valid lifetime\n"
1234 "Preferred lifetime in seconds\n"
1235 "Infinite preferred lifetime\n"
1236 "Do not use prefix for autoconfiguration\n"
1237 "Do not use prefix for onlink determination\n"
1238 "Set Router Address flag\n")
1240 ALIAS (ipv6_nd_prefix
,
1241 ipv6_nd_prefix_val_noauto_cmd
,
1242 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1243 "(<0-4294967295>|infinite) (no-autoconfig|)",
1244 "Interface IPv6 config commands\n"
1245 "Neighbor discovery\n"
1246 "Prefix information\n"
1248 "Valid lifetime in seconds\n"
1249 "Infinite valid lifetime\n"
1250 "Preferred lifetime in seconds\n"
1251 "Infinite preferred lifetime\n"
1252 "Do not use prefix for autoconfiguration")
1254 ALIAS (ipv6_nd_prefix
,
1255 ipv6_nd_prefix_val_offlink_cmd
,
1256 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1257 "(<0-4294967295>|infinite) (off-link|)",
1258 "Interface IPv6 config commands\n"
1259 "Neighbor discovery\n"
1260 "Prefix information\n"
1262 "Valid lifetime in seconds\n"
1263 "Infinite valid lifetime\n"
1264 "Preferred lifetime in seconds\n"
1265 "Infinite preferred lifetime\n"
1266 "Do not use prefix for onlink determination\n")
1268 ALIAS (ipv6_nd_prefix
,
1269 ipv6_nd_prefix_val_rtaddr_cmd
,
1270 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1271 "(<0-4294967295>|infinite) (router-address|)",
1272 "Interface IPv6 config commands\n"
1273 "Neighbor discovery\n"
1274 "Prefix information\n"
1276 "Valid lifetime in seconds\n"
1277 "Infinite valid lifetime\n"
1278 "Preferred lifetime in seconds\n"
1279 "Infinite preferred lifetime\n"
1280 "Set Router Address flag\n")
1282 ALIAS (ipv6_nd_prefix
,
1283 ipv6_nd_prefix_val_cmd
,
1284 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1285 "(<0-4294967295>|infinite)",
1286 "Interface IPv6 config commands\n"
1287 "Neighbor discovery\n"
1288 "Prefix information\n"
1290 "Valid lifetime in seconds\n"
1291 "Infinite valid lifetime\n"
1292 "Preferred lifetime in seconds\n"
1293 "Infinite preferred lifetime\n")
1295 ALIAS (ipv6_nd_prefix
,
1296 ipv6_nd_prefix_noval_cmd
,
1297 "ipv6 nd prefix X:X::X:X/M (no-autoconfig|) (off-link|)",
1298 "Interface IPv6 config commands\n"
1299 "Neighbor discovery\n"
1300 "Prefix information\n"
1302 "Do not use prefix for autoconfiguration\n"
1303 "Do not use prefix for onlink determination\n")
1305 ALIAS (ipv6_nd_prefix
,
1306 ipv6_nd_prefix_noval_rev_cmd
,
1307 "ipv6 nd prefix X:X::X:X/M (off-link|) (no-autoconfig|)",
1308 "Interface IPv6 config commands\n"
1309 "Neighbor discovery\n"
1310 "Prefix information\n"
1312 "Do not use prefix for onlink determination\n"
1313 "Do not use prefix for autoconfiguration\n")
1315 ALIAS (ipv6_nd_prefix
,
1316 ipv6_nd_prefix_noval_noauto_cmd
,
1317 "ipv6 nd prefix X:X::X:X/M (no-autoconfig|)",
1318 "Interface IPv6 config commands\n"
1319 "Neighbor discovery\n"
1320 "Prefix information\n"
1322 "Do not use prefix for autoconfiguration\n")
1324 ALIAS (ipv6_nd_prefix
,
1325 ipv6_nd_prefix_noval_offlink_cmd
,
1326 "ipv6 nd prefix X:X::X:X/M (off-link|)",
1327 "Interface IPv6 config commands\n"
1328 "Neighbor discovery\n"
1329 "Prefix information\n"
1331 "Do not use prefix for onlink determination\n")
1333 ALIAS (ipv6_nd_prefix
,
1334 ipv6_nd_prefix_noval_rtaddr_cmd
,
1335 "ipv6 nd prefix X:X::X:X/M (router-address|)",
1336 "Interface IPv6 config commands\n"
1337 "Neighbor discovery\n"
1338 "Prefix information\n"
1340 "Set Router Address flag\n")
1342 ALIAS (ipv6_nd_prefix
,
1343 ipv6_nd_prefix_prefix_cmd
,
1344 "ipv6 nd prefix X:X::X:X/M",
1345 "Interface IPv6 config commands\n"
1346 "Neighbor discovery\n"
1347 "Prefix information\n"
1350 DEFUN (no_ipv6_nd_prefix
,
1351 no_ipv6_nd_prefix_cmd
,
1352 "no ipv6 nd prefix IPV6PREFIX",
1354 "Interface IPv6 config commands\n"
1355 "Neighbor discovery\n"
1356 "Prefix information\n"
1360 struct interface
*ifp
;
1361 struct zebra_if
*zebra_if
;
1362 struct rtadv_prefix rp
;
1364 ifp
= (struct interface
*) vty
->index
;
1365 zebra_if
= ifp
->info
;
1367 ret
= str2prefix_ipv6 (argv
[0], (struct prefix_ipv6
*) &rp
.prefix
);
1370 vty_out (vty
, "Malformed IPv6 prefix%s", VTY_NEWLINE
);
1374 ret
= rtadv_prefix_reset (zebra_if
, &rp
);
1377 vty_out (vty
, "Non-exist IPv6 prefix%s", VTY_NEWLINE
);
1384 DEFUN (ipv6_nd_router_preference
,
1385 ipv6_nd_router_preference_cmd
,
1386 "ipv6 nd router-preference (high|medium|low)",
1387 "Interface IPv6 config commands\n"
1388 "Neighbor discovery\n"
1389 "Default router preference\n"
1390 "High default router preference\n"
1391 "Low default router preference\n"
1392 "Medium default router preference (default)\n")
1394 struct interface
*ifp
;
1395 struct zebra_if
*zif
;
1398 ifp
= (struct interface
*) vty
->index
;
1401 while (0 != rtadv_pref_strs
[i
])
1403 if (strncmp (argv
[0], rtadv_pref_strs
[i
], 1) == 0)
1405 zif
->rtadv
.DefaultPreference
= i
;
1411 return CMD_ERR_NO_MATCH
;
1414 DEFUN (no_ipv6_nd_router_preference
,
1415 no_ipv6_nd_router_preference_cmd
,
1416 "no ipv6 nd router-preference",
1418 "Interface IPv6 config commands\n"
1419 "Neighbor discovery\n"
1420 "Default router preference\n")
1422 struct interface
*ifp
;
1423 struct zebra_if
*zif
;
1425 ifp
= (struct interface
*) vty
->index
;
1428 zif
->rtadv
.DefaultPreference
= RTADV_PREF_MEDIUM
; /* Default per RFC4191. */
1433 /* Write configuration about router advertisement. */
1435 rtadv_config_write (struct vty
*vty
, struct interface
*ifp
)
1437 struct zebra_if
*zif
;
1438 struct listnode
*node
;
1439 struct rtadv_prefix
*rprefix
;
1440 u_char buf
[INET6_ADDRSTRLEN
];
1448 if (! if_is_loopback (ifp
))
1450 if (zif
->rtadv
.AdvSendAdvertisements
)
1451 vty_out (vty
, " no ipv6 nd suppress-ra%s", VTY_NEWLINE
);
1453 vty_out (vty
, " ipv6 nd suppress-ra%s", VTY_NEWLINE
);
1457 interval
= zif
->rtadv
.MaxRtrAdvInterval
;
1458 if (interval
% 1000)
1459 vty_out (vty
, " ipv6 nd ra-interval msec %d%s", interval
,
1462 if (interval
!= RTADV_MAX_RTR_ADV_INTERVAL
)
1463 vty_out (vty
, " ipv6 nd ra-interval %d%s", interval
/ 1000,
1466 if (zif
->rtadv
.AdvDefaultLifetime
!= RTADV_ADV_DEFAULT_LIFETIME
)
1467 vty_out (vty
, " ipv6 nd ra-lifetime %d%s", zif
->rtadv
.AdvDefaultLifetime
,
1470 if (zif
->rtadv
.AdvReachableTime
)
1471 vty_out (vty
, " ipv6 nd reachable-time %d%s", zif
->rtadv
.AdvReachableTime
,
1474 if (zif
->rtadv
.AdvManagedFlag
)
1475 vty_out (vty
, " ipv6 nd managed-config-flag%s", VTY_NEWLINE
);
1477 if (zif
->rtadv
.AdvOtherConfigFlag
)
1478 vty_out (vty
, " ipv6 nd other-config-flag%s", VTY_NEWLINE
);
1480 if (zif
->rtadv
.DefaultPreference
!= RTADV_PREF_MEDIUM
)
1481 vty_out (vty
, " ipv6 nd router-preference %s%s",
1482 rtadv_pref_strs
[zif
->rtadv
.DefaultPreference
],
1485 for (ALL_LIST_ELEMENTS_RO (zif
->rtadv
.AdvPrefixList
, node
, rprefix
))
1487 vty_out (vty
, " ipv6 nd prefix %s/%d",
1488 inet_ntop (AF_INET6
, &rprefix
->prefix
.u
.prefix6
,
1489 (char *) buf
, INET6_ADDRSTRLEN
),
1490 rprefix
->prefix
.prefixlen
);
1491 if ((rprefix
->AdvValidLifetime
!= RTADV_VALID_LIFETIME
) ||
1492 (rprefix
->AdvPreferredLifetime
!= RTADV_PREFERRED_LIFETIME
))
1494 if (rprefix
->AdvValidLifetime
== UINT32_MAX
)
1495 vty_out (vty
, " infinite");
1497 vty_out (vty
, " %u", rprefix
->AdvValidLifetime
);
1498 if (rprefix
->AdvPreferredLifetime
== UINT32_MAX
)
1499 vty_out (vty
, " infinite");
1501 vty_out (vty
, " %u", rprefix
->AdvPreferredLifetime
);
1503 if (!rprefix
->AdvOnLinkFlag
)
1504 vty_out (vty
, " off-link");
1505 if (!rprefix
->AdvAutonomousFlag
)
1506 vty_out (vty
, " no-autoconfig");
1507 if (rprefix
->AdvRouterAddressFlag
)
1508 vty_out (vty
, " router-address");
1509 vty_out (vty
, "%s", VTY_NEWLINE
);
1515 rtadv_event (enum rtadv_event event
, int val
)
1520 if (! rtadv
->ra_read
)
1521 rtadv
->ra_read
= thread_add_read (zebrad
.master
, rtadv_read
, NULL
, val
);
1522 if (! rtadv
->ra_timer
)
1523 rtadv
->ra_timer
= thread_add_event (zebrad
.master
, rtadv_timer
,
1527 if (rtadv
->ra_timer
)
1529 thread_cancel (rtadv
->ra_timer
);
1530 rtadv
->ra_timer
= NULL
;
1534 thread_cancel (rtadv
->ra_read
);
1535 rtadv
->ra_read
= NULL
;
1539 if (! rtadv
->ra_timer
)
1540 rtadv
->ra_timer
= thread_add_timer (zebrad
.master
, rtadv_timer
, NULL
,
1543 case RTADV_TIMER_MSEC
:
1544 if (! rtadv
->ra_timer
)
1545 rtadv
->ra_timer
= thread_add_timer_msec (zebrad
.master
, rtadv_timer
,
1549 if (! rtadv
->ra_read
)
1550 rtadv
->ra_read
= thread_add_read (zebrad
.master
, rtadv_read
, NULL
, val
);
1563 sock
= rtadv_make_socket ();
1567 rtadv
= rtadv_new ();
1570 install_element (INTERFACE_NODE
, &ipv6_nd_suppress_ra_cmd
);
1571 install_element (INTERFACE_NODE
, &no_ipv6_nd_suppress_ra_cmd
);
1572 install_element (INTERFACE_NODE
, &ipv6_nd_ra_interval_cmd
);
1573 install_element (INTERFACE_NODE
, &ipv6_nd_ra_interval_msec_cmd
);
1574 install_element (INTERFACE_NODE
, &no_ipv6_nd_ra_interval_cmd
);
1575 install_element (INTERFACE_NODE
, &ipv6_nd_ra_lifetime_cmd
);
1576 install_element (INTERFACE_NODE
, &no_ipv6_nd_ra_lifetime_cmd
);
1577 install_element (INTERFACE_NODE
, &ipv6_nd_reachable_time_cmd
);
1578 install_element (INTERFACE_NODE
, &no_ipv6_nd_reachable_time_cmd
);
1579 install_element (INTERFACE_NODE
, &ipv6_nd_managed_config_flag_cmd
);
1580 install_element (INTERFACE_NODE
, &no_ipv6_nd_managed_config_flag_cmd
);
1581 install_element (INTERFACE_NODE
, &ipv6_nd_other_config_flag_cmd
);
1582 install_element (INTERFACE_NODE
, &no_ipv6_nd_other_config_flag_cmd
);
1583 install_element (INTERFACE_NODE
, &ipv6_nd_homeagent_config_flag_cmd
);
1584 install_element (INTERFACE_NODE
, &no_ipv6_nd_homeagent_config_flag_cmd
);
1585 install_element (INTERFACE_NODE
, &ipv6_nd_homeagent_preference_cmd
);
1586 install_element (INTERFACE_NODE
, &no_ipv6_nd_homeagent_preference_cmd
);
1587 install_element (INTERFACE_NODE
, &ipv6_nd_homeagent_lifetime_cmd
);
1588 install_element (INTERFACE_NODE
, &no_ipv6_nd_homeagent_lifetime_cmd
);
1589 install_element (INTERFACE_NODE
, &ipv6_nd_adv_interval_config_option_cmd
);
1590 install_element (INTERFACE_NODE
, &no_ipv6_nd_adv_interval_config_option_cmd
);
1591 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_cmd
);
1592 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_val_rev_rtaddr_cmd
);
1593 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_val_nortaddr_cmd
);
1594 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_val_rev_cmd
);
1595 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_val_noauto_cmd
);
1596 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_val_offlink_cmd
);
1597 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_val_rtaddr_cmd
);
1598 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_val_cmd
);
1599 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_noval_cmd
);
1600 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_noval_rev_cmd
);
1601 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_noval_noauto_cmd
);
1602 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_noval_offlink_cmd
);
1603 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_noval_rtaddr_cmd
);
1604 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_prefix_cmd
);
1605 install_element (INTERFACE_NODE
, &no_ipv6_nd_prefix_cmd
);
1606 install_element (INTERFACE_NODE
, &ipv6_nd_router_preference_cmd
);
1607 install_element (INTERFACE_NODE
, &no_ipv6_nd_router_preference_cmd
);
1611 if_join_all_router (int sock
, struct interface
*ifp
)
1615 struct ipv6_mreq mreq
;
1617 memset (&mreq
, 0, sizeof (struct ipv6_mreq
));
1618 inet_pton (AF_INET6
, ALLROUTER
, &mreq
.ipv6mr_multiaddr
);
1619 mreq
.ipv6mr_interface
= ifp
->ifindex
;
1621 ret
= setsockopt (sock
, IPPROTO_IPV6
, IPV6_JOIN_GROUP
,
1622 (char *) &mreq
, sizeof mreq
);
1624 zlog_warn ("can't setsockopt IPV6_JOIN_GROUP: %s", safe_strerror (errno
));
1626 zlog_info ("rtadv: %s join to all-routers multicast group", ifp
->name
);
1632 if_leave_all_router (int sock
, struct interface
*ifp
)
1636 struct ipv6_mreq mreq
;
1638 memset (&mreq
, 0, sizeof (struct ipv6_mreq
));
1639 inet_pton (AF_INET6
, ALLROUTER
, &mreq
.ipv6mr_multiaddr
);
1640 mreq
.ipv6mr_interface
= ifp
->ifindex
;
1642 ret
= setsockopt (sock
, IPPROTO_IPV6
, IPV6_LEAVE_GROUP
,
1643 (char *) &mreq
, sizeof mreq
);
1645 zlog_warn ("can't setsockopt IPV6_LEAVE_GROUP: %s", safe_strerror (errno
));
1647 zlog_info ("rtadv: %s leave from all-routers multicast group", ifp
->name
);
1658 #endif /* RTADV && HAVE_IPV6 */