X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=net%2Fipv4%2Fnetfilter%2Fip_nat_proto_udp.c;h=7bff78319896f5922ca0aac94909e8d31ace10af;hb=97bf2856c6014879bd04983a3e9dfcdac1e7fe85;hp=ec6053fdc867db4ae033e2e831f8c50a95e3c577;hpb=76828883507a47dae78837ab5dec5a5b4513c667;p=linux-2.6.git diff --git a/net/ipv4/netfilter/ip_nat_proto_udp.c b/net/ipv4/netfilter/ip_nat_proto_udp.c index ec6053fdc..7bff78319 100644 --- a/net/ipv4/netfilter/ip_nat_proto_udp.c +++ b/net/ipv4/netfilter/ip_nat_proto_udp.c @@ -24,7 +24,7 @@ udp_in_range(const struct ip_conntrack_tuple *tuple, const union ip_conntrack_manip_proto *min, const union ip_conntrack_manip_proto *max) { - u_int16_t port; + __be16 port; if (maniptype == IP_NAT_MANIP_SRC) port = tuple->src.u.udp.port; @@ -42,7 +42,7 @@ udp_unique_tuple(struct ip_conntrack_tuple *tuple, const struct ip_conntrack *conntrack) { static u_int16_t port; - u_int16_t *portptr; + __be16 *portptr; unsigned int range_size, min, i; if (maniptype == IP_NAT_MANIP_SRC) @@ -91,8 +91,8 @@ udp_manip_pkt(struct sk_buff **pskb, struct iphdr *iph = (struct iphdr *)((*pskb)->data + iphdroff); struct udphdr *hdr; unsigned int hdroff = iphdroff + iph->ihl*4; - u32 oldip, newip; - u16 *portptr, newport; + __be32 oldip, newip; + __be16 *portptr, newport; if (!skb_make_writable(pskb, hdroff + sizeof(*hdr))) return 0; @@ -113,11 +113,21 @@ udp_manip_pkt(struct sk_buff **pskb, newport = tuple->dst.u.udp.port; portptr = &hdr->dest; } - if (hdr->check) /* 0 is a special case meaning no checksum */ - hdr->check = ip_nat_cheat_check(~oldip, newip, - ip_nat_cheat_check(*portptr ^ 0xFFFF, - newport, - hdr->check)); + + if (hdr->check || (*pskb)->ip_summed == CHECKSUM_PARTIAL) { +#ifdef CONFIG_XEN + if ((*pskb)->proto_csum_blank) + nf_csum_replace4(&hdr->check, oldip, newip); + else +#endif + { + nf_proto_csum_replace4(&hdr->check, *pskb, oldip, newip, 1); + nf_proto_csum_replace2(&hdr->check, *pskb, *portptr, newport, 0); + } + + if (!hdr->check) + hdr->check = CSUM_MANGLED_0; + } *portptr = newport; return 1; }