Skip to content

Commit f6ae9f1

Browse files
committed
netfilter: nft_payload: add C-VLAN support
If the encapsulated ethertype announces another inner VLAN header and the offset falls within the boundaries of the inner VLAN header, then adjust arithmetics to include the extra VLAN header length and fetch the bytes from the vlan header in the skbuff data area that represents this inner VLAN header. Signed-off-by: Pablo Neira Ayuso <[email protected]>
1 parent be193f5 commit f6ae9f1

File tree

1 file changed

+16
-7
lines changed

1 file changed

+16
-7
lines changed

net/netfilter/nft_payload.c

+16-7
Original file line numberDiff line numberDiff line change
@@ -43,27 +43,36 @@ nft_payload_copy_vlan(u32 *d, const struct sk_buff *skb, u8 offset, u8 len)
4343
int mac_off = skb_mac_header(skb) - skb->data;
4444
u8 *vlanh, *dst_u8 = (u8 *) d;
4545
struct vlan_ethhdr veth;
46+
u8 vlan_hlen = 0;
47+
48+
if ((skb->protocol == htons(ETH_P_8021AD) ||
49+
skb->protocol == htons(ETH_P_8021Q)) &&
50+
offset >= VLAN_ETH_HLEN && offset < VLAN_ETH_HLEN + VLAN_HLEN)
51+
vlan_hlen += VLAN_HLEN;
4652

4753
vlanh = (u8 *) &veth;
48-
if (offset < VLAN_ETH_HLEN) {
54+
if (offset < VLAN_ETH_HLEN + vlan_hlen) {
4955
u8 ethlen = len;
5056

51-
if (!nft_payload_rebuild_vlan_hdr(skb, mac_off, &veth))
57+
if (vlan_hlen &&
58+
skb_copy_bits(skb, mac_off, &veth, VLAN_ETH_HLEN) < 0)
59+
return false;
60+
else if (!nft_payload_rebuild_vlan_hdr(skb, mac_off, &veth))
5261
return false;
5362

54-
if (offset + len > VLAN_ETH_HLEN)
55-
ethlen -= offset + len - VLAN_ETH_HLEN;
63+
if (offset + len > VLAN_ETH_HLEN + vlan_hlen)
64+
ethlen -= offset + len - VLAN_ETH_HLEN + vlan_hlen;
5665

57-
memcpy(dst_u8, vlanh + offset, ethlen);
66+
memcpy(dst_u8, vlanh + offset - vlan_hlen, ethlen);
5867

5968
len -= ethlen;
6069
if (len == 0)
6170
return true;
6271

6372
dst_u8 += ethlen;
64-
offset = ETH_HLEN;
73+
offset = ETH_HLEN + vlan_hlen;
6574
} else {
66-
offset -= VLAN_HLEN;
75+
offset -= VLAN_HLEN + vlan_hlen;
6776
}
6877

6978
return skb_copy_bits(skb, offset + mac_off, dst_u8, len) == 0;

0 commit comments

Comments
 (0)