qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

tap-solaris.c (6910B)


      1 /*
      2  * QEMU System Emulator
      3  *
      4  * Copyright (c) 2003-2008 Fabrice Bellard
      5  *
      6  * Permission is hereby granted, free of charge, to any person obtaining a copy
      7  * of this software and associated documentation files (the "Software"), to deal
      8  * in the Software without restriction, including without limitation the rights
      9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     10  * copies of the Software, and to permit persons to whom the Software is
     11  * furnished to do so, subject to the following conditions:
     12  *
     13  * The above copyright notice and this permission notice shall be included in
     14  * all copies or substantial portions of the Software.
     15  *
     16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
     19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
     22  * THE SOFTWARE.
     23  */
     24 
     25 #include "qemu/osdep.h"
     26 #include "qapi/error.h"
     27 #include "tap_int.h"
     28 #include "qemu/ctype.h"
     29 #include "qemu/cutils.h"
     30 
     31 #include <sys/ethernet.h>
     32 #include <sys/sockio.h>
     33 #include <netinet/arp.h>
     34 #include <netinet/in.h>
     35 #include <netinet/in_systm.h>
     36 #include <netinet/ip.h>
     37 #include <netinet/ip_icmp.h> // must come after ip.h
     38 #include <netinet/udp.h>
     39 #include <netinet/tcp.h>
     40 #include <net/if.h>
     41 #include <stropts.h>
     42 #include "qemu/error-report.h"
     43 
     44 ssize_t tap_read_packet(int tapfd, uint8_t *buf, int maxlen)
     45 {
     46     struct strbuf sbuf;
     47     int f = 0;
     48 
     49     sbuf.maxlen = maxlen;
     50     sbuf.buf = (char *)buf;
     51 
     52     return getmsg(tapfd, NULL, &sbuf, &f) >= 0 ? sbuf.len : -1;
     53 }
     54 
     55 #define TUNNEWPPA       (('T'<<16) | 0x0001)
     56 /*
     57  * Allocate TAP device, returns opened fd.
     58  * Stores dev name in the first arg(must be large enough).
     59  */
     60 static int tap_alloc(char *dev, size_t dev_size, Error **errp)
     61 {
     62     /* FIXME leaks like a sieve on error paths */
     63     /* FIXME suspicious: many errors are reported, then ignored */
     64     int tap_fd, if_fd, ppa = -1;
     65     static int ip_fd = 0;
     66     char *ptr;
     67 
     68     static int arp_fd = 0;
     69     int ip_muxid, arp_muxid;
     70     struct strioctl  strioc_if, strioc_ppa;
     71     int link_type = I_PLINK;
     72     struct lifreq ifr;
     73     char actual_name[32] = "";
     74 
     75     memset(&ifr, 0x0, sizeof(ifr));
     76 
     77     if( *dev ){
     78        ptr = dev;
     79        while( *ptr && !qemu_isdigit((int)*ptr) ) ptr++;
     80        ppa = atoi(ptr);
     81     }
     82 
     83     /* Check if IP device was opened */
     84     if( ip_fd )
     85        close(ip_fd);
     86 
     87     TFR(ip_fd = open("/dev/udp", O_RDWR, 0));
     88     if (ip_fd < 0) {
     89         error_setg(errp, "Can't open /dev/ip (actually /dev/udp)");
     90         return -1;
     91     }
     92 
     93     TFR(tap_fd = open("/dev/tap", O_RDWR, 0));
     94     if (tap_fd < 0) {
     95         error_setg(errp, "Can't open /dev/tap");
     96         return -1;
     97     }
     98 
     99     /* Assign a new PPA and get its unit number. */
    100     strioc_ppa.ic_cmd = TUNNEWPPA;
    101     strioc_ppa.ic_timout = 0;
    102     strioc_ppa.ic_len = sizeof(ppa);
    103     strioc_ppa.ic_dp = (char *)&ppa;
    104     if ((ppa = ioctl (tap_fd, I_STR, &strioc_ppa)) < 0)
    105         error_report("Can't assign new interface");
    106 
    107     TFR(if_fd = open("/dev/tap", O_RDWR, 0));
    108     if (if_fd < 0) {
    109         error_setg(errp, "Can't open /dev/tap (2)");
    110         return -1;
    111     }
    112     if(ioctl(if_fd, I_PUSH, "ip") < 0){
    113         error_setg(errp, "Can't push IP module");
    114         return -1;
    115     }
    116 
    117     if (ioctl(if_fd, SIOCGLIFFLAGS, &ifr) < 0)
    118         error_report("Can't get flags");
    119 
    120     snprintf (actual_name, 32, "tap%d", ppa);
    121     pstrcpy(ifr.lifr_name, sizeof(ifr.lifr_name), actual_name);
    122 
    123     ifr.lifr_ppa = ppa;
    124     /* Assign ppa according to the unit number returned by tun device */
    125 
    126     if (ioctl (if_fd, SIOCSLIFNAME, &ifr) < 0)
    127         error_report("Can't set PPA %d", ppa);
    128     if (ioctl(if_fd, SIOCGLIFFLAGS, &ifr) <0)
    129         error_report("Can't get flags");
    130     /* Push arp module to if_fd */
    131     if (ioctl (if_fd, I_PUSH, "arp") < 0)
    132         error_report("Can't push ARP module (2)");
    133 
    134     /* Push arp module to ip_fd */
    135     if (ioctl (ip_fd, I_POP, NULL) < 0)
    136         error_report("I_POP failed");
    137     if (ioctl (ip_fd, I_PUSH, "arp") < 0)
    138         error_report("Can't push ARP module (3)");
    139     /* Open arp_fd */
    140     TFR(arp_fd = open ("/dev/tap", O_RDWR, 0));
    141     if (arp_fd < 0)
    142         error_report("Can't open %s", "/dev/tap");
    143 
    144     /* Set ifname to arp */
    145     strioc_if.ic_cmd = SIOCSLIFNAME;
    146     strioc_if.ic_timout = 0;
    147     strioc_if.ic_len = sizeof(ifr);
    148     strioc_if.ic_dp = (char *)&ifr;
    149     if (ioctl(arp_fd, I_STR, &strioc_if) < 0){
    150         error_report("Can't set ifname to arp");
    151     }
    152 
    153     if((ip_muxid = ioctl(ip_fd, I_LINK, if_fd)) < 0){
    154         error_setg(errp, "Can't link TAP device to IP");
    155         return -1;
    156     }
    157 
    158     if ((arp_muxid = ioctl (ip_fd, link_type, arp_fd)) < 0)
    159         error_report("Can't link TAP device to ARP");
    160 
    161     close (if_fd);
    162 
    163     memset(&ifr, 0x0, sizeof(ifr));
    164     pstrcpy(ifr.lifr_name, sizeof(ifr.lifr_name), actual_name);
    165     ifr.lifr_ip_muxid  = ip_muxid;
    166     ifr.lifr_arp_muxid = arp_muxid;
    167 
    168     if (ioctl (ip_fd, SIOCSLIFMUXID, &ifr) < 0)
    169     {
    170       ioctl (ip_fd, I_PUNLINK , arp_muxid);
    171       ioctl (ip_fd, I_PUNLINK, ip_muxid);
    172       error_report("Can't set multiplexor id");
    173     }
    174 
    175     snprintf(dev, dev_size, "tap%d", ppa);
    176     return tap_fd;
    177 }
    178 
    179 int tap_open(char *ifname, int ifname_size, int *vnet_hdr,
    180              int vnet_hdr_required, int mq_required, Error **errp)
    181 {
    182     char  dev[10]="";
    183     int fd;
    184 
    185     fd = tap_alloc(dev, sizeof(dev), errp);
    186     if (fd < 0) {
    187         return -1;
    188     }
    189     pstrcpy(ifname, ifname_size, dev);
    190     if (*vnet_hdr) {
    191         /* Solaris doesn't have IFF_VNET_HDR */
    192         *vnet_hdr = 0;
    193 
    194         if (vnet_hdr_required && !*vnet_hdr) {
    195             error_setg(errp, "vnet_hdr=1 requested, but no kernel "
    196                        "support for IFF_VNET_HDR available");
    197             close(fd);
    198             return -1;
    199         }
    200     }
    201     g_unix_set_fd_nonblocking(fd, true, NULL);
    202     return fd;
    203 }
    204 
    205 void tap_set_sndbuf(int fd, const NetdevTapOptions *tap, Error **errp)
    206 {
    207 }
    208 
    209 int tap_probe_vnet_hdr(int fd, Error **errp)
    210 {
    211     return 0;
    212 }
    213 
    214 int tap_probe_has_ufo(int fd)
    215 {
    216     return 0;
    217 }
    218 
    219 int tap_probe_vnet_hdr_len(int fd, int len)
    220 {
    221     return 0;
    222 }
    223 
    224 void tap_fd_set_vnet_hdr_len(int fd, int len)
    225 {
    226 }
    227 
    228 int tap_fd_set_vnet_le(int fd, int is_le)
    229 {
    230     return -EINVAL;
    231 }
    232 
    233 int tap_fd_set_vnet_be(int fd, int is_be)
    234 {
    235     return -EINVAL;
    236 }
    237 
    238 void tap_fd_set_offload(int fd, int csum, int tso4,
    239                         int tso6, int ecn, int ufo)
    240 {
    241 }
    242 
    243 int tap_fd_enable(int fd)
    244 {
    245     return -1;
    246 }
    247 
    248 int tap_fd_disable(int fd)
    249 {
    250     return -1;
    251 }
    252 
    253 int tap_fd_get_ifname(int fd, char *ifname)
    254 {
    255     return -1;
    256 }
    257 
    258 int tap_fd_set_steering_ebpf(int fd, int prog_fd)
    259 {
    260     return -1;
    261 }