]> git.proxmox.com Git - mirror_frr.git/blame - zebra/rtadv.c
*: use an ifindex_t type, defined in lib/if.h, for ifindex values
[mirror_frr.git] / zebra / rtadv.c
CommitLineData
718e3744 1/* Router advertisement
7cee1bb1 2 * Copyright (C) 2005 6WIND <jean-mickael.guerin@6wind.com>
718e3744 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"
4a04e5f7 29#include "stream.h"
718e3744 30#include "log.h"
31#include "prefix.h"
32#include "linklist.h"
33#include "command.h"
edd7c245 34#include "privs.h"
cd80d74f 35#include "vrf.h"
718e3744 36
37#include "zebra/interface.h"
38#include "zebra/rtadv.h"
39#include "zebra/debug.h"
537d8ea9 40#include "zebra/rib.h"
4b5e1359 41#include "zebra/zserv.h"
fe18ee2d 42#include "zebra/zebra_ns.h"
7c551956 43#include "zebra/zebra_vrf.h"
718e3744 44
edd7c245 45extern struct zebra_privs_t zserv_privs;
46
8da4e946 47#if defined (HAVE_IPV6) && defined (HAVE_RTADV)
718e3744 48
fa2b17e3 49#ifdef OPEN_BSD
50#include <netinet/icmp6.h>
51#endif
52
718e3744 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
7cee1bb1 64enum rtadv_event {RTADV_START, RTADV_STOP, RTADV_TIMER,
65 RTADV_TIMER_MSEC, RTADV_READ};
718e3744 66
43459b1f 67static void rtadv_event (struct zebra_ns *, enum rtadv_event, int);
718e3744 68
a1ac18c4 69static int if_join_all_router (int, struct interface *);
70static int if_leave_all_router (int, struct interface *);
6b0655a2 71
911ad1e2 72static int
b892f1dd 73rtadv_increment_received(struct zebra_ns *zns, ifindex_t *ifindex)
911ad1e2 74{
795b5abf
QY
75 int ret = -1;
76 struct interface *iface;
77 struct zebra_if *zif;
78
911ad1e2 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 }
795b5abf
QY
86 return ret;
87}
88
a1ac18c4 89static int
911ad1e2 90rtadv_recv_packet (struct zebra_ns *zns, int sock, u_char *buf, int buflen,
b892f1dd 91 struct sockaddr_in6 *from, ifindex_t *ifindex,
718e3744 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
b99760ab 117 for (cmsgptr = ZCMSG_FIRSTHDR(&msg); cmsgptr != NULL;
718e3744 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)
b0b709ab
SH
134 {
135 int *hoptr = (int *) CMSG_DATA (cmsgptr);
136 *hoplimit = *hoptr;
137 }
718e3744 138 }
795b5abf 139
911ad1e2 140 rtadv_increment_received(zns, ifindex);
718e3744 141 return ret;
142}
143
144#define RTADV_MSG_SIZE 4096
145
146/* Send router advertisement packet. */
a1ac18c4 147static void
718e3744 148rtadv_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;
6f0e3f6e 155#ifdef HAVE_STRUCT_SOCKADDR_DL
718e3744 156 struct sockaddr_dl *sdl;
6f0e3f6e 157#endif /* HAVE_STRUCT_SOCKADDR_DL */
57492d56 158 static void *adata = NULL;
718e3744 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;
1eb8ef25 164 struct rtadv_prefix *rprefix;
718e3744 165 u_char all_nodes_addr[] = {0xff,0x02,0,0,0,0,0,0,0,0,0,0,0,0,0,1};
52dc7ee6 166 struct listnode *node;
d660f698 167 u_int16_t pkt_RouterLifetime;
718e3744 168
57492d56 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)
f360eac0 181 zlog_err("rtadv_send_packet: can't malloc control data");
57492d56 182 }
183
718e3744 184 /* Logging of packet. */
185 if (IS_ZEBRA_DEBUG_PACKET)
f360eac0 186 zlog_debug ("%s(%u): Tx RA, socket %u",
187 ifp->name, ifp->ifindex, sock);
718e3744 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);
aca43b65 196 IPV6_ADDR_COPY (&addr.sin6_addr, all_nodes_addr);
718e3744 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;
b60668d0
CC
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
718e3744 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;
7cee1bb1 219 if (zif->rtadv.AdvHomeAgentFlag)
220 rtadv->nd_ra_flags_reserved |= ND_RA_FLAG_HOME_AGENT;
d660f698
DO
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);
718e3744 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
d660f698
DO
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 )
7cee1bb1 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);
d660f698
DO
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 );
7cee1bb1 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
718e3744 279 /* Fill in prefix. */
1eb8ef25 280 for (ALL_LIST_ELEMENTS_RO (zif->rtadv.AdvPrefixList, node, rprefix))
718e3744 281 {
282 struct nd_opt_prefix_info *pinfo;
718e3744 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;
7cee1bb1 295 if (rprefix->AdvRouterAddressFlag)
296 pinfo->nd_opt_pi_flags_reserved |= ND_OPT_PI_FLAG_RADDR;
718e3744 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
aca43b65 302 IPV6_ADDR_COPY (&pinfo->nd_opt_pi_prefix, &rprefix->prefix.prefix);
718e3744 303
304#ifdef DEBUG
305 {
306 u_char buf[INET6_ADDRSTRLEN];
307
b6178002 308 zlog_debug ("DEBUG %s", inet_ntop (AF_INET6, &pinfo->nd_opt_pi_prefix,
3e31cded 309 buf, INET6_ADDRSTRLEN));
718e3744 310
311 }
312#endif /* DEBUG */
313
314 len += sizeof (struct nd_opt_prefix_info);
315 }
316
317 /* Hardware address. */
6f0e3f6e 318#ifdef HAVE_STRUCT_SOCKADDR_DL
718e3744 319 sdl = &ifp->sdl;
320 if (sdl != NULL && sdl->sdl_alen != 0)
321 {
322 buf[len++] = ND_OPT_SOURCE_LINKADDR;
50adf783
DW
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;
718e3744 327
328 memcpy (buf + len, LLADDR (sdl), sdl->sdl_alen);
329 len += sdl->sdl_alen;
50adf783
DW
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;
718e3744 334 }
335#else
336 if (ifp->hw_addr_len != 0)
337 {
338 buf[len++] = ND_OPT_SOURCE_LINKADDR;
50adf783
DW
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;
718e3744 343
344 memcpy (buf + len, ifp->hw_addr, ifp->hw_addr_len);
345 len += ifp->hw_addr_len;
50adf783
DW
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;
718e3744 350 }
6f0e3f6e 351#endif /* HAVE_STRUCT_SOCKADDR_DL */
718e3744 352
6ae93c05
DO
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
718e3744 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;
f841e02e 369 msg.msg_controllen = CMSG_SPACE(sizeof(struct in6_pktinfo));
57492d56 370 msg.msg_flags = 0;
718e3744 371 iov.iov_base = buf;
372 iov.iov_len = len;
373
b99760ab 374 cmsgptr = ZCMSG_FIRSTHDR(&msg);
57492d56 375 cmsgptr->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
718e3744 376 cmsgptr->cmsg_level = IPPROTO_IPV6;
377 cmsgptr->cmsg_type = IPV6_PKTINFO;
80893817 378
718e3744 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);
9ccabd1c 384 if (ret < 0)
385 {
f360eac0 386 zlog_err ("%s(%u): Tx RA failed, socket %u error %d (%s)",
387 ifp->name, ifp->ifindex, sock, errno, safe_strerror(errno));
9ccabd1c 388 }
795b5abf
QY
389 else
390 zif->ra_sent++;
718e3744 391}
392
a1ac18c4 393static int
718e3744 394rtadv_timer (struct thread *thread)
395{
43459b1f 396 struct zebra_ns *zns = THREAD_ARG (thread);
397 vrf_iter_t iter;
1eb8ef25 398 struct listnode *node, *nnode;
718e3744 399 struct interface *ifp;
400 struct zebra_if *zif;
7cee1bb1 401 int period;
718e3744 402
43459b1f 403 zns->rtadv.ra_timer = NULL;
404 if (zns->rtadv.adv_msec_if_count == 0)
7cee1bb1 405 {
406 period = 1000; /* 1 s */
43459b1f 407 rtadv_event (zns, RTADV_TIMER, 1 /* 1 s */);
7cee1bb1 408 }
409 else
410 {
411 period = 10; /* 10 ms */
43459b1f 412 rtadv_event (zns, RTADV_TIMER_MSEC, 10 /* 10 ms */);
7cee1bb1 413 }
718e3744 414
43459b1f 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 {
c23af4d3 418 if (if_is_loopback (ifp) ||
419 CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK) ||
420 ! if_is_operative (ifp))
43459b1f 421 continue;
422
423 zif = ifp->info;
424
425 if (zif->rtadv.AdvSendAdvertisements)
426 {
6c9678b4 427 if (zif->rtadv.inFastRexmit)
43459b1f 428 {
6c9678b4
DD
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
43459b1f 436 rtadv_send_packet (zns->rtadv.sock, ifp);
437 }
6c9678b4
DD
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 }
43459b1f 449 }
450 }
718e3744 451
718e3744 452 return 0;
453}
454
a1ac18c4 455static void
718e3744 456rtadv_process_solicit (struct interface *ifp)
457{
cd80d74f 458 struct zebra_vrf *zvrf = vrf_info_lookup (ifp->vrf_id);
43459b1f 459 struct zebra_ns *zns = zvrf->zns;
718e3744 460
43459b1f 461 assert (zns);
462 rtadv_send_packet (zns->rtadv.sock, ifp);
718e3744 463}
464
a1ac18c4 465static void
a80beece
DS
466rtadv_process_advert (u_char *msg, unsigned int len, struct interface *ifp,
467 struct sockaddr_in6 *addr)
718e3744 468{
a80beece
DS
469 struct nd_router_advert *radvert;
470 char addr_str[INET6_ADDRSTRLEN];
471 struct zebra_if *zif;
1d20ccf3 472 struct prefix p;
a80beece
DS
473
474 zif = ifp->info;
475
476 inet_ntop (AF_INET6, &addr->sin6_addr, addr_str, INET6_ADDRSTRLEN);
477
a80beece 478 if (len < sizeof(struct nd_router_advert)) {
f360eac0 479 zlog_warn("%s(%u): Rx RA with invalid length %d from %s",
480 ifp->name, ifp->ifindex, len, addr_str);
a80beece
DS
481 return;
482 }
483 if (!IN6_IS_ADDR_LINKLOCAL(&addr->sin6_addr)) {
f360eac0 484 zlog_warn("%s(%u): Rx RA with non-linklocal source address from %s",
485 ifp->name, ifp->ifindex, addr_str);
a80beece
DS
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 {
f360eac0 494 zlog_warn("%s(%u): Rx RA - our AdvCurHopLimit doesn't agree with %s",
495 ifp->name, ifp->ifindex, addr_str);
a80beece
DS
496 }
497
498 if ((radvert->nd_ra_flags_reserved & ND_RA_FLAG_MANAGED) &&
499 !zif->rtadv.AdvManagedFlag)
500 {
f360eac0 501 zlog_warn("%s(%u): Rx RA - our AdvManagedFlag doesn't agree with %s",
502 ifp->name, ifp->ifindex, addr_str);
a80beece
DS
503 }
504
505 if ((radvert->nd_ra_flags_reserved & ND_RA_FLAG_OTHER) &&
506 !zif->rtadv.AdvOtherConfigFlag)
507 {
f360eac0 508 zlog_warn("%s(%u): Rx RA - our AdvOtherConfigFlag doesn't agree with %s",
509 ifp->name, ifp->ifindex, addr_str);
a80beece
DS
510 }
511
512 if ((radvert->nd_ra_reachable && zif->rtadv.AdvReachableTime) &&
513 (ntohl(radvert->nd_ra_reachable) != zif->rtadv.AdvReachableTime))
514 {
f360eac0 515 zlog_warn("%s(%u): Rx RA - our AdvReachableTime doesn't agree with %s",
516 ifp->name, ifp->ifindex, addr_str);
a80beece
DS
517 }
518
519 if ((radvert->nd_ra_retransmit && zif->rtadv.AdvRetransTimer) &&
4e3afb14 520 (ntohl(radvert->nd_ra_retransmit) != (unsigned int)zif->rtadv.AdvRetransTimer))
a80beece 521 {
f360eac0 522 zlog_warn("%s(%u): Rx RA - our AdvRetransTimer doesn't agree with %s",
523 ifp->name, ifp->ifindex, addr_str);
a80beece
DS
524 }
525
1d20ccf3 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;
a80beece 530
1d20ccf3 531 if (!nbr_connected_check(ifp, &p))
532 nbr_connected_add_ipv6 (ifp, &addr->sin6_addr);
718e3744 533}
534
a80beece 535
a1ac18c4 536static void
b892f1dd 537rtadv_process_packet (u_char *buf, unsigned int len, ifindex_t ifindex, int hoplimit,
43459b1f 538 struct sockaddr_in6 *from, struct zebra_ns *zns)
718e3744 539{
540 struct icmp6_hdr *icmph;
541 struct interface *ifp;
542 struct zebra_if *zif;
f360eac0 543 char addr_str[INET6_ADDRSTRLEN];
544
545 inet_ntop (AF_INET6, &from->sin6_addr, addr_str, INET6_ADDRSTRLEN);
718e3744 546
547 /* Interface search. */
43459b1f 548 ifp = if_lookup_by_index_per_ns (zns, ifindex);
718e3744 549 if (ifp == NULL)
550 {
f360eac0 551 zlog_warn ("RA/RS received on unknown IF %u from %s",
552 ifindex, addr_str);
718e3744 553 return;
554 }
555
f360eac0 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
c23af4d3 560 if (if_is_loopback (ifp) ||
561 CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK))
718e3744 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 {
f360eac0 572 zlog_warn ("%s(%u): Rx RA with Invalid ICMPV6 packet length %d",
573 ifp->name, ifp->ifindex, len);
718e3744 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 {
f360eac0 583 zlog_warn ("%s(%u): Rx RA - Unwanted ICMPV6 message type %d",
584 ifp->name, ifp->ifindex, icmph->icmp6_type);
718e3744 585 return;
586 }
587
588 /* Hoplimit check. */
589 if (hoplimit >= 0 && hoplimit != 255)
590 {
f360eac0 591 zlog_warn ("%s(%u): Rx RA - Invalid hoplimit %d",
592 ifp->name, ifp->ifindex, hoplimit);
718e3744 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)
a80beece 600 rtadv_process_advert (buf, len, ifp, from);
718e3744 601
602 return;
603}
604
a1ac18c4 605static int
718e3744 606rtadv_read (struct thread *thread)
607{
608 int sock;
609 int len;
610 u_char buf[RTADV_MSG_SIZE];
611 struct sockaddr_in6 from;
b892f1dd 612 ifindex_t ifindex = 0;
718e3744 613 int hoplimit = -1;
43459b1f 614 struct zebra_ns *zns = THREAD_ARG (thread);
718e3744 615
616 sock = THREAD_FD (thread);
43459b1f 617 zns->rtadv.ra_read = NULL;
718e3744 618
619 /* Register myself. */
43459b1f 620 rtadv_event (zns, RTADV_READ, sock);
718e3744 621
911ad1e2 622 len = rtadv_recv_packet (zns, sock, buf, BUFSIZ, &from, &ifindex, &hoplimit);
718e3744 623
624 if (len < 0)
625 {
f360eac0 626 zlog_warn ("RA/RS recv failed, socket %u error %s",
627 sock, safe_strerror (errno));
718e3744 628 return len;
629 }
630
43459b1f 631 rtadv_process_packet (buf, (unsigned)len, ifindex, hoplimit, &from, zns);
718e3744 632
633 return 0;
634}
635
a1ac18c4 636static int
43459b1f 637rtadv_make_socket (void)
718e3744 638{
639 int sock;
43459b1f 640 int ret = 0;
718e3744 641 struct icmp6_filter filter;
642
edd7c245 643 if ( zserv_privs.change (ZPRIVS_RAISE) )
644 zlog_err ("rtadv_make_socket: could not raise privs, %s",
6099b3b5 645 safe_strerror (errno) );
edd7c245 646
43459b1f 647 sock = socket (AF_INET6, SOCK_RAW, IPPROTO_ICMPV6);
718e3744 648
edd7c245 649 if ( zserv_privs.change (ZPRIVS_LOWER) )
650 zlog_err ("rtadv_make_socket: could not lower privs, %s",
6099b3b5 651 safe_strerror (errno) );
edd7c245 652
718e3744 653 if (sock < 0)
a5c304ab
MS
654 {
655 close (sock);
656 return -1;
657 }
718e3744 658
659 ret = setsockopt_ipv6_pktinfo (sock, 1);
718e3744 660 if (ret < 0)
a5c304ab
MS
661 {
662 close (sock);
663 return ret;
664 }
718e3744 665 ret = setsockopt_ipv6_multicast_loop (sock, 0);
666 if (ret < 0)
a5c304ab
MS
667 {
668 close (sock);
669 return ret;
670 }
718e3744 671 ret = setsockopt_ipv6_unicast_hops (sock, 255);
672 if (ret < 0)
a5c304ab
MS
673 {
674 close (sock);
675 return ret;
676 }
718e3744 677 ret = setsockopt_ipv6_multicast_hops (sock, 255);
678 if (ret < 0)
a5c304ab
MS
679 {
680 close (sock);
681 return ret;
682 }
718e3744 683 ret = setsockopt_ipv6_hoplimit (sock, 1);
684 if (ret < 0)
a5c304ab
MS
685 {
686 close (sock);
687 return ret;
688 }
718e3744 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 {
6099b3b5 698 zlog_info ("ICMP6_FILTER set fail: %s", safe_strerror (errno));
718e3744 699 return ret;
700 }
701
702 return sock;
703}
6b0655a2 704
a1ac18c4 705static struct rtadv_prefix *
66e5cd87 706rtadv_prefix_new (void)
718e3744 707{
393deb9b 708 return XCALLOC (MTYPE_RTADV_PREFIX, sizeof (struct rtadv_prefix));
718e3744 709}
710
a1ac18c4 711static void
718e3744 712rtadv_prefix_free (struct rtadv_prefix *rtadv_prefix)
713{
714 XFREE (MTYPE_RTADV_PREFIX, rtadv_prefix);
715}
716
a1ac18c4 717static struct rtadv_prefix *
aca43b65 718rtadv_prefix_lookup (struct list *rplist, struct prefix_ipv6 *p)
718e3744 719{
52dc7ee6 720 struct listnode *node;
718e3744 721 struct rtadv_prefix *rprefix;
722
1eb8ef25 723 for (ALL_LIST_ELEMENTS_RO (rplist, node, rprefix))
aca43b65 724 if (prefix_same ((struct prefix *) &rprefix->prefix, (struct prefix *) p))
1eb8ef25 725 return rprefix;
718e3744 726 return NULL;
727}
728
a1ac18c4 729static struct rtadv_prefix *
aca43b65 730rtadv_prefix_get (struct list *rplist, struct prefix_ipv6 *p)
718e3744 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 ();
aca43b65 739 memcpy (&rprefix->prefix, p, sizeof (struct prefix_ipv6));
718e3744 740 listnode_add (rplist, rprefix);
741
742 return rprefix;
743}
744
a1ac18c4 745static void
718e3744 746rtadv_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;
7cee1bb1 757 rprefix->AdvRouterAddressFlag = rp->AdvRouterAddressFlag;
718e3744 758}
759
a1ac18c4 760static int
718e3744 761rtadv_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
4a04e5f7 776static void
b6120505
DW
777ipv6_nd_suppress_ra_set (struct interface *ifp, ipv6_nd_suppress_ra_status status)
778{
779 struct zebra_if *zif;
780 struct zebra_vrf *zvrf;
43459b1f 781 struct zebra_ns *zns;
b6120505
DW
782
783 zif = ifp->info;
784 zvrf = vrf_info_lookup (ifp->vrf_id);
43459b1f 785 zns = zvrf->zns;
b6120505
DW
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;
43459b1f 794 zns->rtadv.adv_if_count--;
b6120505 795
43459b1f 796 if_leave_all_router (zns->rtadv.sock, ifp);
b6120505 797
43459b1f 798 if (zns->rtadv.adv_if_count == 0)
799 rtadv_event (zns, RTADV_STOP, 0);
b6120505
DW
800 }
801 }
802 else
803 {
804 if (! zif->rtadv.AdvSendAdvertisements)
805 {
806 zif->rtadv.AdvSendAdvertisements = 1;
807 zif->rtadv.AdvIntervalTimer = 0;
43459b1f 808 zns->rtadv.adv_if_count++;
b6120505 809
6c9678b4
DD
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
43459b1f 817 if_join_all_router (zns->rtadv.sock, ifp);
b6120505 818
43459b1f 819 if (zns->rtadv.adv_if_count == 1)
820 rtadv_event (zns, RTADV_START, zns->rtadv.sock);
b6120505
DW
821 }
822 }
823}
824
4a04e5f7 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
5c81b96a 829 * if the operator has explicitly enabled RA. The enable request can also
830 * specify a RA interval (in seconds).
4a04e5f7 831 */
832void
833zebra_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;
5c81b96a 840 int ra_interval;
4a04e5f7 841
842 s = client->ibuf;
843
5c81b96a 844 /* Get interface index and RA interval. */
4a04e5f7 845 ifindex = stream_getl (s);
5c81b96a 846 ra_interval = stream_getl (s);
4a04e5f7 847
848 if (IS_ZEBRA_DEBUG_EVENT)
5c81b96a 849 zlog_debug("%u: IF %u RA %s from client %s, interval %ds",
4a04e5f7 850 zvrf->vrf_id, ifindex, enable ? "enable" : "disable",
5c81b96a 851 zebra_route_string(client->proto), ra_interval);
4a04e5f7 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)
5c81b96a 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 }
4a04e5f7 878 else
879 {
880 if (!zif->rtadv.configured)
5c81b96a 881 {
882 zif->rtadv.MaxRtrAdvInterval = RTADV_MAX_RTR_ADV_INTERVAL;
883 ipv6_nd_suppress_ra_set (ifp, RA_SUPPRESS);
884 }
4a04e5f7 885 }
886}
887
718e3744 888DEFUN (ipv6_nd_suppress_ra,
889 ipv6_nd_suppress_ra_cmd,
890 "ipv6 nd suppress-ra",
3e31cded 891 "Interface IPv6 config commands\n"
718e3744 892 "Neighbor discovery\n"
893 "Suppress Router Advertisement\n")
894{
895 struct interface *ifp;
4a04e5f7 896 struct zebra_if *zif;
718e3744 897
898 ifp = vty->index;
718e3744 899
c23af4d3 900 if (if_is_loopback (ifp) ||
901 CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK))
718e3744 902 {
c23af4d3 903 vty_out (vty, "Cannot configure IPv6 Router Advertisements on this interface%s", VTY_NEWLINE);
718e3744 904 return CMD_WARNING;
905 }
906
b6120505 907 ipv6_nd_suppress_ra_set (ifp, RA_SUPPRESS);
4a04e5f7 908 zif = ifp->info;
909 zif->rtadv.configured = 0;
718e3744 910 return CMD_SUCCESS;
911}
912
718e3744 913DEFUN (no_ipv6_nd_suppress_ra,
914 no_ipv6_nd_suppress_ra_cmd,
915 "no ipv6 nd suppress-ra",
916 NO_STR
3e31cded 917 "Interface IPv6 config commands\n"
718e3744 918 "Neighbor discovery\n"
919 "Suppress Router Advertisement\n")
920{
921 struct interface *ifp;
4a04e5f7 922 struct zebra_if *zif;
718e3744 923
924 ifp = vty->index;
718e3744 925
c23af4d3 926 if (if_is_loopback (ifp) ||
927 CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK))
718e3744 928 {
c23af4d3 929 vty_out (vty, "Cannot configure IPv6 Router Advertisements on this interface%s", VTY_NEWLINE);
718e3744 930 return CMD_WARNING;
931 }
932
b6120505 933 ipv6_nd_suppress_ra_set (ifp, RA_ENABLE);
4a04e5f7 934 zif = ifp->info;
935 zif->rtadv.configured = 1;
718e3744 936 return CMD_SUCCESS;
937}
938
7cee1bb1 939DEFUN (ipv6_nd_ra_interval_msec,
940 ipv6_nd_ra_interval_msec_cmd,
4afa50b3 941 "ipv6 nd ra-interval msec <70-1800000>",
7cee1bb1 942 "Interface IPv6 config commands\n"
943 "Neighbor discovery\n"
944 "Router Advertisement interval\n"
945 "Router Advertisement interval in milliseconds\n")
946{
4afa50b3
DO
947 unsigned interval;
948 struct interface *ifp = (struct interface *) vty->index;
949 struct zebra_if *zif = ifp->info;
cd80d74f 950 struct zebra_vrf *zvrf = vrf_info_lookup (ifp->vrf_id);
43459b1f 951 struct zebra_ns *zns;
7cee1bb1 952
43459b1f 953 zns = zvrf->zns;
4afa50b3
DO
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 }
7cee1bb1 960
961 if (zif->rtadv.MaxRtrAdvInterval % 1000)
43459b1f 962 zns->rtadv.adv_msec_if_count--;
7cee1bb1 963
964 if (interval % 1000)
43459b1f 965 zns->rtadv.adv_msec_if_count++;
7cee1bb1 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
718e3744 974DEFUN (ipv6_nd_ra_interval,
975 ipv6_nd_ra_interval_cmd,
4afa50b3 976 "ipv6 nd ra-interval <1-1800>",
3e31cded 977 "Interface IPv6 config commands\n"
718e3744 978 "Neighbor discovery\n"
979 "Router Advertisement interval\n"
980 "Router Advertisement interval in seconds\n")
981{
4afa50b3
DO
982 unsigned interval;
983 struct interface *ifp = (struct interface *) vty->index;
984 struct zebra_if *zif = ifp->info;
cd80d74f 985 struct zebra_vrf *zvrf = vrf_info_lookup (ifp->vrf_id);
43459b1f 986 struct zebra_ns *zns;
718e3744 987
43459b1f 988 zns = zvrf->zns;
4afa50b3
DO
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 }
718e3744 995
7cee1bb1 996 if (zif->rtadv.MaxRtrAdvInterval % 1000)
43459b1f 997 zns->rtadv.adv_msec_if_count--;
7cee1bb1 998
999 /* convert to milliseconds */
1000 interval = interval * 1000;
1001
718e3744 1002 zif->rtadv.MaxRtrAdvInterval = interval;
1003 zif->rtadv.MinRtrAdvInterval = 0.33 * interval;
1004 zif->rtadv.AdvIntervalTimer = 0;
1005
1006 return CMD_SUCCESS;
1007}
1008
1009DEFUN (no_ipv6_nd_ra_interval,
1010 no_ipv6_nd_ra_interval_cmd,
1011 "no ipv6 nd ra-interval",
1012 NO_STR
3e31cded 1013 "Interface IPv6 config commands\n"
718e3744 1014 "Neighbor discovery\n"
1015 "Router Advertisement interval\n")
1016{
1017 struct interface *ifp;
1018 struct zebra_if *zif;
cd80d74f 1019 struct zebra_vrf *zvrf;
43459b1f 1020 struct zebra_ns *zns;
718e3744 1021
1022 ifp = (struct interface *) vty->index;
1023 zif = ifp->info;
cd80d74f 1024 zvrf = vrf_info_lookup (ifp->vrf_id);
43459b1f 1025 zns = zvrf->zns;
718e3744 1026
7cee1bb1 1027 if (zif->rtadv.MaxRtrAdvInterval % 1000)
43459b1f 1028 zns->rtadv.adv_msec_if_count--;
7cee1bb1 1029
718e3744 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
4afa50b3
DO
1037ALIAS (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
1045ALIAS (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
718e3744 1054DEFUN (ipv6_nd_ra_lifetime,
1055 ipv6_nd_ra_lifetime_cmd,
4afa50b3 1056 "ipv6 nd ra-lifetime <0-9000>",
3e31cded 1057 "Interface IPv6 config commands\n"
718e3744 1058 "Neighbor discovery\n"
1059 "Router lifetime\n"
4afa50b3 1060 "Router lifetime in seconds (0 stands for a non-default gw)\n")
718e3744 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
4afa50b3 1069 VTY_GET_INTEGER_RANGE ("router lifetime", lifetime, argv[0], 0, 9000);
718e3744 1070
d660f698
DO
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 */
4afa50b3 1075 if ((lifetime != 0 && lifetime * 1000 < zif->rtadv.MaxRtrAdvInterval))
718e3744 1076 {
4afa50b3 1077 vty_out (vty, "This ra-lifetime would conflict with configured ra-interval%s", VTY_NEWLINE);
718e3744 1078 return CMD_WARNING;
1079 }
1080
1081 zif->rtadv.AdvDefaultLifetime = lifetime;
1082
1083 return CMD_SUCCESS;
1084}
1085
1086DEFUN (no_ipv6_nd_ra_lifetime,
1087 no_ipv6_nd_ra_lifetime_cmd,
1088 "no ipv6 nd ra-lifetime",
1089 NO_STR
3e31cded 1090 "Interface IPv6 config commands\n"
718e3744 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
d660f698 1100 zif->rtadv.AdvDefaultLifetime = -1;
718e3744 1101
1102 return CMD_SUCCESS;
1103}
1104
4afa50b3
DO
1105ALIAS (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
718e3744 1114DEFUN (ipv6_nd_reachable_time,
1115 ipv6_nd_reachable_time_cmd,
4afa50b3 1116 "ipv6 nd reachable-time <1-3600000>",
3e31cded 1117 "Interface IPv6 config commands\n"
718e3744 1118 "Neighbor discovery\n"
1119 "Reachable time\n"
1120 "Reachable time in milliseconds\n")
1121{
4afa50b3
DO
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);
718e3744 1125 return CMD_SUCCESS;
1126}
1127
1128DEFUN (no_ipv6_nd_reachable_time,
1129 no_ipv6_nd_reachable_time_cmd,
1130 "no ipv6 nd reachable-time",
1131 NO_STR
3e31cded 1132 "Interface IPv6 config commands\n"
718e3744 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
4afa50b3
DO
1147ALIAS (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
7cee1bb1 1156DEFUN (ipv6_nd_homeagent_preference,
1157 ipv6_nd_homeagent_preference_cmd,
4afa50b3 1158 "ipv6 nd home-agent-preference <0-65535>",
7cee1bb1 1159 "Interface IPv6 config commands\n"
1160 "Neighbor discovery\n"
1161 "Home Agent preference\n"
4afa50b3 1162 "preference value (default is 0, least preferred)\n")
7cee1bb1 1163{
4afa50b3
DO
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);
7cee1bb1 1167 return CMD_SUCCESS;
1168}
1169
1170DEFUN (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
4afa50b3
DO
1189ALIAS (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
7cee1bb1 1198DEFUN (ipv6_nd_homeagent_lifetime,
1199 ipv6_nd_homeagent_lifetime_cmd,
4afa50b3 1200 "ipv6 nd home-agent-lifetime <0-65520>",
7cee1bb1 1201 "Interface IPv6 config commands\n"
1202 "Neighbor discovery\n"
1203 "Home Agent lifetime\n"
4afa50b3 1204 "Home Agent lifetime in seconds (0 to track ra-lifetime)\n")
7cee1bb1 1205{
4afa50b3
DO
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);
7cee1bb1 1209 return CMD_SUCCESS;
1210}
1211
1212DEFUN (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
d660f698 1226 zif->rtadv.HomeAgentLifetime = -1;
7cee1bb1 1227
1228 return CMD_SUCCESS;
1229}
1230
4afa50b3
DO
1231ALIAS (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
718e3744 1240DEFUN (ipv6_nd_managed_config_flag,
1241 ipv6_nd_managed_config_flag_cmd,
1242 "ipv6 nd managed-config-flag",
3e31cded 1243 "Interface IPv6 config commands\n"
718e3744 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
1258DEFUN (no_ipv6_nd_managed_config_flag,
1259 no_ipv6_nd_managed_config_flag_cmd,
1260 "no ipv6 nd managed-config-flag",
1261 NO_STR
3e31cded 1262 "Interface IPv6 config commands\n"
718e3744 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
7cee1bb1 1277DEFUN (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
1295DEFUN (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
1314DEFUN (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
1332DEFUN (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
718e3744 1351DEFUN (ipv6_nd_other_config_flag,
1352 ipv6_nd_other_config_flag_cmd,
1353 "ipv6 nd other-config-flag",
3e31cded 1354 "Interface IPv6 config commands\n"
718e3744 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
1369DEFUN (no_ipv6_nd_other_config_flag,
1370 no_ipv6_nd_other_config_flag_cmd,
1371 "no ipv6 nd other-config-flag",
1372 NO_STR
3e31cded 1373 "Interface IPv6 config commands\n"
718e3744 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
3e31cded 1388DEFUN (ipv6_nd_prefix,
1389 ipv6_nd_prefix_cmd,
1390 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
7cee1bb1 1391 "(<0-4294967295>|infinite) (off-link|) (no-autoconfig|) (router-address|)",
3e31cded 1392 "Interface IPv6 config commands\n"
718e3744 1393 "Neighbor discovery\n"
1394 "Prefix information\n"
1395 "IPv6 prefix\n"
1396 "Valid lifetime in seconds\n"
3e31cded 1397 "Infinite valid lifetime\n"
718e3744 1398 "Preferred lifetime in seconds\n"
3e31cded 1399 "Infinite preferred lifetime\n"
1400 "Do not use prefix for onlink determination\n"
7cee1bb1 1401 "Do not use prefix for autoconfiguration\n"
1402 "Set Router Address flag\n")
718e3744 1403{
1404 int i;
1405 int ret;
3e31cded 1406 int cursor = 1;
718e3744 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
aca43b65 1414 ret = str2prefix_ipv6 (argv[0], &rp.prefix);
718e3744 1415 if (!ret)
1416 {
1417 vty_out (vty, "Malformed IPv6 prefix%s", VTY_NEWLINE);
1418 return CMD_WARNING;
1419 }
6bb1273e 1420 apply_mask_ipv6 (&rp.prefix); /* RFC4861 4.6.2 */
3e31cded 1421 rp.AdvOnLinkFlag = 1;
1422 rp.AdvAutonomousFlag = 1;
7cee1bb1 1423 rp.AdvRouterAddressFlag = 0;
3e31cded 1424 rp.AdvValidLifetime = RTADV_VALID_LIFETIME;
1425 rp.AdvPreferredLifetime = RTADV_PREFERRED_LIFETIME;
718e3744 1426
3e31cded 1427 if (argc > 1)
718e3744 1428 {
27b87393
DL
1429 if ((isdigit((unsigned char)argv[1][0]))
1430 || strncmp (argv[1], "i", 1) == 0)
718e3744 1431 {
3e31cded 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;
718e3744 1450 }
3e31cded 1451 if (argc > cursor)
718e3744 1452 {
3e31cded 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;
7cee1bb1 1459 if (strncmp (argv[i], "ro", 2) == 0)
1460 rp.AdvRouterAddressFlag = 1;
3e31cded 1461 }
718e3744 1462 }
1463 }
1464
1465 rtadv_prefix_set (zebra_if, &rp);
1466
1467 return CMD_SUCCESS;
1468}
1469
7cee1bb1 1470ALIAS (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
3e31cded 1485ALIAS (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
7cee1bb1 1500ALIAS (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
3e31cded 1516ALIAS (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"
7cee1bb1 1528 "Do not use prefix for autoconfiguration")
3e31cded 1529
1530ALIAS (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
7cee1bb1 1544ALIAS (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
3e31cded 1558ALIAS (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
1571ALIAS (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
1581ALIAS (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
1591ALIAS (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
1600ALIAS (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
7cee1bb1 1609ALIAS (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
3e31cded 1618ALIAS (ipv6_nd_prefix,
1619 ipv6_nd_prefix_prefix_cmd,
1620 "ipv6 nd prefix X:X::X:X/M",
1621 "Interface IPv6 config commands\n"
718e3744 1622 "Neighbor discovery\n"
1623 "Prefix information\n"
1624 "IPv6 prefix\n")
1625
3e31cded 1626DEFUN (no_ipv6_nd_prefix,
1627 no_ipv6_nd_prefix_cmd,
1628 "no ipv6 nd prefix IPV6PREFIX",
718e3744 1629 NO_STR
3e31cded 1630 "Interface IPv6 config commands\n"
718e3744 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
aca43b65 1643 ret = str2prefix_ipv6 (argv[0], &rp.prefix);
718e3744 1644 if (!ret)
1645 {
1646 vty_out (vty, "Malformed IPv6 prefix%s", VTY_NEWLINE);
1647 return CMD_WARNING;
1648 }
6bb1273e 1649 apply_mask_ipv6 (&rp.prefix); /* RFC4861 4.6.2 */
718e3744 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}
b60668d0 1660
813d4307
DW
1661ALIAS (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
1677ALIAS (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
1692ALIAS (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
1708ALIAS (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
1722ALIAS (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
1736ALIAS (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
1750ALIAS (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
1763ALIAS (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
1774ALIAS (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
1785ALIAS (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
1795ALIAS (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
1805ALIAS (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
b60668d0
CC
1815DEFUN (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
1845DEFUN (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
4afa50b3
DO
1864ALIAS (no_ipv6_nd_router_preference,
1865 no_ipv6_nd_router_preference_val_cmd,
2b00515a 1866 "no ipv6 nd router-preference (high|medium|low)",
4afa50b3
DO
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
6ae93c05
DO
1875DEFUN (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
1889DEFUN (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
1903ALIAS (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
718e3744 1912/* Write configuration about router advertisement. */
1913void
1914rtadv_config_write (struct vty *vty, struct interface *ifp)
1915{
1916 struct zebra_if *zif;
52dc7ee6 1917 struct listnode *node;
718e3744 1918 struct rtadv_prefix *rprefix;
35d921cc 1919 char buf[PREFIX_STRLEN];
7cee1bb1 1920 int interval;
718e3744 1921
718e3744 1922 zif = ifp->info;
1923
c23af4d3 1924 if (!(if_is_loopback (ifp) ||
1925 CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK)))
718e3744 1926 {
c5b37afc 1927 if (zif->rtadv.AdvSendAdvertisements)
1928 vty_out (vty, " no ipv6 nd suppress-ra%s", VTY_NEWLINE);
718e3744 1929 }
7cee1bb1 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,
718e3744 1938 VTY_NEWLINE);
1939
6134b875
DO
1940 if (zif->rtadv.AdvIntervalOption)
1941 vty_out (vty, " ipv6 nd adv-interval-option%s", VTY_NEWLINE);
1942
d660f698 1943 if (zif->rtadv.AdvDefaultLifetime != -1)
718e3744 1944 vty_out (vty, " ipv6 nd ra-lifetime %d%s", zif->rtadv.AdvDefaultLifetime,
1945 VTY_NEWLINE);
1946
6134b875
DO
1947 if (zif->rtadv.HomeAgentPreference)
1948 vty_out (vty, " ipv6 nd home-agent-preference %u%s",
1949 zif->rtadv.HomeAgentPreference, VTY_NEWLINE);
1950
d660f698 1951 if (zif->rtadv.HomeAgentLifetime != -1)
6134b875
DO
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
718e3744 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
b60668d0
CC
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
6ae93c05
DO
1973 if (zif->rtadv.AdvLinkMTU)
1974 vty_out (vty, " ipv6 nd mtu %d%s", zif->rtadv.AdvLinkMTU, VTY_NEWLINE);
1975
1eb8ef25 1976 for (ALL_LIST_ELEMENTS_RO (zif->rtadv.AdvPrefixList, node, rprefix))
718e3744 1977 {
35d921cc
TT
1978 vty_out (vty, " ipv6 nd prefix %s",
1979 prefix2str (&rprefix->prefix, buf, sizeof(buf)));
3e31cded 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");
7cee1bb1 1996 if (rprefix->AdvRouterAddressFlag)
1997 vty_out (vty, " router-address");
718e3744 1998 vty_out (vty, "%s", VTY_NEWLINE);
1999 }
2000}
2001
718e3744 2002
a1ac18c4 2003static void
43459b1f 2004rtadv_event (struct zebra_ns *zns, enum rtadv_event event, int val)
718e3744 2005{
43459b1f 2006 struct rtadv *rtadv = &zns->rtadv;
cd80d74f 2007
718e3744 2008 switch (event)
2009 {
2010 case RTADV_START:
2011 if (! rtadv->ra_read)
6c9678b4 2012 rtadv->ra_read = thread_add_read (zebrad.master, rtadv_read, zns, val);
718e3744 2013 if (! rtadv->ra_timer)
6c9678b4
DD
2014 rtadv->ra_timer = thread_add_event (zebrad.master, rtadv_timer,
2015 zns, 0);
718e3744 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)
43459b1f 2031 rtadv->ra_timer = thread_add_timer (zebrad.master, rtadv_timer, zns,
3e31cded 2032 val);
718e3744 2033 break;
7cee1bb1 2034 case RTADV_TIMER_MSEC:
2035 if (! rtadv->ra_timer)
2036 rtadv->ra_timer = thread_add_timer_msec (zebrad.master, rtadv_timer,
43459b1f 2037 zns, val);
7cee1bb1 2038 break;
718e3744 2039 case RTADV_READ:
2040 if (! rtadv->ra_read)
43459b1f 2041 rtadv->ra_read = thread_add_read (zebrad.master, rtadv_read, zns, val);
718e3744 2042 break;
2043 default:
2044 break;
2045 }
2046 return;
2047}
2048
2049void
43459b1f 2050rtadv_init (struct zebra_ns *zns)
718e3744 2051{
43459b1f 2052 zns->rtadv.sock = rtadv_make_socket ();
cd80d74f 2053}
718e3744 2054
cd80d74f 2055void
43459b1f 2056rtadv_terminate (struct zebra_ns *zns)
cd80d74f 2057{
43459b1f 2058 rtadv_event (zns, RTADV_STOP, 0);
2059 if (zns->rtadv.sock >= 0)
cd80d74f 2060 {
43459b1f 2061 close (zns->rtadv.sock);
2062 zns->rtadv.sock = -1;
cd80d74f 2063 }
718e3744 2064
43459b1f 2065 zns->rtadv.adv_if_count = 0;
2066 zns->rtadv.adv_msec_if_count = 0;
cd80d74f 2067}
718e3744 2068
cd80d74f
FL
2069void
2070rtadv_cmd_init (void)
2071{
718e3744 2072 install_element (INTERFACE_NODE, &ipv6_nd_suppress_ra_cmd);
2073 install_element (INTERFACE_NODE, &no_ipv6_nd_suppress_ra_cmd);
718e3744 2074 install_element (INTERFACE_NODE, &ipv6_nd_ra_interval_cmd);
7cee1bb1 2075 install_element (INTERFACE_NODE, &ipv6_nd_ra_interval_msec_cmd);
718e3744 2076 install_element (INTERFACE_NODE, &no_ipv6_nd_ra_interval_cmd);
4afa50b3
DO
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);
718e3744 2079 install_element (INTERFACE_NODE, &ipv6_nd_ra_lifetime_cmd);
2080 install_element (INTERFACE_NODE, &no_ipv6_nd_ra_lifetime_cmd);
4afa50b3 2081 install_element (INTERFACE_NODE, &no_ipv6_nd_ra_lifetime_val_cmd);
718e3744 2082 install_element (INTERFACE_NODE, &ipv6_nd_reachable_time_cmd);
2083 install_element (INTERFACE_NODE, &no_ipv6_nd_reachable_time_cmd);
4afa50b3 2084 install_element (INTERFACE_NODE, &no_ipv6_nd_reachable_time_val_cmd);
718e3744 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);
7cee1bb1 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);
4afa50b3 2093 install_element (INTERFACE_NODE, &no_ipv6_nd_homeagent_preference_val_cmd);
7cee1bb1 2094 install_element (INTERFACE_NODE, &ipv6_nd_homeagent_lifetime_cmd);
2095 install_element (INTERFACE_NODE, &no_ipv6_nd_homeagent_lifetime_cmd);
4afa50b3 2096 install_element (INTERFACE_NODE, &no_ipv6_nd_homeagent_lifetime_val_cmd);
7cee1bb1 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);
3e31cded 2099 install_element (INTERFACE_NODE, &ipv6_nd_prefix_cmd);
7cee1bb1 2100 install_element (INTERFACE_NODE, &ipv6_nd_prefix_val_rev_rtaddr_cmd);
2101 install_element (INTERFACE_NODE, &ipv6_nd_prefix_val_nortaddr_cmd);
3e31cded 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);
7cee1bb1 2105 install_element (INTERFACE_NODE, &ipv6_nd_prefix_val_rtaddr_cmd);
3e31cded 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);
7cee1bb1 2111 install_element (INTERFACE_NODE, &ipv6_nd_prefix_noval_rtaddr_cmd);
3e31cded 2112 install_element (INTERFACE_NODE, &ipv6_nd_prefix_prefix_cmd);
2113 install_element (INTERFACE_NODE, &no_ipv6_nd_prefix_cmd);
813d4307
DW
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);
b60668d0
CC
2126 install_element (INTERFACE_NODE, &ipv6_nd_router_preference_cmd);
2127 install_element (INTERFACE_NODE, &no_ipv6_nd_router_preference_cmd);
4afa50b3 2128 install_element (INTERFACE_NODE, &no_ipv6_nd_router_preference_val_cmd);
6ae93c05
DO
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);
718e3744 2132}
2133
a1ac18c4 2134static int
718e3744 2135if_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)
f360eac0 2148 zlog_warn ("%s(%u): Failed to join group, socket %u error %s",
2149 ifp->name, ifp->ifindex, sock, safe_strerror (errno));
718e3744 2150
f360eac0 2151 if (IS_ZEBRA_DEBUG_EVENT)
2152 zlog_debug ("%s(%u): Join All-Routers multicast group, socket %u",
2153 ifp->name, ifp->ifindex, sock);
718e3744 2154
2155 return 0;
2156}
2157
a1ac18c4 2158static int
718e3744 2159if_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)
f360eac0 2172 zlog_warn ("%s(%u): Failed to leave group, socket %u error %s",
2173 ifp->name, ifp->ifindex, sock,safe_strerror (errno));
718e3744 2174
f360eac0 2175 if (IS_ZEBRA_DEBUG_EVENT)
2176 zlog_debug ("%s(%u): Leave All-Routers multicast group, socket %u",
2177 ifp->name, ifp->ifindex, sock);
718e3744 2178
2179 return 0;
2180}
2181
2182#else
2183void
43459b1f 2184rtadv_init (struct zebra_ns *zns)
cd80d74f
FL
2185{
2186 /* Empty.*/;
2187}
2188void
43459b1f 2189rtadv_terminate (struct zebra_ns *zns)
cd80d74f
FL
2190{
2191 /* Empty.*/;
2192}
2193void
2194rtadv_cmd_init (void)
718e3744 2195{
2196 /* Empty.*/;
2197}
8da4e946 2198#endif /* HAVE_RTADV && HAVE_IPV6 */