diff options
Diffstat (limited to 'net')
| -rw-r--r-- | net/ieee80211/ieee80211_rx.c | 6 | ||||
| -rw-r--r-- | net/ieee80211/softmac/ieee80211softmac_wx.c | 2 | ||||
| -rw-r--r-- | net/ipv4/tcp_input.c | 3 | ||||
| -rw-r--r-- | net/ipv4/tcp_ipv4.c | 19 | ||||
| -rw-r--r-- | net/ipv6/ndisc.c | 9 | ||||
| -rw-r--r-- | net/ipv6/tcp_ipv6.c | 18 | ||||
| -rw-r--r-- | net/rose/rose_loopback.c | 4 | ||||
| -rw-r--r-- | net/rose/rose_route.c | 15 | ||||
| -rw-r--r-- | net/sched/cls_u32.c | 2 | ||||
| -rw-r--r-- | net/sched/sch_sfq.c | 47 | ||||
| -rw-r--r-- | net/socket.c | 3 |
11 files changed, 77 insertions, 51 deletions
diff --git a/net/ieee80211/ieee80211_rx.c b/net/ieee80211/ieee80211_rx.c index f2de2e48b021..6284c99b456e 100644 --- a/net/ieee80211/ieee80211_rx.c +++ b/net/ieee80211/ieee80211_rx.c | |||
| @@ -366,6 +366,12 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, | |||
| 366 | frag = WLAN_GET_SEQ_FRAG(sc); | 366 | frag = WLAN_GET_SEQ_FRAG(sc); |
| 367 | hdrlen = ieee80211_get_hdrlen(fc); | 367 | hdrlen = ieee80211_get_hdrlen(fc); |
| 368 | 368 | ||
| 369 | if (skb->len < hdrlen) { | ||
| 370 | printk(KERN_INFO "%s: invalid SKB length %d\n", | ||
| 371 | dev->name, skb->len); | ||
| 372 | goto rx_dropped; | ||
| 373 | } | ||
| 374 | |||
| 369 | /* Put this code here so that we avoid duplicating it in all | 375 | /* Put this code here so that we avoid duplicating it in all |
| 370 | * Rx paths. - Jean II */ | 376 | * Rx paths. - Jean II */ |
| 371 | #ifdef CONFIG_WIRELESS_EXT | 377 | #ifdef CONFIG_WIRELESS_EXT |
diff --git a/net/ieee80211/softmac/ieee80211softmac_wx.c b/net/ieee80211/softmac/ieee80211softmac_wx.c index 442b9875f3fb..5742dc803b79 100644 --- a/net/ieee80211/softmac/ieee80211softmac_wx.c +++ b/net/ieee80211/softmac/ieee80211softmac_wx.c | |||
| @@ -114,7 +114,7 @@ check_assoc_again: | |||
| 114 | sm->associnfo.associating = 1; | 114 | sm->associnfo.associating = 1; |
| 115 | /* queue lower level code to do work (if necessary) */ | 115 | /* queue lower level code to do work (if necessary) */ |
| 116 | schedule_delayed_work(&sm->associnfo.work, 0); | 116 | schedule_delayed_work(&sm->associnfo.work, 0); |
| 117 | out: | 117 | |
| 118 | mutex_unlock(&sm->associnfo.mutex); | 118 | mutex_unlock(&sm->associnfo.mutex); |
| 119 | 119 | ||
| 120 | return 0; | 120 | return 0; |
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index bbad2cdb74b7..f893e90061eb 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
| @@ -2420,6 +2420,9 @@ static int tcp_tso_acked(struct sock *sk, struct sk_buff *skb, | |||
| 2420 | __u32 dval = min(tp->fackets_out, packets_acked); | 2420 | __u32 dval = min(tp->fackets_out, packets_acked); |
| 2421 | tp->fackets_out -= dval; | 2421 | tp->fackets_out -= dval; |
| 2422 | } | 2422 | } |
| 2423 | /* hint's skb might be NULL but we don't need to care */ | ||
| 2424 | tp->fastpath_cnt_hint -= min_t(u32, packets_acked, | ||
| 2425 | tp->fastpath_cnt_hint); | ||
| 2423 | tp->packets_out -= packets_acked; | 2426 | tp->packets_out -= packets_acked; |
| 2424 | 2427 | ||
| 2425 | BUG_ON(tcp_skb_pcount(skb) == 0); | 2428 | BUG_ON(tcp_skb_pcount(skb) == 0); |
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 9c94627c8c7e..e089a978e128 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
| @@ -833,8 +833,7 @@ static struct tcp_md5sig_key * | |||
| 833 | return NULL; | 833 | return NULL; |
| 834 | for (i = 0; i < tp->md5sig_info->entries4; i++) { | 834 | for (i = 0; i < tp->md5sig_info->entries4; i++) { |
| 835 | if (tp->md5sig_info->keys4[i].addr == addr) | 835 | if (tp->md5sig_info->keys4[i].addr == addr) |
| 836 | return (struct tcp_md5sig_key *) | 836 | return &tp->md5sig_info->keys4[i].base; |
| 837 | &tp->md5sig_info->keys4[i]; | ||
| 838 | } | 837 | } |
| 839 | return NULL; | 838 | return NULL; |
| 840 | } | 839 | } |
| @@ -865,9 +864,9 @@ int tcp_v4_md5_do_add(struct sock *sk, __be32 addr, | |||
| 865 | key = (struct tcp4_md5sig_key *)tcp_v4_md5_do_lookup(sk, addr); | 864 | key = (struct tcp4_md5sig_key *)tcp_v4_md5_do_lookup(sk, addr); |
| 866 | if (key) { | 865 | if (key) { |
| 867 | /* Pre-existing entry - just update that one. */ | 866 | /* Pre-existing entry - just update that one. */ |
| 868 | kfree(key->key); | 867 | kfree(key->base.key); |
| 869 | key->key = newkey; | 868 | key->base.key = newkey; |
| 870 | key->keylen = newkeylen; | 869 | key->base.keylen = newkeylen; |
| 871 | } else { | 870 | } else { |
| 872 | struct tcp_md5sig_info *md5sig; | 871 | struct tcp_md5sig_info *md5sig; |
| 873 | 872 | ||
| @@ -906,9 +905,9 @@ int tcp_v4_md5_do_add(struct sock *sk, __be32 addr, | |||
| 906 | md5sig->alloced4++; | 905 | md5sig->alloced4++; |
| 907 | } | 906 | } |
| 908 | md5sig->entries4++; | 907 | md5sig->entries4++; |
| 909 | md5sig->keys4[md5sig->entries4 - 1].addr = addr; | 908 | md5sig->keys4[md5sig->entries4 - 1].addr = addr; |
| 910 | md5sig->keys4[md5sig->entries4 - 1].key = newkey; | 909 | md5sig->keys4[md5sig->entries4 - 1].base.key = newkey; |
| 911 | md5sig->keys4[md5sig->entries4 - 1].keylen = newkeylen; | 910 | md5sig->keys4[md5sig->entries4 - 1].base.keylen = newkeylen; |
| 912 | } | 911 | } |
| 913 | return 0; | 912 | return 0; |
| 914 | } | 913 | } |
| @@ -930,7 +929,7 @@ int tcp_v4_md5_do_del(struct sock *sk, __be32 addr) | |||
| 930 | for (i = 0; i < tp->md5sig_info->entries4; i++) { | 929 | for (i = 0; i < tp->md5sig_info->entries4; i++) { |
| 931 | if (tp->md5sig_info->keys4[i].addr == addr) { | 930 | if (tp->md5sig_info->keys4[i].addr == addr) { |
| 932 | /* Free the key */ | 931 | /* Free the key */ |
| 933 | kfree(tp->md5sig_info->keys4[i].key); | 932 | kfree(tp->md5sig_info->keys4[i].base.key); |
| 934 | tp->md5sig_info->entries4--; | 933 | tp->md5sig_info->entries4--; |
| 935 | 934 | ||
| 936 | if (tp->md5sig_info->entries4 == 0) { | 935 | if (tp->md5sig_info->entries4 == 0) { |
| @@ -964,7 +963,7 @@ static void tcp_v4_clear_md5_list(struct sock *sk) | |||
| 964 | if (tp->md5sig_info->entries4) { | 963 | if (tp->md5sig_info->entries4) { |
| 965 | int i; | 964 | int i; |
| 966 | for (i = 0; i < tp->md5sig_info->entries4; i++) | 965 | for (i = 0; i < tp->md5sig_info->entries4; i++) |
| 967 | kfree(tp->md5sig_info->keys4[i].key); | 966 | kfree(tp->md5sig_info->keys4[i].base.key); |
| 968 | tp->md5sig_info->entries4 = 0; | 967 | tp->md5sig_info->entries4 = 0; |
| 969 | tcp_free_md5sig_pool(); | 968 | tcp_free_md5sig_pool(); |
| 970 | } | 969 | } |
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index 73a894a2152c..5b596659177c 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c | |||
| @@ -1268,9 +1268,10 @@ static void ndisc_redirect_rcv(struct sk_buff *skb) | |||
| 1268 | 1268 | ||
| 1269 | if (ipv6_addr_equal(dest, target)) { | 1269 | if (ipv6_addr_equal(dest, target)) { |
| 1270 | on_link = 1; | 1270 | on_link = 1; |
| 1271 | } else if (!(ipv6_addr_type(target) & IPV6_ADDR_LINKLOCAL)) { | 1271 | } else if (ipv6_addr_type(target) != |
| 1272 | (IPV6_ADDR_UNICAST|IPV6_ADDR_LINKLOCAL)) { | ||
| 1272 | ND_PRINTK2(KERN_WARNING | 1273 | ND_PRINTK2(KERN_WARNING |
| 1273 | "ICMPv6 Redirect: target address is not link-local.\n"); | 1274 | "ICMPv6 Redirect: target address is not link-local unicast.\n"); |
| 1274 | return; | 1275 | return; |
| 1275 | } | 1276 | } |
| 1276 | 1277 | ||
| @@ -1344,9 +1345,9 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh, | |||
| 1344 | } | 1345 | } |
| 1345 | 1346 | ||
| 1346 | if (!ipv6_addr_equal(&ipv6_hdr(skb)->daddr, target) && | 1347 | if (!ipv6_addr_equal(&ipv6_hdr(skb)->daddr, target) && |
| 1347 | !(ipv6_addr_type(target) & IPV6_ADDR_LINKLOCAL)) { | 1348 | ipv6_addr_type(target) != (IPV6_ADDR_UNICAST|IPV6_ADDR_LINKLOCAL)) { |
| 1348 | ND_PRINTK2(KERN_WARNING | 1349 | ND_PRINTK2(KERN_WARNING |
| 1349 | "ICMPv6 Redirect: target address is not link-local.\n"); | 1350 | "ICMPv6 Redirect: target address is not link-local unicast.\n"); |
| 1350 | return; | 1351 | return; |
| 1351 | } | 1352 | } |
| 1352 | 1353 | ||
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 0f7defb482e9..3e06799b37a6 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
| @@ -539,7 +539,7 @@ static struct tcp_md5sig_key *tcp_v6_md5_do_lookup(struct sock *sk, | |||
| 539 | 539 | ||
| 540 | for (i = 0; i < tp->md5sig_info->entries6; i++) { | 540 | for (i = 0; i < tp->md5sig_info->entries6; i++) { |
| 541 | if (ipv6_addr_cmp(&tp->md5sig_info->keys6[i].addr, addr) == 0) | 541 | if (ipv6_addr_cmp(&tp->md5sig_info->keys6[i].addr, addr) == 0) |
| 542 | return (struct tcp_md5sig_key *)&tp->md5sig_info->keys6[i]; | 542 | return &tp->md5sig_info->keys6[i].base; |
| 543 | } | 543 | } |
| 544 | return NULL; | 544 | return NULL; |
| 545 | } | 545 | } |
| @@ -567,9 +567,9 @@ static int tcp_v6_md5_do_add(struct sock *sk, struct in6_addr *peer, | |||
| 567 | key = (struct tcp6_md5sig_key*) tcp_v6_md5_do_lookup(sk, peer); | 567 | key = (struct tcp6_md5sig_key*) tcp_v6_md5_do_lookup(sk, peer); |
| 568 | if (key) { | 568 | if (key) { |
| 569 | /* modify existing entry - just update that one */ | 569 | /* modify existing entry - just update that one */ |
| 570 | kfree(key->key); | 570 | kfree(key->base.key); |
| 571 | key->key = newkey; | 571 | key->base.key = newkey; |
| 572 | key->keylen = newkeylen; | 572 | key->base.keylen = newkeylen; |
| 573 | } else { | 573 | } else { |
| 574 | /* reallocate new list if current one is full. */ | 574 | /* reallocate new list if current one is full. */ |
| 575 | if (!tp->md5sig_info) { | 575 | if (!tp->md5sig_info) { |
| @@ -603,8 +603,8 @@ static int tcp_v6_md5_do_add(struct sock *sk, struct in6_addr *peer, | |||
| 603 | 603 | ||
| 604 | ipv6_addr_copy(&tp->md5sig_info->keys6[tp->md5sig_info->entries6].addr, | 604 | ipv6_addr_copy(&tp->md5sig_info->keys6[tp->md5sig_info->entries6].addr, |
| 605 | peer); | 605 | peer); |
| 606 | tp->md5sig_info->keys6[tp->md5sig_info->entries6].key = newkey; | 606 | tp->md5sig_info->keys6[tp->md5sig_info->entries6].base.key = newkey; |
| 607 | tp->md5sig_info->keys6[tp->md5sig_info->entries6].keylen = newkeylen; | 607 | tp->md5sig_info->keys6[tp->md5sig_info->entries6].base.keylen = newkeylen; |
| 608 | 608 | ||
| 609 | tp->md5sig_info->entries6++; | 609 | tp->md5sig_info->entries6++; |
| 610 | } | 610 | } |
| @@ -626,7 +626,7 @@ static int tcp_v6_md5_do_del(struct sock *sk, struct in6_addr *peer) | |||
| 626 | for (i = 0; i < tp->md5sig_info->entries6; i++) { | 626 | for (i = 0; i < tp->md5sig_info->entries6; i++) { |
| 627 | if (ipv6_addr_cmp(&tp->md5sig_info->keys6[i].addr, peer) == 0) { | 627 | if (ipv6_addr_cmp(&tp->md5sig_info->keys6[i].addr, peer) == 0) { |
| 628 | /* Free the key */ | 628 | /* Free the key */ |
| 629 | kfree(tp->md5sig_info->keys6[i].key); | 629 | kfree(tp->md5sig_info->keys6[i].base.key); |
| 630 | tp->md5sig_info->entries6--; | 630 | tp->md5sig_info->entries6--; |
| 631 | 631 | ||
| 632 | if (tp->md5sig_info->entries6 == 0) { | 632 | if (tp->md5sig_info->entries6 == 0) { |
| @@ -657,7 +657,7 @@ static void tcp_v6_clear_md5_list (struct sock *sk) | |||
| 657 | 657 | ||
| 658 | if (tp->md5sig_info->entries6) { | 658 | if (tp->md5sig_info->entries6) { |
| 659 | for (i = 0; i < tp->md5sig_info->entries6; i++) | 659 | for (i = 0; i < tp->md5sig_info->entries6; i++) |
| 660 | kfree(tp->md5sig_info->keys6[i].key); | 660 | kfree(tp->md5sig_info->keys6[i].base.key); |
| 661 | tp->md5sig_info->entries6 = 0; | 661 | tp->md5sig_info->entries6 = 0; |
| 662 | tcp_free_md5sig_pool(); | 662 | tcp_free_md5sig_pool(); |
| 663 | } | 663 | } |
| @@ -668,7 +668,7 @@ static void tcp_v6_clear_md5_list (struct sock *sk) | |||
| 668 | 668 | ||
| 669 | if (tp->md5sig_info->entries4) { | 669 | if (tp->md5sig_info->entries4) { |
| 670 | for (i = 0; i < tp->md5sig_info->entries4; i++) | 670 | for (i = 0; i < tp->md5sig_info->entries4; i++) |
| 671 | kfree(tp->md5sig_info->keys4[i].key); | 671 | kfree(tp->md5sig_info->keys4[i].base.key); |
| 672 | tp->md5sig_info->entries4 = 0; | 672 | tp->md5sig_info->entries4 = 0; |
| 673 | tcp_free_md5sig_pool(); | 673 | tcp_free_md5sig_pool(); |
| 674 | } | 674 | } |
diff --git a/net/rose/rose_loopback.c b/net/rose/rose_loopback.c index cd01642f0491..114df6eec8c3 100644 --- a/net/rose/rose_loopback.c +++ b/net/rose/rose_loopback.c | |||
| @@ -79,7 +79,7 @@ static void rose_loopback_timer(unsigned long param) | |||
| 79 | 79 | ||
| 80 | skb_reset_transport_header(skb); | 80 | skb_reset_transport_header(skb); |
| 81 | 81 | ||
| 82 | sk = rose_find_socket(lci_o, &rose_loopback_neigh); | 82 | sk = rose_find_socket(lci_o, rose_loopback_neigh); |
| 83 | if (sk) { | 83 | if (sk) { |
| 84 | if (rose_process_rx_frame(sk, skb) == 0) | 84 | if (rose_process_rx_frame(sk, skb) == 0) |
| 85 | kfree_skb(skb); | 85 | kfree_skb(skb); |
| @@ -88,7 +88,7 @@ static void rose_loopback_timer(unsigned long param) | |||
| 88 | 88 | ||
| 89 | if (frametype == ROSE_CALL_REQUEST) { | 89 | if (frametype == ROSE_CALL_REQUEST) { |
| 90 | if ((dev = rose_dev_get(dest)) != NULL) { | 90 | if ((dev = rose_dev_get(dest)) != NULL) { |
| 91 | if (rose_rx_call_request(skb, dev, &rose_loopback_neigh, lci_o) == 0) | 91 | if (rose_rx_call_request(skb, dev, rose_loopback_neigh, lci_o) == 0) |
| 92 | kfree_skb(skb); | 92 | kfree_skb(skb); |
| 93 | } else { | 93 | } else { |
| 94 | kfree_skb(skb); | 94 | kfree_skb(skb); |
diff --git a/net/rose/rose_route.c b/net/rose/rose_route.c index bbcbad1da0d0..96f61a71b252 100644 --- a/net/rose/rose_route.c +++ b/net/rose/rose_route.c | |||
| @@ -45,7 +45,7 @@ static DEFINE_SPINLOCK(rose_neigh_list_lock); | |||
| 45 | static struct rose_route *rose_route_list; | 45 | static struct rose_route *rose_route_list; |
| 46 | static DEFINE_SPINLOCK(rose_route_list_lock); | 46 | static DEFINE_SPINLOCK(rose_route_list_lock); |
| 47 | 47 | ||
| 48 | struct rose_neigh rose_loopback_neigh; | 48 | struct rose_neigh *rose_loopback_neigh; |
| 49 | 49 | ||
| 50 | /* | 50 | /* |
| 51 | * Add a new route to a node, and in the process add the node and the | 51 | * Add a new route to a node, and in the process add the node and the |
| @@ -362,7 +362,12 @@ out: | |||
| 362 | */ | 362 | */ |
| 363 | void rose_add_loopback_neigh(void) | 363 | void rose_add_loopback_neigh(void) |
| 364 | { | 364 | { |
| 365 | struct rose_neigh *sn = &rose_loopback_neigh; | 365 | struct rose_neigh *sn; |
| 366 | |||
| 367 | rose_loopback_neigh = kmalloc(sizeof(struct rose_neigh), GFP_KERNEL); | ||
| 368 | if (!rose_loopback_neigh) | ||
| 369 | return; | ||
| 370 | sn = rose_loopback_neigh; | ||
| 366 | 371 | ||
| 367 | sn->callsign = null_ax25_address; | 372 | sn->callsign = null_ax25_address; |
| 368 | sn->digipeat = NULL; | 373 | sn->digipeat = NULL; |
| @@ -417,13 +422,13 @@ int rose_add_loopback_node(rose_address *address) | |||
| 417 | rose_node->mask = 10; | 422 | rose_node->mask = 10; |
| 418 | rose_node->count = 1; | 423 | rose_node->count = 1; |
| 419 | rose_node->loopback = 1; | 424 | rose_node->loopback = 1; |
| 420 | rose_node->neighbour[0] = &rose_loopback_neigh; | 425 | rose_node->neighbour[0] = rose_loopback_neigh; |
| 421 | 426 | ||
| 422 | /* Insert at the head of list. Address is always mask=10 */ | 427 | /* Insert at the head of list. Address is always mask=10 */ |
| 423 | rose_node->next = rose_node_list; | 428 | rose_node->next = rose_node_list; |
| 424 | rose_node_list = rose_node; | 429 | rose_node_list = rose_node; |
| 425 | 430 | ||
| 426 | rose_loopback_neigh.count++; | 431 | rose_loopback_neigh->count++; |
| 427 | 432 | ||
| 428 | out: | 433 | out: |
| 429 | spin_unlock_bh(&rose_node_list_lock); | 434 | spin_unlock_bh(&rose_node_list_lock); |
| @@ -454,7 +459,7 @@ void rose_del_loopback_node(rose_address *address) | |||
| 454 | 459 | ||
| 455 | rose_remove_node(rose_node); | 460 | rose_remove_node(rose_node); |
| 456 | 461 | ||
| 457 | rose_loopback_neigh.count--; | 462 | rose_loopback_neigh->count--; |
| 458 | 463 | ||
| 459 | out: | 464 | out: |
| 460 | spin_unlock_bh(&rose_node_list_lock); | 465 | spin_unlock_bh(&rose_node_list_lock); |
diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c index 8dbe36912ecb..d4d5d2f271d2 100644 --- a/net/sched/cls_u32.c +++ b/net/sched/cls_u32.c | |||
| @@ -502,7 +502,7 @@ static int u32_set_parms(struct tcf_proto *tp, unsigned long base, | |||
| 502 | 502 | ||
| 503 | #ifdef CONFIG_NET_CLS_IND | 503 | #ifdef CONFIG_NET_CLS_IND |
| 504 | if (tb[TCA_U32_INDEV-1]) { | 504 | if (tb[TCA_U32_INDEV-1]) { |
| 505 | int err = tcf_change_indev(tp, n->indev, tb[TCA_U32_INDEV-1]); | 505 | err = tcf_change_indev(tp, n->indev, tb[TCA_U32_INDEV-1]); |
| 506 | if (err < 0) | 506 | if (err < 0) |
| 507 | goto errout; | 507 | goto errout; |
| 508 | } | 508 | } |
diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c index 3a23e30bc79e..b542c875e154 100644 --- a/net/sched/sch_sfq.c +++ b/net/sched/sch_sfq.c | |||
| @@ -19,6 +19,7 @@ | |||
| 19 | #include <linux/init.h> | 19 | #include <linux/init.h> |
| 20 | #include <linux/ipv6.h> | 20 | #include <linux/ipv6.h> |
| 21 | #include <linux/skbuff.h> | 21 | #include <linux/skbuff.h> |
| 22 | #include <linux/jhash.h> | ||
| 22 | #include <net/ip.h> | 23 | #include <net/ip.h> |
| 23 | #include <net/netlink.h> | 24 | #include <net/netlink.h> |
| 24 | #include <net/pkt_sched.h> | 25 | #include <net/pkt_sched.h> |
| @@ -95,7 +96,7 @@ struct sfq_sched_data | |||
| 95 | 96 | ||
| 96 | /* Variables */ | 97 | /* Variables */ |
| 97 | struct timer_list perturb_timer; | 98 | struct timer_list perturb_timer; |
| 98 | int perturbation; | 99 | u32 perturbation; |
| 99 | sfq_index tail; /* Index of current slot in round */ | 100 | sfq_index tail; /* Index of current slot in round */ |
| 100 | sfq_index max_depth; /* Maximal depth */ | 101 | sfq_index max_depth; /* Maximal depth */ |
| 101 | 102 | ||
| @@ -109,12 +110,7 @@ struct sfq_sched_data | |||
| 109 | 110 | ||
| 110 | static __inline__ unsigned sfq_fold_hash(struct sfq_sched_data *q, u32 h, u32 h1) | 111 | static __inline__ unsigned sfq_fold_hash(struct sfq_sched_data *q, u32 h, u32 h1) |
| 111 | { | 112 | { |
| 112 | int pert = q->perturbation; | 113 | return jhash_2words(h, h1, q->perturbation) & (SFQ_HASH_DIVISOR - 1); |
| 113 | |||
| 114 | /* Have we any rotation primitives? If not, WHY? */ | ||
| 115 | h ^= (h1<<pert) ^ (h1>>(0x1F - pert)); | ||
| 116 | h ^= h>>10; | ||
| 117 | return h & 0x3FF; | ||
| 118 | } | 114 | } |
| 119 | 115 | ||
| 120 | static unsigned sfq_hash(struct sfq_sched_data *q, struct sk_buff *skb) | 116 | static unsigned sfq_hash(struct sfq_sched_data *q, struct sk_buff *skb) |
| @@ -256,6 +252,13 @@ sfq_enqueue(struct sk_buff *skb, struct Qdisc* sch) | |||
| 256 | q->ht[hash] = x = q->dep[SFQ_DEPTH].next; | 252 | q->ht[hash] = x = q->dep[SFQ_DEPTH].next; |
| 257 | q->hash[x] = hash; | 253 | q->hash[x] = hash; |
| 258 | } | 254 | } |
| 255 | /* If selected queue has length q->limit, this means that | ||
| 256 | * all another queues are empty and that we do simple tail drop, | ||
| 257 | * i.e. drop _this_ packet. | ||
| 258 | */ | ||
| 259 | if (q->qs[x].qlen >= q->limit) | ||
| 260 | return qdisc_drop(skb, sch); | ||
| 261 | |||
| 259 | sch->qstats.backlog += skb->len; | 262 | sch->qstats.backlog += skb->len; |
| 260 | __skb_queue_tail(&q->qs[x], skb); | 263 | __skb_queue_tail(&q->qs[x], skb); |
| 261 | sfq_inc(q, x); | 264 | sfq_inc(q, x); |
| @@ -294,6 +297,19 @@ sfq_requeue(struct sk_buff *skb, struct Qdisc* sch) | |||
| 294 | } | 297 | } |
| 295 | sch->qstats.backlog += skb->len; | 298 | sch->qstats.backlog += skb->len; |
| 296 | __skb_queue_head(&q->qs[x], skb); | 299 | __skb_queue_head(&q->qs[x], skb); |
| 300 | /* If selected queue has length q->limit+1, this means that | ||
| 301 | * all another queues are empty and we do simple tail drop. | ||
| 302 | * This packet is still requeued at head of queue, tail packet | ||
| 303 | * is dropped. | ||
| 304 | */ | ||
| 305 | if (q->qs[x].qlen > q->limit) { | ||
| 306 | skb = q->qs[x].prev; | ||
| 307 | __skb_unlink(skb, &q->qs[x]); | ||
| 308 | sch->qstats.drops++; | ||
| 309 | sch->qstats.backlog -= skb->len; | ||
| 310 | kfree_skb(skb); | ||
| 311 | return NET_XMIT_CN; | ||
| 312 | } | ||
| 297 | sfq_inc(q, x); | 313 | sfq_inc(q, x); |
| 298 | if (q->qs[x].qlen == 1) { /* The flow is new */ | 314 | if (q->qs[x].qlen == 1) { /* The flow is new */ |
| 299 | if (q->tail == SFQ_DEPTH) { /* It is the first flow */ | 315 | if (q->tail == SFQ_DEPTH) { /* It is the first flow */ |
| @@ -370,12 +386,10 @@ static void sfq_perturbation(unsigned long arg) | |||
| 370 | struct Qdisc *sch = (struct Qdisc*)arg; | 386 | struct Qdisc *sch = (struct Qdisc*)arg; |
| 371 | struct sfq_sched_data *q = qdisc_priv(sch); | 387 | struct sfq_sched_data *q = qdisc_priv(sch); |
| 372 | 388 | ||
| 373 | q->perturbation = net_random()&0x1F; | 389 | get_random_bytes(&q->perturbation, 4); |
| 374 | 390 | ||
| 375 | if (q->perturb_period) { | 391 | if (q->perturb_period) |
| 376 | q->perturb_timer.expires = jiffies + q->perturb_period; | 392 | mod_timer(&q->perturb_timer, jiffies + q->perturb_period); |
| 377 | add_timer(&q->perturb_timer); | ||
| 378 | } | ||
| 379 | } | 393 | } |
| 380 | 394 | ||
| 381 | static int sfq_change(struct Qdisc *sch, struct rtattr *opt) | 395 | static int sfq_change(struct Qdisc *sch, struct rtattr *opt) |
| @@ -391,7 +405,7 @@ static int sfq_change(struct Qdisc *sch, struct rtattr *opt) | |||
| 391 | q->quantum = ctl->quantum ? : psched_mtu(sch->dev); | 405 | q->quantum = ctl->quantum ? : psched_mtu(sch->dev); |
| 392 | q->perturb_period = ctl->perturb_period*HZ; | 406 | q->perturb_period = ctl->perturb_period*HZ; |
| 393 | if (ctl->limit) | 407 | if (ctl->limit) |
| 394 | q->limit = min_t(u32, ctl->limit, SFQ_DEPTH - 2); | 408 | q->limit = min_t(u32, ctl->limit, SFQ_DEPTH - 1); |
| 395 | 409 | ||
| 396 | qlen = sch->q.qlen; | 410 | qlen = sch->q.qlen; |
| 397 | while (sch->q.qlen > q->limit) | 411 | while (sch->q.qlen > q->limit) |
| @@ -400,8 +414,8 @@ static int sfq_change(struct Qdisc *sch, struct rtattr *opt) | |||
| 400 | 414 | ||
| 401 | del_timer(&q->perturb_timer); | 415 | del_timer(&q->perturb_timer); |
| 402 | if (q->perturb_period) { | 416 | if (q->perturb_period) { |
| 403 | q->perturb_timer.expires = jiffies + q->perturb_period; | 417 | mod_timer(&q->perturb_timer, jiffies + q->perturb_period); |
| 404 | add_timer(&q->perturb_timer); | 418 | get_random_bytes(&q->perturbation, 4); |
| 405 | } | 419 | } |
| 406 | sch_tree_unlock(sch); | 420 | sch_tree_unlock(sch); |
| 407 | return 0; | 421 | return 0; |
| @@ -423,12 +437,13 @@ static int sfq_init(struct Qdisc *sch, struct rtattr *opt) | |||
| 423 | q->dep[i+SFQ_DEPTH].next = i+SFQ_DEPTH; | 437 | q->dep[i+SFQ_DEPTH].next = i+SFQ_DEPTH; |
| 424 | q->dep[i+SFQ_DEPTH].prev = i+SFQ_DEPTH; | 438 | q->dep[i+SFQ_DEPTH].prev = i+SFQ_DEPTH; |
| 425 | } | 439 | } |
| 426 | q->limit = SFQ_DEPTH - 2; | 440 | q->limit = SFQ_DEPTH - 1; |
| 427 | q->max_depth = 0; | 441 | q->max_depth = 0; |
| 428 | q->tail = SFQ_DEPTH; | 442 | q->tail = SFQ_DEPTH; |
| 429 | if (opt == NULL) { | 443 | if (opt == NULL) { |
| 430 | q->quantum = psched_mtu(sch->dev); | 444 | q->quantum = psched_mtu(sch->dev); |
| 431 | q->perturb_period = 0; | 445 | q->perturb_period = 0; |
| 446 | get_random_bytes(&q->perturbation, 4); | ||
| 432 | } else { | 447 | } else { |
| 433 | int err = sfq_change(sch, opt); | 448 | int err = sfq_change(sch, opt); |
| 434 | if (err) | 449 | if (err) |
diff --git a/net/socket.c b/net/socket.c index 7d44453dfae1..b09eb9036a17 100644 --- a/net/socket.c +++ b/net/socket.c | |||
| @@ -777,9 +777,6 @@ static ssize_t sock_aio_write(struct kiocb *iocb, const struct iovec *iov, | |||
| 777 | if (pos != 0) | 777 | if (pos != 0) |
| 778 | return -ESPIPE; | 778 | return -ESPIPE; |
| 779 | 779 | ||
| 780 | if (iocb->ki_left == 0) /* Match SYS5 behaviour */ | ||
| 781 | return 0; | ||
| 782 | |||
| 783 | x = alloc_sock_iocb(iocb, &siocb); | 780 | x = alloc_sock_iocb(iocb, &siocb); |
| 784 | if (!x) | 781 | if (!x) |
| 785 | return -ENOMEM; | 782 | return -ENOMEM; |
