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