Commit da878c8e authored by Patrick McHardy's avatar Patrick McHardy Committed by David S. Miller
Browse files

[NETFILTER]: replace open coded checksum updates



Replace open coded checksum update by nf_csum_update calls and clean up
the surrounding code a bit.

Signed-off-by: default avatarPatrick McHardy <kaber@trash.net>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 1158ba27
Loading
Loading
Loading
Loading
+9 −13
Original line number Diff line number Diff line
@@ -27,22 +27,18 @@ MODULE_DESCRIPTION("iptables ECN modification module");
static inline int
set_ect_ip(struct sk_buff **pskb, const struct ipt_ECN_info *einfo)
{
	if (((*pskb)->nh.iph->tos & IPT_ECN_IP_MASK)
	    != (einfo->ip_ect & IPT_ECN_IP_MASK)) {
		u_int16_t diffs[2];
	struct iphdr *iph = (*pskb)->nh.iph;
	u_int16_t oldtos;

	if ((iph->tos & IPT_ECN_IP_MASK) != (einfo->ip_ect & IPT_ECN_IP_MASK)) {
		if (!skb_make_writable(pskb, sizeof(struct iphdr)))
			return 0;

		diffs[0] = htons((*pskb)->nh.iph->tos) ^ 0xFFFF;
		(*pskb)->nh.iph->tos &= ~IPT_ECN_IP_MASK;
		(*pskb)->nh.iph->tos |= (einfo->ip_ect & IPT_ECN_IP_MASK);
		diffs[1] = htons((*pskb)->nh.iph->tos);
		(*pskb)->nh.iph->check
			= csum_fold(csum_partial((char *)diffs,
						 sizeof(diffs),
						 (*pskb)->nh.iph->check
						 ^0xFFFF));
		iph = (*pskb)->nh.iph;
		oldtos = iph->tos;
		iph->tos &= ~IPT_ECN_IP_MASK;
		iph->tos |= (einfo->ip_ect & IPT_ECN_IP_MASK);
		iph->check = nf_csum_update(oldtos ^ 0xFFFF, iph->tos,
					    iph->check);
	} 
	return 1;
}
+8 −14
Original line number Diff line number Diff line
@@ -30,23 +30,17 @@ target(struct sk_buff **pskb,
       void *userinfo)
{
	const struct ipt_tos_target_info *tosinfo = targinfo;
	struct iphdr *iph = (*pskb)->nh.iph;
	u_int16_t oldtos;

	if (((*pskb)->nh.iph->tos & IPTOS_TOS_MASK) != tosinfo->tos) {
		u_int16_t diffs[2];

	if ((iph->tos & IPTOS_TOS_MASK) != tosinfo->tos) {
		if (!skb_make_writable(pskb, sizeof(struct iphdr)))
			return NF_DROP;

		diffs[0] = htons((*pskb)->nh.iph->tos) ^ 0xFFFF;
		(*pskb)->nh.iph->tos
			= ((*pskb)->nh.iph->tos & IPTOS_PREC_MASK)
			| tosinfo->tos;
		diffs[1] = htons((*pskb)->nh.iph->tos);
		(*pskb)->nh.iph->check
			= csum_fold(csum_partial((char *)diffs,
						 sizeof(diffs),
						 (*pskb)->nh.iph->check
						 ^0xFFFF));
		iph = (*pskb)->nh.iph;
		oldtos = iph->tos;
		iph->tos = (iph->tos & IPTOS_PREC_MASK) | tosinfo->tos;
		iph->check = nf_csum_update(oldtos ^ 0xFFFF, iph->tos,
					    iph->check);
	}
	return IPT_CONTINUE;
}
+3 −6
Original line number Diff line number Diff line
@@ -27,7 +27,6 @@ ipt_ttl_target(struct sk_buff **pskb,
{
	struct iphdr *iph;
	const struct ipt_TTL_info *info = targinfo;
	u_int16_t diffs[2];
	int new_ttl;

	if (!skb_make_writable(pskb, (*pskb)->len))
@@ -55,12 +54,10 @@ ipt_ttl_target(struct sk_buff **pskb,
	}

	if (new_ttl != iph->ttl) {
		diffs[0] = htons(((unsigned)iph->ttl) << 8) ^ 0xFFFF;
		iph->check = nf_csum_update((iph->ttl << 8) ^ 0xFFFF,
					    new_ttl << 8,
					    iph->check);
		iph->ttl = new_ttl;
		diffs[1] = htons(((unsigned)iph->ttl) << 8);
		iph->check = csum_fold(csum_partial((char *)diffs,
						    sizeof(diffs),
						    iph->check^0xFFFF));
	}

	return IPT_CONTINUE;