aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/netfilter.h26
-rw-r--r--include/linux/netfilter_ipv4/ip_conntrack_proto_gre.h4
-rw-r--r--net/ipv4/netfilter/ip_nat_core.c6
-rw-r--r--net/ipv4/netfilter/ip_nat_helper.c30
-rw-r--r--net/ipv4/netfilter/ip_nat_proto_gre.c8
-rw-r--r--net/ipv4/netfilter/ip_nat_proto_icmp.c6
-rw-r--r--net/ipv4/netfilter/ip_nat_proto_tcp.c5
-rw-r--r--net/ipv4/netfilter/ip_nat_proto_udp.c7
-rw-r--r--net/ipv4/netfilter/ipt_ECN.c11
-rw-r--r--net/ipv4/netfilter/ipt_TCPMSS.c24
-rw-r--r--net/ipv4/netfilter/ipt_TOS.c5
-rw-r--r--net/ipv4/netfilter/ipt_TTL.c5
-rw-r--r--net/netfilter/core.c27
13 files changed, 70 insertions, 94 deletions
diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h
index 707bb2e53c4e..6ab5e2d6133e 100644
--- a/include/linux/netfilter.h
+++ b/include/linux/netfilter.h
@@ -282,11 +282,27 @@ extern void nf_invalidate_cache(int pf);
282 Returns true or false. */ 282 Returns true or false. */
283extern int skb_make_writable(struct sk_buff **pskb, unsigned int writable_len); 283extern int skb_make_writable(struct sk_buff **pskb, unsigned int writable_len);
284 284
285extern u_int16_t nf_csum_update(u_int32_t oldval, u_int32_t newval, 285static inline void nf_csum_replace4(__sum16 *sum, __be32 from, __be32 to)
286 u_int32_t csum); 286{
287extern u_int16_t nf_proto_csum_update(struct sk_buff *skb, 287 __be32 diff[] = { ~from, to };
288 u_int32_t oldval, u_int32_t newval, 288
289 u_int16_t csum, int pseudohdr); 289 *sum = csum_fold(csum_partial((char *)diff, sizeof(diff), ~csum_unfold(*sum)));
290}
291
292static inline void nf_csum_replace2(__sum16 *sum, __be16 from, __be16 to)
293{
294 nf_csum_replace4(sum, (__force __be32)from, (__force __be32)to);
295}
296
297extern void nf_proto_csum_replace4(__sum16 *sum, struct sk_buff *skb,
298 __be32 from, __be32 to, int pseudohdr);
299
300static inline void nf_proto_csum_replace2(__sum16 *sum, struct sk_buff *skb,
301 __be16 from, __be16 to, int pseudohdr)
302{
303 nf_proto_csum_replace4(sum, skb, (__force __be32)from,
304 (__force __be32)to, pseudohdr);
305}
290 306
291struct nf_afinfo { 307struct nf_afinfo {
292 unsigned short family; 308 unsigned short family;
diff --git a/include/linux/netfilter_ipv4/ip_conntrack_proto_gre.h b/include/linux/netfilter_ipv4/ip_conntrack_proto_gre.h
index 1d853aa873eb..e371e0fc1672 100644
--- a/include/linux/netfilter_ipv4/ip_conntrack_proto_gre.h
+++ b/include/linux/netfilter_ipv4/ip_conntrack_proto_gre.h
@@ -102,11 +102,11 @@ static inline __be32 *gre_key(struct gre_hdr *greh)
102} 102}
103 103
104/* get pointer ot gre csum, if present */ 104/* get pointer ot gre csum, if present */
105static inline u_int16_t *gre_csum(struct gre_hdr *greh) 105static inline __sum16 *gre_csum(struct gre_hdr *greh)
106{ 106{
107 if (!greh->csum) 107 if (!greh->csum)
108 return NULL; 108 return NULL;
109 return (u_int16_t *) (greh+sizeof(*greh)); 109 return (__sum16 *) (greh+sizeof(*greh));
110} 110}
111 111
112#endif /* __KERNEL__ */ 112#endif /* __KERNEL__ */
diff --git a/net/ipv4/netfilter/ip_nat_core.c b/net/ipv4/netfilter/ip_nat_core.c
index 4b6260a97408..9d1a5175dcd4 100644
--- a/net/ipv4/netfilter/ip_nat_core.c
+++ b/net/ipv4/netfilter/ip_nat_core.c
@@ -362,12 +362,10 @@ manip_pkt(u_int16_t proto,
362 iph = (void *)(*pskb)->data + iphdroff; 362 iph = (void *)(*pskb)->data + iphdroff;
363 363
364 if (maniptype == IP_NAT_MANIP_SRC) { 364 if (maniptype == IP_NAT_MANIP_SRC) {
365 iph->check = nf_csum_update(~iph->saddr, target->src.ip, 365 nf_csum_replace4(&iph->check, iph->saddr, target->src.ip);
366 iph->check);
367 iph->saddr = target->src.ip; 366 iph->saddr = target->src.ip;
368 } else { 367 } else {
369 iph->check = nf_csum_update(~iph->daddr, target->dst.ip, 368 nf_csum_replace4(&iph->check, iph->daddr, target->dst.ip);
370 iph->check);
371 iph->daddr = target->dst.ip; 369 iph->daddr = target->dst.ip;
372 } 370 }
373 return 1; 371 return 1;
diff --git a/net/ipv4/netfilter/ip_nat_helper.c b/net/ipv4/netfilter/ip_nat_helper.c
index 3e7fd64c2162..ee80feb4b2a9 100644
--- a/net/ipv4/netfilter/ip_nat_helper.c
+++ b/net/ipv4/netfilter/ip_nat_helper.c
@@ -188,10 +188,8 @@ ip_nat_mangle_tcp_packet(struct sk_buff **pskb,
188 csum_partial((char *)tcph, 188 csum_partial((char *)tcph,
189 datalen, 0)); 189 datalen, 0));
190 } else 190 } else
191 tcph->check = nf_proto_csum_update(*pskb, 191 nf_proto_csum_replace2(&tcph->check, *pskb,
192 htons(oldlen) ^ htons(0xFFFF), 192 htons(oldlen), htons(datalen), 1);
193 htons(datalen),
194 tcph->check, 1);
195 193
196 if (rep_len != match_len) { 194 if (rep_len != match_len) {
197 set_bit(IPS_SEQ_ADJUST_BIT, &ct->status); 195 set_bit(IPS_SEQ_ADJUST_BIT, &ct->status);
@@ -266,10 +264,8 @@ ip_nat_mangle_udp_packet(struct sk_buff **pskb,
266 if (!udph->check) 264 if (!udph->check)
267 udph->check = CSUM_MANGLED_0; 265 udph->check = CSUM_MANGLED_0;
268 } else 266 } else
269 udph->check = nf_proto_csum_update(*pskb, 267 nf_proto_csum_replace2(&udph->check, *pskb,
270 htons(oldlen) ^ htons(0xFFFF), 268 htons(oldlen), htons(datalen), 1);
271 htons(datalen),
272 udph->check, 1);
273 return 1; 269 return 1;
274} 270}
275EXPORT_SYMBOL(ip_nat_mangle_udp_packet); 271EXPORT_SYMBOL(ip_nat_mangle_udp_packet);
@@ -307,14 +303,10 @@ sack_adjust(struct sk_buff *skb,
307 ntohl(sack->start_seq), new_start_seq, 303 ntohl(sack->start_seq), new_start_seq,
308 ntohl(sack->end_seq), new_end_seq); 304 ntohl(sack->end_seq), new_end_seq);
309 305
310 tcph->check = nf_proto_csum_update(skb, 306 nf_proto_csum_replace4(&tcph->check, skb,
311 ~sack->start_seq, 307 sack->start_seq, new_start_seq, 0);
312 new_start_seq, 308 nf_proto_csum_replace4(&tcph->check, skb,
313 tcph->check, 0); 309 sack->end_seq, new_end_seq, 0);
314 tcph->check = nf_proto_csum_update(skb,
315 ~sack->end_seq,
316 new_end_seq,
317 tcph->check, 0);
318 sack->start_seq = new_start_seq; 310 sack->start_seq = new_start_seq;
319 sack->end_seq = new_end_seq; 311 sack->end_seq = new_end_seq;
320 sackoff += sizeof(*sack); 312 sackoff += sizeof(*sack);
@@ -397,10 +389,8 @@ ip_nat_seq_adjust(struct sk_buff **pskb,
397 else 389 else
398 newack = htonl(ntohl(tcph->ack_seq) - other_way->offset_before); 390 newack = htonl(ntohl(tcph->ack_seq) - other_way->offset_before);
399 391
400 tcph->check = nf_proto_csum_update(*pskb, ~tcph->seq, newseq, 392 nf_proto_csum_replace4(&tcph->check, *pskb, tcph->seq, newseq, 0);
401 tcph->check, 0); 393 nf_proto_csum_replace4(&tcph->check, *pskb, tcph->ack_seq, newack, 0);
402 tcph->check = nf_proto_csum_update(*pskb, ~tcph->ack_seq, newack,
403 tcph->check, 0);
404 394
405 DEBUGP("Adjusting sequence number from %u->%u, ack from %u->%u\n", 395 DEBUGP("Adjusting sequence number from %u->%u, ack from %u->%u\n",
406 ntohl(tcph->seq), ntohl(newseq), ntohl(tcph->ack_seq), 396 ntohl(tcph->seq), ntohl(newseq), ntohl(tcph->ack_seq),
diff --git a/net/ipv4/netfilter/ip_nat_proto_gre.c b/net/ipv4/netfilter/ip_nat_proto_gre.c
index bf91f9312b3c..95810202d849 100644
--- a/net/ipv4/netfilter/ip_nat_proto_gre.c
+++ b/net/ipv4/netfilter/ip_nat_proto_gre.c
@@ -129,11 +129,9 @@ gre_manip_pkt(struct sk_buff **pskb,
129 } 129 }
130 if (greh->csum) { 130 if (greh->csum) {
131 /* FIXME: Never tested this code... */ 131 /* FIXME: Never tested this code... */
132 *(gre_csum(greh)) = 132 nf_proto_csum_replace4(gre_csum(greh), *pskb,
133 nf_proto_csum_update(*pskb, 133 *(gre_key(greh)),
134 ~*(gre_key(greh)), 134 tuple->dst.u.gre.key, 0);
135 tuple->dst.u.gre.key,
136 *(gre_csum(greh)), 0);
137 } 135 }
138 *(gre_key(greh)) = tuple->dst.u.gre.key; 136 *(gre_key(greh)) = tuple->dst.u.gre.key;
139 break; 137 break;
diff --git a/net/ipv4/netfilter/ip_nat_proto_icmp.c b/net/ipv4/netfilter/ip_nat_proto_icmp.c
index 3f6efc13ac74..75266fe3e0fa 100644
--- a/net/ipv4/netfilter/ip_nat_proto_icmp.c
+++ b/net/ipv4/netfilter/ip_nat_proto_icmp.c
@@ -66,10 +66,8 @@ icmp_manip_pkt(struct sk_buff **pskb,
66 return 0; 66 return 0;
67 67
68 hdr = (struct icmphdr *)((*pskb)->data + hdroff); 68 hdr = (struct icmphdr *)((*pskb)->data + hdroff);
69 hdr->checksum = nf_proto_csum_update(*pskb, 69 nf_proto_csum_replace2(&hdr->checksum, *pskb,
70 hdr->un.echo.id ^ htons(0xFFFF), 70 hdr->un.echo.id, tuple->src.u.icmp.id, 0);
71 tuple->src.u.icmp.id,
72 hdr->checksum, 0);
73 hdr->un.echo.id = tuple->src.u.icmp.id; 71 hdr->un.echo.id = tuple->src.u.icmp.id;
74 return 1; 72 return 1;
75} 73}
diff --git a/net/ipv4/netfilter/ip_nat_proto_tcp.c b/net/ipv4/netfilter/ip_nat_proto_tcp.c
index 12deb13b93b1..b586d18b3fb3 100644
--- a/net/ipv4/netfilter/ip_nat_proto_tcp.c
+++ b/net/ipv4/netfilter/ip_nat_proto_tcp.c
@@ -129,9 +129,8 @@ tcp_manip_pkt(struct sk_buff **pskb,
129 if (hdrsize < sizeof(*hdr)) 129 if (hdrsize < sizeof(*hdr))
130 return 1; 130 return 1;
131 131
132 hdr->check = nf_proto_csum_update(*pskb, ~oldip, newip, hdr->check, 1); 132 nf_proto_csum_replace4(&hdr->check, *pskb, oldip, newip, 1);
133 hdr->check = nf_proto_csum_update(*pskb, oldport ^ htons(0xFFFF), newport, 133 nf_proto_csum_replace2(&hdr->check, *pskb, oldport, newport, 0);
134 hdr->check, 0);
135 return 1; 134 return 1;
136} 135}
137 136
diff --git a/net/ipv4/netfilter/ip_nat_proto_udp.c b/net/ipv4/netfilter/ip_nat_proto_udp.c
index 82f8a6ab07ec..5ced0877b32f 100644
--- a/net/ipv4/netfilter/ip_nat_proto_udp.c
+++ b/net/ipv4/netfilter/ip_nat_proto_udp.c
@@ -115,11 +115,8 @@ udp_manip_pkt(struct sk_buff **pskb,
115 } 115 }
116 116
117 if (hdr->check || (*pskb)->ip_summed == CHECKSUM_PARTIAL) { 117 if (hdr->check || (*pskb)->ip_summed == CHECKSUM_PARTIAL) {
118 hdr->check = nf_proto_csum_update(*pskb, ~oldip, newip, 118 nf_proto_csum_replace4(&hdr->check, *pskb, oldip, newip, 1);
119 hdr->check, 1); 119 nf_proto_csum_replace2(&hdr->check, *pskb, *portptr, newport, 0);
120 hdr->check = nf_proto_csum_update(*pskb,
121 *portptr ^ htons(0xFFFF), newport,
122 hdr->check, 0);
123 if (!hdr->check) 120 if (!hdr->check)
124 hdr->check = CSUM_MANGLED_0; 121 hdr->check = CSUM_MANGLED_0;
125 } 122 }
diff --git a/net/ipv4/netfilter/ipt_ECN.c b/net/ipv4/netfilter/ipt_ECN.c
index 1aa4517fbcdb..b55d670a24df 100644
--- a/net/ipv4/netfilter/ipt_ECN.c
+++ b/net/ipv4/netfilter/ipt_ECN.c
@@ -28,17 +28,16 @@ static inline int
28set_ect_ip(struct sk_buff **pskb, const struct ipt_ECN_info *einfo) 28set_ect_ip(struct sk_buff **pskb, const struct ipt_ECN_info *einfo)
29{ 29{
30 struct iphdr *iph = (*pskb)->nh.iph; 30 struct iphdr *iph = (*pskb)->nh.iph;
31 u_int16_t oldtos;
32 31
33 if ((iph->tos & IPT_ECN_IP_MASK) != (einfo->ip_ect & IPT_ECN_IP_MASK)) { 32 if ((iph->tos & IPT_ECN_IP_MASK) != (einfo->ip_ect & IPT_ECN_IP_MASK)) {
33 __u8 oldtos;
34 if (!skb_make_writable(pskb, sizeof(struct iphdr))) 34 if (!skb_make_writable(pskb, sizeof(struct iphdr)))
35 return 0; 35 return 0;
36 iph = (*pskb)->nh.iph; 36 iph = (*pskb)->nh.iph;
37 oldtos = iph->tos; 37 oldtos = iph->tos;
38 iph->tos &= ~IPT_ECN_IP_MASK; 38 iph->tos &= ~IPT_ECN_IP_MASK;
39 iph->tos |= (einfo->ip_ect & IPT_ECN_IP_MASK); 39 iph->tos |= (einfo->ip_ect & IPT_ECN_IP_MASK);
40 iph->check = nf_csum_update(htons(oldtos) ^ htons(0xFFFF), 40 nf_csum_replace2(&iph->check, htons(oldtos), htons(iph->tos));
41 htons(iph->tos), iph->check);
42 } 41 }
43 return 1; 42 return 1;
44} 43}
@@ -72,10 +71,8 @@ set_ect_tcp(struct sk_buff **pskb, const struct ipt_ECN_info *einfo)
72 if (einfo->operation & IPT_ECN_OP_SET_CWR) 71 if (einfo->operation & IPT_ECN_OP_SET_CWR)
73 tcph->cwr = einfo->proto.tcp.cwr; 72 tcph->cwr = einfo->proto.tcp.cwr;
74 73
75 tcph->check = nf_proto_csum_update((*pskb), 74 nf_proto_csum_replace2(&tcph->check, *pskb,
76 oldval ^ htons(0xFFFF), 75 oldval, ((__be16 *)tcph)[6], 0);
77 ((__be16 *)tcph)[6],
78 tcph->check, 0);
79 return 1; 76 return 1;
80} 77}
81 78
diff --git a/net/ipv4/netfilter/ipt_TCPMSS.c b/net/ipv4/netfilter/ipt_TCPMSS.c
index 108b6b76311f..93eb5c3c1884 100644
--- a/net/ipv4/netfilter/ipt_TCPMSS.c
+++ b/net/ipv4/netfilter/ipt_TCPMSS.c
@@ -97,10 +97,8 @@ ipt_tcpmss_target(struct sk_buff **pskb,
97 opt[i+2] = (newmss & 0xff00) >> 8; 97 opt[i+2] = (newmss & 0xff00) >> 8;
98 opt[i+3] = (newmss & 0x00ff); 98 opt[i+3] = (newmss & 0x00ff);
99 99
100 tcph->check = nf_proto_csum_update(*pskb, 100 nf_proto_csum_replace2(&tcph->check, *pskb,
101 htons(oldmss)^htons(0xFFFF), 101 htons(oldmss), htons(newmss), 0);
102 htons(newmss),
103 tcph->check, 0);
104 return IPT_CONTINUE; 102 return IPT_CONTINUE;
105 } 103 }
106 } 104 }
@@ -126,28 +124,22 @@ ipt_tcpmss_target(struct sk_buff **pskb,
126 opt = (u_int8_t *)tcph + sizeof(struct tcphdr); 124 opt = (u_int8_t *)tcph + sizeof(struct tcphdr);
127 memmove(opt + TCPOLEN_MSS, opt, tcplen - sizeof(struct tcphdr)); 125 memmove(opt + TCPOLEN_MSS, opt, tcplen - sizeof(struct tcphdr));
128 126
129 tcph->check = nf_proto_csum_update(*pskb, 127 nf_proto_csum_replace2(&tcph->check, *pskb,
130 htons(tcplen) ^ htons(0xFFFF), 128 htons(tcplen), htons(tcplen + TCPOLEN_MSS), 1);
131 htons(tcplen + TCPOLEN_MSS),
132 tcph->check, 1);
133 opt[0] = TCPOPT_MSS; 129 opt[0] = TCPOPT_MSS;
134 opt[1] = TCPOLEN_MSS; 130 opt[1] = TCPOLEN_MSS;
135 opt[2] = (newmss & 0xff00) >> 8; 131 opt[2] = (newmss & 0xff00) >> 8;
136 opt[3] = (newmss & 0x00ff); 132 opt[3] = (newmss & 0x00ff);
137 133
138 tcph->check = nf_proto_csum_update(*pskb, htonl(~0), *((__be32 *)opt), 134 nf_proto_csum_replace4(&tcph->check, *pskb, 0, *((__be32 *)opt), 0);
139 tcph->check, 0);
140 135
141 oldval = ((__be16 *)tcph)[6]; 136 oldval = ((__be16 *)tcph)[6];
142 tcph->doff += TCPOLEN_MSS/4; 137 tcph->doff += TCPOLEN_MSS/4;
143 tcph->check = nf_proto_csum_update(*pskb, 138 nf_proto_csum_replace2(&tcph->check, *pskb,
144 oldval ^ htons(0xFFFF), 139 oldval, ((__be16 *)tcph)[6], 0);
145 ((__be16 *)tcph)[6],
146 tcph->check, 0);
147 140
148 newtotlen = htons(ntohs(iph->tot_len) + TCPOLEN_MSS); 141 newtotlen = htons(ntohs(iph->tot_len) + TCPOLEN_MSS);
149 iph->check = nf_csum_update(iph->tot_len ^ htons(0xFFFF), 142 nf_csum_replace2(&iph->check, iph->tot_len, newtotlen);
150 newtotlen, iph->check);
151 iph->tot_len = newtotlen; 143 iph->tot_len = newtotlen;
152 return IPT_CONTINUE; 144 return IPT_CONTINUE;
153} 145}
diff --git a/net/ipv4/netfilter/ipt_TOS.c b/net/ipv4/netfilter/ipt_TOS.c
index 83b80b3a5d2f..18e74ac4d425 100644
--- a/net/ipv4/netfilter/ipt_TOS.c
+++ b/net/ipv4/netfilter/ipt_TOS.c
@@ -30,16 +30,15 @@ target(struct sk_buff **pskb,
30{ 30{
31 const struct ipt_tos_target_info *tosinfo = targinfo; 31 const struct ipt_tos_target_info *tosinfo = targinfo;
32 struct iphdr *iph = (*pskb)->nh.iph; 32 struct iphdr *iph = (*pskb)->nh.iph;
33 u_int16_t oldtos;
34 33
35 if ((iph->tos & IPTOS_TOS_MASK) != tosinfo->tos) { 34 if ((iph->tos & IPTOS_TOS_MASK) != tosinfo->tos) {
35 __u8 oldtos;
36 if (!skb_make_writable(pskb, sizeof(struct iphdr))) 36 if (!skb_make_writable(pskb, sizeof(struct iphdr)))
37 return NF_DROP; 37 return NF_DROP;
38 iph = (*pskb)->nh.iph; 38 iph = (*pskb)->nh.iph;
39 oldtos = iph->tos; 39 oldtos = iph->tos;
40 iph->tos = (iph->tos & IPTOS_PREC_MASK) | tosinfo->tos; 40 iph->tos = (iph->tos & IPTOS_PREC_MASK) | tosinfo->tos;
41 iph->check = nf_csum_update(htons(oldtos) ^ htons(0xFFFF), 41 nf_csum_replace2(&iph->check, htons(oldtos), htons(iph->tos));
42 htons(iph->tos), iph->check);
43 } 42 }
44 return IPT_CONTINUE; 43 return IPT_CONTINUE;
45} 44}
diff --git a/net/ipv4/netfilter/ipt_TTL.c b/net/ipv4/netfilter/ipt_TTL.c
index ac9517d62af0..fffe5ca82e91 100644
--- a/net/ipv4/netfilter/ipt_TTL.c
+++ b/net/ipv4/netfilter/ipt_TTL.c
@@ -54,9 +54,8 @@ ipt_ttl_target(struct sk_buff **pskb,
54 } 54 }
55 55
56 if (new_ttl != iph->ttl) { 56 if (new_ttl != iph->ttl) {
57 iph->check = nf_csum_update(htons((iph->ttl << 8)) ^ htons(0xFFFF), 57 nf_csum_replace2(&iph->check, htons(iph->ttl << 8),
58 htons(new_ttl << 8), 58 htons(new_ttl << 8));
59 iph->check);
60 iph->ttl = new_ttl; 59 iph->ttl = new_ttl;
61 } 60 }
62 61
diff --git a/net/netfilter/core.c b/net/netfilter/core.c
index d80b935b3a92..17f9e1cbc73b 100644
--- a/net/netfilter/core.c
+++ b/net/netfilter/core.c
@@ -222,28 +222,21 @@ copy_skb:
222} 222}
223EXPORT_SYMBOL(skb_make_writable); 223EXPORT_SYMBOL(skb_make_writable);
224 224
225u_int16_t nf_csum_update(u_int32_t oldval, u_int32_t newval, u_int32_t csum) 225void nf_proto_csum_replace4(__sum16 *sum, struct sk_buff *skb,
226{ 226 __be32 from, __be32 to, int pseudohdr)
227 u_int32_t diff[] = { oldval, newval };
228
229 return csum_fold(csum_partial((char *)diff, sizeof(diff), ~csum));
230}
231EXPORT_SYMBOL(nf_csum_update);
232
233u_int16_t nf_proto_csum_update(struct sk_buff *skb,
234 u_int32_t oldval, u_int32_t newval,
235 u_int16_t csum, int pseudohdr)
236{ 227{
228 __be32 diff[] = { ~from, to };
237 if (skb->ip_summed != CHECKSUM_PARTIAL) { 229 if (skb->ip_summed != CHECKSUM_PARTIAL) {
238 csum = nf_csum_update(oldval, newval, csum); 230 *sum = csum_fold(csum_partial((char *)diff, sizeof(diff),
231 ~csum_unfold(*sum)));
239 if (skb->ip_summed == CHECKSUM_COMPLETE && pseudohdr) 232 if (skb->ip_summed == CHECKSUM_COMPLETE && pseudohdr)
240 skb->csum = nf_csum_update(oldval, newval, skb->csum); 233 skb->csum = ~csum_partial((char *)diff, sizeof(diff),
234 ~skb->csum);
241 } else if (pseudohdr) 235 } else if (pseudohdr)
242 csum = ~nf_csum_update(oldval, newval, ~csum); 236 *sum = ~csum_fold(csum_partial((char *)diff, sizeof(diff),
243 237 csum_unfold(*sum)));
244 return csum;
245} 238}
246EXPORT_SYMBOL(nf_proto_csum_update); 239EXPORT_SYMBOL(nf_proto_csum_replace4);
247 240
248/* This does not belong here, but locally generated errors need it if connection 241/* This does not belong here, but locally generated errors need it if connection
249 tracking in use: without this, connection may not be in hash table, and hence 242 tracking in use: without this, connection may not be in hash table, and hence