aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/netfilter.c
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2006-04-06 17:18:43 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2006-04-10 01:25:41 -0400
commit422c346fad806e2abaeffac686860ebc98dfe33e (patch)
treedd554d11e80ad33afef4b438ec4c2d8943ad37f4 /net/ipv4/netfilter.c
parentbce8032ef3cc58170ab3550e9e271dba7b4c4764 (diff)
[NETFILTER]: Add address family specific checksum helpers
Add checksum operation which takes care of verifying the checksum and dealing with HW checksum errors and avoids multiple checksum operations by setting ip_summed to CHECKSUM_UNNECESSARY after successful verification. Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/netfilter.c')
-rw-r--r--net/ipv4/netfilter.c33
1 files changed, 33 insertions, 0 deletions
diff --git a/net/ipv4/netfilter.c b/net/ipv4/netfilter.c
index b25339c11ea..6a9e34b794b 100644
--- a/net/ipv4/netfilter.c
+++ b/net/ipv4/netfilter.c
@@ -161,8 +161,41 @@ static int nf_ip_reroute(struct sk_buff **pskb, const struct nf_info *info)
161 return 0; 161 return 0;
162} 162}
163 163
164unsigned int nf_ip_checksum(struct sk_buff *skb, unsigned int hook,
165 unsigned int dataoff, u_int8_t protocol)
166{
167 struct iphdr *iph = skb->nh.iph;
168 unsigned int csum = 0;
169
170 switch (skb->ip_summed) {
171 case CHECKSUM_HW:
172 if (hook != NF_IP_PRE_ROUTING && hook != NF_IP_LOCAL_IN)
173 break;
174 if ((protocol == 0 && !(u16)csum_fold(skb->csum)) ||
175 !csum_tcpudp_magic(iph->saddr, iph->daddr,
176 skb->len - dataoff, protocol,
177 skb->csum)) {
178 skb->ip_summed = CHECKSUM_UNNECESSARY;
179 break;
180 }
181 /* fall through */
182 case CHECKSUM_NONE:
183 if (protocol == 0)
184 skb->csum = 0;
185 else
186 skb->csum = csum_tcpudp_nofold(iph->saddr, iph->daddr,
187 skb->len - dataoff,
188 protocol, 0);
189 csum = __skb_checksum_complete(skb);
190 }
191 return csum;
192}
193
194EXPORT_SYMBOL(nf_ip_checksum);
195
164static struct nf_afinfo nf_ip_afinfo = { 196static struct nf_afinfo nf_ip_afinfo = {
165 .family = AF_INET, 197 .family = AF_INET,
198 .checksum = nf_ip_checksum,
166 .saveroute = nf_ip_saveroute, 199 .saveroute = nf_ip_saveroute,
167 .reroute = nf_ip_reroute, 200 .reroute = nf_ip_reroute,
168 .route_key_size = sizeof(struct ip_rt_info), 201 .route_key_size = sizeof(struct ip_rt_info),