Revision f83c6e10 net.c

b/net.c
110 110
#include "audio/audio.h"
111 111
#include "qemu_socket.h"
112 112
#include "qemu-log.h"
113
#include "qemu-config.h"
113 114

  
114 115
#include "slirp/libslirp.h"
115 116
#include "qemu-queue.h"
......
2400 2401
    }
2401 2402
}
2402 2403

  
2404
static int net_init_nic(QemuOpts *opts, Monitor *mon)
2405
{
2406
    int idx;
2407
    NICInfo *nd;
2408

  
2409
    idx = nic_get_free_idx();
2410
    if (idx == -1 || nb_nics >= MAX_NICS) {
2411
        qemu_error("Too Many NICs\n");
2412
        return -1;
2413
    }
2414

  
2415
    nd = &nd_table[idx];
2416

  
2417
    memset(nd, 0, sizeof(*nd));
2418

  
2419
    nd->vlan = qemu_find_vlan(qemu_opt_get_number(opts, "vlan", 0), 1);
2420

  
2421
    if (qemu_opts_id(opts)) {
2422
        nd->id = qemu_strdup(qemu_opts_id(opts));
2423
    }
2424
    if (qemu_opt_get(opts, "name")) {
2425
        nd->name = qemu_strdup(qemu_opt_get(opts, "name"));
2426
    }
2427
    if (qemu_opt_get(opts, "model")) {
2428
        nd->model = qemu_strdup(qemu_opt_get(opts, "model"));
2429
    }
2430
    if (qemu_opt_get(opts, "addr")) {
2431
        nd->devaddr = qemu_strdup(qemu_opt_get(opts, "addr"));
2432
    }
2433

  
2434
    nd->macaddr[0] = 0x52;
2435
    nd->macaddr[1] = 0x54;
2436
    nd->macaddr[2] = 0x00;
2437
    nd->macaddr[3] = 0x12;
2438
    nd->macaddr[4] = 0x34;
2439
    nd->macaddr[5] = 0x56 + idx;
2440

  
2441
    if (qemu_opt_get(opts, "macaddr") &&
2442
        parse_macaddr(nd->macaddr, qemu_opt_get(opts, "macaddr")) < 0) {
2443
        qemu_error("invalid syntax for ethernet address\n");
2444
        return -1;
2445
    }
2446

  
2447
    nd->nvectors = qemu_opt_get_number(opts, "vectors", NIC_NVECTORS_UNSPECIFIED);
2448
    if (nd->nvectors != NIC_NVECTORS_UNSPECIFIED &&
2449
        (nd->nvectors < 0 || nd->nvectors > 0x7ffffff)) {
2450
        qemu_error("invalid # of vectors: %d\n", nd->nvectors);
2451
        return -1;
2452
    }
2453

  
2454
    nd->used = 1;
2455
    nd->vlan->nb_guest_devs++;
2456
    nb_nics++;
2457

  
2458
    return idx;
2459
}
2460

  
2461
#define NET_COMMON_PARAMS_DESC                     \
2462
    {                                              \
2463
        .name = "type",                            \
2464
        .type = QEMU_OPT_STRING,                   \
2465
        .help = "net client type (nic, tap etc.)", \
2466
     }, {                                          \
2467
        .name = "vlan",                            \
2468
        .type = QEMU_OPT_NUMBER,                   \
2469
        .help = "vlan number",                     \
2470
     }, {                                          \
2471
        .name = "name",                            \
2472
        .type = QEMU_OPT_STRING,                   \
2473
        .help = "identifier for monitor commands", \
2474
     }
2475

  
2476
typedef int (*net_client_init_func)(QemuOpts *opts, Monitor *mon);
2477

  
2478
/* magic number, but compiler will warn if too small */
2479
#define NET_MAX_DESC 20
2480

  
2481
static struct {
2482
    const char *type;
2483
    net_client_init_func init;
2484
    QemuOptDesc desc[NET_MAX_DESC];
2485
} net_client_types[] = {
2486
    {
2487
        .type = "none",
2488
        .desc = {
2489
            NET_COMMON_PARAMS_DESC,
2490
            { /* end of list */ }
2491
        },
2492
    }, {
2493
        .type = "nic",
2494
        .init = net_init_nic,
2495
        .desc = {
2496
            NET_COMMON_PARAMS_DESC,
2497
            {
2498
                .name = "macaddr",
2499
                .type = QEMU_OPT_STRING,
2500
                .help = "MAC address",
2501
            }, {
2502
                .name = "model",
2503
                .type = QEMU_OPT_STRING,
2504
                .help = "device model (e1000, rtl8139, virtio etc.)",
2505
            }, {
2506
                .name = "addr",
2507
                .type = QEMU_OPT_STRING,
2508
                .help = "PCI device address",
2509
            }, {
2510
                .name = "vectors",
2511
                .type = QEMU_OPT_NUMBER,
2512
                .help = "number of MSI-x vectors, 0 to disable MSI-X",
2513
            },
2514
            { /* end of list */ }
2515
        },
2516
    },
2517
    { /* end of list */ }
2518
};
2519

  
2520
static int net_client_init_from_opts(Monitor *mon, QemuOpts *opts)
2521
{
2522
    const char *type;
2523
    int i;
2524

  
2525
    type = qemu_opt_get(opts, "type");
2526
    if (!type) {
2527
        qemu_error("No type specified for -net\n");
2528
        return -1;
2529
    }
2530

  
2531
    for (i = 0; net_client_types[i].type != NULL; i++) {
2532
        if (!strcmp(net_client_types[i].type, type)) {
2533
            if (qemu_opts_validate(opts, &net_client_types[i].desc[0]) == -1) {
2534
                return -1;
2535
            }
2536

  
2537
            if (net_client_types[i].init) {
2538
                return net_client_types[i].init(opts, NULL);
2539
            } else {
2540
                return 0;
2541
            }
2542
        }
2543
    }
2544

  
2545
    qemu_error("Invalid -net type '%s'\n", type);
2546
    return -1;
2547
}
2548

  
2403 2549
int net_client_init(Monitor *mon, const char *device, const char *p)
2404 2550
{
2405 2551
    char buf[1024];
......
2407 2553
    VLANState *vlan;
2408 2554
    char *name = NULL;
2409 2555

  
2556
    if (!strcmp(device, "none") ||
2557
        !strcmp(device, "nic")) {
2558
        QemuOpts *opts;
2559

  
2560
        opts = qemu_opts_parse(&qemu_net_opts, p, NULL);
2561
        if (!opts) {
2562
            return -1;
2563
        }
2564

  
2565
        qemu_opt_set(opts, "type", device);
2566

  
2567
        return net_client_init_from_opts(mon, opts);
2568
    }
2569

  
2410 2570
    vlan_id = 0;
2411 2571
    if (get_param_value(buf, sizeof(buf), "vlan", p)) {
2412 2572
        vlan_id = strtol(buf, NULL, 0);
......
2416 2576
    if (get_param_value(buf, sizeof(buf), "name", p)) {
2417 2577
        name = qemu_strdup(buf);
2418 2578
    }
2419
    if (!strcmp(device, "nic")) {
2420
        static const char * const nic_params[] = {
2421
            "vlan", "name", "macaddr", "model", "addr", "id", "vectors", NULL
2422
        };
2423
        NICInfo *nd;
2424
        uint8_t *macaddr;
2425
        int idx = nic_get_free_idx();
2426 2579

  
2427
        if (check_params(buf, sizeof(buf), nic_params, p) < 0) {
2428
            qemu_error("invalid parameter '%s' in '%s'\n", buf, p);
2429
            ret = -1;
2430
            goto out;
2431
        }
2432
        if (idx == -1 || nb_nics >= MAX_NICS) {
2433
            qemu_error("Too Many NICs\n");
2434
            ret = -1;
2435
            goto out;
2436
        }
2437
        nd = &nd_table[idx];
2438
        memset(nd, 0, sizeof(*nd));
2439
        macaddr = nd->macaddr;
2440
        macaddr[0] = 0x52;
2441
        macaddr[1] = 0x54;
2442
        macaddr[2] = 0x00;
2443
        macaddr[3] = 0x12;
2444
        macaddr[4] = 0x34;
2445
        macaddr[5] = 0x56 + idx;
2446

  
2447
        if (get_param_value(buf, sizeof(buf), "macaddr", p)) {
2448
            if (parse_macaddr(macaddr, buf) < 0) {
2449
                qemu_error("invalid syntax for ethernet address\n");
2450
                ret = -1;
2451
                goto out;
2452
            }
2453
        }
2454
        if (get_param_value(buf, sizeof(buf), "model", p)) {
2455
            nd->model = qemu_strdup(buf);
2456
        }
2457
        if (get_param_value(buf, sizeof(buf), "addr", p)) {
2458
            nd->devaddr = qemu_strdup(buf);
2459
        }
2460
        if (get_param_value(buf, sizeof(buf), "id", p)) {
2461
            nd->id = qemu_strdup(buf);
2462
        }
2463
        nd->nvectors = NIC_NVECTORS_UNSPECIFIED;
2464
        if (get_param_value(buf, sizeof(buf), "vectors", p)) {
2465
            char *endptr;
2466
            long vectors = strtol(buf, &endptr, 0);
2467
            if (*endptr) {
2468
                qemu_error("invalid syntax for # of vectors\n");
2469
                ret = -1;
2470
                goto out;
2471
            }
2472
            if (vectors < 0 || vectors > 0x7ffffff) {
2473
                qemu_error("invalid # of vectors\n");
2474
                ret = -1;
2475
                goto out;
2476
            }
2477
            nd->nvectors = vectors;
2478
        }
2479
        nd->vlan = vlan;
2480
        nd->name = name;
2481
        nd->used = 1;
2482
        name = NULL;
2483
        nb_nics++;
2484
        vlan->nb_guest_devs++;
2485
        ret = idx;
2486
    } else
2487
    if (!strcmp(device, "none")) {
2488
        if (*p != '\0') {
2489
            qemu_error("'none' takes no parameters\n");
2490
            ret = -1;
2491
            goto out;
2492
        }
2493
        /* does nothing. It is needed to signal that no network cards
2494
           are wanted */
2495
        ret = 0;
2496
    } else
2497 2580
#ifdef CONFIG_SLIRP
2498 2581
    if (!strcmp(device, "user")) {
2499 2582
        static const char * const slirp_params[] = {

Also available in: Unified diff