Commit d33d93b2 authored by Stefan Hajnoczi's avatar Stefan Hajnoczi
Browse files

net: Use hubs for the vlan feature



Stop using the special-case vlan code in net.c.  Instead use the hub net
client to implement the vlan feature.  The next patch will remove vlan
code from net.c completely.

Signed-off-by: default avatarStefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: default avatarZhi Yong Wu <wuzhy@linux.vnet.ibm.com>
Reviewed-by: default avatarLaszlo Ersek <lersek@redhat.com>
parent f6c874e3
Loading
Loading
Loading
Loading
+20 −17
Original line number Diff line number Diff line
@@ -157,23 +157,25 @@ void qemu_macaddr_default_if_unset(MACAddr *macaddr)
    macaddr->a[5] = 0x56 + index++;
}

/**
 * Generate a name for net client
 *
 * Only net clients created with the legacy -net option need this.  Naming is
 * mandatory for net clients created with -netdev.
 */
static char *assign_name(VLANClientState *vc1, const char *model)
{
    VLANState *vlan;
    VLANClientState *vc;
    char buf[256];
    int id = 0;

    QTAILQ_FOREACH(vlan, &vlans, next) {
        QTAILQ_FOREACH(vc, &vlan->clients, next) {
            if (vc != vc1 && strcmp(vc->model, model) == 0) {
                id++;
            }
        }
    }

    QTAILQ_FOREACH(vc, &non_vlan_clients, next) {
        if (vc != vc1 && strcmp(vc->model, model) == 0) {
        if (vc == vc1) {
            continue;
        }
        /* For compatibility only bump id for net clients on a vlan */
        if (strcmp(vc->model, model) == 0 &&
            net_hub_id_for_client(vc, NULL) == 0) {
            id++;
        }
    }
@@ -750,7 +752,7 @@ int net_handle_fd_param(Monitor *mon, const char *param)
}

static int net_init_nic(const NetClientOptions *opts, const char *name,
                        VLANState *vlan)
                        VLANClientState *peer)
{
    int idx;
    NICInfo *nd;
@@ -776,8 +778,8 @@ static int net_init_nic(const NetClientOptions *opts, const char *name,
            return -1;
        }
    } else {
        assert(vlan);
        nd->vlan = vlan;
        assert(peer);
        nd->netdev = peer;
    }
    if (name) {
        nd->name = g_strdup(name);
@@ -816,7 +818,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,
    VLANState *vlan) = {
    VLANClientState *peer) = {
        [NET_CLIENT_OPTIONS_KIND_NIC]       = net_init_nic,
#ifdef CONFIG_SLIRP
        [NET_CLIENT_OPTIONS_KIND_USER]      = net_init_slirp,
@@ -876,17 +878,17 @@ static int net_client_init1(const void *object, int is_netdev, Error **errp)
    }

    if (net_client_init_fun[opts->kind]) {
        VLANState *vlan = NULL;
        VLANClientState *peer = NULL;

        /* Do not add to a vlan if it's a -netdev or a nic with a netdev=
         * parameter. */
        if (!is_netdev &&
            (opts->kind != NET_CLIENT_OPTIONS_KIND_NIC ||
             !opts->nic->has_netdev)) {
            vlan = qemu_find_vlan(u.net->has_vlan ? u.net->vlan : 0, true);
            peer = net_hub_add_port(u.net->has_vlan ? u.net->vlan : 0, NULL);
        }

        if (net_client_init_fun[opts->kind](opts, name, vlan) < 0) {
        if (net_client_init_fun[opts->kind](opts, name, peer) < 0) {
            /* TODO push error reporting into init() methods */
            error_set(errp, QERR_DEVICE_INIT_FAILED,
                      NetClientOptionsKind_lookup[opts->kind]);
@@ -1085,6 +1087,7 @@ void do_info_network(Monitor *mon)
            print_net_client(mon, peer);
        }
    }
    net_hub_info(mon);
}

void qmp_set_link(const char *name, bool up, Error **errp)
+13 −6
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@
#include "qemu-error.h"
#include "qemu-log.h"
#include "qemu-timer.h"
#include "hub.h"

typedef struct DumpState {
    VLANClientState nc;
@@ -99,7 +100,7 @@ static NetClientInfo net_dump_info = {
    .cleanup = dump_cleanup,
};

static int net_dump_init(VLANState *vlan, const char *device,
static int net_dump_init(VLANClientState *peer, const char *device,
                         const char *name, const char *filename, int len)
{
    struct pcap_file_hdr hdr;
@@ -128,7 +129,7 @@ static int net_dump_init(VLANState *vlan, const char *device,
        return -1;
    }

    nc = qemu_new_net_client(&net_dump_info, vlan, NULL, device, name);
    nc = qemu_new_net_client(&net_dump_info, NULL, peer, device, name);

    snprintf(nc->info_str, sizeof(nc->info_str),
             "dump to %s (len=%d)", filename, len);
@@ -145,7 +146,7 @@ static int net_dump_init(VLANState *vlan, const char *device,
}

int net_init_dump(const NetClientOptions *opts, const char *name,
                  VLANState *vlan)
                  VLANClientState *peer)
{
    int len;
    const char *file;
@@ -155,12 +156,18 @@ int net_init_dump(const NetClientOptions *opts, const char *name,
    assert(opts->kind == NET_CLIENT_OPTIONS_KIND_DUMP);
    dump = opts->dump;

    assert(vlan);
    assert(peer);

    if (dump->has_file) {
        file = dump->file;
    } else {
        snprintf(def_file, sizeof(def_file), "qemu-vlan%d.pcap", vlan->id);
        int id;
        int ret;

        ret = net_hub_id_for_client(peer, &id);
        assert(ret == 0); /* peer must be on a hub */

        snprintf(def_file, sizeof(def_file), "qemu-vlan%d.pcap", id);
        file = def_file;
    }

@@ -174,5 +181,5 @@ int net_init_dump(const NetClientOptions *opts, const char *name,
        len = 65536;
    }

    return net_dump_init(vlan, "dump", name, file, len);
    return net_dump_init(peer, "dump", name, file, len);
}
+1 −1
Original line number Diff line number Diff line
@@ -28,6 +28,6 @@
#include "qapi-types.h"

int net_init_dump(const NetClientOptions *opts, const char *name,
                  VLANState *vlan);
                  VLANClientState *peer);

#endif /* QEMU_NET_DUMP_H */
+3 −3
Original line number Diff line number Diff line
@@ -206,15 +206,15 @@ int net_hub_id_for_client(VLANClientState *nc, int *id)
}

int net_init_hubport(const NetClientOptions *opts, const char *name,
                     VLANState *vlan)
                     VLANClientState *peer)
{
    const NetdevHubPortOptions *hubport;

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

    /* The hub is a "vlan" so this option makes no sense. */
    if (vlan) {
    /* Treat hub port like a backend, NIC must be the one to peer */
    if (peer) {
        return -EINVAL;
    }

+1 −1
Original line number Diff line number Diff line
@@ -18,7 +18,7 @@
#include "qemu-common.h"

int net_init_hubport(const NetClientOptions *opts, const char *name,
                     VLANState *vlan);
                     VLANClientState *peer);
VLANClientState *net_hub_add_port(int hub_id, const char *name);
void net_hub_info(Monitor *mon);
int net_hub_id_for_client(VLANClientState *nc, int *id);
Loading