aboutsummaryrefslogtreecommitdiff
path: root/hw/net
diff options
context:
space:
mode:
authorAkihiko Odaki <akihiko.odaki@daynix.com>2023-05-23 11:43:29 +0900
committerJason Wang <jasowang@redhat.com>2023-05-23 15:20:15 +0800
commit7e64a9cabb6b8fe12d315e355e0c362e1453f227 (patch)
tree0aeab89dc78e4a682a068db32d1da82949c0cc44 /hw/net
parentf199b13bc113c46eaddcf9f375d13f1e400b4e35 (diff)
downloadqemu-7e64a9cabb6b8fe12d315e355e0c362e1453f227.zip
qemu-7e64a9cabb6b8fe12d315e355e0c362e1453f227.tar.gz
qemu-7e64a9cabb6b8fe12d315e355e0c362e1453f227.tar.bz2
igb: Strip the second VLAN tag for extended VLAN
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com> Signed-off-by: Jason Wang <jasowang@redhat.com>
Diffstat (limited to 'hw/net')
-rw-r--r--hw/net/e1000e_core.c3
-rw-r--r--hw/net/igb_core.c14
-rw-r--r--hw/net/net_rx_pkt.c15
-rw-r--r--hw/net/net_rx_pkt.h19
4 files changed, 30 insertions, 21 deletions
diff --git a/hw/net/e1000e_core.c b/hw/net/e1000e_core.c
index 0b939ff..d601386 100644
--- a/hw/net/e1000e_core.c
+++ b/hw/net/e1000e_core.c
@@ -1711,7 +1711,8 @@ e1000e_receive_internal(E1000ECore *core, const struct iovec *iov, int iovcnt,
}
net_rx_pkt_attach_iovec_ex(core->rx_pkt, iov, iovcnt, iov_ofs,
- e1000x_vlan_enabled(core->mac), core->mac[VET]);
+ e1000x_vlan_enabled(core->mac) ? 0 : -1,
+ core->mac[VET], 0);
e1000e_rss_parse_packet(core, core->rx_pkt, &rss_info);
e1000e_rx_ring_init(core, &rxr, rss_info.queue);
diff --git a/hw/net/igb_core.c b/hw/net/igb_core.c
index 5eacf1c..688eaf7 100644
--- a/hw/net/igb_core.c
+++ b/hw/net/igb_core.c
@@ -1611,6 +1611,7 @@ igb_receive_internal(IGBCore *core, const struct iovec *iov, int iovcnt,
E1000E_RxRing rxr;
E1000E_RSSInfo rss_info;
size_t total_size;
+ int strip_vlan_index;
int i;
trace_e1000e_rx_receive_iov(iovcnt);
@@ -1672,9 +1673,18 @@ igb_receive_internal(IGBCore *core, const struct iovec *iov, int iovcnt,
igb_rx_ring_init(core, &rxr, i);
+ if (!igb_rx_strip_vlan(core, rxr.i)) {
+ strip_vlan_index = -1;
+ } else if (core->mac[CTRL_EXT] & BIT(26)) {
+ strip_vlan_index = 1;
+ } else {
+ strip_vlan_index = 0;
+ }
+
net_rx_pkt_attach_iovec_ex(core->rx_pkt, iov, iovcnt, iov_ofs,
- igb_rx_strip_vlan(core, rxr.i),
- core->mac[VET] & 0xffff);
+ strip_vlan_index,
+ core->mac[VET] & 0xffff,
+ core->mac[VET] >> 16);
total_size = net_rx_pkt_get_total_len(core->rx_pkt) +
e1000x_fcs_len(core->mac);
diff --git a/hw/net/net_rx_pkt.c b/hw/net/net_rx_pkt.c
index 3575c8b..32e5f3f 100644
--- a/hw/net/net_rx_pkt.c
+++ b/hw/net/net_rx_pkt.c
@@ -137,20 +137,17 @@ void net_rx_pkt_attach_iovec(struct NetRxPkt *pkt,
void net_rx_pkt_attach_iovec_ex(struct NetRxPkt *pkt,
const struct iovec *iov, int iovcnt,
- size_t iovoff, bool strip_vlan,
- uint16_t vet)
+ size_t iovoff, int strip_vlan_index,
+ uint16_t vet, uint16_t vet_ext)
{
uint16_t tci = 0;
uint16_t ploff = iovoff;
assert(pkt);
- if (strip_vlan) {
- pkt->ehdr_buf_len = eth_strip_vlan_ex(iov, iovcnt, iovoff, vet,
- &pkt->ehdr_buf,
- &ploff, &tci);
- } else {
- pkt->ehdr_buf_len = 0;
- }
+ pkt->ehdr_buf_len = eth_strip_vlan_ex(iov, iovcnt, iovoff,
+ strip_vlan_index, vet, vet_ext,
+ &pkt->ehdr_buf,
+ &ploff, &tci);
pkt->tci = tci;
diff --git a/hw/net/net_rx_pkt.h b/hw/net/net_rx_pkt.h
index ce8dbdb..55ec67a 100644
--- a/hw/net/net_rx_pkt.h
+++ b/hw/net/net_rx_pkt.h
@@ -223,18 +223,19 @@ void net_rx_pkt_attach_iovec(struct NetRxPkt *pkt,
/**
* attach scatter-gather data to rx packet
*
-* @pkt: packet
-* @iov: received data scatter-gather list
-* @iovcnt number of elements in iov
-* @iovoff data start offset in the iov
-* @strip_vlan: should the module strip vlan from data
-* @vet: VLAN tag Ethernet type
+* @pkt: packet
+* @iov: received data scatter-gather list
+* @iovcnt: number of elements in iov
+* @iovoff: data start offset in the iov
+* @strip_vlan_index: index of Q tag if it is to be stripped. negative otherwise.
+* @vet: VLAN tag Ethernet type
+* @vet_ext: outer VLAN tag Ethernet type
*
*/
void net_rx_pkt_attach_iovec_ex(struct NetRxPkt *pkt,
- const struct iovec *iov, int iovcnt,
- size_t iovoff, bool strip_vlan,
- uint16_t vet);
+ const struct iovec *iov, int iovcnt,
+ size_t iovoff, int strip_vlan_index,
+ uint16_t vet, uint16_t vet_ext);
/**
* attach data to rx packet