> -----Original Message----- > From: Akihiko Odaki <akihiko.od...@daynix.com> > Sent: Thursday, 20 April 2023 07:47 > Cc: Sriram Yagnaraman <sriram.yagnara...@est.tech>; Jason Wang > <jasow...@redhat.com>; Dmitry Fleytman <dmitry.fleyt...@gmail.com>; > Michael S . Tsirkin <m...@redhat.com>; Alex Bennée > <alex.ben...@linaro.org>; Philippe Mathieu-Daudé <phi...@linaro.org>; > Thomas Huth <th...@redhat.com>; Wainer dos Santos Moschetta > <waine...@redhat.com>; Beraldo Leal <bl...@redhat.com>; Cleber Rosa > <cr...@redhat.com>; Laurent Vivier <lviv...@redhat.com>; Paolo Bonzini > <pbonz...@redhat.com>; qemu-devel@nongnu.org; Tomasz Dzieciol > <t.dziec...@partner.samsung.com>; Akihiko Odaki > <akihiko.od...@daynix.com> > Subject: [PATCH v2 27/41] net/eth: Always add VLAN tag > > It is possible to have another VLAN tag even if the packet is already tagged. > > Signed-off-by: Akihiko Odaki <akihiko.od...@daynix.com> > --- > include/net/eth.h | 4 ++-- > hw/net/net_tx_pkt.c | 16 +++++++--------- > net/eth.c | 22 ++++++---------------- > 3 files changed, 15 insertions(+), 27 deletions(-) > > diff --git a/include/net/eth.h b/include/net/eth.h index > 95ff24d6b8..048e434685 100644 > --- a/include/net/eth.h > +++ b/include/net/eth.h > @@ -353,8 +353,8 @@ eth_strip_vlan_ex(const struct iovec *iov, int iovcnt, > size_t iovoff, uint16_t eth_get_l3_proto(const struct iovec *l2hdr_iov, int > iovcnt, size_t l2hdr_len); > > -void eth_setup_vlan_headers(struct eth_header *ehdr, uint16_t vlan_tag, > - uint16_t vlan_ethtype, bool *is_new); > +void eth_setup_vlan_headers(struct eth_header *ehdr, size_t *ehdr_size, > + uint16_t vlan_tag, uint16_t vlan_ethtype); > > > uint8_t eth_get_gso_type(uint16_t l3_proto, uint8_t *l3_hdr, uint8_t > l4proto); > diff --git a/hw/net/net_tx_pkt.c b/hw/net/net_tx_pkt.c index > ce6b102391..af8f77a3f0 100644 > --- a/hw/net/net_tx_pkt.c > +++ b/hw/net/net_tx_pkt.c > @@ -40,7 +40,10 @@ struct NetTxPkt { > > struct iovec *vec; > > - uint8_t l2_hdr[ETH_MAX_L2_HDR_LEN]; > + struct { > + struct eth_header eth; > + struct vlan_header vlan[3]; > + } l2_hdr; > union { > struct ip_header ip; > struct ip6_header ip6; > @@ -365,18 +368,13 @@ bool net_tx_pkt_build_vheader(struct NetTxPkt > *pkt, bool tso_enable, void net_tx_pkt_setup_vlan_header_ex(struct NetTxPkt > *pkt, > uint16_t vlan, uint16_t vlan_ethtype) { > - bool is_new; > assert(pkt); > > eth_setup_vlan_headers(pkt->vec[NET_TX_PKT_L2HDR_FRAG].iov_base, > - vlan, vlan_ethtype, &is_new); > + &pkt->vec[NET_TX_PKT_L2HDR_FRAG].iov_len, > + vlan, vlan_ethtype); > > - /* update l2hdrlen */ > - if (is_new) { > - pkt->hdr_len += sizeof(struct vlan_header); > - pkt->vec[NET_TX_PKT_L2HDR_FRAG].iov_len += > - sizeof(struct vlan_header); > - } > + pkt->hdr_len += sizeof(struct vlan_header); > } > > bool net_tx_pkt_add_raw_fragment(struct NetTxPkt *pkt, void *base, size_t > len) diff --git a/net/eth.c b/net/eth.c index f7ffbda600..5307978486 100644 > --- a/net/eth.c > +++ b/net/eth.c > @@ -21,26 +21,16 @@ > #include "net/checksum.h" > #include "net/tap.h" > > -void eth_setup_vlan_headers(struct eth_header *ehdr, uint16_t vlan_tag, > - uint16_t vlan_ethtype, bool *is_new) > +void eth_setup_vlan_headers(struct eth_header *ehdr, size_t *ehdr_size, > + uint16_t vlan_tag, uint16_t vlan_ethtype) > { > struct vlan_header *vhdr = PKT_GET_VLAN_HDR(ehdr); > > - switch (be16_to_cpu(ehdr->h_proto)) { > - case ETH_P_VLAN: > - case ETH_P_DVLAN: > - /* vlan hdr exists */ > - *is_new = false; > - break; > - > - default: > - /* No VLAN header, put a new one */ > - vhdr->h_proto = ehdr->h_proto; > - ehdr->h_proto = cpu_to_be16(vlan_ethtype); > - *is_new = true; > - break; > - } > + memmove(vhdr + 1, vhdr, *ehdr_size - ETH_HLEN);
Do we need a check that we are not overflowing the vlan array size? > vhdr->h_tci = cpu_to_be16(vlan_tag); > + vhdr->h_proto = ehdr->h_proto; > + ehdr->h_proto = cpu_to_be16(vlan_ethtype); > + *ehdr_size += sizeof(*vhdr); > } > > uint8_t > -- > 2.40.0