Annotation of embedaddon/quagga/zebra/ioctl.c, revision 1.1.1.2

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;
1.1.1.2 ! misho      55:   int err = 0;
1.1       misho      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;
1.1.1.2 ! misho      88:   int err = 0;
1.1       misho      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>