diff options
Diffstat (limited to 'net/sctp')
-rw-r--r-- | net/sctp/input.c | 6 | ||||
-rw-r--r-- | net/sctp/ipv6.c | 6 | ||||
-rw-r--r-- | net/sctp/output.c | 48 | ||||
-rw-r--r-- | net/sctp/outqueue.c | 1 | ||||
-rw-r--r-- | net/sctp/protocol.c | 8 | ||||
-rw-r--r-- | net/sctp/sm_statefuns.c | 10 | ||||
-rw-r--r-- | net/sctp/socket.c | 28 | ||||
-rw-r--r-- | net/sctp/ulpevent.c | 30 |
8 files changed, 106 insertions, 31 deletions
diff --git a/net/sctp/input.c b/net/sctp/input.c index 1662f9cc869..42b66e74bbb 100644 --- a/net/sctp/input.c +++ b/net/sctp/input.c | |||
@@ -141,7 +141,8 @@ int sctp_rcv(struct sk_buff *skb) | |||
141 | __skb_pull(skb, skb->h.raw - skb->data); | 141 | __skb_pull(skb, skb->h.raw - skb->data); |
142 | if (skb->len < sizeof(struct sctphdr)) | 142 | if (skb->len < sizeof(struct sctphdr)) |
143 | goto discard_it; | 143 | goto discard_it; |
144 | if (sctp_rcv_checksum(skb) < 0) | 144 | if ((skb->ip_summed != CHECKSUM_UNNECESSARY) && |
145 | (sctp_rcv_checksum(skb) < 0)) | ||
145 | goto discard_it; | 146 | goto discard_it; |
146 | 147 | ||
147 | skb_pull(skb, sizeof(struct sctphdr)); | 148 | skb_pull(skb, sizeof(struct sctphdr)); |
@@ -170,7 +171,8 @@ int sctp_rcv(struct sk_buff *skb) | |||
170 | * IP broadcast addresses cannot be used in an SCTP transport | 171 | * IP broadcast addresses cannot be used in an SCTP transport |
171 | * address." | 172 | * address." |
172 | */ | 173 | */ |
173 | if (!af->addr_valid(&src, NULL) || !af->addr_valid(&dest, NULL)) | 174 | if (!af->addr_valid(&src, NULL, skb) || |
175 | !af->addr_valid(&dest, NULL, skb)) | ||
174 | goto discard_it; | 176 | goto discard_it; |
175 | 177 | ||
176 | asoc = __sctp_rcv_lookup(skb, &src, &dest, &transport); | 178 | asoc = __sctp_rcv_lookup(skb, &src, &dest, &transport); |
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c index c20d282fac0..8ef08070c8b 100644 --- a/net/sctp/ipv6.c +++ b/net/sctp/ipv6.c | |||
@@ -523,7 +523,9 @@ static int sctp_v6_available(union sctp_addr *addr, struct sctp_sock *sp) | |||
523 | * Return 0 - If the address is a non-unicast or an illegal address. | 523 | * Return 0 - If the address is a non-unicast or an illegal address. |
524 | * Return 1 - If the address is a unicast. | 524 | * Return 1 - If the address is a unicast. |
525 | */ | 525 | */ |
526 | static int sctp_v6_addr_valid(union sctp_addr *addr, struct sctp_sock *sp) | 526 | static int sctp_v6_addr_valid(union sctp_addr *addr, |
527 | struct sctp_sock *sp, | ||
528 | const struct sk_buff *skb) | ||
527 | { | 529 | { |
528 | int ret = ipv6_addr_type(&addr->v6.sin6_addr); | 530 | int ret = ipv6_addr_type(&addr->v6.sin6_addr); |
529 | 531 | ||
@@ -537,7 +539,7 @@ static int sctp_v6_addr_valid(union sctp_addr *addr, struct sctp_sock *sp) | |||
537 | if (sp && ipv6_only_sock(sctp_opt2sk(sp))) | 539 | if (sp && ipv6_only_sock(sctp_opt2sk(sp))) |
538 | return 0; | 540 | return 0; |
539 | sctp_v6_map_v4(addr); | 541 | sctp_v6_map_v4(addr); |
540 | return sctp_get_af_specific(AF_INET)->addr_valid(addr, sp); | 542 | return sctp_get_af_specific(AF_INET)->addr_valid(addr, sp, skb); |
541 | } | 543 | } |
542 | 544 | ||
543 | /* Is this a non-unicast address */ | 545 | /* Is this a non-unicast address */ |
diff --git a/net/sctp/output.c b/net/sctp/output.c index 437cba7260a..cdc5a393676 100644 --- a/net/sctp/output.c +++ b/net/sctp/output.c | |||
@@ -295,14 +295,14 @@ int sctp_packet_transmit(struct sctp_packet *packet) | |||
295 | struct sctp_transport *tp = packet->transport; | 295 | struct sctp_transport *tp = packet->transport; |
296 | struct sctp_association *asoc = tp->asoc; | 296 | struct sctp_association *asoc = tp->asoc; |
297 | struct sctphdr *sh; | 297 | struct sctphdr *sh; |
298 | __u32 crc32; | 298 | __u32 crc32 = 0; |
299 | struct sk_buff *nskb; | 299 | struct sk_buff *nskb; |
300 | struct sctp_chunk *chunk, *tmp; | 300 | struct sctp_chunk *chunk, *tmp; |
301 | struct sock *sk; | 301 | struct sock *sk; |
302 | int err = 0; | 302 | int err = 0; |
303 | int padding; /* How much padding do we need? */ | 303 | int padding; /* How much padding do we need? */ |
304 | __u8 has_data = 0; | 304 | __u8 has_data = 0; |
305 | struct dst_entry *dst; | 305 | struct dst_entry *dst = tp->dst; |
306 | 306 | ||
307 | SCTP_DEBUG_PRINTK("%s: packet:%p\n", __FUNCTION__, packet); | 307 | SCTP_DEBUG_PRINTK("%s: packet:%p\n", __FUNCTION__, packet); |
308 | 308 | ||
@@ -327,6 +327,19 @@ int sctp_packet_transmit(struct sctp_packet *packet) | |||
327 | */ | 327 | */ |
328 | skb_set_owner_w(nskb, sk); | 328 | skb_set_owner_w(nskb, sk); |
329 | 329 | ||
330 | /* The 'obsolete' field of dst is set to 2 when a dst is freed. */ | ||
331 | if (!dst || (dst->obsolete > 1)) { | ||
332 | dst_release(dst); | ||
333 | sctp_transport_route(tp, NULL, sctp_sk(sk)); | ||
334 | if (asoc && (asoc->param_flags & SPP_PMTUD_ENABLE)) { | ||
335 | sctp_assoc_sync_pmtu(asoc); | ||
336 | } | ||
337 | } | ||
338 | nskb->dst = dst_clone(tp->dst); | ||
339 | if (!nskb->dst) | ||
340 | goto no_route; | ||
341 | dst = nskb->dst; | ||
342 | |||
330 | /* Build the SCTP header. */ | 343 | /* Build the SCTP header. */ |
331 | sh = (struct sctphdr *)skb_push(nskb, sizeof(struct sctphdr)); | 344 | sh = (struct sctphdr *)skb_push(nskb, sizeof(struct sctphdr)); |
332 | sh->source = htons(packet->source_port); | 345 | sh->source = htons(packet->source_port); |
@@ -350,7 +363,8 @@ int sctp_packet_transmit(struct sctp_packet *packet) | |||
350 | * Note: Adler-32 is no longer applicable, as has been replaced | 363 | * Note: Adler-32 is no longer applicable, as has been replaced |
351 | * by CRC32-C as described in <draft-ietf-tsvwg-sctpcsum-02.txt>. | 364 | * by CRC32-C as described in <draft-ietf-tsvwg-sctpcsum-02.txt>. |
352 | */ | 365 | */ |
353 | crc32 = sctp_start_cksum((__u8 *)sh, sizeof(struct sctphdr)); | 366 | if (!(dst->dev->features & NETIF_F_NO_CSUM)) |
367 | crc32 = sctp_start_cksum((__u8 *)sh, sizeof(struct sctphdr)); | ||
354 | 368 | ||
355 | /** | 369 | /** |
356 | * 6.10 Bundling | 370 | * 6.10 Bundling |
@@ -402,9 +416,14 @@ int sctp_packet_transmit(struct sctp_packet *packet) | |||
402 | if (padding) | 416 | if (padding) |
403 | memset(skb_put(chunk->skb, padding), 0, padding); | 417 | memset(skb_put(chunk->skb, padding), 0, padding); |
404 | 418 | ||
405 | crc32 = sctp_update_copy_cksum(skb_put(nskb, chunk->skb->len), | 419 | if (dst->dev->features & NETIF_F_NO_CSUM) |
406 | chunk->skb->data, | 420 | memcpy(skb_put(nskb, chunk->skb->len), |
407 | chunk->skb->len, crc32); | 421 | chunk->skb->data, chunk->skb->len); |
422 | else | ||
423 | crc32 = sctp_update_copy_cksum(skb_put(nskb, | ||
424 | chunk->skb->len), | ||
425 | chunk->skb->data, | ||
426 | chunk->skb->len, crc32); | ||
408 | 427 | ||
409 | SCTP_DEBUG_PRINTK("%s %p[%s] %s 0x%x, %s %d, %s %d, %s %d\n", | 428 | SCTP_DEBUG_PRINTK("%s %p[%s] %s 0x%x, %s %d, %s %d, %s %d\n", |
410 | "*** Chunk", chunk, | 429 | "*** Chunk", chunk, |
@@ -427,7 +446,8 @@ int sctp_packet_transmit(struct sctp_packet *packet) | |||
427 | } | 446 | } |
428 | 447 | ||
429 | /* Perform final transformation on checksum. */ | 448 | /* Perform final transformation on checksum. */ |
430 | crc32 = sctp_end_cksum(crc32); | 449 | if (!(dst->dev->features & NETIF_F_NO_CSUM)) |
450 | crc32 = sctp_end_cksum(crc32); | ||
431 | 451 | ||
432 | /* 3) Put the resultant value into the checksum field in the | 452 | /* 3) Put the resultant value into the checksum field in the |
433 | * common header, and leave the rest of the bits unchanged. | 453 | * common header, and leave the rest of the bits unchanged. |
@@ -477,20 +497,6 @@ int sctp_packet_transmit(struct sctp_packet *packet) | |||
477 | } | 497 | } |
478 | } | 498 | } |
479 | 499 | ||
480 | dst = tp->dst; | ||
481 | /* The 'obsolete' field of dst is set to 2 when a dst is freed. */ | ||
482 | if (!dst || (dst->obsolete > 1)) { | ||
483 | dst_release(dst); | ||
484 | sctp_transport_route(tp, NULL, sctp_sk(sk)); | ||
485 | if (asoc->param_flags & SPP_PMTUD_ENABLE) { | ||
486 | sctp_assoc_sync_pmtu(asoc); | ||
487 | } | ||
488 | } | ||
489 | |||
490 | nskb->dst = dst_clone(tp->dst); | ||
491 | if (!nskb->dst) | ||
492 | goto no_route; | ||
493 | |||
494 | SCTP_DEBUG_PRINTK("***sctp_transmit_packet*** skb len %d\n", | 500 | SCTP_DEBUG_PRINTK("***sctp_transmit_packet*** skb len %d\n", |
495 | nskb->len); | 501 | nskb->len); |
496 | 502 | ||
diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c index f148f9576dd..e5faa351aaa 100644 --- a/net/sctp/outqueue.c +++ b/net/sctp/outqueue.c | |||
@@ -1262,6 +1262,7 @@ static void sctp_check_transmitted(struct sctp_outq *q, | |||
1262 | if (!tchunk->tsn_gap_acked && | 1262 | if (!tchunk->tsn_gap_acked && |
1263 | !tchunk->resent && | 1263 | !tchunk->resent && |
1264 | tchunk->rtt_in_progress) { | 1264 | tchunk->rtt_in_progress) { |
1265 | tchunk->rtt_in_progress = 0; | ||
1265 | rtt = jiffies - tchunk->sent_at; | 1266 | rtt = jiffies - tchunk->sent_at; |
1266 | sctp_transport_update_rto(transport, | 1267 | sctp_transport_update_rto(transport, |
1267 | rtt); | 1268 | rtt); |
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index 2088aa992b7..816c033d788 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c | |||
@@ -365,12 +365,18 @@ static int sctp_v4_is_any(const union sctp_addr *addr) | |||
365 | * Return 0 - If the address is a non-unicast or an illegal address. | 365 | * Return 0 - If the address is a non-unicast or an illegal address. |
366 | * Return 1 - If the address is a unicast. | 366 | * Return 1 - If the address is a unicast. |
367 | */ | 367 | */ |
368 | static int sctp_v4_addr_valid(union sctp_addr *addr, struct sctp_sock *sp) | 368 | static int sctp_v4_addr_valid(union sctp_addr *addr, |
369 | struct sctp_sock *sp, | ||
370 | const struct sk_buff *skb) | ||
369 | { | 371 | { |
370 | /* Is this a non-unicast address or a unusable SCTP address? */ | 372 | /* Is this a non-unicast address or a unusable SCTP address? */ |
371 | if (IS_IPV4_UNUSABLE_ADDRESS(&addr->v4.sin_addr.s_addr)) | 373 | if (IS_IPV4_UNUSABLE_ADDRESS(&addr->v4.sin_addr.s_addr)) |
372 | return 0; | 374 | return 0; |
373 | 375 | ||
376 | /* Is this a broadcast address? */ | ||
377 | if (skb && ((struct rtable *)skb->dst)->rt_flags & RTCF_BROADCAST) | ||
378 | return 0; | ||
379 | |||
374 | return 1; | 380 | return 1; |
375 | } | 381 | } |
376 | 382 | ||
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index 8bc279219a7..9e58144f485 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c | |||
@@ -5293,10 +5293,18 @@ static int sctp_eat_data(const struct sctp_association *asoc, | |||
5293 | * seems a bit troublesome in that frag_point varies based on | 5293 | * seems a bit troublesome in that frag_point varies based on |
5294 | * PMTU. In cases, such as loopback, this might be a rather | 5294 | * PMTU. In cases, such as loopback, this might be a rather |
5295 | * large spill over. | 5295 | * large spill over. |
5296 | * NOTE: If we have a full receive buffer here, we only renege if | ||
5297 | * our receiver can still make progress without the tsn being | ||
5298 | * received. We do this because in the event that the associations | ||
5299 | * receive queue is empty we are filling a leading gap, and since | ||
5300 | * reneging moves the gap to the end of the tsn stream, we are likely | ||
5301 | * to stall again very shortly. Avoiding the renege when we fill a | ||
5302 | * leading gap is a good heuristic for avoiding such steady state | ||
5303 | * stalls. | ||
5296 | */ | 5304 | */ |
5297 | if (!asoc->rwnd || asoc->rwnd_over || | 5305 | if (!asoc->rwnd || asoc->rwnd_over || |
5298 | (datalen > asoc->rwnd + asoc->frag_point) || | 5306 | (datalen > asoc->rwnd + asoc->frag_point) || |
5299 | rcvbuf_over) { | 5307 | (rcvbuf_over && (!skb_queue_len(&sk->sk_receive_queue)))) { |
5300 | 5308 | ||
5301 | /* If this is the next TSN, consider reneging to make | 5309 | /* If this is the next TSN, consider reneging to make |
5302 | * room. Note: Playing nice with a confused sender. A | 5310 | * room. Note: Playing nice with a confused sender. A |
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 174d4d35e95..b811691c35b 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -172,7 +172,7 @@ static inline int sctp_verify_addr(struct sock *sk, union sctp_addr *addr, | |||
172 | return -EINVAL; | 172 | return -EINVAL; |
173 | 173 | ||
174 | /* Is this a valid SCTP address? */ | 174 | /* Is this a valid SCTP address? */ |
175 | if (!af->addr_valid(addr, sctp_sk(sk))) | 175 | if (!af->addr_valid(addr, sctp_sk(sk), NULL)) |
176 | return -EINVAL; | 176 | return -EINVAL; |
177 | 177 | ||
178 | if (!sctp_sk(sk)->pf->send_verify(sctp_sk(sk), (addr))) | 178 | if (!sctp_sk(sk)->pf->send_verify(sctp_sk(sk), (addr))) |
@@ -2530,8 +2530,32 @@ static int sctp_setsockopt_associnfo(struct sock *sk, char __user *optval, int o | |||
2530 | 2530 | ||
2531 | /* Set the values to the specific association */ | 2531 | /* Set the values to the specific association */ |
2532 | if (asoc) { | 2532 | if (asoc) { |
2533 | if (assocparams.sasoc_asocmaxrxt != 0) | 2533 | if (assocparams.sasoc_asocmaxrxt != 0) { |
2534 | __u32 path_sum = 0; | ||
2535 | int paths = 0; | ||
2536 | struct list_head *pos; | ||
2537 | struct sctp_transport *peer_addr; | ||
2538 | |||
2539 | list_for_each(pos, &asoc->peer.transport_addr_list) { | ||
2540 | peer_addr = list_entry(pos, | ||
2541 | struct sctp_transport, | ||
2542 | transports); | ||
2543 | path_sum += peer_addr->pathmaxrxt; | ||
2544 | paths++; | ||
2545 | } | ||
2546 | |||
2547 | /* Only validate asocmaxrxt if we have more then | ||
2548 | * one path/transport. We do this because path | ||
2549 | * retransmissions are only counted when we have more | ||
2550 | * then one path. | ||
2551 | */ | ||
2552 | if (paths > 1 && | ||
2553 | assocparams.sasoc_asocmaxrxt > path_sum) | ||
2554 | return -EINVAL; | ||
2555 | |||
2534 | asoc->max_retrans = assocparams.sasoc_asocmaxrxt; | 2556 | asoc->max_retrans = assocparams.sasoc_asocmaxrxt; |
2557 | } | ||
2558 | |||
2535 | if (assocparams.sasoc_cookie_life != 0) { | 2559 | if (assocparams.sasoc_cookie_life != 0) { |
2536 | asoc->cookie_life.tv_sec = | 2560 | asoc->cookie_life.tv_sec = |
2537 | assocparams.sasoc_cookie_life / 1000; | 2561 | assocparams.sasoc_cookie_life / 1000; |
diff --git a/net/sctp/ulpevent.c b/net/sctp/ulpevent.c index ba97f974f57..ee236784a6b 100644 --- a/net/sctp/ulpevent.c +++ b/net/sctp/ulpevent.c | |||
@@ -51,6 +51,8 @@ | |||
51 | static void sctp_ulpevent_receive_data(struct sctp_ulpevent *event, | 51 | static void sctp_ulpevent_receive_data(struct sctp_ulpevent *event, |
52 | struct sctp_association *asoc); | 52 | struct sctp_association *asoc); |
53 | static void sctp_ulpevent_release_data(struct sctp_ulpevent *event); | 53 | static void sctp_ulpevent_release_data(struct sctp_ulpevent *event); |
54 | static void sctp_ulpevent_release_frag_data(struct sctp_ulpevent *event); | ||
55 | |||
54 | 56 | ||
55 | /* Initialize an ULP event from an given skb. */ | 57 | /* Initialize an ULP event from an given skb. */ |
56 | SCTP_STATIC void sctp_ulpevent_init(struct sctp_ulpevent *event, int msg_flags) | 58 | SCTP_STATIC void sctp_ulpevent_init(struct sctp_ulpevent *event, int msg_flags) |
@@ -883,6 +885,7 @@ static void sctp_ulpevent_receive_data(struct sctp_ulpevent *event, | |||
883 | static void sctp_ulpevent_release_data(struct sctp_ulpevent *event) | 885 | static void sctp_ulpevent_release_data(struct sctp_ulpevent *event) |
884 | { | 886 | { |
885 | struct sk_buff *skb, *frag; | 887 | struct sk_buff *skb, *frag; |
888 | unsigned int len; | ||
886 | 889 | ||
887 | /* Current stack structures assume that the rcv buffer is | 890 | /* Current stack structures assume that the rcv buffer is |
888 | * per socket. For UDP style sockets this is not true as | 891 | * per socket. For UDP style sockets this is not true as |
@@ -892,7 +895,30 @@ static void sctp_ulpevent_release_data(struct sctp_ulpevent *event) | |||
892 | */ | 895 | */ |
893 | 896 | ||
894 | skb = sctp_event2skb(event); | 897 | skb = sctp_event2skb(event); |
895 | sctp_assoc_rwnd_increase(event->asoc, skb_headlen(skb)); | 898 | len = skb->len; |
899 | |||
900 | if (!skb->data_len) | ||
901 | goto done; | ||
902 | |||
903 | /* Don't forget the fragments. */ | ||
904 | for (frag = skb_shinfo(skb)->frag_list; frag; frag = frag->next) { | ||
905 | /* NOTE: skb_shinfos are recursive. Although IP returns | ||
906 | * skb's with only 1 level of fragments, SCTP reassembly can | ||
907 | * increase the levels. | ||
908 | */ | ||
909 | sctp_ulpevent_release_frag_data(sctp_skb2event(frag)); | ||
910 | } | ||
911 | |||
912 | done: | ||
913 | sctp_assoc_rwnd_increase(event->asoc, len); | ||
914 | sctp_ulpevent_release_owner(event); | ||
915 | } | ||
916 | |||
917 | static void sctp_ulpevent_release_frag_data(struct sctp_ulpevent *event) | ||
918 | { | ||
919 | struct sk_buff *skb, *frag; | ||
920 | |||
921 | skb = sctp_event2skb(event); | ||
896 | 922 | ||
897 | if (!skb->data_len) | 923 | if (!skb->data_len) |
898 | goto done; | 924 | goto done; |
@@ -903,7 +929,7 @@ static void sctp_ulpevent_release_data(struct sctp_ulpevent *event) | |||
903 | * skb's with only 1 level of fragments, SCTP reassembly can | 929 | * skb's with only 1 level of fragments, SCTP reassembly can |
904 | * increase the levels. | 930 | * increase the levels. |
905 | */ | 931 | */ |
906 | sctp_ulpevent_release_data(sctp_skb2event(frag)); | 932 | sctp_ulpevent_release_frag_data(sctp_skb2event(frag)); |
907 | } | 933 | } |
908 | 934 | ||
909 | done: | 935 | done: |