Commit 0bf224d5 authored by Peter Maydell's avatar Peter Maydell
Browse files

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



# gpg: Signature made Mon 12 Oct 2015 08:56:47 BST using RSA key ID 398D6211
# gpg: Good signature from "Jason Wang (Jason Wang on RedHat) <jasowang@redhat.com>"
# gpg: WARNING: This key is not certified with sufficiently trusted signatures!
# gpg:          It is not certain that the signature belongs to the owner.
# Primary key fingerprint: 215D 46F4 8246 689E C77F  3562 EF04 965B 398D 6211

* remotes/jasowang/tags/net-pull-request:
  tests: add test cases for netfilter object
  netfilter: add a netbuffer filter
  net/queue: export qemu_net_queue_append_iov
  netfilter: print filter info associate with the netdev
  netfilter: add an API to pass the packet to next filter
  net/queue: introduce NetQueueDeliverFunc
  net: merge qemu_deliver_packet and qemu_deliver_packet_iov
  netfilter: hook packets before net queue send
  init/cleanup of netfilter object
  vl.c: init delayed object after net_init_clients
  vmxnet3: Add support for VMXNET3_CMD_GET_ADAPTIVE_RING_INFO command
  e1000: use alias for default model
  vmxnet3: Support reading IMR registers on bar0
  net/vmxnet3: Refine l2 header validation

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents 76849223 89b12737
Loading
Loading
Loading
Loading
+1 −7
Original line number Diff line number Diff line
@@ -1647,7 +1647,7 @@ static const TypeInfo e1000_base_info = {

static const E1000Info e1000_devices[] = {
    {
        .name      = "e1000-82540em",
        .name      = "e1000",
        .device_id = E1000_DEV_ID_82540EM,
        .revision  = 0x03,
        .phy_id2   = E1000_PHY_ID2_8254xx_DEFAULT,
@@ -1666,11 +1666,6 @@ static const E1000Info e1000_devices[] = {
    },
};

static const TypeInfo e1000_default_info = {
    .name          = "e1000",
    .parent        = "e1000-82540em",
};

static void e1000_register_types(void)
{
    int i;
@@ -1688,7 +1683,6 @@ static void e1000_register_types(void)

        type_register(&type_info);
    }
    type_register_static(&e1000_default_info);
}

type_init(e1000_register_types)
+15 −4
Original line number Diff line number Diff line
@@ -729,9 +729,7 @@ static void vmxnet3_process_tx_queue(VMXNET3State *s, int qidx)
        }

        if (txd.eop) {
            if (!s->skip_current_tx_pkt) {
                vmxnet_tx_pkt_parse(s->tx_pkt);

            if (!s->skip_current_tx_pkt && vmxnet_tx_pkt_parse(s->tx_pkt)) {
                if (s->needs_vlan) {
                    vmxnet_tx_pkt_setup_vlan_header(s->tx_pkt, s->tci);
                }
@@ -1165,9 +1163,13 @@ vmxnet3_io_bar0_write(void *opaque, hwaddr addr,
static uint64_t
vmxnet3_io_bar0_read(void *opaque, hwaddr addr, unsigned size)
{
    VMXNET3State *s = opaque;

    if (VMW_IS_MULTIREG_ADDR(addr, VMXNET3_REG_IMR,
                        VMXNET3_MAX_INTRS, VMXNET3_REG_ALIGN)) {
        g_assert_not_reached();
        int l = VMW_MULTIREG_IDX_BY_ADDR(addr, VMXNET3_REG_IMR,
                                         VMXNET3_REG_ALIGN);
        return s->interrupt_states[l].is_masked;
    }

    VMW_CBPRN("BAR0 unknown read [%" PRIx64 "], size %d", addr, size);
@@ -1629,6 +1631,11 @@ static void vmxnet3_handle_command(VMXNET3State *s, uint64_t cmd)
        VMW_CBPRN("Set: VMXNET3_CMD_GET_CONF_INTR - interrupt configuration");
        break;

    case VMXNET3_CMD_GET_ADAPTIVE_RING_INFO:
        VMW_CBPRN("Set: VMXNET3_CMD_GET_ADAPTIVE_RING_INFO - "
                  "adaptive ring info flags");
        break;

    default:
        VMW_CBPRN("Received unknown command: %" PRIx64, cmd);
        break;
@@ -1668,6 +1675,10 @@ static uint64_t vmxnet3_get_command_status(VMXNET3State *s)
        ret = vmxnet3_get_interrupt_config(s);
        break;

    case VMXNET3_CMD_GET_ADAPTIVE_RING_INFO:
        ret = VMXNET3_DISABLE_ADAPTIVE_RING;
        break;

    default:
        VMW_WRPRN("Received request for unknown command: %x", s->last_command);
        ret = -1;
+5 −1
Original line number Diff line number Diff line
@@ -198,9 +198,13 @@ enum {
    VMXNET3_CMD_GET_DID_LO,                               /* 0xF00D0005 */
    VMXNET3_CMD_GET_DID_HI,                               /* 0xF00D0006 */
    VMXNET3_CMD_GET_DEV_EXTRA_INFO,                       /* 0xF00D0007 */
    VMXNET3_CMD_GET_CONF_INTR                             /* 0xF00D0008 */
    VMXNET3_CMD_GET_CONF_INTR,                            /* 0xF00D0008 */
    VMXNET3_CMD_GET_ADAPTIVE_RING_INFO                    /* 0xF00D0009 */
};

/* Adaptive Ring Info Flags */
#define VMXNET3_DISABLE_ADAPTIVE_RING 1

/*
 *    Little Endian layout of bitfields -
 *    Byte 0 :    7.....len.....0
+16 −3
Original line number Diff line number Diff line
@@ -142,11 +142,24 @@ static bool vmxnet_tx_pkt_parse_headers(struct VmxnetTxPkt *pkt)

    bytes_read = iov_to_buf(pkt->raw, pkt->raw_frags, 0, l2_hdr->iov_base,
                            ETH_MAX_L2_HDR_LEN);
    if (bytes_read < ETH_MAX_L2_HDR_LEN) {
    if (bytes_read < sizeof(struct eth_header)) {
        l2_hdr->iov_len = 0;
        return false;
    }

    l2_hdr->iov_len = sizeof(struct eth_header);
    switch (be16_to_cpu(PKT_GET_ETH_HDR(l2_hdr->iov_base)->h_proto)) {
    case ETH_P_VLAN:
        l2_hdr->iov_len += sizeof(struct vlan_header);
        break;
    case ETH_P_DVLAN:
        l2_hdr->iov_len += 2 * sizeof(struct vlan_header);
        break;
    }

    if (bytes_read < l2_hdr->iov_len) {
        l2_hdr->iov_len = 0;
        return false;
    } else {
        l2_hdr->iov_len = eth_get_l2_hdr_length(l2_hdr->iov_base);
    }

    l3_proto = eth_get_l3_proto(l2_hdr->iov_base, l2_hdr->iov_len);

include/net/filter.h

0 → 100644
+77 −0
Original line number Diff line number Diff line
/*
 * Copyright (c) 2015 FUJITSU LIMITED
 * Author: Yang Hongyang <yanghy@cn.fujitsu.com>
 *
 * This work is licensed under the terms of the GNU GPL, version 2 or
 * later.  See the COPYING file in the top-level directory.
 */

#ifndef QEMU_NET_FILTER_H
#define QEMU_NET_FILTER_H

#include "qom/object.h"
#include "qemu-common.h"
#include "qemu/typedefs.h"
#include "net/queue.h"

#define TYPE_NETFILTER "netfilter"
#define NETFILTER(obj) \
    OBJECT_CHECK(NetFilterState, (obj), TYPE_NETFILTER)
#define NETFILTER_GET_CLASS(obj) \
    OBJECT_GET_CLASS(NetFilterClass, (obj), TYPE_NETFILTER)
#define NETFILTER_CLASS(klass) \
    OBJECT_CLASS_CHECK(NetFilterClass, (klass), TYPE_NETFILTER)

typedef void (FilterSetup) (NetFilterState *nf, Error **errp);
typedef void (FilterCleanup) (NetFilterState *nf);
/*
 * Return:
 *   0: finished handling the packet, we should continue
 *   size: filter stolen this packet, we stop pass this packet further
 */
typedef ssize_t (FilterReceiveIOV)(NetFilterState *nc,
                                   NetClientState *sender,
                                   unsigned flags,
                                   const struct iovec *iov,
                                   int iovcnt,
                                   NetPacketSent *sent_cb);

typedef struct NetFilterClass {
    ObjectClass parent_class;

    /* optional */
    FilterSetup *setup;
    FilterCleanup *cleanup;
    /* mandatory */
    FilterReceiveIOV *receive_iov;
} NetFilterClass;


struct NetFilterState {
    /* private */
    Object parent;

    /* protected */
    char *netdev_id;
    NetClientState *netdev;
    NetFilterDirection direction;
    char info_str[256];
    QTAILQ_ENTRY(NetFilterState) next;
};

ssize_t qemu_netfilter_receive(NetFilterState *nf,
                               NetFilterDirection direction,
                               NetClientState *sender,
                               unsigned flags,
                               const struct iovec *iov,
                               int iovcnt,
                               NetPacketSent *sent_cb);

/* pass the packet to the next filter */
ssize_t qemu_netfilter_pass_to_next(NetClientState *sender,
                                    unsigned flags,
                                    const struct iovec *iov,
                                    int iovcnt,
                                    void *opaque);

#endif /* QEMU_NET_FILTER_H */
Loading