aboutsummaryrefslogtreecommitdiff
path: root/net/netfilter
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2006-08-05 00:58:33 -0700
committerDavid S. Miller <davem@sunset.davemloft.net>2006-09-22 14:53:54 -0700
commit4cf411de49c65140b3c259748629b561c0d3340f (patch)
tree71dbc9fbbb0b64e805033665e3653d991abb0f7e /net/netfilter
parent84fa7933a33f806bbbaae6775e87459b1ec584c0 (diff)
[NETFILTER]: Get rid of HW checksum invalidation
Update hardware checksums incrementally to avoid breaking GSO. Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/netfilter')
-rw-r--r--net/netfilter/core.c22
1 files changed, 22 insertions, 0 deletions
diff --git a/net/netfilter/core.c b/net/netfilter/core.c
index 5d29d5e23624..27f639f3ac2a 100644
--- a/net/netfilter/core.c
+++ b/net/netfilter/core.c
@@ -222,6 +222,28 @@ copy_skb:
}
EXPORT_SYMBOL(skb_make_writable);
+u_int16_t nf_csum_update(u_int32_t oldval, u_int32_t newval, u_int32_t csum)
+{
+ u_int32_t diff[] = { oldval, newval };
+
+ return csum_fold(csum_partial((char *)diff, sizeof(diff), ~csum));
+}
+EXPORT_SYMBOL(nf_csum_update);
+
+u_int16_t nf_proto_csum_update(struct sk_buff *skb,
+ u_int32_t oldval, u_int32_t newval,
+ u_int16_t csum, int pseudohdr)
+{
+ if (skb->ip_summed != CHECKSUM_PARTIAL) {
+ csum = nf_csum_update(oldval, newval, csum);
+ if (skb->ip_summed == CHECKSUM_COMPLETE && pseudohdr)
+ skb->csum = nf_csum_update(oldval, newval, skb->csum);
+ } else if (pseudohdr)
+ csum = ~nf_csum_update(oldval, newval, ~csum);
+
+ return csum;
+}
+EXPORT_SYMBOL(nf_proto_csum_update);
/* This does not belong here, but locally generated errors need it if connection
tracking in use: without this, connection may not be in hash table, and hence