diff options
author | Jody McIntyre <scjody@modernduck.com> | 2006-01-05 08:03:40 -0500 |
---|---|---|
committer | Jody McIntyre <scjody@modernduck.com> | 2006-01-05 08:03:40 -0500 |
commit | 0a75c23a009ff65f651532cecc16675d05f4de37 (patch) | |
tree | bdcd6158758fe1810f0ddddb80d2816779518688 /net/core | |
parent | 34b8c399dc04c8e51f014b73458e654570698597 (diff) | |
parent | db9edfd7e339ca4113153d887e782dd05be5a9eb (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.c | 36 | ||||
-rw-r--r-- | net/core/dev.c | 4 | ||||
-rw-r--r-- | net/core/filter.c | 112 | ||||
-rw-r--r-- | net/core/flow.c | 8 | ||||
-rw-r--r-- | net/core/net-sysfs.c | 76 | ||||
-rw-r--r-- | net/core/netpoll.c | 1 | ||||
-rw-r--r-- | net/core/pktgen.c | 6 | ||||
-rw-r--r-- | net/core/skbuff.c | 27 | ||||
-rw-r--r-- | net/core/sock.c | 21 | ||||
-rw-r--r-- | net/core/stream.c | 10 | ||||
-rw-r--r-- | net/core/utils.c | 2 |
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 | |||
222 | void 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 | |||
236 | EXPORT_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 | */ |
629 | static int dev_valid_name(const char *name) | 629 | int 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); | |||
3270 | EXPORT_SYMBOL(__dev_get_by_name); | 3270 | EXPORT_SYMBOL(__dev_get_by_name); |
3271 | EXPORT_SYMBOL(__dev_remove_pack); | 3271 | EXPORT_SYMBOL(__dev_remove_pack); |
3272 | EXPORT_SYMBOL(__skb_linearize); | 3272 | EXPORT_SYMBOL(__skb_linearize); |
3273 | EXPORT_SYMBOL(dev_valid_name); | ||
3273 | EXPORT_SYMBOL(dev_add_pack); | 3274 | EXPORT_SYMBOL(dev_add_pack); |
3274 | EXPORT_SYMBOL(dev_alloc_name); | 3275 | EXPORT_SYMBOL(dev_alloc_name); |
3275 | EXPORT_SYMBOL(dev_close); | 3276 | EXPORT_SYMBOL(dev_close); |
3276 | EXPORT_SYMBOL(dev_get_by_flags); | 3277 | EXPORT_SYMBOL(dev_get_by_flags); |
3277 | EXPORT_SYMBOL(dev_get_by_index); | 3278 | EXPORT_SYMBOL(dev_get_by_index); |
3278 | EXPORT_SYMBOL(dev_get_by_name); | 3279 | EXPORT_SYMBOL(dev_get_by_name); |
3279 | EXPORT_SYMBOL(dev_ioctl); | ||
3280 | EXPORT_SYMBOL(dev_open); | 3280 | EXPORT_SYMBOL(dev_open); |
3281 | EXPORT_SYMBOL(dev_queue_xmit); | 3281 | EXPORT_SYMBOL(dev_queue_xmit); |
3282 | EXPORT_SYMBOL(dev_remove_pack); | 3282 | EXPORT_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 | ||
27 | struct flow_cache_entry { | 28 | struct 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 | ||
165 | void *flow_cache_lookup(struct flowi *key, u16 family, u8 dir, | 167 | void *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 */ | 87 | NETDEVICE_SHOW(addr_len, fmt_dec); |
88 | #define NETDEVICE_ATTR(field, format_string) \ | 88 | NETDEVICE_SHOW(iflink, fmt_dec); |
89 | NETDEVICE_SHOW(field, format_string) \ | 89 | NETDEVICE_SHOW(ifindex, fmt_dec); |
90 | static CLASS_DEVICE_ATTR(field, S_IRUGO, show_##field, NULL) \ | 90 | NETDEVICE_SHOW(features, fmt_long_hex); |
91 | 91 | NETDEVICE_SHOW(type, fmt_dec); | |
92 | NETDEVICE_ATTR(addr_len, fmt_dec); | ||
93 | NETDEVICE_ATTR(iflink, fmt_dec); | ||
94 | NETDEVICE_ATTR(ifindex, fmt_dec); | ||
95 | NETDEVICE_ATTR(features, fmt_long_hex); | ||
96 | NETDEVICE_ATTR(type, fmt_dec); | ||
97 | 92 | ||
98 | /* use same locking rules as GIFHWADDR ioctl's */ | 93 | /* use same locking rules as GIFHWADDR ioctl's */ |
99 | static ssize_t format_addr(char *buf, const unsigned char *addr, int len) | 94 | static 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 | ||
139 | static CLASS_DEVICE_ATTR(address, S_IRUGO, show_address, NULL); | ||
140 | static CLASS_DEVICE_ATTR(broadcast, S_IRUGO, show_broadcast, NULL); | ||
141 | static CLASS_DEVICE_ATTR(carrier, S_IRUGO, show_carrier, NULL); | ||
142 | |||
143 | /* read-write attributes */ | 134 | /* read-write attributes */ |
144 | NETDEVICE_SHOW(mtu, fmt_dec); | 135 | NETDEVICE_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 | ||
156 | static CLASS_DEVICE_ATTR(mtu, S_IRUGO | S_IWUSR, show_mtu, store_mtu); | ||
157 | |||
158 | NETDEVICE_SHOW(flags, fmt_hex); | 147 | NETDEVICE_SHOW(flags, fmt_hex); |
159 | 148 | ||
160 | static int change_flags(struct net_device *net, unsigned long new_flags) | 149 | static 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 | ||
170 | static CLASS_DEVICE_ATTR(flags, S_IRUGO | S_IWUSR, show_flags, store_flags); | ||
171 | |||
172 | NETDEVICE_SHOW(tx_queue_len, fmt_ulong); | 159 | NETDEVICE_SHOW(tx_queue_len, fmt_ulong); |
173 | 160 | ||
174 | static int change_tx_queue_len(struct net_device *net, unsigned long new_len) | 161 | static 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 | ||
185 | static CLASS_DEVICE_ATTR(tx_queue_len, S_IRUGO | S_IWUSR, show_tx_queue_len, | ||
186 | store_tx_queue_len); | ||
187 | |||
188 | NETDEVICE_SHOW(weight, fmt_dec); | 172 | NETDEVICE_SHOW(weight, fmt_dec); |
189 | 173 | ||
190 | static int change_weight(struct net_device *net, unsigned long new_weight) | 174 | static 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 | ||
201 | static CLASS_DEVICE_ATTR(weight, S_IRUGO | S_IWUSR, show_weight, | 185 | static 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), | |
205 | static 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 |
372 | static int netdev_hotplug(struct class_device *cd, char **envp, | 353 | static 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) | |||
407 | static struct class net_class = { | 388 | static 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) | |||
431 | int netdev_register_sysfs(struct net_device *net) | 413 | int 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. */ |
489 | static int pg_count_d = 1000; /* 1000 pkts by default */ | 489 | static int pg_count_d = 1000; /* 1000 pkts by default */ |
490 | static int pg_delay_d = 0; | 490 | static int pg_delay_d; |
491 | static int pg_clone_skb_d = 0; | 491 | static int pg_clone_skb_d; |
492 | static int debug = 0; | 492 | static int debug; |
493 | 493 | ||
494 | static DECLARE_MUTEX(pktgen_sem); | 494 | static DECLARE_MUTEX(pktgen_sem); |
495 | static struct pktgen_thread *pktgen_threads = NULL; | 495 | static 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) | |||
135 | struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask, | 135 | struct 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; | ||
181 | out: | 180 | out: |
182 | return skb; | 181 | return skb; |
183 | nodata: | 182 | nodata: |
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, ¤t_timeo, sk_stream_memory_free(sk) && | 142 | sk_wait_event(sk, ¤t_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'; |