Commit 503b55fd authored by Sridhar Samudrala's avatar Sridhar Samudrala Committed by David S. Miller

[SCTP]: Don't do CRC32C checksum over loopback.

Signed-off-by: default avatarSridhar Samudrala <sri@us.ibm.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 4c9f5d53
...@@ -141,7 +141,8 @@ int sctp_rcv(struct sk_buff *skb) ...@@ -141,7 +141,8 @@ int sctp_rcv(struct sk_buff *skb)
__skb_pull(skb, skb->h.raw - skb->data); __skb_pull(skb, skb->h.raw - skb->data);
if (skb->len < sizeof(struct sctphdr)) if (skb->len < sizeof(struct sctphdr))
goto discard_it; goto discard_it;
if (sctp_rcv_checksum(skb) < 0) if ((skb->ip_summed != CHECKSUM_UNNECESSARY) &&
(sctp_rcv_checksum(skb) < 0))
goto discard_it; goto discard_it;
skb_pull(skb, sizeof(struct sctphdr)); skb_pull(skb, sizeof(struct sctphdr));
......
...@@ -295,14 +295,14 @@ int sctp_packet_transmit(struct sctp_packet *packet) ...@@ -295,14 +295,14 @@ int sctp_packet_transmit(struct sctp_packet *packet)
struct sctp_transport *tp = packet->transport; struct sctp_transport *tp = packet->transport;
struct sctp_association *asoc = tp->asoc; struct sctp_association *asoc = tp->asoc;
struct sctphdr *sh; struct sctphdr *sh;
__u32 crc32; __u32 crc32 = 0;
struct sk_buff *nskb; struct sk_buff *nskb;
struct sctp_chunk *chunk, *tmp; struct sctp_chunk *chunk, *tmp;
struct sock *sk; struct sock *sk;
int err = 0; int err = 0;
int padding; /* How much padding do we need? */ int padding; /* How much padding do we need? */
__u8 has_data = 0; __u8 has_data = 0;
struct dst_entry *dst; struct dst_entry *dst = tp->dst;
SCTP_DEBUG_PRINTK("%s: packet:%p\n", __FUNCTION__, packet); SCTP_DEBUG_PRINTK("%s: packet:%p\n", __FUNCTION__, packet);
...@@ -327,6 +327,19 @@ int sctp_packet_transmit(struct sctp_packet *packet) ...@@ -327,6 +327,19 @@ int sctp_packet_transmit(struct sctp_packet *packet)
*/ */
skb_set_owner_w(nskb, sk); 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. */ /* Build the SCTP header. */
sh = (struct sctphdr *)skb_push(nskb, sizeof(struct sctphdr)); sh = (struct sctphdr *)skb_push(nskb, sizeof(struct sctphdr));
sh->source = htons(packet->source_port); sh->source = htons(packet->source_port);
...@@ -350,7 +363,8 @@ int sctp_packet_transmit(struct sctp_packet *packet) ...@@ -350,7 +363,8 @@ int sctp_packet_transmit(struct sctp_packet *packet)
* Note: Adler-32 is no longer applicable, as has been replaced * Note: Adler-32 is no longer applicable, as has been replaced
* by CRC32-C as described in <draft-ietf-tsvwg-sctpcsum-02.txt>. * 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 * 6.10 Bundling
...@@ -402,9 +416,14 @@ int sctp_packet_transmit(struct sctp_packet *packet) ...@@ -402,9 +416,14 @@ int sctp_packet_transmit(struct sctp_packet *packet)
if (padding) if (padding)
memset(skb_put(chunk->skb, padding), 0, padding); memset(skb_put(chunk->skb, padding), 0, padding);
crc32 = sctp_update_copy_cksum(skb_put(nskb, chunk->skb->len), if (dst->dev->features & NETIF_F_NO_CSUM)
chunk->skb->data, memcpy(skb_put(nskb, chunk->skb->len),
chunk->skb->len, crc32); 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", SCTP_DEBUG_PRINTK("%s %p[%s] %s 0x%x, %s %d, %s %d, %s %d\n",
"*** Chunk", chunk, "*** Chunk", chunk,
...@@ -427,7 +446,8 @@ int sctp_packet_transmit(struct sctp_packet *packet) ...@@ -427,7 +446,8 @@ int sctp_packet_transmit(struct sctp_packet *packet)
} }
/* Perform final transformation on checksum. */ /* 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 /* 3) Put the resultant value into the checksum field in the
* common header, and leave the rest of the bits unchanged. * common header, and leave the rest of the bits unchanged.
...@@ -477,20 +497,6 @@ int sctp_packet_transmit(struct sctp_packet *packet) ...@@ -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", SCTP_DEBUG_PRINTK("***sctp_transmit_packet*** skb len %d\n",
nskb->len); nskb->len);
......
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