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
;
88 new = XMALLOC (MTYPE_TMP
, sizeof (struct rtadv
));
89 memset (new, 0, sizeof (struct rtadv
));
94 rtadv_free (struct rtadv
*rtadv
)
96 XFREE (MTYPE_TMP
, rtadv
);
100 rtadv_recv_packet (int sock
, u_char
*buf
, int buflen
,
101 struct sockaddr_in6
*from
, unsigned int *ifindex
,
107 struct cmsghdr
*cmsgptr
;
112 /* Fill in message and iovec. */
113 msg
.msg_name
= (void *) from
;
114 msg
.msg_namelen
= sizeof (struct sockaddr_in6
);
117 msg
.msg_control
= (void *) adata
;
118 msg
.msg_controllen
= sizeof adata
;
120 iov
.iov_len
= buflen
;
122 /* If recvmsg fail return minus value. */
123 ret
= recvmsg (sock
, &msg
, 0);
127 for (cmsgptr
= ZCMSG_FIRSTHDR(&msg
); cmsgptr
!= NULL
;
128 cmsgptr
= CMSG_NXTHDR(&msg
, cmsgptr
))
130 /* I want interface index which this packet comes from. */
131 if (cmsgptr
->cmsg_level
== IPPROTO_IPV6
&&
132 cmsgptr
->cmsg_type
== IPV6_PKTINFO
)
134 struct in6_pktinfo
*ptr
;
136 ptr
= (struct in6_pktinfo
*) CMSG_DATA (cmsgptr
);
137 *ifindex
= ptr
->ipi6_ifindex
;
138 memcpy(&dst
, &ptr
->ipi6_addr
, sizeof(ptr
->ipi6_addr
));
141 /* Incoming packet's hop limit. */
142 if (cmsgptr
->cmsg_level
== IPPROTO_IPV6
&&
143 cmsgptr
->cmsg_type
== IPV6_HOPLIMIT
)
144 *hoplimit
= *((int *) CMSG_DATA (cmsgptr
));
149 #define RTADV_MSG_SIZE 4096
151 /* Send router advertisement packet. */
153 rtadv_send_packet (int sock
, struct interface
*ifp
)
157 struct cmsghdr
*cmsgptr
;
158 struct in6_pktinfo
*pkt
;
159 struct sockaddr_in6 addr
;
160 #ifdef HAVE_STRUCT_SOCKADDR_DL
161 struct sockaddr_dl
*sdl
;
162 #endif /* HAVE_STRUCT_SOCKADDR_DL */
163 static void *adata
= NULL
;
164 unsigned char buf
[RTADV_MSG_SIZE
];
165 struct nd_router_advert
*rtadv
;
168 struct zebra_if
*zif
;
169 struct rtadv_prefix
*rprefix
;
170 u_char all_nodes_addr
[] = {0xff,0x02,0,0,0,0,0,0,0,0,0,0,0,0,0,1};
171 struct listnode
*node
;
174 * Allocate control message bufffer. This is dynamic because
175 * CMSG_SPACE is not guaranteed not to call a function. Note that
176 * the size will be different on different architectures due to
177 * differing alignment rules.
181 /* XXX Free on shutdown. */
182 adata
= malloc(CMSG_SPACE(sizeof(struct in6_pktinfo
)));
185 zlog_err("rtadv_send_packet: can't malloc control data\n");
188 /* Logging of packet. */
189 if (IS_ZEBRA_DEBUG_PACKET
)
190 zlog_debug ("Router advertisement send to %s", ifp
->name
);
192 /* Fill in sockaddr_in6. */
193 memset (&addr
, 0, sizeof (struct sockaddr_in6
));
194 addr
.sin6_family
= AF_INET6
;
196 addr
.sin6_len
= sizeof (struct sockaddr_in6
);
197 #endif /* SIN6_LEN */
198 addr
.sin6_port
= htons (IPPROTO_ICMPV6
);
199 memcpy (&addr
.sin6_addr
, all_nodes_addr
, sizeof (struct in6_addr
));
201 /* Fetch interface information. */
204 /* Make router advertisement message. */
205 rtadv
= (struct nd_router_advert
*) buf
;
207 rtadv
->nd_ra_type
= ND_ROUTER_ADVERT
;
208 rtadv
->nd_ra_code
= 0;
209 rtadv
->nd_ra_cksum
= 0;
211 rtadv
->nd_ra_curhoplimit
= 64;
212 rtadv
->nd_ra_flags_reserved
= 0;
213 if (zif
->rtadv
.AdvManagedFlag
)
214 rtadv
->nd_ra_flags_reserved
|= ND_RA_FLAG_MANAGED
;
215 if (zif
->rtadv
.AdvOtherConfigFlag
)
216 rtadv
->nd_ra_flags_reserved
|= ND_RA_FLAG_OTHER
;
217 if (zif
->rtadv
.AdvHomeAgentFlag
)
218 rtadv
->nd_ra_flags_reserved
|= ND_RA_FLAG_HOME_AGENT
;
219 rtadv
->nd_ra_router_lifetime
= htons (zif
->rtadv
.AdvDefaultLifetime
);
220 rtadv
->nd_ra_reachable
= htonl (zif
->rtadv
.AdvReachableTime
);
221 rtadv
->nd_ra_retransmit
= htonl (0);
223 len
= sizeof (struct nd_router_advert
);
225 if (zif
->rtadv
.AdvHomeAgentFlag
)
227 struct nd_opt_homeagent_info
*ndopt_hai
=
228 (struct nd_opt_homeagent_info
*)(buf
+ len
);
229 ndopt_hai
->nd_opt_hai_type
= ND_OPT_HA_INFORMATION
;
230 ndopt_hai
->nd_opt_hai_len
= 1;
231 ndopt_hai
->nd_opt_hai_reserved
= 0;
232 ndopt_hai
->nd_opt_hai_preference
= htons(zif
->rtadv
.HomeAgentPreference
);
233 ndopt_hai
->nd_opt_hai_lifetime
= htons(zif
->rtadv
.HomeAgentLifetime
);
234 len
+= sizeof(struct nd_opt_homeagent_info
);
237 if (zif
->rtadv
.AdvIntervalOption
)
239 struct nd_opt_adv_interval
*ndopt_adv
=
240 (struct nd_opt_adv_interval
*)(buf
+ len
);
241 ndopt_adv
->nd_opt_ai_type
= ND_OPT_ADV_INTERVAL
;
242 ndopt_adv
->nd_opt_ai_len
= 1;
243 ndopt_adv
->nd_opt_ai_reserved
= 0;
244 ndopt_adv
->nd_opt_ai_interval
= htonl(zif
->rtadv
.MaxRtrAdvInterval
);
245 len
+= sizeof(struct nd_opt_adv_interval
);
248 /* Fill in prefix. */
249 for (ALL_LIST_ELEMENTS_RO (zif
->rtadv
.AdvPrefixList
, node
, rprefix
))
251 struct nd_opt_prefix_info
*pinfo
;
253 pinfo
= (struct nd_opt_prefix_info
*) (buf
+ len
);
255 pinfo
->nd_opt_pi_type
= ND_OPT_PREFIX_INFORMATION
;
256 pinfo
->nd_opt_pi_len
= 4;
257 pinfo
->nd_opt_pi_prefix_len
= rprefix
->prefix
.prefixlen
;
259 pinfo
->nd_opt_pi_flags_reserved
= 0;
260 if (rprefix
->AdvOnLinkFlag
)
261 pinfo
->nd_opt_pi_flags_reserved
|= ND_OPT_PI_FLAG_ONLINK
;
262 if (rprefix
->AdvAutonomousFlag
)
263 pinfo
->nd_opt_pi_flags_reserved
|= ND_OPT_PI_FLAG_AUTO
;
264 if (rprefix
->AdvRouterAddressFlag
)
265 pinfo
->nd_opt_pi_flags_reserved
|= ND_OPT_PI_FLAG_RADDR
;
267 pinfo
->nd_opt_pi_valid_time
= htonl (rprefix
->AdvValidLifetime
);
268 pinfo
->nd_opt_pi_preferred_time
= htonl (rprefix
->AdvPreferredLifetime
);
269 pinfo
->nd_opt_pi_reserved2
= 0;
271 memcpy (&pinfo
->nd_opt_pi_prefix
, &rprefix
->prefix
.u
.prefix6
,
272 sizeof (struct in6_addr
));
276 u_char buf
[INET6_ADDRSTRLEN
];
278 zlog_debug ("DEBUG %s", inet_ntop (AF_INET6
, &pinfo
->nd_opt_pi_prefix
,
279 buf
, INET6_ADDRSTRLEN
));
284 len
+= sizeof (struct nd_opt_prefix_info
);
287 /* Hardware address. */
288 #ifdef HAVE_STRUCT_SOCKADDR_DL
290 if (sdl
!= NULL
&& sdl
->sdl_alen
!= 0)
292 buf
[len
++] = ND_OPT_SOURCE_LINKADDR
;
293 buf
[len
++] = (sdl
->sdl_alen
+ 2) >> 3;
295 memcpy (buf
+ len
, LLADDR (sdl
), sdl
->sdl_alen
);
296 len
+= sdl
->sdl_alen
;
299 if (ifp
->hw_addr_len
!= 0)
301 buf
[len
++] = ND_OPT_SOURCE_LINKADDR
;
302 buf
[len
++] = (ifp
->hw_addr_len
+ 2) >> 3;
304 memcpy (buf
+ len
, ifp
->hw_addr
, ifp
->hw_addr_len
);
305 len
+= ifp
->hw_addr_len
;
307 #endif /* HAVE_STRUCT_SOCKADDR_DL */
309 msg
.msg_name
= (void *) &addr
;
310 msg
.msg_namelen
= sizeof (struct sockaddr_in6
);
313 msg
.msg_control
= (void *) adata
;
314 msg
.msg_controllen
= CMSG_SPACE(sizeof(struct in6_pktinfo
));
319 cmsgptr
= ZCMSG_FIRSTHDR(&msg
);
320 cmsgptr
->cmsg_len
= CMSG_LEN(sizeof(struct in6_pktinfo
));
321 cmsgptr
->cmsg_level
= IPPROTO_IPV6
;
322 cmsgptr
->cmsg_type
= IPV6_PKTINFO
;
324 pkt
= (struct in6_pktinfo
*) CMSG_DATA (cmsgptr
);
325 memset (&pkt
->ipi6_addr
, 0, sizeof (struct in6_addr
));
326 pkt
->ipi6_ifindex
= ifp
->ifindex
;
328 ret
= sendmsg (sock
, &msg
, 0);
331 zlog_err ("rtadv_send_packet: sendmsg %d (%s)\n",
332 errno
, safe_strerror(errno
));
337 rtadv_timer (struct thread
*thread
)
339 struct listnode
*node
, *nnode
;
340 struct interface
*ifp
;
341 struct zebra_if
*zif
;
344 rtadv
->ra_timer
= NULL
;
345 if (rtadv
->adv_msec_if_count
== 0)
347 period
= 1000; /* 1 s */
348 rtadv_event (RTADV_TIMER
, 1 /* 1 s */);
352 period
= 10; /* 10 ms */
353 rtadv_event (RTADV_TIMER_MSEC
, 10 /* 10 ms */);
356 for (ALL_LIST_ELEMENTS (iflist
, node
, nnode
, ifp
))
358 if (if_is_loopback (ifp
))
363 if (zif
->rtadv
.AdvSendAdvertisements
)
365 zif
->rtadv
.AdvIntervalTimer
-= period
;
366 if (zif
->rtadv
.AdvIntervalTimer
<= 0)
368 zif
->rtadv
.AdvIntervalTimer
= zif
->rtadv
.MaxRtrAdvInterval
;
369 rtadv_send_packet (rtadv
->sock
, ifp
);
377 rtadv_process_solicit (struct interface
*ifp
)
379 zlog_info ("Router solicitation received on %s", ifp
->name
);
381 rtadv_send_packet (rtadv
->sock
, ifp
);
385 rtadv_process_advert (void)
387 zlog_info ("Router advertisement received");
391 rtadv_process_packet (u_char
*buf
, unsigned int len
, unsigned int ifindex
, int hoplimit
)
393 struct icmp6_hdr
*icmph
;
394 struct interface
*ifp
;
395 struct zebra_if
*zif
;
397 /* Interface search. */
398 ifp
= if_lookup_by_index (ifindex
);
401 zlog_warn ("Unknown interface index: %d", ifindex
);
405 if (if_is_loopback (ifp
))
408 /* Check interface configuration. */
410 if (! zif
->rtadv
.AdvSendAdvertisements
)
413 /* ICMP message length check. */
414 if (len
< sizeof (struct icmp6_hdr
))
416 zlog_warn ("Invalid ICMPV6 packet length: %d", len
);
420 icmph
= (struct icmp6_hdr
*) buf
;
422 /* ICMP message type check. */
423 if (icmph
->icmp6_type
!= ND_ROUTER_SOLICIT
&&
424 icmph
->icmp6_type
!= ND_ROUTER_ADVERT
)
426 zlog_warn ("Unwanted ICMPV6 message type: %d", icmph
->icmp6_type
);
430 /* Hoplimit check. */
431 if (hoplimit
>= 0 && hoplimit
!= 255)
433 zlog_warn ("Invalid hoplimit %d for router advertisement ICMP packet",
438 /* Check ICMP message type. */
439 if (icmph
->icmp6_type
== ND_ROUTER_SOLICIT
)
440 rtadv_process_solicit (ifp
);
441 else if (icmph
->icmp6_type
== ND_ROUTER_ADVERT
)
442 rtadv_process_advert ();
448 rtadv_read (struct thread
*thread
)
452 u_char buf
[RTADV_MSG_SIZE
];
453 struct sockaddr_in6 from
;
454 unsigned int ifindex
;
457 sock
= THREAD_FD (thread
);
458 rtadv
->ra_read
= NULL
;
460 /* Register myself. */
461 rtadv_event (RTADV_READ
, sock
);
463 len
= rtadv_recv_packet (sock
, buf
, BUFSIZ
, &from
, &ifindex
, &hoplimit
);
467 zlog_warn ("router solicitation recv failed: %s.", safe_strerror (errno
));
471 rtadv_process_packet (buf
, (unsigned)len
, ifindex
, hoplimit
);
477 rtadv_make_socket (void)
481 struct icmp6_filter filter
;
483 if ( zserv_privs
.change (ZPRIVS_RAISE
) )
484 zlog_err ("rtadv_make_socket: could not raise privs, %s",
485 safe_strerror (errno
) );
487 sock
= socket (AF_INET6
, SOCK_RAW
, IPPROTO_ICMPV6
);
489 if ( zserv_privs
.change (ZPRIVS_LOWER
) )
490 zlog_err ("rtadv_make_socket: could not lower privs, %s",
491 safe_strerror (errno
) );
493 /* When we can't make ICMPV6 socket simply back. Router
494 advertisement feature will not be supported. */
498 ret
= setsockopt_ipv6_pktinfo (sock
, 1);
501 ret
= setsockopt_ipv6_multicast_loop (sock
, 0);
504 ret
= setsockopt_ipv6_unicast_hops (sock
, 255);
507 ret
= setsockopt_ipv6_multicast_hops (sock
, 255);
510 ret
= setsockopt_ipv6_hoplimit (sock
, 1);
514 ICMP6_FILTER_SETBLOCKALL(&filter
);
515 ICMP6_FILTER_SETPASS (ND_ROUTER_SOLICIT
, &filter
);
516 ICMP6_FILTER_SETPASS (ND_ROUTER_ADVERT
, &filter
);
518 ret
= setsockopt (sock
, IPPROTO_ICMPV6
, ICMP6_FILTER
, &filter
,
519 sizeof (struct icmp6_filter
));
522 zlog_info ("ICMP6_FILTER set fail: %s", safe_strerror (errno
));
529 static struct rtadv_prefix
*
532 struct rtadv_prefix
*new;
534 new = XMALLOC (MTYPE_RTADV_PREFIX
, sizeof (struct rtadv_prefix
));
535 memset (new, 0, sizeof (struct rtadv_prefix
));
541 rtadv_prefix_free (struct rtadv_prefix
*rtadv_prefix
)
543 XFREE (MTYPE_RTADV_PREFIX
, rtadv_prefix
);
546 static struct rtadv_prefix
*
547 rtadv_prefix_lookup (struct list
*rplist
, struct prefix
*p
)
549 struct listnode
*node
;
550 struct rtadv_prefix
*rprefix
;
552 for (ALL_LIST_ELEMENTS_RO (rplist
, node
, rprefix
))
553 if (prefix_same (&rprefix
->prefix
, p
))
558 static struct rtadv_prefix
*
559 rtadv_prefix_get (struct list
*rplist
, struct prefix
*p
)
561 struct rtadv_prefix
*rprefix
;
563 rprefix
= rtadv_prefix_lookup (rplist
, p
);
567 rprefix
= rtadv_prefix_new ();
568 memcpy (&rprefix
->prefix
, p
, sizeof (struct prefix
));
569 listnode_add (rplist
, rprefix
);
575 rtadv_prefix_set (struct zebra_if
*zif
, struct rtadv_prefix
*rp
)
577 struct rtadv_prefix
*rprefix
;
579 rprefix
= rtadv_prefix_get (zif
->rtadv
.AdvPrefixList
, &rp
->prefix
);
581 /* Set parameters. */
582 rprefix
->AdvValidLifetime
= rp
->AdvValidLifetime
;
583 rprefix
->AdvPreferredLifetime
= rp
->AdvPreferredLifetime
;
584 rprefix
->AdvOnLinkFlag
= rp
->AdvOnLinkFlag
;
585 rprefix
->AdvAutonomousFlag
= rp
->AdvAutonomousFlag
;
586 rprefix
->AdvRouterAddressFlag
= rp
->AdvRouterAddressFlag
;
590 rtadv_prefix_reset (struct zebra_if
*zif
, struct rtadv_prefix
*rp
)
592 struct rtadv_prefix
*rprefix
;
594 rprefix
= rtadv_prefix_lookup (zif
->rtadv
.AdvPrefixList
, &rp
->prefix
);
597 listnode_delete (zif
->rtadv
.AdvPrefixList
, (void *) rprefix
);
598 rtadv_prefix_free (rprefix
);
605 DEFUN (ipv6_nd_suppress_ra
,
606 ipv6_nd_suppress_ra_cmd
,
607 "ipv6 nd suppress-ra",
608 "Interface IPv6 config commands\n"
609 "Neighbor discovery\n"
610 "Suppress Router Advertisement\n")
612 struct interface
*ifp
;
613 struct zebra_if
*zif
;
618 if (if_is_loopback (ifp
))
620 vty_out (vty
, "Invalid interface%s", VTY_NEWLINE
);
624 if (zif
->rtadv
.AdvSendAdvertisements
)
626 zif
->rtadv
.AdvSendAdvertisements
= 0;
627 zif
->rtadv
.AdvIntervalTimer
= 0;
628 rtadv
->adv_if_count
--;
630 if_leave_all_router (rtadv
->sock
, ifp
);
632 if (rtadv
->adv_if_count
== 0)
633 rtadv_event (RTADV_STOP
, 0);
639 DEFUN (no_ipv6_nd_suppress_ra
,
640 no_ipv6_nd_suppress_ra_cmd
,
641 "no ipv6 nd suppress-ra",
643 "Interface IPv6 config commands\n"
644 "Neighbor discovery\n"
645 "Suppress Router Advertisement\n")
647 struct interface
*ifp
;
648 struct zebra_if
*zif
;
653 if (if_is_loopback (ifp
))
655 vty_out (vty
, "Invalid interface%s", VTY_NEWLINE
);
659 if (! zif
->rtadv
.AdvSendAdvertisements
)
661 zif
->rtadv
.AdvSendAdvertisements
= 1;
662 zif
->rtadv
.AdvIntervalTimer
= 0;
663 rtadv
->adv_if_count
++;
665 if_join_all_router (rtadv
->sock
, ifp
);
667 if (rtadv
->adv_if_count
== 1)
668 rtadv_event (RTADV_START
, rtadv
->sock
);
674 DEFUN (ipv6_nd_ra_interval_msec
,
675 ipv6_nd_ra_interval_msec_cmd
,
676 "ipv6 nd ra-interval msec MILLISECONDS",
677 "Interface IPv6 config commands\n"
678 "Neighbor discovery\n"
679 "Router Advertisement interval\n"
680 "Router Advertisement interval in milliseconds\n")
683 struct interface
*ifp
;
684 struct zebra_if
*zif
;
686 ifp
= (struct interface
*) vty
->index
;
689 interval
= atoi (argv
[0]);
693 vty_out (vty
, "Invalid Router Advertisement Interval%s", VTY_NEWLINE
);
697 if (zif
->rtadv
.MaxRtrAdvInterval
% 1000)
698 rtadv
->adv_msec_if_count
--;
701 rtadv
->adv_msec_if_count
++;
703 zif
->rtadv
.MaxRtrAdvInterval
= interval
;
704 zif
->rtadv
.MinRtrAdvInterval
= 0.33 * interval
;
705 zif
->rtadv
.AdvIntervalTimer
= 0;
710 DEFUN (ipv6_nd_ra_interval
,
711 ipv6_nd_ra_interval_cmd
,
712 "ipv6 nd ra-interval SECONDS",
713 "Interface IPv6 config commands\n"
714 "Neighbor discovery\n"
715 "Router Advertisement interval\n"
716 "Router Advertisement interval in seconds\n")
719 struct interface
*ifp
;
720 struct zebra_if
*zif
;
722 ifp
= (struct interface
*) vty
->index
;
725 interval
= atoi (argv
[0]);
729 vty_out (vty
, "Invalid Router Advertisement Interval%s", VTY_NEWLINE
);
733 if (zif
->rtadv
.MaxRtrAdvInterval
% 1000)
734 rtadv
->adv_msec_if_count
--;
736 /* convert to milliseconds */
737 interval
= interval
* 1000;
739 zif
->rtadv
.MaxRtrAdvInterval
= interval
;
740 zif
->rtadv
.MinRtrAdvInterval
= 0.33 * interval
;
741 zif
->rtadv
.AdvIntervalTimer
= 0;
746 DEFUN (no_ipv6_nd_ra_interval
,
747 no_ipv6_nd_ra_interval_cmd
,
748 "no ipv6 nd ra-interval",
750 "Interface IPv6 config commands\n"
751 "Neighbor discovery\n"
752 "Router Advertisement interval\n")
754 struct interface
*ifp
;
755 struct zebra_if
*zif
;
757 ifp
= (struct interface
*) vty
->index
;
760 if (zif
->rtadv
.MaxRtrAdvInterval
% 1000)
761 rtadv
->adv_msec_if_count
--;
763 zif
->rtadv
.MaxRtrAdvInterval
= RTADV_MAX_RTR_ADV_INTERVAL
;
764 zif
->rtadv
.MinRtrAdvInterval
= RTADV_MIN_RTR_ADV_INTERVAL
;
765 zif
->rtadv
.AdvIntervalTimer
= zif
->rtadv
.MaxRtrAdvInterval
;
770 DEFUN (ipv6_nd_ra_lifetime
,
771 ipv6_nd_ra_lifetime_cmd
,
772 "ipv6 nd ra-lifetime SECONDS",
773 "Interface IPv6 config commands\n"
774 "Neighbor discovery\n"
776 "Router lifetime in seconds\n")
779 struct interface
*ifp
;
780 struct zebra_if
*zif
;
782 ifp
= (struct interface
*) vty
->index
;
785 lifetime
= atoi (argv
[0]);
787 if (lifetime
< 0 || lifetime
> 0xffff)
789 vty_out (vty
, "Invalid Router Lifetime%s", VTY_NEWLINE
);
793 zif
->rtadv
.AdvDefaultLifetime
= lifetime
;
798 DEFUN (no_ipv6_nd_ra_lifetime
,
799 no_ipv6_nd_ra_lifetime_cmd
,
800 "no ipv6 nd ra-lifetime",
802 "Interface IPv6 config commands\n"
803 "Neighbor discovery\n"
806 struct interface
*ifp
;
807 struct zebra_if
*zif
;
809 ifp
= (struct interface
*) vty
->index
;
812 zif
->rtadv
.AdvDefaultLifetime
= RTADV_ADV_DEFAULT_LIFETIME
;
817 DEFUN (ipv6_nd_reachable_time
,
818 ipv6_nd_reachable_time_cmd
,
819 "ipv6 nd reachable-time MILLISECONDS",
820 "Interface IPv6 config commands\n"
821 "Neighbor discovery\n"
823 "Reachable time in milliseconds\n")
826 struct interface
*ifp
;
827 struct zebra_if
*zif
;
829 ifp
= (struct interface
*) vty
->index
;
832 rtime
= (u_int32_t
) atol (argv
[0]);
834 if (rtime
> RTADV_MAX_REACHABLE_TIME
)
836 vty_out (vty
, "Invalid Reachable time%s", VTY_NEWLINE
);
840 zif
->rtadv
.AdvReachableTime
= rtime
;
845 DEFUN (no_ipv6_nd_reachable_time
,
846 no_ipv6_nd_reachable_time_cmd
,
847 "no ipv6 nd reachable-time",
849 "Interface IPv6 config commands\n"
850 "Neighbor discovery\n"
853 struct interface
*ifp
;
854 struct zebra_if
*zif
;
856 ifp
= (struct interface
*) vty
->index
;
859 zif
->rtadv
.AdvReachableTime
= 0;
864 DEFUN (ipv6_nd_homeagent_preference
,
865 ipv6_nd_homeagent_preference_cmd
,
866 "ipv6 nd home-agent-preference PREFERENCE",
867 "Interface IPv6 config commands\n"
868 "Neighbor discovery\n"
869 "Home Agent preference\n"
870 "Home Agent preference value 0..65535\n")
873 struct interface
*ifp
;
874 struct zebra_if
*zif
;
876 ifp
= (struct interface
*) vty
->index
;
879 hapref
= (u_int32_t
) atol (argv
[0]);
883 vty_out (vty
, "Invalid Home Agent preference%s", VTY_NEWLINE
);
887 zif
->rtadv
.HomeAgentPreference
= hapref
;
892 DEFUN (no_ipv6_nd_homeagent_preference
,
893 no_ipv6_nd_homeagent_preference_cmd
,
894 "no ipv6 nd home-agent-preference",
896 "Interface IPv6 config commands\n"
897 "Neighbor discovery\n"
898 "Home Agent preference\n")
900 struct interface
*ifp
;
901 struct zebra_if
*zif
;
903 ifp
= (struct interface
*) vty
->index
;
906 zif
->rtadv
.HomeAgentPreference
= 0;
911 DEFUN (ipv6_nd_homeagent_lifetime
,
912 ipv6_nd_homeagent_lifetime_cmd
,
913 "ipv6 nd home-agent-lifetime SECONDS",
914 "Interface IPv6 config commands\n"
915 "Neighbor discovery\n"
916 "Home Agent lifetime\n"
917 "Home Agent lifetime in seconds\n")
920 struct interface
*ifp
;
921 struct zebra_if
*zif
;
923 ifp
= (struct interface
*) vty
->index
;
926 ha_ltime
= (u_int32_t
) atol (argv
[0]);
928 if (ha_ltime
> RTADV_MAX_HALIFETIME
)
930 vty_out (vty
, "Invalid Home Agent Lifetime time%s", VTY_NEWLINE
);
934 zif
->rtadv
.HomeAgentLifetime
= ha_ltime
;
939 DEFUN (no_ipv6_nd_homeagent_lifetime
,
940 no_ipv6_nd_homeagent_lifetime_cmd
,
941 "no ipv6 nd home-agent-lifetime",
943 "Interface IPv6 config commands\n"
944 "Neighbor discovery\n"
945 "Home Agent lifetime\n")
947 struct interface
*ifp
;
948 struct zebra_if
*zif
;
950 ifp
= (struct interface
*) vty
->index
;
953 zif
->rtadv
.HomeAgentLifetime
= 0;
958 DEFUN (ipv6_nd_managed_config_flag
,
959 ipv6_nd_managed_config_flag_cmd
,
960 "ipv6 nd managed-config-flag",
961 "Interface IPv6 config commands\n"
962 "Neighbor discovery\n"
963 "Managed address configuration flag\n")
965 struct interface
*ifp
;
966 struct zebra_if
*zif
;
968 ifp
= (struct interface
*) vty
->index
;
971 zif
->rtadv
.AdvManagedFlag
= 1;
976 DEFUN (no_ipv6_nd_managed_config_flag
,
977 no_ipv6_nd_managed_config_flag_cmd
,
978 "no ipv6 nd managed-config-flag",
980 "Interface IPv6 config commands\n"
981 "Neighbor discovery\n"
982 "Managed address configuration flag\n")
984 struct interface
*ifp
;
985 struct zebra_if
*zif
;
987 ifp
= (struct interface
*) vty
->index
;
990 zif
->rtadv
.AdvManagedFlag
= 0;
995 DEFUN (ipv6_nd_homeagent_config_flag
,
996 ipv6_nd_homeagent_config_flag_cmd
,
997 "ipv6 nd home-agent-config-flag",
998 "Interface IPv6 config commands\n"
999 "Neighbor discovery\n"
1000 "Home Agent configuration flag\n")
1002 struct interface
*ifp
;
1003 struct zebra_if
*zif
;
1005 ifp
= (struct interface
*) vty
->index
;
1008 zif
->rtadv
.AdvHomeAgentFlag
= 1;
1013 DEFUN (no_ipv6_nd_homeagent_config_flag
,
1014 no_ipv6_nd_homeagent_config_flag_cmd
,
1015 "no ipv6 nd home-agent-config-flag",
1017 "Interface IPv6 config commands\n"
1018 "Neighbor discovery\n"
1019 "Home Agent configuration flag\n")
1021 struct interface
*ifp
;
1022 struct zebra_if
*zif
;
1024 ifp
= (struct interface
*) vty
->index
;
1027 zif
->rtadv
.AdvHomeAgentFlag
= 0;
1032 DEFUN (ipv6_nd_adv_interval_config_option
,
1033 ipv6_nd_adv_interval_config_option_cmd
,
1034 "ipv6 nd adv-interval-option",
1035 "Interface IPv6 config commands\n"
1036 "Neighbor discovery\n"
1037 "Advertisement Interval Option\n")
1039 struct interface
*ifp
;
1040 struct zebra_if
*zif
;
1042 ifp
= (struct interface
*) vty
->index
;
1045 zif
->rtadv
.AdvIntervalOption
= 1;
1050 DEFUN (no_ipv6_nd_adv_interval_config_option
,
1051 no_ipv6_nd_adv_interval_config_option_cmd
,
1052 "no ipv6 nd adv-interval-option",
1054 "Interface IPv6 config commands\n"
1055 "Neighbor discovery\n"
1056 "Advertisement Interval Option\n")
1058 struct interface
*ifp
;
1059 struct zebra_if
*zif
;
1061 ifp
= (struct interface
*) vty
->index
;
1064 zif
->rtadv
.AdvIntervalOption
= 0;
1069 DEFUN (ipv6_nd_other_config_flag
,
1070 ipv6_nd_other_config_flag_cmd
,
1071 "ipv6 nd other-config-flag",
1072 "Interface IPv6 config commands\n"
1073 "Neighbor discovery\n"
1074 "Other statefull configuration flag\n")
1076 struct interface
*ifp
;
1077 struct zebra_if
*zif
;
1079 ifp
= (struct interface
*) vty
->index
;
1082 zif
->rtadv
.AdvOtherConfigFlag
= 1;
1087 DEFUN (no_ipv6_nd_other_config_flag
,
1088 no_ipv6_nd_other_config_flag_cmd
,
1089 "no ipv6 nd other-config-flag",
1091 "Interface IPv6 config commands\n"
1092 "Neighbor discovery\n"
1093 "Other statefull configuration flag\n")
1095 struct interface
*ifp
;
1096 struct zebra_if
*zif
;
1098 ifp
= (struct interface
*) vty
->index
;
1101 zif
->rtadv
.AdvOtherConfigFlag
= 0;
1106 DEFUN (ipv6_nd_prefix
,
1108 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1109 "(<0-4294967295>|infinite) (off-link|) (no-autoconfig|) (router-address|)",
1110 "Interface IPv6 config commands\n"
1111 "Neighbor discovery\n"
1112 "Prefix information\n"
1114 "Valid lifetime in seconds\n"
1115 "Infinite valid lifetime\n"
1116 "Preferred lifetime in seconds\n"
1117 "Infinite preferred lifetime\n"
1118 "Do not use prefix for onlink determination\n"
1119 "Do not use prefix for autoconfiguration\n"
1120 "Set Router Address flag\n")
1125 struct interface
*ifp
;
1126 struct zebra_if
*zebra_if
;
1127 struct rtadv_prefix rp
;
1129 ifp
= (struct interface
*) vty
->index
;
1130 zebra_if
= ifp
->info
;
1132 ret
= str2prefix_ipv6 (argv
[0], (struct prefix_ipv6
*) &rp
.prefix
);
1135 vty_out (vty
, "Malformed IPv6 prefix%s", VTY_NEWLINE
);
1138 rp
.AdvOnLinkFlag
= 1;
1139 rp
.AdvAutonomousFlag
= 1;
1140 rp
.AdvRouterAddressFlag
= 0;
1141 rp
.AdvValidLifetime
= RTADV_VALID_LIFETIME
;
1142 rp
.AdvPreferredLifetime
= RTADV_PREFERRED_LIFETIME
;
1146 if ((isdigit(argv
[1][0])) || strncmp (argv
[1], "i", 1) == 0)
1148 if ( strncmp (argv
[1], "i", 1) == 0)
1149 rp
.AdvValidLifetime
= UINT32_MAX
;
1151 rp
.AdvValidLifetime
= (u_int32_t
) strtoll (argv
[1],
1154 if ( strncmp (argv
[2], "i", 1) == 0)
1155 rp
.AdvPreferredLifetime
= UINT32_MAX
;
1157 rp
.AdvPreferredLifetime
= (u_int32_t
) strtoll (argv
[2],
1160 if (rp
.AdvPreferredLifetime
> rp
.AdvValidLifetime
)
1162 vty_out (vty
, "Invalid preferred lifetime%s", VTY_NEWLINE
);
1165 cursor
= cursor
+ 2;
1169 for (i
= cursor
; i
< argc
; i
++)
1171 if (strncmp (argv
[i
], "of", 2) == 0)
1172 rp
.AdvOnLinkFlag
= 0;
1173 if (strncmp (argv
[i
], "no", 2) == 0)
1174 rp
.AdvAutonomousFlag
= 0;
1175 if (strncmp (argv
[i
], "ro", 2) == 0)
1176 rp
.AdvRouterAddressFlag
= 1;
1181 rtadv_prefix_set (zebra_if
, &rp
);
1186 ALIAS (ipv6_nd_prefix
,
1187 ipv6_nd_prefix_val_nortaddr_cmd
,
1188 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1189 "(<0-4294967295>|infinite) (off-link|) (no-autoconfig|)",
1190 "Interface IPv6 config commands\n"
1191 "Neighbor discovery\n"
1192 "Prefix information\n"
1194 "Valid lifetime in seconds\n"
1195 "Infinite valid lifetime\n"
1196 "Preferred lifetime in seconds\n"
1197 "Infinite preferred lifetime\n"
1198 "Do not use prefix for onlink determination\n"
1199 "Do not use prefix for autoconfiguration\n")
1201 ALIAS (ipv6_nd_prefix
,
1202 ipv6_nd_prefix_val_rev_cmd
,
1203 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1204 "(<0-4294967295>|infinite) (no-autoconfig|) (off-link|)",
1205 "Interface IPv6 config commands\n"
1206 "Neighbor discovery\n"
1207 "Prefix information\n"
1209 "Valid lifetime in seconds\n"
1210 "Infinite valid lifetime\n"
1211 "Preferred lifetime in seconds\n"
1212 "Infinite preferred lifetime\n"
1213 "Do not use prefix for autoconfiguration\n"
1214 "Do not use prefix for onlink determination\n")
1216 ALIAS (ipv6_nd_prefix
,
1217 ipv6_nd_prefix_val_rev_rtaddr_cmd
,
1218 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1219 "(<0-4294967295>|infinite) (no-autoconfig|) (off-link|) (router-address|)",
1220 "Interface IPv6 config commands\n"
1221 "Neighbor discovery\n"
1222 "Prefix information\n"
1224 "Valid lifetime in seconds\n"
1225 "Infinite valid lifetime\n"
1226 "Preferred lifetime in seconds\n"
1227 "Infinite preferred lifetime\n"
1228 "Do not use prefix for autoconfiguration\n"
1229 "Do not use prefix for onlink determination\n"
1230 "Set Router Address flag\n")
1232 ALIAS (ipv6_nd_prefix
,
1233 ipv6_nd_prefix_val_noauto_cmd
,
1234 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1235 "(<0-4294967295>|infinite) (no-autoconfig|)",
1236 "Interface IPv6 config commands\n"
1237 "Neighbor discovery\n"
1238 "Prefix information\n"
1240 "Valid lifetime in seconds\n"
1241 "Infinite valid lifetime\n"
1242 "Preferred lifetime in seconds\n"
1243 "Infinite preferred lifetime\n"
1244 "Do not use prefix for autoconfiguration")
1246 ALIAS (ipv6_nd_prefix
,
1247 ipv6_nd_prefix_val_offlink_cmd
,
1248 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1249 "(<0-4294967295>|infinite) (off-link|)",
1250 "Interface IPv6 config commands\n"
1251 "Neighbor discovery\n"
1252 "Prefix information\n"
1254 "Valid lifetime in seconds\n"
1255 "Infinite valid lifetime\n"
1256 "Preferred lifetime in seconds\n"
1257 "Infinite preferred lifetime\n"
1258 "Do not use prefix for onlink determination\n")
1260 ALIAS (ipv6_nd_prefix
,
1261 ipv6_nd_prefix_val_rtaddr_cmd
,
1262 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1263 "(<0-4294967295>|infinite) (router-address|)",
1264 "Interface IPv6 config commands\n"
1265 "Neighbor discovery\n"
1266 "Prefix information\n"
1268 "Valid lifetime in seconds\n"
1269 "Infinite valid lifetime\n"
1270 "Preferred lifetime in seconds\n"
1271 "Infinite preferred lifetime\n"
1272 "Set Router Address flag\n")
1274 ALIAS (ipv6_nd_prefix
,
1275 ipv6_nd_prefix_val_cmd
,
1276 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1277 "(<0-4294967295>|infinite)",
1278 "Interface IPv6 config commands\n"
1279 "Neighbor discovery\n"
1280 "Prefix information\n"
1282 "Valid lifetime in seconds\n"
1283 "Infinite valid lifetime\n"
1284 "Preferred lifetime in seconds\n"
1285 "Infinite preferred lifetime\n")
1287 ALIAS (ipv6_nd_prefix
,
1288 ipv6_nd_prefix_noval_cmd
,
1289 "ipv6 nd prefix X:X::X:X/M (no-autoconfig|) (off-link|)",
1290 "Interface IPv6 config commands\n"
1291 "Neighbor discovery\n"
1292 "Prefix information\n"
1294 "Do not use prefix for autoconfiguration\n"
1295 "Do not use prefix for onlink determination\n")
1297 ALIAS (ipv6_nd_prefix
,
1298 ipv6_nd_prefix_noval_rev_cmd
,
1299 "ipv6 nd prefix X:X::X:X/M (off-link|) (no-autoconfig|)",
1300 "Interface IPv6 config commands\n"
1301 "Neighbor discovery\n"
1302 "Prefix information\n"
1304 "Do not use prefix for onlink determination\n"
1305 "Do not use prefix for autoconfiguration\n")
1307 ALIAS (ipv6_nd_prefix
,
1308 ipv6_nd_prefix_noval_noauto_cmd
,
1309 "ipv6 nd prefix X:X::X:X/M (no-autoconfig|)",
1310 "Interface IPv6 config commands\n"
1311 "Neighbor discovery\n"
1312 "Prefix information\n"
1314 "Do not use prefix for autoconfiguration\n")
1316 ALIAS (ipv6_nd_prefix
,
1317 ipv6_nd_prefix_noval_offlink_cmd
,
1318 "ipv6 nd prefix X:X::X:X/M (off-link|)",
1319 "Interface IPv6 config commands\n"
1320 "Neighbor discovery\n"
1321 "Prefix information\n"
1323 "Do not use prefix for onlink determination\n")
1325 ALIAS (ipv6_nd_prefix
,
1326 ipv6_nd_prefix_noval_rtaddr_cmd
,
1327 "ipv6 nd prefix X:X::X:X/M (router-address|)",
1328 "Interface IPv6 config commands\n"
1329 "Neighbor discovery\n"
1330 "Prefix information\n"
1332 "Set Router Address flag\n")
1334 ALIAS (ipv6_nd_prefix
,
1335 ipv6_nd_prefix_prefix_cmd
,
1336 "ipv6 nd prefix X:X::X:X/M",
1337 "Interface IPv6 config commands\n"
1338 "Neighbor discovery\n"
1339 "Prefix information\n"
1342 DEFUN (no_ipv6_nd_prefix
,
1343 no_ipv6_nd_prefix_cmd
,
1344 "no ipv6 nd prefix IPV6PREFIX",
1346 "Interface IPv6 config commands\n"
1347 "Neighbor discovery\n"
1348 "Prefix information\n"
1352 struct interface
*ifp
;
1353 struct zebra_if
*zebra_if
;
1354 struct rtadv_prefix rp
;
1356 ifp
= (struct interface
*) vty
->index
;
1357 zebra_if
= ifp
->info
;
1359 ret
= str2prefix_ipv6 (argv
[0], (struct prefix_ipv6
*) &rp
.prefix
);
1362 vty_out (vty
, "Malformed IPv6 prefix%s", VTY_NEWLINE
);
1366 ret
= rtadv_prefix_reset (zebra_if
, &rp
);
1369 vty_out (vty
, "Non-exist IPv6 prefix%s", VTY_NEWLINE
);
1375 /* Write configuration about router advertisement. */
1377 rtadv_config_write (struct vty
*vty
, struct interface
*ifp
)
1379 struct zebra_if
*zif
;
1380 struct listnode
*node
;
1381 struct rtadv_prefix
*rprefix
;
1382 u_char buf
[INET6_ADDRSTRLEN
];
1390 if (! if_is_loopback (ifp
))
1392 if (zif
->rtadv
.AdvSendAdvertisements
)
1393 vty_out (vty
, " no ipv6 nd suppress-ra%s", VTY_NEWLINE
);
1395 vty_out (vty
, " ipv6 nd suppress-ra%s", VTY_NEWLINE
);
1399 interval
= zif
->rtadv
.MaxRtrAdvInterval
;
1400 if (interval
% 1000)
1401 vty_out (vty
, " ipv6 nd ra-interval msec %d%s", interval
,
1404 if (interval
!= RTADV_MAX_RTR_ADV_INTERVAL
)
1405 vty_out (vty
, " ipv6 nd ra-interval %d%s", interval
/ 1000,
1408 if (zif
->rtadv
.AdvDefaultLifetime
!= RTADV_ADV_DEFAULT_LIFETIME
)
1409 vty_out (vty
, " ipv6 nd ra-lifetime %d%s", zif
->rtadv
.AdvDefaultLifetime
,
1412 if (zif
->rtadv
.AdvReachableTime
)
1413 vty_out (vty
, " ipv6 nd reachable-time %d%s", zif
->rtadv
.AdvReachableTime
,
1416 if (zif
->rtadv
.AdvManagedFlag
)
1417 vty_out (vty
, " ipv6 nd managed-config-flag%s", VTY_NEWLINE
);
1419 if (zif
->rtadv
.AdvOtherConfigFlag
)
1420 vty_out (vty
, " ipv6 nd other-config-flag%s", VTY_NEWLINE
);
1422 for (ALL_LIST_ELEMENTS_RO (zif
->rtadv
.AdvPrefixList
, node
, rprefix
))
1424 vty_out (vty
, " ipv6 nd prefix %s/%d",
1425 inet_ntop (AF_INET6
, &rprefix
->prefix
.u
.prefix6
,
1426 (char *) buf
, INET6_ADDRSTRLEN
),
1427 rprefix
->prefix
.prefixlen
);
1428 if ((rprefix
->AdvValidLifetime
!= RTADV_VALID_LIFETIME
) ||
1429 (rprefix
->AdvPreferredLifetime
!= RTADV_PREFERRED_LIFETIME
))
1431 if (rprefix
->AdvValidLifetime
== UINT32_MAX
)
1432 vty_out (vty
, " infinite");
1434 vty_out (vty
, " %u", rprefix
->AdvValidLifetime
);
1435 if (rprefix
->AdvPreferredLifetime
== UINT32_MAX
)
1436 vty_out (vty
, " infinite");
1438 vty_out (vty
, " %u", rprefix
->AdvPreferredLifetime
);
1440 if (!rprefix
->AdvOnLinkFlag
)
1441 vty_out (vty
, " off-link");
1442 if (!rprefix
->AdvAutonomousFlag
)
1443 vty_out (vty
, " no-autoconfig");
1444 if (rprefix
->AdvRouterAddressFlag
)
1445 vty_out (vty
, " router-address");
1446 vty_out (vty
, "%s", VTY_NEWLINE
);
1452 rtadv_event (enum rtadv_event event
, int val
)
1457 if (! rtadv
->ra_read
)
1458 rtadv
->ra_read
= thread_add_read (zebrad
.master
, rtadv_read
, NULL
, val
);
1459 if (! rtadv
->ra_timer
)
1460 rtadv
->ra_timer
= thread_add_event (zebrad
.master
, rtadv_timer
,
1464 if (rtadv
->ra_timer
)
1466 thread_cancel (rtadv
->ra_timer
);
1467 rtadv
->ra_timer
= NULL
;
1471 thread_cancel (rtadv
->ra_read
);
1472 rtadv
->ra_read
= NULL
;
1476 if (! rtadv
->ra_timer
)
1477 rtadv
->ra_timer
= thread_add_timer (zebrad
.master
, rtadv_timer
, NULL
,
1480 case RTADV_TIMER_MSEC
:
1481 if (! rtadv
->ra_timer
)
1482 rtadv
->ra_timer
= thread_add_timer_msec (zebrad
.master
, rtadv_timer
,
1486 if (! rtadv
->ra_read
)
1487 rtadv
->ra_read
= thread_add_read (zebrad
.master
, rtadv_read
, NULL
, val
);
1500 sock
= rtadv_make_socket ();
1504 rtadv
= rtadv_new ();
1507 install_element (INTERFACE_NODE
, &ipv6_nd_suppress_ra_cmd
);
1508 install_element (INTERFACE_NODE
, &no_ipv6_nd_suppress_ra_cmd
);
1509 install_element (INTERFACE_NODE
, &ipv6_nd_ra_interval_cmd
);
1510 install_element (INTERFACE_NODE
, &ipv6_nd_ra_interval_msec_cmd
);
1511 install_element (INTERFACE_NODE
, &no_ipv6_nd_ra_interval_cmd
);
1512 install_element (INTERFACE_NODE
, &ipv6_nd_ra_lifetime_cmd
);
1513 install_element (INTERFACE_NODE
, &no_ipv6_nd_ra_lifetime_cmd
);
1514 install_element (INTERFACE_NODE
, &ipv6_nd_reachable_time_cmd
);
1515 install_element (INTERFACE_NODE
, &no_ipv6_nd_reachable_time_cmd
);
1516 install_element (INTERFACE_NODE
, &ipv6_nd_managed_config_flag_cmd
);
1517 install_element (INTERFACE_NODE
, &no_ipv6_nd_managed_config_flag_cmd
);
1518 install_element (INTERFACE_NODE
, &ipv6_nd_other_config_flag_cmd
);
1519 install_element (INTERFACE_NODE
, &no_ipv6_nd_other_config_flag_cmd
);
1520 install_element (INTERFACE_NODE
, &ipv6_nd_homeagent_config_flag_cmd
);
1521 install_element (INTERFACE_NODE
, &no_ipv6_nd_homeagent_config_flag_cmd
);
1522 install_element (INTERFACE_NODE
, &ipv6_nd_homeagent_preference_cmd
);
1523 install_element (INTERFACE_NODE
, &no_ipv6_nd_homeagent_preference_cmd
);
1524 install_element (INTERFACE_NODE
, &ipv6_nd_homeagent_lifetime_cmd
);
1525 install_element (INTERFACE_NODE
, &no_ipv6_nd_homeagent_lifetime_cmd
);
1526 install_element (INTERFACE_NODE
, &ipv6_nd_adv_interval_config_option_cmd
);
1527 install_element (INTERFACE_NODE
, &no_ipv6_nd_adv_interval_config_option_cmd
);
1528 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_cmd
);
1529 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_val_rev_rtaddr_cmd
);
1530 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_val_nortaddr_cmd
);
1531 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_val_rev_cmd
);
1532 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_val_noauto_cmd
);
1533 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_val_offlink_cmd
);
1534 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_val_rtaddr_cmd
);
1535 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_val_cmd
);
1536 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_noval_cmd
);
1537 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_noval_rev_cmd
);
1538 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_noval_noauto_cmd
);
1539 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_noval_offlink_cmd
);
1540 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_noval_rtaddr_cmd
);
1541 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_prefix_cmd
);
1542 install_element (INTERFACE_NODE
, &no_ipv6_nd_prefix_cmd
);
1546 if_join_all_router (int sock
, struct interface
*ifp
)
1550 struct ipv6_mreq mreq
;
1552 memset (&mreq
, 0, sizeof (struct ipv6_mreq
));
1553 inet_pton (AF_INET6
, ALLROUTER
, &mreq
.ipv6mr_multiaddr
);
1554 mreq
.ipv6mr_interface
= ifp
->ifindex
;
1556 ret
= setsockopt (sock
, IPPROTO_IPV6
, IPV6_JOIN_GROUP
,
1557 (char *) &mreq
, sizeof mreq
);
1559 zlog_warn ("can't setsockopt IPV6_JOIN_GROUP: %s", safe_strerror (errno
));
1561 zlog_info ("rtadv: %s join to all-routers multicast group", ifp
->name
);
1567 if_leave_all_router (int sock
, struct interface
*ifp
)
1571 struct ipv6_mreq mreq
;
1573 memset (&mreq
, 0, sizeof (struct ipv6_mreq
));
1574 inet_pton (AF_INET6
, ALLROUTER
, &mreq
.ipv6mr_multiaddr
);
1575 mreq
.ipv6mr_interface
= ifp
->ifindex
;
1577 ret
= setsockopt (sock
, IPPROTO_IPV6
, IPV6_LEAVE_GROUP
,
1578 (char *) &mreq
, sizeof mreq
);
1580 zlog_warn ("can't setsockopt IPV6_LEAVE_GROUP: %s", safe_strerror (errno
));
1582 zlog_info ("rtadv: %s leave from all-routers multicast group", ifp
->name
);
1593 #endif /* RTADV && HAVE_IPV6 */