File:  [Qemu by Fabrice Bellard] / qemu / net.c
Revision 1.1.1.6 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 17:34:22 2018 UTC (3 years, 3 months ago) by root
Branches: qemu, MAIN
CVS tags: qemu0122, qemu0121, qemu0120, HEAD
qemu 0.12.0

    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: #include "net.h"
   25: 
   26: #include "config-host.h"
   27: 
   28: #include "net/tap.h"
   29: #include "net/socket.h"
   30: #include "net/dump.h"
   31: #include "net/slirp.h"
   32: #include "net/vde.h"
   33: #include "net/util.h"
   34: #include "monitor.h"
   35: #include "sysemu.h"
   36: #include "qemu-common.h"
   37: #include "qemu_socket.h"
   38: 
   39: static QTAILQ_HEAD(, VLANState) vlans;
   40: static QTAILQ_HEAD(, VLANClientState) non_vlan_clients;
   41: 
   42: int default_net = 1;
   43: 
   44: /***********************************************************/
   45: /* network device redirectors */
   46: 
   47: #if defined(DEBUG_NET)
   48: static void hex_dump(FILE *f, const uint8_t *buf, int size)
   49: {
   50:     int len, i, j, c;
   51: 
   52:     for(i=0;i<size;i+=16) {
   53:         len = size - i;
   54:         if (len > 16)
   55:             len = 16;
   56:         fprintf(f, "%08x ", i);
   57:         for(j=0;j<16;j++) {
   58:             if (j < len)
   59:                 fprintf(f, " %02x", buf[i+j]);
   60:             else
   61:                 fprintf(f, "   ");
   62:         }
   63:         fprintf(f, " ");
   64:         for(j=0;j<len;j++) {
   65:             c = buf[i+j];
   66:             if (c < ' ' || c > '~')
   67:                 c = '.';
   68:             fprintf(f, "%c", c);
   69:         }
   70:         fprintf(f, "\n");
   71:     }
   72: }
   73: #endif
   74: 
   75: static int get_str_sep(char *buf, int buf_size, const char **pp, int sep)
   76: {
   77:     const char *p, *p1;
   78:     int len;
   79:     p = *pp;
   80:     p1 = strchr(p, sep);
   81:     if (!p1)
   82:         return -1;
   83:     len = p1 - p;
   84:     p1++;
   85:     if (buf_size > 0) {
   86:         if (len > buf_size - 1)
   87:             len = buf_size - 1;
   88:         memcpy(buf, p, len);
   89:         buf[len] = '\0';
   90:     }
   91:     *pp = p1;
   92:     return 0;
   93: }
   94: 
   95: int parse_host_src_port(struct sockaddr_in *haddr,
   96:                         struct sockaddr_in *saddr,
   97:                         const char *input_str)
   98: {
   99:     char *str = strdup(input_str);
  100:     char *host_str = str;
  101:     char *src_str;
  102:     const char *src_str2;
  103:     char *ptr;
  104: 
  105:     /*
  106:      * Chop off any extra arguments at the end of the string which
  107:      * would start with a comma, then fill in the src port information
  108:      * if it was provided else use the "any address" and "any port".
  109:      */
  110:     if ((ptr = strchr(str,',')))
  111:         *ptr = '\0';
  112: 
  113:     if ((src_str = strchr(input_str,'@'))) {
  114:         *src_str = '\0';
  115:         src_str++;
  116:     }
  117: 
  118:     if (parse_host_port(haddr, host_str) < 0)
  119:         goto fail;
  120: 
  121:     src_str2 = src_str;
  122:     if (!src_str || *src_str == '\0')
  123:         src_str2 = ":0";
  124: 
  125:     if (parse_host_port(saddr, src_str2) < 0)
  126:         goto fail;
  127: 
  128:     free(str);
  129:     return(0);
  130: 
  131: fail:
  132:     free(str);
  133:     return -1;
  134: }
  135: 
  136: int parse_host_port(struct sockaddr_in *saddr, const char *str)
  137: {
  138:     char buf[512];
  139:     struct hostent *he;
  140:     const char *p, *r;
  141:     int port;
  142: 
  143:     p = str;
  144:     if (get_str_sep(buf, sizeof(buf), &p, ':') < 0)
  145:         return -1;
  146:     saddr->sin_family = AF_INET;
  147:     if (buf[0] == '\0') {
  148:         saddr->sin_addr.s_addr = 0;
  149:     } else {
  150:         if (qemu_isdigit(buf[0])) {
  151:             if (!inet_aton(buf, &saddr->sin_addr))
  152:                 return -1;
  153:         } else {
  154:             if ((he = gethostbyname(buf)) == NULL)
  155:                 return - 1;
  156:             saddr->sin_addr = *(struct in_addr *)he->h_addr;
  157:         }
  158:     }
  159:     port = strtol(p, (char **)&r, 0);
  160:     if (r == p)
  161:         return -1;
  162:     saddr->sin_port = htons(port);
  163:     return 0;
  164: }
  165: 
  166: void qemu_format_nic_info_str(VLANClientState *vc, uint8_t macaddr[6])
  167: {
  168:     snprintf(vc->info_str, sizeof(vc->info_str),
  169:              "model=%s,macaddr=%02x:%02x:%02x:%02x:%02x:%02x",
  170:              vc->model,
  171:              macaddr[0], macaddr[1], macaddr[2],
  172:              macaddr[3], macaddr[4], macaddr[5]);
  173: }
  174: 
  175: void qemu_macaddr_default_if_unset(MACAddr *macaddr)
  176: {
  177:     static int index = 0;
  178:     static const MACAddr zero = { .a = { 0,0,0,0,0,0 } };
  179: 
  180:     if (memcmp(macaddr, &zero, sizeof(zero)) != 0)
  181:         return;
  182:     macaddr->a[0] = 0x52;
  183:     macaddr->a[1] = 0x54;
  184:     macaddr->a[2] = 0x00;
  185:     macaddr->a[3] = 0x12;
  186:     macaddr->a[4] = 0x34;
  187:     macaddr->a[5] = 0x56 + index++;
  188: }
  189: 
  190: static char *assign_name(VLANClientState *vc1, const char *model)
  191: {
  192:     VLANState *vlan;
  193:     char buf[256];
  194:     int id = 0;
  195: 
  196:     QTAILQ_FOREACH(vlan, &vlans, next) {
  197:         VLANClientState *vc;
  198: 
  199:         QTAILQ_FOREACH(vc, &vlan->clients, next) {
  200:             if (vc != vc1 && strcmp(vc->model, model) == 0) {
  201:                 id++;
  202:             }
  203:         }
  204:     }
  205: 
  206:     snprintf(buf, sizeof(buf), "%s.%d", model, id);
  207: 
  208:     return qemu_strdup(buf);
  209: }
  210: 
  211: static ssize_t qemu_deliver_packet(VLANClientState *sender,
  212:                                    unsigned flags,
  213:                                    const uint8_t *data,
  214:                                    size_t size,
  215:                                    void *opaque);
  216: static ssize_t qemu_deliver_packet_iov(VLANClientState *sender,
  217:                                        unsigned flags,
  218:                                        const struct iovec *iov,
  219:                                        int iovcnt,
  220:                                        void *opaque);
  221: 
  222: VLANClientState *qemu_new_net_client(NetClientInfo *info,
  223:                                      VLANState *vlan,
  224:                                      VLANClientState *peer,
  225:                                      const char *model,
  226:                                      const char *name)
  227: {
  228:     VLANClientState *vc;
  229: 
  230:     assert(info->size >= sizeof(VLANClientState));
  231: 
  232:     vc = qemu_mallocz(info->size);
  233: 
  234:     vc->info = info;
  235:     vc->model = qemu_strdup(model);
  236:     if (name) {
  237:         vc->name = qemu_strdup(name);
  238:     } else {
  239:         vc->name = assign_name(vc, model);
  240:     }
  241: 
  242:     if (vlan) {
  243:         assert(!peer);
  244:         vc->vlan = vlan;
  245:         QTAILQ_INSERT_TAIL(&vc->vlan->clients, vc, next);
  246:     } else {
  247:         if (peer) {
  248:             vc->peer = peer;
  249:             peer->peer = vc;
  250:         }
  251:         QTAILQ_INSERT_TAIL(&non_vlan_clients, vc, next);
  252: 
  253:         vc->send_queue = qemu_new_net_queue(qemu_deliver_packet,
  254:                                             qemu_deliver_packet_iov,
  255:                                             vc);
  256:     }
  257: 
  258:     return vc;
  259: }
  260: 
  261: NICState *qemu_new_nic(NetClientInfo *info,
  262:                        NICConf *conf,
  263:                        const char *model,
  264:                        const char *name,
  265:                        void *opaque)
  266: {
  267:     VLANClientState *nc;
  268:     NICState *nic;
  269: 
  270:     assert(info->type == NET_CLIENT_TYPE_NIC);
  271:     assert(info->size >= sizeof(NICState));
  272: 
  273:     nc = qemu_new_net_client(info, conf->vlan, conf->peer, model, name);
  274: 
  275:     nic = DO_UPCAST(NICState, nc, nc);
  276:     nic->conf = conf;
  277:     nic->opaque = opaque;
  278: 
  279:     return nic;
  280: }
  281: 
  282: void qemu_del_vlan_client(VLANClientState *vc)
  283: {
  284:     if (vc->vlan) {
  285:         QTAILQ_REMOVE(&vc->vlan->clients, vc, next);
  286:     } else {
  287:         if (vc->send_queue) {
  288:             qemu_del_net_queue(vc->send_queue);
  289:         }
  290:         QTAILQ_REMOVE(&non_vlan_clients, vc, next);
  291:         if (vc->peer) {
  292:             vc->peer->peer = NULL;
  293:         }
  294:     }
  295: 
  296:     if (vc->info->cleanup) {
  297:         vc->info->cleanup(vc);
  298:     }
  299: 
  300:     qemu_free(vc->name);
  301:     qemu_free(vc->model);
  302:     qemu_free(vc);
  303: }
  304: 
  305: VLANClientState *
  306: qemu_find_vlan_client_by_name(Monitor *mon, int vlan_id,
  307:                               const char *client_str)
  308: {
  309:     VLANState *vlan;
  310:     VLANClientState *vc;
  311: 
  312:     vlan = qemu_find_vlan(vlan_id, 0);
  313:     if (!vlan) {
  314:         monitor_printf(mon, "unknown VLAN %d\n", vlan_id);
  315:         return NULL;
  316:     }
  317: 
  318:     QTAILQ_FOREACH(vc, &vlan->clients, next) {
  319:         if (!strcmp(vc->name, client_str)) {
  320:             break;
  321:         }
  322:     }
  323:     if (!vc) {
  324:         monitor_printf(mon, "can't find device %s on VLAN %d\n",
  325:                        client_str, vlan_id);
  326:     }
  327: 
  328:     return vc;
  329: }
  330: 
  331: void qemu_foreach_nic(qemu_nic_foreach func, void *opaque)
  332: {
  333:     VLANClientState *nc;
  334:     VLANState *vlan;
  335: 
  336:     QTAILQ_FOREACH(nc, &non_vlan_clients, next) {
  337:         if (nc->info->type == NET_CLIENT_TYPE_NIC) {
  338:             func(DO_UPCAST(NICState, nc, nc), opaque);
  339:         }
  340:     }
  341: 
  342:     QTAILQ_FOREACH(vlan, &vlans, next) {
  343:         QTAILQ_FOREACH(nc, &vlan->clients, next) {
  344:             if (nc->info->type == NET_CLIENT_TYPE_NIC) {
  345:                 func(DO_UPCAST(NICState, nc, nc), opaque);
  346:             }
  347:         }
  348:     }
  349: }
  350: 
  351: int qemu_can_send_packet(VLANClientState *sender)
  352: {
  353:     VLANState *vlan = sender->vlan;
  354:     VLANClientState *vc;
  355: 
  356:     if (sender->peer) {
  357:         if (sender->peer->receive_disabled) {
  358:             return 0;
  359:         } else if (sender->peer->info->can_receive &&
  360:                    !sender->peer->info->can_receive(sender->peer)) {
  361:             return 0;
  362:         } else {
  363:             return 1;
  364:         }
  365:     }
  366: 
  367:     if (!sender->vlan) {
  368:         return 1;
  369:     }
  370: 
  371:     QTAILQ_FOREACH(vc, &vlan->clients, next) {
  372:         if (vc == sender) {
  373:             continue;
  374:         }
  375: 
  376:         /* no can_receive() handler, they can always receive */
  377:         if (!vc->info->can_receive || vc->info->can_receive(vc)) {
  378:             return 1;
  379:         }
  380:     }
  381:     return 0;
  382: }
  383: 
  384: static ssize_t qemu_deliver_packet(VLANClientState *sender,
  385:                                    unsigned flags,
  386:                                    const uint8_t *data,
  387:                                    size_t size,
  388:                                    void *opaque)
  389: {
  390:     VLANClientState *vc = opaque;
  391:     ssize_t ret;
  392: 
  393:     if (vc->link_down) {
  394:         return size;
  395:     }
  396: 
  397:     if (vc->receive_disabled) {
  398:         return 0;
  399:     }
  400: 
  401:     if (flags & QEMU_NET_PACKET_FLAG_RAW && vc->info->receive_raw) {
  402:         ret = vc->info->receive_raw(vc, data, size);
  403:     } else {
  404:         ret = vc->info->receive(vc, data, size);
  405:     }
  406: 
  407:     if (ret == 0) {
  408:         vc->receive_disabled = 1;
  409:     };
  410: 
  411:     return ret;
  412: }
  413: 
  414: static ssize_t qemu_vlan_deliver_packet(VLANClientState *sender,
  415:                                         unsigned flags,
  416:                                         const uint8_t *buf,
  417:                                         size_t size,
  418:                                         void *opaque)
  419: {
  420:     VLANState *vlan = opaque;
  421:     VLANClientState *vc;
  422:     ssize_t ret = -1;
  423: 
  424:     QTAILQ_FOREACH(vc, &vlan->clients, next) {
  425:         ssize_t len;
  426: 
  427:         if (vc == sender) {
  428:             continue;
  429:         }
  430: 
  431:         if (vc->link_down) {
  432:             ret = size;
  433:             continue;
  434:         }
  435: 
  436:         if (vc->receive_disabled) {
  437:             ret = 0;
  438:             continue;
  439:         }
  440: 
  441:         if (flags & QEMU_NET_PACKET_FLAG_RAW && vc->info->receive_raw) {
  442:             len = vc->info->receive_raw(vc, buf, size);
  443:         } else {
  444:             len = vc->info->receive(vc, buf, size);
  445:         }
  446: 
  447:         if (len == 0) {
  448:             vc->receive_disabled = 1;
  449:         }
  450: 
  451:         ret = (ret >= 0) ? ret : len;
  452: 
  453:     }
  454: 
  455:     return ret;
  456: }
  457: 
  458: void qemu_purge_queued_packets(VLANClientState *vc)
  459: {
  460:     NetQueue *queue;
  461: 
  462:     if (!vc->peer && !vc->vlan) {
  463:         return;
  464:     }
  465: 
  466:     if (vc->peer) {
  467:         queue = vc->peer->send_queue;
  468:     } else {
  469:         queue = vc->vlan->send_queue;
  470:     }
  471: 
  472:     qemu_net_queue_purge(queue, vc);
  473: }
  474: 
  475: void qemu_flush_queued_packets(VLANClientState *vc)
  476: {
  477:     NetQueue *queue;
  478: 
  479:     vc->receive_disabled = 0;
  480: 
  481:     if (vc->vlan) {
  482:         queue = vc->vlan->send_queue;
  483:     } else {
  484:         queue = vc->send_queue;
  485:     }
  486: 
  487:     qemu_net_queue_flush(queue);
  488: }
  489: 
  490: static ssize_t qemu_send_packet_async_with_flags(VLANClientState *sender,
  491:                                                  unsigned flags,
  492:                                                  const uint8_t *buf, int size,
  493:                                                  NetPacketSent *sent_cb)
  494: {
  495:     NetQueue *queue;
  496: 
  497: #ifdef DEBUG_NET
  498:     printf("qemu_send_packet_async:\n");
  499:     hex_dump(stdout, buf, size);
  500: #endif
  501: 
  502:     if (sender->link_down || (!sender->peer && !sender->vlan)) {
  503:         return size;
  504:     }
  505: 
  506:     if (sender->peer) {
  507:         queue = sender->peer->send_queue;
  508:     } else {
  509:         queue = sender->vlan->send_queue;
  510:     }
  511: 
  512:     return qemu_net_queue_send(queue, sender, flags, buf, size, sent_cb);
  513: }
  514: 
  515: ssize_t qemu_send_packet_async(VLANClientState *sender,
  516:                                const uint8_t *buf, int size,
  517:                                NetPacketSent *sent_cb)
  518: {
  519:     return qemu_send_packet_async_with_flags(sender, QEMU_NET_PACKET_FLAG_NONE,
  520:                                              buf, size, sent_cb);
  521: }
  522: 
  523: void qemu_send_packet(VLANClientState *vc, const uint8_t *buf, int size)
  524: {
  525:     qemu_send_packet_async(vc, buf, size, NULL);
  526: }
  527: 
  528: ssize_t qemu_send_packet_raw(VLANClientState *vc, const uint8_t *buf, int size)
  529: {
  530:     return qemu_send_packet_async_with_flags(vc, QEMU_NET_PACKET_FLAG_RAW,
  531:                                              buf, size, NULL);
  532: }
  533: 
  534: static ssize_t vc_sendv_compat(VLANClientState *vc, const struct iovec *iov,
  535:                                int iovcnt)
  536: {
  537:     uint8_t buffer[4096];
  538:     size_t offset = 0;
  539:     int i;
  540: 
  541:     for (i = 0; i < iovcnt; i++) {
  542:         size_t len;
  543: 
  544:         len = MIN(sizeof(buffer) - offset, iov[i].iov_len);
  545:         memcpy(buffer + offset, iov[i].iov_base, len);
  546:         offset += len;
  547:     }
  548: 
  549:     return vc->info->receive(vc, buffer, offset);
  550: }
  551: 
  552: static ssize_t calc_iov_length(const struct iovec *iov, int iovcnt)
  553: {
  554:     size_t offset = 0;
  555:     int i;
  556: 
  557:     for (i = 0; i < iovcnt; i++)
  558:         offset += iov[i].iov_len;
  559:     return offset;
  560: }
  561: 
  562: static ssize_t qemu_deliver_packet_iov(VLANClientState *sender,
  563:                                        unsigned flags,
  564:                                        const struct iovec *iov,
  565:                                        int iovcnt,
  566:                                        void *opaque)
  567: {
  568:     VLANClientState *vc = opaque;
  569: 
  570:     if (vc->link_down) {
  571:         return calc_iov_length(iov, iovcnt);
  572:     }
  573: 
  574:     if (vc->info->receive_iov) {
  575:         return vc->info->receive_iov(vc, iov, iovcnt);
  576:     } else {
  577:         return vc_sendv_compat(vc, iov, iovcnt);
  578:     }
  579: }
  580: 
  581: static ssize_t qemu_vlan_deliver_packet_iov(VLANClientState *sender,
  582:                                             unsigned flags,
  583:                                             const struct iovec *iov,
  584:                                             int iovcnt,
  585:                                             void *opaque)
  586: {
  587:     VLANState *vlan = opaque;
  588:     VLANClientState *vc;
  589:     ssize_t ret = -1;
  590: 
  591:     QTAILQ_FOREACH(vc, &vlan->clients, next) {
  592:         ssize_t len;
  593: 
  594:         if (vc == sender) {
  595:             continue;
  596:         }
  597: 
  598:         if (vc->link_down) {
  599:             ret = calc_iov_length(iov, iovcnt);
  600:             continue;
  601:         }
  602: 
  603:         assert(!(flags & QEMU_NET_PACKET_FLAG_RAW));
  604: 
  605:         if (vc->info->receive_iov) {
  606:             len = vc->info->receive_iov(vc, iov, iovcnt);
  607:         } else {
  608:             len = vc_sendv_compat(vc, iov, iovcnt);
  609:         }
  610: 
  611:         ret = (ret >= 0) ? ret : len;
  612:     }
  613: 
  614:     return ret;
  615: }
  616: 
  617: ssize_t qemu_sendv_packet_async(VLANClientState *sender,
  618:                                 const struct iovec *iov, int iovcnt,
  619:                                 NetPacketSent *sent_cb)
  620: {
  621:     NetQueue *queue;
  622: 
  623:     if (sender->link_down || (!sender->peer && !sender->vlan)) {
  624:         return calc_iov_length(iov, iovcnt);
  625:     }
  626: 
  627:     if (sender->peer) {
  628:         queue = sender->peer->send_queue;
  629:     } else {
  630:         queue = sender->vlan->send_queue;
  631:     }
  632: 
  633:     return qemu_net_queue_send_iov(queue, sender,
  634:                                    QEMU_NET_PACKET_FLAG_NONE,
  635:                                    iov, iovcnt, sent_cb);
  636: }
  637: 
  638: ssize_t
  639: qemu_sendv_packet(VLANClientState *vc, const struct iovec *iov, int iovcnt)
  640: {
  641:     return qemu_sendv_packet_async(vc, iov, iovcnt, NULL);
  642: }
  643: 
  644: /* find or alloc a new VLAN */
  645: VLANState *qemu_find_vlan(int id, int allocate)
  646: {
  647:     VLANState *vlan;
  648: 
  649:     QTAILQ_FOREACH(vlan, &vlans, next) {
  650:         if (vlan->id == id) {
  651:             return vlan;
  652:         }
  653:     }
  654: 
  655:     if (!allocate) {
  656:         return NULL;
  657:     }
  658: 
  659:     vlan = qemu_mallocz(sizeof(VLANState));
  660:     vlan->id = id;
  661:     QTAILQ_INIT(&vlan->clients);
  662: 
  663:     vlan->send_queue = qemu_new_net_queue(qemu_vlan_deliver_packet,
  664:                                           qemu_vlan_deliver_packet_iov,
  665:                                           vlan);
  666: 
  667:     QTAILQ_INSERT_TAIL(&vlans, vlan, next);
  668: 
  669:     return vlan;
  670: }
  671: 
  672: VLANClientState *qemu_find_netdev(const char *id)
  673: {
  674:     VLANClientState *vc;
  675: 
  676:     QTAILQ_FOREACH(vc, &non_vlan_clients, next) {
  677:         if (!strcmp(vc->name, id)) {
  678:             return vc;
  679:         }
  680:     }
  681: 
  682:     return NULL;
  683: }
  684: 
  685: static int nic_get_free_idx(void)
  686: {
  687:     int index;
  688: 
  689:     for (index = 0; index < MAX_NICS; index++)
  690:         if (!nd_table[index].used)
  691:             return index;
  692:     return -1;
  693: }
  694: 
  695: int qemu_show_nic_models(const char *arg, const char *const *models)
  696: {
  697:     int i;
  698: 
  699:     if (!arg || strcmp(arg, "?"))
  700:         return 0;
  701: 
  702:     fprintf(stderr, "qemu: Supported NIC models: ");
  703:     for (i = 0 ; models[i]; i++)
  704:         fprintf(stderr, "%s%c", models[i], models[i+1] ? ',' : '\n');
  705:     return 1;
  706: }
  707: 
  708: void qemu_check_nic_model(NICInfo *nd, const char *model)
  709: {
  710:     const char *models[2];
  711: 
  712:     models[0] = model;
  713:     models[1] = NULL;
  714: 
  715:     if (qemu_show_nic_models(nd->model, models))
  716:         exit(0);
  717:     if (qemu_find_nic_model(nd, models, model) < 0)
  718:         exit(1);
  719: }
  720: 
  721: int qemu_find_nic_model(NICInfo *nd, const char * const *models,
  722:                         const char *default_model)
  723: {
  724:     int i;
  725: 
  726:     if (!nd->model)
  727:         nd->model = qemu_strdup(default_model);
  728: 
  729:     for (i = 0 ; models[i]; i++) {
  730:         if (strcmp(nd->model, models[i]) == 0)
  731:             return i;
  732:     }
  733: 
  734:     qemu_error("qemu: Unsupported NIC model: %s\n", nd->model);
  735:     return -1;
  736: }
  737: 
  738: int net_handle_fd_param(Monitor *mon, const char *param)
  739: {
  740:     if (!qemu_isdigit(param[0])) {
  741:         int fd;
  742: 
  743:         fd = monitor_get_fd(mon, param);
  744:         if (fd == -1) {
  745:             qemu_error("No file descriptor named %s found", param);
  746:             return -1;
  747:         }
  748: 
  749:         return fd;
  750:     } else {
  751:         return strtol(param, NULL, 0);
  752:     }
  753: }
  754: 
  755: static int net_init_nic(QemuOpts *opts,
  756:                         Monitor *mon,
  757:                         const char *name,
  758:                         VLANState *vlan)
  759: {
  760:     int idx;
  761:     NICInfo *nd;
  762:     const char *netdev;
  763: 
  764:     idx = nic_get_free_idx();
  765:     if (idx == -1 || nb_nics >= MAX_NICS) {
  766:         qemu_error("Too Many NICs\n");
  767:         return -1;
  768:     }
  769: 
  770:     nd = &nd_table[idx];
  771: 
  772:     memset(nd, 0, sizeof(*nd));
  773: 
  774:     if ((netdev = qemu_opt_get(opts, "netdev"))) {
  775:         nd->netdev = qemu_find_netdev(netdev);
  776:         if (!nd->netdev) {
  777:             qemu_error("netdev '%s' not found\n", netdev);
  778:             return -1;
  779:         }
  780:     } else {
  781:         assert(vlan);
  782:         nd->vlan = vlan;
  783:     }
  784:     if (name) {
  785:         nd->name = qemu_strdup(name);
  786:     }
  787:     if (qemu_opt_get(opts, "model")) {
  788:         nd->model = qemu_strdup(qemu_opt_get(opts, "model"));
  789:     }
  790:     if (qemu_opt_get(opts, "addr")) {
  791:         nd->devaddr = qemu_strdup(qemu_opt_get(opts, "addr"));
  792:     }
  793: 
  794:     nd->macaddr[0] = 0x52;
  795:     nd->macaddr[1] = 0x54;
  796:     nd->macaddr[2] = 0x00;
  797:     nd->macaddr[3] = 0x12;
  798:     nd->macaddr[4] = 0x34;
  799:     nd->macaddr[5] = 0x56 + idx;
  800: 
  801:     if (qemu_opt_get(opts, "macaddr") &&
  802:         net_parse_macaddr(nd->macaddr, qemu_opt_get(opts, "macaddr")) < 0) {
  803:         qemu_error("invalid syntax for ethernet address\n");
  804:         return -1;
  805:     }
  806: 
  807:     nd->nvectors = qemu_opt_get_number(opts, "vectors", NIC_NVECTORS_UNSPECIFIED);
  808:     if (nd->nvectors != NIC_NVECTORS_UNSPECIFIED &&
  809:         (nd->nvectors < 0 || nd->nvectors > 0x7ffffff)) {
  810:         qemu_error("invalid # of vectors: %d\n", nd->nvectors);
  811:         return -1;
  812:     }
  813: 
  814:     nd->used = 1;
  815:     if (vlan) {
  816:         nd->vlan->nb_guest_devs++;
  817:     }
  818:     nb_nics++;
  819: 
  820:     return idx;
  821: }
  822: 
  823: #define NET_COMMON_PARAMS_DESC                     \
  824:     {                                              \
  825:         .name = "type",                            \
  826:         .type = QEMU_OPT_STRING,                   \
  827:         .help = "net client type (nic, tap etc.)", \
  828:      }, {                                          \
  829:         .name = "vlan",                            \
  830:         .type = QEMU_OPT_NUMBER,                   \
  831:         .help = "vlan number",                     \
  832:      }, {                                          \
  833:         .name = "name",                            \
  834:         .type = QEMU_OPT_STRING,                   \
  835:         .help = "identifier for monitor commands", \
  836:      }
  837: 
  838: typedef int (*net_client_init_func)(QemuOpts *opts,
  839:                                     Monitor *mon,
  840:                                     const char *name,
  841:                                     VLANState *vlan);
  842: 
  843: /* magic number, but compiler will warn if too small */
  844: #define NET_MAX_DESC 20
  845: 
  846: static struct {
  847:     const char *type;
  848:     net_client_init_func init;
  849:     QemuOptDesc desc[NET_MAX_DESC];
  850: } net_client_types[] = {
  851:     {
  852:         .type = "none",
  853:         .desc = {
  854:             NET_COMMON_PARAMS_DESC,
  855:             { /* end of list */ }
  856:         },
  857:     }, {
  858:         .type = "nic",
  859:         .init = net_init_nic,
  860:         .desc = {
  861:             NET_COMMON_PARAMS_DESC,
  862:             {
  863:                 .name = "netdev",
  864:                 .type = QEMU_OPT_STRING,
  865:                 .help = "id of -netdev to connect to",
  866:             },
  867:             {
  868:                 .name = "macaddr",
  869:                 .type = QEMU_OPT_STRING,
  870:                 .help = "MAC address",
  871:             }, {
  872:                 .name = "model",
  873:                 .type = QEMU_OPT_STRING,
  874:                 .help = "device model (e1000, rtl8139, virtio etc.)",
  875:             }, {
  876:                 .name = "addr",
  877:                 .type = QEMU_OPT_STRING,
  878:                 .help = "PCI device address",
  879:             }, {
  880:                 .name = "vectors",
  881:                 .type = QEMU_OPT_NUMBER,
  882:                 .help = "number of MSI-x vectors, 0 to disable MSI-X",
  883:             },
  884:             { /* end of list */ }
  885:         },
  886: #ifdef CONFIG_SLIRP
  887:     }, {
  888:         .type = "user",
  889:         .init = net_init_slirp,
  890:         .desc = {
  891:             NET_COMMON_PARAMS_DESC,
  892:             {
  893:                 .name = "hostname",
  894:                 .type = QEMU_OPT_STRING,
  895:                 .help = "client hostname reported by the builtin DHCP server",
  896:             }, {
  897:                 .name = "restrict",
  898:                 .type = QEMU_OPT_STRING,
  899:                 .help = "isolate the guest from the host (y|yes|n|no)",
  900:             }, {
  901:                 .name = "ip",
  902:                 .type = QEMU_OPT_STRING,
  903:                 .help = "legacy parameter, use net= instead",
  904:             }, {
  905:                 .name = "net",
  906:                 .type = QEMU_OPT_STRING,
  907:                 .help = "IP address and optional netmask",
  908:             }, {
  909:                 .name = "host",
  910:                 .type = QEMU_OPT_STRING,
  911:                 .help = "guest-visible address of the host",
  912:             }, {
  913:                 .name = "tftp",
  914:                 .type = QEMU_OPT_STRING,
  915:                 .help = "root directory of the built-in TFTP server",
  916:             }, {
  917:                 .name = "bootfile",
  918:                 .type = QEMU_OPT_STRING,
  919:                 .help = "BOOTP filename, for use with tftp=",
  920:             }, {
  921:                 .name = "dhcpstart",
  922:                 .type = QEMU_OPT_STRING,
  923:                 .help = "the first of the 16 IPs the built-in DHCP server can assign",
  924:             }, {
  925:                 .name = "dns",
  926:                 .type = QEMU_OPT_STRING,
  927:                 .help = "guest-visible address of the virtual nameserver",
  928:             }, {
  929:                 .name = "smb",
  930:                 .type = QEMU_OPT_STRING,
  931:                 .help = "root directory of the built-in SMB server",
  932:             }, {
  933:                 .name = "smbserver",
  934:                 .type = QEMU_OPT_STRING,
  935:                 .help = "IP address of the built-in SMB server",
  936:             }, {
  937:                 .name = "hostfwd",
  938:                 .type = QEMU_OPT_STRING,
  939:                 .help = "guest port number to forward incoming TCP or UDP connections",
  940:             }, {
  941:                 .name = "guestfwd",
  942:                 .type = QEMU_OPT_STRING,
  943:                 .help = "IP address and port to forward guest TCP connections",
  944:             },
  945:             { /* end of list */ }
  946:         },
  947: #endif
  948:     }, {
  949:         .type = "tap",
  950:         .init = net_init_tap,
  951:         .desc = {
  952:             NET_COMMON_PARAMS_DESC,
  953:             {
  954:                 .name = "ifname",
  955:                 .type = QEMU_OPT_STRING,
  956:                 .help = "interface name",
  957:             },
  958: #ifndef _WIN32
  959:             {
  960:                 .name = "fd",
  961:                 .type = QEMU_OPT_STRING,
  962:                 .help = "file descriptor of an already opened tap",
  963:             }, {
  964:                 .name = "script",
  965:                 .type = QEMU_OPT_STRING,
  966:                 .help = "script to initialize the interface",
  967:             }, {
  968:                 .name = "downscript",
  969:                 .type = QEMU_OPT_STRING,
  970:                 .help = "script to shut down the interface",
  971:             }, {
  972:                 .name = "sndbuf",
  973:                 .type = QEMU_OPT_SIZE,
  974:                 .help = "send buffer limit"
  975:             }, {
  976:                 .name = "vnet_hdr",
  977:                 .type = QEMU_OPT_BOOL,
  978:                 .help = "enable the IFF_VNET_HDR flag on the tap interface"
  979:             },
  980: #endif /* _WIN32 */
  981:             { /* end of list */ }
  982:         },
  983:     }, {
  984:         .type = "socket",
  985:         .init = net_init_socket,
  986:         .desc = {
  987:             NET_COMMON_PARAMS_DESC,
  988:             {
  989:                 .name = "fd",
  990:                 .type = QEMU_OPT_STRING,
  991:                 .help = "file descriptor of an already opened socket",
  992:             }, {
  993:                 .name = "listen",
  994:                 .type = QEMU_OPT_STRING,
  995:                 .help = "port number, and optional hostname, to listen on",
  996:             }, {
  997:                 .name = "connect",
  998:                 .type = QEMU_OPT_STRING,
  999:                 .help = "port number, and optional hostname, to connect to",
 1000:             }, {
 1001:                 .name = "mcast",
 1002:                 .type = QEMU_OPT_STRING,
 1003:                 .help = "UDP multicast address and port number",
 1004:             },
 1005:             { /* end of list */ }
 1006:         },
 1007: #ifdef CONFIG_VDE
 1008:     }, {
 1009:         .type = "vde",
 1010:         .init = net_init_vde,
 1011:         .desc = {
 1012:             NET_COMMON_PARAMS_DESC,
 1013:             {
 1014:                 .name = "sock",
 1015:                 .type = QEMU_OPT_STRING,
 1016:                 .help = "socket path",
 1017:             }, {
 1018:                 .name = "port",
 1019:                 .type = QEMU_OPT_NUMBER,
 1020:                 .help = "port number",
 1021:             }, {
 1022:                 .name = "group",
 1023:                 .type = QEMU_OPT_STRING,
 1024:                 .help = "group owner of socket",
 1025:             }, {
 1026:                 .name = "mode",
 1027:                 .type = QEMU_OPT_NUMBER,
 1028:                 .help = "permissions for socket",
 1029:             },
 1030:             { /* end of list */ }
 1031:         },
 1032: #endif
 1033:     }, {
 1034:         .type = "dump",
 1035:         .init = net_init_dump,
 1036:         .desc = {
 1037:             NET_COMMON_PARAMS_DESC,
 1038:             {
 1039:                 .name = "len",
 1040:                 .type = QEMU_OPT_SIZE,
 1041:                 .help = "per-packet size limit (64k default)",
 1042:             }, {
 1043:                 .name = "file",
 1044:                 .type = QEMU_OPT_STRING,
 1045:                 .help = "dump file path (default is qemu-vlan0.pcap)",
 1046:             },
 1047:             { /* end of list */ }
 1048:         },
 1049:     },
 1050:     { /* end of list */ }
 1051: };
 1052: 
 1053: int net_client_init(Monitor *mon, QemuOpts *opts, int is_netdev)
 1054: {
 1055:     const char *name;
 1056:     const char *type;
 1057:     int i;
 1058: 
 1059:     type = qemu_opt_get(opts, "type");
 1060: 
 1061:     if (!is_netdev) {
 1062:         if (!type) {
 1063:             qemu_error("No type specified for -net\n");
 1064:             return -1;
 1065:         }
 1066:     } else {
 1067:         if (!type) {
 1068:             qemu_error("No type specified for -netdev\n");
 1069:             return -1;
 1070:         }
 1071: 
 1072:         if (strcmp(type, "tap") != 0 &&
 1073: #ifdef CONFIG_SLIRP
 1074:             strcmp(type, "user") != 0 &&
 1075: #endif
 1076: #ifdef CONFIG_VDE
 1077:             strcmp(type, "vde") != 0 &&
 1078: #endif
 1079:             strcmp(type, "socket") != 0) {
 1080:             qemu_error("The '%s' network backend type is not valid with -netdev\n",
 1081:                        type);
 1082:             return -1;
 1083:         }
 1084: 
 1085:         if (qemu_opt_get(opts, "vlan")) {
 1086:             qemu_error("The 'vlan' parameter is not valid with -netdev\n");
 1087:             return -1;
 1088:         }
 1089:         if (qemu_opt_get(opts, "name")) {
 1090:             qemu_error("The 'name' parameter is not valid with -netdev\n");
 1091:             return -1;
 1092:         }
 1093:         if (!qemu_opts_id(opts)) {
 1094:             qemu_error("The id= parameter is required with -netdev\n");
 1095:             return -1;
 1096:         }
 1097:     }
 1098: 
 1099:     name = qemu_opts_id(opts);
 1100:     if (!name) {
 1101:         name = qemu_opt_get(opts, "name");
 1102:     }
 1103: 
 1104:     for (i = 0; net_client_types[i].type != NULL; i++) {
 1105:         if (!strcmp(net_client_types[i].type, type)) {
 1106:             VLANState *vlan = NULL;
 1107: 
 1108:             if (qemu_opts_validate(opts, &net_client_types[i].desc[0]) == -1) {
 1109:                 return -1;
 1110:             }
 1111: 
 1112:             /* Do not add to a vlan if it's a -netdev or a nic with a
 1113:              * netdev= parameter. */
 1114:             if (!(is_netdev ||
 1115:                   (strcmp(type, "nic") == 0 && qemu_opt_get(opts, "netdev")))) {
 1116:                 vlan = qemu_find_vlan(qemu_opt_get_number(opts, "vlan", 0), 1);
 1117:             }
 1118: 
 1119:             if (net_client_types[i].init) {
 1120:                 return net_client_types[i].init(opts, mon, name, vlan);
 1121:             } else {
 1122:                 return 0;
 1123:             }
 1124:         }
 1125:     }
 1126: 
 1127:     qemu_error("Invalid -net type '%s'\n", type);
 1128:     return -1;
 1129: }
 1130: 
 1131: void net_client_uninit(NICInfo *nd)
 1132: {
 1133:     if (nd->vlan) {
 1134:         nd->vlan->nb_guest_devs--;
 1135:     }
 1136:     nb_nics--;
 1137: 
 1138:     qemu_free(nd->model);
 1139:     qemu_free(nd->name);
 1140:     qemu_free(nd->devaddr);
 1141: 
 1142:     nd->used = 0;
 1143: }
 1144: 
 1145: static int net_host_check_device(const char *device)
 1146: {
 1147:     int i;
 1148:     const char *valid_param_list[] = { "tap", "socket", "dump"
 1149: #ifdef CONFIG_SLIRP
 1150:                                        ,"user"
 1151: #endif
 1152: #ifdef CONFIG_VDE
 1153:                                        ,"vde"
 1154: #endif
 1155:     };
 1156:     for (i = 0; i < sizeof(valid_param_list) / sizeof(char *); i++) {
 1157:         if (!strncmp(valid_param_list[i], device,
 1158:                      strlen(valid_param_list[i])))
 1159:             return 1;
 1160:     }
 1161: 
 1162:     return 0;
 1163: }
 1164: 
 1165: void net_host_device_add(Monitor *mon, const QDict *qdict)
 1166: {
 1167:     const char *device = qdict_get_str(qdict, "device");
 1168:     const char *opts_str = qdict_get_try_str(qdict, "opts");
 1169:     QemuOpts *opts;
 1170: 
 1171:     if (!net_host_check_device(device)) {
 1172:         monitor_printf(mon, "invalid host network device %s\n", device);
 1173:         return;
 1174:     }
 1175: 
 1176:     opts = qemu_opts_parse(&qemu_net_opts, opts_str ? opts_str : "", NULL);
 1177:     if (!opts) {
 1178:         monitor_printf(mon, "parsing network options '%s' failed\n",
 1179:                        opts_str ? opts_str : "");
 1180:         return;
 1181:     }
 1182: 
 1183:     qemu_opt_set(opts, "type", device);
 1184: 
 1185:     if (net_client_init(mon, opts, 0) < 0) {
 1186:         monitor_printf(mon, "adding host network device %s failed\n", device);
 1187:     }
 1188: }
 1189: 
 1190: void net_host_device_remove(Monitor *mon, const QDict *qdict)
 1191: {
 1192:     VLANClientState *vc;
 1193:     int vlan_id = qdict_get_int(qdict, "vlan_id");
 1194:     const char *device = qdict_get_str(qdict, "device");
 1195: 
 1196:     vc = qemu_find_vlan_client_by_name(mon, vlan_id, device);
 1197:     if (!vc) {
 1198:         return;
 1199:     }
 1200:     if (!net_host_check_device(vc->model)) {
 1201:         monitor_printf(mon, "invalid host network device %s\n", device);
 1202:         return;
 1203:     }
 1204:     qemu_del_vlan_client(vc);
 1205: }
 1206: 
 1207: void net_set_boot_mask(int net_boot_mask)
 1208: {
 1209:     int i;
 1210: 
 1211:     /* Only the first four NICs may be bootable */
 1212:     net_boot_mask = net_boot_mask & 0xF;
 1213: 
 1214:     for (i = 0; i < nb_nics; i++) {
 1215:         if (net_boot_mask & (1 << i)) {
 1216:             nd_table[i].bootable = 1;
 1217:             net_boot_mask &= ~(1 << i);
 1218:         }
 1219:     }
 1220: 
 1221:     if (net_boot_mask) {
 1222:         fprintf(stderr, "Cannot boot from non-existent NIC\n");
 1223:         exit(1);
 1224:     }
 1225: }
 1226: 
 1227: void do_info_network(Monitor *mon)
 1228: {
 1229:     VLANState *vlan;
 1230: 
 1231:     QTAILQ_FOREACH(vlan, &vlans, next) {
 1232:         VLANClientState *vc;
 1233: 
 1234:         monitor_printf(mon, "VLAN %d devices:\n", vlan->id);
 1235: 
 1236:         QTAILQ_FOREACH(vc, &vlan->clients, next) {
 1237:             monitor_printf(mon, "  %s: %s\n", vc->name, vc->info_str);
 1238:         }
 1239:     }
 1240: }
 1241: 
 1242: void do_set_link(Monitor *mon, const QDict *qdict)
 1243: {
 1244:     VLANState *vlan;
 1245:     VLANClientState *vc = NULL;
 1246:     const char *name = qdict_get_str(qdict, "name");
 1247:     const char *up_or_down = qdict_get_str(qdict, "up_or_down");
 1248: 
 1249:     QTAILQ_FOREACH(vlan, &vlans, next) {
 1250:         QTAILQ_FOREACH(vc, &vlan->clients, next) {
 1251:             if (strcmp(vc->name, name) == 0) {
 1252:                 goto done;
 1253:             }
 1254:         }
 1255:     }
 1256: done:
 1257: 
 1258:     if (!vc) {
 1259:         monitor_printf(mon, "could not find network device '%s'\n", name);
 1260:         return;
 1261:     }
 1262: 
 1263:     if (strcmp(up_or_down, "up") == 0)
 1264:         vc->link_down = 0;
 1265:     else if (strcmp(up_or_down, "down") == 0)
 1266:         vc->link_down = 1;
 1267:     else
 1268:         monitor_printf(mon, "invalid link status '%s'; only 'up' or 'down' "
 1269:                        "valid\n", up_or_down);
 1270: 
 1271:     if (vc->info->link_status_changed) {
 1272:         vc->info->link_status_changed(vc);
 1273:     }
 1274: }
 1275: 
 1276: void net_cleanup(void)
 1277: {
 1278:     VLANState *vlan;
 1279:     VLANClientState *vc, *next_vc;
 1280: 
 1281:     QTAILQ_FOREACH(vlan, &vlans, next) {
 1282:         QTAILQ_FOREACH_SAFE(vc, &vlan->clients, next, next_vc) {
 1283:             qemu_del_vlan_client(vc);
 1284:         }
 1285:     }
 1286: 
 1287:     QTAILQ_FOREACH_SAFE(vc, &non_vlan_clients, next, next_vc) {
 1288:         qemu_del_vlan_client(vc);
 1289:     }
 1290: }
 1291: 
 1292: static void net_check_clients(void)
 1293: {
 1294:     VLANState *vlan;
 1295: 
 1296:     QTAILQ_FOREACH(vlan, &vlans, next) {
 1297:         if (vlan->nb_guest_devs == 0 && vlan->nb_host_devs == 0)
 1298:             continue;
 1299:         if (vlan->nb_guest_devs == 0)
 1300:             fprintf(stderr, "Warning: vlan %d with no nics\n", vlan->id);
 1301:         if (vlan->nb_host_devs == 0)
 1302:             fprintf(stderr,
 1303:                     "Warning: vlan %d is not connected to host network\n",
 1304:                     vlan->id);
 1305:     }
 1306: }
 1307: 
 1308: static int net_init_client(QemuOpts *opts, void *dummy)
 1309: {
 1310:     if (net_client_init(NULL, opts, 0) < 0)
 1311:         return -1;
 1312:     return 0;
 1313: }
 1314: 
 1315: static int net_init_netdev(QemuOpts *opts, void *dummy)
 1316: {
 1317:     return net_client_init(NULL, opts, 1);
 1318: }
 1319: 
 1320: int net_init_clients(void)
 1321: {
 1322:     if (default_net) {
 1323:         /* if no clients, we use a default config */
 1324:         qemu_opts_set(&qemu_net_opts, NULL, "type", "nic");
 1325: #ifdef CONFIG_SLIRP
 1326:         qemu_opts_set(&qemu_net_opts, NULL, "type", "user");
 1327: #endif
 1328:     }
 1329: 
 1330:     QTAILQ_INIT(&vlans);
 1331:     QTAILQ_INIT(&non_vlan_clients);
 1332: 
 1333:     if (qemu_opts_foreach(&qemu_netdev_opts, net_init_netdev, NULL, 1) == -1)
 1334:         return -1;
 1335: 
 1336:     if (qemu_opts_foreach(&qemu_net_opts, net_init_client, NULL, 1) == -1) {
 1337:         return -1;
 1338:     }
 1339: 
 1340:     net_check_clients();
 1341: 
 1342:     return 0;
 1343: }
 1344: 
 1345: int net_client_parse(QemuOptsList *opts_list, const char *optarg)
 1346: {
 1347: #if defined(CONFIG_SLIRP)
 1348:     int ret;
 1349:     if (net_slirp_parse_legacy(opts_list, optarg, &ret)) {
 1350:         return ret;
 1351:     }
 1352: #endif
 1353: 
 1354:     if (!qemu_opts_parse(opts_list, optarg, "type")) {
 1355:         return -1;
 1356:     }
 1357: 
 1358:     default_net = 0;
 1359:     return 0;
 1360: }

unix.superglobalmegacorp.com