diff options
| -rw-r--r-- | Documentation/networking/ip-sysctl.txt | 17 | ||||
| -rw-r--r-- | drivers/net/tg3.c | 30 | ||||
| -rw-r--r-- | drivers/net/tg3.h | 1 | ||||
| -rw-r--r-- | include/net/sctp/structs.h | 2 | ||||
| -rw-r--r-- | include/net/sock.h | 8 | ||||
| -rw-r--r-- | lib/ts_bm.c | 40 | ||||
| -rw-r--r-- | net/802/psnap.c | 2 | ||||
| -rw-r--r-- | net/Kconfig | 7 | ||||
| -rw-r--r-- | net/ipv4/icmp.c | 3 | ||||
| -rw-r--r-- | net/ipv4/multipath_wrandom.c | 8 | ||||
| -rw-r--r-- | net/ipv6/addrconf.c | 6 | ||||
| -rw-r--r-- | net/ipv6/af_inet6.c | 6 | ||||
| -rw-r--r-- | net/sctp/output.c | 2 | ||||
| -rw-r--r-- | net/sctp/outqueue.c | 12 |
14 files changed, 97 insertions, 47 deletions
diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt index 2b7cf19a06ad..26364d06ae92 100644 --- a/Documentation/networking/ip-sysctl.txt +++ b/Documentation/networking/ip-sysctl.txt | |||
| @@ -427,6 +427,23 @@ icmp_ignore_bogus_error_responses - BOOLEAN | |||
| 427 | will avoid log file clutter. | 427 | will avoid log file clutter. |
| 428 | Default: FALSE | 428 | Default: FALSE |
| 429 | 429 | ||
| 430 | icmp_errors_use_inbound_ifaddr - BOOLEAN | ||
| 431 | |||
| 432 | If zero, icmp error messages are sent with the primary address of | ||
| 433 | the exiting interface. | ||
| 434 | |||
| 435 | If non-zero, the message will be sent with the primary address of | ||
| 436 | the interface that received the packet that caused the icmp error. | ||
| 437 | This is the behaviour network many administrators will expect from | ||
| 438 | a router. And it can make debugging complicated network layouts | ||
| 439 | much easier. | ||
| 440 | |||
| 441 | Note that if no primary address exists for the interface selected, | ||
| 442 | then the primary address of the first non-loopback interface that | ||
| 443 | has one will be used regarldess of this setting. | ||
| 444 | |||
| 445 | Default: 0 | ||
| 446 | |||
| 430 | igmp_max_memberships - INTEGER | 447 | igmp_max_memberships - INTEGER |
| 431 | Change the maximum number of multicast groups we can subscribe to. | 448 | Change the maximum number of multicast groups we can subscribe to. |
| 432 | Default: 20 | 449 | Default: 20 |
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index f2d1dafde087..e7dc653d5bd6 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c | |||
| @@ -69,8 +69,8 @@ | |||
| 69 | 69 | ||
| 70 | #define DRV_MODULE_NAME "tg3" | 70 | #define DRV_MODULE_NAME "tg3" |
| 71 | #define PFX DRV_MODULE_NAME ": " | 71 | #define PFX DRV_MODULE_NAME ": " |
| 72 | #define DRV_MODULE_VERSION "3.48" | 72 | #define DRV_MODULE_VERSION "3.49" |
| 73 | #define DRV_MODULE_RELDATE "Jan 16, 2006" | 73 | #define DRV_MODULE_RELDATE "Feb 2, 2006" |
| 74 | 74 | ||
| 75 | #define TG3_DEF_MAC_MODE 0 | 75 | #define TG3_DEF_MAC_MODE 0 |
| 76 | #define TG3_DEF_RX_MODE 0 | 76 | #define TG3_DEF_RX_MODE 0 |
| @@ -3482,6 +3482,17 @@ static void tg3_reset_task(void *_data) | |||
| 3482 | struct tg3 *tp = _data; | 3482 | struct tg3 *tp = _data; |
| 3483 | unsigned int restart_timer; | 3483 | unsigned int restart_timer; |
| 3484 | 3484 | ||
| 3485 | tg3_full_lock(tp, 0); | ||
| 3486 | tp->tg3_flags |= TG3_FLAG_IN_RESET_TASK; | ||
| 3487 | |||
| 3488 | if (!netif_running(tp->dev)) { | ||
| 3489 | tp->tg3_flags &= ~TG3_FLAG_IN_RESET_TASK; | ||
| 3490 | tg3_full_unlock(tp); | ||
| 3491 | return; | ||
| 3492 | } | ||
| 3493 | |||
| 3494 | tg3_full_unlock(tp); | ||
| 3495 | |||
| 3485 | tg3_netif_stop(tp); | 3496 | tg3_netif_stop(tp); |
| 3486 | 3497 | ||
| 3487 | tg3_full_lock(tp, 1); | 3498 | tg3_full_lock(tp, 1); |
| @@ -3494,10 +3505,12 @@ static void tg3_reset_task(void *_data) | |||
| 3494 | 3505 | ||
| 3495 | tg3_netif_start(tp); | 3506 | tg3_netif_start(tp); |
| 3496 | 3507 | ||
| 3497 | tg3_full_unlock(tp); | ||
| 3498 | |||
| 3499 | if (restart_timer) | 3508 | if (restart_timer) |
| 3500 | mod_timer(&tp->timer, jiffies + 1); | 3509 | mod_timer(&tp->timer, jiffies + 1); |
| 3510 | |||
| 3511 | tp->tg3_flags &= ~TG3_FLAG_IN_RESET_TASK; | ||
| 3512 | |||
| 3513 | tg3_full_unlock(tp); | ||
| 3501 | } | 3514 | } |
| 3502 | 3515 | ||
| 3503 | static void tg3_tx_timeout(struct net_device *dev) | 3516 | static void tg3_tx_timeout(struct net_device *dev) |
| @@ -6786,6 +6799,13 @@ static int tg3_close(struct net_device *dev) | |||
| 6786 | { | 6799 | { |
| 6787 | struct tg3 *tp = netdev_priv(dev); | 6800 | struct tg3 *tp = netdev_priv(dev); |
| 6788 | 6801 | ||
| 6802 | /* Calling flush_scheduled_work() may deadlock because | ||
| 6803 | * linkwatch_event() may be on the workqueue and it will try to get | ||
| 6804 | * the rtnl_lock which we are holding. | ||
| 6805 | */ | ||
| 6806 | while (tp->tg3_flags & TG3_FLAG_IN_RESET_TASK) | ||
| 6807 | msleep(1); | ||
| 6808 | |||
| 6789 | netif_stop_queue(dev); | 6809 | netif_stop_queue(dev); |
| 6790 | 6810 | ||
| 6791 | del_timer_sync(&tp->timer); | 6811 | del_timer_sync(&tp->timer); |
| @@ -10880,6 +10900,7 @@ static void __devexit tg3_remove_one(struct pci_dev *pdev) | |||
| 10880 | if (dev) { | 10900 | if (dev) { |
| 10881 | struct tg3 *tp = netdev_priv(dev); | 10901 | struct tg3 *tp = netdev_priv(dev); |
| 10882 | 10902 | ||
| 10903 | flush_scheduled_work(); | ||
| 10883 | unregister_netdev(dev); | 10904 | unregister_netdev(dev); |
| 10884 | if (tp->regs) { | 10905 | if (tp->regs) { |
| 10885 | iounmap(tp->regs); | 10906 | iounmap(tp->regs); |
| @@ -10901,6 +10922,7 @@ static int tg3_suspend(struct pci_dev *pdev, pm_message_t state) | |||
| 10901 | if (!netif_running(dev)) | 10922 | if (!netif_running(dev)) |
| 10902 | return 0; | 10923 | return 0; |
| 10903 | 10924 | ||
| 10925 | flush_scheduled_work(); | ||
| 10904 | tg3_netif_stop(tp); | 10926 | tg3_netif_stop(tp); |
| 10905 | 10927 | ||
| 10906 | del_timer_sync(&tp->timer); | 10928 | del_timer_sync(&tp->timer); |
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index e8243305f0e8..7f4b7f6ac40d 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h | |||
| @@ -2162,6 +2162,7 @@ struct tg3 { | |||
| 2162 | #define TG3_FLAG_JUMBO_RING_ENABLE 0x00800000 | 2162 | #define TG3_FLAG_JUMBO_RING_ENABLE 0x00800000 |
| 2163 | #define TG3_FLAG_10_100_ONLY 0x01000000 | 2163 | #define TG3_FLAG_10_100_ONLY 0x01000000 |
| 2164 | #define TG3_FLAG_PAUSE_AUTONEG 0x02000000 | 2164 | #define TG3_FLAG_PAUSE_AUTONEG 0x02000000 |
| 2165 | #define TG3_FLAG_IN_RESET_TASK 0x04000000 | ||
| 2165 | #define TG3_FLAG_BROKEN_CHECKSUMS 0x10000000 | 2166 | #define TG3_FLAG_BROKEN_CHECKSUMS 0x10000000 |
| 2166 | #define TG3_FLAG_GOT_SERDES_FLOWCTL 0x20000000 | 2167 | #define TG3_FLAG_GOT_SERDES_FLOWCTL 0x20000000 |
| 2167 | #define TG3_FLAG_SPLIT_MODE 0x40000000 | 2168 | #define TG3_FLAG_SPLIT_MODE 0x40000000 |
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index 8c522ae031bb..072f407848a6 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h | |||
| @@ -700,7 +700,7 @@ struct sctp_chunk { | |||
| 700 | __u8 ecn_ce_done; /* Have we processed the ECN CE bit? */ | 700 | __u8 ecn_ce_done; /* Have we processed the ECN CE bit? */ |
| 701 | __u8 pdiscard; /* Discard the whole packet now? */ | 701 | __u8 pdiscard; /* Discard the whole packet now? */ |
| 702 | __u8 tsn_gap_acked; /* Is this chunk acked by a GAP ACK? */ | 702 | __u8 tsn_gap_acked; /* Is this chunk acked by a GAP ACK? */ |
| 703 | __u8 fast_retransmit; /* Is this chunk fast retransmitted? */ | 703 | __s8 fast_retransmit; /* Is this chunk fast retransmitted? */ |
| 704 | __u8 tsn_missing_report; /* Data chunk missing counter. */ | 704 | __u8 tsn_missing_report; /* Data chunk missing counter. */ |
| 705 | }; | 705 | }; |
| 706 | 706 | ||
diff --git a/include/net/sock.h b/include/net/sock.h index 1806e5b61419..30758035d616 100644 --- a/include/net/sock.h +++ b/include/net/sock.h | |||
| @@ -1354,12 +1354,12 @@ extern int sock_get_timestamp(struct sock *, struct timeval __user *); | |||
| 1354 | * Enable debug/info messages | 1354 | * Enable debug/info messages |
| 1355 | */ | 1355 | */ |
| 1356 | 1356 | ||
| 1357 | #if 0 | 1357 | #ifdef CONFIG_NETDEBUG |
| 1358 | #define NETDEBUG(fmt, args...) do { } while (0) | ||
| 1359 | #define LIMIT_NETDEBUG(fmt, args...) do { } while(0) | ||
| 1360 | #else | ||
| 1361 | #define NETDEBUG(fmt, args...) printk(fmt,##args) | 1358 | #define NETDEBUG(fmt, args...) printk(fmt,##args) |
| 1362 | #define LIMIT_NETDEBUG(fmt, args...) do { if (net_ratelimit()) printk(fmt,##args); } while(0) | 1359 | #define LIMIT_NETDEBUG(fmt, args...) do { if (net_ratelimit()) printk(fmt,##args); } while(0) |
| 1360 | #else | ||
| 1361 | #define NETDEBUG(fmt, args...) do { } while (0) | ||
| 1362 | #define LIMIT_NETDEBUG(fmt, args...) do { } while(0) | ||
| 1363 | #endif | 1363 | #endif |
| 1364 | 1364 | ||
| 1365 | /* | 1365 | /* |
diff --git a/lib/ts_bm.c b/lib/ts_bm.c index 8a8b3a16133e..c4c1ac5fbd1a 100644 --- a/lib/ts_bm.c +++ b/lib/ts_bm.c | |||
| @@ -94,10 +94,28 @@ next: bs = bm->bad_shift[text[shift-i]]; | |||
| 94 | return UINT_MAX; | 94 | return UINT_MAX; |
| 95 | } | 95 | } |
| 96 | 96 | ||
| 97 | static int subpattern(u8 *pattern, int i, int j, int g) | ||
| 98 | { | ||
| 99 | int x = i+g-1, y = j+g-1, ret = 0; | ||
| 100 | |||
| 101 | while(pattern[x--] == pattern[y--]) { | ||
| 102 | if (y < 0) { | ||
| 103 | ret = 1; | ||
| 104 | break; | ||
| 105 | } | ||
| 106 | if (--g == 0) { | ||
| 107 | ret = pattern[i-1] != pattern[j-1]; | ||
| 108 | break; | ||
| 109 | } | ||
| 110 | } | ||
| 111 | |||
| 112 | return ret; | ||
| 113 | } | ||
| 114 | |||
| 97 | static void compute_prefix_tbl(struct ts_bm *bm, const u8 *pattern, | 115 | static void compute_prefix_tbl(struct ts_bm *bm, const u8 *pattern, |
| 98 | unsigned int len) | 116 | unsigned int len) |
| 99 | { | 117 | { |
| 100 | int i, j, ended, l[ASIZE]; | 118 | int i, j, g; |
| 101 | 119 | ||
| 102 | for (i = 0; i < ASIZE; i++) | 120 | for (i = 0; i < ASIZE; i++) |
| 103 | bm->bad_shift[i] = len; | 121 | bm->bad_shift[i] = len; |
| @@ -106,23 +124,15 @@ static void compute_prefix_tbl(struct ts_bm *bm, const u8 *pattern, | |||
| 106 | 124 | ||
| 107 | /* Compute the good shift array, used to match reocurrences | 125 | /* Compute the good shift array, used to match reocurrences |
| 108 | * of a subpattern */ | 126 | * of a subpattern */ |
| 109 | for (i = 1; i < bm->patlen; i++) { | ||
| 110 | for (j = 0; j < bm->patlen && bm->pattern[bm->patlen - 1 - j] | ||
| 111 | == bm->pattern[bm->patlen - 1 - i - j]; j++); | ||
| 112 | l[i] = j; | ||
| 113 | } | ||
| 114 | |||
| 115 | bm->good_shift[0] = 1; | 127 | bm->good_shift[0] = 1; |
| 116 | for (i = 1; i < bm->patlen; i++) | 128 | for (i = 1; i < bm->patlen; i++) |
| 117 | bm->good_shift[i] = bm->patlen; | 129 | bm->good_shift[i] = bm->patlen; |
| 118 | for (i = bm->patlen - 1; i > 0; i--) | 130 | for (i = bm->patlen-1, g = 1; i > 0; g++, i--) { |
| 119 | bm->good_shift[l[i]] = i; | 131 | for (j = i-1; j >= 1-g ; j--) |
| 120 | ended = 0; | 132 | if (subpattern(bm->pattern, i, j, g)) { |
| 121 | for (i = 0; i < bm->patlen; i++) { | 133 | bm->good_shift[g] = bm->patlen-j-g; |
| 122 | if (l[i] == bm->patlen - 1 - i) | 134 | break; |
| 123 | ended = i; | 135 | } |
| 124 | if (ended) | ||
| 125 | bm->good_shift[i] = ended; | ||
| 126 | } | 136 | } |
| 127 | } | 137 | } |
| 128 | 138 | ||
diff --git a/net/802/psnap.c b/net/802/psnap.c index 4d638944d933..34e42968b477 100644 --- a/net/802/psnap.c +++ b/net/802/psnap.c | |||
| @@ -59,8 +59,10 @@ static int snap_rcv(struct sk_buff *skb, struct net_device *dev, | |||
| 59 | proto = find_snap_client(skb->h.raw); | 59 | proto = find_snap_client(skb->h.raw); |
| 60 | if (proto) { | 60 | if (proto) { |
| 61 | /* Pass the frame on. */ | 61 | /* Pass the frame on. */ |
| 62 | u8 *hdr = skb->data; | ||
| 62 | skb->h.raw += 5; | 63 | skb->h.raw += 5; |
| 63 | skb_pull(skb, 5); | 64 | skb_pull(skb, 5); |
| 65 | skb_postpull_rcsum(skb, hdr, 5); | ||
| 64 | rc = proto->rcvfunc(skb, dev, &snap_packet_type, orig_dev); | 66 | rc = proto->rcvfunc(skb, dev, &snap_packet_type, orig_dev); |
| 65 | } else { | 67 | } else { |
| 66 | skb->sk = NULL; | 68 | skb->sk = NULL; |
diff --git a/net/Kconfig b/net/Kconfig index bc603d9aea56..5126f58d9c44 100644 --- a/net/Kconfig +++ b/net/Kconfig | |||
| @@ -27,6 +27,13 @@ if NET | |||
| 27 | 27 | ||
| 28 | menu "Networking options" | 28 | menu "Networking options" |
| 29 | 29 | ||
| 30 | config NETDEBUG | ||
| 31 | bool "Network packet debugging" | ||
| 32 | help | ||
| 33 | You can say Y here if you want to get additional messages useful in | ||
| 34 | debugging bad packets, but can overwhelm logs under denial of service | ||
| 35 | attacks. | ||
| 36 | |||
| 30 | source "net/packet/Kconfig" | 37 | source "net/packet/Kconfig" |
| 31 | source "net/unix/Kconfig" | 38 | source "net/unix/Kconfig" |
| 32 | source "net/xfrm/Kconfig" | 39 | source "net/xfrm/Kconfig" |
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index 105039eb7629..6bc0887b0834 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c | |||
| @@ -385,7 +385,7 @@ static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb) | |||
| 385 | u32 daddr; | 385 | u32 daddr; |
| 386 | 386 | ||
| 387 | if (ip_options_echo(&icmp_param->replyopts, skb)) | 387 | if (ip_options_echo(&icmp_param->replyopts, skb)) |
| 388 | goto out; | 388 | return; |
| 389 | 389 | ||
| 390 | if (icmp_xmit_lock()) | 390 | if (icmp_xmit_lock()) |
| 391 | return; | 391 | return; |
| @@ -416,7 +416,6 @@ static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb) | |||
| 416 | ip_rt_put(rt); | 416 | ip_rt_put(rt); |
| 417 | out_unlock: | 417 | out_unlock: |
| 418 | icmp_xmit_unlock(); | 418 | icmp_xmit_unlock(); |
| 419 | out:; | ||
| 420 | } | 419 | } |
| 421 | 420 | ||
| 422 | 421 | ||
diff --git a/net/ipv4/multipath_wrandom.c b/net/ipv4/multipath_wrandom.c index d34a9fa608e0..342d0b9098f5 100644 --- a/net/ipv4/multipath_wrandom.c +++ b/net/ipv4/multipath_wrandom.c | |||
| @@ -228,7 +228,7 @@ static void wrandom_set_nhinfo(__u32 network, | |||
| 228 | struct multipath_dest *d, *target_dest = NULL; | 228 | struct multipath_dest *d, *target_dest = NULL; |
| 229 | 229 | ||
| 230 | /* store the weight information for a certain route */ | 230 | /* store the weight information for a certain route */ |
| 231 | spin_lock(&state[state_idx].lock); | 231 | spin_lock_bh(&state[state_idx].lock); |
| 232 | 232 | ||
| 233 | /* find state entry for gateway or add one if necessary */ | 233 | /* find state entry for gateway or add one if necessary */ |
| 234 | list_for_each_entry_rcu(r, &state[state_idx].head, list) { | 234 | list_for_each_entry_rcu(r, &state[state_idx].head, list) { |
| @@ -276,7 +276,7 @@ static void wrandom_set_nhinfo(__u32 network, | |||
| 276 | * we are finished | 276 | * we are finished |
| 277 | */ | 277 | */ |
| 278 | 278 | ||
| 279 | spin_unlock(&state[state_idx].lock); | 279 | spin_unlock_bh(&state[state_idx].lock); |
| 280 | } | 280 | } |
| 281 | 281 | ||
| 282 | static void __multipath_free(struct rcu_head *head) | 282 | static void __multipath_free(struct rcu_head *head) |
| @@ -302,7 +302,7 @@ static void wrandom_flush(void) | |||
| 302 | for (i = 0; i < MULTIPATH_STATE_SIZE; ++i) { | 302 | for (i = 0; i < MULTIPATH_STATE_SIZE; ++i) { |
| 303 | struct multipath_route *r; | 303 | struct multipath_route *r; |
| 304 | 304 | ||
| 305 | spin_lock(&state[i].lock); | 305 | spin_lock_bh(&state[i].lock); |
| 306 | list_for_each_entry_rcu(r, &state[i].head, list) { | 306 | list_for_each_entry_rcu(r, &state[i].head, list) { |
| 307 | struct multipath_dest *d; | 307 | struct multipath_dest *d; |
| 308 | list_for_each_entry_rcu(d, &r->dests, list) { | 308 | list_for_each_entry_rcu(d, &r->dests, list) { |
| @@ -315,7 +315,7 @@ static void wrandom_flush(void) | |||
| 315 | __multipath_free); | 315 | __multipath_free); |
| 316 | } | 316 | } |
| 317 | 317 | ||
| 318 | spin_unlock(&state[i].lock); | 318 | spin_unlock_bh(&state[i].lock); |
| 319 | } | 319 | } |
| 320 | } | 320 | } |
| 321 | 321 | ||
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index d328d5986143..1db50487916b 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
| @@ -3321,9 +3321,7 @@ static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp) | |||
| 3321 | 3321 | ||
| 3322 | switch (event) { | 3322 | switch (event) { |
| 3323 | case RTM_NEWADDR: | 3323 | case RTM_NEWADDR: |
| 3324 | dst_hold(&ifp->rt->u.dst); | 3324 | ip6_ins_rt(ifp->rt, NULL, NULL, NULL); |
| 3325 | if (ip6_ins_rt(ifp->rt, NULL, NULL, NULL)) | ||
| 3326 | dst_release(&ifp->rt->u.dst); | ||
| 3327 | if (ifp->idev->cnf.forwarding) | 3325 | if (ifp->idev->cnf.forwarding) |
| 3328 | addrconf_join_anycast(ifp); | 3326 | addrconf_join_anycast(ifp); |
| 3329 | break; | 3327 | break; |
| @@ -3334,8 +3332,6 @@ static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp) | |||
| 3334 | dst_hold(&ifp->rt->u.dst); | 3332 | dst_hold(&ifp->rt->u.dst); |
| 3335 | if (ip6_del_rt(ifp->rt, NULL, NULL, NULL)) | 3333 | if (ip6_del_rt(ifp->rt, NULL, NULL, NULL)) |
| 3336 | dst_free(&ifp->rt->u.dst); | 3334 | dst_free(&ifp->rt->u.dst); |
| 3337 | else | ||
| 3338 | dst_release(&ifp->rt->u.dst); | ||
| 3339 | break; | 3335 | break; |
| 3340 | } | 3336 | } |
| 3341 | } | 3337 | } |
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index 064ffab82a9f..6c9711ac1c03 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c | |||
| @@ -369,12 +369,6 @@ int inet6_destroy_sock(struct sock *sk) | |||
| 369 | struct sk_buff *skb; | 369 | struct sk_buff *skb; |
| 370 | struct ipv6_txoptions *opt; | 370 | struct ipv6_txoptions *opt; |
| 371 | 371 | ||
| 372 | /* | ||
| 373 | * Release destination entry | ||
| 374 | */ | ||
| 375 | |||
| 376 | sk_dst_reset(sk); | ||
| 377 | |||
| 378 | /* Release rx options */ | 372 | /* Release rx options */ |
| 379 | 373 | ||
| 380 | if ((skb = xchg(&np->pktoptions, NULL)) != NULL) | 374 | if ((skb = xchg(&np->pktoptions, NULL)) != NULL) |
diff --git a/net/sctp/output.c b/net/sctp/output.c index a40991ef72c9..437cba7260a4 100644 --- a/net/sctp/output.c +++ b/net/sctp/output.c | |||
| @@ -608,7 +608,7 @@ static sctp_xmit_t sctp_packet_append_data(struct sctp_packet *packet, | |||
| 608 | * When a Fast Retransmit is being performed the sender SHOULD | 608 | * When a Fast Retransmit is being performed the sender SHOULD |
| 609 | * ignore the value of cwnd and SHOULD NOT delay retransmission. | 609 | * ignore the value of cwnd and SHOULD NOT delay retransmission. |
| 610 | */ | 610 | */ |
| 611 | if (!chunk->fast_retransmit) | 611 | if (chunk->fast_retransmit <= 0) |
| 612 | if (transport->flight_size >= transport->cwnd) { | 612 | if (transport->flight_size >= transport->cwnd) { |
| 613 | retval = SCTP_XMIT_RWND_FULL; | 613 | retval = SCTP_XMIT_RWND_FULL; |
| 614 | goto finish; | 614 | goto finish; |
diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c index efb72faba20c..f148f9576dd2 100644 --- a/net/sctp/outqueue.c +++ b/net/sctp/outqueue.c | |||
| @@ -406,7 +406,7 @@ void sctp_retransmit_mark(struct sctp_outq *q, | |||
| 406 | * chunks that are not yet acked should be added to the | 406 | * chunks that are not yet acked should be added to the |
| 407 | * retransmit queue. | 407 | * retransmit queue. |
| 408 | */ | 408 | */ |
| 409 | if ((fast_retransmit && chunk->fast_retransmit) || | 409 | if ((fast_retransmit && (chunk->fast_retransmit > 0)) || |
| 410 | (!fast_retransmit && !chunk->tsn_gap_acked)) { | 410 | (!fast_retransmit && !chunk->tsn_gap_acked)) { |
| 411 | /* RFC 2960 6.2.1 Processing a Received SACK | 411 | /* RFC 2960 6.2.1 Processing a Received SACK |
| 412 | * | 412 | * |
| @@ -603,7 +603,8 @@ static int sctp_outq_flush_rtx(struct sctp_outq *q, struct sctp_packet *pkt, | |||
| 603 | /* Mark the chunk as ineligible for fast retransmit | 603 | /* Mark the chunk as ineligible for fast retransmit |
| 604 | * after it is retransmitted. | 604 | * after it is retransmitted. |
| 605 | */ | 605 | */ |
| 606 | chunk->fast_retransmit = 0; | 606 | if (chunk->fast_retransmit > 0) |
| 607 | chunk->fast_retransmit = -1; | ||
| 607 | 608 | ||
| 608 | *start_timer = 1; | 609 | *start_timer = 1; |
| 609 | q->empty = 0; | 610 | q->empty = 0; |
| @@ -621,7 +622,8 @@ static int sctp_outq_flush_rtx(struct sctp_outq *q, struct sctp_packet *pkt, | |||
| 621 | list_for_each(lchunk1, lqueue) { | 622 | list_for_each(lchunk1, lqueue) { |
| 622 | chunk1 = list_entry(lchunk1, struct sctp_chunk, | 623 | chunk1 = list_entry(lchunk1, struct sctp_chunk, |
| 623 | transmitted_list); | 624 | transmitted_list); |
| 624 | chunk1->fast_retransmit = 0; | 625 | if (chunk1->fast_retransmit > 0) |
| 626 | chunk1->fast_retransmit = -1; | ||
| 625 | } | 627 | } |
| 626 | } | 628 | } |
| 627 | } | 629 | } |
| @@ -1562,11 +1564,11 @@ static void sctp_mark_missing(struct sctp_outq *q, | |||
| 1562 | /* | 1564 | /* |
| 1563 | * M4) If any DATA chunk is found to have a | 1565 | * M4) If any DATA chunk is found to have a |
| 1564 | * 'TSN.Missing.Report' | 1566 | * 'TSN.Missing.Report' |
| 1565 | * value larger than or equal to 4, mark that chunk for | 1567 | * value larger than or equal to 3, mark that chunk for |
| 1566 | * retransmission and start the fast retransmit procedure. | 1568 | * retransmission and start the fast retransmit procedure. |
| 1567 | */ | 1569 | */ |
| 1568 | 1570 | ||
| 1569 | if (chunk->tsn_missing_report >= 4) { | 1571 | if (chunk->tsn_missing_report >= 3) { |
| 1570 | chunk->fast_retransmit = 1; | 1572 | chunk->fast_retransmit = 1; |
| 1571 | do_fast_retransmit = 1; | 1573 | do_fast_retransmit = 1; |
| 1572 | } | 1574 | } |
