|
@@ -269,36 +269,50 @@ eth_strip_vlan(const struct iovec *iov, int iovcnt, size_t iovoff,
|
|
}
|
|
}
|
|
|
|
|
|
size_t
|
|
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 *payload_offset, uint16_t *tci)
|
|
{
|
|
{
|
|
struct vlan_header vlan_hdr;
|
|
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;
|
|
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
|
|
void
|