Commit 16dbaf90 authored by Jason Wang's avatar Jason Wang Committed by Anthony Liguori
Browse files

tap: support enabling or disabling a queue



This patch introduce a new bit - enabled in TAPState which tracks whether a
specific queue/fd is enabled. The tap/fd is enabled during initialization and
could be enabled/disabled by tap_enalbe() and tap_disable() which calls platform
specific helpers to do the real work. Polling of a tap fd can only done when
the tap was enabled.

Signed-off-by: default avatarJason Wang <jasowang@redhat.com>
Signed-off-by: default avatarAnthony Liguori <aliguori@us.ibm.com>
parent 94fdc6d0
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -35,6 +35,8 @@ int tap_has_vnet_hdr_len(NetClientState *nc, int len);
void tap_using_vnet_hdr(NetClientState *nc, bool using_vnet_hdr);
void tap_set_offload(NetClientState *nc, int csum, int tso4, int tso6, int ecn, int ufo);
void tap_set_vnet_hdr_len(NetClientState *nc, int len);
int tap_enable(NetClientState *nc);
int tap_disable(NetClientState *nc);

int tap_get_fd(NetClientState *nc);

+10 −0
Original line number Diff line number Diff line
@@ -764,3 +764,13 @@ void tap_set_vnet_hdr_len(NetClientState *nc, int len)
{
    abort();
}

int tap_enable(NetClientState *nc)
{
    abort();
}

int tap_disable(NetClientState *nc)
{
    abort();
}
+40 −3
Original line number Diff line number Diff line
@@ -59,6 +59,7 @@ typedef struct TAPState {
    bool write_poll;
    bool using_vnet_hdr;
    bool has_ufo;
    bool enabled;
    VHostNetState *vhost_net;
    unsigned host_vnet_hdr_len;
} TAPState;
@@ -72,9 +73,9 @@ static void tap_writable(void *opaque);
static void tap_update_fd_handler(TAPState *s)
{
    qemu_set_fd_handler2(s->fd,
                         s->read_poll  ? tap_can_send : NULL,
                         s->read_poll  ? tap_send     : NULL,
                         s->write_poll ? tap_writable : NULL,
                         s->read_poll && s->enabled ? tap_can_send : NULL,
                         s->read_poll && s->enabled ? tap_send     : NULL,
                         s->write_poll && s->enabled ? tap_writable : NULL,
                         s);
}

@@ -337,6 +338,7 @@ static TAPState *net_tap_fd_init(NetClientState *peer,
    s->host_vnet_hdr_len = vnet_hdr ? sizeof(struct virtio_net_hdr) : 0;
    s->using_vnet_hdr = false;
    s->has_ufo = tap_probe_has_ufo(s->fd);
    s->enabled = true;
    tap_set_offload(&s->nc, 0, 0, 0, 0, 0);
    /*
     * Make sure host header length is set correctly in tap:
@@ -735,3 +737,38 @@ VHostNetState *tap_get_vhost_net(NetClientState *nc)
    assert(nc->info->type == NET_CLIENT_OPTIONS_KIND_TAP);
    return s->vhost_net;
}

int tap_enable(NetClientState *nc)
{
    TAPState *s = DO_UPCAST(TAPState, nc, nc);
    int ret;

    if (s->enabled) {
        return 0;
    } else {
        ret = tap_fd_enable(s->fd);
        if (ret == 0) {
            s->enabled = true;
            tap_update_fd_handler(s);
        }
        return ret;
    }
}

int tap_disable(NetClientState *nc)
{
    TAPState *s = DO_UPCAST(TAPState, nc, nc);
    int ret;

    if (s->enabled == 0) {
        return 0;
    } else {
        ret = tap_fd_disable(s->fd);
        if (ret == 0) {
            qemu_purge_queued_packets(nc);
            s->enabled = false;
            tap_update_fd_handler(s);
        }
        return ret;
    }
}