diff options
| author | Sridhar Samudrala <sri@us.ibm.com> | 2006-06-17 22:57:28 -0700 | 
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2006-06-17 22:57:28 -0700 | 
| commit | 503b55fd77d11381b1950d1651d3bc782c0cc2cd (patch) | |
| tree | a960542bcc10b97218a601a94e56e579595c0a2c /net | |
| parent | 4c9f5d5305a23851e67471b147e0d459a7166717 (diff) | |
| download | kernel_samsung_tuna-503b55fd77d11381b1950d1651d3bc782c0cc2cd.zip kernel_samsung_tuna-503b55fd77d11381b1950d1651d3bc782c0cc2cd.tar.gz kernel_samsung_tuna-503b55fd77d11381b1950d1651d3bc782c0cc2cd.tar.bz2  | |
[SCTP]: Don't do CRC32C checksum over loopback.
Signed-off-by: Sridhar Samudrala <sri@us.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
| -rw-r--r-- | net/sctp/input.c | 3 | ||||
| -rw-r--r-- | net/sctp/output.c | 48 | 
2 files changed, 29 insertions, 22 deletions
diff --git a/net/sctp/input.c b/net/sctp/input.c index 70d6606..42b66e7 100644 --- a/net/sctp/input.c +++ b/net/sctp/input.c @@ -141,7 +141,8 @@ int sctp_rcv(struct sk_buff *skb)  	__skb_pull(skb, skb->h.raw - skb->data);  	if (skb->len < sizeof(struct sctphdr))  		goto discard_it; -	if (sctp_rcv_checksum(skb) < 0) +	if ((skb->ip_summed != CHECKSUM_UNNECESSARY) && +	    (sctp_rcv_checksum(skb) < 0))  		goto discard_it;  	skb_pull(skb, sizeof(struct sctphdr)); diff --git a/net/sctp/output.c b/net/sctp/output.c index 437cba7..cdc5a39 100644 --- a/net/sctp/output.c +++ b/net/sctp/output.c @@ -295,14 +295,14 @@ int sctp_packet_transmit(struct sctp_packet *packet)  	struct sctp_transport *tp = packet->transport;  	struct sctp_association *asoc = tp->asoc;  	struct sctphdr *sh; -	__u32 crc32; +	__u32 crc32 = 0;  	struct sk_buff *nskb;  	struct sctp_chunk *chunk, *tmp;  	struct sock *sk;  	int err = 0;  	int padding;		/* How much padding do we need?  */  	__u8 has_data = 0; -	struct dst_entry *dst; +	struct dst_entry *dst = tp->dst;  	SCTP_DEBUG_PRINTK("%s: packet:%p\n", __FUNCTION__, packet); @@ -327,6 +327,19 @@ int sctp_packet_transmit(struct sctp_packet *packet)  	 */  	skb_set_owner_w(nskb, sk); +	/* The 'obsolete' field of dst is set to 2 when a dst is freed. */ +	if (!dst || (dst->obsolete > 1)) { +		dst_release(dst); +		sctp_transport_route(tp, NULL, sctp_sk(sk)); +		if (asoc && (asoc->param_flags & SPP_PMTUD_ENABLE)) { +			sctp_assoc_sync_pmtu(asoc); +		} +	} +	nskb->dst = dst_clone(tp->dst); +	if (!nskb->dst) +		goto no_route; +	dst = nskb->dst; +  	/* Build the SCTP header.  */  	sh = (struct sctphdr *)skb_push(nskb, sizeof(struct sctphdr));  	sh->source = htons(packet->source_port); @@ -350,7 +363,8 @@ int sctp_packet_transmit(struct sctp_packet *packet)  	 * Note: Adler-32 is no longer applicable, as has been replaced  	 * by CRC32-C as described in <draft-ietf-tsvwg-sctpcsum-02.txt>.  	 */ -	crc32 = sctp_start_cksum((__u8 *)sh, sizeof(struct sctphdr)); +	if (!(dst->dev->features & NETIF_F_NO_CSUM)) +		crc32 = sctp_start_cksum((__u8 *)sh, sizeof(struct sctphdr));  	/**  	 * 6.10 Bundling @@ -402,9 +416,14 @@ int sctp_packet_transmit(struct sctp_packet *packet)  		if (padding)  			memset(skb_put(chunk->skb, padding), 0, padding); -		crc32 = sctp_update_copy_cksum(skb_put(nskb, chunk->skb->len), -					       chunk->skb->data, -					       chunk->skb->len, crc32); +		if (dst->dev->features & NETIF_F_NO_CSUM) +			memcpy(skb_put(nskb, chunk->skb->len), +			       chunk->skb->data, chunk->skb->len); +		else +			crc32 = sctp_update_copy_cksum(skb_put(nskb, +							chunk->skb->len), +						chunk->skb->data, +						chunk->skb->len, crc32);  		SCTP_DEBUG_PRINTK("%s %p[%s] %s 0x%x, %s %d, %s %d, %s %d\n",  				  "*** Chunk", chunk, @@ -427,7 +446,8 @@ int sctp_packet_transmit(struct sctp_packet *packet)  	}  	/* Perform final transformation on checksum. */ -	crc32 = sctp_end_cksum(crc32); +	if (!(dst->dev->features & NETIF_F_NO_CSUM)) +		crc32 = sctp_end_cksum(crc32);  	/* 3) Put the resultant value into the checksum field in the  	 *    common header, and leave the rest of the bits unchanged. @@ -477,20 +497,6 @@ int sctp_packet_transmit(struct sctp_packet *packet)  		}  	} -	dst = tp->dst; -	/* The 'obsolete' field of dst is set to 2 when a dst is freed. */ -	if (!dst || (dst->obsolete > 1)) { -		dst_release(dst); -		sctp_transport_route(tp, NULL, sctp_sk(sk)); -		if (asoc->param_flags & SPP_PMTUD_ENABLE) { -			sctp_assoc_sync_pmtu(asoc); -		} -	} - -	nskb->dst = dst_clone(tp->dst); -	if (!nskb->dst) -		goto no_route; -  	SCTP_DEBUG_PRINTK("***sctp_transmit_packet*** skb len %d\n",  			  nskb->len);  | 
