diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2016-03-08 10:25:50 +0000 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2016-03-08 10:25:50 +0000 |
commit | d1cc881d54d2abc9c90d92c90deccc8d47966b1c (patch) | |
tree | df46cf293e0e12fdd91068e3aa60b228a8ab061d /net/netmap.c | |
parent | 97556fe80e4f7252300b3498b3477fb4295153a3 (diff) | |
parent | 362786f14a753d8a5256ef97d7c10ed576d6572b (diff) | |
download | qemu-d1cc881d54d2abc9c90d92c90deccc8d47966b1c.zip qemu-d1cc881d54d2abc9c90d92c90deccc8d47966b1c.tar.gz qemu-d1cc881d54d2abc9c90d92c90deccc8d47966b1c.tar.bz2 |
Merge remote-tracking branch 'remotes/jasowang/tags/net-pull-request' into staging
# gpg: Signature made Tue 08 Mar 2016 07:46:08 GMT 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:
net: check packet payload length
filter-buffer: Add status_changed callback processing
filter: Add 'status' property for filter object
rocker: allow user to specify rocker world by property
rocker: add name field into WorldOps ale let world specify its name
rocker: return -ENOMEM in case of some world alloc fails
rocker: forbid to change world type
net: netmap: probe netmap interface for virtio-net header
net: simplify net_init_tap_one logic
MAINTAINERS: Add entries for include/net/ files
net: filter: correctly remove filter from the list during finalization
net: ne2000: check ring buffer control registers
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'net/netmap.c')
-rw-r--r-- | net/netmap.c | 59 |
1 files changed, 38 insertions, 21 deletions
diff --git a/net/netmap.c b/net/netmap.c index 9710321..1b42728 100644 --- a/net/netmap.c +++ b/net/netmap.c @@ -323,20 +323,47 @@ static void netmap_cleanup(NetClientState *nc) } /* Offloading manipulation support callbacks. */ -static bool netmap_has_ufo(NetClientState *nc) +static int netmap_fd_set_vnet_hdr_len(NetmapState *s, int len) { - return true; + struct nmreq req; + + /* Issue a NETMAP_BDG_VNET_HDR command to change the virtio-net header + * length for the netmap adapter associated to 's->ifname'. + */ + memset(&req, 0, sizeof(req)); + pstrcpy(req.nr_name, sizeof(req.nr_name), s->ifname); + req.nr_version = NETMAP_API; + req.nr_cmd = NETMAP_BDG_VNET_HDR; + req.nr_arg1 = len; + + return ioctl(s->nmd->fd, NIOCREGIF, &req); } -static bool netmap_has_vnet_hdr(NetClientState *nc) +static bool netmap_has_vnet_hdr_len(NetClientState *nc, int len) { + NetmapState *s = DO_UPCAST(NetmapState, nc, nc); + int prev_len = s->vnet_hdr_len; + + /* Check that we can set the new length. */ + if (netmap_fd_set_vnet_hdr_len(s, len)) { + return false; + } + + /* Restore the previous length. */ + if (netmap_fd_set_vnet_hdr_len(s, prev_len)) { + error_report("Failed to restore vnet-hdr length %d on %s: %s", + prev_len, s->ifname, strerror(errno)); + abort(); + } + return true; } -static bool netmap_has_vnet_hdr_len(NetClientState *nc, int len) +/* A netmap interface that supports virtio-net headers always + * supports UFO, so we use this callback also for the has_ufo hook. */ +static bool netmap_has_vnet_hdr(NetClientState *nc) { - return len == 0 || len == sizeof(struct virtio_net_hdr) || - len == sizeof(struct virtio_net_hdr_mrg_rxbuf); + return netmap_has_vnet_hdr_len(nc, sizeof(struct virtio_net_hdr)); } static void netmap_using_vnet_hdr(NetClientState *nc, bool enable) @@ -347,20 +374,11 @@ static void netmap_set_vnet_hdr_len(NetClientState *nc, int len) { NetmapState *s = DO_UPCAST(NetmapState, nc, nc); int err; - struct nmreq req; - /* Issue a NETMAP_BDG_VNET_HDR command to change the virtio-net header - * length for the netmap adapter associated to 's->ifname'. - */ - memset(&req, 0, sizeof(req)); - pstrcpy(req.nr_name, sizeof(req.nr_name), s->ifname); - req.nr_version = NETMAP_API; - req.nr_cmd = NETMAP_BDG_VNET_HDR; - req.nr_arg1 = len; - err = ioctl(s->nmd->fd, NIOCREGIF, &req); + err = netmap_fd_set_vnet_hdr_len(s, len); if (err) { - error_report("Unable to execute NETMAP_BDG_VNET_HDR on %s: %s", - s->ifname, strerror(errno)); + error_report("Unable to set vnet-hdr length %d on %s: %s", + len, s->ifname, strerror(errno)); } else { /* Keep track of the current length. */ s->vnet_hdr_len = len; @@ -373,8 +391,7 @@ static void netmap_set_offload(NetClientState *nc, int csum, int tso4, int tso6, NetmapState *s = DO_UPCAST(NetmapState, nc, nc); /* Setting a virtio-net header length greater than zero automatically - * enables the offloadings. - */ + * enables the offloadings. */ if (!s->vnet_hdr_len) { netmap_set_vnet_hdr_len(nc, sizeof(struct virtio_net_hdr)); } @@ -388,7 +405,7 @@ static NetClientInfo net_netmap_info = { .receive_iov = netmap_receive_iov, .poll = netmap_poll, .cleanup = netmap_cleanup, - .has_ufo = netmap_has_ufo, + .has_ufo = netmap_has_vnet_hdr, .has_vnet_hdr = netmap_has_vnet_hdr, .has_vnet_hdr_len = netmap_has_vnet_hdr_len, .using_vnet_hdr = netmap_using_vnet_hdr, |