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
36 #include "zebra/interface.h"
37 #include "zebra/rtadv.h"
38 #include "zebra/debug.h"
39 #include "zebra/rib.h"
40 #include "zebra/zserv.h"
42 extern struct zebra_privs_t zserv_privs
;
44 #if defined (HAVE_IPV6) && defined (HAVE_RTADV)
47 #include <netinet/icmp6.h>
50 /* If RFC2133 definition is used. */
51 #ifndef IPV6_JOIN_GROUP
52 #define IPV6_JOIN_GROUP IPV6_ADD_MEMBERSHIP
54 #ifndef IPV6_LEAVE_GROUP
55 #define IPV6_LEAVE_GROUP IPV6_DROP_MEMBERSHIP
58 #define ALLNODE "ff02::1"
59 #define ALLROUTER "ff02::2"
61 extern struct zebra_t zebrad
;
63 enum rtadv_event
{RTADV_START
, RTADV_STOP
, RTADV_TIMER
,
64 RTADV_TIMER_MSEC
, RTADV_READ
};
66 static void rtadv_event (struct zebra_ns
*, enum rtadv_event
, int);
68 static int if_join_all_router (int, struct interface
*);
69 static int if_leave_all_router (int, struct interface
*);
72 rtadv_recv_packet (int sock
, u_char
*buf
, int buflen
,
73 struct sockaddr_in6
*from
, unsigned int *ifindex
,
79 struct cmsghdr
*cmsgptr
;
84 /* Fill in message and iovec. */
85 msg
.msg_name
= (void *) from
;
86 msg
.msg_namelen
= sizeof (struct sockaddr_in6
);
89 msg
.msg_control
= (void *) adata
;
90 msg
.msg_controllen
= sizeof adata
;
94 /* If recvmsg fail return minus value. */
95 ret
= recvmsg (sock
, &msg
, 0);
99 for (cmsgptr
= ZCMSG_FIRSTHDR(&msg
); cmsgptr
!= NULL
;
100 cmsgptr
= CMSG_NXTHDR(&msg
, cmsgptr
))
102 /* I want interface index which this packet comes from. */
103 if (cmsgptr
->cmsg_level
== IPPROTO_IPV6
&&
104 cmsgptr
->cmsg_type
== IPV6_PKTINFO
)
106 struct in6_pktinfo
*ptr
;
108 ptr
= (struct in6_pktinfo
*) CMSG_DATA (cmsgptr
);
109 *ifindex
= ptr
->ipi6_ifindex
;
110 memcpy(&dst
, &ptr
->ipi6_addr
, sizeof(ptr
->ipi6_addr
));
113 /* Incoming packet's hop limit. */
114 if (cmsgptr
->cmsg_level
== IPPROTO_IPV6
&&
115 cmsgptr
->cmsg_type
== IPV6_HOPLIMIT
)
117 int *hoptr
= (int *) CMSG_DATA (cmsgptr
);
124 #define RTADV_MSG_SIZE 4096
126 /* Send router advertisement packet. */
128 rtadv_send_packet (int sock
, struct interface
*ifp
)
132 struct cmsghdr
*cmsgptr
;
133 struct in6_pktinfo
*pkt
;
134 struct sockaddr_in6 addr
;
135 #ifdef HAVE_STRUCT_SOCKADDR_DL
136 struct sockaddr_dl
*sdl
;
137 #endif /* HAVE_STRUCT_SOCKADDR_DL */
138 static void *adata
= NULL
;
139 unsigned char buf
[RTADV_MSG_SIZE
];
140 struct nd_router_advert
*rtadv
;
143 struct zebra_if
*zif
;
144 struct rtadv_prefix
*rprefix
;
145 u_char all_nodes_addr
[] = {0xff,0x02,0,0,0,0,0,0,0,0,0,0,0,0,0,1};
146 struct listnode
*node
;
147 u_int16_t pkt_RouterLifetime
;
150 * Allocate control message bufffer. This is dynamic because
151 * CMSG_SPACE is not guaranteed not to call a function. Note that
152 * the size will be different on different architectures due to
153 * differing alignment rules.
157 /* XXX Free on shutdown. */
158 adata
= malloc(CMSG_SPACE(sizeof(struct in6_pktinfo
)));
161 zlog_err("rtadv_send_packet: can't malloc control data");
164 /* Logging of packet. */
165 if (IS_ZEBRA_DEBUG_PACKET
)
166 zlog_debug ("%s(%u): Tx RA, socket %u",
167 ifp
->name
, ifp
->ifindex
, sock
);
169 /* Fill in sockaddr_in6. */
170 memset (&addr
, 0, sizeof (struct sockaddr_in6
));
171 addr
.sin6_family
= AF_INET6
;
173 addr
.sin6_len
= sizeof (struct sockaddr_in6
);
174 #endif /* SIN6_LEN */
175 addr
.sin6_port
= htons (IPPROTO_ICMPV6
);
176 IPV6_ADDR_COPY (&addr
.sin6_addr
, all_nodes_addr
);
178 /* Fetch interface information. */
181 /* Make router advertisement message. */
182 rtadv
= (struct nd_router_advert
*) buf
;
184 rtadv
->nd_ra_type
= ND_ROUTER_ADVERT
;
185 rtadv
->nd_ra_code
= 0;
186 rtadv
->nd_ra_cksum
= 0;
188 rtadv
->nd_ra_curhoplimit
= 64;
190 /* RFC4191: Default Router Preference is 0 if Router Lifetime is 0. */
191 rtadv
->nd_ra_flags_reserved
=
192 zif
->rtadv
.AdvDefaultLifetime
== 0 ? 0 : zif
->rtadv
.DefaultPreference
;
193 rtadv
->nd_ra_flags_reserved
<<= 3;
195 if (zif
->rtadv
.AdvManagedFlag
)
196 rtadv
->nd_ra_flags_reserved
|= ND_RA_FLAG_MANAGED
;
197 if (zif
->rtadv
.AdvOtherConfigFlag
)
198 rtadv
->nd_ra_flags_reserved
|= ND_RA_FLAG_OTHER
;
199 if (zif
->rtadv
.AdvHomeAgentFlag
)
200 rtadv
->nd_ra_flags_reserved
|= ND_RA_FLAG_HOME_AGENT
;
201 /* Note that according to Neighbor Discovery (RFC 4861 [18]),
202 * AdvDefaultLifetime is by default based on the value of
203 * MaxRtrAdvInterval. AdvDefaultLifetime is used in the Router Lifetime
204 * field of Router Advertisements. Given that this field is expressed
205 * in seconds, a small MaxRtrAdvInterval value can result in a zero
206 * value for this field. To prevent this, routers SHOULD keep
207 * AdvDefaultLifetime in at least one second, even if the use of
208 * MaxRtrAdvInterval would result in a smaller value. -- RFC6275, 7.5 */
209 pkt_RouterLifetime
= zif
->rtadv
.AdvDefaultLifetime
!= -1 ?
210 zif
->rtadv
.AdvDefaultLifetime
:
211 MAX (1, 0.003 * zif
->rtadv
.MaxRtrAdvInterval
);
212 rtadv
->nd_ra_router_lifetime
= htons (pkt_RouterLifetime
);
213 rtadv
->nd_ra_reachable
= htonl (zif
->rtadv
.AdvReachableTime
);
214 rtadv
->nd_ra_retransmit
= htonl (0);
216 len
= sizeof (struct nd_router_advert
);
218 /* If both the Home Agent Preference and Home Agent Lifetime are set to
219 * their default values specified above, this option SHOULD NOT be
220 * included in the Router Advertisement messages sent by this home
221 * agent. -- RFC6275, 7.4 */
224 zif
->rtadv
.AdvHomeAgentFlag
&&
225 (zif
->rtadv
.HomeAgentPreference
|| zif
->rtadv
.HomeAgentLifetime
!= -1)
228 struct nd_opt_homeagent_info
*ndopt_hai
=
229 (struct nd_opt_homeagent_info
*)(buf
+ len
);
230 ndopt_hai
->nd_opt_hai_type
= ND_OPT_HA_INFORMATION
;
231 ndopt_hai
->nd_opt_hai_len
= 1;
232 ndopt_hai
->nd_opt_hai_reserved
= 0;
233 ndopt_hai
->nd_opt_hai_preference
= htons(zif
->rtadv
.HomeAgentPreference
);
234 /* 16-bit unsigned integer. The lifetime associated with the home
235 * agent in units of seconds. The default value is the same as the
236 * Router Lifetime, as specified in the main body of the Router
237 * Advertisement. The maximum value corresponds to 18.2 hours. A
238 * value of 0 MUST NOT be used. -- RFC6275, 7.5 */
239 ndopt_hai
->nd_opt_hai_lifetime
= htons
241 zif
->rtadv
.HomeAgentLifetime
!= -1 ?
242 zif
->rtadv
.HomeAgentLifetime
:
243 MAX (1, pkt_RouterLifetime
) /* 0 is OK for RL, but not for HAL*/
245 len
+= sizeof(struct nd_opt_homeagent_info
);
248 if (zif
->rtadv
.AdvIntervalOption
)
250 struct nd_opt_adv_interval
*ndopt_adv
=
251 (struct nd_opt_adv_interval
*)(buf
+ len
);
252 ndopt_adv
->nd_opt_ai_type
= ND_OPT_ADV_INTERVAL
;
253 ndopt_adv
->nd_opt_ai_len
= 1;
254 ndopt_adv
->nd_opt_ai_reserved
= 0;
255 ndopt_adv
->nd_opt_ai_interval
= htonl(zif
->rtadv
.MaxRtrAdvInterval
);
256 len
+= sizeof(struct nd_opt_adv_interval
);
259 /* Fill in prefix. */
260 for (ALL_LIST_ELEMENTS_RO (zif
->rtadv
.AdvPrefixList
, node
, rprefix
))
262 struct nd_opt_prefix_info
*pinfo
;
264 pinfo
= (struct nd_opt_prefix_info
*) (buf
+ len
);
266 pinfo
->nd_opt_pi_type
= ND_OPT_PREFIX_INFORMATION
;
267 pinfo
->nd_opt_pi_len
= 4;
268 pinfo
->nd_opt_pi_prefix_len
= rprefix
->prefix
.prefixlen
;
270 pinfo
->nd_opt_pi_flags_reserved
= 0;
271 if (rprefix
->AdvOnLinkFlag
)
272 pinfo
->nd_opt_pi_flags_reserved
|= ND_OPT_PI_FLAG_ONLINK
;
273 if (rprefix
->AdvAutonomousFlag
)
274 pinfo
->nd_opt_pi_flags_reserved
|= ND_OPT_PI_FLAG_AUTO
;
275 if (rprefix
->AdvRouterAddressFlag
)
276 pinfo
->nd_opt_pi_flags_reserved
|= ND_OPT_PI_FLAG_RADDR
;
278 pinfo
->nd_opt_pi_valid_time
= htonl (rprefix
->AdvValidLifetime
);
279 pinfo
->nd_opt_pi_preferred_time
= htonl (rprefix
->AdvPreferredLifetime
);
280 pinfo
->nd_opt_pi_reserved2
= 0;
282 IPV6_ADDR_COPY (&pinfo
->nd_opt_pi_prefix
, &rprefix
->prefix
.prefix
);
286 u_char buf
[INET6_ADDRSTRLEN
];
288 zlog_debug ("DEBUG %s", inet_ntop (AF_INET6
, &pinfo
->nd_opt_pi_prefix
,
289 buf
, INET6_ADDRSTRLEN
));
294 len
+= sizeof (struct nd_opt_prefix_info
);
297 /* Hardware address. */
298 #ifdef HAVE_STRUCT_SOCKADDR_DL
300 if (sdl
!= NULL
&& sdl
->sdl_alen
!= 0)
302 buf
[len
++] = ND_OPT_SOURCE_LINKADDR
;
304 /* Option length should be rounded up to next octet if
305 the link address does not end on an octet boundary. */
306 buf
[len
++] = (sdl
->sdl_alen
+ 9) >> 3;
308 memcpy (buf
+ len
, LLADDR (sdl
), sdl
->sdl_alen
);
309 len
+= sdl
->sdl_alen
;
311 /* Pad option to end on an octet boundary. */
312 memset (buf
+ len
, 0, -(sdl
->sdl_alen
+ 2) & 0x7);
313 len
+= -(sdl
->sdl_alen
+ 2) & 0x7;
316 if (ifp
->hw_addr_len
!= 0)
318 buf
[len
++] = ND_OPT_SOURCE_LINKADDR
;
320 /* Option length should be rounded up to next octet if
321 the link address does not end on an octet boundary. */
322 buf
[len
++] = (ifp
->hw_addr_len
+ 9) >> 3;
324 memcpy (buf
+ len
, ifp
->hw_addr
, ifp
->hw_addr_len
);
325 len
+= ifp
->hw_addr_len
;
327 /* Pad option to end on an octet boundary. */
328 memset (buf
+ len
, 0, -(ifp
->hw_addr_len
+ 2) & 0x7);
329 len
+= -(ifp
->hw_addr_len
+ 2) & 0x7;
331 #endif /* HAVE_STRUCT_SOCKADDR_DL */
334 if (zif
->rtadv
.AdvLinkMTU
)
336 struct nd_opt_mtu
* opt
= (struct nd_opt_mtu
*) (buf
+ len
);
337 opt
->nd_opt_mtu_type
= ND_OPT_MTU
;
338 opt
->nd_opt_mtu_len
= 1;
339 opt
->nd_opt_mtu_reserved
= 0;
340 opt
->nd_opt_mtu_mtu
= htonl (zif
->rtadv
.AdvLinkMTU
);
341 len
+= sizeof (struct nd_opt_mtu
);
344 msg
.msg_name
= (void *) &addr
;
345 msg
.msg_namelen
= sizeof (struct sockaddr_in6
);
348 msg
.msg_control
= (void *) adata
;
349 msg
.msg_controllen
= CMSG_SPACE(sizeof(struct in6_pktinfo
));
354 cmsgptr
= ZCMSG_FIRSTHDR(&msg
);
355 cmsgptr
->cmsg_len
= CMSG_LEN(sizeof(struct in6_pktinfo
));
356 cmsgptr
->cmsg_level
= IPPROTO_IPV6
;
357 cmsgptr
->cmsg_type
= IPV6_PKTINFO
;
359 pkt
= (struct in6_pktinfo
*) CMSG_DATA (cmsgptr
);
360 memset (&pkt
->ipi6_addr
, 0, sizeof (struct in6_addr
));
361 pkt
->ipi6_ifindex
= ifp
->ifindex
;
363 ret
= sendmsg (sock
, &msg
, 0);
366 zlog_err ("%s(%u): Tx RA failed, socket %u error %d (%s)",
367 ifp
->name
, ifp
->ifindex
, sock
, errno
, safe_strerror(errno
));
372 rtadv_timer (struct thread
*thread
)
374 struct zebra_ns
*zns
= THREAD_ARG (thread
);
376 struct listnode
*node
, *nnode
;
377 struct interface
*ifp
;
378 struct zebra_if
*zif
;
381 zns
->rtadv
.ra_timer
= NULL
;
382 if (zns
->rtadv
.adv_msec_if_count
== 0)
384 period
= 1000; /* 1 s */
385 rtadv_event (zns
, RTADV_TIMER
, 1 /* 1 s */);
389 period
= 10; /* 10 ms */
390 rtadv_event (zns
, RTADV_TIMER_MSEC
, 10 /* 10 ms */);
393 for (iter
= vrf_first (); iter
!= VRF_ITER_INVALID
; iter
= vrf_next (iter
))
394 for (ALL_LIST_ELEMENTS (vrf_iter2iflist (iter
), node
, nnode
, ifp
))
396 if (if_is_loopback (ifp
) || ! if_is_operative (ifp
))
401 if (zif
->rtadv
.AdvSendAdvertisements
)
403 zif
->rtadv
.AdvIntervalTimer
-= period
;
404 if (zif
->rtadv
.AdvIntervalTimer
<= 0)
406 /* FIXME: using MaxRtrAdvInterval each time isn't what section
407 6.2.4 of RFC4861 tells to do. */
408 zif
->rtadv
.AdvIntervalTimer
= zif
->rtadv
.MaxRtrAdvInterval
;
409 rtadv_send_packet (zns
->rtadv
.sock
, ifp
);
418 rtadv_process_solicit (struct interface
*ifp
)
420 struct zebra_vrf
*zvrf
= vrf_info_lookup (ifp
->vrf_id
);
421 struct zebra_ns
*zns
= zvrf
->zns
;
424 rtadv_send_packet (zns
->rtadv
.sock
, ifp
);
428 rtadv_process_advert (u_char
*msg
, unsigned int len
, struct interface
*ifp
,
429 struct sockaddr_in6
*addr
)
431 struct nd_router_advert
*radvert
;
432 char addr_str
[INET6_ADDRSTRLEN
];
433 struct zebra_if
*zif
;
437 inet_ntop (AF_INET6
, &addr
->sin6_addr
, addr_str
, INET6_ADDRSTRLEN
);
439 if (len
< sizeof(struct nd_router_advert
)) {
440 zlog_warn("%s(%u): Rx RA with invalid length %d from %s",
441 ifp
->name
, ifp
->ifindex
, len
, addr_str
);
444 if (!IN6_IS_ADDR_LINKLOCAL(&addr
->sin6_addr
)) {
445 zlog_warn("%s(%u): Rx RA with non-linklocal source address from %s",
446 ifp
->name
, ifp
->ifindex
, addr_str
);
450 radvert
= (struct nd_router_advert
*) msg
;
452 if ((radvert
->nd_ra_curhoplimit
&& zif
->rtadv
.AdvCurHopLimit
) &&
453 (radvert
->nd_ra_curhoplimit
!= zif
->rtadv
.AdvCurHopLimit
))
455 zlog_warn("%s(%u): Rx RA - our AdvCurHopLimit doesn't agree with %s",
456 ifp
->name
, ifp
->ifindex
, addr_str
);
459 if ((radvert
->nd_ra_flags_reserved
& ND_RA_FLAG_MANAGED
) &&
460 !zif
->rtadv
.AdvManagedFlag
)
462 zlog_warn("%s(%u): Rx RA - our AdvManagedFlag doesn't agree with %s",
463 ifp
->name
, ifp
->ifindex
, addr_str
);
466 if ((radvert
->nd_ra_flags_reserved
& ND_RA_FLAG_OTHER
) &&
467 !zif
->rtadv
.AdvOtherConfigFlag
)
469 zlog_warn("%s(%u): Rx RA - our AdvOtherConfigFlag doesn't agree with %s",
470 ifp
->name
, ifp
->ifindex
, addr_str
);
473 if ((radvert
->nd_ra_reachable
&& zif
->rtadv
.AdvReachableTime
) &&
474 (ntohl(radvert
->nd_ra_reachable
) != zif
->rtadv
.AdvReachableTime
))
476 zlog_warn("%s(%u): Rx RA - our AdvReachableTime doesn't agree with %s",
477 ifp
->name
, ifp
->ifindex
, addr_str
);
480 if ((radvert
->nd_ra_retransmit
&& zif
->rtadv
.AdvRetransTimer
) &&
481 (ntohl(radvert
->nd_ra_retransmit
) != (unsigned int)zif
->rtadv
.AdvRetransTimer
))
483 zlog_warn("%s(%u): Rx RA - our AdvRetransTimer doesn't agree with %s",
484 ifp
->name
, ifp
->ifindex
, addr_str
);
487 /* Currently supporting only P2P links, so any new RA source address is
488 considered as the replacement of the previously learnt Link-Local address.
489 As per the RFC, lifetime zero is to be considered a delete */
490 if (ntohs(radvert
->nd_ra_router_lifetime
))
491 nbr_connected_replacement_add_ipv6(ifp
, &addr
->sin6_addr
, 128);
493 nbr_connected_delete_ipv6(ifp
, &addr
->sin6_addr
, 128);
500 rtadv_process_packet (u_char
*buf
, unsigned int len
, unsigned int ifindex
, int hoplimit
,
501 struct sockaddr_in6
*from
, struct zebra_ns
*zns
)
503 struct icmp6_hdr
*icmph
;
504 struct interface
*ifp
;
505 struct zebra_if
*zif
;
506 char addr_str
[INET6_ADDRSTRLEN
];
508 inet_ntop (AF_INET6
, &from
->sin6_addr
, addr_str
, INET6_ADDRSTRLEN
);
510 /* Interface search. */
511 ifp
= if_lookup_by_index_per_ns (zns
, ifindex
);
514 zlog_warn ("RA/RS received on unknown IF %u from %s",
519 if (IS_ZEBRA_DEBUG_PACKET
)
520 zlog_debug ("%s(%u): Rx RA/RS len %d from %s",
521 ifp
->name
, ifp
->ifindex
, len
, addr_str
);
523 if (if_is_loopback (ifp
))
526 /* Check interface configuration. */
528 if (! zif
->rtadv
.AdvSendAdvertisements
)
531 /* ICMP message length check. */
532 if (len
< sizeof (struct icmp6_hdr
))
534 zlog_warn ("%s(%u): Rx RA with Invalid ICMPV6 packet length %d",
535 ifp
->name
, ifp
->ifindex
, len
);
539 icmph
= (struct icmp6_hdr
*) buf
;
541 /* ICMP message type check. */
542 if (icmph
->icmp6_type
!= ND_ROUTER_SOLICIT
&&
543 icmph
->icmp6_type
!= ND_ROUTER_ADVERT
)
545 zlog_warn ("%s(%u): Rx RA - Unwanted ICMPV6 message type %d",
546 ifp
->name
, ifp
->ifindex
, icmph
->icmp6_type
);
550 /* Hoplimit check. */
551 if (hoplimit
>= 0 && hoplimit
!= 255)
553 zlog_warn ("%s(%u): Rx RA - Invalid hoplimit %d",
554 ifp
->name
, ifp
->ifindex
, hoplimit
);
558 /* Check ICMP message type. */
559 if (icmph
->icmp6_type
== ND_ROUTER_SOLICIT
)
560 rtadv_process_solicit (ifp
);
561 else if (icmph
->icmp6_type
== ND_ROUTER_ADVERT
)
562 rtadv_process_advert (buf
, len
, ifp
, from
);
568 rtadv_read (struct thread
*thread
)
572 u_char buf
[RTADV_MSG_SIZE
];
573 struct sockaddr_in6 from
;
574 unsigned int ifindex
= 0;
576 struct zebra_ns
*zns
= THREAD_ARG (thread
);
578 sock
= THREAD_FD (thread
);
579 zns
->rtadv
.ra_read
= NULL
;
581 /* Register myself. */
582 rtadv_event (zns
, RTADV_READ
, sock
);
584 len
= rtadv_recv_packet (sock
, buf
, BUFSIZ
, &from
, &ifindex
, &hoplimit
);
588 zlog_warn ("RA/RS recv failed, socket %u error %s",
589 sock
, safe_strerror (errno
));
593 rtadv_process_packet (buf
, (unsigned)len
, ifindex
, hoplimit
, &from
, zns
);
599 rtadv_make_socket (void)
603 struct icmp6_filter filter
;
605 if ( zserv_privs
.change (ZPRIVS_RAISE
) )
606 zlog_err ("rtadv_make_socket: could not raise privs, %s",
607 safe_strerror (errno
) );
609 sock
= socket (AF_INET6
, SOCK_RAW
, IPPROTO_ICMPV6
);
611 if ( zserv_privs
.change (ZPRIVS_LOWER
) )
612 zlog_err ("rtadv_make_socket: could not lower privs, %s",
613 safe_strerror (errno
) );
618 ret
= setsockopt_ipv6_pktinfo (sock
, 1);
621 ret
= setsockopt_ipv6_multicast_loop (sock
, 0);
624 ret
= setsockopt_ipv6_unicast_hops (sock
, 255);
627 ret
= setsockopt_ipv6_multicast_hops (sock
, 255);
630 ret
= setsockopt_ipv6_hoplimit (sock
, 1);
634 ICMP6_FILTER_SETBLOCKALL(&filter
);
635 ICMP6_FILTER_SETPASS (ND_ROUTER_SOLICIT
, &filter
);
636 ICMP6_FILTER_SETPASS (ND_ROUTER_ADVERT
, &filter
);
638 ret
= setsockopt (sock
, IPPROTO_ICMPV6
, ICMP6_FILTER
, &filter
,
639 sizeof (struct icmp6_filter
));
642 zlog_info ("ICMP6_FILTER set fail: %s", safe_strerror (errno
));
649 static struct rtadv_prefix
*
650 rtadv_prefix_new (void)
652 return XCALLOC (MTYPE_RTADV_PREFIX
, sizeof (struct rtadv_prefix
));
656 rtadv_prefix_free (struct rtadv_prefix
*rtadv_prefix
)
658 XFREE (MTYPE_RTADV_PREFIX
, rtadv_prefix
);
661 static struct rtadv_prefix
*
662 rtadv_prefix_lookup (struct list
*rplist
, struct prefix_ipv6
*p
)
664 struct listnode
*node
;
665 struct rtadv_prefix
*rprefix
;
667 for (ALL_LIST_ELEMENTS_RO (rplist
, node
, rprefix
))
668 if (prefix_same ((struct prefix
*) &rprefix
->prefix
, (struct prefix
*) p
))
673 static struct rtadv_prefix
*
674 rtadv_prefix_get (struct list
*rplist
, struct prefix_ipv6
*p
)
676 struct rtadv_prefix
*rprefix
;
678 rprefix
= rtadv_prefix_lookup (rplist
, p
);
682 rprefix
= rtadv_prefix_new ();
683 memcpy (&rprefix
->prefix
, p
, sizeof (struct prefix_ipv6
));
684 listnode_add (rplist
, rprefix
);
690 rtadv_prefix_set (struct zebra_if
*zif
, struct rtadv_prefix
*rp
)
692 struct rtadv_prefix
*rprefix
;
694 rprefix
= rtadv_prefix_get (zif
->rtadv
.AdvPrefixList
, &rp
->prefix
);
696 /* Set parameters. */
697 rprefix
->AdvValidLifetime
= rp
->AdvValidLifetime
;
698 rprefix
->AdvPreferredLifetime
= rp
->AdvPreferredLifetime
;
699 rprefix
->AdvOnLinkFlag
= rp
->AdvOnLinkFlag
;
700 rprefix
->AdvAutonomousFlag
= rp
->AdvAutonomousFlag
;
701 rprefix
->AdvRouterAddressFlag
= rp
->AdvRouterAddressFlag
;
705 rtadv_prefix_reset (struct zebra_if
*zif
, struct rtadv_prefix
*rp
)
707 struct rtadv_prefix
*rprefix
;
709 rprefix
= rtadv_prefix_lookup (zif
->rtadv
.AdvPrefixList
, &rp
->prefix
);
712 listnode_delete (zif
->rtadv
.AdvPrefixList
, (void *) rprefix
);
713 rtadv_prefix_free (rprefix
);
721 ipv6_nd_suppress_ra_set (struct interface
*ifp
, ipv6_nd_suppress_ra_status status
)
723 struct zebra_if
*zif
;
724 struct zebra_vrf
*zvrf
;
725 struct zebra_ns
*zns
;
728 zvrf
= vrf_info_lookup (ifp
->vrf_id
);
731 if (status
== RA_SUPPRESS
)
733 /* RA is currently enabled */
734 if (zif
->rtadv
.AdvSendAdvertisements
)
736 zif
->rtadv
.AdvSendAdvertisements
= 0;
737 zif
->rtadv
.AdvIntervalTimer
= 0;
738 zns
->rtadv
.adv_if_count
--;
740 if_leave_all_router (zns
->rtadv
.sock
, ifp
);
742 if (zns
->rtadv
.adv_if_count
== 0)
743 rtadv_event (zns
, RTADV_STOP
, 0);
748 if (! zif
->rtadv
.AdvSendAdvertisements
)
750 zif
->rtadv
.AdvSendAdvertisements
= 1;
751 zif
->rtadv
.AdvIntervalTimer
= 0;
752 zns
->rtadv
.adv_if_count
++;
754 if_join_all_router (zns
->rtadv
.sock
, ifp
);
756 if (zns
->rtadv
.adv_if_count
== 1)
757 rtadv_event (zns
, RTADV_START
, zns
->rtadv
.sock
);
762 DEFUN (ipv6_nd_suppress_ra
,
763 ipv6_nd_suppress_ra_cmd
,
764 "ipv6 nd suppress-ra",
765 "Interface IPv6 config commands\n"
766 "Neighbor discovery\n"
767 "Suppress Router Advertisement\n")
769 struct interface
*ifp
;
773 if (if_is_loopback (ifp
))
775 vty_out (vty
, "Invalid interface%s", VTY_NEWLINE
);
779 ipv6_nd_suppress_ra_set (ifp
, RA_SUPPRESS
);
783 DEFUN (no_ipv6_nd_suppress_ra
,
784 no_ipv6_nd_suppress_ra_cmd
,
785 "no ipv6 nd suppress-ra",
787 "Interface IPv6 config commands\n"
788 "Neighbor discovery\n"
789 "Suppress Router Advertisement\n")
791 struct interface
*ifp
;
795 if (if_is_loopback (ifp
))
797 vty_out (vty
, "Invalid interface%s", VTY_NEWLINE
);
801 ipv6_nd_suppress_ra_set (ifp
, RA_ENABLE
);
805 DEFUN (ipv6_nd_ra_interval_msec
,
806 ipv6_nd_ra_interval_msec_cmd
,
807 "ipv6 nd ra-interval msec <70-1800000>",
808 "Interface IPv6 config commands\n"
809 "Neighbor discovery\n"
810 "Router Advertisement interval\n"
811 "Router Advertisement interval in milliseconds\n")
814 struct interface
*ifp
= (struct interface
*) vty
->index
;
815 struct zebra_if
*zif
= ifp
->info
;
816 struct zebra_vrf
*zvrf
= vrf_info_lookup (ifp
->vrf_id
);
817 struct zebra_ns
*zns
;
820 VTY_GET_INTEGER_RANGE ("router advertisement interval", interval
, argv
[0], 70, 1800000);
821 if ((zif
->rtadv
.AdvDefaultLifetime
!= -1 && interval
> (unsigned)zif
->rtadv
.AdvDefaultLifetime
* 1000))
823 vty_out (vty
, "This ra-interval would conflict with configured ra-lifetime!%s", VTY_NEWLINE
);
827 if (zif
->rtadv
.MaxRtrAdvInterval
% 1000)
828 zns
->rtadv
.adv_msec_if_count
--;
831 zns
->rtadv
.adv_msec_if_count
++;
833 zif
->rtadv
.MaxRtrAdvInterval
= interval
;
834 zif
->rtadv
.MinRtrAdvInterval
= 0.33 * interval
;
835 zif
->rtadv
.AdvIntervalTimer
= 0;
840 DEFUN (ipv6_nd_ra_interval
,
841 ipv6_nd_ra_interval_cmd
,
842 "ipv6 nd ra-interval <1-1800>",
843 "Interface IPv6 config commands\n"
844 "Neighbor discovery\n"
845 "Router Advertisement interval\n"
846 "Router Advertisement interval in seconds\n")
849 struct interface
*ifp
= (struct interface
*) vty
->index
;
850 struct zebra_if
*zif
= ifp
->info
;
851 struct zebra_vrf
*zvrf
= vrf_info_lookup (ifp
->vrf_id
);
852 struct zebra_ns
*zns
;
855 VTY_GET_INTEGER_RANGE ("router advertisement interval", interval
, argv
[0], 1, 1800);
856 if ((zif
->rtadv
.AdvDefaultLifetime
!= -1 && interval
> (unsigned)zif
->rtadv
.AdvDefaultLifetime
))
858 vty_out (vty
, "This ra-interval would conflict with configured ra-lifetime!%s", VTY_NEWLINE
);
862 if (zif
->rtadv
.MaxRtrAdvInterval
% 1000)
863 zns
->rtadv
.adv_msec_if_count
--;
865 /* convert to milliseconds */
866 interval
= interval
* 1000;
868 zif
->rtadv
.MaxRtrAdvInterval
= interval
;
869 zif
->rtadv
.MinRtrAdvInterval
= 0.33 * interval
;
870 zif
->rtadv
.AdvIntervalTimer
= 0;
875 DEFUN (no_ipv6_nd_ra_interval
,
876 no_ipv6_nd_ra_interval_cmd
,
877 "no ipv6 nd ra-interval",
879 "Interface IPv6 config commands\n"
880 "Neighbor discovery\n"
881 "Router Advertisement interval\n")
883 struct interface
*ifp
;
884 struct zebra_if
*zif
;
885 struct zebra_vrf
*zvrf
;
886 struct zebra_ns
*zns
;
888 ifp
= (struct interface
*) vty
->index
;
890 zvrf
= vrf_info_lookup (ifp
->vrf_id
);
893 if (zif
->rtadv
.MaxRtrAdvInterval
% 1000)
894 zns
->rtadv
.adv_msec_if_count
--;
896 zif
->rtadv
.MaxRtrAdvInterval
= RTADV_MAX_RTR_ADV_INTERVAL
;
897 zif
->rtadv
.MinRtrAdvInterval
= RTADV_MIN_RTR_ADV_INTERVAL
;
898 zif
->rtadv
.AdvIntervalTimer
= zif
->rtadv
.MaxRtrAdvInterval
;
903 ALIAS (no_ipv6_nd_ra_interval
,
904 no_ipv6_nd_ra_interval_val_cmd
,
905 "no ipv6 nd ra-interval <1-1800>",
907 "Interface IPv6 config commands\n"
908 "Neighbor discovery\n"
909 "Router Advertisement interval\n")
911 ALIAS (no_ipv6_nd_ra_interval
,
912 no_ipv6_nd_ra_interval_msec_val_cmd
,
913 "no ipv6 nd ra-interval msec <1-1800000>",
915 "Interface IPv6 config commands\n"
916 "Neighbor discovery\n"
917 "Router Advertisement interval\n"
918 "Router Advertisement interval in milliseconds\n")
920 DEFUN (ipv6_nd_ra_lifetime
,
921 ipv6_nd_ra_lifetime_cmd
,
922 "ipv6 nd ra-lifetime <0-9000>",
923 "Interface IPv6 config commands\n"
924 "Neighbor discovery\n"
926 "Router lifetime in seconds (0 stands for a non-default gw)\n")
929 struct interface
*ifp
;
930 struct zebra_if
*zif
;
932 ifp
= (struct interface
*) vty
->index
;
935 VTY_GET_INTEGER_RANGE ("router lifetime", lifetime
, argv
[0], 0, 9000);
937 /* The value to be placed in the Router Lifetime field
938 * of Router Advertisements sent from the interface,
939 * in seconds. MUST be either zero or between
940 * MaxRtrAdvInterval and 9000 seconds. -- RFC4861, 6.2.1 */
941 if ((lifetime
!= 0 && lifetime
* 1000 < zif
->rtadv
.MaxRtrAdvInterval
))
943 vty_out (vty
, "This ra-lifetime would conflict with configured ra-interval%s", VTY_NEWLINE
);
947 zif
->rtadv
.AdvDefaultLifetime
= lifetime
;
952 DEFUN (no_ipv6_nd_ra_lifetime
,
953 no_ipv6_nd_ra_lifetime_cmd
,
954 "no ipv6 nd ra-lifetime",
956 "Interface IPv6 config commands\n"
957 "Neighbor discovery\n"
960 struct interface
*ifp
;
961 struct zebra_if
*zif
;
963 ifp
= (struct interface
*) vty
->index
;
966 zif
->rtadv
.AdvDefaultLifetime
= -1;
971 ALIAS (no_ipv6_nd_ra_lifetime
,
972 no_ipv6_nd_ra_lifetime_val_cmd
,
973 "no ipv6 nd ra-lifetime <0-9000>",
975 "Interface IPv6 config commands\n"
976 "Neighbor discovery\n"
978 "Router lifetime in seconds (0 stands for a non-default gw)\n")
980 DEFUN (ipv6_nd_reachable_time
,
981 ipv6_nd_reachable_time_cmd
,
982 "ipv6 nd reachable-time <1-3600000>",
983 "Interface IPv6 config commands\n"
984 "Neighbor discovery\n"
986 "Reachable time in milliseconds\n")
988 struct interface
*ifp
= (struct interface
*) vty
->index
;
989 struct zebra_if
*zif
= ifp
->info
;
990 VTY_GET_INTEGER_RANGE ("reachable time", zif
->rtadv
.AdvReachableTime
, argv
[0], 1, RTADV_MAX_REACHABLE_TIME
);
994 DEFUN (no_ipv6_nd_reachable_time
,
995 no_ipv6_nd_reachable_time_cmd
,
996 "no ipv6 nd reachable-time",
998 "Interface IPv6 config commands\n"
999 "Neighbor discovery\n"
1002 struct interface
*ifp
;
1003 struct zebra_if
*zif
;
1005 ifp
= (struct interface
*) vty
->index
;
1008 zif
->rtadv
.AdvReachableTime
= 0;
1013 ALIAS (no_ipv6_nd_reachable_time
,
1014 no_ipv6_nd_reachable_time_val_cmd
,
1015 "no ipv6 nd reachable-time <1-3600000>",
1017 "Interface IPv6 config commands\n"
1018 "Neighbor discovery\n"
1020 "Reachable time in milliseconds\n")
1022 DEFUN (ipv6_nd_homeagent_preference
,
1023 ipv6_nd_homeagent_preference_cmd
,
1024 "ipv6 nd home-agent-preference <0-65535>",
1025 "Interface IPv6 config commands\n"
1026 "Neighbor discovery\n"
1027 "Home Agent preference\n"
1028 "preference value (default is 0, least preferred)\n")
1030 struct interface
*ifp
= (struct interface
*) vty
->index
;
1031 struct zebra_if
*zif
= ifp
->info
;
1032 VTY_GET_INTEGER_RANGE ("home agent preference", zif
->rtadv
.HomeAgentPreference
, argv
[0], 0, 65535);
1036 DEFUN (no_ipv6_nd_homeagent_preference
,
1037 no_ipv6_nd_homeagent_preference_cmd
,
1038 "no ipv6 nd home-agent-preference",
1040 "Interface IPv6 config commands\n"
1041 "Neighbor discovery\n"
1042 "Home Agent preference\n")
1044 struct interface
*ifp
;
1045 struct zebra_if
*zif
;
1047 ifp
= (struct interface
*) vty
->index
;
1050 zif
->rtadv
.HomeAgentPreference
= 0;
1055 ALIAS (no_ipv6_nd_homeagent_preference
,
1056 no_ipv6_nd_homeagent_preference_val_cmd
,
1057 "no ipv6 nd home-agent-preference <0-65535>",
1059 "Interface IPv6 config commands\n"
1060 "Neighbor discovery\n"
1061 "Home Agent preference\n"
1062 "preference value (default is 0, least preferred)\n")
1064 DEFUN (ipv6_nd_homeagent_lifetime
,
1065 ipv6_nd_homeagent_lifetime_cmd
,
1066 "ipv6 nd home-agent-lifetime <0-65520>",
1067 "Interface IPv6 config commands\n"
1068 "Neighbor discovery\n"
1069 "Home Agent lifetime\n"
1070 "Home Agent lifetime in seconds (0 to track ra-lifetime)\n")
1072 struct interface
*ifp
= (struct interface
*) vty
->index
;
1073 struct zebra_if
*zif
= ifp
->info
;
1074 VTY_GET_INTEGER_RANGE ("home agent lifetime", zif
->rtadv
.HomeAgentLifetime
, argv
[0], 0, RTADV_MAX_HALIFETIME
);
1078 DEFUN (no_ipv6_nd_homeagent_lifetime
,
1079 no_ipv6_nd_homeagent_lifetime_cmd
,
1080 "no ipv6 nd home-agent-lifetime",
1082 "Interface IPv6 config commands\n"
1083 "Neighbor discovery\n"
1084 "Home Agent lifetime\n")
1086 struct interface
*ifp
;
1087 struct zebra_if
*zif
;
1089 ifp
= (struct interface
*) vty
->index
;
1092 zif
->rtadv
.HomeAgentLifetime
= -1;
1097 ALIAS (no_ipv6_nd_homeagent_lifetime
,
1098 no_ipv6_nd_homeagent_lifetime_val_cmd
,
1099 "no ipv6 nd home-agent-lifetime <0-65520>",
1101 "Interface IPv6 config commands\n"
1102 "Neighbor discovery\n"
1103 "Home Agent lifetime\n"
1104 "Home Agent lifetime in seconds (0 to track ra-lifetime)\n")
1106 DEFUN (ipv6_nd_managed_config_flag
,
1107 ipv6_nd_managed_config_flag_cmd
,
1108 "ipv6 nd managed-config-flag",
1109 "Interface IPv6 config commands\n"
1110 "Neighbor discovery\n"
1111 "Managed address configuration flag\n")
1113 struct interface
*ifp
;
1114 struct zebra_if
*zif
;
1116 ifp
= (struct interface
*) vty
->index
;
1119 zif
->rtadv
.AdvManagedFlag
= 1;
1124 DEFUN (no_ipv6_nd_managed_config_flag
,
1125 no_ipv6_nd_managed_config_flag_cmd
,
1126 "no ipv6 nd managed-config-flag",
1128 "Interface IPv6 config commands\n"
1129 "Neighbor discovery\n"
1130 "Managed address configuration flag\n")
1132 struct interface
*ifp
;
1133 struct zebra_if
*zif
;
1135 ifp
= (struct interface
*) vty
->index
;
1138 zif
->rtadv
.AdvManagedFlag
= 0;
1143 DEFUN (ipv6_nd_homeagent_config_flag
,
1144 ipv6_nd_homeagent_config_flag_cmd
,
1145 "ipv6 nd home-agent-config-flag",
1146 "Interface IPv6 config commands\n"
1147 "Neighbor discovery\n"
1148 "Home Agent configuration flag\n")
1150 struct interface
*ifp
;
1151 struct zebra_if
*zif
;
1153 ifp
= (struct interface
*) vty
->index
;
1156 zif
->rtadv
.AdvHomeAgentFlag
= 1;
1161 DEFUN (no_ipv6_nd_homeagent_config_flag
,
1162 no_ipv6_nd_homeagent_config_flag_cmd
,
1163 "no ipv6 nd home-agent-config-flag",
1165 "Interface IPv6 config commands\n"
1166 "Neighbor discovery\n"
1167 "Home Agent configuration flag\n")
1169 struct interface
*ifp
;
1170 struct zebra_if
*zif
;
1172 ifp
= (struct interface
*) vty
->index
;
1175 zif
->rtadv
.AdvHomeAgentFlag
= 0;
1180 DEFUN (ipv6_nd_adv_interval_config_option
,
1181 ipv6_nd_adv_interval_config_option_cmd
,
1182 "ipv6 nd adv-interval-option",
1183 "Interface IPv6 config commands\n"
1184 "Neighbor discovery\n"
1185 "Advertisement Interval Option\n")
1187 struct interface
*ifp
;
1188 struct zebra_if
*zif
;
1190 ifp
= (struct interface
*) vty
->index
;
1193 zif
->rtadv
.AdvIntervalOption
= 1;
1198 DEFUN (no_ipv6_nd_adv_interval_config_option
,
1199 no_ipv6_nd_adv_interval_config_option_cmd
,
1200 "no ipv6 nd adv-interval-option",
1202 "Interface IPv6 config commands\n"
1203 "Neighbor discovery\n"
1204 "Advertisement Interval Option\n")
1206 struct interface
*ifp
;
1207 struct zebra_if
*zif
;
1209 ifp
= (struct interface
*) vty
->index
;
1212 zif
->rtadv
.AdvIntervalOption
= 0;
1217 DEFUN (ipv6_nd_other_config_flag
,
1218 ipv6_nd_other_config_flag_cmd
,
1219 "ipv6 nd other-config-flag",
1220 "Interface IPv6 config commands\n"
1221 "Neighbor discovery\n"
1222 "Other statefull configuration flag\n")
1224 struct interface
*ifp
;
1225 struct zebra_if
*zif
;
1227 ifp
= (struct interface
*) vty
->index
;
1230 zif
->rtadv
.AdvOtherConfigFlag
= 1;
1235 DEFUN (no_ipv6_nd_other_config_flag
,
1236 no_ipv6_nd_other_config_flag_cmd
,
1237 "no ipv6 nd other-config-flag",
1239 "Interface IPv6 config commands\n"
1240 "Neighbor discovery\n"
1241 "Other statefull configuration flag\n")
1243 struct interface
*ifp
;
1244 struct zebra_if
*zif
;
1246 ifp
= (struct interface
*) vty
->index
;
1249 zif
->rtadv
.AdvOtherConfigFlag
= 0;
1254 DEFUN (ipv6_nd_prefix
,
1256 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1257 "(<0-4294967295>|infinite) (off-link|) (no-autoconfig|) (router-address|)",
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"
1267 "Do not use prefix for autoconfiguration\n"
1268 "Set Router Address flag\n")
1273 struct interface
*ifp
;
1274 struct zebra_if
*zebra_if
;
1275 struct rtadv_prefix rp
;
1277 ifp
= (struct interface
*) vty
->index
;
1278 zebra_if
= ifp
->info
;
1280 ret
= str2prefix_ipv6 (argv
[0], &rp
.prefix
);
1283 vty_out (vty
, "Malformed IPv6 prefix%s", VTY_NEWLINE
);
1286 apply_mask_ipv6 (&rp
.prefix
); /* RFC4861 4.6.2 */
1287 rp
.AdvOnLinkFlag
= 1;
1288 rp
.AdvAutonomousFlag
= 1;
1289 rp
.AdvRouterAddressFlag
= 0;
1290 rp
.AdvValidLifetime
= RTADV_VALID_LIFETIME
;
1291 rp
.AdvPreferredLifetime
= RTADV_PREFERRED_LIFETIME
;
1295 if ((isdigit(argv
[1][0])) || strncmp (argv
[1], "i", 1) == 0)
1297 if ( strncmp (argv
[1], "i", 1) == 0)
1298 rp
.AdvValidLifetime
= UINT32_MAX
;
1300 rp
.AdvValidLifetime
= (u_int32_t
) strtoll (argv
[1],
1303 if ( strncmp (argv
[2], "i", 1) == 0)
1304 rp
.AdvPreferredLifetime
= UINT32_MAX
;
1306 rp
.AdvPreferredLifetime
= (u_int32_t
) strtoll (argv
[2],
1309 if (rp
.AdvPreferredLifetime
> rp
.AdvValidLifetime
)
1311 vty_out (vty
, "Invalid preferred lifetime%s", VTY_NEWLINE
);
1314 cursor
= cursor
+ 2;
1318 for (i
= cursor
; i
< argc
; i
++)
1320 if (strncmp (argv
[i
], "of", 2) == 0)
1321 rp
.AdvOnLinkFlag
= 0;
1322 if (strncmp (argv
[i
], "no", 2) == 0)
1323 rp
.AdvAutonomousFlag
= 0;
1324 if (strncmp (argv
[i
], "ro", 2) == 0)
1325 rp
.AdvRouterAddressFlag
= 1;
1330 rtadv_prefix_set (zebra_if
, &rp
);
1335 ALIAS (ipv6_nd_prefix
,
1336 ipv6_nd_prefix_val_nortaddr_cmd
,
1337 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1338 "(<0-4294967295>|infinite) (off-link|) (no-autoconfig|)",
1339 "Interface IPv6 config commands\n"
1340 "Neighbor discovery\n"
1341 "Prefix information\n"
1343 "Valid lifetime in seconds\n"
1344 "Infinite valid lifetime\n"
1345 "Preferred lifetime in seconds\n"
1346 "Infinite preferred lifetime\n"
1347 "Do not use prefix for onlink determination\n"
1348 "Do not use prefix for autoconfiguration\n")
1350 ALIAS (ipv6_nd_prefix
,
1351 ipv6_nd_prefix_val_rev_cmd
,
1352 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1353 "(<0-4294967295>|infinite) (no-autoconfig|) (off-link|)",
1354 "Interface IPv6 config commands\n"
1355 "Neighbor discovery\n"
1356 "Prefix information\n"
1358 "Valid lifetime in seconds\n"
1359 "Infinite valid lifetime\n"
1360 "Preferred lifetime in seconds\n"
1361 "Infinite preferred lifetime\n"
1362 "Do not use prefix for autoconfiguration\n"
1363 "Do not use prefix for onlink determination\n")
1365 ALIAS (ipv6_nd_prefix
,
1366 ipv6_nd_prefix_val_rev_rtaddr_cmd
,
1367 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1368 "(<0-4294967295>|infinite) (no-autoconfig|) (off-link|) (router-address|)",
1369 "Interface IPv6 config commands\n"
1370 "Neighbor discovery\n"
1371 "Prefix information\n"
1373 "Valid lifetime in seconds\n"
1374 "Infinite valid lifetime\n"
1375 "Preferred lifetime in seconds\n"
1376 "Infinite preferred lifetime\n"
1377 "Do not use prefix for autoconfiguration\n"
1378 "Do not use prefix for onlink determination\n"
1379 "Set Router Address flag\n")
1381 ALIAS (ipv6_nd_prefix
,
1382 ipv6_nd_prefix_val_noauto_cmd
,
1383 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1384 "(<0-4294967295>|infinite) (no-autoconfig|)",
1385 "Interface IPv6 config commands\n"
1386 "Neighbor discovery\n"
1387 "Prefix information\n"
1389 "Valid lifetime in seconds\n"
1390 "Infinite valid lifetime\n"
1391 "Preferred lifetime in seconds\n"
1392 "Infinite preferred lifetime\n"
1393 "Do not use prefix for autoconfiguration")
1395 ALIAS (ipv6_nd_prefix
,
1396 ipv6_nd_prefix_val_offlink_cmd
,
1397 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1398 "(<0-4294967295>|infinite) (off-link|)",
1399 "Interface IPv6 config commands\n"
1400 "Neighbor discovery\n"
1401 "Prefix information\n"
1403 "Valid lifetime in seconds\n"
1404 "Infinite valid lifetime\n"
1405 "Preferred lifetime in seconds\n"
1406 "Infinite preferred lifetime\n"
1407 "Do not use prefix for onlink determination\n")
1409 ALIAS (ipv6_nd_prefix
,
1410 ipv6_nd_prefix_val_rtaddr_cmd
,
1411 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1412 "(<0-4294967295>|infinite) (router-address|)",
1413 "Interface IPv6 config commands\n"
1414 "Neighbor discovery\n"
1415 "Prefix information\n"
1417 "Valid lifetime in seconds\n"
1418 "Infinite valid lifetime\n"
1419 "Preferred lifetime in seconds\n"
1420 "Infinite preferred lifetime\n"
1421 "Set Router Address flag\n")
1423 ALIAS (ipv6_nd_prefix
,
1424 ipv6_nd_prefix_val_cmd
,
1425 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1426 "(<0-4294967295>|infinite)",
1427 "Interface IPv6 config commands\n"
1428 "Neighbor discovery\n"
1429 "Prefix information\n"
1431 "Valid lifetime in seconds\n"
1432 "Infinite valid lifetime\n"
1433 "Preferred lifetime in seconds\n"
1434 "Infinite preferred lifetime\n")
1436 ALIAS (ipv6_nd_prefix
,
1437 ipv6_nd_prefix_noval_cmd
,
1438 "ipv6 nd prefix X:X::X:X/M (no-autoconfig|) (off-link|)",
1439 "Interface IPv6 config commands\n"
1440 "Neighbor discovery\n"
1441 "Prefix information\n"
1443 "Do not use prefix for autoconfiguration\n"
1444 "Do not use prefix for onlink determination\n")
1446 ALIAS (ipv6_nd_prefix
,
1447 ipv6_nd_prefix_noval_rev_cmd
,
1448 "ipv6 nd prefix X:X::X:X/M (off-link|) (no-autoconfig|)",
1449 "Interface IPv6 config commands\n"
1450 "Neighbor discovery\n"
1451 "Prefix information\n"
1453 "Do not use prefix for onlink determination\n"
1454 "Do not use prefix for autoconfiguration\n")
1456 ALIAS (ipv6_nd_prefix
,
1457 ipv6_nd_prefix_noval_noauto_cmd
,
1458 "ipv6 nd prefix X:X::X:X/M (no-autoconfig|)",
1459 "Interface IPv6 config commands\n"
1460 "Neighbor discovery\n"
1461 "Prefix information\n"
1463 "Do not use prefix for autoconfiguration\n")
1465 ALIAS (ipv6_nd_prefix
,
1466 ipv6_nd_prefix_noval_offlink_cmd
,
1467 "ipv6 nd prefix X:X::X:X/M (off-link|)",
1468 "Interface IPv6 config commands\n"
1469 "Neighbor discovery\n"
1470 "Prefix information\n"
1472 "Do not use prefix for onlink determination\n")
1474 ALIAS (ipv6_nd_prefix
,
1475 ipv6_nd_prefix_noval_rtaddr_cmd
,
1476 "ipv6 nd prefix X:X::X:X/M (router-address|)",
1477 "Interface IPv6 config commands\n"
1478 "Neighbor discovery\n"
1479 "Prefix information\n"
1481 "Set Router Address flag\n")
1483 ALIAS (ipv6_nd_prefix
,
1484 ipv6_nd_prefix_prefix_cmd
,
1485 "ipv6 nd prefix X:X::X:X/M",
1486 "Interface IPv6 config commands\n"
1487 "Neighbor discovery\n"
1488 "Prefix information\n"
1491 DEFUN (no_ipv6_nd_prefix
,
1492 no_ipv6_nd_prefix_cmd
,
1493 "no ipv6 nd prefix IPV6PREFIX",
1495 "Interface IPv6 config commands\n"
1496 "Neighbor discovery\n"
1497 "Prefix information\n"
1501 struct interface
*ifp
;
1502 struct zebra_if
*zebra_if
;
1503 struct rtadv_prefix rp
;
1505 ifp
= (struct interface
*) vty
->index
;
1506 zebra_if
= ifp
->info
;
1508 ret
= str2prefix_ipv6 (argv
[0], &rp
.prefix
);
1511 vty_out (vty
, "Malformed IPv6 prefix%s", VTY_NEWLINE
);
1514 apply_mask_ipv6 (&rp
.prefix
); /* RFC4861 4.6.2 */
1516 ret
= rtadv_prefix_reset (zebra_if
, &rp
);
1519 vty_out (vty
, "Non-exist IPv6 prefix%s", VTY_NEWLINE
);
1526 ALIAS (no_ipv6_nd_prefix
,
1527 no_ipv6_nd_prefix_val_nortaddr_cmd
,
1528 "no ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) (<0-4294967295>|infinite) (off-link|) (no-autoconfig|) (router-address|)",
1530 "Interface IPv6 config commands\n"
1531 "Neighbor discovery\n"
1532 "Prefix information\n"
1534 "Valid lifetime in seconds\n"
1535 "Infinite valid lifetime\n"
1536 "Preferred lifetime in seconds\n"
1537 "Infinite preferred lifetime\n"
1538 "Do not use prefix for onlink determination\n"
1539 "Do not use prefix for autoconfiguration\n"
1540 "Set Router Address flag\n")
1542 ALIAS (no_ipv6_nd_prefix
,
1543 no_ipv6_nd_prefix_val_rev_cmd
,
1544 "no ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) (<0-4294967295>|infinite) (no-autoconfig|) (off-link|)",
1546 "Interface IPv6 config commands\n"
1547 "Neighbor discovery\n"
1548 "Prefix information\n"
1550 "Valid lifetime in seconds\n"
1551 "Infinite valid lifetime\n"
1552 "Preferred lifetime in seconds\n"
1553 "Infinite preferred lifetime\n"
1554 "Do not use prefix for autoconfiguration\n"
1555 "Do not use prefix for onlink determination\n")
1557 ALIAS (no_ipv6_nd_prefix
,
1558 no_ipv6_nd_prefix_val_rev_rtaddr_cmd
,
1559 "no ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) (<0-4294967295>|infinite) (no-autoconfig|) (off-link|) (router-address|)",
1561 "Interface IPv6 config commands\n"
1562 "Neighbor discovery\n"
1563 "Prefix information\n"
1565 "Valid lifetime in seconds\n"
1566 "Infinite valid lifetime\n"
1567 "Preferred lifetime in seconds\n"
1568 "Infinite preferred lifetime\n"
1569 "Do not use prefix for autoconfiguration\n"
1570 "Do not use prefix for onlink determination\n"
1571 "Set Router Address flag\n")
1573 ALIAS (no_ipv6_nd_prefix
,
1574 no_ipv6_nd_prefix_val_noauto_cmd
,
1575 "no ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) (<0-4294967295>|infinite) (no-autoconfig|)",
1577 "Interface IPv6 config commands\n"
1578 "Neighbor discovery\n"
1579 "Prefix information\n"
1581 "Valid lifetime in seconds\n"
1582 "Infinite valid lifetime\n"
1583 "Preferred lifetime in seconds\n"
1584 "Infinite preferred lifetime\n"
1585 "Do not use prefix for autoconfiguration")
1587 ALIAS (no_ipv6_nd_prefix
,
1588 no_ipv6_nd_prefix_val_offlink_cmd
,
1589 "no ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) (<0-4294967295>|infinite) (off-link|)",
1591 "Interface IPv6 config commands\n"
1592 "Neighbor discovery\n"
1593 "Prefix information\n"
1595 "Valid lifetime in seconds\n"
1596 "Infinite valid lifetime\n"
1597 "Preferred lifetime in seconds\n"
1598 "Infinite preferred lifetime\n"
1599 "Do not use prefix for onlink determination\n")
1601 ALIAS (no_ipv6_nd_prefix
,
1602 no_ipv6_nd_prefix_val_rtaddr_cmd
,
1603 "no ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) (<0-4294967295>|infinite) (router-address|)",
1605 "Interface IPv6 config commands\n"
1606 "Neighbor discovery\n"
1607 "Prefix information\n"
1609 "Valid lifetime in seconds\n"
1610 "Infinite valid lifetime\n"
1611 "Preferred lifetime in seconds\n"
1612 "Infinite preferred lifetime\n"
1613 "Set Router Address flag\n")
1615 ALIAS (no_ipv6_nd_prefix
,
1616 no_ipv6_nd_prefix_val_cmd
,
1617 "no ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) (<0-4294967295>|infinite)",
1619 "Interface IPv6 config commands\n"
1620 "Neighbor discovery\n"
1621 "Prefix information\n"
1623 "Valid lifetime in seconds\n"
1624 "Infinite valid lifetime\n"
1625 "Preferred lifetime in seconds\n"
1626 "Infinite preferred lifetime\n")
1628 ALIAS (no_ipv6_nd_prefix
,
1629 no_ipv6_nd_prefix_noval_cmd
,
1630 "no ipv6 nd prefix X:X::X:X/M (no-autoconfig|) (off-link|)",
1632 "Interface IPv6 config commands\n"
1633 "Neighbor discovery\n"
1634 "Prefix information\n"
1636 "Do not use prefix for autoconfiguration\n"
1637 "Do not use prefix for onlink determination\n")
1639 ALIAS (no_ipv6_nd_prefix
,
1640 no_ipv6_nd_prefix_noval_rev_cmd
,
1641 "no ipv6 nd prefix X:X::X:X/M (off-link|) (no-autoconfig|)",
1643 "Interface IPv6 config commands\n"
1644 "Neighbor discovery\n"
1645 "Prefix information\n"
1647 "Do not use prefix for onlink determination\n"
1648 "Do not use prefix for autoconfiguration\n")
1650 ALIAS (no_ipv6_nd_prefix
,
1651 no_ipv6_nd_prefix_noval_noauto_cmd
,
1652 "no ipv6 nd prefix X:X::X:X/M (no-autoconfig|)",
1654 "Interface IPv6 config commands\n"
1655 "Neighbor discovery\n"
1656 "Prefix information\n"
1658 "Do not use prefix for autoconfiguration\n")
1660 ALIAS (no_ipv6_nd_prefix
,
1661 no_ipv6_nd_prefix_noval_offlink_cmd
,
1662 "no ipv6 nd prefix X:X::X:X/M (off-link|)",
1664 "Interface IPv6 config commands\n"
1665 "Neighbor discovery\n"
1666 "Prefix information\n"
1668 "Do not use prefix for onlink determination\n")
1670 ALIAS (no_ipv6_nd_prefix
,
1671 no_ipv6_nd_prefix_noval_rtaddr_cmd
,
1672 "no ipv6 nd prefix X:X::X:X/M (router-address|)",
1674 "Interface IPv6 config commands\n"
1675 "Neighbor discovery\n"
1676 "Prefix information\n"
1678 "Set Router Address flag\n")
1680 DEFUN (ipv6_nd_router_preference
,
1681 ipv6_nd_router_preference_cmd
,
1682 "ipv6 nd router-preference (high|medium|low)",
1683 "Interface IPv6 config commands\n"
1684 "Neighbor discovery\n"
1685 "Default router preference\n"
1686 "High default router preference\n"
1687 "Low default router preference\n"
1688 "Medium default router preference (default)\n")
1690 struct interface
*ifp
;
1691 struct zebra_if
*zif
;
1694 ifp
= (struct interface
*) vty
->index
;
1697 while (0 != rtadv_pref_strs
[i
])
1699 if (strncmp (argv
[0], rtadv_pref_strs
[i
], 1) == 0)
1701 zif
->rtadv
.DefaultPreference
= i
;
1707 return CMD_ERR_NO_MATCH
;
1710 DEFUN (no_ipv6_nd_router_preference
,
1711 no_ipv6_nd_router_preference_cmd
,
1712 "no ipv6 nd router-preference",
1714 "Interface IPv6 config commands\n"
1715 "Neighbor discovery\n"
1716 "Default router preference\n")
1718 struct interface
*ifp
;
1719 struct zebra_if
*zif
;
1721 ifp
= (struct interface
*) vty
->index
;
1724 zif
->rtadv
.DefaultPreference
= RTADV_PREF_MEDIUM
; /* Default per RFC4191. */
1729 ALIAS (no_ipv6_nd_router_preference
,
1730 no_ipv6_nd_router_preference_val_cmd
,
1731 "no ipv6 nd router-preference (high|medium|low)",
1733 "Interface IPv6 config commands\n"
1734 "Neighbor discovery\n"
1735 "Default router preference\n"
1736 "High default router preference\n"
1737 "Low default router preference\n"
1738 "Medium default router preference (default)\n")
1742 "ipv6 nd mtu <1-65535>",
1743 "Interface IPv6 config commands\n"
1744 "Neighbor discovery\n"
1748 struct interface
*ifp
= (struct interface
*) vty
->index
;
1749 struct zebra_if
*zif
= ifp
->info
;
1750 VTY_GET_INTEGER_RANGE ("MTU", zif
->rtadv
.AdvLinkMTU
, argv
[0], 1, 65535);
1754 DEFUN (no_ipv6_nd_mtu
,
1758 "Interface IPv6 config commands\n"
1759 "Neighbor discovery\n"
1762 struct interface
*ifp
= (struct interface
*) vty
->index
;
1763 struct zebra_if
*zif
= ifp
->info
;
1764 zif
->rtadv
.AdvLinkMTU
= 0;
1768 ALIAS (no_ipv6_nd_mtu
,
1769 no_ipv6_nd_mtu_val_cmd
,
1770 "no ipv6 nd mtu <1-65535>",
1772 "Interface IPv6 config commands\n"
1773 "Neighbor discovery\n"
1777 /* Write configuration about router advertisement. */
1779 rtadv_config_write (struct vty
*vty
, struct interface
*ifp
)
1781 struct zebra_if
*zif
;
1782 struct listnode
*node
;
1783 struct rtadv_prefix
*rprefix
;
1784 u_char buf
[INET6_ADDRSTRLEN
];
1789 if (! if_is_loopback (ifp
))
1791 if (ipv6_address_configured(ifp
))
1793 if (! zif
->rtadv
.AdvSendAdvertisements
)
1794 vty_out (vty
, " ipv6 nd suppress-ra%s", VTY_NEWLINE
);
1798 if (zif
->rtadv
.AdvSendAdvertisements
)
1799 vty_out (vty
, " no ipv6 nd suppress-ra%s", VTY_NEWLINE
);
1803 interval
= zif
->rtadv
.MaxRtrAdvInterval
;
1804 if (interval
% 1000)
1805 vty_out (vty
, " ipv6 nd ra-interval msec %d%s", interval
,
1808 if (interval
!= RTADV_MAX_RTR_ADV_INTERVAL
)
1809 vty_out (vty
, " ipv6 nd ra-interval %d%s", interval
/ 1000,
1812 if (zif
->rtadv
.AdvIntervalOption
)
1813 vty_out (vty
, " ipv6 nd adv-interval-option%s", VTY_NEWLINE
);
1815 if (zif
->rtadv
.AdvDefaultLifetime
!= -1)
1816 vty_out (vty
, " ipv6 nd ra-lifetime %d%s", zif
->rtadv
.AdvDefaultLifetime
,
1819 if (zif
->rtadv
.HomeAgentPreference
)
1820 vty_out (vty
, " ipv6 nd home-agent-preference %u%s",
1821 zif
->rtadv
.HomeAgentPreference
, VTY_NEWLINE
);
1823 if (zif
->rtadv
.HomeAgentLifetime
!= -1)
1824 vty_out (vty
, " ipv6 nd home-agent-lifetime %u%s",
1825 zif
->rtadv
.HomeAgentLifetime
, VTY_NEWLINE
);
1827 if (zif
->rtadv
.AdvHomeAgentFlag
)
1828 vty_out (vty
, " ipv6 nd home-agent-config-flag%s", VTY_NEWLINE
);
1830 if (zif
->rtadv
.AdvReachableTime
)
1831 vty_out (vty
, " ipv6 nd reachable-time %d%s", zif
->rtadv
.AdvReachableTime
,
1834 if (zif
->rtadv
.AdvManagedFlag
)
1835 vty_out (vty
, " ipv6 nd managed-config-flag%s", VTY_NEWLINE
);
1837 if (zif
->rtadv
.AdvOtherConfigFlag
)
1838 vty_out (vty
, " ipv6 nd other-config-flag%s", VTY_NEWLINE
);
1840 if (zif
->rtadv
.DefaultPreference
!= RTADV_PREF_MEDIUM
)
1841 vty_out (vty
, " ipv6 nd router-preference %s%s",
1842 rtadv_pref_strs
[zif
->rtadv
.DefaultPreference
],
1845 if (zif
->rtadv
.AdvLinkMTU
)
1846 vty_out (vty
, " ipv6 nd mtu %d%s", zif
->rtadv
.AdvLinkMTU
, VTY_NEWLINE
);
1848 for (ALL_LIST_ELEMENTS_RO (zif
->rtadv
.AdvPrefixList
, node
, rprefix
))
1850 vty_out (vty
, " ipv6 nd prefix %s/%d",
1851 inet_ntop (AF_INET6
, &rprefix
->prefix
.prefix
,
1852 (char *) buf
, INET6_ADDRSTRLEN
),
1853 rprefix
->prefix
.prefixlen
);
1854 if ((rprefix
->AdvValidLifetime
!= RTADV_VALID_LIFETIME
) ||
1855 (rprefix
->AdvPreferredLifetime
!= RTADV_PREFERRED_LIFETIME
))
1857 if (rprefix
->AdvValidLifetime
== UINT32_MAX
)
1858 vty_out (vty
, " infinite");
1860 vty_out (vty
, " %u", rprefix
->AdvValidLifetime
);
1861 if (rprefix
->AdvPreferredLifetime
== UINT32_MAX
)
1862 vty_out (vty
, " infinite");
1864 vty_out (vty
, " %u", rprefix
->AdvPreferredLifetime
);
1866 if (!rprefix
->AdvOnLinkFlag
)
1867 vty_out (vty
, " off-link");
1868 if (!rprefix
->AdvAutonomousFlag
)
1869 vty_out (vty
, " no-autoconfig");
1870 if (rprefix
->AdvRouterAddressFlag
)
1871 vty_out (vty
, " router-address");
1872 vty_out (vty
, "%s", VTY_NEWLINE
);
1878 rtadv_event (struct zebra_ns
*zns
, enum rtadv_event event
, int val
)
1880 struct rtadv
*rtadv
= &zns
->rtadv
;
1885 if (! rtadv
->ra_read
)
1886 rtadv
->ra_read
= thread_add_read (zebrad
.master
, rtadv_read
, zns
, val
);
1887 if (! rtadv
->ra_timer
)
1888 rtadv
->ra_timer
= thread_add_event (zebrad
.master
, rtadv_timer
,
1892 if (rtadv
->ra_timer
)
1894 thread_cancel (rtadv
->ra_timer
);
1895 rtadv
->ra_timer
= NULL
;
1899 thread_cancel (rtadv
->ra_read
);
1900 rtadv
->ra_read
= NULL
;
1904 if (! rtadv
->ra_timer
)
1905 rtadv
->ra_timer
= thread_add_timer (zebrad
.master
, rtadv_timer
, zns
,
1908 case RTADV_TIMER_MSEC
:
1909 if (! rtadv
->ra_timer
)
1910 rtadv
->ra_timer
= thread_add_timer_msec (zebrad
.master
, rtadv_timer
,
1914 if (! rtadv
->ra_read
)
1915 rtadv
->ra_read
= thread_add_read (zebrad
.master
, rtadv_read
, zns
, val
);
1924 rtadv_init (struct zebra_ns
*zns
)
1926 zns
->rtadv
.sock
= rtadv_make_socket ();
1930 rtadv_terminate (struct zebra_ns
*zns
)
1932 rtadv_event (zns
, RTADV_STOP
, 0);
1933 if (zns
->rtadv
.sock
>= 0)
1935 close (zns
->rtadv
.sock
);
1936 zns
->rtadv
.sock
= -1;
1939 zns
->rtadv
.adv_if_count
= 0;
1940 zns
->rtadv
.adv_msec_if_count
= 0;
1944 rtadv_cmd_init (void)
1946 install_element (INTERFACE_NODE
, &ipv6_nd_suppress_ra_cmd
);
1947 install_element (INTERFACE_NODE
, &no_ipv6_nd_suppress_ra_cmd
);
1948 install_element (INTERFACE_NODE
, &ipv6_nd_ra_interval_cmd
);
1949 install_element (INTERFACE_NODE
, &ipv6_nd_ra_interval_msec_cmd
);
1950 install_element (INTERFACE_NODE
, &no_ipv6_nd_ra_interval_cmd
);
1951 install_element (INTERFACE_NODE
, &no_ipv6_nd_ra_interval_val_cmd
);
1952 install_element (INTERFACE_NODE
, &no_ipv6_nd_ra_interval_msec_val_cmd
);
1953 install_element (INTERFACE_NODE
, &ipv6_nd_ra_lifetime_cmd
);
1954 install_element (INTERFACE_NODE
, &no_ipv6_nd_ra_lifetime_cmd
);
1955 install_element (INTERFACE_NODE
, &no_ipv6_nd_ra_lifetime_val_cmd
);
1956 install_element (INTERFACE_NODE
, &ipv6_nd_reachable_time_cmd
);
1957 install_element (INTERFACE_NODE
, &no_ipv6_nd_reachable_time_cmd
);
1958 install_element (INTERFACE_NODE
, &no_ipv6_nd_reachable_time_val_cmd
);
1959 install_element (INTERFACE_NODE
, &ipv6_nd_managed_config_flag_cmd
);
1960 install_element (INTERFACE_NODE
, &no_ipv6_nd_managed_config_flag_cmd
);
1961 install_element (INTERFACE_NODE
, &ipv6_nd_other_config_flag_cmd
);
1962 install_element (INTERFACE_NODE
, &no_ipv6_nd_other_config_flag_cmd
);
1963 install_element (INTERFACE_NODE
, &ipv6_nd_homeagent_config_flag_cmd
);
1964 install_element (INTERFACE_NODE
, &no_ipv6_nd_homeagent_config_flag_cmd
);
1965 install_element (INTERFACE_NODE
, &ipv6_nd_homeagent_preference_cmd
);
1966 install_element (INTERFACE_NODE
, &no_ipv6_nd_homeagent_preference_cmd
);
1967 install_element (INTERFACE_NODE
, &no_ipv6_nd_homeagent_preference_val_cmd
);
1968 install_element (INTERFACE_NODE
, &ipv6_nd_homeagent_lifetime_cmd
);
1969 install_element (INTERFACE_NODE
, &no_ipv6_nd_homeagent_lifetime_cmd
);
1970 install_element (INTERFACE_NODE
, &no_ipv6_nd_homeagent_lifetime_val_cmd
);
1971 install_element (INTERFACE_NODE
, &ipv6_nd_adv_interval_config_option_cmd
);
1972 install_element (INTERFACE_NODE
, &no_ipv6_nd_adv_interval_config_option_cmd
);
1973 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_cmd
);
1974 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_val_rev_rtaddr_cmd
);
1975 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_val_nortaddr_cmd
);
1976 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_val_rev_cmd
);
1977 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_val_noauto_cmd
);
1978 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_val_offlink_cmd
);
1979 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_val_rtaddr_cmd
);
1980 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_val_cmd
);
1981 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_noval_cmd
);
1982 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_noval_rev_cmd
);
1983 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_noval_noauto_cmd
);
1984 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_noval_offlink_cmd
);
1985 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_noval_rtaddr_cmd
);
1986 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_prefix_cmd
);
1987 install_element (INTERFACE_NODE
, &no_ipv6_nd_prefix_cmd
);
1988 install_element (INTERFACE_NODE
, &no_ipv6_nd_prefix_val_rev_rtaddr_cmd
);
1989 install_element (INTERFACE_NODE
, &no_ipv6_nd_prefix_val_nortaddr_cmd
);
1990 install_element (INTERFACE_NODE
, &no_ipv6_nd_prefix_val_rev_cmd
);
1991 install_element (INTERFACE_NODE
, &no_ipv6_nd_prefix_val_noauto_cmd
);
1992 install_element (INTERFACE_NODE
, &no_ipv6_nd_prefix_val_offlink_cmd
);
1993 install_element (INTERFACE_NODE
, &no_ipv6_nd_prefix_val_rtaddr_cmd
);
1994 install_element (INTERFACE_NODE
, &no_ipv6_nd_prefix_val_cmd
);
1995 install_element (INTERFACE_NODE
, &no_ipv6_nd_prefix_noval_cmd
);
1996 install_element (INTERFACE_NODE
, &no_ipv6_nd_prefix_noval_rev_cmd
);
1997 install_element (INTERFACE_NODE
, &no_ipv6_nd_prefix_noval_noauto_cmd
);
1998 install_element (INTERFACE_NODE
, &no_ipv6_nd_prefix_noval_offlink_cmd
);
1999 install_element (INTERFACE_NODE
, &no_ipv6_nd_prefix_noval_rtaddr_cmd
);
2000 install_element (INTERFACE_NODE
, &ipv6_nd_router_preference_cmd
);
2001 install_element (INTERFACE_NODE
, &no_ipv6_nd_router_preference_cmd
);
2002 install_element (INTERFACE_NODE
, &no_ipv6_nd_router_preference_val_cmd
);
2003 install_element (INTERFACE_NODE
, &ipv6_nd_mtu_cmd
);
2004 install_element (INTERFACE_NODE
, &no_ipv6_nd_mtu_cmd
);
2005 install_element (INTERFACE_NODE
, &no_ipv6_nd_mtu_val_cmd
);
2009 if_join_all_router (int sock
, struct interface
*ifp
)
2013 struct ipv6_mreq mreq
;
2015 memset (&mreq
, 0, sizeof (struct ipv6_mreq
));
2016 inet_pton (AF_INET6
, ALLROUTER
, &mreq
.ipv6mr_multiaddr
);
2017 mreq
.ipv6mr_interface
= ifp
->ifindex
;
2019 ret
= setsockopt (sock
, IPPROTO_IPV6
, IPV6_JOIN_GROUP
,
2020 (char *) &mreq
, sizeof mreq
);
2022 zlog_warn ("%s(%u): Failed to join group, socket %u error %s",
2023 ifp
->name
, ifp
->ifindex
, sock
, safe_strerror (errno
));
2025 if (IS_ZEBRA_DEBUG_EVENT
)
2026 zlog_debug ("%s(%u): Join All-Routers multicast group, socket %u",
2027 ifp
->name
, ifp
->ifindex
, sock
);
2033 if_leave_all_router (int sock
, struct interface
*ifp
)
2037 struct ipv6_mreq mreq
;
2039 memset (&mreq
, 0, sizeof (struct ipv6_mreq
));
2040 inet_pton (AF_INET6
, ALLROUTER
, &mreq
.ipv6mr_multiaddr
);
2041 mreq
.ipv6mr_interface
= ifp
->ifindex
;
2043 ret
= setsockopt (sock
, IPPROTO_IPV6
, IPV6_LEAVE_GROUP
,
2044 (char *) &mreq
, sizeof mreq
);
2046 zlog_warn ("%s(%u): Failed to leave group, socket %u error %s",
2047 ifp
->name
, ifp
->ifindex
, sock
,safe_strerror (errno
));
2049 if (IS_ZEBRA_DEBUG_EVENT
)
2050 zlog_debug ("%s(%u): Leave All-Routers multicast group, socket %u",
2051 ifp
->name
, ifp
->ifindex
, sock
);
2058 rtadv_init (struct zebra_ns
*zns
)
2063 rtadv_terminate (struct zebra_ns
*zns
)
2068 rtadv_cmd_init (void)
2072 #endif /* HAVE_RTADV && HAVE_IPV6 */