Commit bc3004f0 authored by Peter Maydell's avatar Peter Maydell
Browse files

Merge remote-tracking branch 'remotes/stefanha/tags/net-pull-request' into staging



# gpg: Signature made Wed May 27 11:02:55 2015 BST using RSA key ID 81AB73C8
# gpg: Good signature from "Stefan Hajnoczi <stefanha@redhat.com>"
# gpg:                 aka "Stefan Hajnoczi <stefanha@gmail.com>"

* remotes/stefanha/tags/net-pull-request:
  net/net: Record usage status of mac address
  tap: Improve -netdev/netdev_add/-net/... tap error reporting
  tap: Finish conversion of tap_open() to Error
  tap-solaris: Convert tap_open() to Error
  tap-bsd: Convert tap_open() to Error
  tap-linux: Convert tap_open() to Error
  tap: Permit incremental conversion of tap_open() to Error
  tap: Convert launch_script() to Error
  tap: Convert net_init_tap_one() to Error
  tap: Convert tap_set_sndbuf() to Error
  tap: Improve -netdev/netdev_add/-net/... bridge error reporting
  tap: net_tap_fd_init() can't fail, drop dead error handling
  net/dump: Improve -net/host_net_add dump error reporting
  net: Improve -net nic error reporting
  net: Permit incremental conversion of init functions to Error
  net: Improve error message for -net hubport a bit
  net: Change help text to list -netdev instead of -net by default

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents 0915aed5 2bc22a58
Loading
Loading
Loading
Loading
+10 −10
Original line number Diff line number Diff line
@@ -28,38 +28,38 @@
#include "qapi-types.h"

int net_init_dump(const NetClientOptions *opts, const char *name,
                  NetClientState *peer);
                  NetClientState *peer, Error **errp);

#ifdef CONFIG_SLIRP
int net_init_slirp(const NetClientOptions *opts, const char *name,
                   NetClientState *peer);
                   NetClientState *peer, Error **errp);
#endif

int net_init_hubport(const NetClientOptions *opts, const char *name,
                     NetClientState *peer);
                     NetClientState *peer, Error **errp);

int net_init_socket(const NetClientOptions *opts, const char *name,
                    NetClientState *peer);
                    NetClientState *peer, Error **errp);

int net_init_tap(const NetClientOptions *opts, const char *name,
                 NetClientState *peer);
                 NetClientState *peer, Error **errp);

int net_init_bridge(const NetClientOptions *opts, const char *name,
                    NetClientState *peer);
                    NetClientState *peer, Error **errp);

int net_init_l2tpv3(const NetClientOptions *opts, const char *name,
                    NetClientState *peer);
                    NetClientState *peer, Error **errp);
#ifdef CONFIG_VDE
int net_init_vde(const NetClientOptions *opts, const char *name,
                 NetClientState *peer);
                 NetClientState *peer, Error **errp);
#endif

#ifdef CONFIG_NETMAP
int net_init_netmap(const NetClientOptions *opts, const char *name,
                    NetClientState *peer);
                    NetClientState *peer, Error **errp);
#endif

int net_init_vhost_user(const NetClientOptions *opts, const char *name,
                        NetClientState *peer);
                        NetClientState *peer, Error **errp);

#endif /* QEMU_NET_CLIENTS_H */
+7 −6
Original line number Diff line number Diff line
@@ -101,7 +101,8 @@ static NetClientInfo net_dump_info = {
};

static int net_dump_init(NetClientState *peer, const char *device,
                         const char *name, const char *filename, int len)
                         const char *name, const char *filename, int len,
                         Error **errp)
{
    struct pcap_file_hdr hdr;
    NetClientState *nc;
@@ -111,7 +112,7 @@ static int net_dump_init(NetClientState *peer, const char *device,

    fd = open(filename, O_CREAT | O_TRUNC | O_WRONLY | O_BINARY, 0644);
    if (fd < 0) {
        error_report("-net dump: can't open %s", filename);
        error_setg_errno(errp, errno, "-net dump: can't open %s", filename);
        return -1;
    }

@@ -124,7 +125,7 @@ static int net_dump_init(NetClientState *peer, const char *device,
    hdr.linktype = 1;

    if (write(fd, &hdr, sizeof(hdr)) < sizeof(hdr)) {
        error_report("-net dump write error: %s", strerror(errno));
        error_setg_errno(errp, errno, "-net dump write error");
        close(fd);
        return -1;
    }
@@ -146,7 +147,7 @@ static int net_dump_init(NetClientState *peer, const char *device,
}

int net_init_dump(const NetClientOptions *opts, const char *name,
                  NetClientState *peer)
                  NetClientState *peer, Error **errp)
{
    int len;
    const char *file;
@@ -173,7 +174,7 @@ int net_init_dump(const NetClientOptions *opts, const char *name,

    if (dump->has_len) {
        if (dump->len > INT_MAX) {
            error_report("invalid length: %"PRIu64, dump->len);
            error_setg(errp, "invalid length: %"PRIu64, dump->len);
            return -1;
        }
        len = dump->len;
@@ -181,5 +182,5 @@ int net_init_dump(const NetClientOptions *opts, const char *name,
        len = 65536;
    }

    return net_dump_init(peer, "dump", name, file, len);
    return net_dump_init(peer, "dump", name, file, len, errp);
}
+2 −5
Original line number Diff line number Diff line
@@ -281,17 +281,14 @@ int net_hub_id_for_client(NetClientState *nc, int *id)
}

int net_init_hubport(const NetClientOptions *opts, const char *name,
                     NetClientState *peer)
                     NetClientState *peer, Error **errp)
{
    const NetdevHubPortOptions *hubport;

    assert(opts->kind == NET_CLIENT_OPTIONS_KIND_HUBPORT);
    assert(!peer);
    hubport = opts->hubport;

    if (peer) {
        return -EINVAL;
    }

    net_hub_add_port(hubport->hubid, name);
    return 0;
}
+2 −3
Original line number Diff line number Diff line
@@ -536,10 +536,9 @@ static NetClientInfo net_l2tpv3_info = {

int net_init_l2tpv3(const NetClientOptions *opts,
                    const char *name,
                    NetClientState *peer)
                    NetClientState *peer, Error **errp)
{


    /* FIXME error_setg(errp, ...) on failure */
    const NetdevL2TPv3Options *l2tpv3;
    NetL2TPV3State *s;
    NetClientState *nc;
+74 −15
Original line number Diff line number Diff line
@@ -167,19 +167,68 @@ void qemu_format_nic_info_str(NetClientState *nc, uint8_t macaddr[6])
             macaddr[3], macaddr[4], macaddr[5]);
}

static int mac_table[256] = {0};

static void qemu_macaddr_set_used(MACAddr *macaddr)
{
    int index;

    for (index = 0x56; index < 0xFF; index++) {
        if (macaddr->a[5] == index) {
            mac_table[index]++;
        }
    }
}

static void qemu_macaddr_set_free(MACAddr *macaddr)
{
    int index;
    static const MACAddr base = { .a = { 0x52, 0x54, 0x00, 0x12, 0x34, 0 } };

    if (memcmp(macaddr->a, &base.a, (sizeof(base.a) - 1)) != 0) {
        return;
    }
    for (index = 0x56; index < 0xFF; index++) {
        if (macaddr->a[5] == index) {
            mac_table[index]--;
        }
    }
}

static int qemu_macaddr_get_free(void)
{
    int index;

    for (index = 0x56; index < 0xFF; index++) {
        if (mac_table[index] == 0) {
            return index;
        }
    }

    return -1;
}

void qemu_macaddr_default_if_unset(MACAddr *macaddr)
{
    static int index = 0;
    static const MACAddr zero = { .a = { 0,0,0,0,0,0 } };
    static const MACAddr base = { .a = { 0x52, 0x54, 0x00, 0x12, 0x34, 0 } };

    if (memcmp(macaddr, &zero, sizeof(zero)) != 0)
    if (memcmp(macaddr, &zero, sizeof(zero)) != 0) {
        if (memcmp(macaddr->a, &base.a, (sizeof(base.a) - 1)) != 0) {
            return;
        } else {
            qemu_macaddr_set_used(macaddr);
            return;
        }
    }

    macaddr->a[0] = 0x52;
    macaddr->a[1] = 0x54;
    macaddr->a[2] = 0x00;
    macaddr->a[3] = 0x12;
    macaddr->a[4] = 0x34;
    macaddr->a[5] = 0x56 + index++;
    macaddr->a[5] = qemu_macaddr_get_free();
    qemu_macaddr_set_used(macaddr);
}

/**
@@ -374,6 +423,8 @@ void qemu_del_nic(NICState *nic)
{
    int i, queues = MAX(nic->conf->peers.queues, 1);

    qemu_macaddr_set_free(&nic->conf->macaddr);

    /* If this is a peer NIC and peer has already been deleted, free it now. */
    if (nic->peer_deleted) {
        for (i = 0; i < queues; i++) {
@@ -740,7 +791,7 @@ int qemu_find_nic_model(NICInfo *nd, const char * const *models,
}

static int net_init_nic(const NetClientOptions *opts, const char *name,
                        NetClientState *peer)
                        NetClientState *peer, Error **errp)
{
    int idx;
    NICInfo *nd;
@@ -751,7 +802,7 @@ static int net_init_nic(const NetClientOptions *opts, const char *name,

    idx = nic_get_free_idx();
    if (idx == -1 || nb_nics >= MAX_NICS) {
        error_report("Too Many NICs");
        error_setg(errp, "too many NICs");
        return -1;
    }

@@ -762,7 +813,7 @@ static int net_init_nic(const NetClientOptions *opts, const char *name,
    if (nic->has_netdev) {
        nd->netdev = qemu_find_netdev(nic->netdev);
        if (!nd->netdev) {
            error_report("netdev '%s' not found", nic->netdev);
            error_setg(errp, "netdev '%s' not found", nic->netdev);
            return -1;
        }
    } else {
@@ -779,19 +830,20 @@ static int net_init_nic(const NetClientOptions *opts, const char *name,

    if (nic->has_macaddr &&
        net_parse_macaddr(nd->macaddr.a, nic->macaddr) < 0) {
        error_report("invalid syntax for ethernet address");
        error_setg(errp, "invalid syntax for ethernet address");
        return -1;
    }
    if (nic->has_macaddr &&
        is_multicast_ether_addr(nd->macaddr.a)) {
        error_report("NIC cannot have multicast MAC address (odd 1st byte)");
        error_setg(errp,
                   "NIC cannot have multicast MAC address (odd 1st byte)");
        return -1;
    }
    qemu_macaddr_default_if_unset(&nd->macaddr);

    if (nic->has_vectors) {
        if (nic->vectors > 0x7ffffff) {
            error_report("invalid # of vectors: %"PRIu32, nic->vectors);
            error_setg(errp, "invalid # of vectors: %"PRIu32, nic->vectors);
            return -1;
        }
        nd->nvectors = nic->vectors;
@@ -809,7 +861,7 @@ static int net_init_nic(const NetClientOptions *opts, const char *name,
static int (* const net_client_init_fun[NET_CLIENT_OPTIONS_KIND_MAX])(
    const NetClientOptions *opts,
    const char *name,
    NetClientState *peer) = {
    NetClientState *peer, Error **errp) = {
        [NET_CLIENT_OPTIONS_KIND_NIC]       = net_init_nic,
#ifdef CONFIG_SLIRP
        [NET_CLIENT_OPTIONS_KIND_USER]      = net_init_slirp,
@@ -882,6 +934,11 @@ static int net_client_init1(const void *object, int is_netdev, Error **errp)
    } else {
        u.net = object;
        opts = u.net->opts;
        if (opts->kind == NET_CLIENT_OPTIONS_KIND_HUBPORT) {
            error_set(errp, QERR_INVALID_PARAMETER_VALUE, "type",
                      "a net type");
            return -1;
        }
        /* missing optional values have been initialized to "all bits zero" */
        name = u.net->has_id ? u.net->id : u.net->name;
    }
@@ -897,10 +954,12 @@ static int net_client_init1(const void *object, int is_netdev, Error **errp)
            peer = net_hub_add_port(u.net->has_vlan ? u.net->vlan : 0, NULL);
        }

        if (net_client_init_fun[opts->kind](opts, name, peer) < 0) {
            /* TODO push error reporting into init() methods */
        if (net_client_init_fun[opts->kind](opts, name, peer, errp) < 0) {
            /* FIXME drop when all init functions store an Error */
            if (errp && !*errp) {
                error_set(errp, QERR_DEVICE_INIT_FAILED,
                          NetClientOptionsKind_lookup[opts->kind]);
            }
            return -1;
        }
    }
Loading