]> git.proxmox.com Git - mirror_frr.git/blame - zebra/ioctl.c
Merge pull request #870 from chiragshah6/mdev
[mirror_frr.git] / zebra / ioctl.c
CommitLineData
718e3744 1/*
2 * Common ioctl functions.
3 * Copyright (C) 1997, 98 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 *
896014f4
DL
17 * You should have received a copy of the GNU General Public License along
18 * with this program; see the file COPYING; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
718e3744 20 */
21
22#include <zebra.h>
23
24#include "linklist.h"
25#include "if.h"
26#include "prefix.h"
27#include "ioctl.h"
28#include "log.h"
edd7c245 29#include "privs.h"
718e3744 30
5e6a74d8 31#include "vty.h"
718e3744 32#include "zebra/rib.h"
33#include "zebra/rt.h"
5c78b3d0 34#include "zebra/interface.h"
718e3744 35
ddfeb486
DL
36#ifndef SUNOS_5
37
55edb0d4
AS
38#ifdef HAVE_BSD_LINK_DETECT
39#include <net/if_media.h>
40#endif /* HAVE_BSD_LINK_DETECT*/
41
edd7c245 42extern struct zebra_privs_t zserv_privs;
43
718e3744 44/* clear and set interface name string */
d62a17ae 45void ifreq_set_name(struct ifreq *ifreq, struct interface *ifp)
718e3744 46{
d62a17ae 47 strncpy(ifreq->ifr_name, ifp->name, IFNAMSIZ);
718e3744 48}
49
50/* call ioctl system call */
d62a17ae 51int if_ioctl(u_long request, caddr_t buffer)
718e3744 52{
d62a17ae 53 int sock;
54 int ret;
55 int err = 0;
56
57 if (zserv_privs.change(ZPRIVS_RAISE))
58 zlog_err("Can't raise privileges");
59 sock = socket(AF_INET, SOCK_DGRAM, 0);
60 if (sock < 0) {
61 int save_errno = errno;
62 if (zserv_privs.change(ZPRIVS_LOWER))
63 zlog_err("Can't lower privileges");
64 zlog_err("Cannot create UDP socket: %s",
65 safe_strerror(save_errno));
66 exit(1);
67 }
68 if ((ret = ioctl(sock, request, buffer)) < 0)
69 err = errno;
70 if (zserv_privs.change(ZPRIVS_LOWER))
71 zlog_err("Can't lower privileges");
72 close(sock);
73
74 if (ret < 0) {
75 errno = err;
76 return ret;
77 }
78 return 0;
718e3744 79}
80
d62a17ae 81static int if_ioctl_ipv6(u_long request, caddr_t buffer)
718e3744 82{
d62a17ae 83 int sock;
84 int ret;
85 int err = 0;
86
87 if (zserv_privs.change(ZPRIVS_RAISE))
88 zlog_err("Can't raise privileges");
89 sock = socket(AF_INET6, SOCK_DGRAM, 0);
90 if (sock < 0) {
91 int save_errno = errno;
92 if (zserv_privs.change(ZPRIVS_LOWER))
93 zlog_err("Can't lower privileges");
94 zlog_err("Cannot create IPv6 datagram socket: %s",
95 safe_strerror(save_errno));
96 exit(1);
97 }
98
99 if ((ret = ioctl(sock, request, buffer)) < 0)
100 err = errno;
101 if (zserv_privs.change(ZPRIVS_LOWER))
102 zlog_err("Can't lower privileges");
103 close(sock);
104
105 if (ret < 0) {
106 errno = err;
107 return ret;
108 }
109 return 0;
718e3744 110}
718e3744 111
112/*
113 * get interface metric
114 * -- if value is not avaliable set -1
115 */
d62a17ae 116void if_get_metric(struct interface *ifp)
718e3744 117{
118#ifdef SIOCGIFMETRIC
d62a17ae 119 struct ifreq ifreq;
718e3744 120
d62a17ae 121 ifreq_set_name(&ifreq, ifp);
718e3744 122
d62a17ae 123 if (if_ioctl(SIOCGIFMETRIC, (caddr_t)&ifreq) < 0)
124 return;
125 ifp->metric = ifreq.ifr_metric;
126 if (ifp->metric == 0)
127 ifp->metric = 1;
128#else /* SIOCGIFMETRIC */
129 ifp->metric = -1;
718e3744 130#endif /* SIOCGIFMETRIC */
131}
132
133/* get interface MTU */
d62a17ae 134void if_get_mtu(struct interface *ifp)
718e3744 135{
d62a17ae 136 struct ifreq ifreq;
718e3744 137
d62a17ae 138 ifreq_set_name(&ifreq, ifp);
718e3744 139
140#if defined(SIOCGIFMTU)
d62a17ae 141 if (if_ioctl(SIOCGIFMTU, (caddr_t)&ifreq) < 0) {
142 zlog_info("Can't lookup mtu by ioctl(SIOCGIFMTU)");
143 ifp->mtu6 = ifp->mtu = -1;
144 return;
145 }
718e3744 146
147#ifdef SUNOS_5
d62a17ae 148 ifp->mtu6 = ifp->mtu = ifreq.ifr_metric;
718e3744 149#else
d62a17ae 150 ifp->mtu6 = ifp->mtu = ifreq.ifr_mtu;
718e3744 151#endif /* SUNOS_5 */
152
d62a17ae 153 /* propogate */
154 zebra_interface_up_update(ifp);
f5e004f7 155
718e3744 156#else
d62a17ae 157 zlog_info("Can't lookup mtu on this system");
158 ifp->mtu6 = ifp->mtu = -1;
718e3744 159#endif
160}
161
162#ifdef HAVE_NETLINK
163/* Interface address setting via netlink interface. */
d62a17ae 164int if_set_prefix(struct interface *ifp, struct connected *ifc)
718e3744 165{
d62a17ae 166 return kernel_address_add_ipv4(ifp, ifc);
718e3744 167}
168
169/* Interface address is removed using netlink interface. */
d62a17ae 170int if_unset_prefix(struct interface *ifp, struct connected *ifc)
718e3744 171{
d62a17ae 172 return kernel_address_delete_ipv4(ifp, ifc);
718e3744 173}
174#else /* ! HAVE_NETLINK */
6f0e3f6e 175#ifdef HAVE_STRUCT_IFALIASREQ
718e3744 176/* Set up interface's IP address, netmask (and broadcas? ). *BSD may
177 has ifaliasreq structure. */
d62a17ae 178int if_set_prefix(struct interface *ifp, struct connected *ifc)
718e3744 179{
d62a17ae 180 int ret;
181 struct ifaliasreq addreq;
182 struct sockaddr_in addr;
183 struct sockaddr_in mask;
184 struct prefix_ipv4 *p;
718e3744 185
d62a17ae 186 p = (struct prefix_ipv4 *)ifc->address;
187 rib_lookup_and_pushup(p, ifp->vrf_id);
718e3744 188
d62a17ae 189 memset(&addreq, 0, sizeof addreq);
190 strncpy((char *)&addreq.ifra_name, ifp->name, sizeof addreq.ifra_name);
718e3744 191
d62a17ae 192 memset(&addr, 0, sizeof(struct sockaddr_in));
193 addr.sin_addr = p->prefix;
194 addr.sin_family = p->family;
6f0e3f6e 195#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
d62a17ae 196 addr.sin_len = sizeof(struct sockaddr_in);
718e3744 197#endif
d62a17ae 198 memcpy(&addreq.ifra_addr, &addr, sizeof(struct sockaddr_in));
718e3744 199
d62a17ae 200 memset(&mask, 0, sizeof(struct sockaddr_in));
201 masklen2ip(p->prefixlen, &mask.sin_addr);
202 mask.sin_family = p->family;
6f0e3f6e 203#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
d62a17ae 204 mask.sin_len = sizeof(struct sockaddr_in);
718e3744 205#endif
d62a17ae 206 memcpy(&addreq.ifra_mask, &mask, sizeof(struct sockaddr_in));
207
208 ret = if_ioctl(SIOCAIFADDR, (caddr_t)&addreq);
209 if (ret < 0)
210 return ret;
211 return 0;
718e3744 212}
213
214/* Set up interface's IP address, netmask (and broadcas? ). *BSD may
215 has ifaliasreq structure. */
d62a17ae 216int if_unset_prefix(struct interface *ifp, struct connected *ifc)
718e3744 217{
d62a17ae 218 int ret;
219 struct ifaliasreq addreq;
220 struct sockaddr_in addr;
221 struct sockaddr_in mask;
222 struct prefix_ipv4 *p;
718e3744 223
d62a17ae 224 p = (struct prefix_ipv4 *)ifc->address;
718e3744 225
d62a17ae 226 memset(&addreq, 0, sizeof addreq);
227 strncpy((char *)&addreq.ifra_name, ifp->name, sizeof addreq.ifra_name);
718e3744 228
d62a17ae 229 memset(&addr, 0, sizeof(struct sockaddr_in));
230 addr.sin_addr = p->prefix;
231 addr.sin_family = p->family;
6f0e3f6e 232#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
d62a17ae 233 addr.sin_len = sizeof(struct sockaddr_in);
718e3744 234#endif
d62a17ae 235 memcpy(&addreq.ifra_addr, &addr, sizeof(struct sockaddr_in));
718e3744 236
d62a17ae 237 memset(&mask, 0, sizeof(struct sockaddr_in));
238 masklen2ip(p->prefixlen, &mask.sin_addr);
239 mask.sin_family = p->family;
6f0e3f6e 240#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
d62a17ae 241 mask.sin_len = sizeof(struct sockaddr_in);
718e3744 242#endif
d62a17ae 243 memcpy(&addreq.ifra_mask, &mask, sizeof(struct sockaddr_in));
244
245 ret = if_ioctl(SIOCDIFADDR, (caddr_t)&addreq);
246 if (ret < 0)
247 return ret;
248 return 0;
718e3744 249}
250#else
251/* Set up interface's address, netmask (and broadcas? ). Linux or
252 Solaris uses ifname:number semantics to set IP address aliases. */
d62a17ae 253int if_set_prefix(struct interface *ifp, struct connected *ifc)
718e3744 254{
d62a17ae 255 int ret;
256 struct ifreq ifreq;
257 struct sockaddr_in addr;
258 struct sockaddr_in broad;
259 struct sockaddr_in mask;
260 struct prefix_ipv4 ifaddr;
261 struct prefix_ipv4 *p;
262
263 p = (struct prefix_ipv4 *)ifc->address;
264
265 ifaddr = *p;
266
267 ifreq_set_name(&ifreq, ifp);
268
269 addr.sin_addr = p->prefix;
270 addr.sin_family = p->family;
271 memcpy(&ifreq.ifr_addr, &addr, sizeof(struct sockaddr_in));
272 ret = if_ioctl(SIOCSIFADDR, (caddr_t)&ifreq);
273 if (ret < 0)
274 return ret;
275
276 /* We need mask for make broadcast addr. */
277 masklen2ip(p->prefixlen, &mask.sin_addr);
278
279 if (if_is_broadcast(ifp)) {
280 apply_mask_ipv4(&ifaddr);
281 addr.sin_addr = ifaddr.prefix;
282
283 broad.sin_addr.s_addr =
284 (addr.sin_addr.s_addr | ~mask.sin_addr.s_addr);
285 broad.sin_family = p->family;
286
287 memcpy(&ifreq.ifr_broadaddr, &broad,
288 sizeof(struct sockaddr_in));
289 ret = if_ioctl(SIOCSIFBRDADDR, (caddr_t)&ifreq);
290 if (ret < 0)
291 return ret;
292 }
293
294 mask.sin_family = p->family;
718e3744 295#ifdef SUNOS_5
d62a17ae 296 memcpy(&mask, &ifreq.ifr_addr, sizeof(mask));
718e3744 297#else
d62a17ae 298 memcpy(&ifreq.ifr_netmask, &mask, sizeof(struct sockaddr_in));
718e3744 299#endif /* SUNOS5 */
d62a17ae 300 ret = if_ioctl(SIOCSIFNETMASK, (caddr_t)&ifreq);
301 if (ret < 0)
302 return ret;
718e3744 303
d62a17ae 304 return 0;
718e3744 305}
306
307/* Set up interface's address, netmask (and broadcas? ). Linux or
308 Solaris uses ifname:number semantics to set IP address aliases. */
d62a17ae 309int if_unset_prefix(struct interface *ifp, struct connected *ifc)
718e3744 310{
d62a17ae 311 int ret;
312 struct ifreq ifreq;
313 struct sockaddr_in addr;
314 struct prefix_ipv4 *p;
718e3744 315
d62a17ae 316 p = (struct prefix_ipv4 *)ifc->address;
718e3744 317
d62a17ae 318 ifreq_set_name(&ifreq, ifp);
718e3744 319
d62a17ae 320 memset(&addr, 0, sizeof(struct sockaddr_in));
321 addr.sin_family = p->family;
322 memcpy(&ifreq.ifr_addr, &addr, sizeof(struct sockaddr_in));
323 ret = if_ioctl(SIOCSIFADDR, (caddr_t)&ifreq);
324 if (ret < 0)
325 return ret;
718e3744 326
d62a17ae 327 return 0;
718e3744 328}
6f0e3f6e 329#endif /* HAVE_STRUCT_IFALIASREQ */
718e3744 330#endif /* HAVE_NETLINK */
331
332/* get interface flags */
d62a17ae 333void if_get_flags(struct interface *ifp)
718e3744 334{
d62a17ae 335 int ret;
336 struct ifreq ifreq;
c543a173 337#ifdef HAVE_BSD_LINK_DETECT
d62a17ae 338 struct ifmediareq ifmr;
c543a173 339#endif /* HAVE_BSD_LINK_DETECT */
718e3744 340
d62a17ae 341 ifreq_set_name(&ifreq, ifp);
718e3744 342
d62a17ae 343 ret = if_ioctl(SIOCGIFFLAGS, (caddr_t)&ifreq);
344 if (ret < 0) {
345 zlog_err("if_ioctl(SIOCGIFFLAGS) failed: %s",
346 safe_strerror(errno));
347 return;
348 }
c543a173 349#ifdef HAVE_BSD_LINK_DETECT /* Detect BSD link-state at start-up */
0b3f3d47 350
d62a17ae 351 /* Per-default, IFF_RUNNING is held high, unless link-detect says
352 * otherwise - we abuse IFF_RUNNING inside zebra as a link-state flag,
353 * following practice on Linux and Solaris kernels
354 */
355 SET_FLAG(ifreq.ifr_flags, IFF_RUNNING);
356
357 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION)) {
358 (void)memset(&ifmr, 0, sizeof(ifmr));
359 strncpy(ifmr.ifm_name, ifp->name, IFNAMSIZ);
360
361 /* Seems not all interfaces implement this ioctl */
362 if (if_ioctl(SIOCGIFMEDIA, (caddr_t)&ifmr) < 0)
363 zlog_err("if_ioctl(SIOCGIFMEDIA) failed: %s",
364 safe_strerror(errno));
365 else if (ifmr.ifm_status & IFM_AVALID) /* Link state is valid */
366 {
367 if (ifmr.ifm_status & IFM_ACTIVE)
368 SET_FLAG(ifreq.ifr_flags, IFF_RUNNING);
369 else
370 UNSET_FLAG(ifreq.ifr_flags, IFF_RUNNING);
371 }
372 }
c543a173 373#endif /* HAVE_BSD_LINK_DETECT */
718e3744 374
d62a17ae 375 if_flags_update(ifp, (ifreq.ifr_flags & 0x0000ffff));
718e3744 376}
377
378/* Set interface flags */
d62a17ae 379int if_set_flags(struct interface *ifp, uint64_t flags)
718e3744 380{
d62a17ae 381 int ret;
382 struct ifreq ifreq;
718e3744 383
d62a17ae 384 memset(&ifreq, 0, sizeof(struct ifreq));
385 ifreq_set_name(&ifreq, ifp);
718e3744 386
d62a17ae 387 ifreq.ifr_flags = ifp->flags;
388 ifreq.ifr_flags |= flags;
718e3744 389
d62a17ae 390 ret = if_ioctl(SIOCSIFFLAGS, (caddr_t)&ifreq);
718e3744 391
d62a17ae 392 if (ret < 0) {
393 zlog_info("can't set interface flags");
394 return ret;
395 }
396 return 0;
718e3744 397}
398
399/* Unset interface's flag. */
d62a17ae 400int if_unset_flags(struct interface *ifp, uint64_t flags)
718e3744 401{
d62a17ae 402 int ret;
403 struct ifreq ifreq;
718e3744 404
d62a17ae 405 memset(&ifreq, 0, sizeof(struct ifreq));
406 ifreq_set_name(&ifreq, ifp);
718e3744 407
d62a17ae 408 ifreq.ifr_flags = ifp->flags;
409 ifreq.ifr_flags &= ~flags;
718e3744 410
d62a17ae 411 ret = if_ioctl(SIOCSIFFLAGS, (caddr_t)&ifreq);
718e3744 412
d62a17ae 413 if (ret < 0) {
414 zlog_info("can't unset interface flags");
415 return ret;
416 }
417 return 0;
718e3744 418}
419
718e3744 420#ifdef LINUX_IPV6
421#ifndef _LINUX_IN6_H
422/* linux/include/net/ipv6.h */
d62a17ae 423struct in6_ifreq {
424 struct in6_addr ifr6_addr;
425 u_int32_t ifr6_prefixlen;
426 int ifr6_ifindex;
718e3744 427};
428#endif /* _LINUX_IN6_H */
429
430/* Interface's address add/delete functions. */
d62a17ae 431int if_prefix_add_ipv6(struct interface *ifp, struct connected *ifc)
718e3744 432{
d62a17ae 433 int ret;
434 struct prefix_ipv6 *p;
435 struct in6_ifreq ifreq;
718e3744 436
d62a17ae 437 p = (struct prefix_ipv6 *)ifc->address;
718e3744 438
d62a17ae 439 memset(&ifreq, 0, sizeof(struct in6_ifreq));
718e3744 440
d62a17ae 441 memcpy(&ifreq.ifr6_addr, &p->prefix, sizeof(struct in6_addr));
442 ifreq.ifr6_ifindex = ifp->ifindex;
443 ifreq.ifr6_prefixlen = p->prefixlen;
718e3744 444
d62a17ae 445 ret = if_ioctl_ipv6(SIOCSIFADDR, (caddr_t)&ifreq);
718e3744 446
d62a17ae 447 return ret;
718e3744 448}
449
d62a17ae 450int if_prefix_delete_ipv6(struct interface *ifp, struct connected *ifc)
718e3744 451{
d62a17ae 452 int ret;
453 struct prefix_ipv6 *p;
454 struct in6_ifreq ifreq;
718e3744 455
d62a17ae 456 p = (struct prefix_ipv6 *)ifc->address;
718e3744 457
d62a17ae 458 memset(&ifreq, 0, sizeof(struct in6_ifreq));
718e3744 459
d62a17ae 460 memcpy(&ifreq.ifr6_addr, &p->prefix, sizeof(struct in6_addr));
461 ifreq.ifr6_ifindex = ifp->ifindex;
462 ifreq.ifr6_prefixlen = p->prefixlen;
718e3744 463
d62a17ae 464 ret = if_ioctl_ipv6(SIOCDIFADDR, (caddr_t)&ifreq);
718e3744 465
d62a17ae 466 return ret;
718e3744 467}
468#else /* LINUX_IPV6 */
6f0e3f6e 469#ifdef HAVE_STRUCT_IN6_ALIASREQ
718e3744 470#ifndef ND6_INFINITE_LIFETIME
471#define ND6_INFINITE_LIFETIME 0xffffffffL
472#endif /* ND6_INFINITE_LIFETIME */
d62a17ae 473int if_prefix_add_ipv6(struct interface *ifp, struct connected *ifc)
718e3744 474{
d62a17ae 475 int ret;
476 struct in6_aliasreq addreq;
477 struct sockaddr_in6 addr;
478 struct sockaddr_in6 mask;
479 struct prefix_ipv6 *p;
718e3744 480
d62a17ae 481 p = (struct prefix_ipv6 *)ifc->address;
718e3744 482
d62a17ae 483 memset(&addreq, 0, sizeof addreq);
484 strncpy((char *)&addreq.ifra_name, ifp->name, sizeof addreq.ifra_name);
718e3744 485
d62a17ae 486 memset(&addr, 0, sizeof(struct sockaddr_in6));
487 addr.sin6_addr = p->prefix;
488 addr.sin6_family = p->family;
6f0e3f6e 489#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
d62a17ae 490 addr.sin6_len = sizeof(struct sockaddr_in6);
718e3744 491#endif
d62a17ae 492 memcpy(&addreq.ifra_addr, &addr, sizeof(struct sockaddr_in6));
718e3744 493
d62a17ae 494 memset(&mask, 0, sizeof(struct sockaddr_in6));
495 masklen2ip6(p->prefixlen, &mask.sin6_addr);
496 mask.sin6_family = p->family;
6f0e3f6e 497#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
d62a17ae 498 mask.sin6_len = sizeof(struct sockaddr_in6);
718e3744 499#endif
d62a17ae 500 memcpy(&addreq.ifra_prefixmask, &mask, sizeof(struct sockaddr_in6));
501
502 addreq.ifra_lifetime.ia6t_vltime = 0xffffffff;
503 addreq.ifra_lifetime.ia6t_pltime = 0xffffffff;
504
505#ifdef HAVE_STRUCT_IF6_ALIASREQ_IFRA_LIFETIME
506 addreq.ifra_lifetime.ia6t_pltime = ND6_INFINITE_LIFETIME;
507 addreq.ifra_lifetime.ia6t_vltime = ND6_INFINITE_LIFETIME;
726f9b2b 508#endif
718e3744 509
d62a17ae 510 ret = if_ioctl_ipv6(SIOCAIFADDR_IN6, (caddr_t)&addreq);
511 if (ret < 0)
512 return ret;
513 return 0;
718e3744 514}
515
d62a17ae 516int if_prefix_delete_ipv6(struct interface *ifp, struct connected *ifc)
718e3744 517{
d62a17ae 518 int ret;
519 struct in6_aliasreq addreq;
520 struct sockaddr_in6 addr;
521 struct sockaddr_in6 mask;
522 struct prefix_ipv6 *p;
718e3744 523
d62a17ae 524 p = (struct prefix_ipv6 *)ifc->address;
718e3744 525
d62a17ae 526 memset(&addreq, 0, sizeof addreq);
527 strncpy((char *)&addreq.ifra_name, ifp->name, sizeof addreq.ifra_name);
718e3744 528
d62a17ae 529 memset(&addr, 0, sizeof(struct sockaddr_in6));
530 addr.sin6_addr = p->prefix;
531 addr.sin6_family = p->family;
6f0e3f6e 532#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
d62a17ae 533 addr.sin6_len = sizeof(struct sockaddr_in6);
718e3744 534#endif
d62a17ae 535 memcpy(&addreq.ifra_addr, &addr, sizeof(struct sockaddr_in6));
718e3744 536
d62a17ae 537 memset(&mask, 0, sizeof(struct sockaddr_in6));
538 masklen2ip6(p->prefixlen, &mask.sin6_addr);
539 mask.sin6_family = p->family;
6f0e3f6e 540#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
d62a17ae 541 mask.sin6_len = sizeof(struct sockaddr_in6);
718e3744 542#endif
d62a17ae 543 memcpy(&addreq.ifra_prefixmask, &mask, sizeof(struct sockaddr_in6));
718e3744 544
6f0e3f6e 545#ifdef HAVE_STRUCT_IF6_ALIASREQ_IFRA_LIFETIME
d62a17ae 546 addreq.ifra_lifetime.ia6t_pltime = ND6_INFINITE_LIFETIME;
547 addreq.ifra_lifetime.ia6t_vltime = ND6_INFINITE_LIFETIME;
726f9b2b 548#endif
718e3744 549
d62a17ae 550 ret = if_ioctl_ipv6(SIOCDIFADDR_IN6, (caddr_t)&addreq);
551 if (ret < 0)
552 return ret;
553 return 0;
718e3744 554}
555#else
d62a17ae 556int if_prefix_add_ipv6(struct interface *ifp, struct connected *ifc)
718e3744 557{
d62a17ae 558 return 0;
718e3744 559}
560
d62a17ae 561int if_prefix_delete_ipv6(struct interface *ifp, struct connected *ifc)
718e3744 562{
d62a17ae 563 return 0;
718e3744 564}
6f0e3f6e 565#endif /* HAVE_STRUCT_IN6_ALIASREQ */
718e3744 566
567#endif /* LINUX_IPV6 */
ddfeb486
DL
568
569#endif /* !SUNOS_5 */