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_vrf
*, 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\n");
164 /* Logging of packet. */
165 if (IS_ZEBRA_DEBUG_PACKET
)
166 zlog_debug ("Router advertisement send to %s", ifp
->name
);
168 /* Fill in sockaddr_in6. */
169 memset (&addr
, 0, sizeof (struct sockaddr_in6
));
170 addr
.sin6_family
= AF_INET6
;
172 addr
.sin6_len
= sizeof (struct sockaddr_in6
);
173 #endif /* SIN6_LEN */
174 addr
.sin6_port
= htons (IPPROTO_ICMPV6
);
175 IPV6_ADDR_COPY (&addr
.sin6_addr
, all_nodes_addr
);
177 /* Fetch interface information. */
180 /* Make router advertisement message. */
181 rtadv
= (struct nd_router_advert
*) buf
;
183 rtadv
->nd_ra_type
= ND_ROUTER_ADVERT
;
184 rtadv
->nd_ra_code
= 0;
185 rtadv
->nd_ra_cksum
= 0;
187 rtadv
->nd_ra_curhoplimit
= 64;
189 /* RFC4191: Default Router Preference is 0 if Router Lifetime is 0. */
190 rtadv
->nd_ra_flags_reserved
=
191 zif
->rtadv
.AdvDefaultLifetime
== 0 ? 0 : zif
->rtadv
.DefaultPreference
;
192 rtadv
->nd_ra_flags_reserved
<<= 3;
194 if (zif
->rtadv
.AdvManagedFlag
)
195 rtadv
->nd_ra_flags_reserved
|= ND_RA_FLAG_MANAGED
;
196 if (zif
->rtadv
.AdvOtherConfigFlag
)
197 rtadv
->nd_ra_flags_reserved
|= ND_RA_FLAG_OTHER
;
198 if (zif
->rtadv
.AdvHomeAgentFlag
)
199 rtadv
->nd_ra_flags_reserved
|= ND_RA_FLAG_HOME_AGENT
;
200 /* Note that according to Neighbor Discovery (RFC 4861 [18]),
201 * AdvDefaultLifetime is by default based on the value of
202 * MaxRtrAdvInterval. AdvDefaultLifetime is used in the Router Lifetime
203 * field of Router Advertisements. Given that this field is expressed
204 * in seconds, a small MaxRtrAdvInterval value can result in a zero
205 * value for this field. To prevent this, routers SHOULD keep
206 * AdvDefaultLifetime in at least one second, even if the use of
207 * MaxRtrAdvInterval would result in a smaller value. -- RFC6275, 7.5 */
208 pkt_RouterLifetime
= zif
->rtadv
.AdvDefaultLifetime
!= -1 ?
209 zif
->rtadv
.AdvDefaultLifetime
:
210 MAX (1, 0.003 * zif
->rtadv
.MaxRtrAdvInterval
);
211 rtadv
->nd_ra_router_lifetime
= htons (pkt_RouterLifetime
);
212 rtadv
->nd_ra_reachable
= htonl (zif
->rtadv
.AdvReachableTime
);
213 rtadv
->nd_ra_retransmit
= htonl (0);
215 len
= sizeof (struct nd_router_advert
);
217 /* If both the Home Agent Preference and Home Agent Lifetime are set to
218 * their default values specified above, this option SHOULD NOT be
219 * included in the Router Advertisement messages sent by this home
220 * agent. -- RFC6275, 7.4 */
223 zif
->rtadv
.AdvHomeAgentFlag
&&
224 (zif
->rtadv
.HomeAgentPreference
|| zif
->rtadv
.HomeAgentLifetime
!= -1)
227 struct nd_opt_homeagent_info
*ndopt_hai
=
228 (struct nd_opt_homeagent_info
*)(buf
+ len
);
229 ndopt_hai
->nd_opt_hai_type
= ND_OPT_HA_INFORMATION
;
230 ndopt_hai
->nd_opt_hai_len
= 1;
231 ndopt_hai
->nd_opt_hai_reserved
= 0;
232 ndopt_hai
->nd_opt_hai_preference
= htons(zif
->rtadv
.HomeAgentPreference
);
233 /* 16-bit unsigned integer. The lifetime associated with the home
234 * agent in units of seconds. The default value is the same as the
235 * Router Lifetime, as specified in the main body of the Router
236 * Advertisement. The maximum value corresponds to 18.2 hours. A
237 * value of 0 MUST NOT be used. -- RFC6275, 7.5 */
238 ndopt_hai
->nd_opt_hai_lifetime
= htons
240 zif
->rtadv
.HomeAgentLifetime
!= -1 ?
241 zif
->rtadv
.HomeAgentLifetime
:
242 MAX (1, pkt_RouterLifetime
) /* 0 is OK for RL, but not for HAL*/
244 len
+= sizeof(struct nd_opt_homeagent_info
);
247 if (zif
->rtadv
.AdvIntervalOption
)
249 struct nd_opt_adv_interval
*ndopt_adv
=
250 (struct nd_opt_adv_interval
*)(buf
+ len
);
251 ndopt_adv
->nd_opt_ai_type
= ND_OPT_ADV_INTERVAL
;
252 ndopt_adv
->nd_opt_ai_len
= 1;
253 ndopt_adv
->nd_opt_ai_reserved
= 0;
254 ndopt_adv
->nd_opt_ai_interval
= htonl(zif
->rtadv
.MaxRtrAdvInterval
);
255 len
+= sizeof(struct nd_opt_adv_interval
);
258 /* Fill in prefix. */
259 for (ALL_LIST_ELEMENTS_RO (zif
->rtadv
.AdvPrefixList
, node
, rprefix
))
261 struct nd_opt_prefix_info
*pinfo
;
263 pinfo
= (struct nd_opt_prefix_info
*) (buf
+ len
);
265 pinfo
->nd_opt_pi_type
= ND_OPT_PREFIX_INFORMATION
;
266 pinfo
->nd_opt_pi_len
= 4;
267 pinfo
->nd_opt_pi_prefix_len
= rprefix
->prefix
.prefixlen
;
269 pinfo
->nd_opt_pi_flags_reserved
= 0;
270 if (rprefix
->AdvOnLinkFlag
)
271 pinfo
->nd_opt_pi_flags_reserved
|= ND_OPT_PI_FLAG_ONLINK
;
272 if (rprefix
->AdvAutonomousFlag
)
273 pinfo
->nd_opt_pi_flags_reserved
|= ND_OPT_PI_FLAG_AUTO
;
274 if (rprefix
->AdvRouterAddressFlag
)
275 pinfo
->nd_opt_pi_flags_reserved
|= ND_OPT_PI_FLAG_RADDR
;
277 pinfo
->nd_opt_pi_valid_time
= htonl (rprefix
->AdvValidLifetime
);
278 pinfo
->nd_opt_pi_preferred_time
= htonl (rprefix
->AdvPreferredLifetime
);
279 pinfo
->nd_opt_pi_reserved2
= 0;
281 IPV6_ADDR_COPY (&pinfo
->nd_opt_pi_prefix
, &rprefix
->prefix
.prefix
);
285 u_char buf
[INET6_ADDRSTRLEN
];
287 zlog_debug ("DEBUG %s", inet_ntop (AF_INET6
, &pinfo
->nd_opt_pi_prefix
,
288 buf
, INET6_ADDRSTRLEN
));
293 len
+= sizeof (struct nd_opt_prefix_info
);
296 /* Hardware address. */
297 #ifdef HAVE_STRUCT_SOCKADDR_DL
299 if (sdl
!= NULL
&& sdl
->sdl_alen
!= 0)
301 buf
[len
++] = ND_OPT_SOURCE_LINKADDR
;
303 /* Option length should be rounded up to next octet if
304 the link address does not end on an octet boundary. */
305 buf
[len
++] = (sdl
->sdl_alen
+ 9) >> 3;
307 memcpy (buf
+ len
, LLADDR (sdl
), sdl
->sdl_alen
);
308 len
+= sdl
->sdl_alen
;
310 /* Pad option to end on an octet boundary. */
311 memset (buf
+ len
, 0, -(sdl
->sdl_alen
+ 2) & 0x7);
312 len
+= -(sdl
->sdl_alen
+ 2) & 0x7;
315 if (ifp
->hw_addr_len
!= 0)
317 buf
[len
++] = ND_OPT_SOURCE_LINKADDR
;
319 /* Option length should be rounded up to next octet if
320 the link address does not end on an octet boundary. */
321 buf
[len
++] = (ifp
->hw_addr_len
+ 9) >> 3;
323 memcpy (buf
+ len
, ifp
->hw_addr
, ifp
->hw_addr_len
);
324 len
+= ifp
->hw_addr_len
;
326 /* Pad option to end on an octet boundary. */
327 memset (buf
+ len
, 0, -(ifp
->hw_addr_len
+ 2) & 0x7);
328 len
+= -(ifp
->hw_addr_len
+ 2) & 0x7;
330 #endif /* HAVE_STRUCT_SOCKADDR_DL */
333 if (zif
->rtadv
.AdvLinkMTU
)
335 struct nd_opt_mtu
* opt
= (struct nd_opt_mtu
*) (buf
+ len
);
336 opt
->nd_opt_mtu_type
= ND_OPT_MTU
;
337 opt
->nd_opt_mtu_len
= 1;
338 opt
->nd_opt_mtu_reserved
= 0;
339 opt
->nd_opt_mtu_mtu
= htonl (zif
->rtadv
.AdvLinkMTU
);
340 len
+= sizeof (struct nd_opt_mtu
);
343 msg
.msg_name
= (void *) &addr
;
344 msg
.msg_namelen
= sizeof (struct sockaddr_in6
);
347 msg
.msg_control
= (void *) adata
;
348 msg
.msg_controllen
= CMSG_SPACE(sizeof(struct in6_pktinfo
));
353 cmsgptr
= ZCMSG_FIRSTHDR(&msg
);
354 cmsgptr
->cmsg_len
= CMSG_LEN(sizeof(struct in6_pktinfo
));
355 cmsgptr
->cmsg_level
= IPPROTO_IPV6
;
356 cmsgptr
->cmsg_type
= IPV6_PKTINFO
;
358 pkt
= (struct in6_pktinfo
*) CMSG_DATA (cmsgptr
);
359 memset (&pkt
->ipi6_addr
, 0, sizeof (struct in6_addr
));
360 pkt
->ipi6_ifindex
= ifp
->ifindex
;
362 ret
= sendmsg (sock
, &msg
, 0);
365 zlog_err ("rtadv_send_packet: sendmsg %d (%s)\n",
366 errno
, safe_strerror(errno
));
371 rtadv_timer (struct thread
*thread
)
373 struct zebra_vrf
*zvrf
= THREAD_ARG (thread
);
374 struct listnode
*node
, *nnode
;
375 struct interface
*ifp
;
376 struct zebra_if
*zif
;
379 zvrf
->rtadv
.ra_timer
= NULL
;
380 if (zvrf
->rtadv
.adv_msec_if_count
== 0)
382 period
= 1000; /* 1 s */
383 rtadv_event (zvrf
, RTADV_TIMER
, 1 /* 1 s */);
387 period
= 10; /* 10 ms */
388 rtadv_event (zvrf
, RTADV_TIMER_MSEC
, 10 /* 10 ms */);
391 for (ALL_LIST_ELEMENTS (vrf_iflist (zvrf
->vrf_id
), node
, nnode
, ifp
))
393 if (if_is_loopback (ifp
) || ! if_is_operative (ifp
))
398 if (zif
->rtadv
.AdvSendAdvertisements
)
400 zif
->rtadv
.AdvIntervalTimer
-= period
;
401 if (zif
->rtadv
.AdvIntervalTimer
<= 0)
403 /* FIXME: using MaxRtrAdvInterval each time isn't what section
404 6.2.4 of RFC4861 tells to do. */
405 zif
->rtadv
.AdvIntervalTimer
= zif
->rtadv
.MaxRtrAdvInterval
;
406 rtadv_send_packet (zvrf
->rtadv
.sock
, ifp
);
414 rtadv_process_solicit (struct interface
*ifp
)
416 struct zebra_vrf
*zvrf
= vrf_info_lookup (ifp
->vrf_id
);
418 zlog_info ("Router solicitation received on %s vrf %u", ifp
->name
, zvrf
->vrf_id
);
420 rtadv_send_packet (zvrf
->rtadv
.sock
, ifp
);
424 rtadv_process_advert (u_char
*msg
, unsigned int len
, struct interface
*ifp
,
425 struct sockaddr_in6
*addr
)
427 struct nd_router_advert
*radvert
;
428 char addr_str
[INET6_ADDRSTRLEN
];
429 struct zebra_if
*zif
;
433 inet_ntop (AF_INET6
, &addr
->sin6_addr
, addr_str
, INET6_ADDRSTRLEN
);
435 if (IS_ZEBRA_DEBUG_PACKET
)
436 zlog_debug ("Router advertisement received on %s from : %s", ifp
->name
, addr_str
);
438 if (len
< sizeof(struct nd_router_advert
)) {
439 zlog_warn("received icmpv6 RA packet with invalid length (%d) from %s",
443 if (!IN6_IS_ADDR_LINKLOCAL(&addr
->sin6_addr
)) {
444 zlog_warn("received icmpv6 RA packet with non-linklocal source address from %s",
449 radvert
= (struct nd_router_advert
*) msg
;
451 if ((radvert
->nd_ra_curhoplimit
&& zif
->rtadv
.AdvCurHopLimit
) &&
452 (radvert
->nd_ra_curhoplimit
!= zif
->rtadv
.AdvCurHopLimit
))
454 zlog_warn("our AdvCurHopLimit on %s doesn't agree with %s",
455 ifp
->name
, addr_str
);
458 if ((radvert
->nd_ra_flags_reserved
& ND_RA_FLAG_MANAGED
) &&
459 !zif
->rtadv
.AdvManagedFlag
)
461 zlog_warn("our AdvManagedFlag on %s doesn't agree with %s",
462 ifp
->name
, addr_str
);
465 if ((radvert
->nd_ra_flags_reserved
& ND_RA_FLAG_OTHER
) &&
466 !zif
->rtadv
.AdvOtherConfigFlag
)
468 zlog_warn("our AdvOtherConfigFlag on %s doesn't agree with %s",
469 ifp
->name
, addr_str
);
472 if ((radvert
->nd_ra_reachable
&& zif
->rtadv
.AdvReachableTime
) &&
473 (ntohl(radvert
->nd_ra_reachable
) != zif
->rtadv
.AdvReachableTime
))
475 zlog_warn("our AdvReachableTime on %s doesn't agree with %s",
476 ifp
->name
, addr_str
);
479 if ((radvert
->nd_ra_retransmit
&& zif
->rtadv
.AdvRetransTimer
) &&
480 (ntohl(radvert
->nd_ra_retransmit
) != (unsigned int)zif
->rtadv
.AdvRetransTimer
))
482 zlog_warn("our AdvRetransTimer on %s doesn't agree with %s",
483 ifp
->name
, addr_str
);
486 /* Currently supporting only P2P links, so any new RA source address is
487 considered as the replacement of the previously learnt Link-Local address.
488 As per the RFC, lifetime zero is to be considered a delete */
489 if (ntohs(radvert
->nd_ra_router_lifetime
))
490 nbr_connected_replacement_add_ipv6(ifp
, &addr
->sin6_addr
, 128);
492 nbr_connected_delete_ipv6(ifp
, &addr
->sin6_addr
, 128);
499 rtadv_process_packet (u_char
*buf
, unsigned int len
, unsigned int ifindex
, int hoplimit
,
500 struct sockaddr_in6
*from
, vrf_id_t vrf_id
)
502 struct icmp6_hdr
*icmph
;
503 struct interface
*ifp
;
504 struct zebra_if
*zif
;
506 /* Interface search. */
507 ifp
= if_lookup_by_index_vrf (ifindex
, vrf_id
);
510 zlog_warn ("Unknown interface index: %d, vrf %u", ifindex
, vrf_id
);
514 if (if_is_loopback (ifp
))
517 /* Check interface configuration. */
519 if (! zif
->rtadv
.AdvSendAdvertisements
)
522 /* ICMP message length check. */
523 if (len
< sizeof (struct icmp6_hdr
))
525 zlog_warn ("Invalid ICMPV6 packet length: %d", len
);
529 icmph
= (struct icmp6_hdr
*) buf
;
531 /* ICMP message type check. */
532 if (icmph
->icmp6_type
!= ND_ROUTER_SOLICIT
&&
533 icmph
->icmp6_type
!= ND_ROUTER_ADVERT
)
535 zlog_warn ("Unwanted ICMPV6 message type: %d", icmph
->icmp6_type
);
539 /* Hoplimit check. */
540 if (hoplimit
>= 0 && hoplimit
!= 255)
542 zlog_warn ("Invalid hoplimit %d for router advertisement ICMP packet",
547 /* Check ICMP message type. */
548 if (icmph
->icmp6_type
== ND_ROUTER_SOLICIT
)
549 rtadv_process_solicit (ifp
);
550 else if (icmph
->icmp6_type
== ND_ROUTER_ADVERT
)
551 rtadv_process_advert (buf
, len
, ifp
, from
);
557 rtadv_read (struct thread
*thread
)
561 u_char buf
[RTADV_MSG_SIZE
];
562 struct sockaddr_in6 from
;
563 unsigned int ifindex
= 0;
565 struct zebra_vrf
*zvrf
= THREAD_ARG (thread
);
567 sock
= THREAD_FD (thread
);
568 zvrf
->rtadv
.ra_read
= NULL
;
570 /* Register myself. */
571 rtadv_event (zvrf
, RTADV_READ
, sock
);
573 len
= rtadv_recv_packet (sock
, buf
, BUFSIZ
, &from
, &ifindex
, &hoplimit
);
577 zlog_warn ("router solicitation recv failed: %s.", safe_strerror (errno
));
581 rtadv_process_packet (buf
, (unsigned)len
, ifindex
, hoplimit
, &from
, zvrf
->vrf_id
);
587 rtadv_make_socket (vrf_id_t vrf_id
)
591 struct icmp6_filter filter
;
593 if ( zserv_privs
.change (ZPRIVS_RAISE
) )
594 zlog_err ("rtadv_make_socket: could not raise privs, %s",
595 safe_strerror (errno
) );
597 sock
= vrf_socket (AF_INET6
, SOCK_RAW
, IPPROTO_ICMPV6
, vrf_id
);
599 if ( zserv_privs
.change (ZPRIVS_LOWER
) )
600 zlog_err ("rtadv_make_socket: could not lower privs, %s",
601 safe_strerror (errno
) );
603 /* When we can't make ICMPV6 socket simply back. Router
604 advertisement feature will not be supported. */
608 ret
= setsockopt_ipv6_pktinfo (sock
, 1);
611 ret
= setsockopt_ipv6_multicast_loop (sock
, 0);
614 ret
= setsockopt_ipv6_unicast_hops (sock
, 255);
617 ret
= setsockopt_ipv6_multicast_hops (sock
, 255);
620 ret
= setsockopt_ipv6_hoplimit (sock
, 1);
624 ICMP6_FILTER_SETBLOCKALL(&filter
);
625 ICMP6_FILTER_SETPASS (ND_ROUTER_SOLICIT
, &filter
);
626 ICMP6_FILTER_SETPASS (ND_ROUTER_ADVERT
, &filter
);
628 ret
= setsockopt (sock
, IPPROTO_ICMPV6
, ICMP6_FILTER
, &filter
,
629 sizeof (struct icmp6_filter
));
632 zlog_info ("ICMP6_FILTER set fail: %s", safe_strerror (errno
));
639 static struct rtadv_prefix
*
640 rtadv_prefix_new (void)
642 return XCALLOC (MTYPE_RTADV_PREFIX
, sizeof (struct rtadv_prefix
));
646 rtadv_prefix_free (struct rtadv_prefix
*rtadv_prefix
)
648 XFREE (MTYPE_RTADV_PREFIX
, rtadv_prefix
);
651 static struct rtadv_prefix
*
652 rtadv_prefix_lookup (struct list
*rplist
, struct prefix_ipv6
*p
)
654 struct listnode
*node
;
655 struct rtadv_prefix
*rprefix
;
657 for (ALL_LIST_ELEMENTS_RO (rplist
, node
, rprefix
))
658 if (prefix_same ((struct prefix
*) &rprefix
->prefix
, (struct prefix
*) p
))
663 static struct rtadv_prefix
*
664 rtadv_prefix_get (struct list
*rplist
, struct prefix_ipv6
*p
)
666 struct rtadv_prefix
*rprefix
;
668 rprefix
= rtadv_prefix_lookup (rplist
, p
);
672 rprefix
= rtadv_prefix_new ();
673 memcpy (&rprefix
->prefix
, p
, sizeof (struct prefix_ipv6
));
674 listnode_add (rplist
, rprefix
);
680 rtadv_prefix_set (struct zebra_if
*zif
, struct rtadv_prefix
*rp
)
682 struct rtadv_prefix
*rprefix
;
684 rprefix
= rtadv_prefix_get (zif
->rtadv
.AdvPrefixList
, &rp
->prefix
);
686 /* Set parameters. */
687 rprefix
->AdvValidLifetime
= rp
->AdvValidLifetime
;
688 rprefix
->AdvPreferredLifetime
= rp
->AdvPreferredLifetime
;
689 rprefix
->AdvOnLinkFlag
= rp
->AdvOnLinkFlag
;
690 rprefix
->AdvAutonomousFlag
= rp
->AdvAutonomousFlag
;
691 rprefix
->AdvRouterAddressFlag
= rp
->AdvRouterAddressFlag
;
695 rtadv_prefix_reset (struct zebra_if
*zif
, struct rtadv_prefix
*rp
)
697 struct rtadv_prefix
*rprefix
;
699 rprefix
= rtadv_prefix_lookup (zif
->rtadv
.AdvPrefixList
, &rp
->prefix
);
702 listnode_delete (zif
->rtadv
.AdvPrefixList
, (void *) rprefix
);
703 rtadv_prefix_free (rprefix
);
711 ipv6_nd_suppress_ra_set (struct interface
*ifp
, ipv6_nd_suppress_ra_status status
)
713 struct zebra_if
*zif
;
714 struct zebra_vrf
*zvrf
;
717 zvrf
= vrf_info_lookup (ifp
->vrf_id
);
719 if (status
== RA_SUPPRESS
)
721 /* RA is currently enabled */
722 if (zif
->rtadv
.AdvSendAdvertisements
)
724 zif
->rtadv
.AdvSendAdvertisements
= 0;
725 zif
->rtadv
.AdvIntervalTimer
= 0;
726 zvrf
->rtadv
.adv_if_count
--;
728 if_leave_all_router (zvrf
->rtadv
.sock
, ifp
);
730 if (zvrf
->rtadv
.adv_if_count
== 0)
731 rtadv_event (zvrf
, RTADV_STOP
, 0);
736 if (! zif
->rtadv
.AdvSendAdvertisements
)
738 zif
->rtadv
.AdvSendAdvertisements
= 1;
739 zif
->rtadv
.AdvIntervalTimer
= 0;
740 zvrf
->rtadv
.adv_if_count
++;
742 if_join_all_router (zvrf
->rtadv
.sock
, ifp
);
744 if (zvrf
->rtadv
.adv_if_count
== 1)
745 rtadv_event (zvrf
, RTADV_START
, zvrf
->rtadv
.sock
);
750 DEFUN (ipv6_nd_suppress_ra
,
751 ipv6_nd_suppress_ra_cmd
,
752 "ipv6 nd suppress-ra",
753 "Interface IPv6 config commands\n"
754 "Neighbor discovery\n"
755 "Suppress Router Advertisement\n")
757 struct interface
*ifp
;
761 if (if_is_loopback (ifp
))
763 vty_out (vty
, "Invalid interface%s", VTY_NEWLINE
);
767 ipv6_nd_suppress_ra_set (ifp
, RA_SUPPRESS
);
771 DEFUN (no_ipv6_nd_suppress_ra
,
772 no_ipv6_nd_suppress_ra_cmd
,
773 "no ipv6 nd suppress-ra",
775 "Interface IPv6 config commands\n"
776 "Neighbor discovery\n"
777 "Suppress Router Advertisement\n")
779 struct interface
*ifp
;
783 if (if_is_loopback (ifp
))
785 vty_out (vty
, "Invalid interface%s", VTY_NEWLINE
);
789 ipv6_nd_suppress_ra_set (ifp
, RA_ENABLE
);
793 DEFUN (ipv6_nd_ra_interval_msec
,
794 ipv6_nd_ra_interval_msec_cmd
,
795 "ipv6 nd ra-interval msec <70-1800000>",
796 "Interface IPv6 config commands\n"
797 "Neighbor discovery\n"
798 "Router Advertisement interval\n"
799 "Router Advertisement interval in milliseconds\n")
802 struct interface
*ifp
= (struct interface
*) vty
->index
;
803 struct zebra_if
*zif
= ifp
->info
;
804 struct zebra_vrf
*zvrf
= vrf_info_lookup (ifp
->vrf_id
);
806 VTY_GET_INTEGER_RANGE ("router advertisement interval", interval
, argv
[0], 70, 1800000);
807 if ((zif
->rtadv
.AdvDefaultLifetime
!= -1 && interval
> (unsigned)zif
->rtadv
.AdvDefaultLifetime
* 1000))
809 vty_out (vty
, "This ra-interval would conflict with configured ra-lifetime!%s", VTY_NEWLINE
);
813 if (zif
->rtadv
.MaxRtrAdvInterval
% 1000)
814 zvrf
->rtadv
.adv_msec_if_count
--;
817 zvrf
->rtadv
.adv_msec_if_count
++;
819 zif
->rtadv
.MaxRtrAdvInterval
= interval
;
820 zif
->rtadv
.MinRtrAdvInterval
= 0.33 * interval
;
821 zif
->rtadv
.AdvIntervalTimer
= 0;
826 DEFUN (ipv6_nd_ra_interval
,
827 ipv6_nd_ra_interval_cmd
,
828 "ipv6 nd ra-interval <1-1800>",
829 "Interface IPv6 config commands\n"
830 "Neighbor discovery\n"
831 "Router Advertisement interval\n"
832 "Router Advertisement interval in seconds\n")
835 struct interface
*ifp
= (struct interface
*) vty
->index
;
836 struct zebra_if
*zif
= ifp
->info
;
837 struct zebra_vrf
*zvrf
= vrf_info_lookup (ifp
->vrf_id
);
839 VTY_GET_INTEGER_RANGE ("router advertisement interval", interval
, argv
[0], 1, 1800);
840 if ((zif
->rtadv
.AdvDefaultLifetime
!= -1 && interval
> (unsigned)zif
->rtadv
.AdvDefaultLifetime
))
842 vty_out (vty
, "This ra-interval would conflict with configured ra-lifetime!%s", VTY_NEWLINE
);
846 if (zif
->rtadv
.MaxRtrAdvInterval
% 1000)
847 zvrf
->rtadv
.adv_msec_if_count
--;
849 /* convert to milliseconds */
850 interval
= interval
* 1000;
852 zif
->rtadv
.MaxRtrAdvInterval
= interval
;
853 zif
->rtadv
.MinRtrAdvInterval
= 0.33 * interval
;
854 zif
->rtadv
.AdvIntervalTimer
= 0;
859 DEFUN (no_ipv6_nd_ra_interval
,
860 no_ipv6_nd_ra_interval_cmd
,
861 "no ipv6 nd ra-interval",
863 "Interface IPv6 config commands\n"
864 "Neighbor discovery\n"
865 "Router Advertisement interval\n")
867 struct interface
*ifp
;
868 struct zebra_if
*zif
;
869 struct zebra_vrf
*zvrf
;
871 ifp
= (struct interface
*) vty
->index
;
873 zvrf
= vrf_info_lookup (ifp
->vrf_id
);
875 if (zif
->rtadv
.MaxRtrAdvInterval
% 1000)
876 zvrf
->rtadv
.adv_msec_if_count
--;
878 zif
->rtadv
.MaxRtrAdvInterval
= RTADV_MAX_RTR_ADV_INTERVAL
;
879 zif
->rtadv
.MinRtrAdvInterval
= RTADV_MIN_RTR_ADV_INTERVAL
;
880 zif
->rtadv
.AdvIntervalTimer
= zif
->rtadv
.MaxRtrAdvInterval
;
885 ALIAS (no_ipv6_nd_ra_interval
,
886 no_ipv6_nd_ra_interval_val_cmd
,
887 "no ipv6 nd ra-interval <1-1800>",
889 "Interface IPv6 config commands\n"
890 "Neighbor discovery\n"
891 "Router Advertisement interval\n")
893 ALIAS (no_ipv6_nd_ra_interval
,
894 no_ipv6_nd_ra_interval_msec_val_cmd
,
895 "no ipv6 nd ra-interval msec <1-1800000>",
897 "Interface IPv6 config commands\n"
898 "Neighbor discovery\n"
899 "Router Advertisement interval\n"
900 "Router Advertisement interval in milliseconds\n")
902 DEFUN (ipv6_nd_ra_lifetime
,
903 ipv6_nd_ra_lifetime_cmd
,
904 "ipv6 nd ra-lifetime <0-9000>",
905 "Interface IPv6 config commands\n"
906 "Neighbor discovery\n"
908 "Router lifetime in seconds (0 stands for a non-default gw)\n")
911 struct interface
*ifp
;
912 struct zebra_if
*zif
;
914 ifp
= (struct interface
*) vty
->index
;
917 VTY_GET_INTEGER_RANGE ("router lifetime", lifetime
, argv
[0], 0, 9000);
919 /* The value to be placed in the Router Lifetime field
920 * of Router Advertisements sent from the interface,
921 * in seconds. MUST be either zero or between
922 * MaxRtrAdvInterval and 9000 seconds. -- RFC4861, 6.2.1 */
923 if ((lifetime
!= 0 && lifetime
* 1000 < zif
->rtadv
.MaxRtrAdvInterval
))
925 vty_out (vty
, "This ra-lifetime would conflict with configured ra-interval%s", VTY_NEWLINE
);
929 zif
->rtadv
.AdvDefaultLifetime
= lifetime
;
934 DEFUN (no_ipv6_nd_ra_lifetime
,
935 no_ipv6_nd_ra_lifetime_cmd
,
936 "no ipv6 nd ra-lifetime",
938 "Interface IPv6 config commands\n"
939 "Neighbor discovery\n"
942 struct interface
*ifp
;
943 struct zebra_if
*zif
;
945 ifp
= (struct interface
*) vty
->index
;
948 zif
->rtadv
.AdvDefaultLifetime
= -1;
953 ALIAS (no_ipv6_nd_ra_lifetime
,
954 no_ipv6_nd_ra_lifetime_val_cmd
,
955 "no ipv6 nd ra-lifetime <0-9000>",
957 "Interface IPv6 config commands\n"
958 "Neighbor discovery\n"
960 "Router lifetime in seconds (0 stands for a non-default gw)\n")
962 DEFUN (ipv6_nd_reachable_time
,
963 ipv6_nd_reachable_time_cmd
,
964 "ipv6 nd reachable-time <1-3600000>",
965 "Interface IPv6 config commands\n"
966 "Neighbor discovery\n"
968 "Reachable time in milliseconds\n")
970 struct interface
*ifp
= (struct interface
*) vty
->index
;
971 struct zebra_if
*zif
= ifp
->info
;
972 VTY_GET_INTEGER_RANGE ("reachable time", zif
->rtadv
.AdvReachableTime
, argv
[0], 1, RTADV_MAX_REACHABLE_TIME
);
976 DEFUN (no_ipv6_nd_reachable_time
,
977 no_ipv6_nd_reachable_time_cmd
,
978 "no ipv6 nd reachable-time",
980 "Interface IPv6 config commands\n"
981 "Neighbor discovery\n"
984 struct interface
*ifp
;
985 struct zebra_if
*zif
;
987 ifp
= (struct interface
*) vty
->index
;
990 zif
->rtadv
.AdvReachableTime
= 0;
995 ALIAS (no_ipv6_nd_reachable_time
,
996 no_ipv6_nd_reachable_time_val_cmd
,
997 "no ipv6 nd reachable-time <1-3600000>",
999 "Interface IPv6 config commands\n"
1000 "Neighbor discovery\n"
1002 "Reachable time in milliseconds\n")
1004 DEFUN (ipv6_nd_homeagent_preference
,
1005 ipv6_nd_homeagent_preference_cmd
,
1006 "ipv6 nd home-agent-preference <0-65535>",
1007 "Interface IPv6 config commands\n"
1008 "Neighbor discovery\n"
1009 "Home Agent preference\n"
1010 "preference value (default is 0, least preferred)\n")
1012 struct interface
*ifp
= (struct interface
*) vty
->index
;
1013 struct zebra_if
*zif
= ifp
->info
;
1014 VTY_GET_INTEGER_RANGE ("home agent preference", zif
->rtadv
.HomeAgentPreference
, argv
[0], 0, 65535);
1018 DEFUN (no_ipv6_nd_homeagent_preference
,
1019 no_ipv6_nd_homeagent_preference_cmd
,
1020 "no ipv6 nd home-agent-preference",
1022 "Interface IPv6 config commands\n"
1023 "Neighbor discovery\n"
1024 "Home Agent preference\n")
1026 struct interface
*ifp
;
1027 struct zebra_if
*zif
;
1029 ifp
= (struct interface
*) vty
->index
;
1032 zif
->rtadv
.HomeAgentPreference
= 0;
1037 ALIAS (no_ipv6_nd_homeagent_preference
,
1038 no_ipv6_nd_homeagent_preference_val_cmd
,
1039 "no ipv6 nd home-agent-preference <0-65535>",
1041 "Interface IPv6 config commands\n"
1042 "Neighbor discovery\n"
1043 "Home Agent preference\n"
1044 "preference value (default is 0, least preferred)\n")
1046 DEFUN (ipv6_nd_homeagent_lifetime
,
1047 ipv6_nd_homeagent_lifetime_cmd
,
1048 "ipv6 nd home-agent-lifetime <0-65520>",
1049 "Interface IPv6 config commands\n"
1050 "Neighbor discovery\n"
1051 "Home Agent lifetime\n"
1052 "Home Agent lifetime in seconds (0 to track ra-lifetime)\n")
1054 struct interface
*ifp
= (struct interface
*) vty
->index
;
1055 struct zebra_if
*zif
= ifp
->info
;
1056 VTY_GET_INTEGER_RANGE ("home agent lifetime", zif
->rtadv
.HomeAgentLifetime
, argv
[0], 0, RTADV_MAX_HALIFETIME
);
1060 DEFUN (no_ipv6_nd_homeagent_lifetime
,
1061 no_ipv6_nd_homeagent_lifetime_cmd
,
1062 "no ipv6 nd home-agent-lifetime",
1064 "Interface IPv6 config commands\n"
1065 "Neighbor discovery\n"
1066 "Home Agent lifetime\n")
1068 struct interface
*ifp
;
1069 struct zebra_if
*zif
;
1071 ifp
= (struct interface
*) vty
->index
;
1074 zif
->rtadv
.HomeAgentLifetime
= -1;
1079 ALIAS (no_ipv6_nd_homeagent_lifetime
,
1080 no_ipv6_nd_homeagent_lifetime_val_cmd
,
1081 "no ipv6 nd home-agent-lifetime <0-65520>",
1083 "Interface IPv6 config commands\n"
1084 "Neighbor discovery\n"
1085 "Home Agent lifetime\n"
1086 "Home Agent lifetime in seconds (0 to track ra-lifetime)\n")
1088 DEFUN (ipv6_nd_managed_config_flag
,
1089 ipv6_nd_managed_config_flag_cmd
,
1090 "ipv6 nd managed-config-flag",
1091 "Interface IPv6 config commands\n"
1092 "Neighbor discovery\n"
1093 "Managed address configuration flag\n")
1095 struct interface
*ifp
;
1096 struct zebra_if
*zif
;
1098 ifp
= (struct interface
*) vty
->index
;
1101 zif
->rtadv
.AdvManagedFlag
= 1;
1106 DEFUN (no_ipv6_nd_managed_config_flag
,
1107 no_ipv6_nd_managed_config_flag_cmd
,
1108 "no ipv6 nd managed-config-flag",
1110 "Interface IPv6 config commands\n"
1111 "Neighbor discovery\n"
1112 "Managed address configuration flag\n")
1114 struct interface
*ifp
;
1115 struct zebra_if
*zif
;
1117 ifp
= (struct interface
*) vty
->index
;
1120 zif
->rtadv
.AdvManagedFlag
= 0;
1125 DEFUN (ipv6_nd_homeagent_config_flag
,
1126 ipv6_nd_homeagent_config_flag_cmd
,
1127 "ipv6 nd home-agent-config-flag",
1128 "Interface IPv6 config commands\n"
1129 "Neighbor discovery\n"
1130 "Home Agent configuration flag\n")
1132 struct interface
*ifp
;
1133 struct zebra_if
*zif
;
1135 ifp
= (struct interface
*) vty
->index
;
1138 zif
->rtadv
.AdvHomeAgentFlag
= 1;
1143 DEFUN (no_ipv6_nd_homeagent_config_flag
,
1144 no_ipv6_nd_homeagent_config_flag_cmd
,
1145 "no ipv6 nd home-agent-config-flag",
1147 "Interface IPv6 config commands\n"
1148 "Neighbor discovery\n"
1149 "Home Agent configuration flag\n")
1151 struct interface
*ifp
;
1152 struct zebra_if
*zif
;
1154 ifp
= (struct interface
*) vty
->index
;
1157 zif
->rtadv
.AdvHomeAgentFlag
= 0;
1162 DEFUN (ipv6_nd_adv_interval_config_option
,
1163 ipv6_nd_adv_interval_config_option_cmd
,
1164 "ipv6 nd adv-interval-option",
1165 "Interface IPv6 config commands\n"
1166 "Neighbor discovery\n"
1167 "Advertisement Interval Option\n")
1169 struct interface
*ifp
;
1170 struct zebra_if
*zif
;
1172 ifp
= (struct interface
*) vty
->index
;
1175 zif
->rtadv
.AdvIntervalOption
= 1;
1180 DEFUN (no_ipv6_nd_adv_interval_config_option
,
1181 no_ipv6_nd_adv_interval_config_option_cmd
,
1182 "no ipv6 nd adv-interval-option",
1184 "Interface IPv6 config commands\n"
1185 "Neighbor discovery\n"
1186 "Advertisement Interval Option\n")
1188 struct interface
*ifp
;
1189 struct zebra_if
*zif
;
1191 ifp
= (struct interface
*) vty
->index
;
1194 zif
->rtadv
.AdvIntervalOption
= 0;
1199 DEFUN (ipv6_nd_other_config_flag
,
1200 ipv6_nd_other_config_flag_cmd
,
1201 "ipv6 nd other-config-flag",
1202 "Interface IPv6 config commands\n"
1203 "Neighbor discovery\n"
1204 "Other statefull configuration flag\n")
1206 struct interface
*ifp
;
1207 struct zebra_if
*zif
;
1209 ifp
= (struct interface
*) vty
->index
;
1212 zif
->rtadv
.AdvOtherConfigFlag
= 1;
1217 DEFUN (no_ipv6_nd_other_config_flag
,
1218 no_ipv6_nd_other_config_flag_cmd
,
1219 "no ipv6 nd other-config-flag",
1221 "Interface IPv6 config commands\n"
1222 "Neighbor discovery\n"
1223 "Other statefull configuration flag\n")
1225 struct interface
*ifp
;
1226 struct zebra_if
*zif
;
1228 ifp
= (struct interface
*) vty
->index
;
1231 zif
->rtadv
.AdvOtherConfigFlag
= 0;
1236 DEFUN (ipv6_nd_prefix
,
1238 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1239 "(<0-4294967295>|infinite) (off-link|) (no-autoconfig|) (router-address|)",
1240 "Interface IPv6 config commands\n"
1241 "Neighbor discovery\n"
1242 "Prefix information\n"
1244 "Valid lifetime in seconds\n"
1245 "Infinite valid lifetime\n"
1246 "Preferred lifetime in seconds\n"
1247 "Infinite preferred lifetime\n"
1248 "Do not use prefix for onlink determination\n"
1249 "Do not use prefix for autoconfiguration\n"
1250 "Set Router Address flag\n")
1255 struct interface
*ifp
;
1256 struct zebra_if
*zebra_if
;
1257 struct rtadv_prefix rp
;
1259 ifp
= (struct interface
*) vty
->index
;
1260 zebra_if
= ifp
->info
;
1262 ret
= str2prefix_ipv6 (argv
[0], &rp
.prefix
);
1265 vty_out (vty
, "Malformed IPv6 prefix%s", VTY_NEWLINE
);
1268 apply_mask_ipv6 (&rp
.prefix
); /* RFC4861 4.6.2 */
1269 rp
.AdvOnLinkFlag
= 1;
1270 rp
.AdvAutonomousFlag
= 1;
1271 rp
.AdvRouterAddressFlag
= 0;
1272 rp
.AdvValidLifetime
= RTADV_VALID_LIFETIME
;
1273 rp
.AdvPreferredLifetime
= RTADV_PREFERRED_LIFETIME
;
1277 if ((isdigit(argv
[1][0])) || strncmp (argv
[1], "i", 1) == 0)
1279 if ( strncmp (argv
[1], "i", 1) == 0)
1280 rp
.AdvValidLifetime
= UINT32_MAX
;
1282 rp
.AdvValidLifetime
= (u_int32_t
) strtoll (argv
[1],
1285 if ( strncmp (argv
[2], "i", 1) == 0)
1286 rp
.AdvPreferredLifetime
= UINT32_MAX
;
1288 rp
.AdvPreferredLifetime
= (u_int32_t
) strtoll (argv
[2],
1291 if (rp
.AdvPreferredLifetime
> rp
.AdvValidLifetime
)
1293 vty_out (vty
, "Invalid preferred lifetime%s", VTY_NEWLINE
);
1296 cursor
= cursor
+ 2;
1300 for (i
= cursor
; i
< argc
; i
++)
1302 if (strncmp (argv
[i
], "of", 2) == 0)
1303 rp
.AdvOnLinkFlag
= 0;
1304 if (strncmp (argv
[i
], "no", 2) == 0)
1305 rp
.AdvAutonomousFlag
= 0;
1306 if (strncmp (argv
[i
], "ro", 2) == 0)
1307 rp
.AdvRouterAddressFlag
= 1;
1312 rtadv_prefix_set (zebra_if
, &rp
);
1317 ALIAS (ipv6_nd_prefix
,
1318 ipv6_nd_prefix_val_nortaddr_cmd
,
1319 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1320 "(<0-4294967295>|infinite) (off-link|) (no-autoconfig|)",
1321 "Interface IPv6 config commands\n"
1322 "Neighbor discovery\n"
1323 "Prefix information\n"
1325 "Valid lifetime in seconds\n"
1326 "Infinite valid lifetime\n"
1327 "Preferred lifetime in seconds\n"
1328 "Infinite preferred lifetime\n"
1329 "Do not use prefix for onlink determination\n"
1330 "Do not use prefix for autoconfiguration\n")
1332 ALIAS (ipv6_nd_prefix
,
1333 ipv6_nd_prefix_val_rev_cmd
,
1334 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1335 "(<0-4294967295>|infinite) (no-autoconfig|) (off-link|)",
1336 "Interface IPv6 config commands\n"
1337 "Neighbor discovery\n"
1338 "Prefix information\n"
1340 "Valid lifetime in seconds\n"
1341 "Infinite valid lifetime\n"
1342 "Preferred lifetime in seconds\n"
1343 "Infinite preferred lifetime\n"
1344 "Do not use prefix for autoconfiguration\n"
1345 "Do not use prefix for onlink determination\n")
1347 ALIAS (ipv6_nd_prefix
,
1348 ipv6_nd_prefix_val_rev_rtaddr_cmd
,
1349 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1350 "(<0-4294967295>|infinite) (no-autoconfig|) (off-link|) (router-address|)",
1351 "Interface IPv6 config commands\n"
1352 "Neighbor discovery\n"
1353 "Prefix information\n"
1355 "Valid lifetime in seconds\n"
1356 "Infinite valid lifetime\n"
1357 "Preferred lifetime in seconds\n"
1358 "Infinite preferred lifetime\n"
1359 "Do not use prefix for autoconfiguration\n"
1360 "Do not use prefix for onlink determination\n"
1361 "Set Router Address flag\n")
1363 ALIAS (ipv6_nd_prefix
,
1364 ipv6_nd_prefix_val_noauto_cmd
,
1365 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1366 "(<0-4294967295>|infinite) (no-autoconfig|)",
1367 "Interface IPv6 config commands\n"
1368 "Neighbor discovery\n"
1369 "Prefix information\n"
1371 "Valid lifetime in seconds\n"
1372 "Infinite valid lifetime\n"
1373 "Preferred lifetime in seconds\n"
1374 "Infinite preferred lifetime\n"
1375 "Do not use prefix for autoconfiguration")
1377 ALIAS (ipv6_nd_prefix
,
1378 ipv6_nd_prefix_val_offlink_cmd
,
1379 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1380 "(<0-4294967295>|infinite) (off-link|)",
1381 "Interface IPv6 config commands\n"
1382 "Neighbor discovery\n"
1383 "Prefix information\n"
1385 "Valid lifetime in seconds\n"
1386 "Infinite valid lifetime\n"
1387 "Preferred lifetime in seconds\n"
1388 "Infinite preferred lifetime\n"
1389 "Do not use prefix for onlink determination\n")
1391 ALIAS (ipv6_nd_prefix
,
1392 ipv6_nd_prefix_val_rtaddr_cmd
,
1393 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1394 "(<0-4294967295>|infinite) (router-address|)",
1395 "Interface IPv6 config commands\n"
1396 "Neighbor discovery\n"
1397 "Prefix information\n"
1399 "Valid lifetime in seconds\n"
1400 "Infinite valid lifetime\n"
1401 "Preferred lifetime in seconds\n"
1402 "Infinite preferred lifetime\n"
1403 "Set Router Address flag\n")
1405 ALIAS (ipv6_nd_prefix
,
1406 ipv6_nd_prefix_val_cmd
,
1407 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1408 "(<0-4294967295>|infinite)",
1409 "Interface IPv6 config commands\n"
1410 "Neighbor discovery\n"
1411 "Prefix information\n"
1413 "Valid lifetime in seconds\n"
1414 "Infinite valid lifetime\n"
1415 "Preferred lifetime in seconds\n"
1416 "Infinite preferred lifetime\n")
1418 ALIAS (ipv6_nd_prefix
,
1419 ipv6_nd_prefix_noval_cmd
,
1420 "ipv6 nd prefix X:X::X:X/M (no-autoconfig|) (off-link|)",
1421 "Interface IPv6 config commands\n"
1422 "Neighbor discovery\n"
1423 "Prefix information\n"
1425 "Do not use prefix for autoconfiguration\n"
1426 "Do not use prefix for onlink determination\n")
1428 ALIAS (ipv6_nd_prefix
,
1429 ipv6_nd_prefix_noval_rev_cmd
,
1430 "ipv6 nd prefix X:X::X:X/M (off-link|) (no-autoconfig|)",
1431 "Interface IPv6 config commands\n"
1432 "Neighbor discovery\n"
1433 "Prefix information\n"
1435 "Do not use prefix for onlink determination\n"
1436 "Do not use prefix for autoconfiguration\n")
1438 ALIAS (ipv6_nd_prefix
,
1439 ipv6_nd_prefix_noval_noauto_cmd
,
1440 "ipv6 nd prefix X:X::X:X/M (no-autoconfig|)",
1441 "Interface IPv6 config commands\n"
1442 "Neighbor discovery\n"
1443 "Prefix information\n"
1445 "Do not use prefix for autoconfiguration\n")
1447 ALIAS (ipv6_nd_prefix
,
1448 ipv6_nd_prefix_noval_offlink_cmd
,
1449 "ipv6 nd prefix X:X::X:X/M (off-link|)",
1450 "Interface IPv6 config commands\n"
1451 "Neighbor discovery\n"
1452 "Prefix information\n"
1454 "Do not use prefix for onlink determination\n")
1456 ALIAS (ipv6_nd_prefix
,
1457 ipv6_nd_prefix_noval_rtaddr_cmd
,
1458 "ipv6 nd prefix X:X::X:X/M (router-address|)",
1459 "Interface IPv6 config commands\n"
1460 "Neighbor discovery\n"
1461 "Prefix information\n"
1463 "Set Router Address flag\n")
1465 ALIAS (ipv6_nd_prefix
,
1466 ipv6_nd_prefix_prefix_cmd
,
1467 "ipv6 nd prefix X:X::X:X/M",
1468 "Interface IPv6 config commands\n"
1469 "Neighbor discovery\n"
1470 "Prefix information\n"
1473 DEFUN (no_ipv6_nd_prefix
,
1474 no_ipv6_nd_prefix_cmd
,
1475 "no ipv6 nd prefix IPV6PREFIX",
1477 "Interface IPv6 config commands\n"
1478 "Neighbor discovery\n"
1479 "Prefix information\n"
1483 struct interface
*ifp
;
1484 struct zebra_if
*zebra_if
;
1485 struct rtadv_prefix rp
;
1487 ifp
= (struct interface
*) vty
->index
;
1488 zebra_if
= ifp
->info
;
1490 ret
= str2prefix_ipv6 (argv
[0], &rp
.prefix
);
1493 vty_out (vty
, "Malformed IPv6 prefix%s", VTY_NEWLINE
);
1496 apply_mask_ipv6 (&rp
.prefix
); /* RFC4861 4.6.2 */
1498 ret
= rtadv_prefix_reset (zebra_if
, &rp
);
1501 vty_out (vty
, "Non-exist IPv6 prefix%s", VTY_NEWLINE
);
1508 ALIAS (no_ipv6_nd_prefix
,
1509 no_ipv6_nd_prefix_val_nortaddr_cmd
,
1510 "no ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) (<0-4294967295>|infinite) (off-link|) (no-autoconfig|) (router-address|)",
1512 "Interface IPv6 config commands\n"
1513 "Neighbor discovery\n"
1514 "Prefix information\n"
1516 "Valid lifetime in seconds\n"
1517 "Infinite valid lifetime\n"
1518 "Preferred lifetime in seconds\n"
1519 "Infinite preferred lifetime\n"
1520 "Do not use prefix for onlink determination\n"
1521 "Do not use prefix for autoconfiguration\n"
1522 "Set Router Address flag\n")
1524 ALIAS (no_ipv6_nd_prefix
,
1525 no_ipv6_nd_prefix_val_rev_cmd
,
1526 "no ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) (<0-4294967295>|infinite) (no-autoconfig|) (off-link|)",
1528 "Interface IPv6 config commands\n"
1529 "Neighbor discovery\n"
1530 "Prefix information\n"
1532 "Valid lifetime in seconds\n"
1533 "Infinite valid lifetime\n"
1534 "Preferred lifetime in seconds\n"
1535 "Infinite preferred lifetime\n"
1536 "Do not use prefix for autoconfiguration\n"
1537 "Do not use prefix for onlink determination\n")
1539 ALIAS (no_ipv6_nd_prefix
,
1540 no_ipv6_nd_prefix_val_rev_rtaddr_cmd
,
1541 "no ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) (<0-4294967295>|infinite) (no-autoconfig|) (off-link|) (router-address|)",
1543 "Interface IPv6 config commands\n"
1544 "Neighbor discovery\n"
1545 "Prefix information\n"
1547 "Valid lifetime in seconds\n"
1548 "Infinite valid lifetime\n"
1549 "Preferred lifetime in seconds\n"
1550 "Infinite preferred lifetime\n"
1551 "Do not use prefix for autoconfiguration\n"
1552 "Do not use prefix for onlink determination\n"
1553 "Set Router Address flag\n")
1555 ALIAS (no_ipv6_nd_prefix
,
1556 no_ipv6_nd_prefix_val_noauto_cmd
,
1557 "no ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) (<0-4294967295>|infinite) (no-autoconfig|)",
1559 "Interface IPv6 config commands\n"
1560 "Neighbor discovery\n"
1561 "Prefix information\n"
1563 "Valid lifetime in seconds\n"
1564 "Infinite valid lifetime\n"
1565 "Preferred lifetime in seconds\n"
1566 "Infinite preferred lifetime\n"
1567 "Do not use prefix for autoconfiguration")
1569 ALIAS (no_ipv6_nd_prefix
,
1570 no_ipv6_nd_prefix_val_offlink_cmd
,
1571 "no ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) (<0-4294967295>|infinite) (off-link|)",
1573 "Interface IPv6 config commands\n"
1574 "Neighbor discovery\n"
1575 "Prefix information\n"
1577 "Valid lifetime in seconds\n"
1578 "Infinite valid lifetime\n"
1579 "Preferred lifetime in seconds\n"
1580 "Infinite preferred lifetime\n"
1581 "Do not use prefix for onlink determination\n")
1583 ALIAS (no_ipv6_nd_prefix
,
1584 no_ipv6_nd_prefix_val_rtaddr_cmd
,
1585 "no ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) (<0-4294967295>|infinite) (router-address|)",
1587 "Interface IPv6 config commands\n"
1588 "Neighbor discovery\n"
1589 "Prefix information\n"
1591 "Valid lifetime in seconds\n"
1592 "Infinite valid lifetime\n"
1593 "Preferred lifetime in seconds\n"
1594 "Infinite preferred lifetime\n"
1595 "Set Router Address flag\n")
1597 ALIAS (no_ipv6_nd_prefix
,
1598 no_ipv6_nd_prefix_val_cmd
,
1599 "no ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) (<0-4294967295>|infinite)",
1601 "Interface IPv6 config commands\n"
1602 "Neighbor discovery\n"
1603 "Prefix information\n"
1605 "Valid lifetime in seconds\n"
1606 "Infinite valid lifetime\n"
1607 "Preferred lifetime in seconds\n"
1608 "Infinite preferred lifetime\n")
1610 ALIAS (no_ipv6_nd_prefix
,
1611 no_ipv6_nd_prefix_noval_cmd
,
1612 "no ipv6 nd prefix X:X::X:X/M (no-autoconfig|) (off-link|)",
1614 "Interface IPv6 config commands\n"
1615 "Neighbor discovery\n"
1616 "Prefix information\n"
1618 "Do not use prefix for autoconfiguration\n"
1619 "Do not use prefix for onlink determination\n")
1621 ALIAS (no_ipv6_nd_prefix
,
1622 no_ipv6_nd_prefix_noval_rev_cmd
,
1623 "no ipv6 nd prefix X:X::X:X/M (off-link|) (no-autoconfig|)",
1625 "Interface IPv6 config commands\n"
1626 "Neighbor discovery\n"
1627 "Prefix information\n"
1629 "Do not use prefix for onlink determination\n"
1630 "Do not use prefix for autoconfiguration\n")
1632 ALIAS (no_ipv6_nd_prefix
,
1633 no_ipv6_nd_prefix_noval_noauto_cmd
,
1634 "no ipv6 nd prefix X:X::X:X/M (no-autoconfig|)",
1636 "Interface IPv6 config commands\n"
1637 "Neighbor discovery\n"
1638 "Prefix information\n"
1640 "Do not use prefix for autoconfiguration\n")
1642 ALIAS (no_ipv6_nd_prefix
,
1643 no_ipv6_nd_prefix_noval_offlink_cmd
,
1644 "no ipv6 nd prefix X:X::X:X/M (off-link|)",
1646 "Interface IPv6 config commands\n"
1647 "Neighbor discovery\n"
1648 "Prefix information\n"
1650 "Do not use prefix for onlink determination\n")
1652 ALIAS (no_ipv6_nd_prefix
,
1653 no_ipv6_nd_prefix_noval_rtaddr_cmd
,
1654 "no ipv6 nd prefix X:X::X:X/M (router-address|)",
1656 "Interface IPv6 config commands\n"
1657 "Neighbor discovery\n"
1658 "Prefix information\n"
1660 "Set Router Address flag\n")
1662 DEFUN (ipv6_nd_router_preference
,
1663 ipv6_nd_router_preference_cmd
,
1664 "ipv6 nd router-preference (high|medium|low)",
1665 "Interface IPv6 config commands\n"
1666 "Neighbor discovery\n"
1667 "Default router preference\n"
1668 "High default router preference\n"
1669 "Low default router preference\n"
1670 "Medium default router preference (default)\n")
1672 struct interface
*ifp
;
1673 struct zebra_if
*zif
;
1676 ifp
= (struct interface
*) vty
->index
;
1679 while (0 != rtadv_pref_strs
[i
])
1681 if (strncmp (argv
[0], rtadv_pref_strs
[i
], 1) == 0)
1683 zif
->rtadv
.DefaultPreference
= i
;
1689 return CMD_ERR_NO_MATCH
;
1692 DEFUN (no_ipv6_nd_router_preference
,
1693 no_ipv6_nd_router_preference_cmd
,
1694 "no ipv6 nd router-preference",
1696 "Interface IPv6 config commands\n"
1697 "Neighbor discovery\n"
1698 "Default router preference\n")
1700 struct interface
*ifp
;
1701 struct zebra_if
*zif
;
1703 ifp
= (struct interface
*) vty
->index
;
1706 zif
->rtadv
.DefaultPreference
= RTADV_PREF_MEDIUM
; /* Default per RFC4191. */
1711 ALIAS (no_ipv6_nd_router_preference
,
1712 no_ipv6_nd_router_preference_val_cmd
,
1713 "no ipv6 nd router-preference (high|medium|low)",
1715 "Interface IPv6 config commands\n"
1716 "Neighbor discovery\n"
1717 "Default router preference\n"
1718 "High default router preference\n"
1719 "Low default router preference\n"
1720 "Medium default router preference (default)\n")
1724 "ipv6 nd mtu <1-65535>",
1725 "Interface IPv6 config commands\n"
1726 "Neighbor discovery\n"
1730 struct interface
*ifp
= (struct interface
*) vty
->index
;
1731 struct zebra_if
*zif
= ifp
->info
;
1732 VTY_GET_INTEGER_RANGE ("MTU", zif
->rtadv
.AdvLinkMTU
, argv
[0], 1, 65535);
1736 DEFUN (no_ipv6_nd_mtu
,
1740 "Interface IPv6 config commands\n"
1741 "Neighbor discovery\n"
1744 struct interface
*ifp
= (struct interface
*) vty
->index
;
1745 struct zebra_if
*zif
= ifp
->info
;
1746 zif
->rtadv
.AdvLinkMTU
= 0;
1750 ALIAS (no_ipv6_nd_mtu
,
1751 no_ipv6_nd_mtu_val_cmd
,
1752 "no ipv6 nd mtu <1-65535>",
1754 "Interface IPv6 config commands\n"
1755 "Neighbor discovery\n"
1759 /* Write configuration about router advertisement. */
1761 rtadv_config_write (struct vty
*vty
, struct interface
*ifp
)
1763 struct zebra_if
*zif
;
1764 struct listnode
*node
;
1765 struct rtadv_prefix
*rprefix
;
1766 u_char buf
[INET6_ADDRSTRLEN
];
1771 if (! if_is_loopback (ifp
))
1773 if (ipv6_address_configured(ifp
))
1775 if (! zif
->rtadv
.AdvSendAdvertisements
)
1776 vty_out (vty
, " ipv6 nd suppress-ra%s", VTY_NEWLINE
);
1780 if (zif
->rtadv
.AdvSendAdvertisements
)
1781 vty_out (vty
, " no ipv6 nd suppress-ra%s", VTY_NEWLINE
);
1785 interval
= zif
->rtadv
.MaxRtrAdvInterval
;
1786 if (interval
% 1000)
1787 vty_out (vty
, " ipv6 nd ra-interval msec %d%s", interval
,
1790 if (interval
!= RTADV_MAX_RTR_ADV_INTERVAL
)
1791 vty_out (vty
, " ipv6 nd ra-interval %d%s", interval
/ 1000,
1794 if (zif
->rtadv
.AdvIntervalOption
)
1795 vty_out (vty
, " ipv6 nd adv-interval-option%s", VTY_NEWLINE
);
1797 if (zif
->rtadv
.AdvDefaultLifetime
!= -1)
1798 vty_out (vty
, " ipv6 nd ra-lifetime %d%s", zif
->rtadv
.AdvDefaultLifetime
,
1801 if (zif
->rtadv
.HomeAgentPreference
)
1802 vty_out (vty
, " ipv6 nd home-agent-preference %u%s",
1803 zif
->rtadv
.HomeAgentPreference
, VTY_NEWLINE
);
1805 if (zif
->rtadv
.HomeAgentLifetime
!= -1)
1806 vty_out (vty
, " ipv6 nd home-agent-lifetime %u%s",
1807 zif
->rtadv
.HomeAgentLifetime
, VTY_NEWLINE
);
1809 if (zif
->rtadv
.AdvHomeAgentFlag
)
1810 vty_out (vty
, " ipv6 nd home-agent-config-flag%s", VTY_NEWLINE
);
1812 if (zif
->rtadv
.AdvReachableTime
)
1813 vty_out (vty
, " ipv6 nd reachable-time %d%s", zif
->rtadv
.AdvReachableTime
,
1816 if (zif
->rtadv
.AdvManagedFlag
)
1817 vty_out (vty
, " ipv6 nd managed-config-flag%s", VTY_NEWLINE
);
1819 if (zif
->rtadv
.AdvOtherConfigFlag
)
1820 vty_out (vty
, " ipv6 nd other-config-flag%s", VTY_NEWLINE
);
1822 if (zif
->rtadv
.DefaultPreference
!= RTADV_PREF_MEDIUM
)
1823 vty_out (vty
, " ipv6 nd router-preference %s%s",
1824 rtadv_pref_strs
[zif
->rtadv
.DefaultPreference
],
1827 if (zif
->rtadv
.AdvLinkMTU
)
1828 vty_out (vty
, " ipv6 nd mtu %d%s", zif
->rtadv
.AdvLinkMTU
, VTY_NEWLINE
);
1830 for (ALL_LIST_ELEMENTS_RO (zif
->rtadv
.AdvPrefixList
, node
, rprefix
))
1832 vty_out (vty
, " ipv6 nd prefix %s/%d",
1833 inet_ntop (AF_INET6
, &rprefix
->prefix
.prefix
,
1834 (char *) buf
, INET6_ADDRSTRLEN
),
1835 rprefix
->prefix
.prefixlen
);
1836 if ((rprefix
->AdvValidLifetime
!= RTADV_VALID_LIFETIME
) ||
1837 (rprefix
->AdvPreferredLifetime
!= RTADV_PREFERRED_LIFETIME
))
1839 if (rprefix
->AdvValidLifetime
== UINT32_MAX
)
1840 vty_out (vty
, " infinite");
1842 vty_out (vty
, " %u", rprefix
->AdvValidLifetime
);
1843 if (rprefix
->AdvPreferredLifetime
== UINT32_MAX
)
1844 vty_out (vty
, " infinite");
1846 vty_out (vty
, " %u", rprefix
->AdvPreferredLifetime
);
1848 if (!rprefix
->AdvOnLinkFlag
)
1849 vty_out (vty
, " off-link");
1850 if (!rprefix
->AdvAutonomousFlag
)
1851 vty_out (vty
, " no-autoconfig");
1852 if (rprefix
->AdvRouterAddressFlag
)
1853 vty_out (vty
, " router-address");
1854 vty_out (vty
, "%s", VTY_NEWLINE
);
1860 rtadv_event (struct zebra_vrf
*zvrf
, enum rtadv_event event
, int val
)
1862 struct rtadv
*rtadv
= &zvrf
->rtadv
;
1867 if (! rtadv
->ra_read
)
1868 rtadv
->ra_read
= thread_add_read (zebrad
.master
, rtadv_read
, zvrf
, val
);
1869 if (! rtadv
->ra_timer
)
1870 rtadv
->ra_timer
= thread_add_event (zebrad
.master
, rtadv_timer
,
1874 if (rtadv
->ra_timer
)
1876 thread_cancel (rtadv
->ra_timer
);
1877 rtadv
->ra_timer
= NULL
;
1881 thread_cancel (rtadv
->ra_read
);
1882 rtadv
->ra_read
= NULL
;
1886 if (! rtadv
->ra_timer
)
1887 rtadv
->ra_timer
= thread_add_timer (zebrad
.master
, rtadv_timer
, zvrf
,
1890 case RTADV_TIMER_MSEC
:
1891 if (! rtadv
->ra_timer
)
1892 rtadv
->ra_timer
= thread_add_timer_msec (zebrad
.master
, rtadv_timer
,
1896 if (! rtadv
->ra_read
)
1897 rtadv
->ra_read
= thread_add_read (zebrad
.master
, rtadv_read
, zvrf
, val
);
1906 rtadv_init (struct zebra_vrf
*zvrf
)
1908 zvrf
->rtadv
.sock
= rtadv_make_socket (zvrf
->vrf_id
);
1912 rtadv_terminate (struct zebra_vrf
*zvrf
)
1914 rtadv_event (zvrf
, RTADV_STOP
, 0);
1916 if (zvrf
->rtadv
.sock
>= 0)
1918 close (zvrf
->rtadv
.sock
);
1919 zvrf
->rtadv
.sock
= -1;
1922 zvrf
->rtadv
.adv_if_count
= 0;
1923 zvrf
->rtadv
.adv_msec_if_count
= 0;
1927 rtadv_cmd_init (void)
1929 install_element (INTERFACE_NODE
, &ipv6_nd_suppress_ra_cmd
);
1930 install_element (INTERFACE_NODE
, &no_ipv6_nd_suppress_ra_cmd
);
1931 install_element (INTERFACE_NODE
, &ipv6_nd_ra_interval_cmd
);
1932 install_element (INTERFACE_NODE
, &ipv6_nd_ra_interval_msec_cmd
);
1933 install_element (INTERFACE_NODE
, &no_ipv6_nd_ra_interval_cmd
);
1934 install_element (INTERFACE_NODE
, &no_ipv6_nd_ra_interval_val_cmd
);
1935 install_element (INTERFACE_NODE
, &no_ipv6_nd_ra_interval_msec_val_cmd
);
1936 install_element (INTERFACE_NODE
, &ipv6_nd_ra_lifetime_cmd
);
1937 install_element (INTERFACE_NODE
, &no_ipv6_nd_ra_lifetime_cmd
);
1938 install_element (INTERFACE_NODE
, &no_ipv6_nd_ra_lifetime_val_cmd
);
1939 install_element (INTERFACE_NODE
, &ipv6_nd_reachable_time_cmd
);
1940 install_element (INTERFACE_NODE
, &no_ipv6_nd_reachable_time_cmd
);
1941 install_element (INTERFACE_NODE
, &no_ipv6_nd_reachable_time_val_cmd
);
1942 install_element (INTERFACE_NODE
, &ipv6_nd_managed_config_flag_cmd
);
1943 install_element (INTERFACE_NODE
, &no_ipv6_nd_managed_config_flag_cmd
);
1944 install_element (INTERFACE_NODE
, &ipv6_nd_other_config_flag_cmd
);
1945 install_element (INTERFACE_NODE
, &no_ipv6_nd_other_config_flag_cmd
);
1946 install_element (INTERFACE_NODE
, &ipv6_nd_homeagent_config_flag_cmd
);
1947 install_element (INTERFACE_NODE
, &no_ipv6_nd_homeagent_config_flag_cmd
);
1948 install_element (INTERFACE_NODE
, &ipv6_nd_homeagent_preference_cmd
);
1949 install_element (INTERFACE_NODE
, &no_ipv6_nd_homeagent_preference_cmd
);
1950 install_element (INTERFACE_NODE
, &no_ipv6_nd_homeagent_preference_val_cmd
);
1951 install_element (INTERFACE_NODE
, &ipv6_nd_homeagent_lifetime_cmd
);
1952 install_element (INTERFACE_NODE
, &no_ipv6_nd_homeagent_lifetime_cmd
);
1953 install_element (INTERFACE_NODE
, &no_ipv6_nd_homeagent_lifetime_val_cmd
);
1954 install_element (INTERFACE_NODE
, &ipv6_nd_adv_interval_config_option_cmd
);
1955 install_element (INTERFACE_NODE
, &no_ipv6_nd_adv_interval_config_option_cmd
);
1956 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_cmd
);
1957 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_val_rev_rtaddr_cmd
);
1958 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_val_nortaddr_cmd
);
1959 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_val_rev_cmd
);
1960 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_val_noauto_cmd
);
1961 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_val_offlink_cmd
);
1962 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_val_rtaddr_cmd
);
1963 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_val_cmd
);
1964 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_noval_cmd
);
1965 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_noval_rev_cmd
);
1966 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_noval_noauto_cmd
);
1967 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_noval_offlink_cmd
);
1968 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_noval_rtaddr_cmd
);
1969 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_prefix_cmd
);
1970 install_element (INTERFACE_NODE
, &no_ipv6_nd_prefix_cmd
);
1971 install_element (INTERFACE_NODE
, &no_ipv6_nd_prefix_val_rev_rtaddr_cmd
);
1972 install_element (INTERFACE_NODE
, &no_ipv6_nd_prefix_val_nortaddr_cmd
);
1973 install_element (INTERFACE_NODE
, &no_ipv6_nd_prefix_val_rev_cmd
);
1974 install_element (INTERFACE_NODE
, &no_ipv6_nd_prefix_val_noauto_cmd
);
1975 install_element (INTERFACE_NODE
, &no_ipv6_nd_prefix_val_offlink_cmd
);
1976 install_element (INTERFACE_NODE
, &no_ipv6_nd_prefix_val_rtaddr_cmd
);
1977 install_element (INTERFACE_NODE
, &no_ipv6_nd_prefix_val_cmd
);
1978 install_element (INTERFACE_NODE
, &no_ipv6_nd_prefix_noval_cmd
);
1979 install_element (INTERFACE_NODE
, &no_ipv6_nd_prefix_noval_rev_cmd
);
1980 install_element (INTERFACE_NODE
, &no_ipv6_nd_prefix_noval_noauto_cmd
);
1981 install_element (INTERFACE_NODE
, &no_ipv6_nd_prefix_noval_offlink_cmd
);
1982 install_element (INTERFACE_NODE
, &no_ipv6_nd_prefix_noval_rtaddr_cmd
);
1983 install_element (INTERFACE_NODE
, &ipv6_nd_router_preference_cmd
);
1984 install_element (INTERFACE_NODE
, &no_ipv6_nd_router_preference_cmd
);
1985 install_element (INTERFACE_NODE
, &no_ipv6_nd_router_preference_val_cmd
);
1986 install_element (INTERFACE_NODE
, &ipv6_nd_mtu_cmd
);
1987 install_element (INTERFACE_NODE
, &no_ipv6_nd_mtu_cmd
);
1988 install_element (INTERFACE_NODE
, &no_ipv6_nd_mtu_val_cmd
);
1992 if_join_all_router (int sock
, struct interface
*ifp
)
1996 struct ipv6_mreq mreq
;
1998 memset (&mreq
, 0, sizeof (struct ipv6_mreq
));
1999 inet_pton (AF_INET6
, ALLROUTER
, &mreq
.ipv6mr_multiaddr
);
2000 mreq
.ipv6mr_interface
= ifp
->ifindex
;
2002 ret
= setsockopt (sock
, IPPROTO_IPV6
, IPV6_JOIN_GROUP
,
2003 (char *) &mreq
, sizeof mreq
);
2005 zlog_warn ("can't setsockopt IPV6_JOIN_GROUP: %s", safe_strerror (errno
));
2007 zlog_info ("rtadv: %s join to all-routers multicast group", ifp
->name
);
2013 if_leave_all_router (int sock
, struct interface
*ifp
)
2017 struct ipv6_mreq mreq
;
2019 memset (&mreq
, 0, sizeof (struct ipv6_mreq
));
2020 inet_pton (AF_INET6
, ALLROUTER
, &mreq
.ipv6mr_multiaddr
);
2021 mreq
.ipv6mr_interface
= ifp
->ifindex
;
2023 ret
= setsockopt (sock
, IPPROTO_IPV6
, IPV6_LEAVE_GROUP
,
2024 (char *) &mreq
, sizeof mreq
);
2026 zlog_warn ("can't setsockopt IPV6_LEAVE_GROUP: %s", safe_strerror (errno
));
2028 zlog_info ("rtadv: %s leave from all-routers multicast group", ifp
->name
);
2035 rtadv_init (struct zebra_vrf
*zvrf
)
2040 rtadv_terminate (struct zebra_vrf
*zvrf
)
2045 rtadv_cmd_init (void)
2049 #endif /* HAVE_RTADV && HAVE_IPV6 */