From: Alexander Duyck <hidden> Date: 2016-02-24 17:29:33
This patch series is meant to fix and/or improve a number of items within
the flow dissector code. The main change out of all of this is that IPv4
and IPv6 fragmentation should now be handled better than it was. As a
result we should see an improvement when handling things like IP fragment
reassembly as the skbs should now only have header data in the linear
portion of the buffer while the fragments will only hold payload data.
---
Alexander Duyck (5):
flow_dissector: Check for IP fragmentation even if not using IPv4 address
flow_dissector: Fix fragment handling for header length computation
flow_dissector: Correctly handle parsing FCoE
flow_dissector: Use same pointer for IPv4 and IPv6 addresses
eth: Pull header from first fragment via eth_get_headlen
net/core/flow_dissector.c | 45 ++++++++++++++++++++++++++-------------------
net/ethernet/eth.c | 3 ++-
2 files changed, 28 insertions(+), 20 deletions(-)
From: Alexander Duyck <hidden> Date: 2016-02-24 17:29:40
This patch corrects the logic for the IPv4 parsing so that it is consistent
with how we handle IPv6. Specifically if we do not have the flow key
indicating we want the addresses we still may need to take a look at the IP
fragmentation bits and to see if we should stop after we have recognized
the L3 header.
Fixes: 807e165dc44f ("flow_dissector: Add control/reporting of fragmentation")
Signed-off-by: Alexander Duyck <redacted>
---
net/core/flow_dissector.c | 17 +++++++++--------
1 file changed, 9 insertions(+), 8 deletions(-)
From: Alexander Duyck <hidden> Date: 2016-02-24 17:29:46
It turns out that for IPv4 we were reporting the ip_proto of the fragment,
and for IPv6 we were not. This patch updates that behavior so that we
always report the IP protocol of the fragment. In addition it takes the
steps of updating the payload offset code so that we will determine the
start of the payload not including the L4 header for any fragment after the
first.
Signed-off-by: Alexander Duyck <redacted>
---
net/core/flow_dissector.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
@@ -741,6 +740,11 @@ u32 __skb_get_poff(const struct sk_buff *skb, void *data,{u32poff=keys->control.thoff;+/* skip L4 headers for fragments after the first */+if((keys->control.flags&FLOW_DIS_IS_FRAGMENT)&&+!(keys->control.flags&FLOW_DIS_FIRST_FRAG))+returnpoff;+switch(keys->basic.ip_proto){caseIPPROTO_TCP:{/* access doff as u8 to avoid unaligned access */
From: Alexander Duyck <hidden> Date: 2016-02-24 17:29:53
The flow dissector bits handling FCoE didn't bother to actually validate
that the space there was enough for the FCoE header. So we need to update
things so that if there is room we add the header and report a good result,
otherwise we do not add the header, and report the bad result.
Signed-off-by: Alexander Duyck <redacted>
---
net/core/flow_dissector.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
@@ -340,8 +340,11 @@ mpls:}casehtons(ETH_P_FCOE):-key_control->thoff=(u16)(nhoff+FCOE_HEADER_LEN);-/* fall through */+if((hlen-nhoff)<FCOE_HEADER_LEN)+gotoout_bad;++nhoff+=FCOE_HEADER_LEN;+gotoout_good;default:gotoout_bad;}
From: Alexander Duyck <hidden> Date: 2016-02-24 17:29:59
The IPv6 parsing was using a local pointer when it could use the same
pointer as the IPv4 portion of the code since the key_addrs can support
both IPv4 and IPv6 as it is just a pointer.
Signed-off-by: Alexander Duyck <redacted>
---
net/core/flow_dissector.c | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)
From: Alexander Duyck <hidden> Date: 2016-02-24 17:30:05
We want to try and pull the L4 header in if it is available in the first
fragment. As such add the flag to indicate we want to pull the headers on
the first fragment in.
Signed-off-by: Alexander Duyck <redacted>
---
net/ethernet/eth.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
@@ -134,7 +135,7 @@ u32 eth_get_headlen(void *data, unsigned int len)/* parse any remaining L2/L3 headers, check for L4 */if(!skb_flow_dissect_flow_keys_buf(&keys,data,eth->h_proto,-sizeof(*eth),len,0))+sizeof(*eth),len,flags))returnmax_t(u32,keys.control.thoff,sizeof(*eth));/* parse for any L4 headers */
From: Tom Herbert <hidden> Date: 2016-02-24 18:14:26
On Wed, Feb 24, 2016 at 9:29 AM, Alexander Duyck [off-list ref] wrote:
This patch corrects the logic for the IPv4 parsing so that it is consistent
with how we handle IPv6. Specifically if we do not have the flow key
indicating we want the addresses we still may need to take a look at the IP
fragmentation bits and to see if we should stop after we have recognized
the L3 header.
Fixes: 807e165dc44f ("flow_dissector: Add control/reporting of fragmentation")
Signed-off-by: Alexander Duyck <redacted>
From: Tom Herbert <hidden> Date: 2016-02-24 18:14:47
On Wed, Feb 24, 2016 at 9:29 AM, Alexander Duyck [off-list ref] wrote:
It turns out that for IPv4 we were reporting the ip_proto of the fragment,
and for IPv6 we were not. This patch updates that behavior so that we
always report the IP protocol of the fragment. In addition it takes the
steps of updating the payload offset code so that we will determine the
start of the payload not including the L4 header for any fragment after the
first.
Signed-off-by: Alexander Duyck <redacted>
@@ -741,6 +740,11 @@ u32 __skb_get_poff(const struct sk_buff *skb, void *data,{u32poff=keys->control.thoff;+/* skip L4 headers for fragments after the first */+if((keys->control.flags&FLOW_DIS_IS_FRAGMENT)&&+!(keys->control.flags&FLOW_DIS_FIRST_FRAG))+returnpoff;+switch(keys->basic.ip_proto){caseIPPROTO_TCP:{/* access doff as u8 to avoid unaligned access */
From: Tom Herbert <hidden> Date: 2016-02-24 18:15:01
On Wed, Feb 24, 2016 at 9:29 AM, Alexander Duyck [off-list ref] wrote:
The flow dissector bits handling FCoE didn't bother to actually validate
that the space there was enough for the FCoE header. So we need to update
things so that if there is room we add the header and report a good result,
otherwise we do not add the header, and report the bad result.
Signed-off-by: Alexander Duyck <redacted>
@@ -340,8 +340,11 @@ mpls:}casehtons(ETH_P_FCOE):-key_control->thoff=(u16)(nhoff+FCOE_HEADER_LEN);-/* fall through */+if((hlen-nhoff)<FCOE_HEADER_LEN)+gotoout_bad;++nhoff+=FCOE_HEADER_LEN;+gotoout_good;default:gotoout_bad;}
From: Tom Herbert <hidden> Date: 2016-02-24 18:15:18
On Wed, Feb 24, 2016 at 9:29 AM, Alexander Duyck [off-list ref] wrote:
The IPv6 parsing was using a local pointer when it could use the same
pointer as the IPv4 portion of the code since the key_addrs can support
both IPv4 and IPv6 as it is just a pointer.
Signed-off-by: Alexander Duyck <redacted>
From: Tom Herbert <hidden> Date: 2016-02-24 18:15:51
On Wed, Feb 24, 2016 at 9:30 AM, Alexander Duyck [off-list ref] wrote:
We want to try and pull the L4 header in if it is available in the first
fragment. As such add the flag to indicate we want to pull the headers on
the first fragment in.
Signed-off-by: Alexander Duyck <redacted>
@@ -134,7 +135,7 @@ u32 eth_get_headlen(void *data, unsigned int len)/* parse any remaining L2/L3 headers, check for L4 */if(!skb_flow_dissect_flow_keys_buf(&keys,data,eth->h_proto,-sizeof(*eth),len,0))+sizeof(*eth),len,flags))returnmax_t(u32,keys.control.thoff,sizeof(*eth));/* parse for any L4 headers */