[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 34/40] igb: Strip the second VLAN tag for extended VLAN
From: |
Akihiko Odaki |
Subject: |
[PATCH 34/40] igb: Strip the second VLAN tag for extended VLAN |
Date: |
Fri, 14 Apr 2023 20:37:31 +0900 |
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
---
hw/net/e1000e_core.c | 3 ++-
hw/net/igb_core.c | 14 ++++++++++--
hw/net/net_rx_pkt.c | 15 +++++--------
hw/net/net_rx_pkt.h | 19 ++++++++--------
include/net/eth.h | 4 ++--
net/eth.c | 52 ++++++++++++++++++++++++++++----------------
6 files changed, 65 insertions(+), 42 deletions(-)
diff --git a/hw/net/e1000e_core.c b/hw/net/e1000e_core.c
index 9dc8b718c0..56a46b1897 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 955db1b1dc..6e8de9d878 100644
--- a/hw/net/igb_core.c
+++ b/hw/net/igb_core.c
@@ -1621,6 +1621,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);
@@ -1677,9 +1678,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 3575c8b9f9..32e5f3f9cf 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 ce8dbdb284..55ec67a1a7 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
diff --git a/include/net/eth.h b/include/net/eth.h
index 6d65b7e2cb..7e76a4b139 100644
--- a/include/net/eth.h
+++ b/include/net/eth.h
@@ -345,8 +345,8 @@ eth_strip_vlan(const struct iovec *iov, int iovcnt, size_t
iovoff,
uint16_t *payload_offset, uint16_t *tci);
size_t
-eth_strip_vlan_ex(const struct iovec *iov, int iovcnt, size_t iovoff,
- uint16_t vet, void *new_ehdr_buf,
+eth_strip_vlan_ex(const struct iovec *iov, int iovcnt, size_t iovoff, int
index,
+ uint16_t vet, uint16_t vet_ext, void *new_ehdr_buf,
uint16_t *payload_offset, uint16_t *tci);
uint16_t
diff --git a/net/eth.c b/net/eth.c
index 7f02aea010..649e66bb1f 100644
--- a/net/eth.c
+++ b/net/eth.c
@@ -269,36 +269,50 @@ eth_strip_vlan(const struct iovec *iov, int iovcnt,
size_t iovoff,
}
size_t
-eth_strip_vlan_ex(const struct iovec *iov, int iovcnt, size_t iovoff,
- uint16_t vet, void *new_ehdr_buf,
+eth_strip_vlan_ex(const struct iovec *iov, int iovcnt, size_t iovoff, int
index,
+ uint16_t vet, uint16_t vet_ext, void *new_ehdr_buf,
uint16_t *payload_offset, uint16_t *tci)
{
struct vlan_header vlan_hdr;
- struct eth_header *new_ehdr = (struct eth_header *) new_ehdr_buf;
-
- size_t copied = iov_to_buf(iov, iovcnt, iovoff,
- new_ehdr, sizeof(*new_ehdr));
-
- if (copied < sizeof(*new_ehdr)) {
- return 0;
- }
+ uint16_t *new_ehdr_proto;
+ size_t new_ehdr_size;
+ size_t copied;
- if (be16_to_cpu(new_ehdr->h_proto) == vet) {
- copied = iov_to_buf(iov, iovcnt, iovoff + sizeof(*new_ehdr),
- &vlan_hdr, sizeof(vlan_hdr));
+ switch (index) {
+ case 0:
+ new_ehdr_proto = &PKT_GET_ETH_HDR(new_ehdr_buf)->h_proto;
+ new_ehdr_size = sizeof(struct eth_header);
+ copied = iov_to_buf(iov, iovcnt, iovoff, new_ehdr_buf, new_ehdr_size);
+ break;
- if (copied < sizeof(vlan_hdr)) {
+ case 1:
+ new_ehdr_proto = &PKT_GET_VLAN_HDR(new_ehdr_buf)->h_proto;
+ new_ehdr_size = sizeof(struct eth_header) + sizeof(struct vlan_header);
+ copied = iov_to_buf(iov, iovcnt, iovoff, new_ehdr_buf, new_ehdr_size);
+ if (be16_to_cpu(PKT_GET_ETH_HDR(new_ehdr_buf)->h_proto) != vet_ext) {
return 0;
}
+ break;
- new_ehdr->h_proto = vlan_hdr.h_proto;
+ default:
+ return 0;
+ }
- *tci = be16_to_cpu(vlan_hdr.h_tci);
- *payload_offset = iovoff + sizeof(*new_ehdr) + sizeof(vlan_hdr);
- return sizeof(struct eth_header);
+ if (copied < new_ehdr_size || be16_to_cpu(*new_ehdr_proto) != vet) {
+ return 0;
+ }
+
+ copied = iov_to_buf(iov, iovcnt, iovoff + new_ehdr_size,
+ &vlan_hdr, sizeof(vlan_hdr));
+ if (copied < sizeof(vlan_hdr)) {
+ return 0;
}
- return 0;
+ *new_ehdr_proto = vlan_hdr.h_proto;
+ *payload_offset = iovoff + new_ehdr_size + sizeof(vlan_hdr);
+ *tci = be16_to_cpu(vlan_hdr.h_tci);
+
+ return new_ehdr_size;
}
void
--
2.40.0
- RE: [PATCH 30/40] igb: Implement igb-specific oversize check, (continued)
- [PATCH 31/40] igb: Use UDP for RSS hash, Akihiko Odaki, 2023/04/14
- [PATCH 38/40] vmxnet3: Do not depend on PC, Akihiko Odaki, 2023/04/14
- [PATCH 37/40] igb: Implement Tx timestamp, Akihiko Odaki, 2023/04/14
- [PATCH 33/40] igb: Implement Tx SCTP CSO, Akihiko Odaki, 2023/04/14
- [PATCH 39/40] MAINTAINERS: Add a reviewer for network packet abstractions, Akihiko Odaki, 2023/04/14
- [PATCH 34/40] igb: Strip the second VLAN tag for extended VLAN,
Akihiko Odaki <=
- [PATCH 40/40] docs/system/devices/igb: Note igb is tested for DPDK, Akihiko Odaki, 2023/04/14
- [PATCH 36/40] igb: Implement Rx PTP2 timestamp, Akihiko Odaki, 2023/04/14
- [PATCH 32/40] igb: Implement Rx SCTP CSO, Akihiko Odaki, 2023/04/14
- [PATCH 35/40] igb: Filter with the second VLAN tag for extended VLAN, Akihiko Odaki, 2023/04/14