Commit a9f54596 authored by Patrick McHardy's avatar Patrick McHardy Committed by David S. Miller

[NETFILTER]: ipt_ECN/ipt_TOS: fix incorrect checksum update

Even though the tos field is only a single byte large, the values need to
be converted to net-endian for the checkum update so they are in the
corrent byte position. Also fix incorrect endian annotations.

Reported by Stephane Chazelas <Stephane_Chazelas@yahoo.fr>
Signed-off-by: default avatarPatrick McHardy <kaber@trash.net>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent f603b6ec
...@@ -28,7 +28,7 @@ static inline int ...@@ -28,7 +28,7 @@ static inline int
set_ect_ip(struct sk_buff **pskb, const struct ipt_ECN_info *einfo) set_ect_ip(struct sk_buff **pskb, const struct ipt_ECN_info *einfo)
{ {
struct iphdr *iph = (*pskb)->nh.iph; struct iphdr *iph = (*pskb)->nh.iph;
__be16 oldtos; u_int16_t oldtos;
if ((iph->tos & IPT_ECN_IP_MASK) != (einfo->ip_ect & IPT_ECN_IP_MASK)) { if ((iph->tos & IPT_ECN_IP_MASK) != (einfo->ip_ect & IPT_ECN_IP_MASK)) {
if (!skb_make_writable(pskb, sizeof(struct iphdr))) if (!skb_make_writable(pskb, sizeof(struct iphdr)))
...@@ -37,8 +37,8 @@ set_ect_ip(struct sk_buff **pskb, const struct ipt_ECN_info *einfo) ...@@ -37,8 +37,8 @@ set_ect_ip(struct sk_buff **pskb, const struct ipt_ECN_info *einfo)
oldtos = iph->tos; oldtos = iph->tos;
iph->tos &= ~IPT_ECN_IP_MASK; iph->tos &= ~IPT_ECN_IP_MASK;
iph->tos |= (einfo->ip_ect & IPT_ECN_IP_MASK); iph->tos |= (einfo->ip_ect & IPT_ECN_IP_MASK);
iph->check = nf_csum_update(oldtos ^ htons(0xFFFF), iph->tos, iph->check = nf_csum_update(htons(oldtos) ^ htons(0xFFFF),
iph->check); htons(iph->tos), iph->check);
} }
return 1; return 1;
} }
......
...@@ -30,7 +30,7 @@ target(struct sk_buff **pskb, ...@@ -30,7 +30,7 @@ target(struct sk_buff **pskb,
{ {
const struct ipt_tos_target_info *tosinfo = targinfo; const struct ipt_tos_target_info *tosinfo = targinfo;
struct iphdr *iph = (*pskb)->nh.iph; struct iphdr *iph = (*pskb)->nh.iph;
__be16 oldtos; u_int16_t oldtos;
if ((iph->tos & IPTOS_TOS_MASK) != tosinfo->tos) { if ((iph->tos & IPTOS_TOS_MASK) != tosinfo->tos) {
if (!skb_make_writable(pskb, sizeof(struct iphdr))) if (!skb_make_writable(pskb, sizeof(struct iphdr)))
...@@ -38,8 +38,8 @@ target(struct sk_buff **pskb, ...@@ -38,8 +38,8 @@ target(struct sk_buff **pskb,
iph = (*pskb)->nh.iph; iph = (*pskb)->nh.iph;
oldtos = iph->tos; oldtos = iph->tos;
iph->tos = (iph->tos & IPTOS_PREC_MASK) | tosinfo->tos; iph->tos = (iph->tos & IPTOS_PREC_MASK) | tosinfo->tos;
iph->check = nf_csum_update(oldtos ^ htons(0xFFFF), iph->tos, iph->check = nf_csum_update(htons(oldtos) ^ htons(0xFFFF),
iph->check); htons(iph->tos), iph->check);
} }
return IPT_CONTINUE; return IPT_CONTINUE;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment