diff options
author | John W. Linville <linville@tuxdriver.com> | 2006-05-17 14:51:24 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2006-05-17 14:51:24 -0400 |
commit | 5dd8816aeb1f068ade0349a22009ff7a66f25413 (patch) | |
tree | c56ff327b1dfa8868b4208aea9ac4158e3bfe308 /net | |
parent | f03cc4fd927357bd4b3cea1a053b9f9d8f1731cc (diff) | |
parent | 0c056c50a6218e0e577817c16ba8851af593d742 (diff) |
Merge branch 'from-linus' into upstream
Diffstat (limited to 'net')
-rw-r--r-- | net/atm/clip.c | 2 | ||||
-rw-r--r-- | net/bridge/br_if.c | 21 | ||||
-rw-r--r-- | net/bridge/br_input.c | 1 | ||||
-rw-r--r-- | net/core/dev.c | 99 | ||||
-rw-r--r-- | net/core/link_watch.c | 10 | ||||
-rw-r--r-- | net/core/neighbour.c | 21 | ||||
-rw-r--r-- | net/core/net-sysfs.c | 49 | ||||
-rw-r--r-- | net/dccp/proto.c | 13 | ||||
-rw-r--r-- | net/ipv4/ip_input.c | 2 | ||||
-rw-r--r-- | net/ipv4/ip_options.c | 2 | ||||
-rw-r--r-- | net/ipv4/tcp_highspeed.c | 2 | ||||
-rw-r--r-- | net/ipv6/inet6_connection_sock.c | 2 | ||||
-rw-r--r-- | net/irda/irias_object.c | 3 | ||||
-rw-r--r-- | net/netrom/af_netrom.c | 3 | ||||
-rw-r--r-- | net/rose/af_rose.c | 3 | ||||
-rw-r--r-- | net/sched/sch_hfsc.c | 6 | ||||
-rw-r--r-- | net/sctp/inqueue.c | 1 | ||||
-rw-r--r-- | net/sctp/sm_statefuns.c | 59 | ||||
-rw-r--r-- | net/sctp/sm_statetable.c | 10 | ||||
-rw-r--r-- | net/sctp/ulpqueue.c | 27 |
20 files changed, 183 insertions, 153 deletions
diff --git a/net/atm/clip.c b/net/atm/clip.c index 1a786bfaa416..72d852982664 100644 --- a/net/atm/clip.c +++ b/net/atm/clip.c | |||
@@ -963,7 +963,7 @@ static struct file_operations arp_seq_fops = { | |||
963 | static int __init atm_clip_init(void) | 963 | static int __init atm_clip_init(void) |
964 | { | 964 | { |
965 | struct proc_dir_entry *p; | 965 | struct proc_dir_entry *p; |
966 | neigh_table_init(&clip_tbl); | 966 | neigh_table_init_no_netlink(&clip_tbl); |
967 | 967 | ||
968 | clip_tbl_hook = &clip_tbl; | 968 | clip_tbl_hook = &clip_tbl; |
969 | register_atm_ioctl(&clip_ioctl_ops); | 969 | register_atm_ioctl(&clip_ioctl_ops); |
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index 59eef42d4a42..ad1c7af65ec8 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c | |||
@@ -308,26 +308,19 @@ int br_add_bridge(const char *name) | |||
308 | if (ret) | 308 | if (ret) |
309 | goto err2; | 309 | goto err2; |
310 | 310 | ||
311 | /* network device kobject is not setup until | ||
312 | * after rtnl_unlock does it's hotplug magic. | ||
313 | * so hold reference to avoid race. | ||
314 | */ | ||
315 | dev_hold(dev); | ||
316 | rtnl_unlock(); | ||
317 | |||
318 | ret = br_sysfs_addbr(dev); | 311 | ret = br_sysfs_addbr(dev); |
319 | dev_put(dev); | 312 | if (ret) |
320 | 313 | goto err3; | |
321 | if (ret) | 314 | rtnl_unlock(); |
322 | unregister_netdev(dev); | 315 | return 0; |
323 | out: | ||
324 | return ret; | ||
325 | 316 | ||
317 | err3: | ||
318 | unregister_netdev(dev); | ||
326 | err2: | 319 | err2: |
327 | free_netdev(dev); | 320 | free_netdev(dev); |
328 | err1: | 321 | err1: |
329 | rtnl_unlock(); | 322 | rtnl_unlock(); |
330 | goto out; | 323 | return ret; |
331 | } | 324 | } |
332 | 325 | ||
333 | int br_del_bridge(const char *name) | 326 | int br_del_bridge(const char *name) |
diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c index b0b7f55c1edd..bfa4d8c333f7 100644 --- a/net/bridge/br_input.c +++ b/net/bridge/br_input.c | |||
@@ -66,6 +66,7 @@ int br_handle_frame_finish(struct sk_buff *skb) | |||
66 | } | 66 | } |
67 | 67 | ||
68 | if (is_multicast_ether_addr(dest)) { | 68 | if (is_multicast_ether_addr(dest)) { |
69 | br->statistics.multicast++; | ||
69 | br_flood_forward(br, skb, !passedup); | 70 | br_flood_forward(br, skb, !passedup); |
70 | if (!passedup) | 71 | if (!passedup) |
71 | br_pass_frame_up(br, skb); | 72 | br_pass_frame_up(br, skb); |
diff --git a/net/core/dev.c b/net/core/dev.c index 3bad1afc89fa..2dce673a039b 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -193,7 +193,7 @@ static inline struct hlist_head *dev_index_hash(int ifindex) | |||
193 | * Our notifier list | 193 | * Our notifier list |
194 | */ | 194 | */ |
195 | 195 | ||
196 | static BLOCKING_NOTIFIER_HEAD(netdev_chain); | 196 | static RAW_NOTIFIER_HEAD(netdev_chain); |
197 | 197 | ||
198 | /* | 198 | /* |
199 | * Device drivers call our routines to queue packets here. We empty the | 199 | * Device drivers call our routines to queue packets here. We empty the |
@@ -736,7 +736,7 @@ int dev_change_name(struct net_device *dev, char *newname) | |||
736 | if (!err) { | 736 | if (!err) { |
737 | hlist_del(&dev->name_hlist); | 737 | hlist_del(&dev->name_hlist); |
738 | hlist_add_head(&dev->name_hlist, dev_name_hash(dev->name)); | 738 | hlist_add_head(&dev->name_hlist, dev_name_hash(dev->name)); |
739 | blocking_notifier_call_chain(&netdev_chain, | 739 | raw_notifier_call_chain(&netdev_chain, |
740 | NETDEV_CHANGENAME, dev); | 740 | NETDEV_CHANGENAME, dev); |
741 | } | 741 | } |
742 | 742 | ||
@@ -751,7 +751,7 @@ int dev_change_name(struct net_device *dev, char *newname) | |||
751 | */ | 751 | */ |
752 | void netdev_features_change(struct net_device *dev) | 752 | void netdev_features_change(struct net_device *dev) |
753 | { | 753 | { |
754 | blocking_notifier_call_chain(&netdev_chain, NETDEV_FEAT_CHANGE, dev); | 754 | raw_notifier_call_chain(&netdev_chain, NETDEV_FEAT_CHANGE, dev); |
755 | } | 755 | } |
756 | EXPORT_SYMBOL(netdev_features_change); | 756 | EXPORT_SYMBOL(netdev_features_change); |
757 | 757 | ||
@@ -766,7 +766,7 @@ EXPORT_SYMBOL(netdev_features_change); | |||
766 | void netdev_state_change(struct net_device *dev) | 766 | void netdev_state_change(struct net_device *dev) |
767 | { | 767 | { |
768 | if (dev->flags & IFF_UP) { | 768 | if (dev->flags & IFF_UP) { |
769 | blocking_notifier_call_chain(&netdev_chain, | 769 | raw_notifier_call_chain(&netdev_chain, |
770 | NETDEV_CHANGE, dev); | 770 | NETDEV_CHANGE, dev); |
771 | rtmsg_ifinfo(RTM_NEWLINK, dev, 0); | 771 | rtmsg_ifinfo(RTM_NEWLINK, dev, 0); |
772 | } | 772 | } |
@@ -864,7 +864,7 @@ int dev_open(struct net_device *dev) | |||
864 | /* | 864 | /* |
865 | * ... and announce new interface. | 865 | * ... and announce new interface. |
866 | */ | 866 | */ |
867 | blocking_notifier_call_chain(&netdev_chain, NETDEV_UP, dev); | 867 | raw_notifier_call_chain(&netdev_chain, NETDEV_UP, dev); |
868 | } | 868 | } |
869 | return ret; | 869 | return ret; |
870 | } | 870 | } |
@@ -887,7 +887,7 @@ int dev_close(struct net_device *dev) | |||
887 | * Tell people we are going down, so that they can | 887 | * Tell people we are going down, so that they can |
888 | * prepare to death, when device is still operating. | 888 | * prepare to death, when device is still operating. |
889 | */ | 889 | */ |
890 | blocking_notifier_call_chain(&netdev_chain, NETDEV_GOING_DOWN, dev); | 890 | raw_notifier_call_chain(&netdev_chain, NETDEV_GOING_DOWN, dev); |
891 | 891 | ||
892 | dev_deactivate(dev); | 892 | dev_deactivate(dev); |
893 | 893 | ||
@@ -924,7 +924,7 @@ int dev_close(struct net_device *dev) | |||
924 | /* | 924 | /* |
925 | * Tell people we are down | 925 | * Tell people we are down |
926 | */ | 926 | */ |
927 | blocking_notifier_call_chain(&netdev_chain, NETDEV_DOWN, dev); | 927 | raw_notifier_call_chain(&netdev_chain, NETDEV_DOWN, dev); |
928 | 928 | ||
929 | return 0; | 929 | return 0; |
930 | } | 930 | } |
@@ -955,7 +955,7 @@ int register_netdevice_notifier(struct notifier_block *nb) | |||
955 | int err; | 955 | int err; |
956 | 956 | ||
957 | rtnl_lock(); | 957 | rtnl_lock(); |
958 | err = blocking_notifier_chain_register(&netdev_chain, nb); | 958 | err = raw_notifier_chain_register(&netdev_chain, nb); |
959 | if (!err) { | 959 | if (!err) { |
960 | for (dev = dev_base; dev; dev = dev->next) { | 960 | for (dev = dev_base; dev; dev = dev->next) { |
961 | nb->notifier_call(nb, NETDEV_REGISTER, dev); | 961 | nb->notifier_call(nb, NETDEV_REGISTER, dev); |
@@ -983,7 +983,7 @@ int unregister_netdevice_notifier(struct notifier_block *nb) | |||
983 | int err; | 983 | int err; |
984 | 984 | ||
985 | rtnl_lock(); | 985 | rtnl_lock(); |
986 | err = blocking_notifier_chain_unregister(&netdev_chain, nb); | 986 | err = raw_notifier_chain_unregister(&netdev_chain, nb); |
987 | rtnl_unlock(); | 987 | rtnl_unlock(); |
988 | return err; | 988 | return err; |
989 | } | 989 | } |
@@ -994,12 +994,12 @@ int unregister_netdevice_notifier(struct notifier_block *nb) | |||
994 | * @v: pointer passed unmodified to notifier function | 994 | * @v: pointer passed unmodified to notifier function |
995 | * | 995 | * |
996 | * Call all network notifier blocks. Parameters and return value | 996 | * Call all network notifier blocks. Parameters and return value |
997 | * are as for blocking_notifier_call_chain(). | 997 | * are as for raw_notifier_call_chain(). |
998 | */ | 998 | */ |
999 | 999 | ||
1000 | int call_netdevice_notifiers(unsigned long val, void *v) | 1000 | int call_netdevice_notifiers(unsigned long val, void *v) |
1001 | { | 1001 | { |
1002 | return blocking_notifier_call_chain(&netdev_chain, val, v); | 1002 | return raw_notifier_call_chain(&netdev_chain, val, v); |
1003 | } | 1003 | } |
1004 | 1004 | ||
1005 | /* When > 0 there are consumers of rx skb time stamps */ | 1005 | /* When > 0 there are consumers of rx skb time stamps */ |
@@ -2308,7 +2308,7 @@ int dev_change_flags(struct net_device *dev, unsigned flags) | |||
2308 | if (dev->flags & IFF_UP && | 2308 | if (dev->flags & IFF_UP && |
2309 | ((old_flags ^ dev->flags) &~ (IFF_UP | IFF_PROMISC | IFF_ALLMULTI | | 2309 | ((old_flags ^ dev->flags) &~ (IFF_UP | IFF_PROMISC | IFF_ALLMULTI | |
2310 | IFF_VOLATILE))) | 2310 | IFF_VOLATILE))) |
2311 | blocking_notifier_call_chain(&netdev_chain, | 2311 | raw_notifier_call_chain(&netdev_chain, |
2312 | NETDEV_CHANGE, dev); | 2312 | NETDEV_CHANGE, dev); |
2313 | 2313 | ||
2314 | if ((flags ^ dev->gflags) & IFF_PROMISC) { | 2314 | if ((flags ^ dev->gflags) & IFF_PROMISC) { |
@@ -2353,7 +2353,7 @@ int dev_set_mtu(struct net_device *dev, int new_mtu) | |||
2353 | else | 2353 | else |
2354 | dev->mtu = new_mtu; | 2354 | dev->mtu = new_mtu; |
2355 | if (!err && dev->flags & IFF_UP) | 2355 | if (!err && dev->flags & IFF_UP) |
2356 | blocking_notifier_call_chain(&netdev_chain, | 2356 | raw_notifier_call_chain(&netdev_chain, |
2357 | NETDEV_CHANGEMTU, dev); | 2357 | NETDEV_CHANGEMTU, dev); |
2358 | return err; | 2358 | return err; |
2359 | } | 2359 | } |
@@ -2370,7 +2370,7 @@ int dev_set_mac_address(struct net_device *dev, struct sockaddr *sa) | |||
2370 | return -ENODEV; | 2370 | return -ENODEV; |
2371 | err = dev->set_mac_address(dev, sa); | 2371 | err = dev->set_mac_address(dev, sa); |
2372 | if (!err) | 2372 | if (!err) |
2373 | blocking_notifier_call_chain(&netdev_chain, | 2373 | raw_notifier_call_chain(&netdev_chain, |
2374 | NETDEV_CHANGEADDR, dev); | 2374 | NETDEV_CHANGEADDR, dev); |
2375 | return err; | 2375 | return err; |
2376 | } | 2376 | } |
@@ -2427,7 +2427,7 @@ static int dev_ifsioc(struct ifreq *ifr, unsigned int cmd) | |||
2427 | return -EINVAL; | 2427 | return -EINVAL; |
2428 | memcpy(dev->broadcast, ifr->ifr_hwaddr.sa_data, | 2428 | memcpy(dev->broadcast, ifr->ifr_hwaddr.sa_data, |
2429 | min(sizeof ifr->ifr_hwaddr.sa_data, (size_t) dev->addr_len)); | 2429 | min(sizeof ifr->ifr_hwaddr.sa_data, (size_t) dev->addr_len)); |
2430 | blocking_notifier_call_chain(&netdev_chain, | 2430 | raw_notifier_call_chain(&netdev_chain, |
2431 | NETDEV_CHANGEADDR, dev); | 2431 | NETDEV_CHANGEADDR, dev); |
2432 | return 0; | 2432 | return 0; |
2433 | 2433 | ||
@@ -2777,6 +2777,8 @@ int register_netdevice(struct net_device *dev) | |||
2777 | BUG_ON(dev_boot_phase); | 2777 | BUG_ON(dev_boot_phase); |
2778 | ASSERT_RTNL(); | 2778 | ASSERT_RTNL(); |
2779 | 2779 | ||
2780 | might_sleep(); | ||
2781 | |||
2780 | /* When net_device's are persistent, this will be fatal. */ | 2782 | /* When net_device's are persistent, this will be fatal. */ |
2781 | BUG_ON(dev->reg_state != NETREG_UNINITIALIZED); | 2783 | BUG_ON(dev->reg_state != NETREG_UNINITIALIZED); |
2782 | 2784 | ||
@@ -2863,6 +2865,11 @@ int register_netdevice(struct net_device *dev) | |||
2863 | if (!dev->rebuild_header) | 2865 | if (!dev->rebuild_header) |
2864 | dev->rebuild_header = default_rebuild_header; | 2866 | dev->rebuild_header = default_rebuild_header; |
2865 | 2867 | ||
2868 | ret = netdev_register_sysfs(dev); | ||
2869 | if (ret) | ||
2870 | goto out_err; | ||
2871 | dev->reg_state = NETREG_REGISTERED; | ||
2872 | |||
2866 | /* | 2873 | /* |
2867 | * Default initial state at registry is that the | 2874 | * Default initial state at registry is that the |
2868 | * device is present. | 2875 | * device is present. |
@@ -2878,14 +2885,11 @@ int register_netdevice(struct net_device *dev) | |||
2878 | hlist_add_head(&dev->name_hlist, head); | 2885 | hlist_add_head(&dev->name_hlist, head); |
2879 | hlist_add_head(&dev->index_hlist, dev_index_hash(dev->ifindex)); | 2886 | hlist_add_head(&dev->index_hlist, dev_index_hash(dev->ifindex)); |
2880 | dev_hold(dev); | 2887 | dev_hold(dev); |
2881 | dev->reg_state = NETREG_REGISTERING; | ||
2882 | write_unlock_bh(&dev_base_lock); | 2888 | write_unlock_bh(&dev_base_lock); |
2883 | 2889 | ||
2884 | /* Notify protocols, that a new device appeared. */ | 2890 | /* Notify protocols, that a new device appeared. */ |
2885 | blocking_notifier_call_chain(&netdev_chain, NETDEV_REGISTER, dev); | 2891 | raw_notifier_call_chain(&netdev_chain, NETDEV_REGISTER, dev); |
2886 | 2892 | ||
2887 | /* Finish registration after unlock */ | ||
2888 | net_set_todo(dev); | ||
2889 | ret = 0; | 2893 | ret = 0; |
2890 | 2894 | ||
2891 | out: | 2895 | out: |
@@ -2961,7 +2965,7 @@ static void netdev_wait_allrefs(struct net_device *dev) | |||
2961 | rtnl_lock(); | 2965 | rtnl_lock(); |
2962 | 2966 | ||
2963 | /* Rebroadcast unregister notification */ | 2967 | /* Rebroadcast unregister notification */ |
2964 | blocking_notifier_call_chain(&netdev_chain, | 2968 | raw_notifier_call_chain(&netdev_chain, |
2965 | NETDEV_UNREGISTER, dev); | 2969 | NETDEV_UNREGISTER, dev); |
2966 | 2970 | ||
2967 | if (test_bit(__LINK_STATE_LINKWATCH_PENDING, | 2971 | if (test_bit(__LINK_STATE_LINKWATCH_PENDING, |
@@ -3008,7 +3012,7 @@ static void netdev_wait_allrefs(struct net_device *dev) | |||
3008 | * | 3012 | * |
3009 | * We are invoked by rtnl_unlock() after it drops the semaphore. | 3013 | * We are invoked by rtnl_unlock() after it drops the semaphore. |
3010 | * This allows us to deal with problems: | 3014 | * This allows us to deal with problems: |
3011 | * 1) We can create/delete sysfs objects which invoke hotplug | 3015 | * 1) We can delete sysfs objects which invoke hotplug |
3012 | * without deadlocking with linkwatch via keventd. | 3016 | * without deadlocking with linkwatch via keventd. |
3013 | * 2) Since we run with the RTNL semaphore not held, we can sleep | 3017 | * 2) Since we run with the RTNL semaphore not held, we can sleep |
3014 | * safely in order to wait for the netdev refcnt to drop to zero. | 3018 | * safely in order to wait for the netdev refcnt to drop to zero. |
@@ -3017,8 +3021,6 @@ static DEFINE_MUTEX(net_todo_run_mutex); | |||
3017 | void netdev_run_todo(void) | 3021 | void netdev_run_todo(void) |
3018 | { | 3022 | { |
3019 | struct list_head list = LIST_HEAD_INIT(list); | 3023 | struct list_head list = LIST_HEAD_INIT(list); |
3020 | int err; | ||
3021 | |||
3022 | 3024 | ||
3023 | /* Need to guard against multiple cpu's getting out of order. */ | 3025 | /* Need to guard against multiple cpu's getting out of order. */ |
3024 | mutex_lock(&net_todo_run_mutex); | 3026 | mutex_lock(&net_todo_run_mutex); |
@@ -3041,40 +3043,29 @@ void netdev_run_todo(void) | |||
3041 | = list_entry(list.next, struct net_device, todo_list); | 3043 | = list_entry(list.next, struct net_device, todo_list); |
3042 | list_del(&dev->todo_list); | 3044 | list_del(&dev->todo_list); |
3043 | 3045 | ||
3044 | switch(dev->reg_state) { | 3046 | if (unlikely(dev->reg_state != NETREG_UNREGISTERING)) { |
3045 | case NETREG_REGISTERING: | 3047 | printk(KERN_ERR "network todo '%s' but state %d\n", |
3046 | dev->reg_state = NETREG_REGISTERED; | 3048 | dev->name, dev->reg_state); |
3047 | err = netdev_register_sysfs(dev); | 3049 | dump_stack(); |
3048 | if (err) | 3050 | continue; |
3049 | printk(KERN_ERR "%s: failed sysfs registration (%d)\n", | 3051 | } |
3050 | dev->name, err); | ||
3051 | break; | ||
3052 | |||
3053 | case NETREG_UNREGISTERING: | ||
3054 | netdev_unregister_sysfs(dev); | ||
3055 | dev->reg_state = NETREG_UNREGISTERED; | ||
3056 | |||
3057 | netdev_wait_allrefs(dev); | ||
3058 | 3052 | ||
3059 | /* paranoia */ | 3053 | netdev_unregister_sysfs(dev); |
3060 | BUG_ON(atomic_read(&dev->refcnt)); | 3054 | dev->reg_state = NETREG_UNREGISTERED; |
3061 | BUG_TRAP(!dev->ip_ptr); | ||
3062 | BUG_TRAP(!dev->ip6_ptr); | ||
3063 | BUG_TRAP(!dev->dn_ptr); | ||
3064 | 3055 | ||
3056 | netdev_wait_allrefs(dev); | ||
3065 | 3057 | ||
3066 | /* It must be the very last action, | 3058 | /* paranoia */ |
3067 | * after this 'dev' may point to freed up memory. | 3059 | BUG_ON(atomic_read(&dev->refcnt)); |
3068 | */ | 3060 | BUG_TRAP(!dev->ip_ptr); |
3069 | if (dev->destructor) | 3061 | BUG_TRAP(!dev->ip6_ptr); |
3070 | dev->destructor(dev); | 3062 | BUG_TRAP(!dev->dn_ptr); |
3071 | break; | ||
3072 | 3063 | ||
3073 | default: | 3064 | /* It must be the very last action, |
3074 | printk(KERN_ERR "network todo '%s' but state %d\n", | 3065 | * after this 'dev' may point to freed up memory. |
3075 | dev->name, dev->reg_state); | 3066 | */ |
3076 | break; | 3067 | if (dev->destructor) |
3077 | } | 3068 | dev->destructor(dev); |
3078 | } | 3069 | } |
3079 | 3070 | ||
3080 | out: | 3071 | out: |
@@ -3216,7 +3207,7 @@ int unregister_netdevice(struct net_device *dev) | |||
3216 | /* Notify protocols, that we are about to destroy | 3207 | /* Notify protocols, that we are about to destroy |
3217 | this device. They should clean all the things. | 3208 | this device. They should clean all the things. |
3218 | */ | 3209 | */ |
3219 | blocking_notifier_call_chain(&netdev_chain, NETDEV_UNREGISTER, dev); | 3210 | raw_notifier_call_chain(&netdev_chain, NETDEV_UNREGISTER, dev); |
3220 | 3211 | ||
3221 | /* | 3212 | /* |
3222 | * Flush the multicast chain | 3213 | * Flush the multicast chain |
diff --git a/net/core/link_watch.c b/net/core/link_watch.c index 341de44c7ed1..646937cc2d84 100644 --- a/net/core/link_watch.c +++ b/net/core/link_watch.c | |||
@@ -170,13 +170,13 @@ void linkwatch_fire_event(struct net_device *dev) | |||
170 | spin_unlock_irqrestore(&lweventlist_lock, flags); | 170 | spin_unlock_irqrestore(&lweventlist_lock, flags); |
171 | 171 | ||
172 | if (!test_and_set_bit(LW_RUNNING, &linkwatch_flags)) { | 172 | if (!test_and_set_bit(LW_RUNNING, &linkwatch_flags)) { |
173 | unsigned long thisevent = jiffies; | 173 | unsigned long delay = linkwatch_nextevent - jiffies; |
174 | 174 | ||
175 | if (thisevent >= linkwatch_nextevent) { | 175 | /* If we wrap around we'll delay it by at most HZ. */ |
176 | if (!delay || delay > HZ) | ||
176 | schedule_work(&linkwatch_work); | 177 | schedule_work(&linkwatch_work); |
177 | } else { | 178 | else |
178 | schedule_delayed_work(&linkwatch_work, linkwatch_nextevent - thisevent); | 179 | schedule_delayed_work(&linkwatch_work, delay); |
179 | } | ||
180 | } | 180 | } |
181 | } | 181 | } |
182 | } | 182 | } |
diff --git a/net/core/neighbour.c b/net/core/neighbour.c index 4cf878efdb49..50a8c73caf97 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c | |||
@@ -1326,8 +1326,7 @@ void neigh_parms_destroy(struct neigh_parms *parms) | |||
1326 | kfree(parms); | 1326 | kfree(parms); |
1327 | } | 1327 | } |
1328 | 1328 | ||
1329 | 1329 | void neigh_table_init_no_netlink(struct neigh_table *tbl) | |
1330 | void neigh_table_init(struct neigh_table *tbl) | ||
1331 | { | 1330 | { |
1332 | unsigned long now = jiffies; | 1331 | unsigned long now = jiffies; |
1333 | unsigned long phsize; | 1332 | unsigned long phsize; |
@@ -1383,10 +1382,27 @@ void neigh_table_init(struct neigh_table *tbl) | |||
1383 | 1382 | ||
1384 | tbl->last_flush = now; | 1383 | tbl->last_flush = now; |
1385 | tbl->last_rand = now + tbl->parms.reachable_time * 20; | 1384 | tbl->last_rand = now + tbl->parms.reachable_time * 20; |
1385 | } | ||
1386 | |||
1387 | void neigh_table_init(struct neigh_table *tbl) | ||
1388 | { | ||
1389 | struct neigh_table *tmp; | ||
1390 | |||
1391 | neigh_table_init_no_netlink(tbl); | ||
1386 | write_lock(&neigh_tbl_lock); | 1392 | write_lock(&neigh_tbl_lock); |
1393 | for (tmp = neigh_tables; tmp; tmp = tmp->next) { | ||
1394 | if (tmp->family == tbl->family) | ||
1395 | break; | ||
1396 | } | ||
1387 | tbl->next = neigh_tables; | 1397 | tbl->next = neigh_tables; |
1388 | neigh_tables = tbl; | 1398 | neigh_tables = tbl; |
1389 | write_unlock(&neigh_tbl_lock); | 1399 | write_unlock(&neigh_tbl_lock); |
1400 | |||
1401 | if (unlikely(tmp)) { | ||
1402 | printk(KERN_ERR "NEIGH: Registering multiple tables for " | ||
1403 | "family %d\n", tbl->family); | ||
1404 | dump_stack(); | ||
1405 | } | ||
1390 | } | 1406 | } |
1391 | 1407 | ||
1392 | int neigh_table_clear(struct neigh_table *tbl) | 1408 | int neigh_table_clear(struct neigh_table *tbl) |
@@ -2657,6 +2673,7 @@ EXPORT_SYMBOL(neigh_rand_reach_time); | |||
2657 | EXPORT_SYMBOL(neigh_resolve_output); | 2673 | EXPORT_SYMBOL(neigh_resolve_output); |
2658 | EXPORT_SYMBOL(neigh_table_clear); | 2674 | EXPORT_SYMBOL(neigh_table_clear); |
2659 | EXPORT_SYMBOL(neigh_table_init); | 2675 | EXPORT_SYMBOL(neigh_table_init); |
2676 | EXPORT_SYMBOL(neigh_table_init_no_netlink); | ||
2660 | EXPORT_SYMBOL(neigh_update); | 2677 | EXPORT_SYMBOL(neigh_update); |
2661 | EXPORT_SYMBOL(neigh_update_hhs); | 2678 | EXPORT_SYMBOL(neigh_update_hhs); |
2662 | EXPORT_SYMBOL(pneigh_enqueue); | 2679 | EXPORT_SYMBOL(pneigh_enqueue); |
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c index c12990c9c603..47a6fceb6771 100644 --- a/net/core/net-sysfs.c +++ b/net/core/net-sysfs.c | |||
@@ -29,7 +29,7 @@ static const char fmt_ulong[] = "%lu\n"; | |||
29 | 29 | ||
30 | static inline int dev_isalive(const struct net_device *dev) | 30 | static inline int dev_isalive(const struct net_device *dev) |
31 | { | 31 | { |
32 | return dev->reg_state == NETREG_REGISTERED; | 32 | return dev->reg_state <= NETREG_REGISTERED; |
33 | } | 33 | } |
34 | 34 | ||
35 | /* use same locking rules as GIF* ioctl's */ | 35 | /* use same locking rules as GIF* ioctl's */ |
@@ -445,58 +445,33 @@ static struct class net_class = { | |||
445 | 445 | ||
446 | void netdev_unregister_sysfs(struct net_device * net) | 446 | void netdev_unregister_sysfs(struct net_device * net) |
447 | { | 447 | { |
448 | struct class_device * class_dev = &(net->class_dev); | 448 | class_device_del(&(net->class_dev)); |
449 | |||
450 | if (net->get_stats) | ||
451 | sysfs_remove_group(&class_dev->kobj, &netstat_group); | ||
452 | |||
453 | #ifdef WIRELESS_EXT | ||
454 | if (net->get_wireless_stats || (net->wireless_handlers && | ||
455 | net->wireless_handlers->get_wireless_stats)) | ||
456 | sysfs_remove_group(&class_dev->kobj, &wireless_group); | ||
457 | #endif | ||
458 | class_device_del(class_dev); | ||
459 | |||
460 | } | 449 | } |
461 | 450 | ||
462 | /* Create sysfs entries for network device. */ | 451 | /* Create sysfs entries for network device. */ |
463 | int netdev_register_sysfs(struct net_device *net) | 452 | int netdev_register_sysfs(struct net_device *net) |
464 | { | 453 | { |
465 | struct class_device *class_dev = &(net->class_dev); | 454 | struct class_device *class_dev = &(net->class_dev); |
466 | int ret; | 455 | struct attribute_group **groups = net->sysfs_groups; |
467 | 456 | ||
457 | class_device_initialize(class_dev); | ||
468 | class_dev->class = &net_class; | 458 | class_dev->class = &net_class; |
469 | class_dev->class_data = net; | 459 | class_dev->class_data = net; |
460 | class_dev->groups = groups; | ||
470 | 461 | ||
462 | BUILD_BUG_ON(BUS_ID_SIZE < IFNAMSIZ); | ||
471 | strlcpy(class_dev->class_id, net->name, BUS_ID_SIZE); | 463 | strlcpy(class_dev->class_id, net->name, BUS_ID_SIZE); |
472 | if ((ret = class_device_register(class_dev))) | ||
473 | goto out; | ||
474 | 464 | ||
475 | if (net->get_stats && | 465 | if (net->get_stats) |
476 | (ret = sysfs_create_group(&class_dev->kobj, &netstat_group))) | 466 | *groups++ = &netstat_group; |
477 | goto out_unreg; | ||
478 | 467 | ||
479 | #ifdef WIRELESS_EXT | 468 | #ifdef WIRELESS_EXT |
480 | if (net->get_wireless_stats || (net->wireless_handlers && | 469 | if (net->get_wireless_stats |
481 | net->wireless_handlers->get_wireless_stats)) { | 470 | || (net->wireless_handlers && net->wireless_handlers->get_wireless_stats)) |
482 | ret = sysfs_create_group(&class_dev->kobj, &wireless_group); | 471 | *groups++ = &wireless_group; |
483 | if (ret) | ||
484 | goto out_cleanup; | ||
485 | } | ||
486 | return 0; | ||
487 | out_cleanup: | ||
488 | if (net->get_stats) | ||
489 | sysfs_remove_group(&class_dev->kobj, &netstat_group); | ||
490 | #else | ||
491 | return 0; | ||
492 | #endif | 472 | #endif |
493 | 473 | ||
494 | out_unreg: | 474 | return class_device_add(class_dev); |
495 | printk(KERN_WARNING "%s: sysfs attribute registration failed %d\n", | ||
496 | net->name, ret); | ||
497 | class_device_unregister(class_dev); | ||
498 | out: | ||
499 | return ret; | ||
500 | } | 475 | } |
501 | 476 | ||
502 | int netdev_sysfs_init(void) | 477 | int netdev_sysfs_init(void) |
diff --git a/net/dccp/proto.c b/net/dccp/proto.c index 1ff7328b0e17..2e0ee8355c41 100644 --- a/net/dccp/proto.c +++ b/net/dccp/proto.c | |||
@@ -848,6 +848,7 @@ static int dccp_close_state(struct sock *sk) | |||
848 | void dccp_close(struct sock *sk, long timeout) | 848 | void dccp_close(struct sock *sk, long timeout) |
849 | { | 849 | { |
850 | struct sk_buff *skb; | 850 | struct sk_buff *skb; |
851 | int state; | ||
851 | 852 | ||
852 | lock_sock(sk); | 853 | lock_sock(sk); |
853 | 854 | ||
@@ -882,6 +883,11 @@ void dccp_close(struct sock *sk, long timeout) | |||
882 | sk_stream_wait_close(sk, timeout); | 883 | sk_stream_wait_close(sk, timeout); |
883 | 884 | ||
884 | adjudge_to_death: | 885 | adjudge_to_death: |
886 | state = sk->sk_state; | ||
887 | sock_hold(sk); | ||
888 | sock_orphan(sk); | ||
889 | atomic_inc(sk->sk_prot->orphan_count); | ||
890 | |||
885 | /* | 891 | /* |
886 | * It is the last release_sock in its life. It will remove backlog. | 892 | * It is the last release_sock in its life. It will remove backlog. |
887 | */ | 893 | */ |
@@ -894,8 +900,9 @@ adjudge_to_death: | |||
894 | bh_lock_sock(sk); | 900 | bh_lock_sock(sk); |
895 | BUG_TRAP(!sock_owned_by_user(sk)); | 901 | BUG_TRAP(!sock_owned_by_user(sk)); |
896 | 902 | ||
897 | sock_hold(sk); | 903 | /* Have we already been destroyed by a softirq or backlog? */ |
898 | sock_orphan(sk); | 904 | if (state != DCCP_CLOSED && sk->sk_state == DCCP_CLOSED) |
905 | goto out; | ||
899 | 906 | ||
900 | /* | 907 | /* |
901 | * The last release_sock may have processed the CLOSE or RESET | 908 | * The last release_sock may have processed the CLOSE or RESET |
@@ -915,12 +922,12 @@ adjudge_to_death: | |||
915 | #endif | 922 | #endif |
916 | } | 923 | } |
917 | 924 | ||
918 | atomic_inc(sk->sk_prot->orphan_count); | ||
919 | if (sk->sk_state == DCCP_CLOSED) | 925 | if (sk->sk_state == DCCP_CLOSED) |
920 | inet_csk_destroy_sock(sk); | 926 | inet_csk_destroy_sock(sk); |
921 | 927 | ||
922 | /* Otherwise, socket is reprieved until protocol close. */ | 928 | /* Otherwise, socket is reprieved until protocol close. */ |
923 | 929 | ||
930 | out: | ||
924 | bh_unlock_sock(sk); | 931 | bh_unlock_sock(sk); |
925 | local_bh_enable(); | 932 | local_bh_enable(); |
926 | sock_put(sk); | 933 | sock_put(sk); |
diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c index 18d7fad474d7..c9026dbf4c93 100644 --- a/net/ipv4/ip_input.c +++ b/net/ipv4/ip_input.c | |||
@@ -337,7 +337,7 @@ static inline int ip_rcv_finish(struct sk_buff *skb) | |||
337 | * Initialise the virtual path cache for the packet. It describes | 337 | * Initialise the virtual path cache for the packet. It describes |
338 | * how the packet travels inside Linux networking. | 338 | * how the packet travels inside Linux networking. |
339 | */ | 339 | */ |
340 | if (likely(skb->dst == NULL)) { | 340 | if (skb->dst == NULL) { |
341 | int err = ip_route_input(skb, iph->daddr, iph->saddr, iph->tos, | 341 | int err = ip_route_input(skb, iph->daddr, iph->saddr, iph->tos, |
342 | skb->dev); | 342 | skb->dev); |
343 | if (unlikely(err)) { | 343 | if (unlikely(err)) { |
diff --git a/net/ipv4/ip_options.c b/net/ipv4/ip_options.c index 9bebad07bf2e..cbcae6544622 100644 --- a/net/ipv4/ip_options.c +++ b/net/ipv4/ip_options.c | |||
@@ -209,7 +209,7 @@ int ip_options_echo(struct ip_options * dopt, struct sk_buff * skb) | |||
209 | 209 | ||
210 | void ip_options_fragment(struct sk_buff * skb) | 210 | void ip_options_fragment(struct sk_buff * skb) |
211 | { | 211 | { |
212 | unsigned char * optptr = skb->nh.raw; | 212 | unsigned char * optptr = skb->nh.raw + sizeof(struct iphdr); |
213 | struct ip_options * opt = &(IPCB(skb)->opt); | 213 | struct ip_options * opt = &(IPCB(skb)->opt); |
214 | int l = opt->optlen; | 214 | int l = opt->optlen; |
215 | int optlen; | 215 | int optlen; |
diff --git a/net/ipv4/tcp_highspeed.c b/net/ipv4/tcp_highspeed.c index e0e9d1383c7c..b72fa55dfb84 100644 --- a/net/ipv4/tcp_highspeed.c +++ b/net/ipv4/tcp_highspeed.c | |||
@@ -137,8 +137,8 @@ static void hstcp_cong_avoid(struct sock *sk, u32 adk, u32 rtt, | |||
137 | if (tp->snd_cwnd < tp->snd_cwnd_clamp) { | 137 | if (tp->snd_cwnd < tp->snd_cwnd_clamp) { |
138 | tp->snd_cwnd_cnt += ca->ai; | 138 | tp->snd_cwnd_cnt += ca->ai; |
139 | if (tp->snd_cwnd_cnt >= tp->snd_cwnd) { | 139 | if (tp->snd_cwnd_cnt >= tp->snd_cwnd) { |
140 | tp->snd_cwnd++; | ||
141 | tp->snd_cwnd_cnt -= tp->snd_cwnd; | 140 | tp->snd_cwnd_cnt -= tp->snd_cwnd; |
141 | tp->snd_cwnd++; | ||
142 | } | 142 | } |
143 | } | 143 | } |
144 | } | 144 | } |
diff --git a/net/ipv6/inet6_connection_sock.c b/net/ipv6/inet6_connection_sock.c index f8f3a37a1494..eb2865d5ae28 100644 --- a/net/ipv6/inet6_connection_sock.c +++ b/net/ipv6/inet6_connection_sock.c | |||
@@ -173,6 +173,7 @@ int inet6_csk_xmit(struct sk_buff *skb, int ipfragok) | |||
173 | 173 | ||
174 | if (err) { | 174 | if (err) { |
175 | sk->sk_err_soft = -err; | 175 | sk->sk_err_soft = -err; |
176 | kfree_skb(skb); | ||
176 | return err; | 177 | return err; |
177 | } | 178 | } |
178 | 179 | ||
@@ -181,6 +182,7 @@ int inet6_csk_xmit(struct sk_buff *skb, int ipfragok) | |||
181 | 182 | ||
182 | if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) { | 183 | if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) { |
183 | sk->sk_route_caps = 0; | 184 | sk->sk_route_caps = 0; |
185 | kfree_skb(skb); | ||
184 | return err; | 186 | return err; |
185 | } | 187 | } |
186 | 188 | ||
diff --git a/net/irda/irias_object.c b/net/irda/irias_object.c index c6d169fbdceb..82e665c79991 100644 --- a/net/irda/irias_object.c +++ b/net/irda/irias_object.c | |||
@@ -257,7 +257,6 @@ struct ias_attrib *irias_find_attrib(struct ias_object *obj, char *name) | |||
257 | /* Unsafe (locking), attrib might change */ | 257 | /* Unsafe (locking), attrib might change */ |
258 | return attrib; | 258 | return attrib; |
259 | } | 259 | } |
260 | EXPORT_SYMBOL(irias_find_attrib); | ||
261 | 260 | ||
262 | /* | 261 | /* |
263 | * Function irias_add_attribute (obj, attrib) | 262 | * Function irias_add_attribute (obj, attrib) |
@@ -484,7 +483,6 @@ struct ias_value *irias_new_string_value(char *string) | |||
484 | 483 | ||
485 | return value; | 484 | return value; |
486 | } | 485 | } |
487 | EXPORT_SYMBOL(irias_new_string_value); | ||
488 | 486 | ||
489 | /* | 487 | /* |
490 | * Function irias_new_octseq_value (octets, len) | 488 | * Function irias_new_octseq_value (octets, len) |
@@ -519,7 +517,6 @@ struct ias_value *irias_new_octseq_value(__u8 *octseq , int len) | |||
519 | memcpy(value->t.oct_seq, octseq , len); | 517 | memcpy(value->t.oct_seq, octseq , len); |
520 | return value; | 518 | return value; |
521 | } | 519 | } |
522 | EXPORT_SYMBOL(irias_new_octseq_value); | ||
523 | 520 | ||
524 | struct ias_value *irias_new_missing_value(void) | 521 | struct ias_value *irias_new_missing_value(void) |
525 | { | 522 | { |
diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c index ecd288beca7c..3669cb953e6e 100644 --- a/net/netrom/af_netrom.c +++ b/net/netrom/af_netrom.c | |||
@@ -1370,8 +1370,6 @@ static struct notifier_block nr_dev_notifier = { | |||
1370 | 1370 | ||
1371 | static struct net_device **dev_nr; | 1371 | static struct net_device **dev_nr; |
1372 | 1372 | ||
1373 | static char banner[] __initdata = KERN_INFO "G4KLX NET/ROM for Linux. Version 0.7 for AX25.037 Linux 2.4\n"; | ||
1374 | |||
1375 | static int __init nr_proto_init(void) | 1373 | static int __init nr_proto_init(void) |
1376 | { | 1374 | { |
1377 | int i; | 1375 | int i; |
@@ -1419,7 +1417,6 @@ static int __init nr_proto_init(void) | |||
1419 | } | 1417 | } |
1420 | 1418 | ||
1421 | register_netdevice_notifier(&nr_dev_notifier); | 1419 | register_netdevice_notifier(&nr_dev_notifier); |
1422 | printk(banner); | ||
1423 | 1420 | ||
1424 | ax25_protocol_register(AX25_P_NETROM, nr_route_frame); | 1421 | ax25_protocol_register(AX25_P_NETROM, nr_route_frame); |
1425 | ax25_linkfail_register(nr_link_failed); | 1422 | ax25_linkfail_register(nr_link_failed); |
diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c index ef4538ac84f0..55564efccf11 100644 --- a/net/rose/af_rose.c +++ b/net/rose/af_rose.c | |||
@@ -1469,8 +1469,6 @@ static struct notifier_block rose_dev_notifier = { | |||
1469 | 1469 | ||
1470 | static struct net_device **dev_rose; | 1470 | static struct net_device **dev_rose; |
1471 | 1471 | ||
1472 | static const char banner[] = KERN_INFO "F6FBB/G4KLX ROSE for Linux. Version 0.62 for AX25.037 Linux 2.4\n"; | ||
1473 | |||
1474 | static int __init rose_proto_init(void) | 1472 | static int __init rose_proto_init(void) |
1475 | { | 1473 | { |
1476 | int i; | 1474 | int i; |
@@ -1519,7 +1517,6 @@ static int __init rose_proto_init(void) | |||
1519 | 1517 | ||
1520 | sock_register(&rose_family_ops); | 1518 | sock_register(&rose_family_ops); |
1521 | register_netdevice_notifier(&rose_dev_notifier); | 1519 | register_netdevice_notifier(&rose_dev_notifier); |
1522 | printk(banner); | ||
1523 | 1520 | ||
1524 | ax25_protocol_register(AX25_P_ROSE, rose_route_frame); | 1521 | ax25_protocol_register(AX25_P_ROSE, rose_route_frame); |
1525 | ax25_linkfail_register(rose_link_failed); | 1522 | ax25_linkfail_register(rose_link_failed); |
diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c index 91132f6871d7..f1c7bd29f2cd 100644 --- a/net/sched/sch_hfsc.c +++ b/net/sched/sch_hfsc.c | |||
@@ -974,10 +974,10 @@ hfsc_adjust_levels(struct hfsc_class *cl) | |||
974 | do { | 974 | do { |
975 | level = 0; | 975 | level = 0; |
976 | list_for_each_entry(p, &cl->children, siblings) { | 976 | list_for_each_entry(p, &cl->children, siblings) { |
977 | if (p->level > level) | 977 | if (p->level >= level) |
978 | level = p->level; | 978 | level = p->level + 1; |
979 | } | 979 | } |
980 | cl->level = level + 1; | 980 | cl->level = level; |
981 | } while ((cl = cl->cl_parent) != NULL); | 981 | } while ((cl = cl->cl_parent) != NULL); |
982 | } | 982 | } |
983 | 983 | ||
diff --git a/net/sctp/inqueue.c b/net/sctp/inqueue.c index 297b8951463e..cf0c767d43ae 100644 --- a/net/sctp/inqueue.c +++ b/net/sctp/inqueue.c | |||
@@ -149,6 +149,7 @@ struct sctp_chunk *sctp_inq_pop(struct sctp_inq *queue) | |||
149 | /* This is the first chunk in the packet. */ | 149 | /* This is the first chunk in the packet. */ |
150 | chunk->singleton = 1; | 150 | chunk->singleton = 1; |
151 | ch = (sctp_chunkhdr_t *) chunk->skb->data; | 151 | ch = (sctp_chunkhdr_t *) chunk->skb->data; |
152 | chunk->data_accepted = 0; | ||
152 | } | 153 | } |
153 | 154 | ||
154 | chunk->chunk_hdr = ch; | 155 | chunk->chunk_hdr = ch; |
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index 2b9a832b29a7..8cdba51ec076 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c | |||
@@ -636,8 +636,9 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(const struct sctp_endpoint *ep, | |||
636 | */ | 636 | */ |
637 | chunk->subh.cookie_hdr = | 637 | chunk->subh.cookie_hdr = |
638 | (struct sctp_signed_cookie *)chunk->skb->data; | 638 | (struct sctp_signed_cookie *)chunk->skb->data; |
639 | skb_pull(chunk->skb, | 639 | if (!pskb_pull(chunk->skb, ntohs(chunk->chunk_hdr->length) - |
640 | ntohs(chunk->chunk_hdr->length) - sizeof(sctp_chunkhdr_t)); | 640 | sizeof(sctp_chunkhdr_t))) |
641 | goto nomem; | ||
641 | 642 | ||
642 | /* 5.1 D) Upon reception of the COOKIE ECHO chunk, Endpoint | 643 | /* 5.1 D) Upon reception of the COOKIE ECHO chunk, Endpoint |
643 | * "Z" will reply with a COOKIE ACK chunk after building a TCB | 644 | * "Z" will reply with a COOKIE ACK chunk after building a TCB |
@@ -965,7 +966,8 @@ sctp_disposition_t sctp_sf_beat_8_3(const struct sctp_endpoint *ep, | |||
965 | */ | 966 | */ |
966 | chunk->subh.hb_hdr = (sctp_heartbeathdr_t *) chunk->skb->data; | 967 | chunk->subh.hb_hdr = (sctp_heartbeathdr_t *) chunk->skb->data; |
967 | paylen = ntohs(chunk->chunk_hdr->length) - sizeof(sctp_chunkhdr_t); | 968 | paylen = ntohs(chunk->chunk_hdr->length) - sizeof(sctp_chunkhdr_t); |
968 | skb_pull(chunk->skb, paylen); | 969 | if (!pskb_pull(chunk->skb, paylen)) |
970 | goto nomem; | ||
969 | 971 | ||
970 | reply = sctp_make_heartbeat_ack(asoc, chunk, | 972 | reply = sctp_make_heartbeat_ack(asoc, chunk, |
971 | chunk->subh.hb_hdr, paylen); | 973 | chunk->subh.hb_hdr, paylen); |
@@ -1860,8 +1862,9 @@ sctp_disposition_t sctp_sf_do_5_2_4_dupcook(const struct sctp_endpoint *ep, | |||
1860 | * are in good shape. | 1862 | * are in good shape. |
1861 | */ | 1863 | */ |
1862 | chunk->subh.cookie_hdr = (struct sctp_signed_cookie *)chunk->skb->data; | 1864 | chunk->subh.cookie_hdr = (struct sctp_signed_cookie *)chunk->skb->data; |
1863 | skb_pull(chunk->skb, ntohs(chunk->chunk_hdr->length) - | 1865 | if (!pskb_pull(chunk->skb, ntohs(chunk->chunk_hdr->length) - |
1864 | sizeof(sctp_chunkhdr_t)); | 1866 | sizeof(sctp_chunkhdr_t))) |
1867 | goto nomem; | ||
1865 | 1868 | ||
1866 | /* In RFC 2960 5.2.4 3, if both Verification Tags in the State Cookie | 1869 | /* In RFC 2960 5.2.4 3, if both Verification Tags in the State Cookie |
1867 | * of a duplicate COOKIE ECHO match the Verification Tags of the | 1870 | * of a duplicate COOKIE ECHO match the Verification Tags of the |
@@ -5151,7 +5154,9 @@ static int sctp_eat_data(const struct sctp_association *asoc, | |||
5151 | int tmp; | 5154 | int tmp; |
5152 | __u32 tsn; | 5155 | __u32 tsn; |
5153 | int account_value; | 5156 | int account_value; |
5157 | struct sctp_tsnmap *map = (struct sctp_tsnmap *)&asoc->peer.tsn_map; | ||
5154 | struct sock *sk = asoc->base.sk; | 5158 | struct sock *sk = asoc->base.sk; |
5159 | int rcvbuf_over = 0; | ||
5155 | 5160 | ||
5156 | data_hdr = chunk->subh.data_hdr = (sctp_datahdr_t *)chunk->skb->data; | 5161 | data_hdr = chunk->subh.data_hdr = (sctp_datahdr_t *)chunk->skb->data; |
5157 | skb_pull(chunk->skb, sizeof(sctp_datahdr_t)); | 5162 | skb_pull(chunk->skb, sizeof(sctp_datahdr_t)); |
@@ -5162,10 +5167,16 @@ static int sctp_eat_data(const struct sctp_association *asoc, | |||
5162 | /* ASSERT: Now skb->data is really the user data. */ | 5167 | /* ASSERT: Now skb->data is really the user data. */ |
5163 | 5168 | ||
5164 | /* | 5169 | /* |
5165 | * if we are established, and we have used up our receive | 5170 | * If we are established, and we have used up our receive buffer |
5166 | * buffer memory, drop the frame | 5171 | * memory, think about droping the frame. |
5167 | */ | 5172 | * Note that we have an opportunity to improve performance here. |
5168 | if (asoc->state == SCTP_STATE_ESTABLISHED) { | 5173 | * If we accept one chunk from an skbuff, we have to keep all the |
5174 | * memory of that skbuff around until the chunk is read into user | ||
5175 | * space. Therefore, once we accept 1 chunk we may as well accept all | ||
5176 | * remaining chunks in the skbuff. The data_accepted flag helps us do | ||
5177 | * that. | ||
5178 | */ | ||
5179 | if ((asoc->state == SCTP_STATE_ESTABLISHED) && (!chunk->data_accepted)) { | ||
5169 | /* | 5180 | /* |
5170 | * If the receive buffer policy is 1, then each | 5181 | * If the receive buffer policy is 1, then each |
5171 | * association can allocate up to sk_rcvbuf bytes | 5182 | * association can allocate up to sk_rcvbuf bytes |
@@ -5176,9 +5187,25 @@ static int sctp_eat_data(const struct sctp_association *asoc, | |||
5176 | account_value = atomic_read(&asoc->rmem_alloc); | 5187 | account_value = atomic_read(&asoc->rmem_alloc); |
5177 | else | 5188 | else |
5178 | account_value = atomic_read(&sk->sk_rmem_alloc); | 5189 | account_value = atomic_read(&sk->sk_rmem_alloc); |
5179 | 5190 | if (account_value > sk->sk_rcvbuf) { | |
5180 | if (account_value > sk->sk_rcvbuf) | 5191 | /* |
5181 | return SCTP_IERROR_IGNORE_TSN; | 5192 | * We need to make forward progress, even when we are |
5193 | * under memory pressure, so we always allow the | ||
5194 | * next tsn after the ctsn ack point to be accepted. | ||
5195 | * This lets us avoid deadlocks in which we have to | ||
5196 | * drop frames that would otherwise let us drain the | ||
5197 | * receive queue. | ||
5198 | */ | ||
5199 | if ((sctp_tsnmap_get_ctsn(map) + 1) != tsn) | ||
5200 | return SCTP_IERROR_IGNORE_TSN; | ||
5201 | |||
5202 | /* | ||
5203 | * We're going to accept the frame but we should renege | ||
5204 | * to make space for it. This will send us down that | ||
5205 | * path later in this function. | ||
5206 | */ | ||
5207 | rcvbuf_over = 1; | ||
5208 | } | ||
5182 | } | 5209 | } |
5183 | 5210 | ||
5184 | /* Process ECN based congestion. | 5211 | /* Process ECN based congestion. |
@@ -5226,6 +5253,7 @@ static int sctp_eat_data(const struct sctp_association *asoc, | |||
5226 | datalen -= sizeof(sctp_data_chunk_t); | 5253 | datalen -= sizeof(sctp_data_chunk_t); |
5227 | 5254 | ||
5228 | deliver = SCTP_CMD_CHUNK_ULP; | 5255 | deliver = SCTP_CMD_CHUNK_ULP; |
5256 | chunk->data_accepted = 1; | ||
5229 | 5257 | ||
5230 | /* Think about partial delivery. */ | 5258 | /* Think about partial delivery. */ |
5231 | if ((datalen >= asoc->rwnd) && (!asoc->ulpq.pd_mode)) { | 5259 | if ((datalen >= asoc->rwnd) && (!asoc->ulpq.pd_mode)) { |
@@ -5242,7 +5270,8 @@ static int sctp_eat_data(const struct sctp_association *asoc, | |||
5242 | * large spill over. | 5270 | * large spill over. |
5243 | */ | 5271 | */ |
5244 | if (!asoc->rwnd || asoc->rwnd_over || | 5272 | if (!asoc->rwnd || asoc->rwnd_over || |
5245 | (datalen > asoc->rwnd + asoc->frag_point)) { | 5273 | (datalen > asoc->rwnd + asoc->frag_point) || |
5274 | rcvbuf_over) { | ||
5246 | 5275 | ||
5247 | /* If this is the next TSN, consider reneging to make | 5276 | /* If this is the next TSN, consider reneging to make |
5248 | * room. Note: Playing nice with a confused sender. A | 5277 | * room. Note: Playing nice with a confused sender. A |
@@ -5250,8 +5279,8 @@ static int sctp_eat_data(const struct sctp_association *asoc, | |||
5250 | * space and in the future we may want to detect and | 5279 | * space and in the future we may want to detect and |
5251 | * do more drastic reneging. | 5280 | * do more drastic reneging. |
5252 | */ | 5281 | */ |
5253 | if (sctp_tsnmap_has_gap(&asoc->peer.tsn_map) && | 5282 | if (sctp_tsnmap_has_gap(map) && |
5254 | (sctp_tsnmap_get_ctsn(&asoc->peer.tsn_map) + 1) == tsn) { | 5283 | (sctp_tsnmap_get_ctsn(map) + 1) == tsn) { |
5255 | SCTP_DEBUG_PRINTK("Reneging for tsn:%u\n", tsn); | 5284 | SCTP_DEBUG_PRINTK("Reneging for tsn:%u\n", tsn); |
5256 | deliver = SCTP_CMD_RENEGE; | 5285 | deliver = SCTP_CMD_RENEGE; |
5257 | } else { | 5286 | } else { |
diff --git a/net/sctp/sm_statetable.c b/net/sctp/sm_statetable.c index 75ef10408764..8bcca5676151 100644 --- a/net/sctp/sm_statetable.c +++ b/net/sctp/sm_statetable.c | |||
@@ -366,9 +366,9 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type, | |||
366 | /* SCTP_STATE_EMPTY */ \ | 366 | /* SCTP_STATE_EMPTY */ \ |
367 | {.fn = sctp_sf_ootb, .name = "sctp_sf_ootb"}, \ | 367 | {.fn = sctp_sf_ootb, .name = "sctp_sf_ootb"}, \ |
368 | /* SCTP_STATE_CLOSED */ \ | 368 | /* SCTP_STATE_CLOSED */ \ |
369 | {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ | 369 | {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ |
370 | /* SCTP_STATE_COOKIE_WAIT */ \ | 370 | /* SCTP_STATE_COOKIE_WAIT */ \ |
371 | {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ | 371 | {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ |
372 | /* SCTP_STATE_COOKIE_ECHOED */ \ | 372 | /* SCTP_STATE_COOKIE_ECHOED */ \ |
373 | {.fn = sctp_sf_do_ecne, .name = "sctp_sf_do_ecne"}, \ | 373 | {.fn = sctp_sf_do_ecne, .name = "sctp_sf_do_ecne"}, \ |
374 | /* SCTP_STATE_ESTABLISHED */ \ | 374 | /* SCTP_STATE_ESTABLISHED */ \ |
@@ -380,7 +380,7 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type, | |||
380 | /* SCTP_STATE_SHUTDOWN_RECEIVED */ \ | 380 | /* SCTP_STATE_SHUTDOWN_RECEIVED */ \ |
381 | {.fn = sctp_sf_do_ecne, .name = "sctp_sf_do_ecne"}, \ | 381 | {.fn = sctp_sf_do_ecne, .name = "sctp_sf_do_ecne"}, \ |
382 | /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ | 382 | /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ |
383 | {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ | 383 | {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ |
384 | } /* TYPE_SCTP_ECN_ECNE */ | 384 | } /* TYPE_SCTP_ECN_ECNE */ |
385 | 385 | ||
386 | #define TYPE_SCTP_ECN_CWR { \ | 386 | #define TYPE_SCTP_ECN_CWR { \ |
@@ -401,7 +401,7 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type, | |||
401 | /* SCTP_STATE_SHUTDOWN_RECEIVED */ \ | 401 | /* SCTP_STATE_SHUTDOWN_RECEIVED */ \ |
402 | {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ | 402 | {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ |
403 | /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ | 403 | /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ |
404 | {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ | 404 | {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ |
405 | } /* TYPE_SCTP_ECN_CWR */ | 405 | } /* TYPE_SCTP_ECN_CWR */ |
406 | 406 | ||
407 | #define TYPE_SCTP_SHUTDOWN_COMPLETE { \ | 407 | #define TYPE_SCTP_SHUTDOWN_COMPLETE { \ |
@@ -647,7 +647,7 @@ chunk_event_table_unknown[SCTP_STATE_NUM_STATES] = { | |||
647 | /* SCTP_STATE_EMPTY */ \ | 647 | /* SCTP_STATE_EMPTY */ \ |
648 | {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ | 648 | {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ |
649 | /* SCTP_STATE_CLOSED */ \ | 649 | /* SCTP_STATE_CLOSED */ \ |
650 | {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ | 650 | {.fn = sctp_sf_error_closed, .name = "sctp_sf_error_closed"}, \ |
651 | /* SCTP_STATE_COOKIE_WAIT */ \ | 651 | /* SCTP_STATE_COOKIE_WAIT */ \ |
652 | {.fn = sctp_sf_do_prm_requestheartbeat, \ | 652 | {.fn = sctp_sf_do_prm_requestheartbeat, \ |
653 | .name = "sctp_sf_do_prm_requestheartbeat"}, \ | 653 | .name = "sctp_sf_do_prm_requestheartbeat"}, \ |
diff --git a/net/sctp/ulpqueue.c b/net/sctp/ulpqueue.c index 2080b2d28c98..575e556aeb3e 100644 --- a/net/sctp/ulpqueue.c +++ b/net/sctp/ulpqueue.c | |||
@@ -279,6 +279,7 @@ static inline void sctp_ulpq_store_reasm(struct sctp_ulpq *ulpq, | |||
279 | static struct sctp_ulpevent *sctp_make_reassembled_event(struct sk_buff_head *queue, struct sk_buff *f_frag, struct sk_buff *l_frag) | 279 | static struct sctp_ulpevent *sctp_make_reassembled_event(struct sk_buff_head *queue, struct sk_buff *f_frag, struct sk_buff *l_frag) |
280 | { | 280 | { |
281 | struct sk_buff *pos; | 281 | struct sk_buff *pos; |
282 | struct sk_buff *new = NULL; | ||
282 | struct sctp_ulpevent *event; | 283 | struct sctp_ulpevent *event; |
283 | struct sk_buff *pnext, *last; | 284 | struct sk_buff *pnext, *last; |
284 | struct sk_buff *list = skb_shinfo(f_frag)->frag_list; | 285 | struct sk_buff *list = skb_shinfo(f_frag)->frag_list; |
@@ -297,11 +298,33 @@ static struct sctp_ulpevent *sctp_make_reassembled_event(struct sk_buff_head *qu | |||
297 | */ | 298 | */ |
298 | if (last) | 299 | if (last) |
299 | last->next = pos; | 300 | last->next = pos; |
300 | else | 301 | else { |
301 | skb_shinfo(f_frag)->frag_list = pos; | 302 | if (skb_cloned(f_frag)) { |
303 | /* This is a cloned skb, we can't just modify | ||
304 | * the frag_list. We need a new skb to do that. | ||
305 | * Instead of calling skb_unshare(), we'll do it | ||
306 | * ourselves since we need to delay the free. | ||
307 | */ | ||
308 | new = skb_copy(f_frag, GFP_ATOMIC); | ||
309 | if (!new) | ||
310 | return NULL; /* try again later */ | ||
311 | |||
312 | new->sk = f_frag->sk; | ||
313 | |||
314 | skb_shinfo(new)->frag_list = pos; | ||
315 | } else | ||
316 | skb_shinfo(f_frag)->frag_list = pos; | ||
317 | } | ||
302 | 318 | ||
303 | /* Remove the first fragment from the reassembly queue. */ | 319 | /* Remove the first fragment from the reassembly queue. */ |
304 | __skb_unlink(f_frag, queue); | 320 | __skb_unlink(f_frag, queue); |
321 | |||
322 | /* if we did unshare, then free the old skb and re-assign */ | ||
323 | if (new) { | ||
324 | kfree_skb(f_frag); | ||
325 | f_frag = new; | ||
326 | } | ||
327 | |||
305 | while (pos) { | 328 | while (pos) { |
306 | 329 | ||
307 | pnext = pos->next; | 330 | pnext = pos->next; |