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
26 #include "zebra_memory.h"
38 #include "zebra/interface.h"
39 #include "zebra/rtadv.h"
40 #include "zebra/debug.h"
41 #include "zebra/rib.h"
42 #include "zebra/zserv.h"
43 #include "zebra/zebra_ns.h"
44 #include "zebra/zebra_vrf.h"
46 extern struct zebra_privs_t zserv_privs
;
48 #if defined (HAVE_IPV6) && defined (HAVE_RTADV)
51 #include <netinet/icmp6.h>
54 /* If RFC2133 definition is used. */
55 #ifndef IPV6_JOIN_GROUP
56 #define IPV6_JOIN_GROUP IPV6_ADD_MEMBERSHIP
58 #ifndef IPV6_LEAVE_GROUP
59 #define IPV6_LEAVE_GROUP IPV6_DROP_MEMBERSHIP
62 #define ALLNODE "ff02::1"
63 #define ALLROUTER "ff02::2"
65 enum rtadv_event
{RTADV_START
, RTADV_STOP
, RTADV_TIMER
,
66 RTADV_TIMER_MSEC
, RTADV_READ
};
68 static void rtadv_event (struct zebra_ns
*, enum rtadv_event
, int);
70 static int if_join_all_router (int, struct interface
*);
71 static int if_leave_all_router (int, struct interface
*);
74 rtadv_increment_received(struct zebra_ns
*zns
, ifindex_t
*ifindex
)
77 struct interface
*iface
;
80 iface
= if_lookup_by_index_per_ns (zns
, *ifindex
);
81 if (iface
&& iface
->info
)
91 rtadv_recv_packet (struct zebra_ns
*zns
, int sock
, u_char
*buf
, int buflen
,
92 struct sockaddr_in6
*from
, ifindex_t
*ifindex
,
98 struct cmsghdr
*cmsgptr
;
103 /* Fill in message and iovec. */
104 msg
.msg_name
= (void *) from
;
105 msg
.msg_namelen
= sizeof (struct sockaddr_in6
);
108 msg
.msg_control
= (void *) adata
;
109 msg
.msg_controllen
= sizeof adata
;
111 iov
.iov_len
= buflen
;
113 /* If recvmsg fail return minus value. */
114 ret
= recvmsg (sock
, &msg
, 0);
118 for (cmsgptr
= ZCMSG_FIRSTHDR(&msg
); cmsgptr
!= NULL
;
119 cmsgptr
= CMSG_NXTHDR(&msg
, cmsgptr
))
121 /* I want interface index which this packet comes from. */
122 if (cmsgptr
->cmsg_level
== IPPROTO_IPV6
&&
123 cmsgptr
->cmsg_type
== IPV6_PKTINFO
)
125 struct in6_pktinfo
*ptr
;
127 ptr
= (struct in6_pktinfo
*) CMSG_DATA (cmsgptr
);
128 *ifindex
= ptr
->ipi6_ifindex
;
129 memcpy(&dst
, &ptr
->ipi6_addr
, sizeof(ptr
->ipi6_addr
));
132 /* Incoming packet's hop limit. */
133 if (cmsgptr
->cmsg_level
== IPPROTO_IPV6
&&
134 cmsgptr
->cmsg_type
== IPV6_HOPLIMIT
)
136 int *hoptr
= (int *) CMSG_DATA (cmsgptr
);
141 rtadv_increment_received(zns
, ifindex
);
145 #define RTADV_MSG_SIZE 4096
147 /* Send router advertisement packet. */
149 rtadv_send_packet (int sock
, struct interface
*ifp
)
153 struct cmsghdr
*cmsgptr
;
154 struct in6_pktinfo
*pkt
;
155 struct sockaddr_in6 addr
;
156 static void *adata
= NULL
;
157 unsigned char buf
[RTADV_MSG_SIZE
];
158 struct nd_router_advert
*rtadv
;
161 struct zebra_if
*zif
;
162 struct rtadv_prefix
*rprefix
;
163 u_char all_nodes_addr
[] = {0xff,0x02,0,0,0,0,0,0,0,0,0,0,0,0,0,1};
164 struct listnode
*node
;
165 u_int16_t pkt_RouterLifetime
;
168 * Allocate control message bufffer. This is dynamic because
169 * CMSG_SPACE is not guaranteed not to call a function. Note that
170 * the size will be different on different architectures due to
171 * differing alignment rules.
175 /* XXX Free on shutdown. */
176 adata
= malloc(CMSG_SPACE(sizeof(struct in6_pktinfo
)));
179 zlog_err("rtadv_send_packet: can't malloc control data");
182 /* Logging of packet. */
183 if (IS_ZEBRA_DEBUG_PACKET
)
184 zlog_debug ("%s(%u): Tx RA, socket %u",
185 ifp
->name
, ifp
->ifindex
, sock
);
187 /* Fill in sockaddr_in6. */
188 memset (&addr
, 0, sizeof (struct sockaddr_in6
));
189 addr
.sin6_family
= AF_INET6
;
191 addr
.sin6_len
= sizeof (struct sockaddr_in6
);
192 #endif /* SIN6_LEN */
193 addr
.sin6_port
= htons (IPPROTO_ICMPV6
);
194 IPV6_ADDR_COPY (&addr
.sin6_addr
, all_nodes_addr
);
196 /* Fetch interface information. */
199 /* Make router advertisement message. */
200 rtadv
= (struct nd_router_advert
*) buf
;
202 rtadv
->nd_ra_type
= ND_ROUTER_ADVERT
;
203 rtadv
->nd_ra_code
= 0;
204 rtadv
->nd_ra_cksum
= 0;
206 rtadv
->nd_ra_curhoplimit
= 64;
208 /* RFC4191: Default Router Preference is 0 if Router Lifetime is 0. */
209 rtadv
->nd_ra_flags_reserved
=
210 zif
->rtadv
.AdvDefaultLifetime
== 0 ? 0 : zif
->rtadv
.DefaultPreference
;
211 rtadv
->nd_ra_flags_reserved
<<= 3;
213 if (zif
->rtadv
.AdvManagedFlag
)
214 rtadv
->nd_ra_flags_reserved
|= ND_RA_FLAG_MANAGED
;
215 if (zif
->rtadv
.AdvOtherConfigFlag
)
216 rtadv
->nd_ra_flags_reserved
|= ND_RA_FLAG_OTHER
;
217 if (zif
->rtadv
.AdvHomeAgentFlag
)
218 rtadv
->nd_ra_flags_reserved
|= ND_RA_FLAG_HOME_AGENT
;
219 /* Note that according to Neighbor Discovery (RFC 4861 [18]),
220 * AdvDefaultLifetime is by default based on the value of
221 * MaxRtrAdvInterval. AdvDefaultLifetime is used in the Router Lifetime
222 * field of Router Advertisements. Given that this field is expressed
223 * in seconds, a small MaxRtrAdvInterval value can result in a zero
224 * value for this field. To prevent this, routers SHOULD keep
225 * AdvDefaultLifetime in at least one second, even if the use of
226 * MaxRtrAdvInterval would result in a smaller value. -- RFC6275, 7.5 */
227 pkt_RouterLifetime
= zif
->rtadv
.AdvDefaultLifetime
!= -1 ?
228 zif
->rtadv
.AdvDefaultLifetime
:
229 MAX (1, 0.003 * zif
->rtadv
.MaxRtrAdvInterval
);
230 rtadv
->nd_ra_router_lifetime
= htons (pkt_RouterLifetime
);
231 rtadv
->nd_ra_reachable
= htonl (zif
->rtadv
.AdvReachableTime
);
232 rtadv
->nd_ra_retransmit
= htonl (0);
234 len
= sizeof (struct nd_router_advert
);
236 /* If both the Home Agent Preference and Home Agent Lifetime are set to
237 * their default values specified above, this option SHOULD NOT be
238 * included in the Router Advertisement messages sent by this home
239 * agent. -- RFC6275, 7.4 */
242 zif
->rtadv
.AdvHomeAgentFlag
&&
243 (zif
->rtadv
.HomeAgentPreference
|| zif
->rtadv
.HomeAgentLifetime
!= -1)
246 struct nd_opt_homeagent_info
*ndopt_hai
=
247 (struct nd_opt_homeagent_info
*)(buf
+ len
);
248 ndopt_hai
->nd_opt_hai_type
= ND_OPT_HA_INFORMATION
;
249 ndopt_hai
->nd_opt_hai_len
= 1;
250 ndopt_hai
->nd_opt_hai_reserved
= 0;
251 ndopt_hai
->nd_opt_hai_preference
= htons(zif
->rtadv
.HomeAgentPreference
);
252 /* 16-bit unsigned integer. The lifetime associated with the home
253 * agent in units of seconds. The default value is the same as the
254 * Router Lifetime, as specified in the main body of the Router
255 * Advertisement. The maximum value corresponds to 18.2 hours. A
256 * value of 0 MUST NOT be used. -- RFC6275, 7.5 */
257 ndopt_hai
->nd_opt_hai_lifetime
= htons
259 zif
->rtadv
.HomeAgentLifetime
!= -1 ?
260 zif
->rtadv
.HomeAgentLifetime
:
261 MAX (1, pkt_RouterLifetime
) /* 0 is OK for RL, but not for HAL*/
263 len
+= sizeof(struct nd_opt_homeagent_info
);
266 if (zif
->rtadv
.AdvIntervalOption
)
268 struct nd_opt_adv_interval
*ndopt_adv
=
269 (struct nd_opt_adv_interval
*)(buf
+ len
);
270 ndopt_adv
->nd_opt_ai_type
= ND_OPT_ADV_INTERVAL
;
271 ndopt_adv
->nd_opt_ai_len
= 1;
272 ndopt_adv
->nd_opt_ai_reserved
= 0;
273 ndopt_adv
->nd_opt_ai_interval
= htonl(zif
->rtadv
.MaxRtrAdvInterval
);
274 len
+= sizeof(struct nd_opt_adv_interval
);
277 /* Fill in prefix. */
278 for (ALL_LIST_ELEMENTS_RO (zif
->rtadv
.AdvPrefixList
, node
, rprefix
))
280 struct nd_opt_prefix_info
*pinfo
;
282 pinfo
= (struct nd_opt_prefix_info
*) (buf
+ len
);
284 pinfo
->nd_opt_pi_type
= ND_OPT_PREFIX_INFORMATION
;
285 pinfo
->nd_opt_pi_len
= 4;
286 pinfo
->nd_opt_pi_prefix_len
= rprefix
->prefix
.prefixlen
;
288 pinfo
->nd_opt_pi_flags_reserved
= 0;
289 if (rprefix
->AdvOnLinkFlag
)
290 pinfo
->nd_opt_pi_flags_reserved
|= ND_OPT_PI_FLAG_ONLINK
;
291 if (rprefix
->AdvAutonomousFlag
)
292 pinfo
->nd_opt_pi_flags_reserved
|= ND_OPT_PI_FLAG_AUTO
;
293 if (rprefix
->AdvRouterAddressFlag
)
294 pinfo
->nd_opt_pi_flags_reserved
|= ND_OPT_PI_FLAG_RADDR
;
296 pinfo
->nd_opt_pi_valid_time
= htonl (rprefix
->AdvValidLifetime
);
297 pinfo
->nd_opt_pi_preferred_time
= htonl (rprefix
->AdvPreferredLifetime
);
298 pinfo
->nd_opt_pi_reserved2
= 0;
300 IPV6_ADDR_COPY (&pinfo
->nd_opt_pi_prefix
, &rprefix
->prefix
.prefix
);
304 u_char buf
[INET6_ADDRSTRLEN
];
306 zlog_debug ("DEBUG %s", inet_ntop (AF_INET6
, &pinfo
->nd_opt_pi_prefix
,
307 buf
, INET6_ADDRSTRLEN
));
312 len
+= sizeof (struct nd_opt_prefix_info
);
315 /* Hardware address. */
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;
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 ("%s(%u): Tx RA failed, socket %u error %d (%s)",
366 ifp
->name
, ifp
->ifindex
, sock
, errno
, safe_strerror(errno
));
373 rtadv_timer (struct thread
*thread
)
375 struct zebra_ns
*zns
= THREAD_ARG (thread
);
377 struct listnode
*node
, *nnode
;
378 struct interface
*ifp
;
379 struct zebra_if
*zif
;
382 zns
->rtadv
.ra_timer
= NULL
;
383 if (zns
->rtadv
.adv_msec_if_count
== 0)
385 period
= 1000; /* 1 s */
386 rtadv_event (zns
, RTADV_TIMER
, 1 /* 1 s */);
390 period
= 10; /* 10 ms */
391 rtadv_event (zns
, RTADV_TIMER_MSEC
, 10 /* 10 ms */);
394 for (iter
= vrf_first (); iter
!= VRF_ITER_INVALID
; iter
= vrf_next (iter
))
395 for (ALL_LIST_ELEMENTS (vrf_iter2iflist (iter
), node
, nnode
, ifp
))
397 if (if_is_loopback (ifp
) ||
398 CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_VRF_LOOPBACK
) ||
399 ! if_is_operative (ifp
))
404 if (zif
->rtadv
.AdvSendAdvertisements
)
406 if (zif
->rtadv
.inFastRexmit
)
408 /* We assume we fast rexmit every sec so no additional vars */
409 if (--zif
->rtadv
.NumFastReXmitsRemain
<= 0)
410 zif
->rtadv
.inFastRexmit
= 0;
412 if (IS_ZEBRA_DEBUG_SEND
)
413 zlog_debug("Fast RA Rexmit on interface %s", ifp
->name
);
415 rtadv_send_packet (zns
->rtadv
.sock
, ifp
);
419 zif
->rtadv
.AdvIntervalTimer
-= period
;
420 if (zif
->rtadv
.AdvIntervalTimer
<= 0)
422 /* FIXME: using MaxRtrAdvInterval each time isn't what section
423 6.2.4 of RFC4861 tells to do. */
424 zif
->rtadv
.AdvIntervalTimer
= zif
->rtadv
.MaxRtrAdvInterval
;
425 rtadv_send_packet (zns
->rtadv
.sock
, ifp
);
435 rtadv_process_solicit (struct interface
*ifp
)
437 struct zebra_vrf
*zvrf
= vrf_info_lookup (ifp
->vrf_id
);
438 struct zebra_ns
*zns
= zvrf
->zns
;
441 rtadv_send_packet (zns
->rtadv
.sock
, ifp
);
445 rtadv_process_advert (u_char
*msg
, unsigned int len
, struct interface
*ifp
,
446 struct sockaddr_in6
*addr
)
448 struct nd_router_advert
*radvert
;
449 char addr_str
[INET6_ADDRSTRLEN
];
450 struct zebra_if
*zif
;
455 inet_ntop (AF_INET6
, &addr
->sin6_addr
, addr_str
, INET6_ADDRSTRLEN
);
457 if (len
< sizeof(struct nd_router_advert
)) {
458 zlog_warn("%s(%u): Rx RA with invalid length %d from %s",
459 ifp
->name
, ifp
->ifindex
, len
, addr_str
);
462 if (!IN6_IS_ADDR_LINKLOCAL(&addr
->sin6_addr
)) {
463 zlog_warn("%s(%u): Rx RA with non-linklocal source address from %s",
464 ifp
->name
, ifp
->ifindex
, addr_str
);
468 radvert
= (struct nd_router_advert
*) msg
;
470 if ((radvert
->nd_ra_curhoplimit
&& zif
->rtadv
.AdvCurHopLimit
) &&
471 (radvert
->nd_ra_curhoplimit
!= zif
->rtadv
.AdvCurHopLimit
))
473 zlog_warn("%s(%u): Rx RA - our AdvCurHopLimit doesn't agree with %s",
474 ifp
->name
, ifp
->ifindex
, addr_str
);
477 if ((radvert
->nd_ra_flags_reserved
& ND_RA_FLAG_MANAGED
) &&
478 !zif
->rtadv
.AdvManagedFlag
)
480 zlog_warn("%s(%u): Rx RA - our AdvManagedFlag doesn't agree with %s",
481 ifp
->name
, ifp
->ifindex
, addr_str
);
484 if ((radvert
->nd_ra_flags_reserved
& ND_RA_FLAG_OTHER
) &&
485 !zif
->rtadv
.AdvOtherConfigFlag
)
487 zlog_warn("%s(%u): Rx RA - our AdvOtherConfigFlag doesn't agree with %s",
488 ifp
->name
, ifp
->ifindex
, addr_str
);
491 if ((radvert
->nd_ra_reachable
&& zif
->rtadv
.AdvReachableTime
) &&
492 (ntohl(radvert
->nd_ra_reachable
) != zif
->rtadv
.AdvReachableTime
))
494 zlog_warn("%s(%u): Rx RA - our AdvReachableTime doesn't agree with %s",
495 ifp
->name
, ifp
->ifindex
, addr_str
);
498 if ((radvert
->nd_ra_retransmit
&& zif
->rtadv
.AdvRetransTimer
) &&
499 (ntohl(radvert
->nd_ra_retransmit
) != (unsigned int)zif
->rtadv
.AdvRetransTimer
))
501 zlog_warn("%s(%u): Rx RA - our AdvRetransTimer doesn't agree with %s",
502 ifp
->name
, ifp
->ifindex
, addr_str
);
505 /* Create entry for neighbor if not known. */
507 IPV6_ADDR_COPY (&p
.u
.prefix
, &addr
->sin6_addr
);
508 p
.prefixlen
= IPV6_MAX_PREFIXLEN
;
510 if (!nbr_connected_check(ifp
, &p
))
511 nbr_connected_add_ipv6 (ifp
, &addr
->sin6_addr
);
516 rtadv_process_packet (u_char
*buf
, unsigned int len
, ifindex_t ifindex
, int hoplimit
,
517 struct sockaddr_in6
*from
, struct zebra_ns
*zns
)
519 struct icmp6_hdr
*icmph
;
520 struct interface
*ifp
;
521 struct zebra_if
*zif
;
522 char addr_str
[INET6_ADDRSTRLEN
];
524 inet_ntop (AF_INET6
, &from
->sin6_addr
, addr_str
, INET6_ADDRSTRLEN
);
526 /* Interface search. */
527 ifp
= if_lookup_by_index_per_ns (zns
, ifindex
);
530 zlog_warn ("RA/RS received on unknown IF %u from %s",
535 if (IS_ZEBRA_DEBUG_PACKET
)
536 zlog_debug ("%s(%u): Rx RA/RS len %d from %s",
537 ifp
->name
, ifp
->ifindex
, len
, addr_str
);
539 if (if_is_loopback (ifp
) ||
540 CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_VRF_LOOPBACK
))
543 /* Check interface configuration. */
545 if (! zif
->rtadv
.AdvSendAdvertisements
)
548 /* ICMP message length check. */
549 if (len
< sizeof (struct icmp6_hdr
))
551 zlog_warn ("%s(%u): Rx RA with Invalid ICMPV6 packet length %d",
552 ifp
->name
, ifp
->ifindex
, len
);
556 icmph
= (struct icmp6_hdr
*) buf
;
558 /* ICMP message type check. */
559 if (icmph
->icmp6_type
!= ND_ROUTER_SOLICIT
&&
560 icmph
->icmp6_type
!= ND_ROUTER_ADVERT
)
562 zlog_warn ("%s(%u): Rx RA - Unwanted ICMPV6 message type %d",
563 ifp
->name
, ifp
->ifindex
, icmph
->icmp6_type
);
567 /* Hoplimit check. */
568 if (hoplimit
>= 0 && hoplimit
!= 255)
570 zlog_warn ("%s(%u): Rx RA - Invalid hoplimit %d",
571 ifp
->name
, ifp
->ifindex
, hoplimit
);
575 /* Check ICMP message type. */
576 if (icmph
->icmp6_type
== ND_ROUTER_SOLICIT
)
577 rtadv_process_solicit (ifp
);
578 else if (icmph
->icmp6_type
== ND_ROUTER_ADVERT
)
579 rtadv_process_advert (buf
, len
, ifp
, from
);
585 rtadv_read (struct thread
*thread
)
589 u_char buf
[RTADV_MSG_SIZE
];
590 struct sockaddr_in6 from
;
591 ifindex_t ifindex
= 0;
593 struct zebra_ns
*zns
= THREAD_ARG (thread
);
595 sock
= THREAD_FD (thread
);
596 zns
->rtadv
.ra_read
= NULL
;
598 /* Register myself. */
599 rtadv_event (zns
, RTADV_READ
, sock
);
601 len
= rtadv_recv_packet (zns
, sock
, buf
, sizeof (buf
), &from
, &ifindex
, &hoplimit
);
605 zlog_warn ("RA/RS recv failed, socket %u error %s",
606 sock
, safe_strerror (errno
));
610 rtadv_process_packet (buf
, (unsigned)len
, ifindex
, hoplimit
, &from
, zns
);
616 rtadv_make_socket (void)
620 struct icmp6_filter filter
;
622 if ( zserv_privs
.change (ZPRIVS_RAISE
) )
623 zlog_err ("rtadv_make_socket: could not raise privs, %s",
624 safe_strerror (errno
) );
626 sock
= socket (AF_INET6
, SOCK_RAW
, IPPROTO_ICMPV6
);
628 if ( zserv_privs
.change (ZPRIVS_LOWER
) )
629 zlog_err ("rtadv_make_socket: could not lower privs, %s",
630 safe_strerror (errno
) );
638 ret
= setsockopt_ipv6_pktinfo (sock
, 1);
644 ret
= setsockopt_ipv6_multicast_loop (sock
, 0);
650 ret
= setsockopt_ipv6_unicast_hops (sock
, 255);
656 ret
= setsockopt_ipv6_multicast_hops (sock
, 255);
662 ret
= setsockopt_ipv6_hoplimit (sock
, 1);
669 ICMP6_FILTER_SETBLOCKALL(&filter
);
670 ICMP6_FILTER_SETPASS (ND_ROUTER_SOLICIT
, &filter
);
671 ICMP6_FILTER_SETPASS (ND_ROUTER_ADVERT
, &filter
);
673 ret
= setsockopt (sock
, IPPROTO_ICMPV6
, ICMP6_FILTER
, &filter
,
674 sizeof (struct icmp6_filter
));
677 zlog_info ("ICMP6_FILTER set fail: %s", safe_strerror (errno
));
684 static struct rtadv_prefix
*
685 rtadv_prefix_new (void)
687 return XCALLOC (MTYPE_RTADV_PREFIX
, sizeof (struct rtadv_prefix
));
691 rtadv_prefix_free (struct rtadv_prefix
*rtadv_prefix
)
693 XFREE (MTYPE_RTADV_PREFIX
, rtadv_prefix
);
696 static struct rtadv_prefix
*
697 rtadv_prefix_lookup (struct list
*rplist
, struct prefix_ipv6
*p
)
699 struct listnode
*node
;
700 struct rtadv_prefix
*rprefix
;
702 for (ALL_LIST_ELEMENTS_RO (rplist
, node
, rprefix
))
703 if (prefix_same ((struct prefix
*) &rprefix
->prefix
, (struct prefix
*) p
))
708 static struct rtadv_prefix
*
709 rtadv_prefix_get (struct list
*rplist
, struct prefix_ipv6
*p
)
711 struct rtadv_prefix
*rprefix
;
713 rprefix
= rtadv_prefix_lookup (rplist
, p
);
717 rprefix
= rtadv_prefix_new ();
718 memcpy (&rprefix
->prefix
, p
, sizeof (struct prefix_ipv6
));
719 listnode_add (rplist
, rprefix
);
725 rtadv_prefix_set (struct zebra_if
*zif
, struct rtadv_prefix
*rp
)
727 struct rtadv_prefix
*rprefix
;
729 rprefix
= rtadv_prefix_get (zif
->rtadv
.AdvPrefixList
, &rp
->prefix
);
731 /* Set parameters. */
732 rprefix
->AdvValidLifetime
= rp
->AdvValidLifetime
;
733 rprefix
->AdvPreferredLifetime
= rp
->AdvPreferredLifetime
;
734 rprefix
->AdvOnLinkFlag
= rp
->AdvOnLinkFlag
;
735 rprefix
->AdvAutonomousFlag
= rp
->AdvAutonomousFlag
;
736 rprefix
->AdvRouterAddressFlag
= rp
->AdvRouterAddressFlag
;
740 rtadv_prefix_reset (struct zebra_if
*zif
, struct rtadv_prefix
*rp
)
742 struct rtadv_prefix
*rprefix
;
744 rprefix
= rtadv_prefix_lookup (zif
->rtadv
.AdvPrefixList
, &rp
->prefix
);
747 listnode_delete (zif
->rtadv
.AdvPrefixList
, (void *) rprefix
);
748 rtadv_prefix_free (rprefix
);
756 ipv6_nd_suppress_ra_set (struct interface
*ifp
, ipv6_nd_suppress_ra_status status
)
758 struct zebra_if
*zif
;
759 struct zebra_vrf
*zvrf
;
760 struct zebra_ns
*zns
;
763 zvrf
= vrf_info_lookup (ifp
->vrf_id
);
766 if (status
== RA_SUPPRESS
)
768 /* RA is currently enabled */
769 if (zif
->rtadv
.AdvSendAdvertisements
)
771 zif
->rtadv
.AdvSendAdvertisements
= 0;
772 zif
->rtadv
.AdvIntervalTimer
= 0;
773 zns
->rtadv
.adv_if_count
--;
775 if_leave_all_router (zns
->rtadv
.sock
, ifp
);
777 if (zns
->rtadv
.adv_if_count
== 0)
778 rtadv_event (zns
, RTADV_STOP
, 0);
783 if (! zif
->rtadv
.AdvSendAdvertisements
)
785 zif
->rtadv
.AdvSendAdvertisements
= 1;
786 zif
->rtadv
.AdvIntervalTimer
= 0;
787 zns
->rtadv
.adv_if_count
++;
789 if (zif
->rtadv
.MaxRtrAdvInterval
>= 1000)
791 /* Enable Fast RA only when RA interval is in secs */
792 zif
->rtadv
.inFastRexmit
= 1;
793 zif
->rtadv
.NumFastReXmitsRemain
= RTADV_NUM_FAST_REXMITS
;
796 if_join_all_router (zns
->rtadv
.sock
, ifp
);
798 if (zns
->rtadv
.adv_if_count
== 1)
799 rtadv_event (zns
, RTADV_START
, zns
->rtadv
.sock
);
805 * Handle client (BGP) message to enable or disable IPv6 RA on an interface.
806 * Note that while the client could request RA on an interface on which the
807 * operator has not enabled RA, RA won't be disabled upon client request
808 * if the operator has explicitly enabled RA. The enable request can also
809 * specify a RA interval (in seconds).
812 zebra_interface_radv_set (struct zserv
*client
, int sock
, u_short length
,
813 struct zebra_vrf
*zvrf
, int enable
)
816 unsigned int ifindex
;
817 struct interface
*ifp
;
818 struct zebra_if
*zif
;
823 /* Get interface index and RA interval. */
824 ifindex
= stream_getl (s
);
825 ra_interval
= stream_getl (s
);
827 if (IS_ZEBRA_DEBUG_EVENT
)
828 zlog_debug("%u: IF %u RA %s from client %s, interval %ds",
829 zvrf
->vrf_id
, ifindex
, enable
? "enable" : "disable",
830 zebra_route_string(client
->proto
), ra_interval
);
832 /* Locate interface and check VRF match. */
833 ifp
= if_lookup_by_index_per_ns (zebra_ns_lookup (NS_DEFAULT
), ifindex
);
836 zlog_warn("%u: IF %u RA %s client %s - interface unknown",
837 zvrf
->vrf_id
, ifindex
, enable
? "enable" : "disable",
838 zebra_route_string(client
->proto
));
841 if (ifp
->vrf_id
!= zvrf
->vrf_id
)
843 zlog_warn("%u: IF %u RA %s client %s - VRF mismatch, IF VRF %u",
844 zvrf
->vrf_id
, ifindex
, enable
? "enable" : "disable",
845 zebra_route_string(client
->proto
), ifp
->vrf_id
);
852 ipv6_nd_suppress_ra_set (ifp
, RA_ENABLE
);
854 (ra_interval
* 1000) < zif
->rtadv
.MaxRtrAdvInterval
)
855 zif
->rtadv
.MaxRtrAdvInterval
= ra_interval
* 1000;
859 if (!zif
->rtadv
.configured
)
861 zif
->rtadv
.MaxRtrAdvInterval
= RTADV_MAX_RTR_ADV_INTERVAL
;
862 ipv6_nd_suppress_ra_set (ifp
, RA_SUPPRESS
);
867 DEFUN (ipv6_nd_suppress_ra
,
868 ipv6_nd_suppress_ra_cmd
,
869 "ipv6 nd suppress-ra",
870 "Interface IPv6 config commands\n"
871 "Neighbor discovery\n"
872 "Suppress Router Advertisement\n")
874 struct interface
*ifp
;
875 struct zebra_if
*zif
;
879 if (if_is_loopback (ifp
) ||
880 CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_VRF_LOOPBACK
))
882 vty_out (vty
, "Cannot configure IPv6 Router Advertisements on this interface%s", VTY_NEWLINE
);
886 ipv6_nd_suppress_ra_set (ifp
, RA_SUPPRESS
);
888 zif
->rtadv
.configured
= 0;
892 DEFUN (no_ipv6_nd_suppress_ra
,
893 no_ipv6_nd_suppress_ra_cmd
,
894 "no ipv6 nd suppress-ra",
896 "Interface IPv6 config commands\n"
897 "Neighbor discovery\n"
898 "Suppress Router Advertisement\n")
900 struct interface
*ifp
;
901 struct zebra_if
*zif
;
905 if (if_is_loopback (ifp
) ||
906 CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_VRF_LOOPBACK
))
908 vty_out (vty
, "Cannot configure IPv6 Router Advertisements on this interface%s", VTY_NEWLINE
);
912 ipv6_nd_suppress_ra_set (ifp
, RA_ENABLE
);
914 zif
->rtadv
.configured
= 1;
918 DEFUN (ipv6_nd_ra_interval_msec
,
919 ipv6_nd_ra_interval_msec_cmd
,
920 "ipv6 nd ra-interval msec (70-1800000)",
921 "Interface IPv6 config commands\n"
922 "Neighbor discovery\n"
923 "Router Advertisement interval\n"
924 "Router Advertisement interval in milliseconds\n")
927 struct interface
*ifp
= (struct interface
*) vty
->index
;
928 struct zebra_if
*zif
= ifp
->info
;
929 struct zebra_vrf
*zvrf
= vrf_info_lookup (ifp
->vrf_id
);
930 struct zebra_ns
*zns
;
933 VTY_GET_INTEGER_RANGE ("router advertisement interval", interval
, argv
[4]->arg
, 70, 1800000);
934 if ((zif
->rtadv
.AdvDefaultLifetime
!= -1 && interval
> (unsigned)zif
->rtadv
.AdvDefaultLifetime
* 1000))
936 vty_out (vty
, "This ra-interval would conflict with configured ra-lifetime!%s", VTY_NEWLINE
);
940 if (zif
->rtadv
.MaxRtrAdvInterval
% 1000)
941 zns
->rtadv
.adv_msec_if_count
--;
944 zns
->rtadv
.adv_msec_if_count
++;
946 zif
->rtadv
.MaxRtrAdvInterval
= interval
;
947 zif
->rtadv
.MinRtrAdvInterval
= 0.33 * interval
;
948 zif
->rtadv
.AdvIntervalTimer
= 0;
953 DEFUN (ipv6_nd_ra_interval
,
954 ipv6_nd_ra_interval_cmd
,
955 "ipv6 nd ra-interval (1-1800)",
956 "Interface IPv6 config commands\n"
957 "Neighbor discovery\n"
958 "Router Advertisement interval\n"
959 "Router Advertisement interval in seconds\n")
962 struct interface
*ifp
= (struct interface
*) vty
->index
;
963 struct zebra_if
*zif
= ifp
->info
;
964 struct zebra_vrf
*zvrf
= vrf_info_lookup (ifp
->vrf_id
);
965 struct zebra_ns
*zns
;
968 VTY_GET_INTEGER_RANGE ("router advertisement interval", interval
, argv
[3]->arg
, 1, 1800);
969 if ((zif
->rtadv
.AdvDefaultLifetime
!= -1 && interval
> (unsigned)zif
->rtadv
.AdvDefaultLifetime
))
971 vty_out (vty
, "This ra-interval would conflict with configured ra-lifetime!%s", VTY_NEWLINE
);
975 if (zif
->rtadv
.MaxRtrAdvInterval
% 1000)
976 zns
->rtadv
.adv_msec_if_count
--;
978 /* convert to milliseconds */
979 interval
= interval
* 1000;
981 zif
->rtadv
.MaxRtrAdvInterval
= interval
;
982 zif
->rtadv
.MinRtrAdvInterval
= 0.33 * interval
;
983 zif
->rtadv
.AdvIntervalTimer
= 0;
989 * CHECK ME - The following ALIASes need to be implemented in this DEFUN
990 * "no ipv6 nd ra-interval <1-1800>",
992 * "Interface IPv6 config commands\n"
993 * "Neighbor discovery\n"
994 * "Router Advertisement interval\n"
996 * "no ipv6 nd ra-interval msec <1-1800000>",
998 * "Interface IPv6 config commands\n"
999 * "Neighbor discovery\n"
1000 * "Router Advertisement interval\n"
1001 * "Router Advertisement interval in milliseconds\n"
1004 DEFUN (no_ipv6_nd_ra_interval
,
1005 no_ipv6_nd_ra_interval_cmd
,
1006 "no ipv6 nd ra-interval",
1008 "Interface IPv6 config commands\n"
1009 "Neighbor discovery\n"
1010 "Router Advertisement interval\n")
1012 struct interface
*ifp
;
1013 struct zebra_if
*zif
;
1014 struct zebra_vrf
*zvrf
;
1015 struct zebra_ns
*zns
;
1017 ifp
= (struct interface
*) vty
->index
;
1019 zvrf
= vrf_info_lookup (ifp
->vrf_id
);
1022 if (zif
->rtadv
.MaxRtrAdvInterval
% 1000)
1023 zns
->rtadv
.adv_msec_if_count
--;
1025 zif
->rtadv
.MaxRtrAdvInterval
= RTADV_MAX_RTR_ADV_INTERVAL
;
1026 zif
->rtadv
.MinRtrAdvInterval
= RTADV_MIN_RTR_ADV_INTERVAL
;
1027 zif
->rtadv
.AdvIntervalTimer
= zif
->rtadv
.MaxRtrAdvInterval
;
1034 DEFUN (ipv6_nd_ra_lifetime
,
1035 ipv6_nd_ra_lifetime_cmd
,
1036 "ipv6 nd ra-lifetime (0-9000)",
1037 "Interface IPv6 config commands\n"
1038 "Neighbor discovery\n"
1040 "Router lifetime in seconds (0 stands for a non-default gw)\n")
1043 struct interface
*ifp
;
1044 struct zebra_if
*zif
;
1046 ifp
= (struct interface
*) vty
->index
;
1049 VTY_GET_INTEGER_RANGE ("router lifetime", lifetime
, argv
[3]->arg
, 0, 9000);
1051 /* The value to be placed in the Router Lifetime field
1052 * of Router Advertisements sent from the interface,
1053 * in seconds. MUST be either zero or between
1054 * MaxRtrAdvInterval and 9000 seconds. -- RFC4861, 6.2.1 */
1055 if ((lifetime
!= 0 && lifetime
* 1000 < zif
->rtadv
.MaxRtrAdvInterval
))
1057 vty_out (vty
, "This ra-lifetime would conflict with configured ra-interval%s", VTY_NEWLINE
);
1061 zif
->rtadv
.AdvDefaultLifetime
= lifetime
;
1067 * CHECK ME - The following ALIASes need to be implemented in this DEFUN
1068 * "no ipv6 nd ra-lifetime <0-9000>",
1070 * "Interface IPv6 config commands\n"
1071 * "Neighbor discovery\n"
1072 * "Router lifetime\n"
1073 * "Router lifetime in seconds (0 stands for a non-default gw)\n"
1076 DEFUN (no_ipv6_nd_ra_lifetime
,
1077 no_ipv6_nd_ra_lifetime_cmd
,
1078 "no ipv6 nd ra-lifetime",
1080 "Interface IPv6 config commands\n"
1081 "Neighbor discovery\n"
1082 "Router lifetime\n")
1084 struct interface
*ifp
;
1085 struct zebra_if
*zif
;
1087 ifp
= (struct interface
*) vty
->index
;
1090 zif
->rtadv
.AdvDefaultLifetime
= -1;
1096 DEFUN (ipv6_nd_reachable_time
,
1097 ipv6_nd_reachable_time_cmd
,
1098 "ipv6 nd reachable-time (1-3600000)",
1099 "Interface IPv6 config commands\n"
1100 "Neighbor discovery\n"
1102 "Reachable time in milliseconds\n")
1104 struct interface
*ifp
= (struct interface
*) vty
->index
;
1105 struct zebra_if
*zif
= ifp
->info
;
1106 VTY_GET_INTEGER_RANGE ("reachable time", zif
->rtadv
.AdvReachableTime
, argv
[3]->arg
, 1, RTADV_MAX_REACHABLE_TIME
);
1111 * CHECK ME - The following ALIASes need to be implemented in this DEFUN
1112 * "no ipv6 nd reachable-time <1-3600000>",
1114 * "Interface IPv6 config commands\n"
1115 * "Neighbor discovery\n"
1116 * "Reachable time\n"
1117 * "Reachable time in milliseconds\n"
1120 DEFUN (no_ipv6_nd_reachable_time
,
1121 no_ipv6_nd_reachable_time_cmd
,
1122 "no ipv6 nd reachable-time",
1124 "Interface IPv6 config commands\n"
1125 "Neighbor discovery\n"
1128 struct interface
*ifp
;
1129 struct zebra_if
*zif
;
1131 ifp
= (struct interface
*) vty
->index
;
1134 zif
->rtadv
.AdvReachableTime
= 0;
1140 DEFUN (ipv6_nd_homeagent_preference
,
1141 ipv6_nd_homeagent_preference_cmd
,
1142 "ipv6 nd home-agent-preference (0-65535)",
1143 "Interface IPv6 config commands\n"
1144 "Neighbor discovery\n"
1145 "Home Agent preference\n"
1146 "preference value (default is 0, least preferred)\n")
1148 struct interface
*ifp
= (struct interface
*) vty
->index
;
1149 struct zebra_if
*zif
= ifp
->info
;
1150 VTY_GET_INTEGER_RANGE ("home agent preference", zif
->rtadv
.HomeAgentPreference
, argv
[3]->arg
, 0, 65535);
1155 * CHECK ME - The following ALIASes need to be implemented in this DEFUN
1156 * "no ipv6 nd home-agent-preference <0-65535>",
1158 * "Interface IPv6 config commands\n"
1159 * "Neighbor discovery\n"
1160 * "Home Agent preference\n"
1161 * "preference value (default is 0, least preferred)\n"
1164 DEFUN (no_ipv6_nd_homeagent_preference
,
1165 no_ipv6_nd_homeagent_preference_cmd
,
1166 "no ipv6 nd home-agent-preference",
1168 "Interface IPv6 config commands\n"
1169 "Neighbor discovery\n"
1170 "Home Agent preference\n")
1172 struct interface
*ifp
;
1173 struct zebra_if
*zif
;
1175 ifp
= (struct interface
*) vty
->index
;
1178 zif
->rtadv
.HomeAgentPreference
= 0;
1184 DEFUN (ipv6_nd_homeagent_lifetime
,
1185 ipv6_nd_homeagent_lifetime_cmd
,
1186 "ipv6 nd home-agent-lifetime (0-65520)",
1187 "Interface IPv6 config commands\n"
1188 "Neighbor discovery\n"
1189 "Home Agent lifetime\n"
1190 "Home Agent lifetime in seconds (0 to track ra-lifetime)\n")
1192 struct interface
*ifp
= (struct interface
*) vty
->index
;
1193 struct zebra_if
*zif
= ifp
->info
;
1194 VTY_GET_INTEGER_RANGE ("home agent lifetime", zif
->rtadv
.HomeAgentLifetime
, argv
[3]->arg
, 0, RTADV_MAX_HALIFETIME
);
1199 * CHECK ME - The following ALIASes need to be implemented in this DEFUN
1200 * "no ipv6 nd home-agent-lifetime <0-65520>",
1202 * "Interface IPv6 config commands\n"
1203 * "Neighbor discovery\n"
1204 * "Home Agent lifetime\n"
1205 * "Home Agent lifetime in seconds (0 to track ra-lifetime)\n"
1208 DEFUN (no_ipv6_nd_homeagent_lifetime
,
1209 no_ipv6_nd_homeagent_lifetime_cmd
,
1210 "no ipv6 nd home-agent-lifetime",
1212 "Interface IPv6 config commands\n"
1213 "Neighbor discovery\n"
1214 "Home Agent lifetime\n")
1216 struct interface
*ifp
;
1217 struct zebra_if
*zif
;
1219 ifp
= (struct interface
*) vty
->index
;
1222 zif
->rtadv
.HomeAgentLifetime
= -1;
1228 DEFUN (ipv6_nd_managed_config_flag
,
1229 ipv6_nd_managed_config_flag_cmd
,
1230 "ipv6 nd managed-config-flag",
1231 "Interface IPv6 config commands\n"
1232 "Neighbor discovery\n"
1233 "Managed address configuration flag\n")
1235 struct interface
*ifp
;
1236 struct zebra_if
*zif
;
1238 ifp
= (struct interface
*) vty
->index
;
1241 zif
->rtadv
.AdvManagedFlag
= 1;
1246 DEFUN (no_ipv6_nd_managed_config_flag
,
1247 no_ipv6_nd_managed_config_flag_cmd
,
1248 "no ipv6 nd managed-config-flag",
1250 "Interface IPv6 config commands\n"
1251 "Neighbor discovery\n"
1252 "Managed address configuration flag\n")
1254 struct interface
*ifp
;
1255 struct zebra_if
*zif
;
1257 ifp
= (struct interface
*) vty
->index
;
1260 zif
->rtadv
.AdvManagedFlag
= 0;
1265 DEFUN (ipv6_nd_homeagent_config_flag
,
1266 ipv6_nd_homeagent_config_flag_cmd
,
1267 "ipv6 nd home-agent-config-flag",
1268 "Interface IPv6 config commands\n"
1269 "Neighbor discovery\n"
1270 "Home Agent configuration flag\n")
1272 struct interface
*ifp
;
1273 struct zebra_if
*zif
;
1275 ifp
= (struct interface
*) vty
->index
;
1278 zif
->rtadv
.AdvHomeAgentFlag
= 1;
1283 DEFUN (no_ipv6_nd_homeagent_config_flag
,
1284 no_ipv6_nd_homeagent_config_flag_cmd
,
1285 "no ipv6 nd home-agent-config-flag",
1287 "Interface IPv6 config commands\n"
1288 "Neighbor discovery\n"
1289 "Home Agent configuration flag\n")
1291 struct interface
*ifp
;
1292 struct zebra_if
*zif
;
1294 ifp
= (struct interface
*) vty
->index
;
1297 zif
->rtadv
.AdvHomeAgentFlag
= 0;
1302 DEFUN (ipv6_nd_adv_interval_config_option
,
1303 ipv6_nd_adv_interval_config_option_cmd
,
1304 "ipv6 nd adv-interval-option",
1305 "Interface IPv6 config commands\n"
1306 "Neighbor discovery\n"
1307 "Advertisement Interval Option\n")
1309 struct interface
*ifp
;
1310 struct zebra_if
*zif
;
1312 ifp
= (struct interface
*) vty
->index
;
1315 zif
->rtadv
.AdvIntervalOption
= 1;
1320 DEFUN (no_ipv6_nd_adv_interval_config_option
,
1321 no_ipv6_nd_adv_interval_config_option_cmd
,
1322 "no ipv6 nd adv-interval-option",
1324 "Interface IPv6 config commands\n"
1325 "Neighbor discovery\n"
1326 "Advertisement Interval Option\n")
1328 struct interface
*ifp
;
1329 struct zebra_if
*zif
;
1331 ifp
= (struct interface
*) vty
->index
;
1334 zif
->rtadv
.AdvIntervalOption
= 0;
1339 DEFUN (ipv6_nd_other_config_flag
,
1340 ipv6_nd_other_config_flag_cmd
,
1341 "ipv6 nd other-config-flag",
1342 "Interface IPv6 config commands\n"
1343 "Neighbor discovery\n"
1344 "Other statefull configuration flag\n")
1346 struct interface
*ifp
;
1347 struct zebra_if
*zif
;
1349 ifp
= (struct interface
*) vty
->index
;
1352 zif
->rtadv
.AdvOtherConfigFlag
= 1;
1357 DEFUN (no_ipv6_nd_other_config_flag
,
1358 no_ipv6_nd_other_config_flag_cmd
,
1359 "no ipv6 nd other-config-flag",
1361 "Interface IPv6 config commands\n"
1362 "Neighbor discovery\n"
1363 "Other statefull configuration flag\n")
1365 struct interface
*ifp
;
1366 struct zebra_if
*zif
;
1368 ifp
= (struct interface
*) vty
->index
;
1371 zif
->rtadv
.AdvOtherConfigFlag
= 0;
1377 * CHECK ME - The following ALIASes need to be implemented in this DEFUN
1378 * "ipv6 nd prefix X:X::X:X/M (no-autoconfig|)",
1379 * "Interface IPv6 config commands\n"
1380 * "Neighbor discovery\n"
1381 * "Prefix information\n"
1383 * "Do not use prefix for autoconfiguration\n"
1385 * "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1386 * "(<0-4294967295>|infinite)",
1387 * "Interface IPv6 config commands\n"
1388 * "Neighbor discovery\n"
1389 * "Prefix information\n"
1391 * "Valid lifetime in seconds\n"
1392 * "Infinite valid lifetime\n"
1393 * "Preferred lifetime in seconds\n"
1394 * "Infinite preferred lifetime\n"
1396 * "ipv6 nd prefix X:X::X:X/M (off-link|) (no-autoconfig|)",
1397 * "Interface IPv6 config commands\n"
1398 * "Neighbor discovery\n"
1399 * "Prefix information\n"
1401 * "Do not use prefix for onlink determination\n"
1402 * "Do not use prefix for autoconfiguration\n"
1404 * "ipv6 nd prefix X:X::X:X/M (router-address|)",
1405 * "Interface IPv6 config commands\n"
1406 * "Neighbor discovery\n"
1407 * "Prefix information\n"
1409 * "Set Router Address flag\n"
1411 * "ipv6 nd prefix X:X::X:X/M (no-autoconfig|) (off-link|)",
1412 * "Interface IPv6 config commands\n"
1413 * "Neighbor discovery\n"
1414 * "Prefix information\n"
1416 * "Do not use prefix for autoconfiguration\n"
1417 * "Do not use prefix for onlink determination\n"
1419 * "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1420 * "(<0-4294967295>|infinite) (router-address|)",
1421 * "Interface IPv6 config commands\n"
1422 * "Neighbor discovery\n"
1423 * "Prefix information\n"
1425 * "Valid lifetime in seconds\n"
1426 * "Infinite valid lifetime\n"
1427 * "Preferred lifetime in seconds\n"
1428 * "Infinite preferred lifetime\n"
1429 * "Set Router Address flag\n"
1431 * "ipv6 nd prefix X:X::X:X/M",
1432 * "Interface IPv6 config commands\n"
1433 * "Neighbor discovery\n"
1434 * "Prefix information\n"
1437 * "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1438 * "(<0-4294967295>|infinite) (off-link|) (no-autoconfig|)",
1439 * "Interface IPv6 config commands\n"
1440 * "Neighbor discovery\n"
1441 * "Prefix information\n"
1443 * "Valid lifetime in seconds\n"
1444 * "Infinite valid lifetime\n"
1445 * "Preferred lifetime in seconds\n"
1446 * "Infinite preferred lifetime\n"
1447 * "Do not use prefix for onlink determination\n"
1448 * "Do not use prefix for autoconfiguration\n"
1450 * "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1451 * "(<0-4294967295>|infinite) (no-autoconfig|) (off-link|)",
1452 * "Interface IPv6 config commands\n"
1453 * "Neighbor discovery\n"
1454 * "Prefix information\n"
1456 * "Valid lifetime in seconds\n"
1457 * "Infinite valid lifetime\n"
1458 * "Preferred lifetime in seconds\n"
1459 * "Infinite preferred lifetime\n"
1460 * "Do not use prefix for autoconfiguration\n"
1461 * "Do not use prefix for onlink determination\n"
1463 * "ipv6 nd prefix X:X::X:X/M (off-link|)",
1464 * "Interface IPv6 config commands\n"
1465 * "Neighbor discovery\n"
1466 * "Prefix information\n"
1468 * "Do not use prefix for onlink determination\n"
1470 * "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1471 * "(<0-4294967295>|infinite) (no-autoconfig|)",
1472 * "Interface IPv6 config commands\n"
1473 * "Neighbor discovery\n"
1474 * "Prefix information\n"
1476 * "Valid lifetime in seconds\n"
1477 * "Infinite valid lifetime\n"
1478 * "Preferred lifetime in seconds\n"
1479 * "Infinite preferred lifetime\n"
1480 * "Do not use prefix for autoconfiguration"
1482 * "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1483 * "(<0-4294967295>|infinite) (off-link|)",
1484 * "Interface IPv6 config commands\n"
1485 * "Neighbor discovery\n"
1486 * "Prefix information\n"
1488 * "Valid lifetime in seconds\n"
1489 * "Infinite valid lifetime\n"
1490 * "Preferred lifetime in seconds\n"
1491 * "Infinite preferred lifetime\n"
1492 * "Do not use prefix for onlink determination\n"
1494 * "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1495 * "(<0-4294967295>|infinite) (no-autoconfig|) (off-link|) (router-address|)",
1496 * "Interface IPv6 config commands\n"
1497 * "Neighbor discovery\n"
1498 * "Prefix information\n"
1500 * "Valid lifetime in seconds\n"
1501 * "Infinite valid lifetime\n"
1502 * "Preferred lifetime in seconds\n"
1503 * "Infinite preferred lifetime\n"
1504 * "Do not use prefix for autoconfiguration\n"
1505 * "Do not use prefix for onlink determination\n"
1506 * "Set Router Address flag\n"
1509 DEFUN (ipv6_nd_prefix
,
1511 "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")
1527 struct interface
*ifp
;
1528 struct zebra_if
*zebra_if
;
1529 struct rtadv_prefix rp
;
1531 ifp
= (struct interface
*) vty
->index
;
1532 zebra_if
= ifp
->info
;
1534 ret
= str2prefix_ipv6 (argv
[3]->arg
, &rp
.prefix
);
1537 vty_out (vty
, "Malformed IPv6 prefix%s", VTY_NEWLINE
);
1540 apply_mask_ipv6 (&rp
.prefix
); /* RFC4861 4.6.2 */
1541 rp
.AdvOnLinkFlag
= 1;
1542 rp
.AdvAutonomousFlag
= 1;
1543 rp
.AdvRouterAddressFlag
= 0;
1544 rp
.AdvValidLifetime
= RTADV_VALID_LIFETIME
;
1545 rp
.AdvPreferredLifetime
= RTADV_PREFERRED_LIFETIME
;
1549 if ((isdigit((unsigned char)argv
[4]->arg
[0]))
1550 || strncmp (argv
[4]->arg
, "i", 1) == 0)
1552 if ( strncmp (argv
[4]->arg
, "i", 1) == 0)
1553 rp
.AdvValidLifetime
= UINT32_MAX
;
1555 rp
.AdvValidLifetime
= (u_int32_t
) strtoll (argv
[4]->arg
,
1558 if ( strncmp (argv
[5]->arg
, "i", 1) == 0)
1559 rp
.AdvPreferredLifetime
= UINT32_MAX
;
1561 rp
.AdvPreferredLifetime
= (u_int32_t
) strtoll (argv
[5]->arg
,
1564 if (rp
.AdvPreferredLifetime
> rp
.AdvValidLifetime
)
1566 vty_out (vty
, "Invalid preferred lifetime%s", VTY_NEWLINE
);
1569 cursor
= cursor
+ 2;
1573 for (i
= cursor
; i
< argc
; i
++)
1575 if (strncmp (argv
[i
], "of", 2) == 0)
1576 rp
.AdvOnLinkFlag
= 0;
1577 if (strncmp (argv
[i
], "no", 2) == 0)
1578 rp
.AdvAutonomousFlag
= 0;
1579 if (strncmp (argv
[i
], "ro", 2) == 0)
1580 rp
.AdvRouterAddressFlag
= 1;
1585 rtadv_prefix_set (zebra_if
, &rp
);
1604 * CHECK ME - The following ALIASes need to be implemented in this DEFUN
1605 * "no ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) (<0-4294967295>|infinite) (no-autoconfig|) (off-link|)",
1607 * "Interface IPv6 config commands\n"
1608 * "Neighbor discovery\n"
1609 * "Prefix information\n"
1611 * "Valid lifetime in seconds\n"
1612 * "Infinite valid lifetime\n"
1613 * "Preferred lifetime in seconds\n"
1614 * "Infinite preferred lifetime\n"
1615 * "Do not use prefix for autoconfiguration\n"
1616 * "Do not use prefix for onlink determination\n"
1618 * "no ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) (<0-4294967295>|infinite) (no-autoconfig|)",
1620 * "Interface IPv6 config commands\n"
1621 * "Neighbor discovery\n"
1622 * "Prefix information\n"
1624 * "Valid lifetime in seconds\n"
1625 * "Infinite valid lifetime\n"
1626 * "Preferred lifetime in seconds\n"
1627 * "Infinite preferred lifetime\n"
1628 * "Do not use prefix for autoconfiguration"
1630 * "no ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) (<0-4294967295>|infinite) (off-link|) (no-autoconfig|) (router-address|)",
1632 * "Interface IPv6 config commands\n"
1633 * "Neighbor discovery\n"
1634 * "Prefix information\n"
1636 * "Valid lifetime in seconds\n"
1637 * "Infinite valid lifetime\n"
1638 * "Preferred lifetime in seconds\n"
1639 * "Infinite preferred lifetime\n"
1640 * "Do not use prefix for onlink determination\n"
1641 * "Do not use prefix for autoconfiguration\n"
1642 * "Set Router Address flag\n"
1644 * "no ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) (<0-4294967295>|infinite) (off-link|)",
1646 * "Interface IPv6 config commands\n"
1647 * "Neighbor discovery\n"
1648 * "Prefix information\n"
1650 * "Valid lifetime in seconds\n"
1651 * "Infinite valid lifetime\n"
1652 * "Preferred lifetime in seconds\n"
1653 * "Infinite preferred lifetime\n"
1654 * "Do not use prefix for onlink determination\n"
1656 * "no ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) (<0-4294967295>|infinite) (no-autoconfig|) (off-link|) (router-address|)",
1658 * "Interface IPv6 config commands\n"
1659 * "Neighbor discovery\n"
1660 * "Prefix information\n"
1662 * "Valid lifetime in seconds\n"
1663 * "Infinite valid lifetime\n"
1664 * "Preferred lifetime in seconds\n"
1665 * "Infinite preferred lifetime\n"
1666 * "Do not use prefix for autoconfiguration\n"
1667 * "Do not use prefix for onlink determination\n"
1668 * "Set Router Address flag\n"
1670 * "no ipv6 nd prefix X:X::X:X/M (router-address|)",
1672 * "Interface IPv6 config commands\n"
1673 * "Neighbor discovery\n"
1674 * "Prefix information\n"
1676 * "Set Router Address flag\n"
1678 * "no ipv6 nd prefix X:X::X:X/M (off-link|)",
1680 * "Interface IPv6 config commands\n"
1681 * "Neighbor discovery\n"
1682 * "Prefix information\n"
1684 * "Do not use prefix for onlink determination\n"
1686 * "no ipv6 nd prefix X:X::X:X/M (no-autoconfig|)",
1688 * "Interface IPv6 config commands\n"
1689 * "Neighbor discovery\n"
1690 * "Prefix information\n"
1692 * "Do not use prefix for autoconfiguration\n"
1694 * "no ipv6 nd prefix X:X::X:X/M (no-autoconfig|) (off-link|)",
1696 * "Interface IPv6 config commands\n"
1697 * "Neighbor discovery\n"
1698 * "Prefix information\n"
1700 * "Do not use prefix for autoconfiguration\n"
1701 * "Do not use prefix for onlink determination\n"
1703 * "no ipv6 nd prefix X:X::X:X/M (off-link|) (no-autoconfig|)",
1705 * "Interface IPv6 config commands\n"
1706 * "Neighbor discovery\n"
1707 * "Prefix information\n"
1709 * "Do not use prefix for onlink determination\n"
1710 * "Do not use prefix for autoconfiguration\n"
1712 * "no ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) (<0-4294967295>|infinite) (router-address|)",
1714 * "Interface IPv6 config commands\n"
1715 * "Neighbor discovery\n"
1716 * "Prefix information\n"
1718 * "Valid lifetime in seconds\n"
1719 * "Infinite valid lifetime\n"
1720 * "Preferred lifetime in seconds\n"
1721 * "Infinite preferred lifetime\n"
1722 * "Set Router Address flag\n"
1724 * "no ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) (<0-4294967295>|infinite)",
1726 * "Interface IPv6 config commands\n"
1727 * "Neighbor discovery\n"
1728 * "Prefix information\n"
1730 * "Valid lifetime in seconds\n"
1731 * "Infinite valid lifetime\n"
1732 * "Preferred lifetime in seconds\n"
1733 * "Infinite preferred lifetime\n"
1736 DEFUN (no_ipv6_nd_prefix
,
1737 no_ipv6_nd_prefix_cmd
,
1738 "no ipv6 nd prefix IPV6PREFIX",
1740 "Interface IPv6 config commands\n"
1741 "Neighbor discovery\n"
1742 "Prefix information\n"
1746 struct interface
*ifp
;
1747 struct zebra_if
*zebra_if
;
1748 struct rtadv_prefix rp
;
1750 ifp
= (struct interface
*) vty
->index
;
1751 zebra_if
= ifp
->info
;
1753 ret
= str2prefix_ipv6 (argv
[0], &rp
.prefix
);
1756 vty_out (vty
, "Malformed IPv6 prefix%s", VTY_NEWLINE
);
1759 apply_mask_ipv6 (&rp
.prefix
); /* RFC4861 4.6.2 */
1761 ret
= rtadv_prefix_reset (zebra_if
, &rp
);
1764 vty_out (vty
, "Non-exist IPv6 prefix%s", VTY_NEWLINE
);
1783 DEFUN (ipv6_nd_router_preference
,
1784 ipv6_nd_router_preference_cmd
,
1785 "ipv6 nd router-preference <high|medium|low>",
1786 "Interface IPv6 config commands\n"
1787 "Neighbor discovery\n"
1788 "Default router preference\n"
1789 "High default router preference\n"
1790 "Low default router preference\n"
1791 "Medium default router preference (default)\n")
1793 struct interface
*ifp
;
1794 struct zebra_if
*zif
;
1797 ifp
= (struct interface
*) vty
->index
;
1800 while (0 != rtadv_pref_strs
[i
])
1802 if (strncmp (argv
[3]->arg
, rtadv_pref_strs
[i
], 1) == 0)
1804 zif
->rtadv
.DefaultPreference
= i
;
1810 return CMD_ERR_NO_MATCH
;
1814 * CHECK ME - The following ALIASes need to be implemented in this DEFUN
1815 * "no ipv6 nd router-preference (high|medium|low)",
1817 * "Interface IPv6 config commands\n"
1818 * "Neighbor discovery\n"
1819 * "Default router preference\n"
1820 * "High default router preference\n"
1821 * "Low default router preference\n"
1822 * "Medium default router preference (default)\n"
1825 DEFUN (no_ipv6_nd_router_preference
,
1826 no_ipv6_nd_router_preference_cmd
,
1827 "no ipv6 nd router-preference",
1829 "Interface IPv6 config commands\n"
1830 "Neighbor discovery\n"
1831 "Default router preference\n")
1833 struct interface
*ifp
;
1834 struct zebra_if
*zif
;
1836 ifp
= (struct interface
*) vty
->index
;
1839 zif
->rtadv
.DefaultPreference
= RTADV_PREF_MEDIUM
; /* Default per RFC4191. */
1847 "ipv6 nd mtu (1-65535)",
1848 "Interface IPv6 config commands\n"
1849 "Neighbor discovery\n"
1853 struct interface
*ifp
= (struct interface
*) vty
->index
;
1854 struct zebra_if
*zif
= ifp
->info
;
1855 VTY_GET_INTEGER_RANGE ("MTU", zif
->rtadv
.AdvLinkMTU
, argv
[3]->arg
, 1, 65535);
1860 * CHECK ME - The following ALIASes need to be implemented in this DEFUN
1861 * "no ipv6 nd mtu <1-65535>",
1863 * "Interface IPv6 config commands\n"
1864 * "Neighbor discovery\n"
1865 * "Advertised MTU\n"
1869 DEFUN (no_ipv6_nd_mtu
,
1873 "Interface IPv6 config commands\n"
1874 "Neighbor discovery\n"
1877 struct interface
*ifp
= (struct interface
*) vty
->index
;
1878 struct zebra_if
*zif
= ifp
->info
;
1879 zif
->rtadv
.AdvLinkMTU
= 0;
1884 /* Write configuration about router advertisement. */
1886 rtadv_config_write (struct vty
*vty
, struct interface
*ifp
)
1888 struct zebra_if
*zif
;
1889 struct listnode
*node
;
1890 struct rtadv_prefix
*rprefix
;
1891 char buf
[PREFIX_STRLEN
];
1896 if (!(if_is_loopback (ifp
) ||
1897 CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_VRF_LOOPBACK
)))
1899 if (zif
->rtadv
.AdvSendAdvertisements
)
1900 vty_out (vty
, " no ipv6 nd suppress-ra%s", VTY_NEWLINE
);
1903 interval
= zif
->rtadv
.MaxRtrAdvInterval
;
1904 if (interval
% 1000)
1905 vty_out (vty
, " ipv6 nd ra-interval msec %d%s", interval
,
1908 if (interval
!= RTADV_MAX_RTR_ADV_INTERVAL
)
1909 vty_out (vty
, " ipv6 nd ra-interval %d%s", interval
/ 1000,
1912 if (zif
->rtadv
.AdvIntervalOption
)
1913 vty_out (vty
, " ipv6 nd adv-interval-option%s", VTY_NEWLINE
);
1915 if (zif
->rtadv
.AdvDefaultLifetime
!= -1)
1916 vty_out (vty
, " ipv6 nd ra-lifetime %d%s", zif
->rtadv
.AdvDefaultLifetime
,
1919 if (zif
->rtadv
.HomeAgentPreference
)
1920 vty_out (vty
, " ipv6 nd home-agent-preference %u%s",
1921 zif
->rtadv
.HomeAgentPreference
, VTY_NEWLINE
);
1923 if (zif
->rtadv
.HomeAgentLifetime
!= -1)
1924 vty_out (vty
, " ipv6 nd home-agent-lifetime %u%s",
1925 zif
->rtadv
.HomeAgentLifetime
, VTY_NEWLINE
);
1927 if (zif
->rtadv
.AdvHomeAgentFlag
)
1928 vty_out (vty
, " ipv6 nd home-agent-config-flag%s", VTY_NEWLINE
);
1930 if (zif
->rtadv
.AdvReachableTime
)
1931 vty_out (vty
, " ipv6 nd reachable-time %d%s", zif
->rtadv
.AdvReachableTime
,
1934 if (zif
->rtadv
.AdvManagedFlag
)
1935 vty_out (vty
, " ipv6 nd managed-config-flag%s", VTY_NEWLINE
);
1937 if (zif
->rtadv
.AdvOtherConfigFlag
)
1938 vty_out (vty
, " ipv6 nd other-config-flag%s", VTY_NEWLINE
);
1940 if (zif
->rtadv
.DefaultPreference
!= RTADV_PREF_MEDIUM
)
1941 vty_out (vty
, " ipv6 nd router-preference %s%s",
1942 rtadv_pref_strs
[zif
->rtadv
.DefaultPreference
],
1945 if (zif
->rtadv
.AdvLinkMTU
)
1946 vty_out (vty
, " ipv6 nd mtu %d%s", zif
->rtadv
.AdvLinkMTU
, VTY_NEWLINE
);
1948 for (ALL_LIST_ELEMENTS_RO (zif
->rtadv
.AdvPrefixList
, node
, rprefix
))
1950 vty_out (vty
, " ipv6 nd prefix %s",
1951 prefix2str (&rprefix
->prefix
, buf
, sizeof(buf
)));
1952 if ((rprefix
->AdvValidLifetime
!= RTADV_VALID_LIFETIME
) ||
1953 (rprefix
->AdvPreferredLifetime
!= RTADV_PREFERRED_LIFETIME
))
1955 if (rprefix
->AdvValidLifetime
== UINT32_MAX
)
1956 vty_out (vty
, " infinite");
1958 vty_out (vty
, " %u", rprefix
->AdvValidLifetime
);
1959 if (rprefix
->AdvPreferredLifetime
== UINT32_MAX
)
1960 vty_out (vty
, " infinite");
1962 vty_out (vty
, " %u", rprefix
->AdvPreferredLifetime
);
1964 if (!rprefix
->AdvOnLinkFlag
)
1965 vty_out (vty
, " off-link");
1966 if (!rprefix
->AdvAutonomousFlag
)
1967 vty_out (vty
, " no-autoconfig");
1968 if (rprefix
->AdvRouterAddressFlag
)
1969 vty_out (vty
, " router-address");
1970 vty_out (vty
, "%s", VTY_NEWLINE
);
1976 rtadv_event (struct zebra_ns
*zns
, enum rtadv_event event
, int val
)
1978 struct rtadv
*rtadv
= &zns
->rtadv
;
1983 if (! rtadv
->ra_read
)
1984 rtadv
->ra_read
= thread_add_read (zebrad
.master
, rtadv_read
, zns
, val
);
1985 if (! rtadv
->ra_timer
)
1986 rtadv
->ra_timer
= thread_add_event (zebrad
.master
, rtadv_timer
,
1990 if (rtadv
->ra_timer
)
1992 thread_cancel (rtadv
->ra_timer
);
1993 rtadv
->ra_timer
= NULL
;
1997 thread_cancel (rtadv
->ra_read
);
1998 rtadv
->ra_read
= NULL
;
2002 if (! rtadv
->ra_timer
)
2003 rtadv
->ra_timer
= thread_add_timer (zebrad
.master
, rtadv_timer
, zns
,
2006 case RTADV_TIMER_MSEC
:
2007 if (! rtadv
->ra_timer
)
2008 rtadv
->ra_timer
= thread_add_timer_msec (zebrad
.master
, rtadv_timer
,
2012 if (! rtadv
->ra_read
)
2013 rtadv
->ra_read
= thread_add_read (zebrad
.master
, rtadv_read
, zns
, val
);
2022 rtadv_init (struct zebra_ns
*zns
)
2024 zns
->rtadv
.sock
= rtadv_make_socket ();
2028 rtadv_terminate (struct zebra_ns
*zns
)
2030 rtadv_event (zns
, RTADV_STOP
, 0);
2031 if (zns
->rtadv
.sock
>= 0)
2033 close (zns
->rtadv
.sock
);
2034 zns
->rtadv
.sock
= -1;
2037 zns
->rtadv
.adv_if_count
= 0;
2038 zns
->rtadv
.adv_msec_if_count
= 0;
2042 rtadv_cmd_init (void)
2044 install_element (INTERFACE_NODE
, &ipv6_nd_suppress_ra_cmd
);
2045 install_element (INTERFACE_NODE
, &no_ipv6_nd_suppress_ra_cmd
);
2046 install_element (INTERFACE_NODE
, &ipv6_nd_ra_interval_cmd
);
2047 install_element (INTERFACE_NODE
, &ipv6_nd_ra_interval_msec_cmd
);
2048 install_element (INTERFACE_NODE
, &no_ipv6_nd_ra_interval_cmd
);
2049 install_element (INTERFACE_NODE
, &ipv6_nd_ra_lifetime_cmd
);
2050 install_element (INTERFACE_NODE
, &no_ipv6_nd_ra_lifetime_cmd
);
2051 install_element (INTERFACE_NODE
, &ipv6_nd_reachable_time_cmd
);
2052 install_element (INTERFACE_NODE
, &no_ipv6_nd_reachable_time_cmd
);
2053 install_element (INTERFACE_NODE
, &ipv6_nd_managed_config_flag_cmd
);
2054 install_element (INTERFACE_NODE
, &no_ipv6_nd_managed_config_flag_cmd
);
2055 install_element (INTERFACE_NODE
, &ipv6_nd_other_config_flag_cmd
);
2056 install_element (INTERFACE_NODE
, &no_ipv6_nd_other_config_flag_cmd
);
2057 install_element (INTERFACE_NODE
, &ipv6_nd_homeagent_config_flag_cmd
);
2058 install_element (INTERFACE_NODE
, &no_ipv6_nd_homeagent_config_flag_cmd
);
2059 install_element (INTERFACE_NODE
, &ipv6_nd_homeagent_preference_cmd
);
2060 install_element (INTERFACE_NODE
, &no_ipv6_nd_homeagent_preference_cmd
);
2061 install_element (INTERFACE_NODE
, &ipv6_nd_homeagent_lifetime_cmd
);
2062 install_element (INTERFACE_NODE
, &no_ipv6_nd_homeagent_lifetime_cmd
);
2063 install_element (INTERFACE_NODE
, &ipv6_nd_adv_interval_config_option_cmd
);
2064 install_element (INTERFACE_NODE
, &no_ipv6_nd_adv_interval_config_option_cmd
);
2065 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_cmd
);
2066 install_element (INTERFACE_NODE
, &no_ipv6_nd_prefix_cmd
);
2067 install_element (INTERFACE_NODE
, &ipv6_nd_router_preference_cmd
);
2068 install_element (INTERFACE_NODE
, &no_ipv6_nd_router_preference_cmd
);
2069 install_element (INTERFACE_NODE
, &ipv6_nd_mtu_cmd
);
2070 install_element (INTERFACE_NODE
, &no_ipv6_nd_mtu_cmd
);
2074 if_join_all_router (int sock
, struct interface
*ifp
)
2078 struct ipv6_mreq mreq
;
2080 memset (&mreq
, 0, sizeof (struct ipv6_mreq
));
2081 inet_pton (AF_INET6
, ALLROUTER
, &mreq
.ipv6mr_multiaddr
);
2082 mreq
.ipv6mr_interface
= ifp
->ifindex
;
2084 ret
= setsockopt (sock
, IPPROTO_IPV6
, IPV6_JOIN_GROUP
,
2085 (char *) &mreq
, sizeof mreq
);
2087 zlog_warn ("%s(%u): Failed to join group, socket %u error %s",
2088 ifp
->name
, ifp
->ifindex
, sock
, safe_strerror (errno
));
2090 if (IS_ZEBRA_DEBUG_EVENT
)
2091 zlog_debug ("%s(%u): Join All-Routers multicast group, socket %u",
2092 ifp
->name
, ifp
->ifindex
, sock
);
2098 if_leave_all_router (int sock
, struct interface
*ifp
)
2102 struct ipv6_mreq mreq
;
2104 memset (&mreq
, 0, sizeof (struct ipv6_mreq
));
2105 inet_pton (AF_INET6
, ALLROUTER
, &mreq
.ipv6mr_multiaddr
);
2106 mreq
.ipv6mr_interface
= ifp
->ifindex
;
2108 ret
= setsockopt (sock
, IPPROTO_IPV6
, IPV6_LEAVE_GROUP
,
2109 (char *) &mreq
, sizeof mreq
);
2111 zlog_warn ("%s(%u): Failed to leave group, socket %u error %s",
2112 ifp
->name
, ifp
->ifindex
, sock
,safe_strerror (errno
));
2114 if (IS_ZEBRA_DEBUG_EVENT
)
2115 zlog_debug ("%s(%u): Leave All-Routers multicast group, socket %u",
2116 ifp
->name
, ifp
->ifindex
, sock
);
2123 rtadv_init (struct zebra_ns
*zns
)
2128 rtadv_terminate (struct zebra_ns
*zns
)
2133 rtadv_cmd_init (void)
2137 #endif /* HAVE_RTADV && HAVE_IPV6 */