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