aboutsummaryrefslogtreecommitdiffstats
path: root/net/core
diff options
context:
space:
mode:
authorJody McIntyre <scjody@modernduck.com>2006-01-05 08:03:40 -0500
committerJody McIntyre <scjody@modernduck.com>2006-01-05 08:03:40 -0500
commit0a75c23a009ff65f651532cecc16675d05f4de37 (patch)
treebdcd6158758fe1810f0ddddb80d2816779518688 /net/core
parent34b8c399dc04c8e51f014b73458e654570698597 (diff)
parentdb9edfd7e339ca4113153d887e782dd05be5a9eb (diff)
Merge with http://kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
Diffstat (limited to 'net/core')
-rw-r--r--net/core/datagram.c36
-rw-r--r--net/core/dev.c4
-rw-r--r--net/core/filter.c112
-rw-r--r--net/core/flow.c8
-rw-r--r--net/core/net-sysfs.c76
-rw-r--r--net/core/netpoll.c1
-rw-r--r--net/core/pktgen.c6
-rw-r--r--net/core/skbuff.c27
-rw-r--r--net/core/sock.c21
-rw-r--r--net/core/stream.c10
-rw-r--r--net/core/utils.c2
11 files changed, 185 insertions, 118 deletions
diff --git a/net/core/datagram.c b/net/core/datagram.c
index 1bcfef51ac..f8d322e1ea 100644
--- a/net/core/datagram.c
+++ b/net/core/datagram.c
@@ -47,6 +47,7 @@
47#include <linux/rtnetlink.h> 47#include <linux/rtnetlink.h>
48#include <linux/poll.h> 48#include <linux/poll.h>
49#include <linux/highmem.h> 49#include <linux/highmem.h>
50#include <linux/spinlock.h>
50 51
51#include <net/protocol.h> 52#include <net/protocol.h>
52#include <linux/skbuff.h> 53#include <linux/skbuff.h>
@@ -200,6 +201,41 @@ void skb_free_datagram(struct sock *sk, struct sk_buff *skb)
200} 201}
201 202
202/** 203/**
204 * skb_kill_datagram - Free a datagram skbuff forcibly
205 * @sk: socket
206 * @skb: datagram skbuff
207 * @flags: MSG_ flags
208 *
209 * This function frees a datagram skbuff that was received by
210 * skb_recv_datagram. The flags argument must match the one
211 * used for skb_recv_datagram.
212 *
213 * If the MSG_PEEK flag is set, and the packet is still on the
214 * receive queue of the socket, it will be taken off the queue
215 * before it is freed.
216 *
217 * This function currently only disables BH when acquiring the
218 * sk_receive_queue lock. Therefore it must not be used in a
219 * context where that lock is acquired in an IRQ context.
220 */
221
222void skb_kill_datagram(struct sock *sk, struct sk_buff *skb, unsigned int flags)
223{
224 if (flags & MSG_PEEK) {
225 spin_lock_bh(&sk->sk_receive_queue.lock);
226 if (skb == skb_peek(&sk->sk_receive_queue)) {
227 __skb_unlink(skb, &sk->sk_receive_queue);
228 atomic_dec(&skb->users);
229 }
230 spin_unlock_bh(&sk->sk_receive_queue.lock);
231 }
232
233 kfree_skb(skb);
234}
235
236EXPORT_SYMBOL(skb_kill_datagram);
237
238/**
203 * skb_copy_datagram_iovec - Copy a datagram to an iovec. 239 * skb_copy_datagram_iovec - Copy a datagram to an iovec.
204 * @skb: buffer to copy 240 * @skb: buffer to copy
205 * @offset: offset in the buffer to start copying from 241 * @offset: offset in the buffer to start copying from
diff --git a/net/core/dev.c b/net/core/dev.c
index a5efc9ae01..5081287923 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -626,7 +626,7 @@ struct net_device * dev_get_by_flags(unsigned short if_flags, unsigned short mas
626 * Network device names need to be valid file names to 626 * Network device names need to be valid file names to
627 * to allow sysfs to work 627 * to allow sysfs to work
628 */ 628 */
629static int dev_valid_name(const char *name) 629int dev_valid_name(const char *name)
630{ 630{
631 return !(*name == '\0' 631 return !(*name == '\0'
632 || !strcmp(name, ".") 632 || !strcmp(name, ".")
@@ -3270,13 +3270,13 @@ EXPORT_SYMBOL(__dev_get_by_index);
3270EXPORT_SYMBOL(__dev_get_by_name); 3270EXPORT_SYMBOL(__dev_get_by_name);
3271EXPORT_SYMBOL(__dev_remove_pack); 3271EXPORT_SYMBOL(__dev_remove_pack);
3272EXPORT_SYMBOL(__skb_linearize); 3272EXPORT_SYMBOL(__skb_linearize);
3273EXPORT_SYMBOL(dev_valid_name);
3273EXPORT_SYMBOL(dev_add_pack); 3274EXPORT_SYMBOL(dev_add_pack);
3274EXPORT_SYMBOL(dev_alloc_name); 3275EXPORT_SYMBOL(dev_alloc_name);
3275EXPORT_SYMBOL(dev_close); 3276EXPORT_SYMBOL(dev_close);
3276EXPORT_SYMBOL(dev_get_by_flags); 3277EXPORT_SYMBOL(dev_get_by_flags);
3277EXPORT_SYMBOL(dev_get_by_index); 3278EXPORT_SYMBOL(dev_get_by_index);
3278EXPORT_SYMBOL(dev_get_by_name); 3279EXPORT_SYMBOL(dev_get_by_name);
3279EXPORT_SYMBOL(dev_ioctl);
3280EXPORT_SYMBOL(dev_open); 3280EXPORT_SYMBOL(dev_open);
3281EXPORT_SYMBOL(dev_queue_xmit); 3281EXPORT_SYMBOL(dev_queue_xmit);
3282EXPORT_SYMBOL(dev_remove_pack); 3282EXPORT_SYMBOL(dev_remove_pack);
diff --git a/net/core/filter.c b/net/core/filter.c
index 3a10e0bc90..8964d34455 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -13,6 +13,7 @@
13 * 2 of the License, or (at your option) any later version. 13 * 2 of the License, or (at your option) any later version.
14 * 14 *
15 * Andi Kleen - Fix a few bad bugs and races. 15 * Andi Kleen - Fix a few bad bugs and races.
16 * Kris Katterjohn - Added many additional checks in sk_chk_filter()
16 */ 17 */
17 18
18#include <linux/module.h> 19#include <linux/module.h>
@@ -250,7 +251,7 @@ load_b:
250 mem[fentry->k] = X; 251 mem[fentry->k] = X;
251 continue; 252 continue;
252 default: 253 default:
253 /* Invalid instruction counts as RET */ 254 WARN_ON(1);
254 return 0; 255 return 0;
255 } 256 }
256 257
@@ -283,8 +284,8 @@ load_b:
283 * 284 *
284 * Check the user's filter code. If we let some ugly 285 * Check the user's filter code. If we let some ugly
285 * filter code slip through kaboom! The filter must contain 286 * filter code slip through kaboom! The filter must contain
286 * no references or jumps that are out of range, no illegal instructions 287 * no references or jumps that are out of range, no illegal
287 * and no backward jumps. It must end with a RET instruction 288 * instructions, and must end with a RET instruction.
288 * 289 *
289 * Returns 0 if the rule set is legal or a negative errno code if not. 290 * Returns 0 if the rule set is legal or a negative errno code if not.
290 */ 291 */
@@ -300,38 +301,85 @@ int sk_chk_filter(struct sock_filter *filter, int flen)
300 for (pc = 0; pc < flen; pc++) { 301 for (pc = 0; pc < flen; pc++) {
301 /* all jumps are forward as they are not signed */ 302 /* all jumps are forward as they are not signed */
302 ftest = &filter[pc]; 303 ftest = &filter[pc];
303 if (BPF_CLASS(ftest->code) == BPF_JMP) {
304 /* but they mustn't jump off the end */
305 if (BPF_OP(ftest->code) == BPF_JA) {
306 /*
307 * Note, the large ftest->k might cause loops.
308 * Compare this with conditional jumps below,
309 * where offsets are limited. --ANK (981016)
310 */
311 if (ftest->k >= (unsigned)(flen-pc-1))
312 return -EINVAL;
313 } else {
314 /* for conditionals both must be safe */
315 if (pc + ftest->jt +1 >= flen ||
316 pc + ftest->jf +1 >= flen)
317 return -EINVAL;
318 }
319 }
320 304
321 /* check for division by zero -Kris Katterjohn 2005-10-30 */ 305 /* Only allow valid instructions */
322 if (ftest->code == (BPF_ALU|BPF_DIV|BPF_K) && ftest->k == 0) 306 switch (ftest->code) {
323 return -EINVAL; 307 case BPF_ALU|BPF_ADD|BPF_K:
308 case BPF_ALU|BPF_ADD|BPF_X:
309 case BPF_ALU|BPF_SUB|BPF_K:
310 case BPF_ALU|BPF_SUB|BPF_X:
311 case BPF_ALU|BPF_MUL|BPF_K:
312 case BPF_ALU|BPF_MUL|BPF_X:
313 case BPF_ALU|BPF_DIV|BPF_X:
314 case BPF_ALU|BPF_AND|BPF_K:
315 case BPF_ALU|BPF_AND|BPF_X:
316 case BPF_ALU|BPF_OR|BPF_K:
317 case BPF_ALU|BPF_OR|BPF_X:
318 case BPF_ALU|BPF_LSH|BPF_K:
319 case BPF_ALU|BPF_LSH|BPF_X:
320 case BPF_ALU|BPF_RSH|BPF_K:
321 case BPF_ALU|BPF_RSH|BPF_X:
322 case BPF_ALU|BPF_NEG:
323 case BPF_LD|BPF_W|BPF_ABS:
324 case BPF_LD|BPF_H|BPF_ABS:
325 case BPF_LD|BPF_B|BPF_ABS:
326 case BPF_LD|BPF_W|BPF_LEN:
327 case BPF_LD|BPF_W|BPF_IND:
328 case BPF_LD|BPF_H|BPF_IND:
329 case BPF_LD|BPF_B|BPF_IND:
330 case BPF_LD|BPF_IMM:
331 case BPF_LDX|BPF_W|BPF_LEN:
332 case BPF_LDX|BPF_B|BPF_MSH:
333 case BPF_LDX|BPF_IMM:
334 case BPF_MISC|BPF_TAX:
335 case BPF_MISC|BPF_TXA:
336 case BPF_RET|BPF_K:
337 case BPF_RET|BPF_A:
338 break;
339
340 /* Some instructions need special checks */
324 341
325 /* check that memory operations use valid addresses. */ 342 case BPF_ALU|BPF_DIV|BPF_K:
326 if (ftest->k >= BPF_MEMWORDS) { 343 /* check for division by zero */
327 /* but it might not be a memory operation... */ 344 if (ftest->k == 0)
328 switch (ftest->code) {
329 case BPF_ST:
330 case BPF_STX:
331 case BPF_LD|BPF_MEM:
332 case BPF_LDX|BPF_MEM:
333 return -EINVAL; 345 return -EINVAL;
334 } 346 break;
347
348 case BPF_LD|BPF_MEM:
349 case BPF_LDX|BPF_MEM:
350 case BPF_ST:
351 case BPF_STX:
352 /* check for invalid memory addresses */
353 if (ftest->k >= BPF_MEMWORDS)
354 return -EINVAL;
355 break;
356
357 case BPF_JMP|BPF_JA:
358 /*
359 * Note, the large ftest->k might cause loops.
360 * Compare this with conditional jumps below,
361 * where offsets are limited. --ANK (981016)
362 */
363 if (ftest->k >= (unsigned)(flen-pc-1))
364 return -EINVAL;
365 break;
366
367 case BPF_JMP|BPF_JEQ|BPF_K:
368 case BPF_JMP|BPF_JEQ|BPF_X:
369 case BPF_JMP|BPF_JGE|BPF_K:
370 case BPF_JMP|BPF_JGE|BPF_X:
371 case BPF_JMP|BPF_JGT|BPF_K:
372 case BPF_JMP|BPF_JGT|BPF_X:
373 case BPF_JMP|BPF_JSET|BPF_K:
374 case BPF_JMP|BPF_JSET|BPF_X:
375 /* for conditionals both must be safe */
376 if (pc + ftest->jt + 1 >= flen ||
377 pc + ftest->jf + 1 >= flen)
378 return -EINVAL;
379 break;
380
381 default:
382 return -EINVAL;
335 } 383 }
336 } 384 }
337 385
diff --git a/net/core/flow.c b/net/core/flow.c
index 7e95b39de9..c4f2538502 100644
--- a/net/core/flow.c
+++ b/net/core/flow.c
@@ -23,6 +23,7 @@
23#include <net/flow.h> 23#include <net/flow.h>
24#include <asm/atomic.h> 24#include <asm/atomic.h>
25#include <asm/semaphore.h> 25#include <asm/semaphore.h>
26#include <linux/security.h>
26 27
27struct flow_cache_entry { 28struct flow_cache_entry {
28 struct flow_cache_entry *next; 29 struct flow_cache_entry *next;
@@ -30,6 +31,7 @@ struct flow_cache_entry {
30 u8 dir; 31 u8 dir;
31 struct flowi key; 32 struct flowi key;
32 u32 genid; 33 u32 genid;
34 u32 sk_sid;
33 void *object; 35 void *object;
34 atomic_t *object_ref; 36 atomic_t *object_ref;
35}; 37};
@@ -162,7 +164,7 @@ static int flow_key_compare(struct flowi *key1, struct flowi *key2)
162 return 0; 164 return 0;
163} 165}
164 166
165void *flow_cache_lookup(struct flowi *key, u16 family, u8 dir, 167void *flow_cache_lookup(struct flowi *key, u32 sk_sid, u16 family, u8 dir,
166 flow_resolve_t resolver) 168 flow_resolve_t resolver)
167{ 169{
168 struct flow_cache_entry *fle, **head; 170 struct flow_cache_entry *fle, **head;
@@ -186,6 +188,7 @@ void *flow_cache_lookup(struct flowi *key, u16 family, u8 dir,
186 for (fle = *head; fle; fle = fle->next) { 188 for (fle = *head; fle; fle = fle->next) {
187 if (fle->family == family && 189 if (fle->family == family &&
188 fle->dir == dir && 190 fle->dir == dir &&
191 fle->sk_sid == sk_sid &&
189 flow_key_compare(key, &fle->key) == 0) { 192 flow_key_compare(key, &fle->key) == 0) {
190 if (fle->genid == atomic_read(&flow_cache_genid)) { 193 if (fle->genid == atomic_read(&flow_cache_genid)) {
191 void *ret = fle->object; 194 void *ret = fle->object;
@@ -210,6 +213,7 @@ void *flow_cache_lookup(struct flowi *key, u16 family, u8 dir,
210 *head = fle; 213 *head = fle;
211 fle->family = family; 214 fle->family = family;
212 fle->dir = dir; 215 fle->dir = dir;
216 fle->sk_sid = sk_sid;
213 memcpy(&fle->key, key, sizeof(*key)); 217 memcpy(&fle->key, key, sizeof(*key));
214 fle->object = NULL; 218 fle->object = NULL;
215 flow_count(cpu)++; 219 flow_count(cpu)++;
@@ -221,7 +225,7 @@ nocache:
221 void *obj; 225 void *obj;
222 atomic_t *obj_ref; 226 atomic_t *obj_ref;
223 227
224 resolver(key, family, dir, &obj, &obj_ref); 228 resolver(key, sk_sid, family, dir, &obj, &obj_ref);
225 229
226 if (fle) { 230 if (fle) {
227 fle->genid = atomic_read(&flow_cache_genid); 231 fle->genid = atomic_read(&flow_cache_genid);
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c
index e2137f3e48..e1da81d261 100644
--- a/net/core/net-sysfs.c
+++ b/net/core/net-sysfs.c
@@ -84,16 +84,11 @@ static ssize_t netdev_store(struct class_device *dev,
84 return ret; 84 return ret;
85} 85}
86 86
87/* generate a read-only network device class attribute */ 87NETDEVICE_SHOW(addr_len, fmt_dec);
88#define NETDEVICE_ATTR(field, format_string) \ 88NETDEVICE_SHOW(iflink, fmt_dec);
89NETDEVICE_SHOW(field, format_string) \ 89NETDEVICE_SHOW(ifindex, fmt_dec);
90static CLASS_DEVICE_ATTR(field, S_IRUGO, show_##field, NULL) \ 90NETDEVICE_SHOW(features, fmt_long_hex);
91 91NETDEVICE_SHOW(type, fmt_dec);
92NETDEVICE_ATTR(addr_len, fmt_dec);
93NETDEVICE_ATTR(iflink, fmt_dec);
94NETDEVICE_ATTR(ifindex, fmt_dec);
95NETDEVICE_ATTR(features, fmt_long_hex);
96NETDEVICE_ATTR(type, fmt_dec);
97 92
98/* use same locking rules as GIFHWADDR ioctl's */ 93/* use same locking rules as GIFHWADDR ioctl's */
99static ssize_t format_addr(char *buf, const unsigned char *addr, int len) 94static ssize_t format_addr(char *buf, const unsigned char *addr, int len)
@@ -136,10 +131,6 @@ static ssize_t show_carrier(struct class_device *dev, char *buf)
136 return -EINVAL; 131 return -EINVAL;
137} 132}
138 133
139static CLASS_DEVICE_ATTR(address, S_IRUGO, show_address, NULL);
140static CLASS_DEVICE_ATTR(broadcast, S_IRUGO, show_broadcast, NULL);
141static CLASS_DEVICE_ATTR(carrier, S_IRUGO, show_carrier, NULL);
142
143/* read-write attributes */ 134/* read-write attributes */
144NETDEVICE_SHOW(mtu, fmt_dec); 135NETDEVICE_SHOW(mtu, fmt_dec);
145 136
@@ -153,8 +144,6 @@ static ssize_t store_mtu(struct class_device *dev, const char *buf, size_t len)
153 return netdev_store(dev, buf, len, change_mtu); 144 return netdev_store(dev, buf, len, change_mtu);
154} 145}
155 146
156static CLASS_DEVICE_ATTR(mtu, S_IRUGO | S_IWUSR, show_mtu, store_mtu);
157
158NETDEVICE_SHOW(flags, fmt_hex); 147NETDEVICE_SHOW(flags, fmt_hex);
159 148
160static int change_flags(struct net_device *net, unsigned long new_flags) 149static int change_flags(struct net_device *net, unsigned long new_flags)
@@ -167,8 +156,6 @@ static ssize_t store_flags(struct class_device *dev, const char *buf, size_t len
167 return netdev_store(dev, buf, len, change_flags); 156 return netdev_store(dev, buf, len, change_flags);
168} 157}
169 158
170static CLASS_DEVICE_ATTR(flags, S_IRUGO | S_IWUSR, show_flags, store_flags);
171
172NETDEVICE_SHOW(tx_queue_len, fmt_ulong); 159NETDEVICE_SHOW(tx_queue_len, fmt_ulong);
173 160
174static int change_tx_queue_len(struct net_device *net, unsigned long new_len) 161static int change_tx_queue_len(struct net_device *net, unsigned long new_len)
@@ -182,9 +169,6 @@ static ssize_t store_tx_queue_len(struct class_device *dev, const char *buf, siz
182 return netdev_store(dev, buf, len, change_tx_queue_len); 169 return netdev_store(dev, buf, len, change_tx_queue_len);
183} 170}
184 171
185static CLASS_DEVICE_ATTR(tx_queue_len, S_IRUGO | S_IWUSR, show_tx_queue_len,
186 store_tx_queue_len);
187
188NETDEVICE_SHOW(weight, fmt_dec); 172NETDEVICE_SHOW(weight, fmt_dec);
189 173
190static int change_weight(struct net_device *net, unsigned long new_weight) 174static int change_weight(struct net_device *net, unsigned long new_weight)
@@ -198,24 +182,21 @@ static ssize_t store_weight(struct class_device *dev, const char *buf, size_t le
198 return netdev_store(dev, buf, len, change_weight); 182 return netdev_store(dev, buf, len, change_weight);
199} 183}
200 184
201static CLASS_DEVICE_ATTR(weight, S_IRUGO | S_IWUSR, show_weight, 185static struct class_device_attribute net_class_attributes[] = {
202 store_weight); 186 __ATTR(addr_len, S_IRUGO, show_addr_len, NULL),
203 187 __ATTR(iflink, S_IRUGO, show_iflink, NULL),
204 188 __ATTR(ifindex, S_IRUGO, show_ifindex, NULL),
205static struct class_device_attribute *net_class_attributes[] = { 189 __ATTR(features, S_IRUGO, show_features, NULL),
206 &class_device_attr_ifindex, 190 __ATTR(type, S_IRUGO, show_type, NULL),
207 &class_device_attr_iflink, 191 __ATTR(address, S_IRUGO, show_address, NULL),
208 &class_device_attr_addr_len, 192 __ATTR(broadcast, S_IRUGO, show_broadcast, NULL),
209 &class_device_attr_tx_queue_len, 193 __ATTR(carrier, S_IRUGO, show_carrier, NULL),
210 &class_device_attr_features, 194 __ATTR(mtu, S_IRUGO | S_IWUSR, show_mtu, store_mtu),
211 &class_device_attr_mtu, 195 __ATTR(flags, S_IRUGO | S_IWUSR, show_flags, store_flags),
212 &class_device_attr_flags, 196 __ATTR(tx_queue_len, S_IRUGO | S_IWUSR, show_tx_queue_len,
213 &class_device_attr_weight, 197 store_tx_queue_len),
214 &class_device_attr_type, 198 __ATTR(weight, S_IRUGO | S_IWUSR, show_weight, store_weight),
215 &class_device_attr_address, 199 {}
216 &class_device_attr_broadcast,
217 &class_device_attr_carrier,
218 NULL
219}; 200};
220 201
221/* Show a given an attribute in the statistics group */ 202/* Show a given an attribute in the statistics group */
@@ -369,14 +350,14 @@ static struct attribute_group wireless_group = {
369#endif 350#endif
370 351
371#ifdef CONFIG_HOTPLUG 352#ifdef CONFIG_HOTPLUG
372static int netdev_hotplug(struct class_device *cd, char **envp, 353static int netdev_uevent(struct class_device *cd, char **envp,
373 int num_envp, char *buf, int size) 354 int num_envp, char *buf, int size)
374{ 355{
375 struct net_device *dev = to_net_dev(cd); 356 struct net_device *dev = to_net_dev(cd);
376 int i = 0; 357 int i = 0;
377 int n; 358 int n;
378 359
379 /* pass interface in env to hotplug. */ 360 /* pass interface to uevent. */
380 envp[i++] = buf; 361 envp[i++] = buf;
381 n = snprintf(buf, size, "INTERFACE=%s", dev->name) + 1; 362 n = snprintf(buf, size, "INTERFACE=%s", dev->name) + 1;
382 buf += n; 363 buf += n;
@@ -407,8 +388,9 @@ static void netdev_release(struct class_device *cd)
407static struct class net_class = { 388static struct class net_class = {
408 .name = "net", 389 .name = "net",
409 .release = netdev_release, 390 .release = netdev_release,
391 .class_dev_attrs = net_class_attributes,
410#ifdef CONFIG_HOTPLUG 392#ifdef CONFIG_HOTPLUG
411 .hotplug = netdev_hotplug, 393 .uevent = netdev_uevent,
412#endif 394#endif
413}; 395};
414 396
@@ -431,8 +413,6 @@ void netdev_unregister_sysfs(struct net_device * net)
431int netdev_register_sysfs(struct net_device *net) 413int netdev_register_sysfs(struct net_device *net)
432{ 414{
433 struct class_device *class_dev = &(net->class_dev); 415 struct class_device *class_dev = &(net->class_dev);
434 int i;
435 struct class_device_attribute *attr;
436 int ret; 416 int ret;
437 417
438 class_dev->class = &net_class; 418 class_dev->class = &net_class;
@@ -442,12 +422,6 @@ int netdev_register_sysfs(struct net_device *net)
442 if ((ret = class_device_register(class_dev))) 422 if ((ret = class_device_register(class_dev)))
443 goto out; 423 goto out;
444 424
445 for (i = 0; (attr = net_class_attributes[i]) != NULL; i++) {
446 if ((ret = class_device_create_file(class_dev, attr)))
447 goto out_unreg;
448 }
449
450
451 if (net->get_stats && 425 if (net->get_stats &&
452 (ret = sysfs_create_group(&class_dev->kobj, &netstat_group))) 426 (ret = sysfs_create_group(&class_dev->kobj, &netstat_group)))
453 goto out_unreg; 427 goto out_unreg;
diff --git a/net/core/netpoll.c b/net/core/netpoll.c
index 49424a42a2..281a632fa6 100644
--- a/net/core/netpoll.c
+++ b/net/core/netpoll.c
@@ -13,6 +13,7 @@
13#include <linux/netdevice.h> 13#include <linux/netdevice.h>
14#include <linux/etherdevice.h> 14#include <linux/etherdevice.h>
15#include <linux/string.h> 15#include <linux/string.h>
16#include <linux/if_arp.h>
16#include <linux/inetdevice.h> 17#include <linux/inetdevice.h>
17#include <linux/inet.h> 18#include <linux/inet.h>
18#include <linux/interrupt.h> 19#include <linux/interrupt.h>
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index 7fc3e9e28c..06cad2d63e 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -487,9 +487,9 @@ static unsigned int fmt_ip6(char *s,const char ip[16]);
487 487
488/* Module parameters, defaults. */ 488/* Module parameters, defaults. */
489static int pg_count_d = 1000; /* 1000 pkts by default */ 489static int pg_count_d = 1000; /* 1000 pkts by default */
490static int pg_delay_d = 0; 490static int pg_delay_d;
491static int pg_clone_skb_d = 0; 491static int pg_clone_skb_d;
492static int debug = 0; 492static int debug;
493 493
494static DECLARE_MUTEX(pktgen_sem); 494static DECLARE_MUTEX(pktgen_sem);
495static struct pktgen_thread *pktgen_threads = NULL; 495static struct pktgen_thread *pktgen_threads = NULL;
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 83fee37de3..070f91cfde 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -135,17 +135,13 @@ void skb_under_panic(struct sk_buff *skb, int sz, void *here)
135struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask, 135struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask,
136 int fclone) 136 int fclone)
137{ 137{
138 struct skb_shared_info *shinfo;
138 struct sk_buff *skb; 139 struct sk_buff *skb;
139 u8 *data; 140 u8 *data;
140 141
141 /* Get the HEAD */ 142 /* Get the HEAD */
142 if (fclone) 143 skb = kmem_cache_alloc(fclone ? skbuff_fclone_cache : skbuff_head_cache,
143 skb = kmem_cache_alloc(skbuff_fclone_cache, 144 gfp_mask & ~__GFP_DMA);
144 gfp_mask & ~__GFP_DMA);
145 else
146 skb = kmem_cache_alloc(skbuff_head_cache,
147 gfp_mask & ~__GFP_DMA);
148
149 if (!skb) 145 if (!skb)
150 goto out; 146 goto out;
151 147
@@ -162,6 +158,16 @@ struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask,
162 skb->data = data; 158 skb->data = data;
163 skb->tail = data; 159 skb->tail = data;
164 skb->end = data + size; 160 skb->end = data + size;
161 /* make sure we initialize shinfo sequentially */
162 shinfo = skb_shinfo(skb);
163 atomic_set(&shinfo->dataref, 1);
164 shinfo->nr_frags = 0;
165 shinfo->tso_size = 0;
166 shinfo->tso_segs = 0;
167 shinfo->ufo_size = 0;
168 shinfo->ip6_frag_id = 0;
169 shinfo->frag_list = NULL;
170
165 if (fclone) { 171 if (fclone) {
166 struct sk_buff *child = skb + 1; 172 struct sk_buff *child = skb + 1;
167 atomic_t *fclone_ref = (atomic_t *) (child + 1); 173 atomic_t *fclone_ref = (atomic_t *) (child + 1);
@@ -171,13 +177,6 @@ struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask,
171 177
172 child->fclone = SKB_FCLONE_UNAVAILABLE; 178 child->fclone = SKB_FCLONE_UNAVAILABLE;
173 } 179 }
174 atomic_set(&(skb_shinfo(skb)->dataref), 1);
175 skb_shinfo(skb)->nr_frags = 0;
176 skb_shinfo(skb)->tso_size = 0;
177 skb_shinfo(skb)->tso_segs = 0;
178 skb_shinfo(skb)->frag_list = NULL;
179 skb_shinfo(skb)->ufo_size = 0;
180 skb_shinfo(skb)->ip6_frag_id = 0;
181out: 180out:
182 return skb; 181 return skb;
183nodata: 182nodata:
diff --git a/net/core/sock.c b/net/core/sock.c
index 13cc3be4f0..6465b0e4c8 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -1488,7 +1488,7 @@ int proto_register(struct proto *prot, int alloc_slab)
1488 } 1488 }
1489 } 1489 }
1490 1490
1491 if (prot->twsk_obj_size) { 1491 if (prot->twsk_prot != NULL) {
1492 static const char mask[] = "tw_sock_%s"; 1492 static const char mask[] = "tw_sock_%s";
1493 1493
1494 timewait_sock_slab_name = kmalloc(strlen(prot->name) + sizeof(mask) - 1, GFP_KERNEL); 1494 timewait_sock_slab_name = kmalloc(strlen(prot->name) + sizeof(mask) - 1, GFP_KERNEL);
@@ -1497,11 +1497,12 @@ int proto_register(struct proto *prot, int alloc_slab)
1497 goto out_free_request_sock_slab; 1497 goto out_free_request_sock_slab;
1498 1498
1499 sprintf(timewait_sock_slab_name, mask, prot->name); 1499 sprintf(timewait_sock_slab_name, mask, prot->name);
1500 prot->twsk_slab = kmem_cache_create(timewait_sock_slab_name, 1500 prot->twsk_prot->twsk_slab =
1501 prot->twsk_obj_size, 1501 kmem_cache_create(timewait_sock_slab_name,
1502 0, SLAB_HWCACHE_ALIGN, 1502 prot->twsk_prot->twsk_obj_size,
1503 NULL, NULL); 1503 0, SLAB_HWCACHE_ALIGN,
1504 if (prot->twsk_slab == NULL) 1504 NULL, NULL);
1505 if (prot->twsk_prot->twsk_slab == NULL)
1505 goto out_free_timewait_sock_slab_name; 1506 goto out_free_timewait_sock_slab_name;
1506 } 1507 }
1507 } 1508 }
@@ -1548,12 +1549,12 @@ void proto_unregister(struct proto *prot)
1548 prot->rsk_prot->slab = NULL; 1549 prot->rsk_prot->slab = NULL;
1549 } 1550 }
1550 1551
1551 if (prot->twsk_slab != NULL) { 1552 if (prot->twsk_prot != NULL && prot->twsk_prot->twsk_slab != NULL) {
1552 const char *name = kmem_cache_name(prot->twsk_slab); 1553 const char *name = kmem_cache_name(prot->twsk_prot->twsk_slab);
1553 1554
1554 kmem_cache_destroy(prot->twsk_slab); 1555 kmem_cache_destroy(prot->twsk_prot->twsk_slab);
1555 kfree(name); 1556 kfree(name);
1556 prot->twsk_slab = NULL; 1557 prot->twsk_prot->twsk_slab = NULL;
1557 } 1558 }
1558} 1559}
1559 1560
diff --git a/net/core/stream.c b/net/core/stream.c
index 15bfd03e80..35e25259fd 100644
--- a/net/core/stream.c
+++ b/net/core/stream.c
@@ -55,8 +55,9 @@ int sk_stream_wait_connect(struct sock *sk, long *timeo_p)
55 int done; 55 int done;
56 56
57 do { 57 do {
58 if (sk->sk_err) 58 int err = sock_error(sk);
59 return sock_error(sk); 59 if (err)
60 return err;
60 if ((1 << sk->sk_state) & ~(TCPF_SYN_SENT | TCPF_SYN_RECV)) 61 if ((1 << sk->sk_state) & ~(TCPF_SYN_SENT | TCPF_SYN_RECV))
61 return -EPIPE; 62 return -EPIPE;
62 if (!*timeo_p) 63 if (!*timeo_p)
@@ -67,6 +68,7 @@ int sk_stream_wait_connect(struct sock *sk, long *timeo_p)
67 prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE); 68 prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
68 sk->sk_write_pending++; 69 sk->sk_write_pending++;
69 done = sk_wait_event(sk, timeo_p, 70 done = sk_wait_event(sk, timeo_p,
71 !sk->sk_err &&
70 !((1 << sk->sk_state) & 72 !((1 << sk->sk_state) &
71 ~(TCPF_ESTABLISHED | TCPF_CLOSE_WAIT))); 73 ~(TCPF_ESTABLISHED | TCPF_CLOSE_WAIT)));
72 finish_wait(sk->sk_sleep, &wait); 74 finish_wait(sk->sk_sleep, &wait);
@@ -137,7 +139,9 @@ int sk_stream_wait_memory(struct sock *sk, long *timeo_p)
137 139
138 set_bit(SOCK_NOSPACE, &sk->sk_socket->flags); 140 set_bit(SOCK_NOSPACE, &sk->sk_socket->flags);
139 sk->sk_write_pending++; 141 sk->sk_write_pending++;
140 sk_wait_event(sk, &current_timeo, sk_stream_memory_free(sk) && 142 sk_wait_event(sk, &current_timeo, !sk->sk_err &&
143 !(sk->sk_shutdown & SEND_SHUTDOWN) &&
144 sk_stream_memory_free(sk) &&
141 vm_wait); 145 vm_wait);
142 sk->sk_write_pending--; 146 sk->sk_write_pending--;
143 147
diff --git a/net/core/utils.c b/net/core/utils.c
index 7b5970fc9e..587eb7787d 100644
--- a/net/core/utils.c
+++ b/net/core/utils.c
@@ -175,7 +175,7 @@ __u32 in_aton(const char *str)
175 if (*str != '\0') 175 if (*str != '\0')
176 { 176 {
177 val = 0; 177 val = 0;
178 while (*str != '\0' && *str != '.') 178 while (*str != '\0' && *str != '.' && *str != '\n')
179 { 179 {
180 val *= 10; 180 val *= 10;
181 val += *str - '0'; 181 val += *str - '0';