From: Changli Gao on 29 May 2010 06:50 fix the wrong checksum when addr isn't in old_addr/mask When addr isn't in old_addr/mask we don't do SNAT or DNAT, and we should not update the checksum too. Signed-off-by: Changli Gao <xiaosuo(a)gmail.com> ---- net/sched/act_nat.c | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/net/sched/act_nat.c b/net/sched/act_nat.c index d885ba3..f9b12a9 100644 --- a/net/sched/act_nat.c +++ b/net/sched/act_nat.c @@ -142,24 +142,25 @@ static int tcf_nat(struct sk_buff *skb, struct tc_action *a, else addr = iph->daddr; - if (!((old_addr ^ addr) & mask)) { - if (skb_cloned(skb) && - !skb_clone_writable(skb, sizeof(*iph)) && - pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) - goto drop; + if ((old_addr ^ addr) & mask) + goto out; - new_addr &= mask; - new_addr |= addr & ~mask; + if (skb_cloned(skb) && + !skb_clone_writable(skb, sizeof(*iph)) && + pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) + goto drop; - /* Rewrite IP header */ - iph = ip_hdr(skb); - if (egress) - iph->saddr = new_addr; - else - iph->daddr = new_addr; + new_addr &= mask; + new_addr |= addr & ~mask; - csum_replace4(&iph->check, addr, new_addr); - } + /* Rewrite IP header */ + iph = ip_hdr(skb); + if (egress) + iph->saddr = new_addr; + else + iph->daddr = new_addr; + + csum_replace4(&iph->check, addr, new_addr); ihl = iph->ihl * 4; @@ -247,6 +248,7 @@ static int tcf_nat(struct sk_buff *skb, struct tc_action *a, break; } +out: return action; drop: -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo(a)vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
|
Pages: 1 Prev: input/touchscreen: Synaptics Touchscreen Driver Next: linux-kernel@vger.kernel.org |