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;
209 rtadv
->nd_ra_flags_reserved
= 0;
210 if (zif
->rtadv
.AdvManagedFlag
)
211 rtadv
->nd_ra_flags_reserved
|= ND_RA_FLAG_MANAGED
;
212 if (zif
->rtadv
.AdvOtherConfigFlag
)
213 rtadv
->nd_ra_flags_reserved
|= ND_RA_FLAG_OTHER
;
214 if (zif
->rtadv
.AdvHomeAgentFlag
)
215 rtadv
->nd_ra_flags_reserved
|= ND_RA_FLAG_HOME_AGENT
;
216 rtadv
->nd_ra_router_lifetime
= htons (zif
->rtadv
.AdvDefaultLifetime
);
217 rtadv
->nd_ra_reachable
= htonl (zif
->rtadv
.AdvReachableTime
);
218 rtadv
->nd_ra_retransmit
= htonl (0);
220 len
= sizeof (struct nd_router_advert
);
222 if (zif
->rtadv
.AdvHomeAgentFlag
)
224 struct nd_opt_homeagent_info
*ndopt_hai
=
225 (struct nd_opt_homeagent_info
*)(buf
+ len
);
226 ndopt_hai
->nd_opt_hai_type
= ND_OPT_HA_INFORMATION
;
227 ndopt_hai
->nd_opt_hai_len
= 1;
228 ndopt_hai
->nd_opt_hai_reserved
= 0;
229 ndopt_hai
->nd_opt_hai_preference
= htons(zif
->rtadv
.HomeAgentPreference
);
230 ndopt_hai
->nd_opt_hai_lifetime
= htons(zif
->rtadv
.HomeAgentLifetime
);
231 len
+= sizeof(struct nd_opt_homeagent_info
);
234 if (zif
->rtadv
.AdvIntervalOption
)
236 struct nd_opt_adv_interval
*ndopt_adv
=
237 (struct nd_opt_adv_interval
*)(buf
+ len
);
238 ndopt_adv
->nd_opt_ai_type
= ND_OPT_ADV_INTERVAL
;
239 ndopt_adv
->nd_opt_ai_len
= 1;
240 ndopt_adv
->nd_opt_ai_reserved
= 0;
241 ndopt_adv
->nd_opt_ai_interval
= htonl(zif
->rtadv
.MaxRtrAdvInterval
);
242 len
+= sizeof(struct nd_opt_adv_interval
);
245 /* Fill in prefix. */
246 for (ALL_LIST_ELEMENTS_RO (zif
->rtadv
.AdvPrefixList
, node
, rprefix
))
248 struct nd_opt_prefix_info
*pinfo
;
250 pinfo
= (struct nd_opt_prefix_info
*) (buf
+ len
);
252 pinfo
->nd_opt_pi_type
= ND_OPT_PREFIX_INFORMATION
;
253 pinfo
->nd_opt_pi_len
= 4;
254 pinfo
->nd_opt_pi_prefix_len
= rprefix
->prefix
.prefixlen
;
256 pinfo
->nd_opt_pi_flags_reserved
= 0;
257 if (rprefix
->AdvOnLinkFlag
)
258 pinfo
->nd_opt_pi_flags_reserved
|= ND_OPT_PI_FLAG_ONLINK
;
259 if (rprefix
->AdvAutonomousFlag
)
260 pinfo
->nd_opt_pi_flags_reserved
|= ND_OPT_PI_FLAG_AUTO
;
261 if (rprefix
->AdvRouterAddressFlag
)
262 pinfo
->nd_opt_pi_flags_reserved
|= ND_OPT_PI_FLAG_RADDR
;
264 pinfo
->nd_opt_pi_valid_time
= htonl (rprefix
->AdvValidLifetime
);
265 pinfo
->nd_opt_pi_preferred_time
= htonl (rprefix
->AdvPreferredLifetime
);
266 pinfo
->nd_opt_pi_reserved2
= 0;
268 memcpy (&pinfo
->nd_opt_pi_prefix
, &rprefix
->prefix
.u
.prefix6
,
269 sizeof (struct in6_addr
));
273 u_char buf
[INET6_ADDRSTRLEN
];
275 zlog_debug ("DEBUG %s", inet_ntop (AF_INET6
, &pinfo
->nd_opt_pi_prefix
,
276 buf
, INET6_ADDRSTRLEN
));
281 len
+= sizeof (struct nd_opt_prefix_info
);
284 /* Hardware address. */
285 #ifdef HAVE_STRUCT_SOCKADDR_DL
287 if (sdl
!= NULL
&& sdl
->sdl_alen
!= 0)
289 buf
[len
++] = ND_OPT_SOURCE_LINKADDR
;
290 buf
[len
++] = (sdl
->sdl_alen
+ 2) >> 3;
292 memcpy (buf
+ len
, LLADDR (sdl
), sdl
->sdl_alen
);
293 len
+= sdl
->sdl_alen
;
296 if (ifp
->hw_addr_len
!= 0)
298 buf
[len
++] = ND_OPT_SOURCE_LINKADDR
;
299 buf
[len
++] = (ifp
->hw_addr_len
+ 2) >> 3;
301 memcpy (buf
+ len
, ifp
->hw_addr
, ifp
->hw_addr_len
);
302 len
+= ifp
->hw_addr_len
;
304 #endif /* HAVE_STRUCT_SOCKADDR_DL */
306 msg
.msg_name
= (void *) &addr
;
307 msg
.msg_namelen
= sizeof (struct sockaddr_in6
);
310 msg
.msg_control
= (void *) adata
;
311 msg
.msg_controllen
= CMSG_SPACE(sizeof(struct in6_pktinfo
));
316 cmsgptr
= ZCMSG_FIRSTHDR(&msg
);
317 cmsgptr
->cmsg_len
= CMSG_LEN(sizeof(struct in6_pktinfo
));
318 cmsgptr
->cmsg_level
= IPPROTO_IPV6
;
319 cmsgptr
->cmsg_type
= IPV6_PKTINFO
;
321 pkt
= (struct in6_pktinfo
*) CMSG_DATA (cmsgptr
);
322 memset (&pkt
->ipi6_addr
, 0, sizeof (struct in6_addr
));
323 pkt
->ipi6_ifindex
= ifp
->ifindex
;
325 ret
= sendmsg (sock
, &msg
, 0);
328 zlog_err ("rtadv_send_packet: sendmsg %d (%s)\n",
329 errno
, safe_strerror(errno
));
334 rtadv_timer (struct thread
*thread
)
336 struct listnode
*node
, *nnode
;
337 struct interface
*ifp
;
338 struct zebra_if
*zif
;
341 rtadv
->ra_timer
= NULL
;
342 if (rtadv
->adv_msec_if_count
== 0)
344 period
= 1000; /* 1 s */
345 rtadv_event (RTADV_TIMER
, 1 /* 1 s */);
349 period
= 10; /* 10 ms */
350 rtadv_event (RTADV_TIMER_MSEC
, 10 /* 10 ms */);
353 for (ALL_LIST_ELEMENTS (iflist
, node
, nnode
, ifp
))
355 if (if_is_loopback (ifp
))
360 if (zif
->rtadv
.AdvSendAdvertisements
)
362 zif
->rtadv
.AdvIntervalTimer
-= period
;
363 if (zif
->rtadv
.AdvIntervalTimer
<= 0)
365 zif
->rtadv
.AdvIntervalTimer
= zif
->rtadv
.MaxRtrAdvInterval
;
366 rtadv_send_packet (rtadv
->sock
, ifp
);
374 rtadv_process_solicit (struct interface
*ifp
)
376 zlog_info ("Router solicitation received on %s", ifp
->name
);
378 rtadv_send_packet (rtadv
->sock
, ifp
);
382 rtadv_process_advert (void)
384 zlog_info ("Router advertisement received");
388 rtadv_process_packet (u_char
*buf
, unsigned int len
, unsigned int ifindex
, int hoplimit
)
390 struct icmp6_hdr
*icmph
;
391 struct interface
*ifp
;
392 struct zebra_if
*zif
;
394 /* Interface search. */
395 ifp
= if_lookup_by_index (ifindex
);
398 zlog_warn ("Unknown interface index: %d", ifindex
);
402 if (if_is_loopback (ifp
))
405 /* Check interface configuration. */
407 if (! zif
->rtadv
.AdvSendAdvertisements
)
410 /* ICMP message length check. */
411 if (len
< sizeof (struct icmp6_hdr
))
413 zlog_warn ("Invalid ICMPV6 packet length: %d", len
);
417 icmph
= (struct icmp6_hdr
*) buf
;
419 /* ICMP message type check. */
420 if (icmph
->icmp6_type
!= ND_ROUTER_SOLICIT
&&
421 icmph
->icmp6_type
!= ND_ROUTER_ADVERT
)
423 zlog_warn ("Unwanted ICMPV6 message type: %d", icmph
->icmp6_type
);
427 /* Hoplimit check. */
428 if (hoplimit
>= 0 && hoplimit
!= 255)
430 zlog_warn ("Invalid hoplimit %d for router advertisement ICMP packet",
435 /* Check ICMP message type. */
436 if (icmph
->icmp6_type
== ND_ROUTER_SOLICIT
)
437 rtadv_process_solicit (ifp
);
438 else if (icmph
->icmp6_type
== ND_ROUTER_ADVERT
)
439 rtadv_process_advert ();
445 rtadv_read (struct thread
*thread
)
449 u_char buf
[RTADV_MSG_SIZE
];
450 struct sockaddr_in6 from
;
451 unsigned int ifindex
;
454 sock
= THREAD_FD (thread
);
455 rtadv
->ra_read
= NULL
;
457 /* Register myself. */
458 rtadv_event (RTADV_READ
, sock
);
460 len
= rtadv_recv_packet (sock
, buf
, BUFSIZ
, &from
, &ifindex
, &hoplimit
);
464 zlog_warn ("router solicitation recv failed: %s.", safe_strerror (errno
));
468 rtadv_process_packet (buf
, (unsigned)len
, ifindex
, hoplimit
);
474 rtadv_make_socket (void)
478 struct icmp6_filter filter
;
480 if ( zserv_privs
.change (ZPRIVS_RAISE
) )
481 zlog_err ("rtadv_make_socket: could not raise privs, %s",
482 safe_strerror (errno
) );
484 sock
= socket (AF_INET6
, SOCK_RAW
, IPPROTO_ICMPV6
);
486 if ( zserv_privs
.change (ZPRIVS_LOWER
) )
487 zlog_err ("rtadv_make_socket: could not lower privs, %s",
488 safe_strerror (errno
) );
490 /* When we can't make ICMPV6 socket simply back. Router
491 advertisement feature will not be supported. */
495 ret
= setsockopt_ipv6_pktinfo (sock
, 1);
498 ret
= setsockopt_ipv6_multicast_loop (sock
, 0);
501 ret
= setsockopt_ipv6_unicast_hops (sock
, 255);
504 ret
= setsockopt_ipv6_multicast_hops (sock
, 255);
507 ret
= setsockopt_ipv6_hoplimit (sock
, 1);
511 ICMP6_FILTER_SETBLOCKALL(&filter
);
512 ICMP6_FILTER_SETPASS (ND_ROUTER_SOLICIT
, &filter
);
513 ICMP6_FILTER_SETPASS (ND_ROUTER_ADVERT
, &filter
);
515 ret
= setsockopt (sock
, IPPROTO_ICMPV6
, ICMP6_FILTER
, &filter
,
516 sizeof (struct icmp6_filter
));
519 zlog_info ("ICMP6_FILTER set fail: %s", safe_strerror (errno
));
526 static struct rtadv_prefix
*
529 return XCALLOC (MTYPE_RTADV_PREFIX
, sizeof (struct rtadv_prefix
));
533 rtadv_prefix_free (struct rtadv_prefix
*rtadv_prefix
)
535 XFREE (MTYPE_RTADV_PREFIX
, rtadv_prefix
);
538 static struct rtadv_prefix
*
539 rtadv_prefix_lookup (struct list
*rplist
, struct prefix
*p
)
541 struct listnode
*node
;
542 struct rtadv_prefix
*rprefix
;
544 for (ALL_LIST_ELEMENTS_RO (rplist
, node
, rprefix
))
545 if (prefix_same (&rprefix
->prefix
, p
))
550 static struct rtadv_prefix
*
551 rtadv_prefix_get (struct list
*rplist
, struct prefix
*p
)
553 struct rtadv_prefix
*rprefix
;
555 rprefix
= rtadv_prefix_lookup (rplist
, p
);
559 rprefix
= rtadv_prefix_new ();
560 memcpy (&rprefix
->prefix
, p
, sizeof (struct prefix
));
561 listnode_add (rplist
, rprefix
);
567 rtadv_prefix_set (struct zebra_if
*zif
, struct rtadv_prefix
*rp
)
569 struct rtadv_prefix
*rprefix
;
571 rprefix
= rtadv_prefix_get (zif
->rtadv
.AdvPrefixList
, &rp
->prefix
);
573 /* Set parameters. */
574 rprefix
->AdvValidLifetime
= rp
->AdvValidLifetime
;
575 rprefix
->AdvPreferredLifetime
= rp
->AdvPreferredLifetime
;
576 rprefix
->AdvOnLinkFlag
= rp
->AdvOnLinkFlag
;
577 rprefix
->AdvAutonomousFlag
= rp
->AdvAutonomousFlag
;
578 rprefix
->AdvRouterAddressFlag
= rp
->AdvRouterAddressFlag
;
582 rtadv_prefix_reset (struct zebra_if
*zif
, struct rtadv_prefix
*rp
)
584 struct rtadv_prefix
*rprefix
;
586 rprefix
= rtadv_prefix_lookup (zif
->rtadv
.AdvPrefixList
, &rp
->prefix
);
589 listnode_delete (zif
->rtadv
.AdvPrefixList
, (void *) rprefix
);
590 rtadv_prefix_free (rprefix
);
597 DEFUN (ipv6_nd_suppress_ra
,
598 ipv6_nd_suppress_ra_cmd
,
599 "ipv6 nd suppress-ra",
600 "Interface IPv6 config commands\n"
601 "Neighbor discovery\n"
602 "Suppress Router Advertisement\n")
604 struct interface
*ifp
;
605 struct zebra_if
*zif
;
610 if (if_is_loopback (ifp
))
612 vty_out (vty
, "Invalid interface%s", VTY_NEWLINE
);
616 if (zif
->rtadv
.AdvSendAdvertisements
)
618 zif
->rtadv
.AdvSendAdvertisements
= 0;
619 zif
->rtadv
.AdvIntervalTimer
= 0;
620 rtadv
->adv_if_count
--;
622 if_leave_all_router (rtadv
->sock
, ifp
);
624 if (rtadv
->adv_if_count
== 0)
625 rtadv_event (RTADV_STOP
, 0);
631 DEFUN (no_ipv6_nd_suppress_ra
,
632 no_ipv6_nd_suppress_ra_cmd
,
633 "no ipv6 nd suppress-ra",
635 "Interface IPv6 config commands\n"
636 "Neighbor discovery\n"
637 "Suppress Router Advertisement\n")
639 struct interface
*ifp
;
640 struct zebra_if
*zif
;
645 if (if_is_loopback (ifp
))
647 vty_out (vty
, "Invalid interface%s", VTY_NEWLINE
);
651 if (! zif
->rtadv
.AdvSendAdvertisements
)
653 zif
->rtadv
.AdvSendAdvertisements
= 1;
654 zif
->rtadv
.AdvIntervalTimer
= 0;
655 rtadv
->adv_if_count
++;
657 if_join_all_router (rtadv
->sock
, ifp
);
659 if (rtadv
->adv_if_count
== 1)
660 rtadv_event (RTADV_START
, rtadv
->sock
);
666 DEFUN (ipv6_nd_ra_interval_msec
,
667 ipv6_nd_ra_interval_msec_cmd
,
668 "ipv6 nd ra-interval msec MILLISECONDS",
669 "Interface IPv6 config commands\n"
670 "Neighbor discovery\n"
671 "Router Advertisement interval\n"
672 "Router Advertisement interval in milliseconds\n")
675 struct interface
*ifp
;
676 struct zebra_if
*zif
;
678 ifp
= (struct interface
*) vty
->index
;
681 interval
= atoi (argv
[0]);
685 vty_out (vty
, "Invalid Router Advertisement Interval%s", VTY_NEWLINE
);
689 if (zif
->rtadv
.MaxRtrAdvInterval
% 1000)
690 rtadv
->adv_msec_if_count
--;
693 rtadv
->adv_msec_if_count
++;
695 zif
->rtadv
.MaxRtrAdvInterval
= interval
;
696 zif
->rtadv
.MinRtrAdvInterval
= 0.33 * interval
;
697 zif
->rtadv
.AdvIntervalTimer
= 0;
702 DEFUN (ipv6_nd_ra_interval
,
703 ipv6_nd_ra_interval_cmd
,
704 "ipv6 nd ra-interval SECONDS",
705 "Interface IPv6 config commands\n"
706 "Neighbor discovery\n"
707 "Router Advertisement interval\n"
708 "Router Advertisement interval in seconds\n")
711 struct interface
*ifp
;
712 struct zebra_if
*zif
;
714 ifp
= (struct interface
*) vty
->index
;
717 interval
= atoi (argv
[0]);
721 vty_out (vty
, "Invalid Router Advertisement Interval%s", VTY_NEWLINE
);
725 if (zif
->rtadv
.MaxRtrAdvInterval
% 1000)
726 rtadv
->adv_msec_if_count
--;
728 /* convert to milliseconds */
729 interval
= interval
* 1000;
731 zif
->rtadv
.MaxRtrAdvInterval
= interval
;
732 zif
->rtadv
.MinRtrAdvInterval
= 0.33 * interval
;
733 zif
->rtadv
.AdvIntervalTimer
= 0;
738 DEFUN (no_ipv6_nd_ra_interval
,
739 no_ipv6_nd_ra_interval_cmd
,
740 "no ipv6 nd ra-interval",
742 "Interface IPv6 config commands\n"
743 "Neighbor discovery\n"
744 "Router Advertisement interval\n")
746 struct interface
*ifp
;
747 struct zebra_if
*zif
;
749 ifp
= (struct interface
*) vty
->index
;
752 if (zif
->rtadv
.MaxRtrAdvInterval
% 1000)
753 rtadv
->adv_msec_if_count
--;
755 zif
->rtadv
.MaxRtrAdvInterval
= RTADV_MAX_RTR_ADV_INTERVAL
;
756 zif
->rtadv
.MinRtrAdvInterval
= RTADV_MIN_RTR_ADV_INTERVAL
;
757 zif
->rtadv
.AdvIntervalTimer
= zif
->rtadv
.MaxRtrAdvInterval
;
762 DEFUN (ipv6_nd_ra_lifetime
,
763 ipv6_nd_ra_lifetime_cmd
,
764 "ipv6 nd ra-lifetime SECONDS",
765 "Interface IPv6 config commands\n"
766 "Neighbor discovery\n"
768 "Router lifetime in seconds\n")
771 struct interface
*ifp
;
772 struct zebra_if
*zif
;
774 ifp
= (struct interface
*) vty
->index
;
777 lifetime
= atoi (argv
[0]);
779 if (lifetime
< 0 || lifetime
> 0xffff)
781 vty_out (vty
, "Invalid Router Lifetime%s", VTY_NEWLINE
);
785 zif
->rtadv
.AdvDefaultLifetime
= lifetime
;
790 DEFUN (no_ipv6_nd_ra_lifetime
,
791 no_ipv6_nd_ra_lifetime_cmd
,
792 "no ipv6 nd ra-lifetime",
794 "Interface IPv6 config commands\n"
795 "Neighbor discovery\n"
798 struct interface
*ifp
;
799 struct zebra_if
*zif
;
801 ifp
= (struct interface
*) vty
->index
;
804 zif
->rtadv
.AdvDefaultLifetime
= RTADV_ADV_DEFAULT_LIFETIME
;
809 DEFUN (ipv6_nd_reachable_time
,
810 ipv6_nd_reachable_time_cmd
,
811 "ipv6 nd reachable-time MILLISECONDS",
812 "Interface IPv6 config commands\n"
813 "Neighbor discovery\n"
815 "Reachable time in milliseconds\n")
818 struct interface
*ifp
;
819 struct zebra_if
*zif
;
821 ifp
= (struct interface
*) vty
->index
;
824 rtime
= (u_int32_t
) atol (argv
[0]);
826 if (rtime
> RTADV_MAX_REACHABLE_TIME
)
828 vty_out (vty
, "Invalid Reachable time%s", VTY_NEWLINE
);
832 zif
->rtadv
.AdvReachableTime
= rtime
;
837 DEFUN (no_ipv6_nd_reachable_time
,
838 no_ipv6_nd_reachable_time_cmd
,
839 "no ipv6 nd reachable-time",
841 "Interface IPv6 config commands\n"
842 "Neighbor discovery\n"
845 struct interface
*ifp
;
846 struct zebra_if
*zif
;
848 ifp
= (struct interface
*) vty
->index
;
851 zif
->rtadv
.AdvReachableTime
= 0;
856 DEFUN (ipv6_nd_homeagent_preference
,
857 ipv6_nd_homeagent_preference_cmd
,
858 "ipv6 nd home-agent-preference PREFERENCE",
859 "Interface IPv6 config commands\n"
860 "Neighbor discovery\n"
861 "Home Agent preference\n"
862 "Home Agent preference value 0..65535\n")
865 struct interface
*ifp
;
866 struct zebra_if
*zif
;
868 ifp
= (struct interface
*) vty
->index
;
871 hapref
= (u_int32_t
) atol (argv
[0]);
875 vty_out (vty
, "Invalid Home Agent preference%s", VTY_NEWLINE
);
879 zif
->rtadv
.HomeAgentPreference
= hapref
;
884 DEFUN (no_ipv6_nd_homeagent_preference
,
885 no_ipv6_nd_homeagent_preference_cmd
,
886 "no ipv6 nd home-agent-preference",
888 "Interface IPv6 config commands\n"
889 "Neighbor discovery\n"
890 "Home Agent preference\n")
892 struct interface
*ifp
;
893 struct zebra_if
*zif
;
895 ifp
= (struct interface
*) vty
->index
;
898 zif
->rtadv
.HomeAgentPreference
= 0;
903 DEFUN (ipv6_nd_homeagent_lifetime
,
904 ipv6_nd_homeagent_lifetime_cmd
,
905 "ipv6 nd home-agent-lifetime SECONDS",
906 "Interface IPv6 config commands\n"
907 "Neighbor discovery\n"
908 "Home Agent lifetime\n"
909 "Home Agent lifetime in seconds\n")
912 struct interface
*ifp
;
913 struct zebra_if
*zif
;
915 ifp
= (struct interface
*) vty
->index
;
918 ha_ltime
= (u_int32_t
) atol (argv
[0]);
920 if (ha_ltime
> RTADV_MAX_HALIFETIME
)
922 vty_out (vty
, "Invalid Home Agent Lifetime time%s", VTY_NEWLINE
);
926 zif
->rtadv
.HomeAgentLifetime
= ha_ltime
;
931 DEFUN (no_ipv6_nd_homeagent_lifetime
,
932 no_ipv6_nd_homeagent_lifetime_cmd
,
933 "no ipv6 nd home-agent-lifetime",
935 "Interface IPv6 config commands\n"
936 "Neighbor discovery\n"
937 "Home Agent lifetime\n")
939 struct interface
*ifp
;
940 struct zebra_if
*zif
;
942 ifp
= (struct interface
*) vty
->index
;
945 zif
->rtadv
.HomeAgentLifetime
= 0;
950 DEFUN (ipv6_nd_managed_config_flag
,
951 ipv6_nd_managed_config_flag_cmd
,
952 "ipv6 nd managed-config-flag",
953 "Interface IPv6 config commands\n"
954 "Neighbor discovery\n"
955 "Managed address configuration flag\n")
957 struct interface
*ifp
;
958 struct zebra_if
*zif
;
960 ifp
= (struct interface
*) vty
->index
;
963 zif
->rtadv
.AdvManagedFlag
= 1;
968 DEFUN (no_ipv6_nd_managed_config_flag
,
969 no_ipv6_nd_managed_config_flag_cmd
,
970 "no ipv6 nd managed-config-flag",
972 "Interface IPv6 config commands\n"
973 "Neighbor discovery\n"
974 "Managed address configuration flag\n")
976 struct interface
*ifp
;
977 struct zebra_if
*zif
;
979 ifp
= (struct interface
*) vty
->index
;
982 zif
->rtadv
.AdvManagedFlag
= 0;
987 DEFUN (ipv6_nd_homeagent_config_flag
,
988 ipv6_nd_homeagent_config_flag_cmd
,
989 "ipv6 nd home-agent-config-flag",
990 "Interface IPv6 config commands\n"
991 "Neighbor discovery\n"
992 "Home Agent configuration flag\n")
994 struct interface
*ifp
;
995 struct zebra_if
*zif
;
997 ifp
= (struct interface
*) vty
->index
;
1000 zif
->rtadv
.AdvHomeAgentFlag
= 1;
1005 DEFUN (no_ipv6_nd_homeagent_config_flag
,
1006 no_ipv6_nd_homeagent_config_flag_cmd
,
1007 "no ipv6 nd home-agent-config-flag",
1009 "Interface IPv6 config commands\n"
1010 "Neighbor discovery\n"
1011 "Home Agent configuration flag\n")
1013 struct interface
*ifp
;
1014 struct zebra_if
*zif
;
1016 ifp
= (struct interface
*) vty
->index
;
1019 zif
->rtadv
.AdvHomeAgentFlag
= 0;
1024 DEFUN (ipv6_nd_adv_interval_config_option
,
1025 ipv6_nd_adv_interval_config_option_cmd
,
1026 "ipv6 nd adv-interval-option",
1027 "Interface IPv6 config commands\n"
1028 "Neighbor discovery\n"
1029 "Advertisement Interval Option\n")
1031 struct interface
*ifp
;
1032 struct zebra_if
*zif
;
1034 ifp
= (struct interface
*) vty
->index
;
1037 zif
->rtadv
.AdvIntervalOption
= 1;
1042 DEFUN (no_ipv6_nd_adv_interval_config_option
,
1043 no_ipv6_nd_adv_interval_config_option_cmd
,
1044 "no ipv6 nd adv-interval-option",
1046 "Interface IPv6 config commands\n"
1047 "Neighbor discovery\n"
1048 "Advertisement Interval Option\n")
1050 struct interface
*ifp
;
1051 struct zebra_if
*zif
;
1053 ifp
= (struct interface
*) vty
->index
;
1056 zif
->rtadv
.AdvIntervalOption
= 0;
1061 DEFUN (ipv6_nd_other_config_flag
,
1062 ipv6_nd_other_config_flag_cmd
,
1063 "ipv6 nd other-config-flag",
1064 "Interface IPv6 config commands\n"
1065 "Neighbor discovery\n"
1066 "Other statefull configuration flag\n")
1068 struct interface
*ifp
;
1069 struct zebra_if
*zif
;
1071 ifp
= (struct interface
*) vty
->index
;
1074 zif
->rtadv
.AdvOtherConfigFlag
= 1;
1079 DEFUN (no_ipv6_nd_other_config_flag
,
1080 no_ipv6_nd_other_config_flag_cmd
,
1081 "no ipv6 nd other-config-flag",
1083 "Interface IPv6 config commands\n"
1084 "Neighbor discovery\n"
1085 "Other statefull configuration flag\n")
1087 struct interface
*ifp
;
1088 struct zebra_if
*zif
;
1090 ifp
= (struct interface
*) vty
->index
;
1093 zif
->rtadv
.AdvOtherConfigFlag
= 0;
1098 DEFUN (ipv6_nd_prefix
,
1100 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1101 "(<0-4294967295>|infinite) (off-link|) (no-autoconfig|) (router-address|)",
1102 "Interface IPv6 config commands\n"
1103 "Neighbor discovery\n"
1104 "Prefix information\n"
1106 "Valid lifetime in seconds\n"
1107 "Infinite valid lifetime\n"
1108 "Preferred lifetime in seconds\n"
1109 "Infinite preferred lifetime\n"
1110 "Do not use prefix for onlink determination\n"
1111 "Do not use prefix for autoconfiguration\n"
1112 "Set Router Address flag\n")
1117 struct interface
*ifp
;
1118 struct zebra_if
*zebra_if
;
1119 struct rtadv_prefix rp
;
1121 ifp
= (struct interface
*) vty
->index
;
1122 zebra_if
= ifp
->info
;
1124 ret
= str2prefix_ipv6 (argv
[0], (struct prefix_ipv6
*) &rp
.prefix
);
1127 vty_out (vty
, "Malformed IPv6 prefix%s", VTY_NEWLINE
);
1130 rp
.AdvOnLinkFlag
= 1;
1131 rp
.AdvAutonomousFlag
= 1;
1132 rp
.AdvRouterAddressFlag
= 0;
1133 rp
.AdvValidLifetime
= RTADV_VALID_LIFETIME
;
1134 rp
.AdvPreferredLifetime
= RTADV_PREFERRED_LIFETIME
;
1138 if ((isdigit(argv
[1][0])) || strncmp (argv
[1], "i", 1) == 0)
1140 if ( strncmp (argv
[1], "i", 1) == 0)
1141 rp
.AdvValidLifetime
= UINT32_MAX
;
1143 rp
.AdvValidLifetime
= (u_int32_t
) strtoll (argv
[1],
1146 if ( strncmp (argv
[2], "i", 1) == 0)
1147 rp
.AdvPreferredLifetime
= UINT32_MAX
;
1149 rp
.AdvPreferredLifetime
= (u_int32_t
) strtoll (argv
[2],
1152 if (rp
.AdvPreferredLifetime
> rp
.AdvValidLifetime
)
1154 vty_out (vty
, "Invalid preferred lifetime%s", VTY_NEWLINE
);
1157 cursor
= cursor
+ 2;
1161 for (i
= cursor
; i
< argc
; i
++)
1163 if (strncmp (argv
[i
], "of", 2) == 0)
1164 rp
.AdvOnLinkFlag
= 0;
1165 if (strncmp (argv
[i
], "no", 2) == 0)
1166 rp
.AdvAutonomousFlag
= 0;
1167 if (strncmp (argv
[i
], "ro", 2) == 0)
1168 rp
.AdvRouterAddressFlag
= 1;
1173 rtadv_prefix_set (zebra_if
, &rp
);
1178 ALIAS (ipv6_nd_prefix
,
1179 ipv6_nd_prefix_val_nortaddr_cmd
,
1180 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1181 "(<0-4294967295>|infinite) (off-link|) (no-autoconfig|)",
1182 "Interface IPv6 config commands\n"
1183 "Neighbor discovery\n"
1184 "Prefix information\n"
1186 "Valid lifetime in seconds\n"
1187 "Infinite valid lifetime\n"
1188 "Preferred lifetime in seconds\n"
1189 "Infinite preferred lifetime\n"
1190 "Do not use prefix for onlink determination\n"
1191 "Do not use prefix for autoconfiguration\n")
1193 ALIAS (ipv6_nd_prefix
,
1194 ipv6_nd_prefix_val_rev_cmd
,
1195 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1196 "(<0-4294967295>|infinite) (no-autoconfig|) (off-link|)",
1197 "Interface IPv6 config commands\n"
1198 "Neighbor discovery\n"
1199 "Prefix information\n"
1201 "Valid lifetime in seconds\n"
1202 "Infinite valid lifetime\n"
1203 "Preferred lifetime in seconds\n"
1204 "Infinite preferred lifetime\n"
1205 "Do not use prefix for autoconfiguration\n"
1206 "Do not use prefix for onlink determination\n")
1208 ALIAS (ipv6_nd_prefix
,
1209 ipv6_nd_prefix_val_rev_rtaddr_cmd
,
1210 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1211 "(<0-4294967295>|infinite) (no-autoconfig|) (off-link|) (router-address|)",
1212 "Interface IPv6 config commands\n"
1213 "Neighbor discovery\n"
1214 "Prefix information\n"
1216 "Valid lifetime in seconds\n"
1217 "Infinite valid lifetime\n"
1218 "Preferred lifetime in seconds\n"
1219 "Infinite preferred lifetime\n"
1220 "Do not use prefix for autoconfiguration\n"
1221 "Do not use prefix for onlink determination\n"
1222 "Set Router Address flag\n")
1224 ALIAS (ipv6_nd_prefix
,
1225 ipv6_nd_prefix_val_noauto_cmd
,
1226 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1227 "(<0-4294967295>|infinite) (no-autoconfig|)",
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")
1238 ALIAS (ipv6_nd_prefix
,
1239 ipv6_nd_prefix_val_offlink_cmd
,
1240 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1241 "(<0-4294967295>|infinite) (off-link|)",
1242 "Interface IPv6 config commands\n"
1243 "Neighbor discovery\n"
1244 "Prefix information\n"
1246 "Valid lifetime in seconds\n"
1247 "Infinite valid lifetime\n"
1248 "Preferred lifetime in seconds\n"
1249 "Infinite preferred lifetime\n"
1250 "Do not use prefix for onlink determination\n")
1252 ALIAS (ipv6_nd_prefix
,
1253 ipv6_nd_prefix_val_rtaddr_cmd
,
1254 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1255 "(<0-4294967295>|infinite) (router-address|)",
1256 "Interface IPv6 config commands\n"
1257 "Neighbor discovery\n"
1258 "Prefix information\n"
1260 "Valid lifetime in seconds\n"
1261 "Infinite valid lifetime\n"
1262 "Preferred lifetime in seconds\n"
1263 "Infinite preferred lifetime\n"
1264 "Set Router Address flag\n")
1266 ALIAS (ipv6_nd_prefix
,
1267 ipv6_nd_prefix_val_cmd
,
1268 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1269 "(<0-4294967295>|infinite)",
1270 "Interface IPv6 config commands\n"
1271 "Neighbor discovery\n"
1272 "Prefix information\n"
1274 "Valid lifetime in seconds\n"
1275 "Infinite valid lifetime\n"
1276 "Preferred lifetime in seconds\n"
1277 "Infinite preferred lifetime\n")
1279 ALIAS (ipv6_nd_prefix
,
1280 ipv6_nd_prefix_noval_cmd
,
1281 "ipv6 nd prefix X:X::X:X/M (no-autoconfig|) (off-link|)",
1282 "Interface IPv6 config commands\n"
1283 "Neighbor discovery\n"
1284 "Prefix information\n"
1286 "Do not use prefix for autoconfiguration\n"
1287 "Do not use prefix for onlink determination\n")
1289 ALIAS (ipv6_nd_prefix
,
1290 ipv6_nd_prefix_noval_rev_cmd
,
1291 "ipv6 nd prefix X:X::X:X/M (off-link|) (no-autoconfig|)",
1292 "Interface IPv6 config commands\n"
1293 "Neighbor discovery\n"
1294 "Prefix information\n"
1296 "Do not use prefix for onlink determination\n"
1297 "Do not use prefix for autoconfiguration\n")
1299 ALIAS (ipv6_nd_prefix
,
1300 ipv6_nd_prefix_noval_noauto_cmd
,
1301 "ipv6 nd prefix X:X::X:X/M (no-autoconfig|)",
1302 "Interface IPv6 config commands\n"
1303 "Neighbor discovery\n"
1304 "Prefix information\n"
1306 "Do not use prefix for autoconfiguration\n")
1308 ALIAS (ipv6_nd_prefix
,
1309 ipv6_nd_prefix_noval_offlink_cmd
,
1310 "ipv6 nd prefix X:X::X:X/M (off-link|)",
1311 "Interface IPv6 config commands\n"
1312 "Neighbor discovery\n"
1313 "Prefix information\n"
1315 "Do not use prefix for onlink determination\n")
1317 ALIAS (ipv6_nd_prefix
,
1318 ipv6_nd_prefix_noval_rtaddr_cmd
,
1319 "ipv6 nd prefix X:X::X:X/M (router-address|)",
1320 "Interface IPv6 config commands\n"
1321 "Neighbor discovery\n"
1322 "Prefix information\n"
1324 "Set Router Address flag\n")
1326 ALIAS (ipv6_nd_prefix
,
1327 ipv6_nd_prefix_prefix_cmd
,
1328 "ipv6 nd prefix X:X::X:X/M",
1329 "Interface IPv6 config commands\n"
1330 "Neighbor discovery\n"
1331 "Prefix information\n"
1334 DEFUN (no_ipv6_nd_prefix
,
1335 no_ipv6_nd_prefix_cmd
,
1336 "no ipv6 nd prefix IPV6PREFIX",
1338 "Interface IPv6 config commands\n"
1339 "Neighbor discovery\n"
1340 "Prefix information\n"
1344 struct interface
*ifp
;
1345 struct zebra_if
*zebra_if
;
1346 struct rtadv_prefix rp
;
1348 ifp
= (struct interface
*) vty
->index
;
1349 zebra_if
= ifp
->info
;
1351 ret
= str2prefix_ipv6 (argv
[0], (struct prefix_ipv6
*) &rp
.prefix
);
1354 vty_out (vty
, "Malformed IPv6 prefix%s", VTY_NEWLINE
);
1358 ret
= rtadv_prefix_reset (zebra_if
, &rp
);
1361 vty_out (vty
, "Non-exist IPv6 prefix%s", VTY_NEWLINE
);
1367 /* Write configuration about router advertisement. */
1369 rtadv_config_write (struct vty
*vty
, struct interface
*ifp
)
1371 struct zebra_if
*zif
;
1372 struct listnode
*node
;
1373 struct rtadv_prefix
*rprefix
;
1374 u_char buf
[INET6_ADDRSTRLEN
];
1382 if (! if_is_loopback (ifp
))
1384 if (zif
->rtadv
.AdvSendAdvertisements
)
1385 vty_out (vty
, " no ipv6 nd suppress-ra%s", VTY_NEWLINE
);
1387 vty_out (vty
, " ipv6 nd suppress-ra%s", VTY_NEWLINE
);
1391 interval
= zif
->rtadv
.MaxRtrAdvInterval
;
1392 if (interval
% 1000)
1393 vty_out (vty
, " ipv6 nd ra-interval msec %d%s", interval
,
1396 if (interval
!= RTADV_MAX_RTR_ADV_INTERVAL
)
1397 vty_out (vty
, " ipv6 nd ra-interval %d%s", interval
/ 1000,
1400 if (zif
->rtadv
.AdvDefaultLifetime
!= RTADV_ADV_DEFAULT_LIFETIME
)
1401 vty_out (vty
, " ipv6 nd ra-lifetime %d%s", zif
->rtadv
.AdvDefaultLifetime
,
1404 if (zif
->rtadv
.AdvReachableTime
)
1405 vty_out (vty
, " ipv6 nd reachable-time %d%s", zif
->rtadv
.AdvReachableTime
,
1408 if (zif
->rtadv
.AdvManagedFlag
)
1409 vty_out (vty
, " ipv6 nd managed-config-flag%s", VTY_NEWLINE
);
1411 if (zif
->rtadv
.AdvOtherConfigFlag
)
1412 vty_out (vty
, " ipv6 nd other-config-flag%s", VTY_NEWLINE
);
1414 for (ALL_LIST_ELEMENTS_RO (zif
->rtadv
.AdvPrefixList
, node
, rprefix
))
1416 vty_out (vty
, " ipv6 nd prefix %s/%d",
1417 inet_ntop (AF_INET6
, &rprefix
->prefix
.u
.prefix6
,
1418 (char *) buf
, INET6_ADDRSTRLEN
),
1419 rprefix
->prefix
.prefixlen
);
1420 if ((rprefix
->AdvValidLifetime
!= RTADV_VALID_LIFETIME
) ||
1421 (rprefix
->AdvPreferredLifetime
!= RTADV_PREFERRED_LIFETIME
))
1423 if (rprefix
->AdvValidLifetime
== UINT32_MAX
)
1424 vty_out (vty
, " infinite");
1426 vty_out (vty
, " %u", rprefix
->AdvValidLifetime
);
1427 if (rprefix
->AdvPreferredLifetime
== UINT32_MAX
)
1428 vty_out (vty
, " infinite");
1430 vty_out (vty
, " %u", rprefix
->AdvPreferredLifetime
);
1432 if (!rprefix
->AdvOnLinkFlag
)
1433 vty_out (vty
, " off-link");
1434 if (!rprefix
->AdvAutonomousFlag
)
1435 vty_out (vty
, " no-autoconfig");
1436 if (rprefix
->AdvRouterAddressFlag
)
1437 vty_out (vty
, " router-address");
1438 vty_out (vty
, "%s", VTY_NEWLINE
);
1444 rtadv_event (enum rtadv_event event
, int val
)
1449 if (! rtadv
->ra_read
)
1450 rtadv
->ra_read
= thread_add_read (zebrad
.master
, rtadv_read
, NULL
, val
);
1451 if (! rtadv
->ra_timer
)
1452 rtadv
->ra_timer
= thread_add_event (zebrad
.master
, rtadv_timer
,
1456 if (rtadv
->ra_timer
)
1458 thread_cancel (rtadv
->ra_timer
);
1459 rtadv
->ra_timer
= NULL
;
1463 thread_cancel (rtadv
->ra_read
);
1464 rtadv
->ra_read
= NULL
;
1468 if (! rtadv
->ra_timer
)
1469 rtadv
->ra_timer
= thread_add_timer (zebrad
.master
, rtadv_timer
, NULL
,
1472 case RTADV_TIMER_MSEC
:
1473 if (! rtadv
->ra_timer
)
1474 rtadv
->ra_timer
= thread_add_timer_msec (zebrad
.master
, rtadv_timer
,
1478 if (! rtadv
->ra_read
)
1479 rtadv
->ra_read
= thread_add_read (zebrad
.master
, rtadv_read
, NULL
, val
);
1492 sock
= rtadv_make_socket ();
1496 rtadv
= rtadv_new ();
1499 install_element (INTERFACE_NODE
, &ipv6_nd_suppress_ra_cmd
);
1500 install_element (INTERFACE_NODE
, &no_ipv6_nd_suppress_ra_cmd
);
1501 install_element (INTERFACE_NODE
, &ipv6_nd_ra_interval_cmd
);
1502 install_element (INTERFACE_NODE
, &ipv6_nd_ra_interval_msec_cmd
);
1503 install_element (INTERFACE_NODE
, &no_ipv6_nd_ra_interval_cmd
);
1504 install_element (INTERFACE_NODE
, &ipv6_nd_ra_lifetime_cmd
);
1505 install_element (INTERFACE_NODE
, &no_ipv6_nd_ra_lifetime_cmd
);
1506 install_element (INTERFACE_NODE
, &ipv6_nd_reachable_time_cmd
);
1507 install_element (INTERFACE_NODE
, &no_ipv6_nd_reachable_time_cmd
);
1508 install_element (INTERFACE_NODE
, &ipv6_nd_managed_config_flag_cmd
);
1509 install_element (INTERFACE_NODE
, &no_ipv6_nd_managed_config_flag_cmd
);
1510 install_element (INTERFACE_NODE
, &ipv6_nd_other_config_flag_cmd
);
1511 install_element (INTERFACE_NODE
, &no_ipv6_nd_other_config_flag_cmd
);
1512 install_element (INTERFACE_NODE
, &ipv6_nd_homeagent_config_flag_cmd
);
1513 install_element (INTERFACE_NODE
, &no_ipv6_nd_homeagent_config_flag_cmd
);
1514 install_element (INTERFACE_NODE
, &ipv6_nd_homeagent_preference_cmd
);
1515 install_element (INTERFACE_NODE
, &no_ipv6_nd_homeagent_preference_cmd
);
1516 install_element (INTERFACE_NODE
, &ipv6_nd_homeagent_lifetime_cmd
);
1517 install_element (INTERFACE_NODE
, &no_ipv6_nd_homeagent_lifetime_cmd
);
1518 install_element (INTERFACE_NODE
, &ipv6_nd_adv_interval_config_option_cmd
);
1519 install_element (INTERFACE_NODE
, &no_ipv6_nd_adv_interval_config_option_cmd
);
1520 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_cmd
);
1521 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_val_rev_rtaddr_cmd
);
1522 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_val_nortaddr_cmd
);
1523 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_val_rev_cmd
);
1524 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_val_noauto_cmd
);
1525 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_val_offlink_cmd
);
1526 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_val_rtaddr_cmd
);
1527 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_val_cmd
);
1528 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_noval_cmd
);
1529 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_noval_rev_cmd
);
1530 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_noval_noauto_cmd
);
1531 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_noval_offlink_cmd
);
1532 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_noval_rtaddr_cmd
);
1533 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_prefix_cmd
);
1534 install_element (INTERFACE_NODE
, &no_ipv6_nd_prefix_cmd
);
1538 if_join_all_router (int sock
, struct interface
*ifp
)
1542 struct ipv6_mreq mreq
;
1544 memset (&mreq
, 0, sizeof (struct ipv6_mreq
));
1545 inet_pton (AF_INET6
, ALLROUTER
, &mreq
.ipv6mr_multiaddr
);
1546 mreq
.ipv6mr_interface
= ifp
->ifindex
;
1548 ret
= setsockopt (sock
, IPPROTO_IPV6
, IPV6_JOIN_GROUP
,
1549 (char *) &mreq
, sizeof mreq
);
1551 zlog_warn ("can't setsockopt IPV6_JOIN_GROUP: %s", safe_strerror (errno
));
1553 zlog_info ("rtadv: %s join to all-routers multicast group", ifp
->name
);
1559 if_leave_all_router (int sock
, struct interface
*ifp
)
1563 struct ipv6_mreq mreq
;
1565 memset (&mreq
, 0, sizeof (struct ipv6_mreq
));
1566 inet_pton (AF_INET6
, ALLROUTER
, &mreq
.ipv6mr_multiaddr
);
1567 mreq
.ipv6mr_interface
= ifp
->ifindex
;
1569 ret
= setsockopt (sock
, IPPROTO_IPV6
, IPV6_LEAVE_GROUP
,
1570 (char *) &mreq
, sizeof mreq
);
1572 zlog_warn ("can't setsockopt IPV6_LEAVE_GROUP: %s", safe_strerror (errno
));
1574 zlog_info ("rtadv: %s leave from all-routers multicast group", ifp
->name
);
1585 #endif /* RTADV && HAVE_IPV6 */