[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
RE: [PATCH 06/40] net/net_rx_pkt: Use iovec for net_rx_pkt_set_protocols
From: |
Sriram Yagnaraman |
Subject: |
RE: [PATCH 06/40] net/net_rx_pkt: Use iovec for net_rx_pkt_set_protocols() |
Date: |
Sat, 15 Apr 2023 19:09:00 +0000 |
> -----Original Message-----
> From: Akihiko Odaki <akihiko.odaki@daynix.com>
> Sent: Friday, 14 April 2023 13:37
> Cc: Sriram Yagnaraman <sriram.yagnaraman@est.tech>; Jason Wang
> <jasowang@redhat.com>; Dmitry Fleytman <dmitry.fleytman@gmail.com>;
> Michael S. Tsirkin <mst@redhat.com>; Alex Bennée <alex.bennee@linaro.org>;
> Philippe Mathieu-Daudé <philmd@linaro.org>; Thomas Huth
> <thuth@redhat.com>; Wainer dos Santos Moschetta
> <wainersm@redhat.com>; Beraldo Leal <bleal@redhat.com>; Cleber Rosa
> <crosa@redhat.com>; Laurent Vivier <lvivier@redhat.com>; Paolo Bonzini
> <pbonzini@redhat.com>; qemu-devel@nongnu.org; Akihiko Odaki
> <akihiko.odaki@daynix.com>
> Subject: [PATCH 06/40] net/net_rx_pkt: Use iovec for
> net_rx_pkt_set_protocols()
>
> igb does not properly ensure the buffer passed to
> net_rx_pkt_set_protocols() is contiguous for the entire L2/L3/L4 header.
> Allow it to pass scattered data to net_rx_pkt_set_protocols().
>
> Fixes: 3a977deebe ("Intrdocue igb device emulation")
> Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
> ---
> hw/net/igb_core.c | 2 +-
> hw/net/net_rx_pkt.c | 14 +++++--------- hw/net/net_rx_pkt.h | 10 ++++++----
> hw/net/virtio-net.c | 7 +++++--
> hw/net/vmxnet3.c | 7 ++++++-
> include/net/eth.h | 6 +++---
> net/eth.c | 18 ++++++++----------
> 7 files changed, 34 insertions(+), 30 deletions(-)
>
Very nice.
Reviewed-by: Sriram Yagnaraman <sriram.yagnaraman@est.tech>
> diff --git a/hw/net/igb_core.c b/hw/net/igb_core.c index
> 5d4884b834..53f60fc3d3 100644
> --- a/hw/net/igb_core.c
> +++ b/hw/net/igb_core.c
> @@ -1650,7 +1650,7 @@ igb_receive_internal(IGBCore *core, const struct
> iovec *iov, int iovcnt,
>
> ehdr = PKT_GET_ETH_HDR(filter_buf);
> net_rx_pkt_set_packet_type(core->rx_pkt, get_eth_packet_type(ehdr));
> - net_rx_pkt_set_protocols(core->rx_pkt, filter_buf, size);
> + net_rx_pkt_set_protocols(core->rx_pkt, iov, iovcnt, iov_ofs);
>
> queues = igb_receive_assign(core, ehdr, size, &rss_info, external_tx);
> if (!queues) {
> diff --git a/hw/net/net_rx_pkt.c b/hw/net/net_rx_pkt.c index
> 39cdea06de..63be6e05ad 100644
> --- a/hw/net/net_rx_pkt.c
> +++ b/hw/net/net_rx_pkt.c
> @@ -103,7 +103,7 @@ net_rx_pkt_pull_data(struct NetRxPkt *pkt,
> iov, iovcnt, ploff, pkt->tot_len);
> }
>
> - eth_get_protocols(pkt->vec, pkt->vec_len, &pkt->hasip4, &pkt->hasip6,
> + eth_get_protocols(pkt->vec, pkt->vec_len, 0, &pkt->hasip4,
> + &pkt->hasip6,
> &pkt->l3hdr_off, &pkt->l4hdr_off, &pkt->l5hdr_off,
> &pkt->ip6hdr_info, &pkt->ip4hdr_info,
> &pkt->l4hdr_info);
>
> @@ -186,17 +186,13 @@ size_t net_rx_pkt_get_total_len(struct NetRxPkt
> *pkt)
> return pkt->tot_len;
> }
>
> -void net_rx_pkt_set_protocols(struct NetRxPkt *pkt, const void *data,
> - size_t len)
> +void net_rx_pkt_set_protocols(struct NetRxPkt *pkt,
> + const struct iovec *iov, size_t iovcnt,
> + size_t iovoff)
> {
> - const struct iovec iov = {
> - .iov_base = (void *)data,
> - .iov_len = len
> - };
> -
> assert(pkt);
>
> - eth_get_protocols(&iov, 1, &pkt->hasip4, &pkt->hasip6,
> + eth_get_protocols(iov, iovcnt, iovoff, &pkt->hasip4, &pkt->hasip6,
> &pkt->l3hdr_off, &pkt->l4hdr_off, &pkt->l5hdr_off,
> &pkt->ip6hdr_info, &pkt->ip4hdr_info,
> &pkt->l4hdr_info); } diff --
> git a/hw/net/net_rx_pkt.h b/hw/net/net_rx_pkt.h index
> d00b484900..a06f5c2675 100644
> --- a/hw/net/net_rx_pkt.h
> +++ b/hw/net/net_rx_pkt.h
> @@ -55,12 +55,14 @@ size_t net_rx_pkt_get_total_len(struct NetRxPkt *pkt);
> * parse and set packet analysis results
> *
> * @pkt: packet
> - * @data: pointer to the data buffer to be parsed
> - * @len: data length
> + * @iov: received data scatter-gather list
> + * @iovcnt: number of elements in iov
> + * @iovoff: data start offset in the iov
> *
> */
> -void net_rx_pkt_set_protocols(struct NetRxPkt *pkt, const void *data,
> - size_t len);
> +void net_rx_pkt_set_protocols(struct NetRxPkt *pkt,
> + const struct iovec *iov, size_t iovcnt,
> + size_t iovoff);
>
> /**
> * fetches packet analysis results
> diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c index
> 53e1c32643..37551fd854 100644
> --- a/hw/net/virtio-net.c
> +++ b/hw/net/virtio-net.c
> @@ -1835,9 +1835,12 @@ static int virtio_net_process_rss(NetClientState
> *nc, const uint8_t *buf,
> VIRTIO_NET_HASH_REPORT_UDPv6,
> VIRTIO_NET_HASH_REPORT_UDPv6_EX
> };
> + struct iovec iov = {
> + .iov_base = (void *)buf,
> + .iov_len = size
> + };
>
> - net_rx_pkt_set_protocols(pkt, buf + n->host_hdr_len,
> - size - n->host_hdr_len);
> + net_rx_pkt_set_protocols(pkt, &iov, 1, n->host_hdr_len);
> net_rx_pkt_get_protocols(pkt, &hasip4, &hasip6, &l4hdr_proto);
> net_hash_type = virtio_net_get_hash_type(hasip4, hasip6, l4hdr_proto,
> n->rss_data.hash_types); diff
> --git
> a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c index 9acff310e7..05f41b6dfa
> 100644
> --- a/hw/net/vmxnet3.c
> +++ b/hw/net/vmxnet3.c
> @@ -2001,7 +2001,12 @@ vmxnet3_receive(NetClientState *nc, const uint8_t
> *buf, size_t size)
> get_eth_packet_type(PKT_GET_ETH_HDR(buf)));
>
> if (vmxnet3_rx_filter_may_indicate(s, buf, size)) {
> - net_rx_pkt_set_protocols(s->rx_pkt, buf, size);
> + struct iovec iov = {
> + .iov_base = (void *)buf,
> + .iov_len = size
> + };
> +
> + net_rx_pkt_set_protocols(s->rx_pkt, &iov, 1, 0);
> vmxnet3_rx_need_csum_calculate(s->rx_pkt, buf, size);
> net_rx_pkt_attach_data(s->rx_pkt, buf, size, s->rx_vlan_stripping);
> bytes_indicated = vmxnet3_indicate_packet(s) ? size : -1; diff --git
> a/include/net/eth.h b/include/net/eth.h index c5ae4493b4..9f19c3a695
> 100644
> --- a/include/net/eth.h
> +++ b/include/net/eth.h
> @@ -312,10 +312,10 @@ eth_get_l2_hdr_length(const void *p) }
>
> static inline uint32_t
> -eth_get_l2_hdr_length_iov(const struct iovec *iov, int iovcnt)
> +eth_get_l2_hdr_length_iov(const struct iovec *iov, size_t iovcnt,
> +size_t iovoff)
> {
> uint8_t p[sizeof(struct eth_header) + sizeof(struct vlan_header)];
> - size_t copied = iov_to_buf(iov, iovcnt, 0, p, ARRAY_SIZE(p));
> + size_t copied = iov_to_buf(iov, iovcnt, iovoff, p, ARRAY_SIZE(p));
>
> if (copied < ARRAY_SIZE(p)) {
> return copied;
> @@ -397,7 +397,7 @@ typedef struct eth_l4_hdr_info_st {
> bool has_tcp_data;
> } eth_l4_hdr_info;
>
> -void eth_get_protocols(const struct iovec *iov, int iovcnt,
> +void eth_get_protocols(const struct iovec *iov, size_t iovcnt, size_t
> +iovoff,
> bool *hasip4, bool *hasip6,
> size_t *l3hdr_off,
> size_t *l4hdr_off, diff --git a/net/eth.c b/net/eth.c
> index
> 70bcd8e355..d7b30df79f 100644
> --- a/net/eth.c
> +++ b/net/eth.c
> @@ -136,7 +136,7 @@ _eth_tcp_has_data(bool is_ip4,
> return l4len > TCP_HEADER_DATA_OFFSET(tcp); }
>
> -void eth_get_protocols(const struct iovec *iov, int iovcnt,
> +void eth_get_protocols(const struct iovec *iov, size_t iovcnt, size_t
> +iovoff,
> bool *hasip4, bool *hasip6,
> size_t *l3hdr_off,
> size_t *l4hdr_off, @@ -147,26 +147,24 @@ void
> eth_get_protocols(const struct iovec *iov, int iovcnt, {
> int proto;
> bool fragment = false;
> - size_t l2hdr_len = eth_get_l2_hdr_length_iov(iov, iovcnt);
> size_t input_size = iov_size(iov, iovcnt);
> size_t copied;
> uint8_t ip_p;
>
> *hasip4 = *hasip6 = false;
> + *l3hdr_off = iovoff + eth_get_l2_hdr_length_iov(iov, iovcnt,
> + iovoff);
> l4hdr_info->proto = ETH_L4_HDR_PROTO_INVALID;
>
> - proto = eth_get_l3_proto(iov, iovcnt, l2hdr_len);
> -
> - *l3hdr_off = l2hdr_len;
> + proto = eth_get_l3_proto(iov, iovcnt, *l3hdr_off);
>
> if (proto == ETH_P_IP) {
> struct ip_header *iphdr = &ip4hdr_info->ip4_hdr;
>
> - if (input_size < l2hdr_len) {
> + if (input_size < *l3hdr_off) {
> return;
> }
>
> - copied = iov_to_buf(iov, iovcnt, l2hdr_len, iphdr, sizeof(*iphdr));
> + copied = iov_to_buf(iov, iovcnt, *l3hdr_off, iphdr,
> + sizeof(*iphdr));
> if (copied < sizeof(*iphdr) ||
> IP_HEADER_VERSION(iphdr) != IP_HEADER_VERSION_4) {
> return;
> @@ -175,17 +173,17 @@ void eth_get_protocols(const struct iovec *iov, int
> iovcnt,
> *hasip4 = true;
> ip_p = iphdr->ip_p;
> ip4hdr_info->fragment = IP4_IS_FRAGMENT(iphdr);
> - *l4hdr_off = l2hdr_len + IP_HDR_GET_LEN(iphdr);
> + *l4hdr_off = *l3hdr_off + IP_HDR_GET_LEN(iphdr);
>
> fragment = ip4hdr_info->fragment;
> } else if (proto == ETH_P_IPV6) {
> - if (!eth_parse_ipv6_hdr(iov, iovcnt, l2hdr_len, ip6hdr_info)) {
> + if (!eth_parse_ipv6_hdr(iov, iovcnt, *l3hdr_off, ip6hdr_info))
> + {
> return;
> }
>
> *hasip6 = true;
> ip_p = ip6hdr_info->l4proto;
> - *l4hdr_off = l2hdr_len + ip6hdr_info->full_hdr_len;
> + *l4hdr_off = *l3hdr_off + ip6hdr_info->full_hdr_len;
> fragment = ip6hdr_info->fragment;
> } else {
> return;
> --
> 2.40.0
- [PATCH 02/40] e1000x: Fix BPRC and MPRC, (continued)
- [PATCH 03/40] igb: Fix Rx packet type encoding, Akihiko Odaki, 2023/04/14
- [PATCH 05/40] igb: Do not require CTRL.VME for tx VLAN tagging, Akihiko Odaki, 2023/04/14
- [PATCH 06/40] net/net_rx_pkt: Use iovec for net_rx_pkt_set_protocols(), Akihiko Odaki, 2023/04/14
- RE: [PATCH 06/40] net/net_rx_pkt: Use iovec for net_rx_pkt_set_protocols(),
Sriram Yagnaraman <=
- [PATCH 07/40] e1000e: Always copy ethernet header, Akihiko Odaki, 2023/04/14
- [PATCH 08/40] igb: Always copy ethernet header, Akihiko Odaki, 2023/04/14
- [PATCH 09/40] Fix references to igb Avocado test, Akihiko Odaki, 2023/04/14
- [PATCH 11/40] tests/avocado: Remove test_igb_nomsi_kvm, Akihiko Odaki, 2023/04/14
- [PATCH 10/40] tests/avocado: Remove unused imports, Akihiko Odaki, 2023/04/14
- [PATCH 12/40] hw/net/net_tx_pkt: Remove net_rx_pkt_get_l4_info, Akihiko Odaki, 2023/04/14
- [PATCH 13/40] net/eth: Rename eth_setup_vlan_headers_ex, Akihiko Odaki, 2023/04/14