File:  [Qemu by Fabrice Bellard] / qemu / net.c
Revision 1.1.1.13 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 19:17:12 2018 UTC (3 years, 1 month ago) by root
Branches: qemu, MAIN
CVS tags: qemu1001, HEAD
qemu 1.0.1

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

unix.superglobalmegacorp.com