]> git.proxmox.com Git - mirror_frr.git/blob - zebra/rtadv.c
zebra: stack overrun in IPv6 RA receive code (CVE ##TBA##)
[mirror_frr.git] / zebra / rtadv.c
1 /* Router advertisement
2 * Copyright (C) 2005 6WIND <jean-mickael.guerin@6wind.com>
3 * Copyright (C) 1999 Kunihiro Ishiguro
4 *
5 * This file is part of GNU Zebra.
6 *
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
10 * later version.
11 *
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.
16 *
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
20 * 02111-1307, USA.
21 */
22
23 #include <zebra.h>
24
25 #include "memory.h"
26 #include "sockopt.h"
27 #include "thread.h"
28 #include "if.h"
29 #include "stream.h"
30 #include "log.h"
31 #include "prefix.h"
32 #include "linklist.h"
33 #include "command.h"
34 #include "privs.h"
35 #include "vrf.h"
36
37 #include "zebra/interface.h"
38 #include "zebra/rtadv.h"
39 #include "zebra/debug.h"
40 #include "zebra/rib.h"
41 #include "zebra/zserv.h"
42 #include "zebra/zebra_ns.h"
43 #include "zebra/zebra_vrf.h"
44
45 extern struct zebra_privs_t zserv_privs;
46
47 #if defined (HAVE_IPV6) && defined (HAVE_RTADV)
48
49 #ifdef OPEN_BSD
50 #include <netinet/icmp6.h>
51 #endif
52
53 /* If RFC2133 definition is used. */
54 #ifndef IPV6_JOIN_GROUP
55 #define IPV6_JOIN_GROUP IPV6_ADD_MEMBERSHIP
56 #endif
57 #ifndef IPV6_LEAVE_GROUP
58 #define IPV6_LEAVE_GROUP IPV6_DROP_MEMBERSHIP
59 #endif
60
61 #define ALLNODE "ff02::1"
62 #define ALLROUTER "ff02::2"
63
64 enum rtadv_event {RTADV_START, RTADV_STOP, RTADV_TIMER,
65 RTADV_TIMER_MSEC, RTADV_READ};
66
67 static void rtadv_event (struct zebra_ns *, enum rtadv_event, int);
68
69 static int if_join_all_router (int, struct interface *);
70 static int if_leave_all_router (int, struct interface *);
71
72 static int
73 rtadv_increment_received(struct zebra_ns *zns, unsigned int *ifindex)
74 {
75 int ret = -1;
76 struct interface *iface;
77 struct zebra_if *zif;
78
79 iface = if_lookup_by_index_per_ns (zns, *ifindex);
80 if (iface && iface->info)
81 {
82 zif = iface->info;
83 zif->ra_rcvd++;
84 ret = 0;
85 }
86 return ret;
87 }
88
89 static int
90 rtadv_recv_packet (struct zebra_ns *zns, int sock, u_char *buf, int buflen,
91 struct sockaddr_in6 *from, unsigned int *ifindex,
92 int *hoplimit)
93 {
94 int ret;
95 struct msghdr msg;
96 struct iovec iov;
97 struct cmsghdr *cmsgptr;
98 struct in6_addr dst;
99
100 char adata[1024];
101
102 /* Fill in message and iovec. */
103 msg.msg_name = (void *) from;
104 msg.msg_namelen = sizeof (struct sockaddr_in6);
105 msg.msg_iov = &iov;
106 msg.msg_iovlen = 1;
107 msg.msg_control = (void *) adata;
108 msg.msg_controllen = sizeof adata;
109 iov.iov_base = buf;
110 iov.iov_len = buflen;
111
112 /* If recvmsg fail return minus value. */
113 ret = recvmsg (sock, &msg, 0);
114 if (ret < 0)
115 return ret;
116
117 for (cmsgptr = ZCMSG_FIRSTHDR(&msg); cmsgptr != NULL;
118 cmsgptr = CMSG_NXTHDR(&msg, cmsgptr))
119 {
120 /* I want interface index which this packet comes from. */
121 if (cmsgptr->cmsg_level == IPPROTO_IPV6 &&
122 cmsgptr->cmsg_type == IPV6_PKTINFO)
123 {
124 struct in6_pktinfo *ptr;
125
126 ptr = (struct in6_pktinfo *) CMSG_DATA (cmsgptr);
127 *ifindex = ptr->ipi6_ifindex;
128 memcpy(&dst, &ptr->ipi6_addr, sizeof(ptr->ipi6_addr));
129 }
130
131 /* Incoming packet's hop limit. */
132 if (cmsgptr->cmsg_level == IPPROTO_IPV6 &&
133 cmsgptr->cmsg_type == IPV6_HOPLIMIT)
134 {
135 int *hoptr = (int *) CMSG_DATA (cmsgptr);
136 *hoplimit = *hoptr;
137 }
138 }
139
140 rtadv_increment_received(zns, ifindex);
141 return ret;
142 }
143
144 #define RTADV_MSG_SIZE 4096
145
146 /* Send router advertisement packet. */
147 static void
148 rtadv_send_packet (int sock, struct interface *ifp)
149 {
150 struct msghdr msg;
151 struct iovec iov;
152 struct cmsghdr *cmsgptr;
153 struct in6_pktinfo *pkt;
154 struct sockaddr_in6 addr;
155 #ifdef HAVE_STRUCT_SOCKADDR_DL
156 struct sockaddr_dl *sdl;
157 #endif /* HAVE_STRUCT_SOCKADDR_DL */
158 static void *adata = NULL;
159 unsigned char buf[RTADV_MSG_SIZE];
160 struct nd_router_advert *rtadv;
161 int ret;
162 int len = 0;
163 struct zebra_if *zif;
164 struct rtadv_prefix *rprefix;
165 u_char all_nodes_addr[] = {0xff,0x02,0,0,0,0,0,0,0,0,0,0,0,0,0,1};
166 struct listnode *node;
167 u_int16_t pkt_RouterLifetime;
168
169 /*
170 * Allocate control message bufffer. This is dynamic because
171 * CMSG_SPACE is not guaranteed not to call a function. Note that
172 * the size will be different on different architectures due to
173 * differing alignment rules.
174 */
175 if (adata == NULL)
176 {
177 /* XXX Free on shutdown. */
178 adata = malloc(CMSG_SPACE(sizeof(struct in6_pktinfo)));
179
180 if (adata == NULL)
181 zlog_err("rtadv_send_packet: can't malloc control data");
182 }
183
184 /* Logging of packet. */
185 if (IS_ZEBRA_DEBUG_PACKET)
186 zlog_debug ("%s(%u): Tx RA, socket %u",
187 ifp->name, ifp->ifindex, sock);
188
189 /* Fill in sockaddr_in6. */
190 memset (&addr, 0, sizeof (struct sockaddr_in6));
191 addr.sin6_family = AF_INET6;
192 #ifdef SIN6_LEN
193 addr.sin6_len = sizeof (struct sockaddr_in6);
194 #endif /* SIN6_LEN */
195 addr.sin6_port = htons (IPPROTO_ICMPV6);
196 IPV6_ADDR_COPY (&addr.sin6_addr, all_nodes_addr);
197
198 /* Fetch interface information. */
199 zif = ifp->info;
200
201 /* Make router advertisement message. */
202 rtadv = (struct nd_router_advert *) buf;
203
204 rtadv->nd_ra_type = ND_ROUTER_ADVERT;
205 rtadv->nd_ra_code = 0;
206 rtadv->nd_ra_cksum = 0;
207
208 rtadv->nd_ra_curhoplimit = 64;
209
210 /* RFC4191: Default Router Preference is 0 if Router Lifetime is 0. */
211 rtadv->nd_ra_flags_reserved =
212 zif->rtadv.AdvDefaultLifetime == 0 ? 0 : zif->rtadv.DefaultPreference;
213 rtadv->nd_ra_flags_reserved <<= 3;
214
215 if (zif->rtadv.AdvManagedFlag)
216 rtadv->nd_ra_flags_reserved |= ND_RA_FLAG_MANAGED;
217 if (zif->rtadv.AdvOtherConfigFlag)
218 rtadv->nd_ra_flags_reserved |= ND_RA_FLAG_OTHER;
219 if (zif->rtadv.AdvHomeAgentFlag)
220 rtadv->nd_ra_flags_reserved |= ND_RA_FLAG_HOME_AGENT;
221 /* Note that according to Neighbor Discovery (RFC 4861 [18]),
222 * AdvDefaultLifetime is by default based on the value of
223 * MaxRtrAdvInterval. AdvDefaultLifetime is used in the Router Lifetime
224 * field of Router Advertisements. Given that this field is expressed
225 * in seconds, a small MaxRtrAdvInterval value can result in a zero
226 * value for this field. To prevent this, routers SHOULD keep
227 * AdvDefaultLifetime in at least one second, even if the use of
228 * MaxRtrAdvInterval would result in a smaller value. -- RFC6275, 7.5 */
229 pkt_RouterLifetime = zif->rtadv.AdvDefaultLifetime != -1 ?
230 zif->rtadv.AdvDefaultLifetime :
231 MAX (1, 0.003 * zif->rtadv.MaxRtrAdvInterval);
232 rtadv->nd_ra_router_lifetime = htons (pkt_RouterLifetime);
233 rtadv->nd_ra_reachable = htonl (zif->rtadv.AdvReachableTime);
234 rtadv->nd_ra_retransmit = htonl (0);
235
236 len = sizeof (struct nd_router_advert);
237
238 /* If both the Home Agent Preference and Home Agent Lifetime are set to
239 * their default values specified above, this option SHOULD NOT be
240 * included in the Router Advertisement messages sent by this home
241 * agent. -- RFC6275, 7.4 */
242 if
243 (
244 zif->rtadv.AdvHomeAgentFlag &&
245 (zif->rtadv.HomeAgentPreference || zif->rtadv.HomeAgentLifetime != -1)
246 )
247 {
248 struct nd_opt_homeagent_info *ndopt_hai =
249 (struct nd_opt_homeagent_info *)(buf + len);
250 ndopt_hai->nd_opt_hai_type = ND_OPT_HA_INFORMATION;
251 ndopt_hai->nd_opt_hai_len = 1;
252 ndopt_hai->nd_opt_hai_reserved = 0;
253 ndopt_hai->nd_opt_hai_preference = htons(zif->rtadv.HomeAgentPreference);
254 /* 16-bit unsigned integer. The lifetime associated with the home
255 * agent in units of seconds. The default value is the same as the
256 * Router Lifetime, as specified in the main body of the Router
257 * Advertisement. The maximum value corresponds to 18.2 hours. A
258 * value of 0 MUST NOT be used. -- RFC6275, 7.5 */
259 ndopt_hai->nd_opt_hai_lifetime = htons
260 (
261 zif->rtadv.HomeAgentLifetime != -1 ?
262 zif->rtadv.HomeAgentLifetime :
263 MAX (1, pkt_RouterLifetime) /* 0 is OK for RL, but not for HAL*/
264 );
265 len += sizeof(struct nd_opt_homeagent_info);
266 }
267
268 if (zif->rtadv.AdvIntervalOption)
269 {
270 struct nd_opt_adv_interval *ndopt_adv =
271 (struct nd_opt_adv_interval *)(buf + len);
272 ndopt_adv->nd_opt_ai_type = ND_OPT_ADV_INTERVAL;
273 ndopt_adv->nd_opt_ai_len = 1;
274 ndopt_adv->nd_opt_ai_reserved = 0;
275 ndopt_adv->nd_opt_ai_interval = htonl(zif->rtadv.MaxRtrAdvInterval);
276 len += sizeof(struct nd_opt_adv_interval);
277 }
278
279 /* Fill in prefix. */
280 for (ALL_LIST_ELEMENTS_RO (zif->rtadv.AdvPrefixList, node, rprefix))
281 {
282 struct nd_opt_prefix_info *pinfo;
283
284 pinfo = (struct nd_opt_prefix_info *) (buf + len);
285
286 pinfo->nd_opt_pi_type = ND_OPT_PREFIX_INFORMATION;
287 pinfo->nd_opt_pi_len = 4;
288 pinfo->nd_opt_pi_prefix_len = rprefix->prefix.prefixlen;
289
290 pinfo->nd_opt_pi_flags_reserved = 0;
291 if (rprefix->AdvOnLinkFlag)
292 pinfo->nd_opt_pi_flags_reserved |= ND_OPT_PI_FLAG_ONLINK;
293 if (rprefix->AdvAutonomousFlag)
294 pinfo->nd_opt_pi_flags_reserved |= ND_OPT_PI_FLAG_AUTO;
295 if (rprefix->AdvRouterAddressFlag)
296 pinfo->nd_opt_pi_flags_reserved |= ND_OPT_PI_FLAG_RADDR;
297
298 pinfo->nd_opt_pi_valid_time = htonl (rprefix->AdvValidLifetime);
299 pinfo->nd_opt_pi_preferred_time = htonl (rprefix->AdvPreferredLifetime);
300 pinfo->nd_opt_pi_reserved2 = 0;
301
302 IPV6_ADDR_COPY (&pinfo->nd_opt_pi_prefix, &rprefix->prefix.prefix);
303
304 #ifdef DEBUG
305 {
306 u_char buf[INET6_ADDRSTRLEN];
307
308 zlog_debug ("DEBUG %s", inet_ntop (AF_INET6, &pinfo->nd_opt_pi_prefix,
309 buf, INET6_ADDRSTRLEN));
310
311 }
312 #endif /* DEBUG */
313
314 len += sizeof (struct nd_opt_prefix_info);
315 }
316
317 /* Hardware address. */
318 #ifdef HAVE_STRUCT_SOCKADDR_DL
319 sdl = &ifp->sdl;
320 if (sdl != NULL && sdl->sdl_alen != 0)
321 {
322 buf[len++] = ND_OPT_SOURCE_LINKADDR;
323
324 /* Option length should be rounded up to next octet if
325 the link address does not end on an octet boundary. */
326 buf[len++] = (sdl->sdl_alen + 9) >> 3;
327
328 memcpy (buf + len, LLADDR (sdl), sdl->sdl_alen);
329 len += sdl->sdl_alen;
330
331 /* Pad option to end on an octet boundary. */
332 memset (buf + len, 0, -(sdl->sdl_alen + 2) & 0x7);
333 len += -(sdl->sdl_alen + 2) & 0x7;
334 }
335 #else
336 if (ifp->hw_addr_len != 0)
337 {
338 buf[len++] = ND_OPT_SOURCE_LINKADDR;
339
340 /* Option length should be rounded up to next octet if
341 the link address does not end on an octet boundary. */
342 buf[len++] = (ifp->hw_addr_len + 9) >> 3;
343
344 memcpy (buf + len, ifp->hw_addr, ifp->hw_addr_len);
345 len += ifp->hw_addr_len;
346
347 /* Pad option to end on an octet boundary. */
348 memset (buf + len, 0, -(ifp->hw_addr_len + 2) & 0x7);
349 len += -(ifp->hw_addr_len + 2) & 0x7;
350 }
351 #endif /* HAVE_STRUCT_SOCKADDR_DL */
352
353 /* MTU */
354 if (zif->rtadv.AdvLinkMTU)
355 {
356 struct nd_opt_mtu * opt = (struct nd_opt_mtu *) (buf + len);
357 opt->nd_opt_mtu_type = ND_OPT_MTU;
358 opt->nd_opt_mtu_len = 1;
359 opt->nd_opt_mtu_reserved = 0;
360 opt->nd_opt_mtu_mtu = htonl (zif->rtadv.AdvLinkMTU);
361 len += sizeof (struct nd_opt_mtu);
362 }
363
364 msg.msg_name = (void *) &addr;
365 msg.msg_namelen = sizeof (struct sockaddr_in6);
366 msg.msg_iov = &iov;
367 msg.msg_iovlen = 1;
368 msg.msg_control = (void *) adata;
369 msg.msg_controllen = CMSG_SPACE(sizeof(struct in6_pktinfo));
370 msg.msg_flags = 0;
371 iov.iov_base = buf;
372 iov.iov_len = len;
373
374 cmsgptr = ZCMSG_FIRSTHDR(&msg);
375 cmsgptr->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
376 cmsgptr->cmsg_level = IPPROTO_IPV6;
377 cmsgptr->cmsg_type = IPV6_PKTINFO;
378
379 pkt = (struct in6_pktinfo *) CMSG_DATA (cmsgptr);
380 memset (&pkt->ipi6_addr, 0, sizeof (struct in6_addr));
381 pkt->ipi6_ifindex = ifp->ifindex;
382
383 ret = sendmsg (sock, &msg, 0);
384 if (ret < 0)
385 {
386 zlog_err ("%s(%u): Tx RA failed, socket %u error %d (%s)",
387 ifp->name, ifp->ifindex, sock, errno, safe_strerror(errno));
388 }
389 else
390 zif->ra_sent++;
391 }
392
393 static int
394 rtadv_timer (struct thread *thread)
395 {
396 struct zebra_ns *zns = THREAD_ARG (thread);
397 vrf_iter_t iter;
398 struct listnode *node, *nnode;
399 struct interface *ifp;
400 struct zebra_if *zif;
401 int period;
402
403 zns->rtadv.ra_timer = NULL;
404 if (zns->rtadv.adv_msec_if_count == 0)
405 {
406 period = 1000; /* 1 s */
407 rtadv_event (zns, RTADV_TIMER, 1 /* 1 s */);
408 }
409 else
410 {
411 period = 10; /* 10 ms */
412 rtadv_event (zns, RTADV_TIMER_MSEC, 10 /* 10 ms */);
413 }
414
415 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
416 for (ALL_LIST_ELEMENTS (vrf_iter2iflist (iter), node, nnode, ifp))
417 {
418 if (if_is_loopback (ifp) ||
419 CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK) ||
420 ! if_is_operative (ifp))
421 continue;
422
423 zif = ifp->info;
424
425 if (zif->rtadv.AdvSendAdvertisements)
426 {
427 if (zif->rtadv.inFastRexmit)
428 {
429 /* We assume we fast rexmit every sec so no additional vars */
430 if (--zif->rtadv.NumFastReXmitsRemain <= 0)
431 zif->rtadv.inFastRexmit = 0;
432
433 if (IS_ZEBRA_DEBUG_SEND)
434 zlog_debug("Fast RA Rexmit on interface %s", ifp->name);
435
436 rtadv_send_packet (zns->rtadv.sock, ifp);
437 }
438 else
439 {
440 zif->rtadv.AdvIntervalTimer -= period;
441 if (zif->rtadv.AdvIntervalTimer <= 0)
442 {
443 /* FIXME: using MaxRtrAdvInterval each time isn't what section
444 6.2.4 of RFC4861 tells to do. */
445 zif->rtadv.AdvIntervalTimer = zif->rtadv.MaxRtrAdvInterval;
446 rtadv_send_packet (zns->rtadv.sock, ifp);
447 }
448 }
449 }
450 }
451
452 return 0;
453 }
454
455 static void
456 rtadv_process_solicit (struct interface *ifp)
457 {
458 struct zebra_vrf *zvrf = vrf_info_lookup (ifp->vrf_id);
459 struct zebra_ns *zns = zvrf->zns;
460
461 assert (zns);
462 rtadv_send_packet (zns->rtadv.sock, ifp);
463 }
464
465 static void
466 rtadv_process_advert (u_char *msg, unsigned int len, struct interface *ifp,
467 struct sockaddr_in6 *addr)
468 {
469 struct nd_router_advert *radvert;
470 char addr_str[INET6_ADDRSTRLEN];
471 struct zebra_if *zif;
472 struct prefix p;
473
474 zif = ifp->info;
475
476 inet_ntop (AF_INET6, &addr->sin6_addr, addr_str, INET6_ADDRSTRLEN);
477
478 if (len < sizeof(struct nd_router_advert)) {
479 zlog_warn("%s(%u): Rx RA with invalid length %d from %s",
480 ifp->name, ifp->ifindex, len, addr_str);
481 return;
482 }
483 if (!IN6_IS_ADDR_LINKLOCAL(&addr->sin6_addr)) {
484 zlog_warn("%s(%u): Rx RA with non-linklocal source address from %s",
485 ifp->name, ifp->ifindex, addr_str);
486 return;
487 }
488
489 radvert = (struct nd_router_advert *) msg;
490
491 if ((radvert->nd_ra_curhoplimit && zif->rtadv.AdvCurHopLimit) &&
492 (radvert->nd_ra_curhoplimit != zif->rtadv.AdvCurHopLimit))
493 {
494 zlog_warn("%s(%u): Rx RA - our AdvCurHopLimit doesn't agree with %s",
495 ifp->name, ifp->ifindex, addr_str);
496 }
497
498 if ((radvert->nd_ra_flags_reserved & ND_RA_FLAG_MANAGED) &&
499 !zif->rtadv.AdvManagedFlag)
500 {
501 zlog_warn("%s(%u): Rx RA - our AdvManagedFlag doesn't agree with %s",
502 ifp->name, ifp->ifindex, addr_str);
503 }
504
505 if ((radvert->nd_ra_flags_reserved & ND_RA_FLAG_OTHER) &&
506 !zif->rtadv.AdvOtherConfigFlag)
507 {
508 zlog_warn("%s(%u): Rx RA - our AdvOtherConfigFlag doesn't agree with %s",
509 ifp->name, ifp->ifindex, addr_str);
510 }
511
512 if ((radvert->nd_ra_reachable && zif->rtadv.AdvReachableTime) &&
513 (ntohl(radvert->nd_ra_reachable) != zif->rtadv.AdvReachableTime))
514 {
515 zlog_warn("%s(%u): Rx RA - our AdvReachableTime doesn't agree with %s",
516 ifp->name, ifp->ifindex, addr_str);
517 }
518
519 if ((radvert->nd_ra_retransmit && zif->rtadv.AdvRetransTimer) &&
520 (ntohl(radvert->nd_ra_retransmit) != (unsigned int)zif->rtadv.AdvRetransTimer))
521 {
522 zlog_warn("%s(%u): Rx RA - our AdvRetransTimer doesn't agree with %s",
523 ifp->name, ifp->ifindex, addr_str);
524 }
525
526 /* Create entry for neighbor if not known. */
527 p.family = AF_INET6;
528 IPV6_ADDR_COPY (&p.u.prefix, &addr->sin6_addr);
529 p.prefixlen = IPV6_MAX_PREFIXLEN;
530
531 if (!nbr_connected_check(ifp, &p))
532 nbr_connected_add_ipv6 (ifp, &addr->sin6_addr);
533 }
534
535
536 static void
537 rtadv_process_packet (u_char *buf, unsigned int len, unsigned int ifindex, int hoplimit,
538 struct sockaddr_in6 *from, struct zebra_ns *zns)
539 {
540 struct icmp6_hdr *icmph;
541 struct interface *ifp;
542 struct zebra_if *zif;
543 char addr_str[INET6_ADDRSTRLEN];
544
545 inet_ntop (AF_INET6, &from->sin6_addr, addr_str, INET6_ADDRSTRLEN);
546
547 /* Interface search. */
548 ifp = if_lookup_by_index_per_ns (zns, ifindex);
549 if (ifp == NULL)
550 {
551 zlog_warn ("RA/RS received on unknown IF %u from %s",
552 ifindex, addr_str);
553 return;
554 }
555
556 if (IS_ZEBRA_DEBUG_PACKET)
557 zlog_debug ("%s(%u): Rx RA/RS len %d from %s",
558 ifp->name, ifp->ifindex, len, addr_str);
559
560 if (if_is_loopback (ifp) ||
561 CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK))
562 return;
563
564 /* Check interface configuration. */
565 zif = ifp->info;
566 if (! zif->rtadv.AdvSendAdvertisements)
567 return;
568
569 /* ICMP message length check. */
570 if (len < sizeof (struct icmp6_hdr))
571 {
572 zlog_warn ("%s(%u): Rx RA with Invalid ICMPV6 packet length %d",
573 ifp->name, ifp->ifindex, len);
574 return;
575 }
576
577 icmph = (struct icmp6_hdr *) buf;
578
579 /* ICMP message type check. */
580 if (icmph->icmp6_type != ND_ROUTER_SOLICIT &&
581 icmph->icmp6_type != ND_ROUTER_ADVERT)
582 {
583 zlog_warn ("%s(%u): Rx RA - Unwanted ICMPV6 message type %d",
584 ifp->name, ifp->ifindex, icmph->icmp6_type);
585 return;
586 }
587
588 /* Hoplimit check. */
589 if (hoplimit >= 0 && hoplimit != 255)
590 {
591 zlog_warn ("%s(%u): Rx RA - Invalid hoplimit %d",
592 ifp->name, ifp->ifindex, hoplimit);
593 return;
594 }
595
596 /* Check ICMP message type. */
597 if (icmph->icmp6_type == ND_ROUTER_SOLICIT)
598 rtadv_process_solicit (ifp);
599 else if (icmph->icmp6_type == ND_ROUTER_ADVERT)
600 rtadv_process_advert (buf, len, ifp, from);
601
602 return;
603 }
604
605 static int
606 rtadv_read (struct thread *thread)
607 {
608 int sock;
609 int len;
610 u_char buf[RTADV_MSG_SIZE];
611 struct sockaddr_in6 from;
612 unsigned int ifindex = 0;
613 int hoplimit = -1;
614 struct zebra_ns *zns = THREAD_ARG (thread);
615
616 sock = THREAD_FD (thread);
617 zns->rtadv.ra_read = NULL;
618
619 /* Register myself. */
620 rtadv_event (zns, RTADV_READ, sock);
621
622 len = rtadv_recv_packet (zns, sock, buf, sizeof (buf), &from, &ifindex, &hoplimit);
623
624 if (len < 0)
625 {
626 zlog_warn ("RA/RS recv failed, socket %u error %s",
627 sock, safe_strerror (errno));
628 return len;
629 }
630
631 rtadv_process_packet (buf, (unsigned)len, ifindex, hoplimit, &from, zns);
632
633 return 0;
634 }
635
636 static int
637 rtadv_make_socket (void)
638 {
639 int sock;
640 int ret = 0;
641 struct icmp6_filter filter;
642
643 if ( zserv_privs.change (ZPRIVS_RAISE) )
644 zlog_err ("rtadv_make_socket: could not raise privs, %s",
645 safe_strerror (errno) );
646
647 sock = socket (AF_INET6, SOCK_RAW, IPPROTO_ICMPV6);
648
649 if ( zserv_privs.change (ZPRIVS_LOWER) )
650 zlog_err ("rtadv_make_socket: could not lower privs, %s",
651 safe_strerror (errno) );
652
653 if (sock < 0)
654 {
655 close (sock);
656 return -1;
657 }
658
659 ret = setsockopt_ipv6_pktinfo (sock, 1);
660 if (ret < 0)
661 {
662 close (sock);
663 return ret;
664 }
665 ret = setsockopt_ipv6_multicast_loop (sock, 0);
666 if (ret < 0)
667 {
668 close (sock);
669 return ret;
670 }
671 ret = setsockopt_ipv6_unicast_hops (sock, 255);
672 if (ret < 0)
673 {
674 close (sock);
675 return ret;
676 }
677 ret = setsockopt_ipv6_multicast_hops (sock, 255);
678 if (ret < 0)
679 {
680 close (sock);
681 return ret;
682 }
683 ret = setsockopt_ipv6_hoplimit (sock, 1);
684 if (ret < 0)
685 {
686 close (sock);
687 return ret;
688 }
689
690 ICMP6_FILTER_SETBLOCKALL(&filter);
691 ICMP6_FILTER_SETPASS (ND_ROUTER_SOLICIT, &filter);
692 ICMP6_FILTER_SETPASS (ND_ROUTER_ADVERT, &filter);
693
694 ret = setsockopt (sock, IPPROTO_ICMPV6, ICMP6_FILTER, &filter,
695 sizeof (struct icmp6_filter));
696 if (ret < 0)
697 {
698 zlog_info ("ICMP6_FILTER set fail: %s", safe_strerror (errno));
699 return ret;
700 }
701
702 return sock;
703 }
704
705 static struct rtadv_prefix *
706 rtadv_prefix_new (void)
707 {
708 return XCALLOC (MTYPE_RTADV_PREFIX, sizeof (struct rtadv_prefix));
709 }
710
711 static void
712 rtadv_prefix_free (struct rtadv_prefix *rtadv_prefix)
713 {
714 XFREE (MTYPE_RTADV_PREFIX, rtadv_prefix);
715 }
716
717 static struct rtadv_prefix *
718 rtadv_prefix_lookup (struct list *rplist, struct prefix_ipv6 *p)
719 {
720 struct listnode *node;
721 struct rtadv_prefix *rprefix;
722
723 for (ALL_LIST_ELEMENTS_RO (rplist, node, rprefix))
724 if (prefix_same ((struct prefix *) &rprefix->prefix, (struct prefix *) p))
725 return rprefix;
726 return NULL;
727 }
728
729 static struct rtadv_prefix *
730 rtadv_prefix_get (struct list *rplist, struct prefix_ipv6 *p)
731 {
732 struct rtadv_prefix *rprefix;
733
734 rprefix = rtadv_prefix_lookup (rplist, p);
735 if (rprefix)
736 return rprefix;
737
738 rprefix = rtadv_prefix_new ();
739 memcpy (&rprefix->prefix, p, sizeof (struct prefix_ipv6));
740 listnode_add (rplist, rprefix);
741
742 return rprefix;
743 }
744
745 static void
746 rtadv_prefix_set (struct zebra_if *zif, struct rtadv_prefix *rp)
747 {
748 struct rtadv_prefix *rprefix;
749
750 rprefix = rtadv_prefix_get (zif->rtadv.AdvPrefixList, &rp->prefix);
751
752 /* Set parameters. */
753 rprefix->AdvValidLifetime = rp->AdvValidLifetime;
754 rprefix->AdvPreferredLifetime = rp->AdvPreferredLifetime;
755 rprefix->AdvOnLinkFlag = rp->AdvOnLinkFlag;
756 rprefix->AdvAutonomousFlag = rp->AdvAutonomousFlag;
757 rprefix->AdvRouterAddressFlag = rp->AdvRouterAddressFlag;
758 }
759
760 static int
761 rtadv_prefix_reset (struct zebra_if *zif, struct rtadv_prefix *rp)
762 {
763 struct rtadv_prefix *rprefix;
764
765 rprefix = rtadv_prefix_lookup (zif->rtadv.AdvPrefixList, &rp->prefix);
766 if (rprefix != NULL)
767 {
768 listnode_delete (zif->rtadv.AdvPrefixList, (void *) rprefix);
769 rtadv_prefix_free (rprefix);
770 return 1;
771 }
772 else
773 return 0;
774 }
775
776 static void
777 ipv6_nd_suppress_ra_set (struct interface *ifp, ipv6_nd_suppress_ra_status status)
778 {
779 struct zebra_if *zif;
780 struct zebra_vrf *zvrf;
781 struct zebra_ns *zns;
782
783 zif = ifp->info;
784 zvrf = vrf_info_lookup (ifp->vrf_id);
785 zns = zvrf->zns;
786
787 if (status == RA_SUPPRESS)
788 {
789 /* RA is currently enabled */
790 if (zif->rtadv.AdvSendAdvertisements)
791 {
792 zif->rtadv.AdvSendAdvertisements = 0;
793 zif->rtadv.AdvIntervalTimer = 0;
794 zns->rtadv.adv_if_count--;
795
796 if_leave_all_router (zns->rtadv.sock, ifp);
797
798 if (zns->rtadv.adv_if_count == 0)
799 rtadv_event (zns, RTADV_STOP, 0);
800 }
801 }
802 else
803 {
804 if (! zif->rtadv.AdvSendAdvertisements)
805 {
806 zif->rtadv.AdvSendAdvertisements = 1;
807 zif->rtadv.AdvIntervalTimer = 0;
808 zns->rtadv.adv_if_count++;
809
810 if (zif->rtadv.MaxRtrAdvInterval >= 1000)
811 {
812 /* Enable Fast RA only when RA interval is in secs */
813 zif->rtadv.inFastRexmit = 1;
814 zif->rtadv.NumFastReXmitsRemain = RTADV_NUM_FAST_REXMITS;
815 }
816
817 if_join_all_router (zns->rtadv.sock, ifp);
818
819 if (zns->rtadv.adv_if_count == 1)
820 rtadv_event (zns, RTADV_START, zns->rtadv.sock);
821 }
822 }
823 }
824
825 /*
826 * Handle client (BGP) message to enable or disable IPv6 RA on an interface.
827 * Note that while the client could request RA on an interface on which the
828 * operator has not enabled RA, RA won't be disabled upon client request
829 * if the operator has explicitly enabled RA. The enable request can also
830 * specify a RA interval (in seconds).
831 */
832 void
833 zebra_interface_radv_set (struct zserv *client, int sock, u_short length,
834 struct zebra_vrf *zvrf, int enable)
835 {
836 struct stream *s;
837 unsigned int ifindex;
838 struct interface *ifp;
839 struct zebra_if *zif;
840 int ra_interval;
841
842 s = client->ibuf;
843
844 /* Get interface index and RA interval. */
845 ifindex = stream_getl (s);
846 ra_interval = stream_getl (s);
847
848 if (IS_ZEBRA_DEBUG_EVENT)
849 zlog_debug("%u: IF %u RA %s from client %s, interval %ds",
850 zvrf->vrf_id, ifindex, enable ? "enable" : "disable",
851 zebra_route_string(client->proto), ra_interval);
852
853 /* Locate interface and check VRF match. */
854 ifp = if_lookup_by_index_per_ns (zebra_ns_lookup (NS_DEFAULT), ifindex);
855 if (!ifp)
856 {
857 zlog_warn("%u: IF %u RA %s client %s - interface unknown",
858 zvrf->vrf_id, ifindex, enable ? "enable" : "disable",
859 zebra_route_string(client->proto));
860 return;
861 }
862 if (ifp->vrf_id != zvrf->vrf_id)
863 {
864 zlog_warn("%u: IF %u RA %s client %s - VRF mismatch, IF VRF %u",
865 zvrf->vrf_id, ifindex, enable ? "enable" : "disable",
866 zebra_route_string(client->proto), ifp->vrf_id);
867 return;
868 }
869
870 zif = ifp->info;
871 if (enable)
872 {
873 ipv6_nd_suppress_ra_set (ifp, RA_ENABLE);
874 if (ra_interval &&
875 (ra_interval * 1000) < zif->rtadv.MaxRtrAdvInterval)
876 zif->rtadv.MaxRtrAdvInterval = ra_interval * 1000;
877 }
878 else
879 {
880 if (!zif->rtadv.configured)
881 {
882 zif->rtadv.MaxRtrAdvInterval = RTADV_MAX_RTR_ADV_INTERVAL;
883 ipv6_nd_suppress_ra_set (ifp, RA_SUPPRESS);
884 }
885 }
886 }
887
888 DEFUN (ipv6_nd_suppress_ra,
889 ipv6_nd_suppress_ra_cmd,
890 "ipv6 nd suppress-ra",
891 "Interface IPv6 config commands\n"
892 "Neighbor discovery\n"
893 "Suppress Router Advertisement\n")
894 {
895 struct interface *ifp;
896 struct zebra_if *zif;
897
898 ifp = vty->index;
899
900 if (if_is_loopback (ifp) ||
901 CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK))
902 {
903 vty_out (vty, "Cannot configure IPv6 Router Advertisements on this interface%s", VTY_NEWLINE);
904 return CMD_WARNING;
905 }
906
907 ipv6_nd_suppress_ra_set (ifp, RA_SUPPRESS);
908 zif = ifp->info;
909 zif->rtadv.configured = 0;
910 return CMD_SUCCESS;
911 }
912
913 DEFUN (no_ipv6_nd_suppress_ra,
914 no_ipv6_nd_suppress_ra_cmd,
915 "no ipv6 nd suppress-ra",
916 NO_STR
917 "Interface IPv6 config commands\n"
918 "Neighbor discovery\n"
919 "Suppress Router Advertisement\n")
920 {
921 struct interface *ifp;
922 struct zebra_if *zif;
923
924 ifp = vty->index;
925
926 if (if_is_loopback (ifp) ||
927 CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK))
928 {
929 vty_out (vty, "Cannot configure IPv6 Router Advertisements on this interface%s", VTY_NEWLINE);
930 return CMD_WARNING;
931 }
932
933 ipv6_nd_suppress_ra_set (ifp, RA_ENABLE);
934 zif = ifp->info;
935 zif->rtadv.configured = 1;
936 return CMD_SUCCESS;
937 }
938
939 DEFUN (ipv6_nd_ra_interval_msec,
940 ipv6_nd_ra_interval_msec_cmd,
941 "ipv6 nd ra-interval msec <70-1800000>",
942 "Interface IPv6 config commands\n"
943 "Neighbor discovery\n"
944 "Router Advertisement interval\n"
945 "Router Advertisement interval in milliseconds\n")
946 {
947 unsigned interval;
948 struct interface *ifp = (struct interface *) vty->index;
949 struct zebra_if *zif = ifp->info;
950 struct zebra_vrf *zvrf = vrf_info_lookup (ifp->vrf_id);
951 struct zebra_ns *zns;
952
953 zns = zvrf->zns;
954 VTY_GET_INTEGER_RANGE ("router advertisement interval", interval, argv[0], 70, 1800000);
955 if ((zif->rtadv.AdvDefaultLifetime != -1 && interval > (unsigned)zif->rtadv.AdvDefaultLifetime * 1000))
956 {
957 vty_out (vty, "This ra-interval would conflict with configured ra-lifetime!%s", VTY_NEWLINE);
958 return CMD_WARNING;
959 }
960
961 if (zif->rtadv.MaxRtrAdvInterval % 1000)
962 zns->rtadv.adv_msec_if_count--;
963
964 if (interval % 1000)
965 zns->rtadv.adv_msec_if_count++;
966
967 zif->rtadv.MaxRtrAdvInterval = interval;
968 zif->rtadv.MinRtrAdvInterval = 0.33 * interval;
969 zif->rtadv.AdvIntervalTimer = 0;
970
971 return CMD_SUCCESS;
972 }
973
974 DEFUN (ipv6_nd_ra_interval,
975 ipv6_nd_ra_interval_cmd,
976 "ipv6 nd ra-interval <1-1800>",
977 "Interface IPv6 config commands\n"
978 "Neighbor discovery\n"
979 "Router Advertisement interval\n"
980 "Router Advertisement interval in seconds\n")
981 {
982 unsigned interval;
983 struct interface *ifp = (struct interface *) vty->index;
984 struct zebra_if *zif = ifp->info;
985 struct zebra_vrf *zvrf = vrf_info_lookup (ifp->vrf_id);
986 struct zebra_ns *zns;
987
988 zns = zvrf->zns;
989 VTY_GET_INTEGER_RANGE ("router advertisement interval", interval, argv[0], 1, 1800);
990 if ((zif->rtadv.AdvDefaultLifetime != -1 && interval > (unsigned)zif->rtadv.AdvDefaultLifetime))
991 {
992 vty_out (vty, "This ra-interval would conflict with configured ra-lifetime!%s", VTY_NEWLINE);
993 return CMD_WARNING;
994 }
995
996 if (zif->rtadv.MaxRtrAdvInterval % 1000)
997 zns->rtadv.adv_msec_if_count--;
998
999 /* convert to milliseconds */
1000 interval = interval * 1000;
1001
1002 zif->rtadv.MaxRtrAdvInterval = interval;
1003 zif->rtadv.MinRtrAdvInterval = 0.33 * interval;
1004 zif->rtadv.AdvIntervalTimer = 0;
1005
1006 return CMD_SUCCESS;
1007 }
1008
1009 DEFUN (no_ipv6_nd_ra_interval,
1010 no_ipv6_nd_ra_interval_cmd,
1011 "no ipv6 nd ra-interval",
1012 NO_STR
1013 "Interface IPv6 config commands\n"
1014 "Neighbor discovery\n"
1015 "Router Advertisement interval\n")
1016 {
1017 struct interface *ifp;
1018 struct zebra_if *zif;
1019 struct zebra_vrf *zvrf;
1020 struct zebra_ns *zns;
1021
1022 ifp = (struct interface *) vty->index;
1023 zif = ifp->info;
1024 zvrf = vrf_info_lookup (ifp->vrf_id);
1025 zns = zvrf->zns;
1026
1027 if (zif->rtadv.MaxRtrAdvInterval % 1000)
1028 zns->rtadv.adv_msec_if_count--;
1029
1030 zif->rtadv.MaxRtrAdvInterval = RTADV_MAX_RTR_ADV_INTERVAL;
1031 zif->rtadv.MinRtrAdvInterval = RTADV_MIN_RTR_ADV_INTERVAL;
1032 zif->rtadv.AdvIntervalTimer = zif->rtadv.MaxRtrAdvInterval;
1033
1034 return CMD_SUCCESS;
1035 }
1036
1037 ALIAS (no_ipv6_nd_ra_interval,
1038 no_ipv6_nd_ra_interval_val_cmd,
1039 "no ipv6 nd ra-interval <1-1800>",
1040 NO_STR
1041 "Interface IPv6 config commands\n"
1042 "Neighbor discovery\n"
1043 "Router Advertisement interval\n")
1044
1045 ALIAS (no_ipv6_nd_ra_interval,
1046 no_ipv6_nd_ra_interval_msec_val_cmd,
1047 "no ipv6 nd ra-interval msec <1-1800000>",
1048 NO_STR
1049 "Interface IPv6 config commands\n"
1050 "Neighbor discovery\n"
1051 "Router Advertisement interval\n"
1052 "Router Advertisement interval in milliseconds\n")
1053
1054 DEFUN (ipv6_nd_ra_lifetime,
1055 ipv6_nd_ra_lifetime_cmd,
1056 "ipv6 nd ra-lifetime <0-9000>",
1057 "Interface IPv6 config commands\n"
1058 "Neighbor discovery\n"
1059 "Router lifetime\n"
1060 "Router lifetime in seconds (0 stands for a non-default gw)\n")
1061 {
1062 int lifetime;
1063 struct interface *ifp;
1064 struct zebra_if *zif;
1065
1066 ifp = (struct interface *) vty->index;
1067 zif = ifp->info;
1068
1069 VTY_GET_INTEGER_RANGE ("router lifetime", lifetime, argv[0], 0, 9000);
1070
1071 /* The value to be placed in the Router Lifetime field
1072 * of Router Advertisements sent from the interface,
1073 * in seconds. MUST be either zero or between
1074 * MaxRtrAdvInterval and 9000 seconds. -- RFC4861, 6.2.1 */
1075 if ((lifetime != 0 && lifetime * 1000 < zif->rtadv.MaxRtrAdvInterval))
1076 {
1077 vty_out (vty, "This ra-lifetime would conflict with configured ra-interval%s", VTY_NEWLINE);
1078 return CMD_WARNING;
1079 }
1080
1081 zif->rtadv.AdvDefaultLifetime = lifetime;
1082
1083 return CMD_SUCCESS;
1084 }
1085
1086 DEFUN (no_ipv6_nd_ra_lifetime,
1087 no_ipv6_nd_ra_lifetime_cmd,
1088 "no ipv6 nd ra-lifetime",
1089 NO_STR
1090 "Interface IPv6 config commands\n"
1091 "Neighbor discovery\n"
1092 "Router lifetime\n")
1093 {
1094 struct interface *ifp;
1095 struct zebra_if *zif;
1096
1097 ifp = (struct interface *) vty->index;
1098 zif = ifp->info;
1099
1100 zif->rtadv.AdvDefaultLifetime = -1;
1101
1102 return CMD_SUCCESS;
1103 }
1104
1105 ALIAS (no_ipv6_nd_ra_lifetime,
1106 no_ipv6_nd_ra_lifetime_val_cmd,
1107 "no ipv6 nd ra-lifetime <0-9000>",
1108 NO_STR
1109 "Interface IPv6 config commands\n"
1110 "Neighbor discovery\n"
1111 "Router lifetime\n"
1112 "Router lifetime in seconds (0 stands for a non-default gw)\n")
1113
1114 DEFUN (ipv6_nd_reachable_time,
1115 ipv6_nd_reachable_time_cmd,
1116 "ipv6 nd reachable-time <1-3600000>",
1117 "Interface IPv6 config commands\n"
1118 "Neighbor discovery\n"
1119 "Reachable time\n"
1120 "Reachable time in milliseconds\n")
1121 {
1122 struct interface *ifp = (struct interface *) vty->index;
1123 struct zebra_if *zif = ifp->info;
1124 VTY_GET_INTEGER_RANGE ("reachable time", zif->rtadv.AdvReachableTime, argv[0], 1, RTADV_MAX_REACHABLE_TIME);
1125 return CMD_SUCCESS;
1126 }
1127
1128 DEFUN (no_ipv6_nd_reachable_time,
1129 no_ipv6_nd_reachable_time_cmd,
1130 "no ipv6 nd reachable-time",
1131 NO_STR
1132 "Interface IPv6 config commands\n"
1133 "Neighbor discovery\n"
1134 "Reachable time\n")
1135 {
1136 struct interface *ifp;
1137 struct zebra_if *zif;
1138
1139 ifp = (struct interface *) vty->index;
1140 zif = ifp->info;
1141
1142 zif->rtadv.AdvReachableTime = 0;
1143
1144 return CMD_SUCCESS;
1145 }
1146
1147 ALIAS (no_ipv6_nd_reachable_time,
1148 no_ipv6_nd_reachable_time_val_cmd,
1149 "no ipv6 nd reachable-time <1-3600000>",
1150 NO_STR
1151 "Interface IPv6 config commands\n"
1152 "Neighbor discovery\n"
1153 "Reachable time\n"
1154 "Reachable time in milliseconds\n")
1155
1156 DEFUN (ipv6_nd_homeagent_preference,
1157 ipv6_nd_homeagent_preference_cmd,
1158 "ipv6 nd home-agent-preference <0-65535>",
1159 "Interface IPv6 config commands\n"
1160 "Neighbor discovery\n"
1161 "Home Agent preference\n"
1162 "preference value (default is 0, least preferred)\n")
1163 {
1164 struct interface *ifp = (struct interface *) vty->index;
1165 struct zebra_if *zif = ifp->info;
1166 VTY_GET_INTEGER_RANGE ("home agent preference", zif->rtadv.HomeAgentPreference, argv[0], 0, 65535);
1167 return CMD_SUCCESS;
1168 }
1169
1170 DEFUN (no_ipv6_nd_homeagent_preference,
1171 no_ipv6_nd_homeagent_preference_cmd,
1172 "no ipv6 nd home-agent-preference",
1173 NO_STR
1174 "Interface IPv6 config commands\n"
1175 "Neighbor discovery\n"
1176 "Home Agent preference\n")
1177 {
1178 struct interface *ifp;
1179 struct zebra_if *zif;
1180
1181 ifp = (struct interface *) vty->index;
1182 zif = ifp->info;
1183
1184 zif->rtadv.HomeAgentPreference = 0;
1185
1186 return CMD_SUCCESS;
1187 }
1188
1189 ALIAS (no_ipv6_nd_homeagent_preference,
1190 no_ipv6_nd_homeagent_preference_val_cmd,
1191 "no ipv6 nd home-agent-preference <0-65535>",
1192 NO_STR
1193 "Interface IPv6 config commands\n"
1194 "Neighbor discovery\n"
1195 "Home Agent preference\n"
1196 "preference value (default is 0, least preferred)\n")
1197
1198 DEFUN (ipv6_nd_homeagent_lifetime,
1199 ipv6_nd_homeagent_lifetime_cmd,
1200 "ipv6 nd home-agent-lifetime <0-65520>",
1201 "Interface IPv6 config commands\n"
1202 "Neighbor discovery\n"
1203 "Home Agent lifetime\n"
1204 "Home Agent lifetime in seconds (0 to track ra-lifetime)\n")
1205 {
1206 struct interface *ifp = (struct interface *) vty->index;
1207 struct zebra_if *zif = ifp->info;
1208 VTY_GET_INTEGER_RANGE ("home agent lifetime", zif->rtadv.HomeAgentLifetime, argv[0], 0, RTADV_MAX_HALIFETIME);
1209 return CMD_SUCCESS;
1210 }
1211
1212 DEFUN (no_ipv6_nd_homeagent_lifetime,
1213 no_ipv6_nd_homeagent_lifetime_cmd,
1214 "no ipv6 nd home-agent-lifetime",
1215 NO_STR
1216 "Interface IPv6 config commands\n"
1217 "Neighbor discovery\n"
1218 "Home Agent lifetime\n")
1219 {
1220 struct interface *ifp;
1221 struct zebra_if *zif;
1222
1223 ifp = (struct interface *) vty->index;
1224 zif = ifp->info;
1225
1226 zif->rtadv.HomeAgentLifetime = -1;
1227
1228 return CMD_SUCCESS;
1229 }
1230
1231 ALIAS (no_ipv6_nd_homeagent_lifetime,
1232 no_ipv6_nd_homeagent_lifetime_val_cmd,
1233 "no ipv6 nd home-agent-lifetime <0-65520>",
1234 NO_STR
1235 "Interface IPv6 config commands\n"
1236 "Neighbor discovery\n"
1237 "Home Agent lifetime\n"
1238 "Home Agent lifetime in seconds (0 to track ra-lifetime)\n")
1239
1240 DEFUN (ipv6_nd_managed_config_flag,
1241 ipv6_nd_managed_config_flag_cmd,
1242 "ipv6 nd managed-config-flag",
1243 "Interface IPv6 config commands\n"
1244 "Neighbor discovery\n"
1245 "Managed address configuration flag\n")
1246 {
1247 struct interface *ifp;
1248 struct zebra_if *zif;
1249
1250 ifp = (struct interface *) vty->index;
1251 zif = ifp->info;
1252
1253 zif->rtadv.AdvManagedFlag = 1;
1254
1255 return CMD_SUCCESS;
1256 }
1257
1258 DEFUN (no_ipv6_nd_managed_config_flag,
1259 no_ipv6_nd_managed_config_flag_cmd,
1260 "no ipv6 nd managed-config-flag",
1261 NO_STR
1262 "Interface IPv6 config commands\n"
1263 "Neighbor discovery\n"
1264 "Managed address configuration flag\n")
1265 {
1266 struct interface *ifp;
1267 struct zebra_if *zif;
1268
1269 ifp = (struct interface *) vty->index;
1270 zif = ifp->info;
1271
1272 zif->rtadv.AdvManagedFlag = 0;
1273
1274 return CMD_SUCCESS;
1275 }
1276
1277 DEFUN (ipv6_nd_homeagent_config_flag,
1278 ipv6_nd_homeagent_config_flag_cmd,
1279 "ipv6 nd home-agent-config-flag",
1280 "Interface IPv6 config commands\n"
1281 "Neighbor discovery\n"
1282 "Home Agent configuration flag\n")
1283 {
1284 struct interface *ifp;
1285 struct zebra_if *zif;
1286
1287 ifp = (struct interface *) vty->index;
1288 zif = ifp->info;
1289
1290 zif->rtadv.AdvHomeAgentFlag = 1;
1291
1292 return CMD_SUCCESS;
1293 }
1294
1295 DEFUN (no_ipv6_nd_homeagent_config_flag,
1296 no_ipv6_nd_homeagent_config_flag_cmd,
1297 "no ipv6 nd home-agent-config-flag",
1298 NO_STR
1299 "Interface IPv6 config commands\n"
1300 "Neighbor discovery\n"
1301 "Home Agent configuration flag\n")
1302 {
1303 struct interface *ifp;
1304 struct zebra_if *zif;
1305
1306 ifp = (struct interface *) vty->index;
1307 zif = ifp->info;
1308
1309 zif->rtadv.AdvHomeAgentFlag = 0;
1310
1311 return CMD_SUCCESS;
1312 }
1313
1314 DEFUN (ipv6_nd_adv_interval_config_option,
1315 ipv6_nd_adv_interval_config_option_cmd,
1316 "ipv6 nd adv-interval-option",
1317 "Interface IPv6 config commands\n"
1318 "Neighbor discovery\n"
1319 "Advertisement Interval Option\n")
1320 {
1321 struct interface *ifp;
1322 struct zebra_if *zif;
1323
1324 ifp = (struct interface *) vty->index;
1325 zif = ifp->info;
1326
1327 zif->rtadv.AdvIntervalOption = 1;
1328
1329 return CMD_SUCCESS;
1330 }
1331
1332 DEFUN (no_ipv6_nd_adv_interval_config_option,
1333 no_ipv6_nd_adv_interval_config_option_cmd,
1334 "no ipv6 nd adv-interval-option",
1335 NO_STR
1336 "Interface IPv6 config commands\n"
1337 "Neighbor discovery\n"
1338 "Advertisement Interval Option\n")
1339 {
1340 struct interface *ifp;
1341 struct zebra_if *zif;
1342
1343 ifp = (struct interface *) vty->index;
1344 zif = ifp->info;
1345
1346 zif->rtadv.AdvIntervalOption = 0;
1347
1348 return CMD_SUCCESS;
1349 }
1350
1351 DEFUN (ipv6_nd_other_config_flag,
1352 ipv6_nd_other_config_flag_cmd,
1353 "ipv6 nd other-config-flag",
1354 "Interface IPv6 config commands\n"
1355 "Neighbor discovery\n"
1356 "Other statefull configuration flag\n")
1357 {
1358 struct interface *ifp;
1359 struct zebra_if *zif;
1360
1361 ifp = (struct interface *) vty->index;
1362 zif = ifp->info;
1363
1364 zif->rtadv.AdvOtherConfigFlag = 1;
1365
1366 return CMD_SUCCESS;
1367 }
1368
1369 DEFUN (no_ipv6_nd_other_config_flag,
1370 no_ipv6_nd_other_config_flag_cmd,
1371 "no ipv6 nd other-config-flag",
1372 NO_STR
1373 "Interface IPv6 config commands\n"
1374 "Neighbor discovery\n"
1375 "Other statefull configuration flag\n")
1376 {
1377 struct interface *ifp;
1378 struct zebra_if *zif;
1379
1380 ifp = (struct interface *) vty->index;
1381 zif = ifp->info;
1382
1383 zif->rtadv.AdvOtherConfigFlag = 0;
1384
1385 return CMD_SUCCESS;
1386 }
1387
1388 DEFUN (ipv6_nd_prefix,
1389 ipv6_nd_prefix_cmd,
1390 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1391 "(<0-4294967295>|infinite) (off-link|) (no-autoconfig|) (router-address|)",
1392 "Interface IPv6 config commands\n"
1393 "Neighbor discovery\n"
1394 "Prefix information\n"
1395 "IPv6 prefix\n"
1396 "Valid lifetime in seconds\n"
1397 "Infinite valid lifetime\n"
1398 "Preferred lifetime in seconds\n"
1399 "Infinite preferred lifetime\n"
1400 "Do not use prefix for onlink determination\n"
1401 "Do not use prefix for autoconfiguration\n"
1402 "Set Router Address flag\n")
1403 {
1404 int i;
1405 int ret;
1406 int cursor = 1;
1407 struct interface *ifp;
1408 struct zebra_if *zebra_if;
1409 struct rtadv_prefix rp;
1410
1411 ifp = (struct interface *) vty->index;
1412 zebra_if = ifp->info;
1413
1414 ret = str2prefix_ipv6 (argv[0], &rp.prefix);
1415 if (!ret)
1416 {
1417 vty_out (vty, "Malformed IPv6 prefix%s", VTY_NEWLINE);
1418 return CMD_WARNING;
1419 }
1420 apply_mask_ipv6 (&rp.prefix); /* RFC4861 4.6.2 */
1421 rp.AdvOnLinkFlag = 1;
1422 rp.AdvAutonomousFlag = 1;
1423 rp.AdvRouterAddressFlag = 0;
1424 rp.AdvValidLifetime = RTADV_VALID_LIFETIME;
1425 rp.AdvPreferredLifetime = RTADV_PREFERRED_LIFETIME;
1426
1427 if (argc > 1)
1428 {
1429 if ((isdigit((unsigned char)argv[1][0]))
1430 || strncmp (argv[1], "i", 1) == 0)
1431 {
1432 if ( strncmp (argv[1], "i", 1) == 0)
1433 rp.AdvValidLifetime = UINT32_MAX;
1434 else
1435 rp.AdvValidLifetime = (u_int32_t) strtoll (argv[1],
1436 (char **)NULL, 10);
1437
1438 if ( strncmp (argv[2], "i", 1) == 0)
1439 rp.AdvPreferredLifetime = UINT32_MAX;
1440 else
1441 rp.AdvPreferredLifetime = (u_int32_t) strtoll (argv[2],
1442 (char **)NULL, 10);
1443
1444 if (rp.AdvPreferredLifetime > rp.AdvValidLifetime)
1445 {
1446 vty_out (vty, "Invalid preferred lifetime%s", VTY_NEWLINE);
1447 return CMD_WARNING;
1448 }
1449 cursor = cursor + 2;
1450 }
1451 if (argc > cursor)
1452 {
1453 for (i = cursor; i < argc; i++)
1454 {
1455 if (strncmp (argv[i], "of", 2) == 0)
1456 rp.AdvOnLinkFlag = 0;
1457 if (strncmp (argv[i], "no", 2) == 0)
1458 rp.AdvAutonomousFlag = 0;
1459 if (strncmp (argv[i], "ro", 2) == 0)
1460 rp.AdvRouterAddressFlag = 1;
1461 }
1462 }
1463 }
1464
1465 rtadv_prefix_set (zebra_if, &rp);
1466
1467 return CMD_SUCCESS;
1468 }
1469
1470 ALIAS (ipv6_nd_prefix,
1471 ipv6_nd_prefix_val_nortaddr_cmd,
1472 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1473 "(<0-4294967295>|infinite) (off-link|) (no-autoconfig|)",
1474 "Interface IPv6 config commands\n"
1475 "Neighbor discovery\n"
1476 "Prefix information\n"
1477 "IPv6 prefix\n"
1478 "Valid lifetime in seconds\n"
1479 "Infinite valid lifetime\n"
1480 "Preferred lifetime in seconds\n"
1481 "Infinite preferred lifetime\n"
1482 "Do not use prefix for onlink determination\n"
1483 "Do not use prefix for autoconfiguration\n")
1484
1485 ALIAS (ipv6_nd_prefix,
1486 ipv6_nd_prefix_val_rev_cmd,
1487 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1488 "(<0-4294967295>|infinite) (no-autoconfig|) (off-link|)",
1489 "Interface IPv6 config commands\n"
1490 "Neighbor discovery\n"
1491 "Prefix information\n"
1492 "IPv6 prefix\n"
1493 "Valid lifetime in seconds\n"
1494 "Infinite valid lifetime\n"
1495 "Preferred lifetime in seconds\n"
1496 "Infinite preferred lifetime\n"
1497 "Do not use prefix for autoconfiguration\n"
1498 "Do not use prefix for onlink determination\n")
1499
1500 ALIAS (ipv6_nd_prefix,
1501 ipv6_nd_prefix_val_rev_rtaddr_cmd,
1502 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1503 "(<0-4294967295>|infinite) (no-autoconfig|) (off-link|) (router-address|)",
1504 "Interface IPv6 config commands\n"
1505 "Neighbor discovery\n"
1506 "Prefix information\n"
1507 "IPv6 prefix\n"
1508 "Valid lifetime in seconds\n"
1509 "Infinite valid lifetime\n"
1510 "Preferred lifetime in seconds\n"
1511 "Infinite preferred lifetime\n"
1512 "Do not use prefix for autoconfiguration\n"
1513 "Do not use prefix for onlink determination\n"
1514 "Set Router Address flag\n")
1515
1516 ALIAS (ipv6_nd_prefix,
1517 ipv6_nd_prefix_val_noauto_cmd,
1518 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1519 "(<0-4294967295>|infinite) (no-autoconfig|)",
1520 "Interface IPv6 config commands\n"
1521 "Neighbor discovery\n"
1522 "Prefix information\n"
1523 "IPv6 prefix\n"
1524 "Valid lifetime in seconds\n"
1525 "Infinite valid lifetime\n"
1526 "Preferred lifetime in seconds\n"
1527 "Infinite preferred lifetime\n"
1528 "Do not use prefix for autoconfiguration")
1529
1530 ALIAS (ipv6_nd_prefix,
1531 ipv6_nd_prefix_val_offlink_cmd,
1532 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1533 "(<0-4294967295>|infinite) (off-link|)",
1534 "Interface IPv6 config commands\n"
1535 "Neighbor discovery\n"
1536 "Prefix information\n"
1537 "IPv6 prefix\n"
1538 "Valid lifetime in seconds\n"
1539 "Infinite valid lifetime\n"
1540 "Preferred lifetime in seconds\n"
1541 "Infinite preferred lifetime\n"
1542 "Do not use prefix for onlink determination\n")
1543
1544 ALIAS (ipv6_nd_prefix,
1545 ipv6_nd_prefix_val_rtaddr_cmd,
1546 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1547 "(<0-4294967295>|infinite) (router-address|)",
1548 "Interface IPv6 config commands\n"
1549 "Neighbor discovery\n"
1550 "Prefix information\n"
1551 "IPv6 prefix\n"
1552 "Valid lifetime in seconds\n"
1553 "Infinite valid lifetime\n"
1554 "Preferred lifetime in seconds\n"
1555 "Infinite preferred lifetime\n"
1556 "Set Router Address flag\n")
1557
1558 ALIAS (ipv6_nd_prefix,
1559 ipv6_nd_prefix_val_cmd,
1560 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1561 "(<0-4294967295>|infinite)",
1562 "Interface IPv6 config commands\n"
1563 "Neighbor discovery\n"
1564 "Prefix information\n"
1565 "IPv6 prefix\n"
1566 "Valid lifetime in seconds\n"
1567 "Infinite valid lifetime\n"
1568 "Preferred lifetime in seconds\n"
1569 "Infinite preferred lifetime\n")
1570
1571 ALIAS (ipv6_nd_prefix,
1572 ipv6_nd_prefix_noval_cmd,
1573 "ipv6 nd prefix X:X::X:X/M (no-autoconfig|) (off-link|)",
1574 "Interface IPv6 config commands\n"
1575 "Neighbor discovery\n"
1576 "Prefix information\n"
1577 "IPv6 prefix\n"
1578 "Do not use prefix for autoconfiguration\n"
1579 "Do not use prefix for onlink determination\n")
1580
1581 ALIAS (ipv6_nd_prefix,
1582 ipv6_nd_prefix_noval_rev_cmd,
1583 "ipv6 nd prefix X:X::X:X/M (off-link|) (no-autoconfig|)",
1584 "Interface IPv6 config commands\n"
1585 "Neighbor discovery\n"
1586 "Prefix information\n"
1587 "IPv6 prefix\n"
1588 "Do not use prefix for onlink determination\n"
1589 "Do not use prefix for autoconfiguration\n")
1590
1591 ALIAS (ipv6_nd_prefix,
1592 ipv6_nd_prefix_noval_noauto_cmd,
1593 "ipv6 nd prefix X:X::X:X/M (no-autoconfig|)",
1594 "Interface IPv6 config commands\n"
1595 "Neighbor discovery\n"
1596 "Prefix information\n"
1597 "IPv6 prefix\n"
1598 "Do not use prefix for autoconfiguration\n")
1599
1600 ALIAS (ipv6_nd_prefix,
1601 ipv6_nd_prefix_noval_offlink_cmd,
1602 "ipv6 nd prefix X:X::X:X/M (off-link|)",
1603 "Interface IPv6 config commands\n"
1604 "Neighbor discovery\n"
1605 "Prefix information\n"
1606 "IPv6 prefix\n"
1607 "Do not use prefix for onlink determination\n")
1608
1609 ALIAS (ipv6_nd_prefix,
1610 ipv6_nd_prefix_noval_rtaddr_cmd,
1611 "ipv6 nd prefix X:X::X:X/M (router-address|)",
1612 "Interface IPv6 config commands\n"
1613 "Neighbor discovery\n"
1614 "Prefix information\n"
1615 "IPv6 prefix\n"
1616 "Set Router Address flag\n")
1617
1618 ALIAS (ipv6_nd_prefix,
1619 ipv6_nd_prefix_prefix_cmd,
1620 "ipv6 nd prefix X:X::X:X/M",
1621 "Interface IPv6 config commands\n"
1622 "Neighbor discovery\n"
1623 "Prefix information\n"
1624 "IPv6 prefix\n")
1625
1626 DEFUN (no_ipv6_nd_prefix,
1627 no_ipv6_nd_prefix_cmd,
1628 "no ipv6 nd prefix IPV6PREFIX",
1629 NO_STR
1630 "Interface IPv6 config commands\n"
1631 "Neighbor discovery\n"
1632 "Prefix information\n"
1633 "IPv6 prefix\n")
1634 {
1635 int ret;
1636 struct interface *ifp;
1637 struct zebra_if *zebra_if;
1638 struct rtadv_prefix rp;
1639
1640 ifp = (struct interface *) vty->index;
1641 zebra_if = ifp->info;
1642
1643 ret = str2prefix_ipv6 (argv[0], &rp.prefix);
1644 if (!ret)
1645 {
1646 vty_out (vty, "Malformed IPv6 prefix%s", VTY_NEWLINE);
1647 return CMD_WARNING;
1648 }
1649 apply_mask_ipv6 (&rp.prefix); /* RFC4861 4.6.2 */
1650
1651 ret = rtadv_prefix_reset (zebra_if, &rp);
1652 if (!ret)
1653 {
1654 vty_out (vty, "Non-exist IPv6 prefix%s", VTY_NEWLINE);
1655 return CMD_WARNING;
1656 }
1657
1658 return CMD_SUCCESS;
1659 }
1660
1661 ALIAS (no_ipv6_nd_prefix,
1662 no_ipv6_nd_prefix_val_nortaddr_cmd,
1663 "no ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) (<0-4294967295>|infinite) (off-link|) (no-autoconfig|) (router-address|)",
1664 NO_STR
1665 "Interface IPv6 config commands\n"
1666 "Neighbor discovery\n"
1667 "Prefix information\n"
1668 "IPv6 prefix\n"
1669 "Valid lifetime in seconds\n"
1670 "Infinite valid lifetime\n"
1671 "Preferred lifetime in seconds\n"
1672 "Infinite preferred lifetime\n"
1673 "Do not use prefix for onlink determination\n"
1674 "Do not use prefix for autoconfiguration\n"
1675 "Set Router Address flag\n")
1676
1677 ALIAS (no_ipv6_nd_prefix,
1678 no_ipv6_nd_prefix_val_rev_cmd,
1679 "no ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) (<0-4294967295>|infinite) (no-autoconfig|) (off-link|)",
1680 NO_STR
1681 "Interface IPv6 config commands\n"
1682 "Neighbor discovery\n"
1683 "Prefix information\n"
1684 "IPv6 prefix\n"
1685 "Valid lifetime in seconds\n"
1686 "Infinite valid lifetime\n"
1687 "Preferred lifetime in seconds\n"
1688 "Infinite preferred lifetime\n"
1689 "Do not use prefix for autoconfiguration\n"
1690 "Do not use prefix for onlink determination\n")
1691
1692 ALIAS (no_ipv6_nd_prefix,
1693 no_ipv6_nd_prefix_val_rev_rtaddr_cmd,
1694 "no ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) (<0-4294967295>|infinite) (no-autoconfig|) (off-link|) (router-address|)",
1695 NO_STR
1696 "Interface IPv6 config commands\n"
1697 "Neighbor discovery\n"
1698 "Prefix information\n"
1699 "IPv6 prefix\n"
1700 "Valid lifetime in seconds\n"
1701 "Infinite valid lifetime\n"
1702 "Preferred lifetime in seconds\n"
1703 "Infinite preferred lifetime\n"
1704 "Do not use prefix for autoconfiguration\n"
1705 "Do not use prefix for onlink determination\n"
1706 "Set Router Address flag\n")
1707
1708 ALIAS (no_ipv6_nd_prefix,
1709 no_ipv6_nd_prefix_val_noauto_cmd,
1710 "no ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) (<0-4294967295>|infinite) (no-autoconfig|)",
1711 NO_STR
1712 "Interface IPv6 config commands\n"
1713 "Neighbor discovery\n"
1714 "Prefix information\n"
1715 "IPv6 prefix\n"
1716 "Valid lifetime in seconds\n"
1717 "Infinite valid lifetime\n"
1718 "Preferred lifetime in seconds\n"
1719 "Infinite preferred lifetime\n"
1720 "Do not use prefix for autoconfiguration")
1721
1722 ALIAS (no_ipv6_nd_prefix,
1723 no_ipv6_nd_prefix_val_offlink_cmd,
1724 "no ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) (<0-4294967295>|infinite) (off-link|)",
1725 NO_STR
1726 "Interface IPv6 config commands\n"
1727 "Neighbor discovery\n"
1728 "Prefix information\n"
1729 "IPv6 prefix\n"
1730 "Valid lifetime in seconds\n"
1731 "Infinite valid lifetime\n"
1732 "Preferred lifetime in seconds\n"
1733 "Infinite preferred lifetime\n"
1734 "Do not use prefix for onlink determination\n")
1735
1736 ALIAS (no_ipv6_nd_prefix,
1737 no_ipv6_nd_prefix_val_rtaddr_cmd,
1738 "no ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) (<0-4294967295>|infinite) (router-address|)",
1739 NO_STR
1740 "Interface IPv6 config commands\n"
1741 "Neighbor discovery\n"
1742 "Prefix information\n"
1743 "IPv6 prefix\n"
1744 "Valid lifetime in seconds\n"
1745 "Infinite valid lifetime\n"
1746 "Preferred lifetime in seconds\n"
1747 "Infinite preferred lifetime\n"
1748 "Set Router Address flag\n")
1749
1750 ALIAS (no_ipv6_nd_prefix,
1751 no_ipv6_nd_prefix_val_cmd,
1752 "no ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) (<0-4294967295>|infinite)",
1753 NO_STR
1754 "Interface IPv6 config commands\n"
1755 "Neighbor discovery\n"
1756 "Prefix information\n"
1757 "IPv6 prefix\n"
1758 "Valid lifetime in seconds\n"
1759 "Infinite valid lifetime\n"
1760 "Preferred lifetime in seconds\n"
1761 "Infinite preferred lifetime\n")
1762
1763 ALIAS (no_ipv6_nd_prefix,
1764 no_ipv6_nd_prefix_noval_cmd,
1765 "no ipv6 nd prefix X:X::X:X/M (no-autoconfig|) (off-link|)",
1766 NO_STR
1767 "Interface IPv6 config commands\n"
1768 "Neighbor discovery\n"
1769 "Prefix information\n"
1770 "IPv6 prefix\n"
1771 "Do not use prefix for autoconfiguration\n"
1772 "Do not use prefix for onlink determination\n")
1773
1774 ALIAS (no_ipv6_nd_prefix,
1775 no_ipv6_nd_prefix_noval_rev_cmd,
1776 "no ipv6 nd prefix X:X::X:X/M (off-link|) (no-autoconfig|)",
1777 NO_STR
1778 "Interface IPv6 config commands\n"
1779 "Neighbor discovery\n"
1780 "Prefix information\n"
1781 "IPv6 prefix\n"
1782 "Do not use prefix for onlink determination\n"
1783 "Do not use prefix for autoconfiguration\n")
1784
1785 ALIAS (no_ipv6_nd_prefix,
1786 no_ipv6_nd_prefix_noval_noauto_cmd,
1787 "no ipv6 nd prefix X:X::X:X/M (no-autoconfig|)",
1788 NO_STR
1789 "Interface IPv6 config commands\n"
1790 "Neighbor discovery\n"
1791 "Prefix information\n"
1792 "IPv6 prefix\n"
1793 "Do not use prefix for autoconfiguration\n")
1794
1795 ALIAS (no_ipv6_nd_prefix,
1796 no_ipv6_nd_prefix_noval_offlink_cmd,
1797 "no ipv6 nd prefix X:X::X:X/M (off-link|)",
1798 NO_STR
1799 "Interface IPv6 config commands\n"
1800 "Neighbor discovery\n"
1801 "Prefix information\n"
1802 "IPv6 prefix\n"
1803 "Do not use prefix for onlink determination\n")
1804
1805 ALIAS (no_ipv6_nd_prefix,
1806 no_ipv6_nd_prefix_noval_rtaddr_cmd,
1807 "no ipv6 nd prefix X:X::X:X/M (router-address|)",
1808 NO_STR
1809 "Interface IPv6 config commands\n"
1810 "Neighbor discovery\n"
1811 "Prefix information\n"
1812 "IPv6 prefix\n"
1813 "Set Router Address flag\n")
1814
1815 DEFUN (ipv6_nd_router_preference,
1816 ipv6_nd_router_preference_cmd,
1817 "ipv6 nd router-preference (high|medium|low)",
1818 "Interface IPv6 config commands\n"
1819 "Neighbor discovery\n"
1820 "Default router preference\n"
1821 "High default router preference\n"
1822 "Low default router preference\n"
1823 "Medium default router preference (default)\n")
1824 {
1825 struct interface *ifp;
1826 struct zebra_if *zif;
1827 int i = 0;
1828
1829 ifp = (struct interface *) vty->index;
1830 zif = ifp->info;
1831
1832 while (0 != rtadv_pref_strs[i])
1833 {
1834 if (strncmp (argv[0], rtadv_pref_strs[i], 1) == 0)
1835 {
1836 zif->rtadv.DefaultPreference = i;
1837 return CMD_SUCCESS;
1838 }
1839 i++;
1840 }
1841
1842 return CMD_ERR_NO_MATCH;
1843 }
1844
1845 DEFUN (no_ipv6_nd_router_preference,
1846 no_ipv6_nd_router_preference_cmd,
1847 "no ipv6 nd router-preference",
1848 NO_STR
1849 "Interface IPv6 config commands\n"
1850 "Neighbor discovery\n"
1851 "Default router preference\n")
1852 {
1853 struct interface *ifp;
1854 struct zebra_if *zif;
1855
1856 ifp = (struct interface *) vty->index;
1857 zif = ifp->info;
1858
1859 zif->rtadv.DefaultPreference = RTADV_PREF_MEDIUM; /* Default per RFC4191. */
1860
1861 return CMD_SUCCESS;
1862 }
1863
1864 ALIAS (no_ipv6_nd_router_preference,
1865 no_ipv6_nd_router_preference_val_cmd,
1866 "no ipv6 nd router-preference (high|medium|low)",
1867 NO_STR
1868 "Interface IPv6 config commands\n"
1869 "Neighbor discovery\n"
1870 "Default router preference\n"
1871 "High default router preference\n"
1872 "Low default router preference\n"
1873 "Medium default router preference (default)\n")
1874
1875 DEFUN (ipv6_nd_mtu,
1876 ipv6_nd_mtu_cmd,
1877 "ipv6 nd mtu <1-65535>",
1878 "Interface IPv6 config commands\n"
1879 "Neighbor discovery\n"
1880 "Advertised MTU\n"
1881 "MTU in bytes\n")
1882 {
1883 struct interface *ifp = (struct interface *) vty->index;
1884 struct zebra_if *zif = ifp->info;
1885 VTY_GET_INTEGER_RANGE ("MTU", zif->rtadv.AdvLinkMTU, argv[0], 1, 65535);
1886 return CMD_SUCCESS;
1887 }
1888
1889 DEFUN (no_ipv6_nd_mtu,
1890 no_ipv6_nd_mtu_cmd,
1891 "no ipv6 nd mtu",
1892 NO_STR
1893 "Interface IPv6 config commands\n"
1894 "Neighbor discovery\n"
1895 "Advertised MTU\n")
1896 {
1897 struct interface *ifp = (struct interface *) vty->index;
1898 struct zebra_if *zif = ifp->info;
1899 zif->rtadv.AdvLinkMTU = 0;
1900 return CMD_SUCCESS;
1901 }
1902
1903 ALIAS (no_ipv6_nd_mtu,
1904 no_ipv6_nd_mtu_val_cmd,
1905 "no ipv6 nd mtu <1-65535>",
1906 NO_STR
1907 "Interface IPv6 config commands\n"
1908 "Neighbor discovery\n"
1909 "Advertised MTU\n"
1910 "MTU in bytes\n")
1911
1912 /* Write configuration about router advertisement. */
1913 void
1914 rtadv_config_write (struct vty *vty, struct interface *ifp)
1915 {
1916 struct zebra_if *zif;
1917 struct listnode *node;
1918 struct rtadv_prefix *rprefix;
1919 char buf[PREFIX_STRLEN];
1920 int interval;
1921
1922 zif = ifp->info;
1923
1924 if (!(if_is_loopback (ifp) ||
1925 CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK)))
1926 {
1927 if (zif->rtadv.AdvSendAdvertisements)
1928 vty_out (vty, " no ipv6 nd suppress-ra%s", VTY_NEWLINE);
1929 }
1930
1931 interval = zif->rtadv.MaxRtrAdvInterval;
1932 if (interval % 1000)
1933 vty_out (vty, " ipv6 nd ra-interval msec %d%s", interval,
1934 VTY_NEWLINE);
1935 else
1936 if (interval != RTADV_MAX_RTR_ADV_INTERVAL)
1937 vty_out (vty, " ipv6 nd ra-interval %d%s", interval / 1000,
1938 VTY_NEWLINE);
1939
1940 if (zif->rtadv.AdvIntervalOption)
1941 vty_out (vty, " ipv6 nd adv-interval-option%s", VTY_NEWLINE);
1942
1943 if (zif->rtadv.AdvDefaultLifetime != -1)
1944 vty_out (vty, " ipv6 nd ra-lifetime %d%s", zif->rtadv.AdvDefaultLifetime,
1945 VTY_NEWLINE);
1946
1947 if (zif->rtadv.HomeAgentPreference)
1948 vty_out (vty, " ipv6 nd home-agent-preference %u%s",
1949 zif->rtadv.HomeAgentPreference, VTY_NEWLINE);
1950
1951 if (zif->rtadv.HomeAgentLifetime != -1)
1952 vty_out (vty, " ipv6 nd home-agent-lifetime %u%s",
1953 zif->rtadv.HomeAgentLifetime, VTY_NEWLINE);
1954
1955 if (zif->rtadv.AdvHomeAgentFlag)
1956 vty_out (vty, " ipv6 nd home-agent-config-flag%s", VTY_NEWLINE);
1957
1958 if (zif->rtadv.AdvReachableTime)
1959 vty_out (vty, " ipv6 nd reachable-time %d%s", zif->rtadv.AdvReachableTime,
1960 VTY_NEWLINE);
1961
1962 if (zif->rtadv.AdvManagedFlag)
1963 vty_out (vty, " ipv6 nd managed-config-flag%s", VTY_NEWLINE);
1964
1965 if (zif->rtadv.AdvOtherConfigFlag)
1966 vty_out (vty, " ipv6 nd other-config-flag%s", VTY_NEWLINE);
1967
1968 if (zif->rtadv.DefaultPreference != RTADV_PREF_MEDIUM)
1969 vty_out (vty, " ipv6 nd router-preference %s%s",
1970 rtadv_pref_strs[zif->rtadv.DefaultPreference],
1971 VTY_NEWLINE);
1972
1973 if (zif->rtadv.AdvLinkMTU)
1974 vty_out (vty, " ipv6 nd mtu %d%s", zif->rtadv.AdvLinkMTU, VTY_NEWLINE);
1975
1976 for (ALL_LIST_ELEMENTS_RO (zif->rtadv.AdvPrefixList, node, rprefix))
1977 {
1978 vty_out (vty, " ipv6 nd prefix %s",
1979 prefix2str (&rprefix->prefix, buf, sizeof(buf)));
1980 if ((rprefix->AdvValidLifetime != RTADV_VALID_LIFETIME) ||
1981 (rprefix->AdvPreferredLifetime != RTADV_PREFERRED_LIFETIME))
1982 {
1983 if (rprefix->AdvValidLifetime == UINT32_MAX)
1984 vty_out (vty, " infinite");
1985 else
1986 vty_out (vty, " %u", rprefix->AdvValidLifetime);
1987 if (rprefix->AdvPreferredLifetime == UINT32_MAX)
1988 vty_out (vty, " infinite");
1989 else
1990 vty_out (vty, " %u", rprefix->AdvPreferredLifetime);
1991 }
1992 if (!rprefix->AdvOnLinkFlag)
1993 vty_out (vty, " off-link");
1994 if (!rprefix->AdvAutonomousFlag)
1995 vty_out (vty, " no-autoconfig");
1996 if (rprefix->AdvRouterAddressFlag)
1997 vty_out (vty, " router-address");
1998 vty_out (vty, "%s", VTY_NEWLINE);
1999 }
2000 }
2001
2002
2003 static void
2004 rtadv_event (struct zebra_ns *zns, enum rtadv_event event, int val)
2005 {
2006 struct rtadv *rtadv = &zns->rtadv;
2007
2008 switch (event)
2009 {
2010 case RTADV_START:
2011 if (! rtadv->ra_read)
2012 rtadv->ra_read = thread_add_read (zebrad.master, rtadv_read, zns, val);
2013 if (! rtadv->ra_timer)
2014 rtadv->ra_timer = thread_add_event (zebrad.master, rtadv_timer,
2015 zns, 0);
2016 break;
2017 case RTADV_STOP:
2018 if (rtadv->ra_timer)
2019 {
2020 thread_cancel (rtadv->ra_timer);
2021 rtadv->ra_timer = NULL;
2022 }
2023 if (rtadv->ra_read)
2024 {
2025 thread_cancel (rtadv->ra_read);
2026 rtadv->ra_read = NULL;
2027 }
2028 break;
2029 case RTADV_TIMER:
2030 if (! rtadv->ra_timer)
2031 rtadv->ra_timer = thread_add_timer (zebrad.master, rtadv_timer, zns,
2032 val);
2033 break;
2034 case RTADV_TIMER_MSEC:
2035 if (! rtadv->ra_timer)
2036 rtadv->ra_timer = thread_add_timer_msec (zebrad.master, rtadv_timer,
2037 zns, val);
2038 break;
2039 case RTADV_READ:
2040 if (! rtadv->ra_read)
2041 rtadv->ra_read = thread_add_read (zebrad.master, rtadv_read, zns, val);
2042 break;
2043 default:
2044 break;
2045 }
2046 return;
2047 }
2048
2049 void
2050 rtadv_init (struct zebra_ns *zns)
2051 {
2052 zns->rtadv.sock = rtadv_make_socket ();
2053 }
2054
2055 void
2056 rtadv_terminate (struct zebra_ns *zns)
2057 {
2058 rtadv_event (zns, RTADV_STOP, 0);
2059 if (zns->rtadv.sock >= 0)
2060 {
2061 close (zns->rtadv.sock);
2062 zns->rtadv.sock = -1;
2063 }
2064
2065 zns->rtadv.adv_if_count = 0;
2066 zns->rtadv.adv_msec_if_count = 0;
2067 }
2068
2069 void
2070 rtadv_cmd_init (void)
2071 {
2072 install_element (INTERFACE_NODE, &ipv6_nd_suppress_ra_cmd);
2073 install_element (INTERFACE_NODE, &no_ipv6_nd_suppress_ra_cmd);
2074 install_element (INTERFACE_NODE, &ipv6_nd_ra_interval_cmd);
2075 install_element (INTERFACE_NODE, &ipv6_nd_ra_interval_msec_cmd);
2076 install_element (INTERFACE_NODE, &no_ipv6_nd_ra_interval_cmd);
2077 install_element (INTERFACE_NODE, &no_ipv6_nd_ra_interval_val_cmd);
2078 install_element (INTERFACE_NODE, &no_ipv6_nd_ra_interval_msec_val_cmd);
2079 install_element (INTERFACE_NODE, &ipv6_nd_ra_lifetime_cmd);
2080 install_element (INTERFACE_NODE, &no_ipv6_nd_ra_lifetime_cmd);
2081 install_element (INTERFACE_NODE, &no_ipv6_nd_ra_lifetime_val_cmd);
2082 install_element (INTERFACE_NODE, &ipv6_nd_reachable_time_cmd);
2083 install_element (INTERFACE_NODE, &no_ipv6_nd_reachable_time_cmd);
2084 install_element (INTERFACE_NODE, &no_ipv6_nd_reachable_time_val_cmd);
2085 install_element (INTERFACE_NODE, &ipv6_nd_managed_config_flag_cmd);
2086 install_element (INTERFACE_NODE, &no_ipv6_nd_managed_config_flag_cmd);
2087 install_element (INTERFACE_NODE, &ipv6_nd_other_config_flag_cmd);
2088 install_element (INTERFACE_NODE, &no_ipv6_nd_other_config_flag_cmd);
2089 install_element (INTERFACE_NODE, &ipv6_nd_homeagent_config_flag_cmd);
2090 install_element (INTERFACE_NODE, &no_ipv6_nd_homeagent_config_flag_cmd);
2091 install_element (INTERFACE_NODE, &ipv6_nd_homeagent_preference_cmd);
2092 install_element (INTERFACE_NODE, &no_ipv6_nd_homeagent_preference_cmd);
2093 install_element (INTERFACE_NODE, &no_ipv6_nd_homeagent_preference_val_cmd);
2094 install_element (INTERFACE_NODE, &ipv6_nd_homeagent_lifetime_cmd);
2095 install_element (INTERFACE_NODE, &no_ipv6_nd_homeagent_lifetime_cmd);
2096 install_element (INTERFACE_NODE, &no_ipv6_nd_homeagent_lifetime_val_cmd);
2097 install_element (INTERFACE_NODE, &ipv6_nd_adv_interval_config_option_cmd);
2098 install_element (INTERFACE_NODE, &no_ipv6_nd_adv_interval_config_option_cmd);
2099 install_element (INTERFACE_NODE, &ipv6_nd_prefix_cmd);
2100 install_element (INTERFACE_NODE, &ipv6_nd_prefix_val_rev_rtaddr_cmd);
2101 install_element (INTERFACE_NODE, &ipv6_nd_prefix_val_nortaddr_cmd);
2102 install_element (INTERFACE_NODE, &ipv6_nd_prefix_val_rev_cmd);
2103 install_element (INTERFACE_NODE, &ipv6_nd_prefix_val_noauto_cmd);
2104 install_element (INTERFACE_NODE, &ipv6_nd_prefix_val_offlink_cmd);
2105 install_element (INTERFACE_NODE, &ipv6_nd_prefix_val_rtaddr_cmd);
2106 install_element (INTERFACE_NODE, &ipv6_nd_prefix_val_cmd);
2107 install_element (INTERFACE_NODE, &ipv6_nd_prefix_noval_cmd);
2108 install_element (INTERFACE_NODE, &ipv6_nd_prefix_noval_rev_cmd);
2109 install_element (INTERFACE_NODE, &ipv6_nd_prefix_noval_noauto_cmd);
2110 install_element (INTERFACE_NODE, &ipv6_nd_prefix_noval_offlink_cmd);
2111 install_element (INTERFACE_NODE, &ipv6_nd_prefix_noval_rtaddr_cmd);
2112 install_element (INTERFACE_NODE, &ipv6_nd_prefix_prefix_cmd);
2113 install_element (INTERFACE_NODE, &no_ipv6_nd_prefix_cmd);
2114 install_element (INTERFACE_NODE, &no_ipv6_nd_prefix_val_rev_rtaddr_cmd);
2115 install_element (INTERFACE_NODE, &no_ipv6_nd_prefix_val_nortaddr_cmd);
2116 install_element (INTERFACE_NODE, &no_ipv6_nd_prefix_val_rev_cmd);
2117 install_element (INTERFACE_NODE, &no_ipv6_nd_prefix_val_noauto_cmd);
2118 install_element (INTERFACE_NODE, &no_ipv6_nd_prefix_val_offlink_cmd);
2119 install_element (INTERFACE_NODE, &no_ipv6_nd_prefix_val_rtaddr_cmd);
2120 install_element (INTERFACE_NODE, &no_ipv6_nd_prefix_val_cmd);
2121 install_element (INTERFACE_NODE, &no_ipv6_nd_prefix_noval_cmd);
2122 install_element (INTERFACE_NODE, &no_ipv6_nd_prefix_noval_rev_cmd);
2123 install_element (INTERFACE_NODE, &no_ipv6_nd_prefix_noval_noauto_cmd);
2124 install_element (INTERFACE_NODE, &no_ipv6_nd_prefix_noval_offlink_cmd);
2125 install_element (INTERFACE_NODE, &no_ipv6_nd_prefix_noval_rtaddr_cmd);
2126 install_element (INTERFACE_NODE, &ipv6_nd_router_preference_cmd);
2127 install_element (INTERFACE_NODE, &no_ipv6_nd_router_preference_cmd);
2128 install_element (INTERFACE_NODE, &no_ipv6_nd_router_preference_val_cmd);
2129 install_element (INTERFACE_NODE, &ipv6_nd_mtu_cmd);
2130 install_element (INTERFACE_NODE, &no_ipv6_nd_mtu_cmd);
2131 install_element (INTERFACE_NODE, &no_ipv6_nd_mtu_val_cmd);
2132 }
2133
2134 static int
2135 if_join_all_router (int sock, struct interface *ifp)
2136 {
2137 int ret;
2138
2139 struct ipv6_mreq mreq;
2140
2141 memset (&mreq, 0, sizeof (struct ipv6_mreq));
2142 inet_pton (AF_INET6, ALLROUTER, &mreq.ipv6mr_multiaddr);
2143 mreq.ipv6mr_interface = ifp->ifindex;
2144
2145 ret = setsockopt (sock, IPPROTO_IPV6, IPV6_JOIN_GROUP,
2146 (char *) &mreq, sizeof mreq);
2147 if (ret < 0)
2148 zlog_warn ("%s(%u): Failed to join group, socket %u error %s",
2149 ifp->name, ifp->ifindex, sock, safe_strerror (errno));
2150
2151 if (IS_ZEBRA_DEBUG_EVENT)
2152 zlog_debug ("%s(%u): Join All-Routers multicast group, socket %u",
2153 ifp->name, ifp->ifindex, sock);
2154
2155 return 0;
2156 }
2157
2158 static int
2159 if_leave_all_router (int sock, struct interface *ifp)
2160 {
2161 int ret;
2162
2163 struct ipv6_mreq mreq;
2164
2165 memset (&mreq, 0, sizeof (struct ipv6_mreq));
2166 inet_pton (AF_INET6, ALLROUTER, &mreq.ipv6mr_multiaddr);
2167 mreq.ipv6mr_interface = ifp->ifindex;
2168
2169 ret = setsockopt (sock, IPPROTO_IPV6, IPV6_LEAVE_GROUP,
2170 (char *) &mreq, sizeof mreq);
2171 if (ret < 0)
2172 zlog_warn ("%s(%u): Failed to leave group, socket %u error %s",
2173 ifp->name, ifp->ifindex, sock,safe_strerror (errno));
2174
2175 if (IS_ZEBRA_DEBUG_EVENT)
2176 zlog_debug ("%s(%u): Leave All-Routers multicast group, socket %u",
2177 ifp->name, ifp->ifindex, sock);
2178
2179 return 0;
2180 }
2181
2182 #else
2183 void
2184 rtadv_init (struct zebra_ns *zns)
2185 {
2186 /* Empty.*/;
2187 }
2188 void
2189 rtadv_terminate (struct zebra_ns *zns)
2190 {
2191 /* Empty.*/;
2192 }
2193 void
2194 rtadv_cmd_init (void)
2195 {
2196 /* Empty.*/;
2197 }
2198 #endif /* HAVE_RTADV && HAVE_IPV6 */