Early in the datapath skb_vlan_untag function is called, stripped
the vlan from the skb and set skb->vlan_tci and skb->vlan_proto fields.
The current dissection doesn't handle vlan packets correctly. Vlan
doesn't exist in skb->data anymore when applying flow dissection on the
skb, fix that.
Fixes: 0744dd00c1b1 ('net: introduce skb_flow_dissect()')
Signed-off-by: Hadar Hen Zion <[email protected]>
---
net/core/flow_dissector.c | 13 +++----------
1 file changed, 3 insertions(+), 10 deletions(-)
diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c
index 61ad43f..6060fc2 100644
--- a/net/core/flow_dissector.c
+++ b/net/core/flow_dissector.c
@@ -122,7 +122,8 @@ bool __skb_flow_dissect(const struct sk_buff *skb,
if (!data) {
data = skb->data;
- proto = skb->protocol;
+ proto = skb_vlan_tag_present(skb) ?
+ skb->vlan_proto : skb->protocol;
nhoff = skb_network_offset(skb);
hlen = skb_headlen(skb);
}
@@ -240,13 +241,6 @@ ipv6:
}
case htons(ETH_P_8021AD):
case htons(ETH_P_8021Q): {
- const struct vlan_hdr *vlan;
- struct vlan_hdr _vlan;
-
- vlan = __skb_header_pointer(skb, nhoff, sizeof(_vlan), data,
hlen, &_vlan);
- if (!vlan)
- goto out_bad;
-
if (dissector_uses_key(flow_dissector,
FLOW_DISSECTOR_KEY_VLANID)) {
key_tags = skb_flow_dissector_target(flow_dissector,
@@ -256,8 +250,7 @@ ipv6:
key_tags->vlan_id = skb_vlan_tag_get_id(skb);
}
- proto = vlan->h_vlan_encapsulated_proto;
- nhoff += sizeof(*vlan);
+ proto = skb->protocol;
goto again;
}
case htons(ETH_P_PPP_SES): {
--
1.8.3.1