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>
This commit is contained in:
Akihiko Odaki 2023-05-23 11:43:29 +09:00 committed by Jason Wang
parent f199b13bc1
commit 7e64a9cabb
6 changed files with 66 additions and 43 deletions

View file

@ -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;
uint16_t *new_ehdr_proto;
size_t new_ehdr_size;
size_t copied;
size_t copied = iov_to_buf(iov, iovcnt, iovoff,
new_ehdr, sizeof(*new_ehdr));
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(*new_ehdr)) {
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;
default:
return 0;
}
if (be16_to_cpu(new_ehdr->h_proto) == vet) {
copied = iov_to_buf(iov, iovcnt, iovoff + sizeof(*new_ehdr),
&vlan_hdr, sizeof(vlan_hdr));
if (copied < sizeof(vlan_hdr)) {
return 0;
}
new_ehdr->h_proto = vlan_hdr.h_proto;
*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;
}
return 0;
copied = iov_to_buf(iov, iovcnt, iovoff + new_ehdr_size,
&vlan_hdr, sizeof(vlan_hdr));
if (copied < sizeof(vlan_hdr)) {
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