Eric Woudstra <ericwouds@xxxxxxxxx> wrote: > In the conntrack hook it may not always be the case that: > skb_network_header(skb) == skb->data. > > This is problematic when L4 function nf_conntrack_handle_packet() > is accessing L3 data. This function uses thoff and ip_hdr() > to finds it's data. But it also calculates the checksum. > nf_checksum() and nf_checksum_partial() both use lower skb-checksum > functions that are based on using skb->data. > > When skb_network_header(skb) != skb->data, adjust accordingly, > so that the checksum is calculated correctly. > > Signed-off-by: Eric Woudstra <ericwouds@xxxxxxxxx> > --- > net/netfilter/utils.c | 20 ++++++++++++++------ > 1 file changed, 14 insertions(+), 6 deletions(-) > > diff --git a/net/netfilter/utils.c b/net/netfilter/utils.c > index 008419db815a..9ba822983bc0 100644 > --- a/net/netfilter/utils.c > +++ b/net/netfilter/utils.c > @@ -124,16 +124,20 @@ __sum16 nf_checksum(struct sk_buff *skb, unsigned int hook, > unsigned int dataoff, u8 protocol, > unsigned short family) > { > + unsigned int nhpull = skb_network_header(skb) - skb->data; skb_network_offset() ? And can you add a comment that tells why there is a need for pull/push pair despite the dataoff - nhpull argument? > + DEBUG_NET_WARN_ON_ONCE(!skb_pointer_if_linear(skb, nhpull, 0)); maybe if (DEBUG_NET_WARN ... return 0 ? > @@ -143,18 +147,22 @@ __sum16 nf_checksum_partial(struct sk_buff *skb, unsigned int hook, > unsigned int dataoff, unsigned int len, > u8 protocol, unsigned short family) > { > + unsigned int nhpull = skb_network_header(skb) - skb->data; > __sum16 csum = 0; > + DEBUG_NET_WARN_ON_ONCE(!skb_pointer_if_linear(skb, nhpull, 0)); > + __skb_pull(skb, nhpull); Same here, but no need to copy the comment from nf_checksum, its enough to say something like "see nf_checksum()".