diff options
author | Patrick McHardy <kaber@trash.net> | 2009-06-11 10:00:49 -0400 |
---|---|---|
committer | Patrick McHardy <kaber@trash.net> | 2009-06-11 10:00:49 -0400 |
commit | 36432dae73cf2c90a59b39c8df9fd8219272b005 (patch) | |
tree | 660b9104305a809ec4fdeb295ca13d6e90790ecc /net/core | |
parent | 440f0d588555892601cfe511728a0fc0c8204063 (diff) | |
parent | bb400801c2f40bbd9a688818323ad09abfc4e581 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6
Diffstat (limited to 'net/core')
-rw-r--r-- | net/core/datagram.c | 181 | ||||
-rw-r--r-- | net/core/dev.c | 230 | ||||
-rw-r--r-- | net/core/iovec.c | 4 | ||||
-rw-r--r-- | net/core/neighbour.c | 57 | ||||
-rw-r--r-- | net/core/pktgen.c | 6 | ||||
-rw-r--r-- | net/core/skb_dma_map.c | 13 | ||||
-rw-r--r-- | net/core/skbuff.c | 241 | ||||
-rw-r--r-- | net/core/sock.c | 135 | ||||
-rw-r--r-- | net/core/user_dma.c | 46 |
9 files changed, 491 insertions, 422 deletions
diff --git a/net/core/datagram.c b/net/core/datagram.c index e2a36f05cdf..58abee1f1df 100644 --- a/net/core/datagram.c +++ b/net/core/datagram.c | |||
@@ -282,6 +282,7 @@ int skb_copy_datagram_iovec(const struct sk_buff *skb, int offset, | |||
282 | { | 282 | { |
283 | int start = skb_headlen(skb); | 283 | int start = skb_headlen(skb); |
284 | int i, copy = start - offset; | 284 | int i, copy = start - offset; |
285 | struct sk_buff *frag_iter; | ||
285 | 286 | ||
286 | /* Copy header. */ | 287 | /* Copy header. */ |
287 | if (copy > 0) { | 288 | if (copy > 0) { |
@@ -322,28 +323,24 @@ int skb_copy_datagram_iovec(const struct sk_buff *skb, int offset, | |||
322 | start = end; | 323 | start = end; |
323 | } | 324 | } |
324 | 325 | ||
325 | if (skb_shinfo(skb)->frag_list) { | 326 | skb_walk_frags(skb, frag_iter) { |
326 | struct sk_buff *list = skb_shinfo(skb)->frag_list; | 327 | int end; |
327 | 328 | ||
328 | for (; list; list = list->next) { | 329 | WARN_ON(start > offset + len); |
329 | int end; | 330 | |
330 | 331 | end = start + frag_iter->len; | |
331 | WARN_ON(start > offset + len); | 332 | if ((copy = end - offset) > 0) { |
332 | 333 | if (copy > len) | |
333 | end = start + list->len; | 334 | copy = len; |
334 | if ((copy = end - offset) > 0) { | 335 | if (skb_copy_datagram_iovec(frag_iter, |
335 | if (copy > len) | 336 | offset - start, |
336 | copy = len; | 337 | to, copy)) |
337 | if (skb_copy_datagram_iovec(list, | 338 | goto fault; |
338 | offset - start, | 339 | if ((len -= copy) == 0) |
339 | to, copy)) | 340 | return 0; |
340 | goto fault; | 341 | offset += copy; |
341 | if ((len -= copy) == 0) | ||
342 | return 0; | ||
343 | offset += copy; | ||
344 | } | ||
345 | start = end; | ||
346 | } | 342 | } |
343 | start = end; | ||
347 | } | 344 | } |
348 | if (!len) | 345 | if (!len) |
349 | return 0; | 346 | return 0; |
@@ -369,6 +366,7 @@ int skb_copy_datagram_const_iovec(const struct sk_buff *skb, int offset, | |||
369 | { | 366 | { |
370 | int start = skb_headlen(skb); | 367 | int start = skb_headlen(skb); |
371 | int i, copy = start - offset; | 368 | int i, copy = start - offset; |
369 | struct sk_buff *frag_iter; | ||
372 | 370 | ||
373 | /* Copy header. */ | 371 | /* Copy header. */ |
374 | if (copy > 0) { | 372 | if (copy > 0) { |
@@ -411,30 +409,26 @@ int skb_copy_datagram_const_iovec(const struct sk_buff *skb, int offset, | |||
411 | start = end; | 409 | start = end; |
412 | } | 410 | } |
413 | 411 | ||
414 | if (skb_shinfo(skb)->frag_list) { | 412 | skb_walk_frags(skb, frag_iter) { |
415 | struct sk_buff *list = skb_shinfo(skb)->frag_list; | 413 | int end; |
416 | 414 | ||
417 | for (; list; list = list->next) { | 415 | WARN_ON(start > offset + len); |
418 | int end; | 416 | |
419 | 417 | end = start + frag_iter->len; | |
420 | WARN_ON(start > offset + len); | 418 | if ((copy = end - offset) > 0) { |
421 | 419 | if (copy > len) | |
422 | end = start + list->len; | 420 | copy = len; |
423 | if ((copy = end - offset) > 0) { | 421 | if (skb_copy_datagram_const_iovec(frag_iter, |
424 | if (copy > len) | 422 | offset - start, |
425 | copy = len; | 423 | to, to_offset, |
426 | if (skb_copy_datagram_const_iovec(list, | 424 | copy)) |
427 | offset - start, | 425 | goto fault; |
428 | to, to_offset, | 426 | if ((len -= copy) == 0) |
429 | copy)) | 427 | return 0; |
430 | goto fault; | 428 | offset += copy; |
431 | if ((len -= copy) == 0) | 429 | to_offset += copy; |
432 | return 0; | ||
433 | offset += copy; | ||
434 | to_offset += copy; | ||
435 | } | ||
436 | start = end; | ||
437 | } | 430 | } |
431 | start = end; | ||
438 | } | 432 | } |
439 | if (!len) | 433 | if (!len) |
440 | return 0; | 434 | return 0; |
@@ -461,12 +455,14 @@ int skb_copy_datagram_from_iovec(struct sk_buff *skb, int offset, | |||
461 | { | 455 | { |
462 | int start = skb_headlen(skb); | 456 | int start = skb_headlen(skb); |
463 | int i, copy = start - offset; | 457 | int i, copy = start - offset; |
458 | struct sk_buff *frag_iter; | ||
464 | 459 | ||
465 | /* Copy header. */ | 460 | /* Copy header. */ |
466 | if (copy > 0) { | 461 | if (copy > 0) { |
467 | if (copy > len) | 462 | if (copy > len) |
468 | copy = len; | 463 | copy = len; |
469 | if (memcpy_fromiovecend(skb->data + offset, from, 0, copy)) | 464 | if (memcpy_fromiovecend(skb->data + offset, from, from_offset, |
465 | copy)) | ||
470 | goto fault; | 466 | goto fault; |
471 | if ((len -= copy) == 0) | 467 | if ((len -= copy) == 0) |
472 | return 0; | 468 | return 0; |
@@ -505,31 +501,27 @@ int skb_copy_datagram_from_iovec(struct sk_buff *skb, int offset, | |||
505 | start = end; | 501 | start = end; |
506 | } | 502 | } |
507 | 503 | ||
508 | if (skb_shinfo(skb)->frag_list) { | 504 | skb_walk_frags(skb, frag_iter) { |
509 | struct sk_buff *list = skb_shinfo(skb)->frag_list; | 505 | int end; |
510 | 506 | ||
511 | for (; list; list = list->next) { | 507 | WARN_ON(start > offset + len); |
512 | int end; | 508 | |
513 | 509 | end = start + frag_iter->len; | |
514 | WARN_ON(start > offset + len); | 510 | if ((copy = end - offset) > 0) { |
515 | 511 | if (copy > len) | |
516 | end = start + list->len; | 512 | copy = len; |
517 | if ((copy = end - offset) > 0) { | 513 | if (skb_copy_datagram_from_iovec(frag_iter, |
518 | if (copy > len) | 514 | offset - start, |
519 | copy = len; | 515 | from, |
520 | if (skb_copy_datagram_from_iovec(list, | 516 | from_offset, |
521 | offset - start, | 517 | copy)) |
522 | from, | 518 | goto fault; |
523 | from_offset, | 519 | if ((len -= copy) == 0) |
524 | copy)) | 520 | return 0; |
525 | goto fault; | 521 | offset += copy; |
526 | if ((len -= copy) == 0) | 522 | from_offset += copy; |
527 | return 0; | ||
528 | offset += copy; | ||
529 | from_offset += copy; | ||
530 | } | ||
531 | start = end; | ||
532 | } | 523 | } |
524 | start = end; | ||
533 | } | 525 | } |
534 | if (!len) | 526 | if (!len) |
535 | return 0; | 527 | return 0; |
@@ -544,8 +536,9 @@ static int skb_copy_and_csum_datagram(const struct sk_buff *skb, int offset, | |||
544 | __wsum *csump) | 536 | __wsum *csump) |
545 | { | 537 | { |
546 | int start = skb_headlen(skb); | 538 | int start = skb_headlen(skb); |
547 | int pos = 0; | ||
548 | int i, copy = start - offset; | 539 | int i, copy = start - offset; |
540 | struct sk_buff *frag_iter; | ||
541 | int pos = 0; | ||
549 | 542 | ||
550 | /* Copy header. */ | 543 | /* Copy header. */ |
551 | if (copy > 0) { | 544 | if (copy > 0) { |
@@ -596,33 +589,29 @@ static int skb_copy_and_csum_datagram(const struct sk_buff *skb, int offset, | |||
596 | start = end; | 589 | start = end; |
597 | } | 590 | } |
598 | 591 | ||
599 | if (skb_shinfo(skb)->frag_list) { | 592 | skb_walk_frags(skb, frag_iter) { |
600 | struct sk_buff *list = skb_shinfo(skb)->frag_list; | 593 | int end; |
601 | 594 | ||
602 | for (; list; list=list->next) { | 595 | WARN_ON(start > offset + len); |
603 | int end; | 596 | |
604 | 597 | end = start + frag_iter->len; | |
605 | WARN_ON(start > offset + len); | 598 | if ((copy = end - offset) > 0) { |
606 | 599 | __wsum csum2 = 0; | |
607 | end = start + list->len; | 600 | if (copy > len) |
608 | if ((copy = end - offset) > 0) { | 601 | copy = len; |
609 | __wsum csum2 = 0; | 602 | if (skb_copy_and_csum_datagram(frag_iter, |
610 | if (copy > len) | 603 | offset - start, |
611 | copy = len; | 604 | to, copy, |
612 | if (skb_copy_and_csum_datagram(list, | 605 | &csum2)) |
613 | offset - start, | 606 | goto fault; |
614 | to, copy, | 607 | *csump = csum_block_add(*csump, csum2, pos); |
615 | &csum2)) | 608 | if ((len -= copy) == 0) |
616 | goto fault; | 609 | return 0; |
617 | *csump = csum_block_add(*csump, csum2, pos); | 610 | offset += copy; |
618 | if ((len -= copy) == 0) | 611 | to += copy; |
619 | return 0; | 612 | pos += copy; |
620 | offset += copy; | ||
621 | to += copy; | ||
622 | pos += copy; | ||
623 | } | ||
624 | start = end; | ||
625 | } | 613 | } |
614 | start = end; | ||
626 | } | 615 | } |
627 | if (!len) | 616 | if (!len) |
628 | return 0; | 617 | return 0; |
diff --git a/net/core/dev.c b/net/core/dev.c index ed4550fd9ec..11560e3258b 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -269,7 +269,8 @@ static const unsigned short netdev_lock_type[] = | |||
269 | ARPHRD_IRDA, ARPHRD_FCPP, ARPHRD_FCAL, ARPHRD_FCPL, | 269 | ARPHRD_IRDA, ARPHRD_FCPP, ARPHRD_FCAL, ARPHRD_FCPL, |
270 | ARPHRD_FCFABRIC, ARPHRD_IEEE802_TR, ARPHRD_IEEE80211, | 270 | ARPHRD_FCFABRIC, ARPHRD_IEEE802_TR, ARPHRD_IEEE80211, |
271 | ARPHRD_IEEE80211_PRISM, ARPHRD_IEEE80211_RADIOTAP, ARPHRD_PHONET, | 271 | ARPHRD_IEEE80211_PRISM, ARPHRD_IEEE80211_RADIOTAP, ARPHRD_PHONET, |
272 | ARPHRD_PHONET_PIPE, ARPHRD_VOID, ARPHRD_NONE}; | 272 | ARPHRD_PHONET_PIPE, ARPHRD_IEEE802154, ARPHRD_IEEE802154_PHY, |
273 | ARPHRD_VOID, ARPHRD_NONE}; | ||
273 | 274 | ||
274 | static const char *netdev_lock_name[] = | 275 | static const char *netdev_lock_name[] = |
275 | {"_xmit_NETROM", "_xmit_ETHER", "_xmit_EETHER", "_xmit_AX25", | 276 | {"_xmit_NETROM", "_xmit_ETHER", "_xmit_EETHER", "_xmit_AX25", |
@@ -286,7 +287,8 @@ static const char *netdev_lock_name[] = | |||
286 | "_xmit_IRDA", "_xmit_FCPP", "_xmit_FCAL", "_xmit_FCPL", | 287 | "_xmit_IRDA", "_xmit_FCPP", "_xmit_FCAL", "_xmit_FCPL", |
287 | "_xmit_FCFABRIC", "_xmit_IEEE802_TR", "_xmit_IEEE80211", | 288 | "_xmit_FCFABRIC", "_xmit_IEEE802_TR", "_xmit_IEEE80211", |
288 | "_xmit_IEEE80211_PRISM", "_xmit_IEEE80211_RADIOTAP", "_xmit_PHONET", | 289 | "_xmit_IEEE80211_PRISM", "_xmit_IEEE80211_RADIOTAP", "_xmit_PHONET", |
289 | "_xmit_PHONET_PIPE", "_xmit_VOID", "_xmit_NONE"}; | 290 | "_xmit_PHONET_PIPE", "_xmit_IEEE802154", "_xmit_IEEE802154_PHY", |
291 | "_xmit_VOID", "_xmit_NONE"}; | ||
290 | 292 | ||
291 | static struct lock_class_key netdev_xmit_lock_key[ARRAY_SIZE(netdev_lock_type)]; | 293 | static struct lock_class_key netdev_xmit_lock_key[ARRAY_SIZE(netdev_lock_type)]; |
292 | static struct lock_class_key netdev_addr_lock_key[ARRAY_SIZE(netdev_lock_type)]; | 294 | static struct lock_class_key netdev_addr_lock_key[ARRAY_SIZE(netdev_lock_type)]; |
@@ -1048,7 +1050,7 @@ void dev_load(struct net *net, const char *name) | |||
1048 | int dev_open(struct net_device *dev) | 1050 | int dev_open(struct net_device *dev) |
1049 | { | 1051 | { |
1050 | const struct net_device_ops *ops = dev->netdev_ops; | 1052 | const struct net_device_ops *ops = dev->netdev_ops; |
1051 | int ret = 0; | 1053 | int ret; |
1052 | 1054 | ||
1053 | ASSERT_RTNL(); | 1055 | ASSERT_RTNL(); |
1054 | 1056 | ||
@@ -1065,6 +1067,11 @@ int dev_open(struct net_device *dev) | |||
1065 | if (!netif_device_present(dev)) | 1067 | if (!netif_device_present(dev)) |
1066 | return -ENODEV; | 1068 | return -ENODEV; |
1067 | 1069 | ||
1070 | ret = call_netdevice_notifiers(NETDEV_PRE_UP, dev); | ||
1071 | ret = notifier_to_errno(ret); | ||
1072 | if (ret) | ||
1073 | return ret; | ||
1074 | |||
1068 | /* | 1075 | /* |
1069 | * Call device private open method | 1076 | * Call device private open method |
1070 | */ | 1077 | */ |
@@ -1693,10 +1700,9 @@ int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev, | |||
1693 | * If device doesnt need skb->dst, release it right now while | 1700 | * If device doesnt need skb->dst, release it right now while |
1694 | * its hot in this cpu cache | 1701 | * its hot in this cpu cache |
1695 | */ | 1702 | */ |
1696 | if ((dev->priv_flags & IFF_XMIT_DST_RELEASE) && skb->dst) { | 1703 | if (dev->priv_flags & IFF_XMIT_DST_RELEASE) |
1697 | dst_release(skb->dst); | 1704 | skb_dst_drop(skb); |
1698 | skb->dst = NULL; | 1705 | |
1699 | } | ||
1700 | rc = ops->ndo_start_xmit(skb, dev); | 1706 | rc = ops->ndo_start_xmit(skb, dev); |
1701 | if (rc == 0) | 1707 | if (rc == 0) |
1702 | txq_trans_update(txq); | 1708 | txq_trans_update(txq); |
@@ -1816,7 +1822,7 @@ int dev_queue_xmit(struct sk_buff *skb) | |||
1816 | if (netif_needs_gso(dev, skb)) | 1822 | if (netif_needs_gso(dev, skb)) |
1817 | goto gso; | 1823 | goto gso; |
1818 | 1824 | ||
1819 | if (skb_shinfo(skb)->frag_list && | 1825 | if (skb_has_frags(skb) && |
1820 | !(dev->features & NETIF_F_FRAGLIST) && | 1826 | !(dev->features & NETIF_F_FRAGLIST) && |
1821 | __skb_linearize(skb)) | 1827 | __skb_linearize(skb)) |
1822 | goto out_kfree_skb; | 1828 | goto out_kfree_skb; |
@@ -2403,7 +2409,7 @@ int dev_gro_receive(struct napi_struct *napi, struct sk_buff *skb) | |||
2403 | if (!(skb->dev->features & NETIF_F_GRO)) | 2409 | if (!(skb->dev->features & NETIF_F_GRO)) |
2404 | goto normal; | 2410 | goto normal; |
2405 | 2411 | ||
2406 | if (skb_is_gso(skb) || skb_shinfo(skb)->frag_list) | 2412 | if (skb_is_gso(skb) || skb_has_frags(skb)) |
2407 | goto normal; | 2413 | goto normal; |
2408 | 2414 | ||
2409 | rcu_read_lock(); | 2415 | rcu_read_lock(); |
@@ -3473,8 +3479,9 @@ void dev_set_rx_mode(struct net_device *dev) | |||
3473 | 3479 | ||
3474 | /* hw addresses list handling functions */ | 3480 | /* hw addresses list handling functions */ |
3475 | 3481 | ||
3476 | static int __hw_addr_add(struct list_head *list, unsigned char *addr, | 3482 | static int __hw_addr_add(struct list_head *list, int *delta, |
3477 | int addr_len, unsigned char addr_type) | 3483 | unsigned char *addr, int addr_len, |
3484 | unsigned char addr_type) | ||
3478 | { | 3485 | { |
3479 | struct netdev_hw_addr *ha; | 3486 | struct netdev_hw_addr *ha; |
3480 | int alloc_size; | 3487 | int alloc_size; |
@@ -3482,6 +3489,15 @@ static int __hw_addr_add(struct list_head *list, unsigned char *addr, | |||
3482 | if (addr_len > MAX_ADDR_LEN) | 3489 | if (addr_len > MAX_ADDR_LEN) |
3483 | return -EINVAL; | 3490 | return -EINVAL; |
3484 | 3491 | ||
3492 | list_for_each_entry(ha, list, list) { | ||
3493 | if (!memcmp(ha->addr, addr, addr_len) && | ||
3494 | ha->type == addr_type) { | ||
3495 | ha->refcount++; | ||
3496 | return 0; | ||
3497 | } | ||
3498 | } | ||
3499 | |||
3500 | |||
3485 | alloc_size = sizeof(*ha); | 3501 | alloc_size = sizeof(*ha); |
3486 | if (alloc_size < L1_CACHE_BYTES) | 3502 | if (alloc_size < L1_CACHE_BYTES) |
3487 | alloc_size = L1_CACHE_BYTES; | 3503 | alloc_size = L1_CACHE_BYTES; |
@@ -3490,7 +3506,11 @@ static int __hw_addr_add(struct list_head *list, unsigned char *addr, | |||
3490 | return -ENOMEM; | 3506 | return -ENOMEM; |
3491 | memcpy(ha->addr, addr, addr_len); | 3507 | memcpy(ha->addr, addr, addr_len); |
3492 | ha->type = addr_type; | 3508 | ha->type = addr_type; |
3509 | ha->refcount = 1; | ||
3510 | ha->synced = false; | ||
3493 | list_add_tail_rcu(&ha->list, list); | 3511 | list_add_tail_rcu(&ha->list, list); |
3512 | if (delta) | ||
3513 | (*delta)++; | ||
3494 | return 0; | 3514 | return 0; |
3495 | } | 3515 | } |
3496 | 3516 | ||
@@ -3502,29 +3522,30 @@ static void ha_rcu_free(struct rcu_head *head) | |||
3502 | kfree(ha); | 3522 | kfree(ha); |
3503 | } | 3523 | } |
3504 | 3524 | ||
3505 | static int __hw_addr_del_ii(struct list_head *list, unsigned char *addr, | 3525 | static int __hw_addr_del(struct list_head *list, int *delta, |
3506 | int addr_len, unsigned char addr_type, | 3526 | unsigned char *addr, int addr_len, |
3507 | int ignore_index) | 3527 | unsigned char addr_type) |
3508 | { | 3528 | { |
3509 | struct netdev_hw_addr *ha; | 3529 | struct netdev_hw_addr *ha; |
3510 | int i = 0; | ||
3511 | 3530 | ||
3512 | list_for_each_entry(ha, list, list) { | 3531 | list_for_each_entry(ha, list, list) { |
3513 | if (i++ != ignore_index && | 3532 | if (!memcmp(ha->addr, addr, addr_len) && |
3514 | !memcmp(ha->addr, addr, addr_len) && | ||
3515 | (ha->type == addr_type || !addr_type)) { | 3533 | (ha->type == addr_type || !addr_type)) { |
3534 | if (--ha->refcount) | ||
3535 | return 0; | ||
3516 | list_del_rcu(&ha->list); | 3536 | list_del_rcu(&ha->list); |
3517 | call_rcu(&ha->rcu_head, ha_rcu_free); | 3537 | call_rcu(&ha->rcu_head, ha_rcu_free); |
3538 | if (delta) | ||
3539 | (*delta)--; | ||
3518 | return 0; | 3540 | return 0; |
3519 | } | 3541 | } |
3520 | } | 3542 | } |
3521 | return -ENOENT; | 3543 | return -ENOENT; |
3522 | } | 3544 | } |
3523 | 3545 | ||
3524 | static int __hw_addr_add_multiple_ii(struct list_head *to_list, | 3546 | static int __hw_addr_add_multiple(struct list_head *to_list, int *to_delta, |
3525 | struct list_head *from_list, | 3547 | struct list_head *from_list, int addr_len, |
3526 | int addr_len, unsigned char addr_type, | 3548 | unsigned char addr_type) |
3527 | int ignore_index) | ||
3528 | { | 3549 | { |
3529 | int err; | 3550 | int err; |
3530 | struct netdev_hw_addr *ha, *ha2; | 3551 | struct netdev_hw_addr *ha, *ha2; |
@@ -3532,7 +3553,8 @@ static int __hw_addr_add_multiple_ii(struct list_head *to_list, | |||
3532 | 3553 | ||
3533 | list_for_each_entry(ha, from_list, list) { | 3554 | list_for_each_entry(ha, from_list, list) { |
3534 | type = addr_type ? addr_type : ha->type; | 3555 | type = addr_type ? addr_type : ha->type; |
3535 | err = __hw_addr_add(to_list, ha->addr, addr_len, type); | 3556 | err = __hw_addr_add(to_list, to_delta, ha->addr, |
3557 | addr_len, type); | ||
3536 | if (err) | 3558 | if (err) |
3537 | goto unroll; | 3559 | goto unroll; |
3538 | } | 3560 | } |
@@ -3543,27 +3565,69 @@ unroll: | |||
3543 | if (ha2 == ha) | 3565 | if (ha2 == ha) |
3544 | break; | 3566 | break; |
3545 | type = addr_type ? addr_type : ha2->type; | 3567 | type = addr_type ? addr_type : ha2->type; |
3546 | __hw_addr_del_ii(to_list, ha2->addr, addr_len, type, | 3568 | __hw_addr_del(to_list, to_delta, ha2->addr, |
3547 | ignore_index); | 3569 | addr_len, type); |
3548 | } | 3570 | } |
3549 | return err; | 3571 | return err; |
3550 | } | 3572 | } |
3551 | 3573 | ||
3552 | static void __hw_addr_del_multiple_ii(struct list_head *to_list, | 3574 | static void __hw_addr_del_multiple(struct list_head *to_list, int *to_delta, |
3553 | struct list_head *from_list, | 3575 | struct list_head *from_list, int addr_len, |
3554 | int addr_len, unsigned char addr_type, | 3576 | unsigned char addr_type) |
3555 | int ignore_index) | ||
3556 | { | 3577 | { |
3557 | struct netdev_hw_addr *ha; | 3578 | struct netdev_hw_addr *ha; |
3558 | unsigned char type; | 3579 | unsigned char type; |
3559 | 3580 | ||
3560 | list_for_each_entry(ha, from_list, list) { | 3581 | list_for_each_entry(ha, from_list, list) { |
3561 | type = addr_type ? addr_type : ha->type; | 3582 | type = addr_type ? addr_type : ha->type; |
3562 | __hw_addr_del_ii(to_list, ha->addr, addr_len, addr_type, | 3583 | __hw_addr_del(to_list, to_delta, ha->addr, |
3563 | ignore_index); | 3584 | addr_len, addr_type); |
3585 | } | ||
3586 | } | ||
3587 | |||
3588 | static int __hw_addr_sync(struct list_head *to_list, int *to_delta, | ||
3589 | struct list_head *from_list, int *from_delta, | ||
3590 | int addr_len) | ||
3591 | { | ||
3592 | int err = 0; | ||
3593 | struct netdev_hw_addr *ha, *tmp; | ||
3594 | |||
3595 | list_for_each_entry_safe(ha, tmp, from_list, list) { | ||
3596 | if (!ha->synced) { | ||
3597 | err = __hw_addr_add(to_list, to_delta, ha->addr, | ||
3598 | addr_len, ha->type); | ||
3599 | if (err) | ||
3600 | break; | ||
3601 | ha->synced = true; | ||
3602 | ha->refcount++; | ||
3603 | } else if (ha->refcount == 1) { | ||
3604 | __hw_addr_del(to_list, to_delta, ha->addr, | ||
3605 | addr_len, ha->type); | ||
3606 | __hw_addr_del(from_list, from_delta, ha->addr, | ||
3607 | addr_len, ha->type); | ||
3608 | } | ||
3609 | } | ||
3610 | return err; | ||
3611 | } | ||
3612 | |||
3613 | static void __hw_addr_unsync(struct list_head *to_list, int *to_delta, | ||
3614 | struct list_head *from_list, int *from_delta, | ||
3615 | int addr_len) | ||
3616 | { | ||
3617 | struct netdev_hw_addr *ha, *tmp; | ||
3618 | |||
3619 | list_for_each_entry_safe(ha, tmp, from_list, list) { | ||
3620 | if (ha->synced) { | ||
3621 | __hw_addr_del(to_list, to_delta, ha->addr, | ||
3622 | addr_len, ha->type); | ||
3623 | ha->synced = false; | ||
3624 | __hw_addr_del(from_list, from_delta, ha->addr, | ||
3625 | addr_len, ha->type); | ||
3626 | } | ||
3564 | } | 3627 | } |
3565 | } | 3628 | } |
3566 | 3629 | ||
3630 | |||
3567 | static void __hw_addr_flush(struct list_head *list) | 3631 | static void __hw_addr_flush(struct list_head *list) |
3568 | { | 3632 | { |
3569 | struct netdev_hw_addr *ha, *tmp; | 3633 | struct netdev_hw_addr *ha, *tmp; |
@@ -3593,8 +3657,8 @@ static int dev_addr_init(struct net_device *dev) | |||
3593 | /* rtnl_mutex must be held here */ | 3657 | /* rtnl_mutex must be held here */ |
3594 | 3658 | ||
3595 | INIT_LIST_HEAD(&dev->dev_addr_list); | 3659 | INIT_LIST_HEAD(&dev->dev_addr_list); |
3596 | memset(addr, 0, sizeof(*addr)); | 3660 | memset(addr, 0, sizeof(addr)); |
3597 | err = __hw_addr_add(&dev->dev_addr_list, addr, sizeof(*addr), | 3661 | err = __hw_addr_add(&dev->dev_addr_list, NULL, addr, sizeof(addr), |
3598 | NETDEV_HW_ADDR_T_LAN); | 3662 | NETDEV_HW_ADDR_T_LAN); |
3599 | if (!err) { | 3663 | if (!err) { |
3600 | /* | 3664 | /* |
@@ -3626,7 +3690,7 @@ int dev_addr_add(struct net_device *dev, unsigned char *addr, | |||
3626 | 3690 | ||
3627 | ASSERT_RTNL(); | 3691 | ASSERT_RTNL(); |
3628 | 3692 | ||
3629 | err = __hw_addr_add(&dev->dev_addr_list, addr, dev->addr_len, | 3693 | err = __hw_addr_add(&dev->dev_addr_list, NULL, addr, dev->addr_len, |
3630 | addr_type); | 3694 | addr_type); |
3631 | if (!err) | 3695 | if (!err) |
3632 | call_netdevice_notifiers(NETDEV_CHANGEADDR, dev); | 3696 | call_netdevice_notifiers(NETDEV_CHANGEADDR, dev); |
@@ -3649,11 +3713,20 @@ int dev_addr_del(struct net_device *dev, unsigned char *addr, | |||
3649 | unsigned char addr_type) | 3713 | unsigned char addr_type) |
3650 | { | 3714 | { |
3651 | int err; | 3715 | int err; |
3716 | struct netdev_hw_addr *ha; | ||
3652 | 3717 | ||
3653 | ASSERT_RTNL(); | 3718 | ASSERT_RTNL(); |
3654 | 3719 | ||
3655 | err = __hw_addr_del_ii(&dev->dev_addr_list, addr, dev->addr_len, | 3720 | /* |
3656 | addr_type, 0); | 3721 | * We can not remove the first address from the list because |
3722 | * dev->dev_addr points to that. | ||
3723 | */ | ||
3724 | ha = list_first_entry(&dev->dev_addr_list, struct netdev_hw_addr, list); | ||
3725 | if (ha->addr == dev->dev_addr && ha->refcount == 1) | ||
3726 | return -ENOENT; | ||
3727 | |||
3728 | err = __hw_addr_del(&dev->dev_addr_list, NULL, addr, dev->addr_len, | ||
3729 | addr_type); | ||
3657 | if (!err) | 3730 | if (!err) |
3658 | call_netdevice_notifiers(NETDEV_CHANGEADDR, dev); | 3731 | call_netdevice_notifiers(NETDEV_CHANGEADDR, dev); |
3659 | return err; | 3732 | return err; |
@@ -3680,9 +3753,9 @@ int dev_addr_add_multiple(struct net_device *to_dev, | |||
3680 | 3753 | ||
3681 | if (from_dev->addr_len != to_dev->addr_len) | 3754 | if (from_dev->addr_len != to_dev->addr_len) |
3682 | return -EINVAL; | 3755 | return -EINVAL; |
3683 | err = __hw_addr_add_multiple_ii(&to_dev->dev_addr_list, | 3756 | err = __hw_addr_add_multiple(&to_dev->dev_addr_list, NULL, |
3684 | &from_dev->dev_addr_list, | 3757 | &from_dev->dev_addr_list, |
3685 | to_dev->addr_len, addr_type, 0); | 3758 | to_dev->addr_len, addr_type); |
3686 | if (!err) | 3759 | if (!err) |
3687 | call_netdevice_notifiers(NETDEV_CHANGEADDR, to_dev); | 3760 | call_netdevice_notifiers(NETDEV_CHANGEADDR, to_dev); |
3688 | return err; | 3761 | return err; |
@@ -3707,9 +3780,9 @@ int dev_addr_del_multiple(struct net_device *to_dev, | |||
3707 | 3780 | ||
3708 | if (from_dev->addr_len != to_dev->addr_len) | 3781 | if (from_dev->addr_len != to_dev->addr_len) |
3709 | return -EINVAL; | 3782 | return -EINVAL; |
3710 | __hw_addr_del_multiple_ii(&to_dev->dev_addr_list, | 3783 | __hw_addr_del_multiple(&to_dev->dev_addr_list, NULL, |
3711 | &from_dev->dev_addr_list, | 3784 | &from_dev->dev_addr_list, |
3712 | to_dev->addr_len, addr_type, 0); | 3785 | to_dev->addr_len, addr_type); |
3713 | call_netdevice_notifiers(NETDEV_CHANGEADDR, to_dev); | 3786 | call_netdevice_notifiers(NETDEV_CHANGEADDR, to_dev); |
3714 | return 0; | 3787 | return 0; |
3715 | } | 3788 | } |
@@ -3779,24 +3852,22 @@ int __dev_addr_add(struct dev_addr_list **list, int *count, | |||
3779 | * dev_unicast_delete - Release secondary unicast address. | 3852 | * dev_unicast_delete - Release secondary unicast address. |
3780 | * @dev: device | 3853 | * @dev: device |
3781 | * @addr: address to delete | 3854 | * @addr: address to delete |
3782 | * @alen: length of @addr | ||
3783 | * | 3855 | * |
3784 | * Release reference to a secondary unicast address and remove it | 3856 | * Release reference to a secondary unicast address and remove it |
3785 | * from the device if the reference count drops to zero. | 3857 | * from the device if the reference count drops to zero. |
3786 | * | 3858 | * |
3787 | * The caller must hold the rtnl_mutex. | 3859 | * The caller must hold the rtnl_mutex. |
3788 | */ | 3860 | */ |
3789 | int dev_unicast_delete(struct net_device *dev, void *addr, int alen) | 3861 | int dev_unicast_delete(struct net_device *dev, void *addr) |
3790 | { | 3862 | { |
3791 | int err; | 3863 | int err; |
3792 | 3864 | ||
3793 | ASSERT_RTNL(); | 3865 | ASSERT_RTNL(); |
3794 | 3866 | ||
3795 | netif_addr_lock_bh(dev); | 3867 | err = __hw_addr_del(&dev->uc_list, &dev->uc_count, addr, |
3796 | err = __dev_addr_delete(&dev->uc_list, &dev->uc_count, addr, alen, 0); | 3868 | dev->addr_len, NETDEV_HW_ADDR_T_UNICAST); |
3797 | if (!err) | 3869 | if (!err) |
3798 | __dev_set_rx_mode(dev); | 3870 | __dev_set_rx_mode(dev); |
3799 | netif_addr_unlock_bh(dev); | ||
3800 | return err; | 3871 | return err; |
3801 | } | 3872 | } |
3802 | EXPORT_SYMBOL(dev_unicast_delete); | 3873 | EXPORT_SYMBOL(dev_unicast_delete); |
@@ -3805,24 +3876,22 @@ EXPORT_SYMBOL(dev_unicast_delete); | |||
3805 | * dev_unicast_add - add a secondary unicast address | 3876 | * dev_unicast_add - add a secondary unicast address |
3806 | * @dev: device | 3877 | * @dev: device |
3807 | * @addr: address to add | 3878 | * @addr: address to add |
3808 | * @alen: length of @addr | ||
3809 | * | 3879 | * |
3810 | * Add a secondary unicast address to the device or increase | 3880 | * Add a secondary unicast address to the device or increase |
3811 | * the reference count if it already exists. | 3881 | * the reference count if it already exists. |
3812 | * | 3882 | * |
3813 | * The caller must hold the rtnl_mutex. | 3883 | * The caller must hold the rtnl_mutex. |
3814 | */ | 3884 | */ |
3815 | int dev_unicast_add(struct net_device *dev, void *addr, int alen) | 3885 | int dev_unicast_add(struct net_device *dev, void *addr) |
3816 | { | 3886 | { |
3817 | int err; | 3887 | int err; |
3818 | 3888 | ||
3819 | ASSERT_RTNL(); | 3889 | ASSERT_RTNL(); |
3820 | 3890 | ||
3821 | netif_addr_lock_bh(dev); | 3891 | err = __hw_addr_add(&dev->uc_list, &dev->uc_count, addr, |
3822 | err = __dev_addr_add(&dev->uc_list, &dev->uc_count, addr, alen, 0); | 3892 | dev->addr_len, NETDEV_HW_ADDR_T_UNICAST); |
3823 | if (!err) | 3893 | if (!err) |
3824 | __dev_set_rx_mode(dev); | 3894 | __dev_set_rx_mode(dev); |
3825 | netif_addr_unlock_bh(dev); | ||
3826 | return err; | 3895 | return err; |
3827 | } | 3896 | } |
3828 | EXPORT_SYMBOL(dev_unicast_add); | 3897 | EXPORT_SYMBOL(dev_unicast_add); |
@@ -3879,8 +3948,7 @@ void __dev_addr_unsync(struct dev_addr_list **to, int *to_count, | |||
3879 | * @from: source device | 3948 | * @from: source device |
3880 | * | 3949 | * |
3881 | * Add newly added addresses to the destination device and release | 3950 | * Add newly added addresses to the destination device and release |
3882 | * addresses that have no users left. The source device must be | 3951 | * addresses that have no users left. |
3883 | * locked by netif_tx_lock_bh. | ||
3884 | * | 3952 | * |
3885 | * This function is intended to be called from the dev->set_rx_mode | 3953 | * This function is intended to be called from the dev->set_rx_mode |
3886 | * function of layered software devices. | 3954 | * function of layered software devices. |
@@ -3889,12 +3957,15 @@ int dev_unicast_sync(struct net_device *to, struct net_device *from) | |||
3889 | { | 3957 | { |
3890 | int err = 0; | 3958 | int err = 0; |
3891 | 3959 | ||
3892 | netif_addr_lock_bh(to); | 3960 | ASSERT_RTNL(); |
3893 | err = __dev_addr_sync(&to->uc_list, &to->uc_count, | 3961 | |
3894 | &from->uc_list, &from->uc_count); | 3962 | if (to->addr_len != from->addr_len) |
3963 | return -EINVAL; | ||
3964 | |||
3965 | err = __hw_addr_sync(&to->uc_list, &to->uc_count, | ||
3966 | &from->uc_list, &from->uc_count, to->addr_len); | ||
3895 | if (!err) | 3967 | if (!err) |
3896 | __dev_set_rx_mode(to); | 3968 | __dev_set_rx_mode(to); |
3897 | netif_addr_unlock_bh(to); | ||
3898 | return err; | 3969 | return err; |
3899 | } | 3970 | } |
3900 | EXPORT_SYMBOL(dev_unicast_sync); | 3971 | EXPORT_SYMBOL(dev_unicast_sync); |
@@ -3910,18 +3981,33 @@ EXPORT_SYMBOL(dev_unicast_sync); | |||
3910 | */ | 3981 | */ |
3911 | void dev_unicast_unsync(struct net_device *to, struct net_device *from) | 3982 | void dev_unicast_unsync(struct net_device *to, struct net_device *from) |
3912 | { | 3983 | { |
3913 | netif_addr_lock_bh(from); | 3984 | ASSERT_RTNL(); |
3914 | netif_addr_lock(to); | ||
3915 | 3985 | ||
3916 | __dev_addr_unsync(&to->uc_list, &to->uc_count, | 3986 | if (to->addr_len != from->addr_len) |
3917 | &from->uc_list, &from->uc_count); | 3987 | return; |
3918 | __dev_set_rx_mode(to); | ||
3919 | 3988 | ||
3920 | netif_addr_unlock(to); | 3989 | __hw_addr_unsync(&to->uc_list, &to->uc_count, |
3921 | netif_addr_unlock_bh(from); | 3990 | &from->uc_list, &from->uc_count, to->addr_len); |
3991 | __dev_set_rx_mode(to); | ||
3922 | } | 3992 | } |
3923 | EXPORT_SYMBOL(dev_unicast_unsync); | 3993 | EXPORT_SYMBOL(dev_unicast_unsync); |
3924 | 3994 | ||
3995 | static void dev_unicast_flush(struct net_device *dev) | ||
3996 | { | ||
3997 | /* rtnl_mutex must be held here */ | ||
3998 | |||
3999 | __hw_addr_flush(&dev->uc_list); | ||
4000 | dev->uc_count = 0; | ||
4001 | } | ||
4002 | |||
4003 | static void dev_unicast_init(struct net_device *dev) | ||
4004 | { | ||
4005 | /* rtnl_mutex must be held here */ | ||
4006 | |||
4007 | INIT_LIST_HEAD(&dev->uc_list); | ||
4008 | } | ||
4009 | |||
4010 | |||
3925 | static void __dev_addr_discard(struct dev_addr_list **list) | 4011 | static void __dev_addr_discard(struct dev_addr_list **list) |
3926 | { | 4012 | { |
3927 | struct dev_addr_list *tmp; | 4013 | struct dev_addr_list *tmp; |
@@ -3940,9 +4026,6 @@ static void dev_addr_discard(struct net_device *dev) | |||
3940 | { | 4026 | { |
3941 | netif_addr_lock_bh(dev); | 4027 | netif_addr_lock_bh(dev); |
3942 | 4028 | ||
3943 | __dev_addr_discard(&dev->uc_list); | ||
3944 | dev->uc_count = 0; | ||
3945 | |||
3946 | __dev_addr_discard(&dev->mc_list); | 4029 | __dev_addr_discard(&dev->mc_list); |
3947 | dev->mc_count = 0; | 4030 | dev->mc_count = 0; |
3948 | 4031 | ||
@@ -4535,6 +4618,7 @@ static void rollback_registered(struct net_device *dev) | |||
4535 | /* | 4618 | /* |
4536 | * Flush the unicast and multicast chains | 4619 | * Flush the unicast and multicast chains |
4537 | */ | 4620 | */ |
4621 | dev_unicast_flush(dev); | ||
4538 | dev_addr_discard(dev); | 4622 | dev_addr_discard(dev); |
4539 | 4623 | ||
4540 | if (dev->netdev_ops->ndo_uninit) | 4624 | if (dev->netdev_ops->ndo_uninit) |
@@ -4988,18 +5072,18 @@ struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name, | |||
4988 | struct netdev_queue *tx; | 5072 | struct netdev_queue *tx; |
4989 | struct net_device *dev; | 5073 | struct net_device *dev; |
4990 | size_t alloc_size; | 5074 | size_t alloc_size; |
4991 | void *p; | 5075 | struct net_device *p; |
4992 | 5076 | ||
4993 | BUG_ON(strlen(name) >= sizeof(dev->name)); | 5077 | BUG_ON(strlen(name) >= sizeof(dev->name)); |
4994 | 5078 | ||
4995 | alloc_size = sizeof(struct net_device); | 5079 | alloc_size = sizeof(struct net_device); |
4996 | if (sizeof_priv) { | 5080 | if (sizeof_priv) { |
4997 | /* ensure 32-byte alignment of private area */ | 5081 | /* ensure 32-byte alignment of private area */ |
4998 | alloc_size = (alloc_size + NETDEV_ALIGN_CONST) & ~NETDEV_ALIGN_CONST; | 5082 | alloc_size = ALIGN(alloc_size, NETDEV_ALIGN); |
4999 | alloc_size += sizeof_priv; | 5083 | alloc_size += sizeof_priv; |
5000 | } | 5084 | } |
5001 | /* ensure 32-byte alignment of whole construct */ | 5085 | /* ensure 32-byte alignment of whole construct */ |
5002 | alloc_size += NETDEV_ALIGN_CONST; | 5086 | alloc_size += NETDEV_ALIGN - 1; |
5003 | 5087 | ||
5004 | p = kzalloc(alloc_size, GFP_KERNEL); | 5088 | p = kzalloc(alloc_size, GFP_KERNEL); |
5005 | if (!p) { | 5089 | if (!p) { |
@@ -5014,13 +5098,14 @@ struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name, | |||
5014 | goto free_p; | 5098 | goto free_p; |
5015 | } | 5099 | } |
5016 | 5100 | ||
5017 | dev = (struct net_device *) | 5101 | dev = PTR_ALIGN(p, NETDEV_ALIGN); |
5018 | (((long)p + NETDEV_ALIGN_CONST) & ~NETDEV_ALIGN_CONST); | ||
5019 | dev->padded = (char *)dev - (char *)p; | 5102 | dev->padded = (char *)dev - (char *)p; |
5020 | 5103 | ||
5021 | if (dev_addr_init(dev)) | 5104 | if (dev_addr_init(dev)) |
5022 | goto free_tx; | 5105 | goto free_tx; |
5023 | 5106 | ||
5107 | dev_unicast_init(dev); | ||
5108 | |||
5024 | dev_net_set(dev, &init_net); | 5109 | dev_net_set(dev, &init_net); |
5025 | 5110 | ||
5026 | dev->_tx = tx; | 5111 | dev->_tx = tx; |
@@ -5224,6 +5309,7 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char | |||
5224 | /* | 5309 | /* |
5225 | * Flush the unicast and multicast chains | 5310 | * Flush the unicast and multicast chains |
5226 | */ | 5311 | */ |
5312 | dev_unicast_flush(dev); | ||
5227 | dev_addr_discard(dev); | 5313 | dev_addr_discard(dev); |
5228 | 5314 | ||
5229 | netdev_unregister_kobject(dev); | 5315 | netdev_unregister_kobject(dev); |
diff --git a/net/core/iovec.c b/net/core/iovec.c index 40a76ce19d9..16ad45d4882 100644 --- a/net/core/iovec.c +++ b/net/core/iovec.c | |||
@@ -112,9 +112,9 @@ int memcpy_toiovecend(const struct iovec *iov, unsigned char *kdata, | |||
112 | continue; | 112 | continue; |
113 | } | 113 | } |
114 | copy = min_t(unsigned int, iov->iov_len - offset, len); | 114 | copy = min_t(unsigned int, iov->iov_len - offset, len); |
115 | offset = 0; | 115 | if (copy_to_user(iov->iov_base + offset, kdata, copy)) |
116 | if (copy_to_user(iov->iov_base, kdata, copy)) | ||
117 | return -EFAULT; | 116 | return -EFAULT; |
117 | offset = 0; | ||
118 | kdata += copy; | 118 | kdata += copy; |
119 | len -= copy; | 119 | len -= copy; |
120 | } | 120 | } |
diff --git a/net/core/neighbour.c b/net/core/neighbour.c index a1cbce7fdae..163b4f5b036 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c | |||
@@ -771,6 +771,28 @@ static __inline__ int neigh_max_probes(struct neighbour *n) | |||
771 | p->ucast_probes + p->app_probes + p->mcast_probes); | 771 | p->ucast_probes + p->app_probes + p->mcast_probes); |
772 | } | 772 | } |
773 | 773 | ||
774 | static void neigh_invalidate(struct neighbour *neigh) | ||
775 | { | ||
776 | struct sk_buff *skb; | ||
777 | |||
778 | NEIGH_CACHE_STAT_INC(neigh->tbl, res_failed); | ||
779 | NEIGH_PRINTK2("neigh %p is failed.\n", neigh); | ||
780 | neigh->updated = jiffies; | ||
781 | |||
782 | /* It is very thin place. report_unreachable is very complicated | ||
783 | routine. Particularly, it can hit the same neighbour entry! | ||
784 | |||
785 | So that, we try to be accurate and avoid dead loop. --ANK | ||
786 | */ | ||
787 | while (neigh->nud_state == NUD_FAILED && | ||
788 | (skb = __skb_dequeue(&neigh->arp_queue)) != NULL) { | ||
789 | write_unlock(&neigh->lock); | ||
790 | neigh->ops->error_report(neigh, skb); | ||
791 | write_lock(&neigh->lock); | ||
792 | } | ||
793 | skb_queue_purge(&neigh->arp_queue); | ||
794 | } | ||
795 | |||
774 | /* Called when a timer expires for a neighbour entry. */ | 796 | /* Called when a timer expires for a neighbour entry. */ |
775 | 797 | ||
776 | static void neigh_timer_handler(unsigned long arg) | 798 | static void neigh_timer_handler(unsigned long arg) |
@@ -835,26 +857,9 @@ static void neigh_timer_handler(unsigned long arg) | |||
835 | 857 | ||
836 | if ((neigh->nud_state & (NUD_INCOMPLETE | NUD_PROBE)) && | 858 | if ((neigh->nud_state & (NUD_INCOMPLETE | NUD_PROBE)) && |
837 | atomic_read(&neigh->probes) >= neigh_max_probes(neigh)) { | 859 | atomic_read(&neigh->probes) >= neigh_max_probes(neigh)) { |
838 | struct sk_buff *skb; | ||
839 | |||
840 | neigh->nud_state = NUD_FAILED; | 860 | neigh->nud_state = NUD_FAILED; |
841 | neigh->updated = jiffies; | ||
842 | notify = 1; | 861 | notify = 1; |
843 | NEIGH_CACHE_STAT_INC(neigh->tbl, res_failed); | 862 | neigh_invalidate(neigh); |
844 | NEIGH_PRINTK2("neigh %p is failed.\n", neigh); | ||
845 | |||
846 | /* It is very thin place. report_unreachable is very complicated | ||
847 | routine. Particularly, it can hit the same neighbour entry! | ||
848 | |||
849 | So that, we try to be accurate and avoid dead loop. --ANK | ||
850 | */ | ||
851 | while (neigh->nud_state == NUD_FAILED && | ||
852 | (skb = __skb_dequeue(&neigh->arp_queue)) != NULL) { | ||
853 | write_unlock(&neigh->lock); | ||
854 | neigh->ops->error_report(neigh, skb); | ||
855 | write_lock(&neigh->lock); | ||
856 | } | ||
857 | skb_queue_purge(&neigh->arp_queue); | ||
858 | } | 863 | } |
859 | 864 | ||
860 | if (neigh->nud_state & NUD_IN_TIMER) { | 865 | if (neigh->nud_state & NUD_IN_TIMER) { |
@@ -1001,6 +1006,11 @@ int neigh_update(struct neighbour *neigh, const u8 *lladdr, u8 new, | |||
1001 | neigh->nud_state = new; | 1006 | neigh->nud_state = new; |
1002 | err = 0; | 1007 | err = 0; |
1003 | notify = old & NUD_VALID; | 1008 | notify = old & NUD_VALID; |
1009 | if ((old & (NUD_INCOMPLETE | NUD_PROBE)) && | ||
1010 | (new & NUD_FAILED)) { | ||
1011 | neigh_invalidate(neigh); | ||
1012 | notify = 1; | ||
1013 | } | ||
1004 | goto out; | 1014 | goto out; |
1005 | } | 1015 | } |
1006 | 1016 | ||
@@ -1088,8 +1098,8 @@ int neigh_update(struct neighbour *neigh, const u8 *lladdr, u8 new, | |||
1088 | struct neighbour *n1 = neigh; | 1098 | struct neighbour *n1 = neigh; |
1089 | write_unlock_bh(&neigh->lock); | 1099 | write_unlock_bh(&neigh->lock); |
1090 | /* On shaper/eql skb->dst->neighbour != neigh :( */ | 1100 | /* On shaper/eql skb->dst->neighbour != neigh :( */ |
1091 | if (skb->dst && skb->dst->neighbour) | 1101 | if (skb_dst(skb) && skb_dst(skb)->neighbour) |
1092 | n1 = skb->dst->neighbour; | 1102 | n1 = skb_dst(skb)->neighbour; |
1093 | n1->output(skb); | 1103 | n1->output(skb); |
1094 | write_lock_bh(&neigh->lock); | 1104 | write_lock_bh(&neigh->lock); |
1095 | } | 1105 | } |
@@ -1182,7 +1192,7 @@ EXPORT_SYMBOL(neigh_compat_output); | |||
1182 | 1192 | ||
1183 | int neigh_resolve_output(struct sk_buff *skb) | 1193 | int neigh_resolve_output(struct sk_buff *skb) |
1184 | { | 1194 | { |
1185 | struct dst_entry *dst = skb->dst; | 1195 | struct dst_entry *dst = skb_dst(skb); |
1186 | struct neighbour *neigh; | 1196 | struct neighbour *neigh; |
1187 | int rc = 0; | 1197 | int rc = 0; |
1188 | 1198 | ||
@@ -1229,7 +1239,7 @@ EXPORT_SYMBOL(neigh_resolve_output); | |||
1229 | int neigh_connected_output(struct sk_buff *skb) | 1239 | int neigh_connected_output(struct sk_buff *skb) |
1230 | { | 1240 | { |
1231 | int err; | 1241 | int err; |
1232 | struct dst_entry *dst = skb->dst; | 1242 | struct dst_entry *dst = skb_dst(skb); |
1233 | struct neighbour *neigh = dst->neighbour; | 1243 | struct neighbour *neigh = dst->neighbour; |
1234 | struct net_device *dev = neigh->dev; | 1244 | struct net_device *dev = neigh->dev; |
1235 | 1245 | ||
@@ -1298,8 +1308,7 @@ void pneigh_enqueue(struct neigh_table *tbl, struct neigh_parms *p, | |||
1298 | if (time_before(tbl->proxy_timer.expires, sched_next)) | 1308 | if (time_before(tbl->proxy_timer.expires, sched_next)) |
1299 | sched_next = tbl->proxy_timer.expires; | 1309 | sched_next = tbl->proxy_timer.expires; |
1300 | } | 1310 | } |
1301 | dst_release(skb->dst); | 1311 | skb_dst_drop(skb); |
1302 | skb->dst = NULL; | ||
1303 | dev_hold(skb->dev); | 1312 | dev_hold(skb->dev); |
1304 | __skb_queue_tail(&tbl->proxy_queue, skb); | 1313 | __skb_queue_tail(&tbl->proxy_queue, skb); |
1305 | mod_timer(&tbl->proxy_timer, sched_next); | 1314 | mod_timer(&tbl->proxy_timer, sched_next); |
diff --git a/net/core/pktgen.c b/net/core/pktgen.c index b8ccd3c88d6..19b8c20e98a 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c | |||
@@ -3691,8 +3691,7 @@ out1: | |||
3691 | #ifdef CONFIG_XFRM | 3691 | #ifdef CONFIG_XFRM |
3692 | free_SAs(pkt_dev); | 3692 | free_SAs(pkt_dev); |
3693 | #endif | 3693 | #endif |
3694 | if (pkt_dev->flows) | 3694 | vfree(pkt_dev->flows); |
3695 | vfree(pkt_dev->flows); | ||
3696 | kfree(pkt_dev); | 3695 | kfree(pkt_dev); |
3697 | return err; | 3696 | return err; |
3698 | } | 3697 | } |
@@ -3791,8 +3790,7 @@ static int pktgen_remove_device(struct pktgen_thread *t, | |||
3791 | #ifdef CONFIG_XFRM | 3790 | #ifdef CONFIG_XFRM |
3792 | free_SAs(pkt_dev); | 3791 | free_SAs(pkt_dev); |
3793 | #endif | 3792 | #endif |
3794 | if (pkt_dev->flows) | 3793 | vfree(pkt_dev->flows); |
3795 | vfree(pkt_dev->flows); | ||
3796 | kfree(pkt_dev); | 3794 | kfree(pkt_dev); |
3797 | return 0; | 3795 | return 0; |
3798 | } | 3796 | } |
diff --git a/net/core/skb_dma_map.c b/net/core/skb_dma_map.c index 86234923a3b..79687dfd695 100644 --- a/net/core/skb_dma_map.c +++ b/net/core/skb_dma_map.c | |||
@@ -20,7 +20,7 @@ int skb_dma_map(struct device *dev, struct sk_buff *skb, | |||
20 | if (dma_mapping_error(dev, map)) | 20 | if (dma_mapping_error(dev, map)) |
21 | goto out_err; | 21 | goto out_err; |
22 | 22 | ||
23 | sp->dma_maps[0] = map; | 23 | sp->dma_head = map; |
24 | for (i = 0; i < sp->nr_frags; i++) { | 24 | for (i = 0; i < sp->nr_frags; i++) { |
25 | skb_frag_t *fp = &sp->frags[i]; | 25 | skb_frag_t *fp = &sp->frags[i]; |
26 | 26 | ||
@@ -28,9 +28,8 @@ int skb_dma_map(struct device *dev, struct sk_buff *skb, | |||
28 | fp->size, dir); | 28 | fp->size, dir); |
29 | if (dma_mapping_error(dev, map)) | 29 | if (dma_mapping_error(dev, map)) |
30 | goto unwind; | 30 | goto unwind; |
31 | sp->dma_maps[i + 1] = map; | 31 | sp->dma_maps[i] = map; |
32 | } | 32 | } |
33 | sp->num_dma_maps = i + 1; | ||
34 | 33 | ||
35 | return 0; | 34 | return 0; |
36 | 35 | ||
@@ -38,10 +37,10 @@ unwind: | |||
38 | while (--i >= 0) { | 37 | while (--i >= 0) { |
39 | skb_frag_t *fp = &sp->frags[i]; | 38 | skb_frag_t *fp = &sp->frags[i]; |
40 | 39 | ||
41 | dma_unmap_page(dev, sp->dma_maps[i + 1], | 40 | dma_unmap_page(dev, sp->dma_maps[i], |
42 | fp->size, dir); | 41 | fp->size, dir); |
43 | } | 42 | } |
44 | dma_unmap_single(dev, sp->dma_maps[0], | 43 | dma_unmap_single(dev, sp->dma_head, |
45 | skb_headlen(skb), dir); | 44 | skb_headlen(skb), dir); |
46 | out_err: | 45 | out_err: |
47 | return -ENOMEM; | 46 | return -ENOMEM; |
@@ -54,12 +53,12 @@ void skb_dma_unmap(struct device *dev, struct sk_buff *skb, | |||
54 | struct skb_shared_info *sp = skb_shinfo(skb); | 53 | struct skb_shared_info *sp = skb_shinfo(skb); |
55 | int i; | 54 | int i; |
56 | 55 | ||
57 | dma_unmap_single(dev, sp->dma_maps[0], | 56 | dma_unmap_single(dev, sp->dma_head, |
58 | skb_headlen(skb), dir); | 57 | skb_headlen(skb), dir); |
59 | for (i = 0; i < sp->nr_frags; i++) { | 58 | for (i = 0; i < sp->nr_frags; i++) { |
60 | skb_frag_t *fp = &sp->frags[i]; | 59 | skb_frag_t *fp = &sp->frags[i]; |
61 | 60 | ||
62 | dma_unmap_page(dev, sp->dma_maps[i + 1], | 61 | dma_unmap_page(dev, sp->dma_maps[i], |
63 | fp->size, dir); | 62 | fp->size, dir); |
64 | } | 63 | } |
65 | } | 64 | } |
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 8e815e685f2..b94d777e3eb 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
@@ -210,7 +210,7 @@ struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask, | |||
210 | shinfo->gso_type = 0; | 210 | shinfo->gso_type = 0; |
211 | shinfo->ip6_frag_id = 0; | 211 | shinfo->ip6_frag_id = 0; |
212 | shinfo->tx_flags.flags = 0; | 212 | shinfo->tx_flags.flags = 0; |
213 | shinfo->frag_list = NULL; | 213 | skb_frag_list_init(skb); |
214 | memset(&shinfo->hwtstamps, 0, sizeof(shinfo->hwtstamps)); | 214 | memset(&shinfo->hwtstamps, 0, sizeof(shinfo->hwtstamps)); |
215 | 215 | ||
216 | if (fclone) { | 216 | if (fclone) { |
@@ -323,7 +323,7 @@ static void skb_clone_fraglist(struct sk_buff *skb) | |||
323 | { | 323 | { |
324 | struct sk_buff *list; | 324 | struct sk_buff *list; |
325 | 325 | ||
326 | for (list = skb_shinfo(skb)->frag_list; list; list = list->next) | 326 | skb_walk_frags(skb, list) |
327 | skb_get(list); | 327 | skb_get(list); |
328 | } | 328 | } |
329 | 329 | ||
@@ -338,7 +338,7 @@ static void skb_release_data(struct sk_buff *skb) | |||
338 | put_page(skb_shinfo(skb)->frags[i].page); | 338 | put_page(skb_shinfo(skb)->frags[i].page); |
339 | } | 339 | } |
340 | 340 | ||
341 | if (skb_shinfo(skb)->frag_list) | 341 | if (skb_has_frags(skb)) |
342 | skb_drop_fraglist(skb); | 342 | skb_drop_fraglist(skb); |
343 | 343 | ||
344 | kfree(skb->head); | 344 | kfree(skb->head); |
@@ -381,7 +381,7 @@ static void kfree_skbmem(struct sk_buff *skb) | |||
381 | 381 | ||
382 | static void skb_release_head_state(struct sk_buff *skb) | 382 | static void skb_release_head_state(struct sk_buff *skb) |
383 | { | 383 | { |
384 | dst_release(skb->dst); | 384 | skb_dst_drop(skb); |
385 | #ifdef CONFIG_XFRM | 385 | #ifdef CONFIG_XFRM |
386 | secpath_put(skb->sp); | 386 | secpath_put(skb->sp); |
387 | #endif | 387 | #endif |
@@ -503,7 +503,7 @@ int skb_recycle_check(struct sk_buff *skb, int skb_size) | |||
503 | shinfo->gso_type = 0; | 503 | shinfo->gso_type = 0; |
504 | shinfo->ip6_frag_id = 0; | 504 | shinfo->ip6_frag_id = 0; |
505 | shinfo->tx_flags.flags = 0; | 505 | shinfo->tx_flags.flags = 0; |
506 | shinfo->frag_list = NULL; | 506 | skb_frag_list_init(skb); |
507 | memset(&shinfo->hwtstamps, 0, sizeof(shinfo->hwtstamps)); | 507 | memset(&shinfo->hwtstamps, 0, sizeof(shinfo->hwtstamps)); |
508 | 508 | ||
509 | memset(skb, 0, offsetof(struct sk_buff, tail)); | 509 | memset(skb, 0, offsetof(struct sk_buff, tail)); |
@@ -521,7 +521,7 @@ static void __copy_skb_header(struct sk_buff *new, const struct sk_buff *old) | |||
521 | new->transport_header = old->transport_header; | 521 | new->transport_header = old->transport_header; |
522 | new->network_header = old->network_header; | 522 | new->network_header = old->network_header; |
523 | new->mac_header = old->mac_header; | 523 | new->mac_header = old->mac_header; |
524 | new->dst = dst_clone(old->dst); | 524 | skb_dst_set(new, dst_clone(skb_dst(old))); |
525 | #ifdef CONFIG_XFRM | 525 | #ifdef CONFIG_XFRM |
526 | new->sp = secpath_get(old->sp); | 526 | new->sp = secpath_get(old->sp); |
527 | #endif | 527 | #endif |
@@ -552,7 +552,6 @@ static void __copy_skb_header(struct sk_buff *new, const struct sk_buff *old) | |||
552 | new->vlan_tci = old->vlan_tci; | 552 | new->vlan_tci = old->vlan_tci; |
553 | #if defined(CONFIG_MAC80211) || defined(CONFIG_MAC80211_MODULE) | 553 | #if defined(CONFIG_MAC80211) || defined(CONFIG_MAC80211_MODULE) |
554 | new->do_not_encrypt = old->do_not_encrypt; | 554 | new->do_not_encrypt = old->do_not_encrypt; |
555 | new->requeue = old->requeue; | ||
556 | #endif | 555 | #endif |
557 | 556 | ||
558 | skb_copy_secmark(new, old); | 557 | skb_copy_secmark(new, old); |
@@ -758,7 +757,7 @@ struct sk_buff *pskb_copy(struct sk_buff *skb, gfp_t gfp_mask) | |||
758 | skb_shinfo(n)->nr_frags = i; | 757 | skb_shinfo(n)->nr_frags = i; |
759 | } | 758 | } |
760 | 759 | ||
761 | if (skb_shinfo(skb)->frag_list) { | 760 | if (skb_has_frags(skb)) { |
762 | skb_shinfo(n)->frag_list = skb_shinfo(skb)->frag_list; | 761 | skb_shinfo(n)->frag_list = skb_shinfo(skb)->frag_list; |
763 | skb_clone_fraglist(n); | 762 | skb_clone_fraglist(n); |
764 | } | 763 | } |
@@ -821,7 +820,7 @@ int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail, | |||
821 | for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) | 820 | for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) |
822 | get_page(skb_shinfo(skb)->frags[i].page); | 821 | get_page(skb_shinfo(skb)->frags[i].page); |
823 | 822 | ||
824 | if (skb_shinfo(skb)->frag_list) | 823 | if (skb_has_frags(skb)) |
825 | skb_clone_fraglist(skb); | 824 | skb_clone_fraglist(skb); |
826 | 825 | ||
827 | skb_release_data(skb); | 826 | skb_release_data(skb); |
@@ -1093,7 +1092,7 @@ drop_pages: | |||
1093 | for (; i < nfrags; i++) | 1092 | for (; i < nfrags; i++) |
1094 | put_page(skb_shinfo(skb)->frags[i].page); | 1093 | put_page(skb_shinfo(skb)->frags[i].page); |
1095 | 1094 | ||
1096 | if (skb_shinfo(skb)->frag_list) | 1095 | if (skb_has_frags(skb)) |
1097 | skb_drop_fraglist(skb); | 1096 | skb_drop_fraglist(skb); |
1098 | goto done; | 1097 | goto done; |
1099 | } | 1098 | } |
@@ -1188,7 +1187,7 @@ unsigned char *__pskb_pull_tail(struct sk_buff *skb, int delta) | |||
1188 | /* Optimization: no fragments, no reasons to preestimate | 1187 | /* Optimization: no fragments, no reasons to preestimate |
1189 | * size of pulled pages. Superb. | 1188 | * size of pulled pages. Superb. |
1190 | */ | 1189 | */ |
1191 | if (!skb_shinfo(skb)->frag_list) | 1190 | if (!skb_has_frags(skb)) |
1192 | goto pull_pages; | 1191 | goto pull_pages; |
1193 | 1192 | ||
1194 | /* Estimate size of pulled pages. */ | 1193 | /* Estimate size of pulled pages. */ |
@@ -1285,8 +1284,9 @@ EXPORT_SYMBOL(__pskb_pull_tail); | |||
1285 | 1284 | ||
1286 | int skb_copy_bits(const struct sk_buff *skb, int offset, void *to, int len) | 1285 | int skb_copy_bits(const struct sk_buff *skb, int offset, void *to, int len) |
1287 | { | 1286 | { |
1288 | int i, copy; | ||
1289 | int start = skb_headlen(skb); | 1287 | int start = skb_headlen(skb); |
1288 | struct sk_buff *frag_iter; | ||
1289 | int i, copy; | ||
1290 | 1290 | ||
1291 | if (offset > (int)skb->len - len) | 1291 | if (offset > (int)skb->len - len) |
1292 | goto fault; | 1292 | goto fault; |
@@ -1328,28 +1328,23 @@ int skb_copy_bits(const struct sk_buff *skb, int offset, void *to, int len) | |||
1328 | start = end; | 1328 | start = end; |
1329 | } | 1329 | } |
1330 | 1330 | ||
1331 | if (skb_shinfo(skb)->frag_list) { | 1331 | skb_walk_frags(skb, frag_iter) { |
1332 | struct sk_buff *list = skb_shinfo(skb)->frag_list; | 1332 | int end; |
1333 | 1333 | ||
1334 | for (; list; list = list->next) { | 1334 | WARN_ON(start > offset + len); |
1335 | int end; | 1335 | |
1336 | 1336 | end = start + frag_iter->len; | |
1337 | WARN_ON(start > offset + len); | 1337 | if ((copy = end - offset) > 0) { |
1338 | 1338 | if (copy > len) | |
1339 | end = start + list->len; | 1339 | copy = len; |
1340 | if ((copy = end - offset) > 0) { | 1340 | if (skb_copy_bits(frag_iter, offset - start, to, copy)) |
1341 | if (copy > len) | 1341 | goto fault; |
1342 | copy = len; | 1342 | if ((len -= copy) == 0) |
1343 | if (skb_copy_bits(list, offset - start, | 1343 | return 0; |
1344 | to, copy)) | 1344 | offset += copy; |
1345 | goto fault; | 1345 | to += copy; |
1346 | if ((len -= copy) == 0) | ||
1347 | return 0; | ||
1348 | offset += copy; | ||
1349 | to += copy; | ||
1350 | } | ||
1351 | start = end; | ||
1352 | } | 1346 | } |
1347 | start = end; | ||
1353 | } | 1348 | } |
1354 | if (!len) | 1349 | if (!len) |
1355 | return 0; | 1350 | return 0; |
@@ -1534,6 +1529,7 @@ int skb_splice_bits(struct sk_buff *skb, unsigned int offset, | |||
1534 | .ops = &sock_pipe_buf_ops, | 1529 | .ops = &sock_pipe_buf_ops, |
1535 | .spd_release = sock_spd_release, | 1530 | .spd_release = sock_spd_release, |
1536 | }; | 1531 | }; |
1532 | struct sk_buff *frag_iter; | ||
1537 | struct sock *sk = skb->sk; | 1533 | struct sock *sk = skb->sk; |
1538 | 1534 | ||
1539 | /* | 1535 | /* |
@@ -1548,13 +1544,11 @@ int skb_splice_bits(struct sk_buff *skb, unsigned int offset, | |||
1548 | /* | 1544 | /* |
1549 | * now see if we have a frag_list to map | 1545 | * now see if we have a frag_list to map |
1550 | */ | 1546 | */ |
1551 | if (skb_shinfo(skb)->frag_list) { | 1547 | skb_walk_frags(skb, frag_iter) { |
1552 | struct sk_buff *list = skb_shinfo(skb)->frag_list; | 1548 | if (!tlen) |
1553 | 1549 | break; | |
1554 | for (; list && tlen; list = list->next) { | 1550 | if (__skb_splice_bits(frag_iter, &offset, &tlen, &spd, sk)) |
1555 | if (__skb_splice_bits(list, &offset, &tlen, &spd, sk)) | 1551 | break; |
1556 | break; | ||
1557 | } | ||
1558 | } | 1552 | } |
1559 | 1553 | ||
1560 | done: | 1554 | done: |
@@ -1593,8 +1587,9 @@ done: | |||
1593 | 1587 | ||
1594 | int skb_store_bits(struct sk_buff *skb, int offset, const void *from, int len) | 1588 | int skb_store_bits(struct sk_buff *skb, int offset, const void *from, int len) |
1595 | { | 1589 | { |
1596 | int i, copy; | ||
1597 | int start = skb_headlen(skb); | 1590 | int start = skb_headlen(skb); |
1591 | struct sk_buff *frag_iter; | ||
1592 | int i, copy; | ||
1598 | 1593 | ||
1599 | if (offset > (int)skb->len - len) | 1594 | if (offset > (int)skb->len - len) |
1600 | goto fault; | 1595 | goto fault; |
@@ -1635,28 +1630,24 @@ int skb_store_bits(struct sk_buff *skb, int offset, const void *from, int len) | |||
1635 | start = end; | 1630 | start = end; |
1636 | } | 1631 | } |
1637 | 1632 | ||
1638 | if (skb_shinfo(skb)->frag_list) { | 1633 | skb_walk_frags(skb, frag_iter) { |
1639 | struct sk_buff *list = skb_shinfo(skb)->frag_list; | 1634 | int end; |
1640 | 1635 | ||
1641 | for (; list; list = list->next) { | 1636 | WARN_ON(start > offset + len); |
1642 | int end; | 1637 | |
1643 | 1638 | end = start + frag_iter->len; | |
1644 | WARN_ON(start > offset + len); | 1639 | if ((copy = end - offset) > 0) { |
1645 | 1640 | if (copy > len) | |
1646 | end = start + list->len; | 1641 | copy = len; |
1647 | if ((copy = end - offset) > 0) { | 1642 | if (skb_store_bits(frag_iter, offset - start, |
1648 | if (copy > len) | 1643 | from, copy)) |
1649 | copy = len; | 1644 | goto fault; |
1650 | if (skb_store_bits(list, offset - start, | 1645 | if ((len -= copy) == 0) |
1651 | from, copy)) | 1646 | return 0; |
1652 | goto fault; | 1647 | offset += copy; |
1653 | if ((len -= copy) == 0) | 1648 | from += copy; |
1654 | return 0; | ||
1655 | offset += copy; | ||
1656 | from += copy; | ||
1657 | } | ||
1658 | start = end; | ||
1659 | } | 1649 | } |
1650 | start = end; | ||
1660 | } | 1651 | } |
1661 | if (!len) | 1652 | if (!len) |
1662 | return 0; | 1653 | return 0; |
@@ -1673,6 +1664,7 @@ __wsum skb_checksum(const struct sk_buff *skb, int offset, | |||
1673 | { | 1664 | { |
1674 | int start = skb_headlen(skb); | 1665 | int start = skb_headlen(skb); |
1675 | int i, copy = start - offset; | 1666 | int i, copy = start - offset; |
1667 | struct sk_buff *frag_iter; | ||
1676 | int pos = 0; | 1668 | int pos = 0; |
1677 | 1669 | ||
1678 | /* Checksum header. */ | 1670 | /* Checksum header. */ |
@@ -1712,29 +1704,25 @@ __wsum skb_checksum(const struct sk_buff *skb, int offset, | |||
1712 | start = end; | 1704 | start = end; |
1713 | } | 1705 | } |
1714 | 1706 | ||
1715 | if (skb_shinfo(skb)->frag_list) { | 1707 | skb_walk_frags(skb, frag_iter) { |
1716 | struct sk_buff *list = skb_shinfo(skb)->frag_list; | 1708 | int end; |
1717 | 1709 | ||
1718 | for (; list; list = list->next) { | 1710 | WARN_ON(start > offset + len); |
1719 | int end; | 1711 | |
1720 | 1712 | end = start + frag_iter->len; | |
1721 | WARN_ON(start > offset + len); | 1713 | if ((copy = end - offset) > 0) { |
1722 | 1714 | __wsum csum2; | |
1723 | end = start + list->len; | 1715 | if (copy > len) |
1724 | if ((copy = end - offset) > 0) { | 1716 | copy = len; |
1725 | __wsum csum2; | 1717 | csum2 = skb_checksum(frag_iter, offset - start, |
1726 | if (copy > len) | 1718 | copy, 0); |
1727 | copy = len; | 1719 | csum = csum_block_add(csum, csum2, pos); |
1728 | csum2 = skb_checksum(list, offset - start, | 1720 | if ((len -= copy) == 0) |
1729 | copy, 0); | 1721 | return csum; |
1730 | csum = csum_block_add(csum, csum2, pos); | 1722 | offset += copy; |
1731 | if ((len -= copy) == 0) | 1723 | pos += copy; |
1732 | return csum; | ||
1733 | offset += copy; | ||
1734 | pos += copy; | ||
1735 | } | ||
1736 | start = end; | ||
1737 | } | 1724 | } |
1725 | start = end; | ||
1738 | } | 1726 | } |
1739 | BUG_ON(len); | 1727 | BUG_ON(len); |
1740 | 1728 | ||
@@ -1749,6 +1737,7 @@ __wsum skb_copy_and_csum_bits(const struct sk_buff *skb, int offset, | |||
1749 | { | 1737 | { |
1750 | int start = skb_headlen(skb); | 1738 | int start = skb_headlen(skb); |
1751 | int i, copy = start - offset; | 1739 | int i, copy = start - offset; |
1740 | struct sk_buff *frag_iter; | ||
1752 | int pos = 0; | 1741 | int pos = 0; |
1753 | 1742 | ||
1754 | /* Copy header. */ | 1743 | /* Copy header. */ |
@@ -1793,31 +1782,27 @@ __wsum skb_copy_and_csum_bits(const struct sk_buff *skb, int offset, | |||
1793 | start = end; | 1782 | start = end; |
1794 | } | 1783 | } |
1795 | 1784 | ||
1796 | if (skb_shinfo(skb)->frag_list) { | 1785 | skb_walk_frags(skb, frag_iter) { |
1797 | struct sk_buff *list = skb_shinfo(skb)->frag_list; | 1786 | __wsum csum2; |
1787 | int end; | ||
1798 | 1788 | ||
1799 | for (; list; list = list->next) { | 1789 | WARN_ON(start > offset + len); |
1800 | __wsum csum2; | 1790 | |
1801 | int end; | 1791 | end = start + frag_iter->len; |
1802 | 1792 | if ((copy = end - offset) > 0) { | |
1803 | WARN_ON(start > offset + len); | 1793 | if (copy > len) |
1804 | 1794 | copy = len; | |
1805 | end = start + list->len; | 1795 | csum2 = skb_copy_and_csum_bits(frag_iter, |
1806 | if ((copy = end - offset) > 0) { | 1796 | offset - start, |
1807 | if (copy > len) | 1797 | to, copy, 0); |
1808 | copy = len; | 1798 | csum = csum_block_add(csum, csum2, pos); |
1809 | csum2 = skb_copy_and_csum_bits(list, | 1799 | if ((len -= copy) == 0) |
1810 | offset - start, | 1800 | return csum; |
1811 | to, copy, 0); | 1801 | offset += copy; |
1812 | csum = csum_block_add(csum, csum2, pos); | 1802 | to += copy; |
1813 | if ((len -= copy) == 0) | 1803 | pos += copy; |
1814 | return csum; | ||
1815 | offset += copy; | ||
1816 | to += copy; | ||
1817 | pos += copy; | ||
1818 | } | ||
1819 | start = end; | ||
1820 | } | 1804 | } |
1805 | start = end; | ||
1821 | } | 1806 | } |
1822 | BUG_ON(len); | 1807 | BUG_ON(len); |
1823 | return csum; | 1808 | return csum; |
@@ -2327,8 +2312,7 @@ next_skb: | |||
2327 | st->frag_data = NULL; | 2312 | st->frag_data = NULL; |
2328 | } | 2313 | } |
2329 | 2314 | ||
2330 | if (st->root_skb == st->cur_skb && | 2315 | if (st->root_skb == st->cur_skb && skb_has_frags(st->root_skb)) { |
2331 | skb_shinfo(st->root_skb)->frag_list) { | ||
2332 | st->cur_skb = skb_shinfo(st->root_skb)->frag_list; | 2316 | st->cur_skb = skb_shinfo(st->root_skb)->frag_list; |
2333 | st->frag_idx = 0; | 2317 | st->frag_idx = 0; |
2334 | goto next_skb; | 2318 | goto next_skb; |
@@ -2639,7 +2623,7 @@ struct sk_buff *skb_segment(struct sk_buff *skb, int features) | |||
2639 | } else | 2623 | } else |
2640 | skb_get(fskb2); | 2624 | skb_get(fskb2); |
2641 | 2625 | ||
2642 | BUG_ON(skb_shinfo(nskb)->frag_list); | 2626 | SKB_FRAG_ASSERT(nskb); |
2643 | skb_shinfo(nskb)->frag_list = fskb2; | 2627 | skb_shinfo(nskb)->frag_list = fskb2; |
2644 | } | 2628 | } |
2645 | 2629 | ||
@@ -2796,6 +2780,7 @@ __skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, int len) | |||
2796 | { | 2780 | { |
2797 | int start = skb_headlen(skb); | 2781 | int start = skb_headlen(skb); |
2798 | int i, copy = start - offset; | 2782 | int i, copy = start - offset; |
2783 | struct sk_buff *frag_iter; | ||
2799 | int elt = 0; | 2784 | int elt = 0; |
2800 | 2785 | ||
2801 | if (copy > 0) { | 2786 | if (copy > 0) { |
@@ -2829,26 +2814,22 @@ __skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, int len) | |||
2829 | start = end; | 2814 | start = end; |
2830 | } | 2815 | } |
2831 | 2816 | ||
2832 | if (skb_shinfo(skb)->frag_list) { | 2817 | skb_walk_frags(skb, frag_iter) { |
2833 | struct sk_buff *list = skb_shinfo(skb)->frag_list; | 2818 | int end; |
2834 | |||
2835 | for (; list; list = list->next) { | ||
2836 | int end; | ||
2837 | 2819 | ||
2838 | WARN_ON(start > offset + len); | 2820 | WARN_ON(start > offset + len); |
2839 | 2821 | ||
2840 | end = start + list->len; | 2822 | end = start + frag_iter->len; |
2841 | if ((copy = end - offset) > 0) { | 2823 | if ((copy = end - offset) > 0) { |
2842 | if (copy > len) | 2824 | if (copy > len) |
2843 | copy = len; | 2825 | copy = len; |
2844 | elt += __skb_to_sgvec(list, sg+elt, offset - start, | 2826 | elt += __skb_to_sgvec(frag_iter, sg+elt, offset - start, |
2845 | copy); | 2827 | copy); |
2846 | if ((len -= copy) == 0) | 2828 | if ((len -= copy) == 0) |
2847 | return elt; | 2829 | return elt; |
2848 | offset += copy; | 2830 | offset += copy; |
2849 | } | ||
2850 | start = end; | ||
2851 | } | 2831 | } |
2832 | start = end; | ||
2852 | } | 2833 | } |
2853 | BUG_ON(len); | 2834 | BUG_ON(len); |
2854 | return elt; | 2835 | return elt; |
@@ -2896,7 +2877,7 @@ int skb_cow_data(struct sk_buff *skb, int tailbits, struct sk_buff **trailer) | |||
2896 | return -ENOMEM; | 2877 | return -ENOMEM; |
2897 | 2878 | ||
2898 | /* Easy case. Most of packets will go this way. */ | 2879 | /* Easy case. Most of packets will go this way. */ |
2899 | if (!skb_shinfo(skb)->frag_list) { | 2880 | if (!skb_has_frags(skb)) { |
2900 | /* A little of trouble, not enough of space for trailer. | 2881 | /* A little of trouble, not enough of space for trailer. |
2901 | * This should not happen, when stack is tuned to generate | 2882 | * This should not happen, when stack is tuned to generate |
2902 | * good frames. OK, on miss we reallocate and reserve even more | 2883 | * good frames. OK, on miss we reallocate and reserve even more |
@@ -2931,7 +2912,7 @@ int skb_cow_data(struct sk_buff *skb, int tailbits, struct sk_buff **trailer) | |||
2931 | 2912 | ||
2932 | if (skb1->next == NULL && tailbits) { | 2913 | if (skb1->next == NULL && tailbits) { |
2933 | if (skb_shinfo(skb1)->nr_frags || | 2914 | if (skb_shinfo(skb1)->nr_frags || |
2934 | skb_shinfo(skb1)->frag_list || | 2915 | skb_has_frags(skb1) || |
2935 | skb_tailroom(skb1) < tailbits) | 2916 | skb_tailroom(skb1) < tailbits) |
2936 | ntail = tailbits + 128; | 2917 | ntail = tailbits + 128; |
2937 | } | 2918 | } |
@@ -2940,7 +2921,7 @@ int skb_cow_data(struct sk_buff *skb, int tailbits, struct sk_buff **trailer) | |||
2940 | skb_cloned(skb1) || | 2921 | skb_cloned(skb1) || |
2941 | ntail || | 2922 | ntail || |
2942 | skb_shinfo(skb1)->nr_frags || | 2923 | skb_shinfo(skb1)->nr_frags || |
2943 | skb_shinfo(skb1)->frag_list) { | 2924 | skb_has_frags(skb1)) { |
2944 | struct sk_buff *skb2; | 2925 | struct sk_buff *skb2; |
2945 | 2926 | ||
2946 | /* Fuck, we are miserable poor guys... */ | 2927 | /* Fuck, we are miserable poor guys... */ |
@@ -3026,12 +3007,12 @@ EXPORT_SYMBOL_GPL(skb_tstamp_tx); | |||
3026 | */ | 3007 | */ |
3027 | bool skb_partial_csum_set(struct sk_buff *skb, u16 start, u16 off) | 3008 | bool skb_partial_csum_set(struct sk_buff *skb, u16 start, u16 off) |
3028 | { | 3009 | { |
3029 | if (unlikely(start > skb->len - 2) || | 3010 | if (unlikely(start > skb_headlen(skb)) || |
3030 | unlikely((int)start + off > skb->len - 2)) { | 3011 | unlikely((int)start + off > skb_headlen(skb) - 2)) { |
3031 | if (net_ratelimit()) | 3012 | if (net_ratelimit()) |
3032 | printk(KERN_WARNING | 3013 | printk(KERN_WARNING |
3033 | "bad partial csum: csum=%u/%u len=%u\n", | 3014 | "bad partial csum: csum=%u/%u len=%u\n", |
3034 | start, off, skb->len); | 3015 | start, off, skb_headlen(skb)); |
3035 | return false; | 3016 | return false; |
3036 | } | 3017 | } |
3037 | skb->ip_summed = CHECKSUM_PARTIAL; | 3018 | skb->ip_summed = CHECKSUM_PARTIAL; |
diff --git a/net/core/sock.c b/net/core/sock.c index 7dbf3ffb35c..06e26b77ad9 100644 --- a/net/core/sock.c +++ b/net/core/sock.c | |||
@@ -155,6 +155,7 @@ static const char *af_family_key_strings[AF_MAX+1] = { | |||
155 | "sk_lock-27" , "sk_lock-28" , "sk_lock-AF_CAN" , | 155 | "sk_lock-27" , "sk_lock-28" , "sk_lock-AF_CAN" , |
156 | "sk_lock-AF_TIPC" , "sk_lock-AF_BLUETOOTH", "sk_lock-IUCV" , | 156 | "sk_lock-AF_TIPC" , "sk_lock-AF_BLUETOOTH", "sk_lock-IUCV" , |
157 | "sk_lock-AF_RXRPC" , "sk_lock-AF_ISDN" , "sk_lock-AF_PHONET" , | 157 | "sk_lock-AF_RXRPC" , "sk_lock-AF_ISDN" , "sk_lock-AF_PHONET" , |
158 | "sk_lock-AF_IEEE802154", | ||
158 | "sk_lock-AF_MAX" | 159 | "sk_lock-AF_MAX" |
159 | }; | 160 | }; |
160 | static const char *af_family_slock_key_strings[AF_MAX+1] = { | 161 | static const char *af_family_slock_key_strings[AF_MAX+1] = { |
@@ -170,6 +171,7 @@ static const char *af_family_slock_key_strings[AF_MAX+1] = { | |||
170 | "slock-27" , "slock-28" , "slock-AF_CAN" , | 171 | "slock-27" , "slock-28" , "slock-AF_CAN" , |
171 | "slock-AF_TIPC" , "slock-AF_BLUETOOTH", "slock-AF_IUCV" , | 172 | "slock-AF_TIPC" , "slock-AF_BLUETOOTH", "slock-AF_IUCV" , |
172 | "slock-AF_RXRPC" , "slock-AF_ISDN" , "slock-AF_PHONET" , | 173 | "slock-AF_RXRPC" , "slock-AF_ISDN" , "slock-AF_PHONET" , |
174 | "slock-AF_IEEE802154", | ||
173 | "slock-AF_MAX" | 175 | "slock-AF_MAX" |
174 | }; | 176 | }; |
175 | static const char *af_family_clock_key_strings[AF_MAX+1] = { | 177 | static const char *af_family_clock_key_strings[AF_MAX+1] = { |
@@ -185,6 +187,7 @@ static const char *af_family_clock_key_strings[AF_MAX+1] = { | |||
185 | "clock-27" , "clock-28" , "clock-AF_CAN" , | 187 | "clock-27" , "clock-28" , "clock-AF_CAN" , |
186 | "clock-AF_TIPC" , "clock-AF_BLUETOOTH", "clock-AF_IUCV" , | 188 | "clock-AF_TIPC" , "clock-AF_BLUETOOTH", "clock-AF_IUCV" , |
187 | "clock-AF_RXRPC" , "clock-AF_ISDN" , "clock-AF_PHONET" , | 189 | "clock-AF_RXRPC" , "clock-AF_ISDN" , "clock-AF_PHONET" , |
190 | "clock-AF_IEEE802154", | ||
188 | "clock-AF_MAX" | 191 | "clock-AF_MAX" |
189 | }; | 192 | }; |
190 | 193 | ||
@@ -212,6 +215,7 @@ __u32 sysctl_rmem_default __read_mostly = SK_RMEM_MAX; | |||
212 | 215 | ||
213 | /* Maximal space eaten by iovec or ancilliary data plus some space */ | 216 | /* Maximal space eaten by iovec or ancilliary data plus some space */ |
214 | int sysctl_optmem_max __read_mostly = sizeof(unsigned long)*(2*UIO_MAXIOV+512); | 217 | int sysctl_optmem_max __read_mostly = sizeof(unsigned long)*(2*UIO_MAXIOV+512); |
218 | EXPORT_SYMBOL(sysctl_optmem_max); | ||
215 | 219 | ||
216 | static int sock_set_timeout(long *timeo_p, char __user *optval, int optlen) | 220 | static int sock_set_timeout(long *timeo_p, char __user *optval, int optlen) |
217 | { | 221 | { |
@@ -444,7 +448,7 @@ static inline void sock_valbool_flag(struct sock *sk, int bit, int valbool) | |||
444 | int sock_setsockopt(struct socket *sock, int level, int optname, | 448 | int sock_setsockopt(struct socket *sock, int level, int optname, |
445 | char __user *optval, int optlen) | 449 | char __user *optval, int optlen) |
446 | { | 450 | { |
447 | struct sock *sk=sock->sk; | 451 | struct sock *sk = sock->sk; |
448 | int val; | 452 | int val; |
449 | int valbool; | 453 | int valbool; |
450 | struct linger ling; | 454 | struct linger ling; |
@@ -463,15 +467,15 @@ int sock_setsockopt(struct socket *sock, int level, int optname, | |||
463 | if (get_user(val, (int __user *)optval)) | 467 | if (get_user(val, (int __user *)optval)) |
464 | return -EFAULT; | 468 | return -EFAULT; |
465 | 469 | ||
466 | valbool = val?1:0; | 470 | valbool = val ? 1 : 0; |
467 | 471 | ||
468 | lock_sock(sk); | 472 | lock_sock(sk); |
469 | 473 | ||
470 | switch(optname) { | 474 | switch (optname) { |
471 | case SO_DEBUG: | 475 | case SO_DEBUG: |
472 | if (val && !capable(CAP_NET_ADMIN)) { | 476 | if (val && !capable(CAP_NET_ADMIN)) |
473 | ret = -EACCES; | 477 | ret = -EACCES; |
474 | } else | 478 | else |
475 | sock_valbool_flag(sk, SOCK_DBG, valbool); | 479 | sock_valbool_flag(sk, SOCK_DBG, valbool); |
476 | break; | 480 | break; |
477 | case SO_REUSEADDR: | 481 | case SO_REUSEADDR: |
@@ -582,7 +586,7 @@ set_rcvbuf: | |||
582 | ret = -EINVAL; /* 1003.1g */ | 586 | ret = -EINVAL; /* 1003.1g */ |
583 | break; | 587 | break; |
584 | } | 588 | } |
585 | if (copy_from_user(&ling,optval,sizeof(ling))) { | 589 | if (copy_from_user(&ling, optval, sizeof(ling))) { |
586 | ret = -EFAULT; | 590 | ret = -EFAULT; |
587 | break; | 591 | break; |
588 | } | 592 | } |
@@ -690,9 +694,8 @@ set_rcvbuf: | |||
690 | case SO_MARK: | 694 | case SO_MARK: |
691 | if (!capable(CAP_NET_ADMIN)) | 695 | if (!capable(CAP_NET_ADMIN)) |
692 | ret = -EPERM; | 696 | ret = -EPERM; |
693 | else { | 697 | else |
694 | sk->sk_mark = val; | 698 | sk->sk_mark = val; |
695 | } | ||
696 | break; | 699 | break; |
697 | 700 | ||
698 | /* We implement the SO_SNDLOWAT etc to | 701 | /* We implement the SO_SNDLOWAT etc to |
@@ -704,6 +707,7 @@ set_rcvbuf: | |||
704 | release_sock(sk); | 707 | release_sock(sk); |
705 | return ret; | 708 | return ret; |
706 | } | 709 | } |
710 | EXPORT_SYMBOL(sock_setsockopt); | ||
707 | 711 | ||
708 | 712 | ||
709 | int sock_getsockopt(struct socket *sock, int level, int optname, | 713 | int sock_getsockopt(struct socket *sock, int level, int optname, |
@@ -727,7 +731,7 @@ int sock_getsockopt(struct socket *sock, int level, int optname, | |||
727 | 731 | ||
728 | memset(&v, 0, sizeof(v)); | 732 | memset(&v, 0, sizeof(v)); |
729 | 733 | ||
730 | switch(optname) { | 734 | switch (optname) { |
731 | case SO_DEBUG: | 735 | case SO_DEBUG: |
732 | v.val = sock_flag(sk, SOCK_DBG); | 736 | v.val = sock_flag(sk, SOCK_DBG); |
733 | break; | 737 | break; |
@@ -762,7 +766,7 @@ int sock_getsockopt(struct socket *sock, int level, int optname, | |||
762 | 766 | ||
763 | case SO_ERROR: | 767 | case SO_ERROR: |
764 | v.val = -sock_error(sk); | 768 | v.val = -sock_error(sk); |
765 | if (v.val==0) | 769 | if (v.val == 0) |
766 | v.val = xchg(&sk->sk_err_soft, 0); | 770 | v.val = xchg(&sk->sk_err_soft, 0); |
767 | break; | 771 | break; |
768 | 772 | ||
@@ -816,7 +820,7 @@ int sock_getsockopt(struct socket *sock, int level, int optname, | |||
816 | break; | 820 | break; |
817 | 821 | ||
818 | case SO_RCVTIMEO: | 822 | case SO_RCVTIMEO: |
819 | lv=sizeof(struct timeval); | 823 | lv = sizeof(struct timeval); |
820 | if (sk->sk_rcvtimeo == MAX_SCHEDULE_TIMEOUT) { | 824 | if (sk->sk_rcvtimeo == MAX_SCHEDULE_TIMEOUT) { |
821 | v.tm.tv_sec = 0; | 825 | v.tm.tv_sec = 0; |
822 | v.tm.tv_usec = 0; | 826 | v.tm.tv_usec = 0; |
@@ -827,7 +831,7 @@ int sock_getsockopt(struct socket *sock, int level, int optname, | |||
827 | break; | 831 | break; |
828 | 832 | ||
829 | case SO_SNDTIMEO: | 833 | case SO_SNDTIMEO: |
830 | lv=sizeof(struct timeval); | 834 | lv = sizeof(struct timeval); |
831 | if (sk->sk_sndtimeo == MAX_SCHEDULE_TIMEOUT) { | 835 | if (sk->sk_sndtimeo == MAX_SCHEDULE_TIMEOUT) { |
832 | v.tm.tv_sec = 0; | 836 | v.tm.tv_sec = 0; |
833 | v.tm.tv_usec = 0; | 837 | v.tm.tv_usec = 0; |
@@ -842,7 +846,7 @@ int sock_getsockopt(struct socket *sock, int level, int optname, | |||
842 | break; | 846 | break; |
843 | 847 | ||
844 | case SO_SNDLOWAT: | 848 | case SO_SNDLOWAT: |
845 | v.val=1; | 849 | v.val = 1; |
846 | break; | 850 | break; |
847 | 851 | ||
848 | case SO_PASSCRED: | 852 | case SO_PASSCRED: |
@@ -1002,8 +1006,9 @@ struct sock *sk_alloc(struct net *net, int family, gfp_t priority, | |||
1002 | 1006 | ||
1003 | return sk; | 1007 | return sk; |
1004 | } | 1008 | } |
1009 | EXPORT_SYMBOL(sk_alloc); | ||
1005 | 1010 | ||
1006 | void sk_free(struct sock *sk) | 1011 | static void __sk_free(struct sock *sk) |
1007 | { | 1012 | { |
1008 | struct sk_filter *filter; | 1013 | struct sk_filter *filter; |
1009 | 1014 | ||
@@ -1027,6 +1032,18 @@ void sk_free(struct sock *sk) | |||
1027 | sk_prot_free(sk->sk_prot_creator, sk); | 1032 | sk_prot_free(sk->sk_prot_creator, sk); |
1028 | } | 1033 | } |
1029 | 1034 | ||
1035 | void sk_free(struct sock *sk) | ||
1036 | { | ||
1037 | /* | ||
1038 | * We substract one from sk_wmem_alloc and can know if | ||
1039 | * some packets are still in some tx queue. | ||
1040 | * If not null, sock_wfree() will call __sk_free(sk) later | ||
1041 | */ | ||
1042 | if (atomic_dec_and_test(&sk->sk_wmem_alloc)) | ||
1043 | __sk_free(sk); | ||
1044 | } | ||
1045 | EXPORT_SYMBOL(sk_free); | ||
1046 | |||
1030 | /* | 1047 | /* |
1031 | * Last sock_put should drop referrence to sk->sk_net. It has already | 1048 | * Last sock_put should drop referrence to sk->sk_net. It has already |
1032 | * been dropped in sk_change_net. Taking referrence to stopping namespace | 1049 | * been dropped in sk_change_net. Taking referrence to stopping namespace |
@@ -1065,7 +1082,10 @@ struct sock *sk_clone(const struct sock *sk, const gfp_t priority) | |||
1065 | newsk->sk_backlog.head = newsk->sk_backlog.tail = NULL; | 1082 | newsk->sk_backlog.head = newsk->sk_backlog.tail = NULL; |
1066 | 1083 | ||
1067 | atomic_set(&newsk->sk_rmem_alloc, 0); | 1084 | atomic_set(&newsk->sk_rmem_alloc, 0); |
1068 | atomic_set(&newsk->sk_wmem_alloc, 0); | 1085 | /* |
1086 | * sk_wmem_alloc set to one (see sk_free() and sock_wfree()) | ||
1087 | */ | ||
1088 | atomic_set(&newsk->sk_wmem_alloc, 1); | ||
1069 | atomic_set(&newsk->sk_omem_alloc, 0); | 1089 | atomic_set(&newsk->sk_omem_alloc, 0); |
1070 | skb_queue_head_init(&newsk->sk_receive_queue); | 1090 | skb_queue_head_init(&newsk->sk_receive_queue); |
1071 | skb_queue_head_init(&newsk->sk_write_queue); | 1091 | skb_queue_head_init(&newsk->sk_write_queue); |
@@ -1126,7 +1146,6 @@ struct sock *sk_clone(const struct sock *sk, const gfp_t priority) | |||
1126 | out: | 1146 | out: |
1127 | return newsk; | 1147 | return newsk; |
1128 | } | 1148 | } |
1129 | |||
1130 | EXPORT_SYMBOL_GPL(sk_clone); | 1149 | EXPORT_SYMBOL_GPL(sk_clone); |
1131 | 1150 | ||
1132 | void sk_setup_caps(struct sock *sk, struct dst_entry *dst) | 1151 | void sk_setup_caps(struct sock *sk, struct dst_entry *dst) |
@@ -1170,13 +1189,20 @@ void __init sk_init(void) | |||
1170 | void sock_wfree(struct sk_buff *skb) | 1189 | void sock_wfree(struct sk_buff *skb) |
1171 | { | 1190 | { |
1172 | struct sock *sk = skb->sk; | 1191 | struct sock *sk = skb->sk; |
1192 | int res; | ||
1173 | 1193 | ||
1174 | /* In case it might be waiting for more memory. */ | 1194 | /* In case it might be waiting for more memory. */ |
1175 | atomic_sub(skb->truesize, &sk->sk_wmem_alloc); | 1195 | res = atomic_sub_return(skb->truesize, &sk->sk_wmem_alloc); |
1176 | if (!sock_flag(sk, SOCK_USE_WRITE_QUEUE)) | 1196 | if (!sock_flag(sk, SOCK_USE_WRITE_QUEUE)) |
1177 | sk->sk_write_space(sk); | 1197 | sk->sk_write_space(sk); |
1178 | sock_put(sk); | 1198 | /* |
1199 | * if sk_wmem_alloc reached 0, we are last user and should | ||
1200 | * free this sock, as sk_free() call could not do it. | ||
1201 | */ | ||
1202 | if (res == 0) | ||
1203 | __sk_free(sk); | ||
1179 | } | 1204 | } |
1205 | EXPORT_SYMBOL(sock_wfree); | ||
1180 | 1206 | ||
1181 | /* | 1207 | /* |
1182 | * Read buffer destructor automatically called from kfree_skb. | 1208 | * Read buffer destructor automatically called from kfree_skb. |
@@ -1188,6 +1214,7 @@ void sock_rfree(struct sk_buff *skb) | |||
1188 | atomic_sub(skb->truesize, &sk->sk_rmem_alloc); | 1214 | atomic_sub(skb->truesize, &sk->sk_rmem_alloc); |
1189 | sk_mem_uncharge(skb->sk, skb->truesize); | 1215 | sk_mem_uncharge(skb->sk, skb->truesize); |
1190 | } | 1216 | } |
1217 | EXPORT_SYMBOL(sock_rfree); | ||
1191 | 1218 | ||
1192 | 1219 | ||
1193 | int sock_i_uid(struct sock *sk) | 1220 | int sock_i_uid(struct sock *sk) |
@@ -1199,6 +1226,7 @@ int sock_i_uid(struct sock *sk) | |||
1199 | read_unlock(&sk->sk_callback_lock); | 1226 | read_unlock(&sk->sk_callback_lock); |
1200 | return uid; | 1227 | return uid; |
1201 | } | 1228 | } |
1229 | EXPORT_SYMBOL(sock_i_uid); | ||
1202 | 1230 | ||
1203 | unsigned long sock_i_ino(struct sock *sk) | 1231 | unsigned long sock_i_ino(struct sock *sk) |
1204 | { | 1232 | { |
@@ -1209,6 +1237,7 @@ unsigned long sock_i_ino(struct sock *sk) | |||
1209 | read_unlock(&sk->sk_callback_lock); | 1237 | read_unlock(&sk->sk_callback_lock); |
1210 | return ino; | 1238 | return ino; |
1211 | } | 1239 | } |
1240 | EXPORT_SYMBOL(sock_i_ino); | ||
1212 | 1241 | ||
1213 | /* | 1242 | /* |
1214 | * Allocate a skb from the socket's send buffer. | 1243 | * Allocate a skb from the socket's send buffer. |
@@ -1217,7 +1246,7 @@ struct sk_buff *sock_wmalloc(struct sock *sk, unsigned long size, int force, | |||
1217 | gfp_t priority) | 1246 | gfp_t priority) |
1218 | { | 1247 | { |
1219 | if (force || atomic_read(&sk->sk_wmem_alloc) < sk->sk_sndbuf) { | 1248 | if (force || atomic_read(&sk->sk_wmem_alloc) < sk->sk_sndbuf) { |
1220 | struct sk_buff * skb = alloc_skb(size, priority); | 1249 | struct sk_buff *skb = alloc_skb(size, priority); |
1221 | if (skb) { | 1250 | if (skb) { |
1222 | skb_set_owner_w(skb, sk); | 1251 | skb_set_owner_w(skb, sk); |
1223 | return skb; | 1252 | return skb; |
@@ -1225,6 +1254,7 @@ struct sk_buff *sock_wmalloc(struct sock *sk, unsigned long size, int force, | |||
1225 | } | 1254 | } |
1226 | return NULL; | 1255 | return NULL; |
1227 | } | 1256 | } |
1257 | EXPORT_SYMBOL(sock_wmalloc); | ||
1228 | 1258 | ||
1229 | /* | 1259 | /* |
1230 | * Allocate a skb from the socket's receive buffer. | 1260 | * Allocate a skb from the socket's receive buffer. |
@@ -1261,6 +1291,7 @@ void *sock_kmalloc(struct sock *sk, int size, gfp_t priority) | |||
1261 | } | 1291 | } |
1262 | return NULL; | 1292 | return NULL; |
1263 | } | 1293 | } |
1294 | EXPORT_SYMBOL(sock_kmalloc); | ||
1264 | 1295 | ||
1265 | /* | 1296 | /* |
1266 | * Free an option memory block. | 1297 | * Free an option memory block. |
@@ -1270,11 +1301,12 @@ void sock_kfree_s(struct sock *sk, void *mem, int size) | |||
1270 | kfree(mem); | 1301 | kfree(mem); |
1271 | atomic_sub(size, &sk->sk_omem_alloc); | 1302 | atomic_sub(size, &sk->sk_omem_alloc); |
1272 | } | 1303 | } |
1304 | EXPORT_SYMBOL(sock_kfree_s); | ||
1273 | 1305 | ||
1274 | /* It is almost wait_for_tcp_memory minus release_sock/lock_sock. | 1306 | /* It is almost wait_for_tcp_memory minus release_sock/lock_sock. |
1275 | I think, these locks should be removed for datagram sockets. | 1307 | I think, these locks should be removed for datagram sockets. |
1276 | */ | 1308 | */ |
1277 | static long sock_wait_for_wmem(struct sock * sk, long timeo) | 1309 | static long sock_wait_for_wmem(struct sock *sk, long timeo) |
1278 | { | 1310 | { |
1279 | DEFINE_WAIT(wait); | 1311 | DEFINE_WAIT(wait); |
1280 | 1312 | ||
@@ -1392,6 +1424,7 @@ struct sk_buff *sock_alloc_send_skb(struct sock *sk, unsigned long size, | |||
1392 | { | 1424 | { |
1393 | return sock_alloc_send_pskb(sk, size, 0, noblock, errcode); | 1425 | return sock_alloc_send_pskb(sk, size, 0, noblock, errcode); |
1394 | } | 1426 | } |
1427 | EXPORT_SYMBOL(sock_alloc_send_skb); | ||
1395 | 1428 | ||
1396 | static void __lock_sock(struct sock *sk) | 1429 | static void __lock_sock(struct sock *sk) |
1397 | { | 1430 | { |
@@ -1460,7 +1493,6 @@ int sk_wait_data(struct sock *sk, long *timeo) | |||
1460 | finish_wait(sk->sk_sleep, &wait); | 1493 | finish_wait(sk->sk_sleep, &wait); |
1461 | return rc; | 1494 | return rc; |
1462 | } | 1495 | } |
1463 | |||
1464 | EXPORT_SYMBOL(sk_wait_data); | 1496 | EXPORT_SYMBOL(sk_wait_data); |
1465 | 1497 | ||
1466 | /** | 1498 | /** |
@@ -1541,7 +1573,6 @@ suppress_allocation: | |||
1541 | atomic_sub(amt, prot->memory_allocated); | 1573 | atomic_sub(amt, prot->memory_allocated); |
1542 | return 0; | 1574 | return 0; |
1543 | } | 1575 | } |
1544 | |||
1545 | EXPORT_SYMBOL(__sk_mem_schedule); | 1576 | EXPORT_SYMBOL(__sk_mem_schedule); |
1546 | 1577 | ||
1547 | /** | 1578 | /** |
@@ -1560,7 +1591,6 @@ void __sk_mem_reclaim(struct sock *sk) | |||
1560 | (atomic_read(prot->memory_allocated) < prot->sysctl_mem[0])) | 1591 | (atomic_read(prot->memory_allocated) < prot->sysctl_mem[0])) |
1561 | *prot->memory_pressure = 0; | 1592 | *prot->memory_pressure = 0; |
1562 | } | 1593 | } |
1563 | |||
1564 | EXPORT_SYMBOL(__sk_mem_reclaim); | 1594 | EXPORT_SYMBOL(__sk_mem_reclaim); |
1565 | 1595 | ||
1566 | 1596 | ||
@@ -1575,78 +1605,92 @@ int sock_no_bind(struct socket *sock, struct sockaddr *saddr, int len) | |||
1575 | { | 1605 | { |
1576 | return -EOPNOTSUPP; | 1606 | return -EOPNOTSUPP; |
1577 | } | 1607 | } |
1608 | EXPORT_SYMBOL(sock_no_bind); | ||
1578 | 1609 | ||
1579 | int sock_no_connect(struct socket *sock, struct sockaddr *saddr, | 1610 | int sock_no_connect(struct socket *sock, struct sockaddr *saddr, |
1580 | int len, int flags) | 1611 | int len, int flags) |
1581 | { | 1612 | { |
1582 | return -EOPNOTSUPP; | 1613 | return -EOPNOTSUPP; |
1583 | } | 1614 | } |
1615 | EXPORT_SYMBOL(sock_no_connect); | ||
1584 | 1616 | ||
1585 | int sock_no_socketpair(struct socket *sock1, struct socket *sock2) | 1617 | int sock_no_socketpair(struct socket *sock1, struct socket *sock2) |
1586 | { | 1618 | { |
1587 | return -EOPNOTSUPP; | 1619 | return -EOPNOTSUPP; |
1588 | } | 1620 | } |
1621 | EXPORT_SYMBOL(sock_no_socketpair); | ||
1589 | 1622 | ||
1590 | int sock_no_accept(struct socket *sock, struct socket *newsock, int flags) | 1623 | int sock_no_accept(struct socket *sock, struct socket *newsock, int flags) |
1591 | { | 1624 | { |
1592 | return -EOPNOTSUPP; | 1625 | return -EOPNOTSUPP; |
1593 | } | 1626 | } |
1627 | EXPORT_SYMBOL(sock_no_accept); | ||
1594 | 1628 | ||
1595 | int sock_no_getname(struct socket *sock, struct sockaddr *saddr, | 1629 | int sock_no_getname(struct socket *sock, struct sockaddr *saddr, |
1596 | int *len, int peer) | 1630 | int *len, int peer) |
1597 | { | 1631 | { |
1598 | return -EOPNOTSUPP; | 1632 | return -EOPNOTSUPP; |
1599 | } | 1633 | } |
1634 | EXPORT_SYMBOL(sock_no_getname); | ||
1600 | 1635 | ||
1601 | unsigned int sock_no_poll(struct file * file, struct socket *sock, poll_table *pt) | 1636 | unsigned int sock_no_poll(struct file *file, struct socket *sock, poll_table *pt) |
1602 | { | 1637 | { |
1603 | return 0; | 1638 | return 0; |
1604 | } | 1639 | } |
1640 | EXPORT_SYMBOL(sock_no_poll); | ||
1605 | 1641 | ||
1606 | int sock_no_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | 1642 | int sock_no_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) |
1607 | { | 1643 | { |
1608 | return -EOPNOTSUPP; | 1644 | return -EOPNOTSUPP; |
1609 | } | 1645 | } |
1646 | EXPORT_SYMBOL(sock_no_ioctl); | ||
1610 | 1647 | ||
1611 | int sock_no_listen(struct socket *sock, int backlog) | 1648 | int sock_no_listen(struct socket *sock, int backlog) |
1612 | { | 1649 | { |
1613 | return -EOPNOTSUPP; | 1650 | return -EOPNOTSUPP; |
1614 | } | 1651 | } |
1652 | EXPORT_SYMBOL(sock_no_listen); | ||
1615 | 1653 | ||
1616 | int sock_no_shutdown(struct socket *sock, int how) | 1654 | int sock_no_shutdown(struct socket *sock, int how) |
1617 | { | 1655 | { |
1618 | return -EOPNOTSUPP; | 1656 | return -EOPNOTSUPP; |
1619 | } | 1657 | } |
1658 | EXPORT_SYMBOL(sock_no_shutdown); | ||
1620 | 1659 | ||
1621 | int sock_no_setsockopt(struct socket *sock, int level, int optname, | 1660 | int sock_no_setsockopt(struct socket *sock, int level, int optname, |
1622 | char __user *optval, int optlen) | 1661 | char __user *optval, int optlen) |
1623 | { | 1662 | { |
1624 | return -EOPNOTSUPP; | 1663 | return -EOPNOTSUPP; |
1625 | } | 1664 | } |
1665 | EXPORT_SYMBOL(sock_no_setsockopt); | ||
1626 | 1666 | ||
1627 | int sock_no_getsockopt(struct socket *sock, int level, int optname, | 1667 | int sock_no_getsockopt(struct socket *sock, int level, int optname, |
1628 | char __user *optval, int __user *optlen) | 1668 | char __user *optval, int __user *optlen) |
1629 | { | 1669 | { |
1630 | return -EOPNOTSUPP; | 1670 | return -EOPNOTSUPP; |
1631 | } | 1671 | } |
1672 | EXPORT_SYMBOL(sock_no_getsockopt); | ||
1632 | 1673 | ||
1633 | int sock_no_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m, | 1674 | int sock_no_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m, |
1634 | size_t len) | 1675 | size_t len) |
1635 | { | 1676 | { |
1636 | return -EOPNOTSUPP; | 1677 | return -EOPNOTSUPP; |
1637 | } | 1678 | } |
1679 | EXPORT_SYMBOL(sock_no_sendmsg); | ||
1638 | 1680 | ||
1639 | int sock_no_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m, | 1681 | int sock_no_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m, |
1640 | size_t len, int flags) | 1682 | size_t len, int flags) |
1641 | { | 1683 | { |
1642 | return -EOPNOTSUPP; | 1684 | return -EOPNOTSUPP; |
1643 | } | 1685 | } |
1686 | EXPORT_SYMBOL(sock_no_recvmsg); | ||
1644 | 1687 | ||
1645 | int sock_no_mmap(struct file *file, struct socket *sock, struct vm_area_struct *vma) | 1688 | int sock_no_mmap(struct file *file, struct socket *sock, struct vm_area_struct *vma) |
1646 | { | 1689 | { |
1647 | /* Mirror missing mmap method error code */ | 1690 | /* Mirror missing mmap method error code */ |
1648 | return -ENODEV; | 1691 | return -ENODEV; |
1649 | } | 1692 | } |
1693 | EXPORT_SYMBOL(sock_no_mmap); | ||
1650 | 1694 | ||
1651 | ssize_t sock_no_sendpage(struct socket *sock, struct page *page, int offset, size_t size, int flags) | 1695 | ssize_t sock_no_sendpage(struct socket *sock, struct page *page, int offset, size_t size, int flags) |
1652 | { | 1696 | { |
@@ -1660,6 +1704,7 @@ ssize_t sock_no_sendpage(struct socket *sock, struct page *page, int offset, siz | |||
1660 | kunmap(page); | 1704 | kunmap(page); |
1661 | return res; | 1705 | return res; |
1662 | } | 1706 | } |
1707 | EXPORT_SYMBOL(sock_no_sendpage); | ||
1663 | 1708 | ||
1664 | /* | 1709 | /* |
1665 | * Default Socket Callbacks | 1710 | * Default Socket Callbacks |
@@ -1723,6 +1768,7 @@ void sk_send_sigurg(struct sock *sk) | |||
1723 | if (send_sigurg(&sk->sk_socket->file->f_owner)) | 1768 | if (send_sigurg(&sk->sk_socket->file->f_owner)) |
1724 | sk_wake_async(sk, SOCK_WAKE_URG, POLL_PRI); | 1769 | sk_wake_async(sk, SOCK_WAKE_URG, POLL_PRI); |
1725 | } | 1770 | } |
1771 | EXPORT_SYMBOL(sk_send_sigurg); | ||
1726 | 1772 | ||
1727 | void sk_reset_timer(struct sock *sk, struct timer_list* timer, | 1773 | void sk_reset_timer(struct sock *sk, struct timer_list* timer, |
1728 | unsigned long expires) | 1774 | unsigned long expires) |
@@ -1730,7 +1776,6 @@ void sk_reset_timer(struct sock *sk, struct timer_list* timer, | |||
1730 | if (!mod_timer(timer, expires)) | 1776 | if (!mod_timer(timer, expires)) |
1731 | sock_hold(sk); | 1777 | sock_hold(sk); |
1732 | } | 1778 | } |
1733 | |||
1734 | EXPORT_SYMBOL(sk_reset_timer); | 1779 | EXPORT_SYMBOL(sk_reset_timer); |
1735 | 1780 | ||
1736 | void sk_stop_timer(struct sock *sk, struct timer_list* timer) | 1781 | void sk_stop_timer(struct sock *sk, struct timer_list* timer) |
@@ -1738,7 +1783,6 @@ void sk_stop_timer(struct sock *sk, struct timer_list* timer) | |||
1738 | if (timer_pending(timer) && del_timer(timer)) | 1783 | if (timer_pending(timer) && del_timer(timer)) |
1739 | __sock_put(sk); | 1784 | __sock_put(sk); |
1740 | } | 1785 | } |
1741 | |||
1742 | EXPORT_SYMBOL(sk_stop_timer); | 1786 | EXPORT_SYMBOL(sk_stop_timer); |
1743 | 1787 | ||
1744 | void sock_init_data(struct socket *sock, struct sock *sk) | 1788 | void sock_init_data(struct socket *sock, struct sock *sk) |
@@ -1795,8 +1839,10 @@ void sock_init_data(struct socket *sock, struct sock *sk) | |||
1795 | sk->sk_stamp = ktime_set(-1L, 0); | 1839 | sk->sk_stamp = ktime_set(-1L, 0); |
1796 | 1840 | ||
1797 | atomic_set(&sk->sk_refcnt, 1); | 1841 | atomic_set(&sk->sk_refcnt, 1); |
1842 | atomic_set(&sk->sk_wmem_alloc, 1); | ||
1798 | atomic_set(&sk->sk_drops, 0); | 1843 | atomic_set(&sk->sk_drops, 0); |
1799 | } | 1844 | } |
1845 | EXPORT_SYMBOL(sock_init_data); | ||
1800 | 1846 | ||
1801 | void lock_sock_nested(struct sock *sk, int subclass) | 1847 | void lock_sock_nested(struct sock *sk, int subclass) |
1802 | { | 1848 | { |
@@ -1812,7 +1858,6 @@ void lock_sock_nested(struct sock *sk, int subclass) | |||
1812 | mutex_acquire(&sk->sk_lock.dep_map, subclass, 0, _RET_IP_); | 1858 | mutex_acquire(&sk->sk_lock.dep_map, subclass, 0, _RET_IP_); |
1813 | local_bh_enable(); | 1859 | local_bh_enable(); |
1814 | } | 1860 | } |
1815 | |||
1816 | EXPORT_SYMBOL(lock_sock_nested); | 1861 | EXPORT_SYMBOL(lock_sock_nested); |
1817 | 1862 | ||
1818 | void release_sock(struct sock *sk) | 1863 | void release_sock(struct sock *sk) |
@@ -1895,7 +1940,6 @@ int sock_common_getsockopt(struct socket *sock, int level, int optname, | |||
1895 | 1940 | ||
1896 | return sk->sk_prot->getsockopt(sk, level, optname, optval, optlen); | 1941 | return sk->sk_prot->getsockopt(sk, level, optname, optval, optlen); |
1897 | } | 1942 | } |
1898 | |||
1899 | EXPORT_SYMBOL(sock_common_getsockopt); | 1943 | EXPORT_SYMBOL(sock_common_getsockopt); |
1900 | 1944 | ||
1901 | #ifdef CONFIG_COMPAT | 1945 | #ifdef CONFIG_COMPAT |
@@ -1925,7 +1969,6 @@ int sock_common_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
1925 | msg->msg_namelen = addr_len; | 1969 | msg->msg_namelen = addr_len; |
1926 | return err; | 1970 | return err; |
1927 | } | 1971 | } |
1928 | |||
1929 | EXPORT_SYMBOL(sock_common_recvmsg); | 1972 | EXPORT_SYMBOL(sock_common_recvmsg); |
1930 | 1973 | ||
1931 | /* | 1974 | /* |
@@ -1938,7 +1981,6 @@ int sock_common_setsockopt(struct socket *sock, int level, int optname, | |||
1938 | 1981 | ||
1939 | return sk->sk_prot->setsockopt(sk, level, optname, optval, optlen); | 1982 | return sk->sk_prot->setsockopt(sk, level, optname, optval, optlen); |
1940 | } | 1983 | } |
1941 | |||
1942 | EXPORT_SYMBOL(sock_common_setsockopt); | 1984 | EXPORT_SYMBOL(sock_common_setsockopt); |
1943 | 1985 | ||
1944 | #ifdef CONFIG_COMPAT | 1986 | #ifdef CONFIG_COMPAT |
@@ -1989,7 +2031,6 @@ void sk_common_release(struct sock *sk) | |||
1989 | sk_refcnt_debug_release(sk); | 2031 | sk_refcnt_debug_release(sk); |
1990 | sock_put(sk); | 2032 | sock_put(sk); |
1991 | } | 2033 | } |
1992 | |||
1993 | EXPORT_SYMBOL(sk_common_release); | 2034 | EXPORT_SYMBOL(sk_common_release); |
1994 | 2035 | ||
1995 | static DEFINE_RWLOCK(proto_list_lock); | 2036 | static DEFINE_RWLOCK(proto_list_lock); |
@@ -2171,7 +2212,6 @@ out_free_sock_slab: | |||
2171 | out: | 2212 | out: |
2172 | return -ENOBUFS; | 2213 | return -ENOBUFS; |
2173 | } | 2214 | } |
2174 | |||
2175 | EXPORT_SYMBOL(proto_register); | 2215 | EXPORT_SYMBOL(proto_register); |
2176 | 2216 | ||
2177 | void proto_unregister(struct proto *prot) | 2217 | void proto_unregister(struct proto *prot) |
@@ -2198,7 +2238,6 @@ void proto_unregister(struct proto *prot) | |||
2198 | prot->twsk_prot->twsk_slab = NULL; | 2238 | prot->twsk_prot->twsk_slab = NULL; |
2199 | } | 2239 | } |
2200 | } | 2240 | } |
2201 | |||
2202 | EXPORT_SYMBOL(proto_unregister); | 2241 | EXPORT_SYMBOL(proto_unregister); |
2203 | 2242 | ||
2204 | #ifdef CONFIG_PROC_FS | 2243 | #ifdef CONFIG_PROC_FS |
@@ -2324,33 +2363,3 @@ static int __init proto_init(void) | |||
2324 | subsys_initcall(proto_init); | 2363 | subsys_initcall(proto_init); |
2325 | 2364 | ||
2326 | #endif /* PROC_FS */ | 2365 | #endif /* PROC_FS */ |
2327 | |||
2328 | EXPORT_SYMBOL(sk_alloc); | ||
2329 | EXPORT_SYMBOL(sk_free); | ||
2330 | EXPORT_SYMBOL(sk_send_sigurg); | ||
2331 | EXPORT_SYMBOL(sock_alloc_send_skb); | ||
2332 | EXPORT_SYMBOL(sock_init_data); | ||
2333 | EXPORT_SYMBOL(sock_kfree_s); | ||
2334 | EXPORT_SYMBOL(sock_kmalloc); | ||
2335 | EXPORT_SYMBOL(sock_no_accept); | ||
2336 | EXPORT_SYMBOL(sock_no_bind); | ||
2337 | EXPORT_SYMBOL(sock_no_connect); | ||
2338 | EXPORT_SYMBOL(sock_no_getname); | ||
2339 | EXPORT_SYMBOL(sock_no_getsockopt); | ||
2340 | EXPORT_SYMBOL(sock_no_ioctl); | ||
2341 | EXPORT_SYMBOL(sock_no_listen); | ||
2342 | EXPORT_SYMBOL(sock_no_mmap); | ||
2343 | EXPORT_SYMBOL(sock_no_poll); | ||
2344 | EXPORT_SYMBOL(sock_no_recvmsg); | ||
2345 | EXPORT_SYMBOL(sock_no_sendmsg); | ||
2346 | EXPORT_SYMBOL(sock_no_sendpage); | ||
2347 | EXPORT_SYMBOL(sock_no_setsockopt); | ||
2348 | EXPORT_SYMBOL(sock_no_shutdown); | ||
2349 | EXPORT_SYMBOL(sock_no_socketpair); | ||
2350 | EXPORT_SYMBOL(sock_rfree); | ||
2351 | EXPORT_SYMBOL(sock_setsockopt); | ||
2352 | EXPORT_SYMBOL(sock_wfree); | ||
2353 | EXPORT_SYMBOL(sock_wmalloc); | ||
2354 | EXPORT_SYMBOL(sock_i_uid); | ||
2355 | EXPORT_SYMBOL(sock_i_ino); | ||
2356 | EXPORT_SYMBOL(sysctl_optmem_max); | ||
diff --git a/net/core/user_dma.c b/net/core/user_dma.c index 164b090d5ac..25d717ebc92 100644 --- a/net/core/user_dma.c +++ b/net/core/user_dma.c | |||
@@ -51,6 +51,7 @@ int dma_skb_copy_datagram_iovec(struct dma_chan *chan, | |||
51 | { | 51 | { |
52 | int start = skb_headlen(skb); | 52 | int start = skb_headlen(skb); |
53 | int i, copy = start - offset; | 53 | int i, copy = start - offset; |
54 | struct sk_buff *frag_iter; | ||
54 | dma_cookie_t cookie = 0; | 55 | dma_cookie_t cookie = 0; |
55 | 56 | ||
56 | /* Copy header. */ | 57 | /* Copy header. */ |
@@ -94,31 +95,28 @@ int dma_skb_copy_datagram_iovec(struct dma_chan *chan, | |||
94 | start = end; | 95 | start = end; |
95 | } | 96 | } |
96 | 97 | ||
97 | if (skb_shinfo(skb)->frag_list) { | 98 | skb_walk_frags(skb, frag_iter) { |
98 | struct sk_buff *list = skb_shinfo(skb)->frag_list; | 99 | int end; |
99 | 100 | ||
100 | for (; list; list = list->next) { | 101 | WARN_ON(start > offset + len); |
101 | int end; | 102 | |
102 | 103 | end = start + frag_iter->len; | |
103 | WARN_ON(start > offset + len); | 104 | copy = end - offset; |
104 | 105 | if (copy > 0) { | |
105 | end = start + list->len; | 106 | if (copy > len) |
106 | copy = end - offset; | 107 | copy = len; |
107 | if (copy > 0) { | 108 | cookie = dma_skb_copy_datagram_iovec(chan, frag_iter, |
108 | if (copy > len) | 109 | offset - start, |
109 | copy = len; | 110 | to, copy, |
110 | cookie = dma_skb_copy_datagram_iovec(chan, list, | 111 | pinned_list); |
111 | offset - start, to, copy, | 112 | if (cookie < 0) |
112 | pinned_list); | 113 | goto fault; |
113 | if (cookie < 0) | 114 | len -= copy; |
114 | goto fault; | 115 | if (len == 0) |
115 | len -= copy; | 116 | goto end; |
116 | if (len == 0) | 117 | offset += copy; |
117 | goto end; | ||
118 | offset += copy; | ||
119 | } | ||
120 | start = end; | ||
121 | } | 118 | } |
119 | start = end; | ||
122 | } | 120 | } |
123 | 121 | ||
124 | end: | 122 | end: |