aboutsummaryrefslogtreecommitdiffstats
path: root/net/core
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2009-12-04 09:59:47 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2009-12-04 09:59:47 -0500
commit5cb2faa6ede7ada9cb2bffc832c4ce60f53d6834 (patch)
tree7b72b66081d042a41dc822575503133364857ce2 /net/core
parente0ee98513d1a2e24d2ddbdecf4216bcca29d1158 (diff)
parent6060e8df517847bf445ebc61de7d4d9c7faae990 (diff)
Merge branch 'pending-misc' (early part) into devel
Diffstat (limited to 'net/core')
-rw-r--r--net/core/datagram.c10
-rw-r--r--net/core/dev.c11
-rw-r--r--net/core/pktgen.c47
-rw-r--r--net/core/skbuff.c3
4 files changed, 47 insertions, 24 deletions
diff --git a/net/core/datagram.c b/net/core/datagram.c
index 1c6cf3a1a4f6..4ade3011bb3c 100644
--- a/net/core/datagram.c
+++ b/net/core/datagram.c
@@ -224,6 +224,15 @@ void skb_free_datagram(struct sock *sk, struct sk_buff *skb)
224 consume_skb(skb); 224 consume_skb(skb);
225 sk_mem_reclaim_partial(sk); 225 sk_mem_reclaim_partial(sk);
226} 226}
227EXPORT_SYMBOL(skb_free_datagram);
228
229void skb_free_datagram_locked(struct sock *sk, struct sk_buff *skb)
230{
231 lock_sock(sk);
232 skb_free_datagram(sk, skb);
233 release_sock(sk);
234}
235EXPORT_SYMBOL(skb_free_datagram_locked);
227 236
228/** 237/**
229 * skb_kill_datagram - Free a datagram skbuff forcibly 238 * skb_kill_datagram - Free a datagram skbuff forcibly
@@ -752,5 +761,4 @@ unsigned int datagram_poll(struct file *file, struct socket *sock,
752EXPORT_SYMBOL(datagram_poll); 761EXPORT_SYMBOL(datagram_poll);
753EXPORT_SYMBOL(skb_copy_and_csum_datagram_iovec); 762EXPORT_SYMBOL(skb_copy_and_csum_datagram_iovec);
754EXPORT_SYMBOL(skb_copy_datagram_iovec); 763EXPORT_SYMBOL(skb_copy_datagram_iovec);
755EXPORT_SYMBOL(skb_free_datagram);
756EXPORT_SYMBOL(skb_recv_datagram); 764EXPORT_SYMBOL(skb_recv_datagram);
diff --git a/net/core/dev.c b/net/core/dev.c
index b8f74cfb1bfd..fe10551d3671 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -942,14 +942,15 @@ rollback:
942 ret = notifier_to_errno(ret); 942 ret = notifier_to_errno(ret);
943 943
944 if (ret) { 944 if (ret) {
945 if (err) { 945 /* err >= 0 after dev_alloc_name() or stores the first errno */
946 printk(KERN_ERR 946 if (err >= 0) {
947 "%s: name change rollback failed: %d.\n",
948 dev->name, ret);
949 } else {
950 err = ret; 947 err = ret;
951 memcpy(dev->name, oldname, IFNAMSIZ); 948 memcpy(dev->name, oldname, IFNAMSIZ);
952 goto rollback; 949 goto rollback;
950 } else {
951 printk(KERN_ERR
952 "%s: name change rollback failed: %d.\n",
953 dev->name, ret);
953 } 954 }
954 } 955 }
955 956
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index 86acdba0a97d..6e79e96cb4f2 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -335,6 +335,7 @@ struct pktgen_dev {
335 __u32 cur_src_mac_offset; 335 __u32 cur_src_mac_offset;
336 __be32 cur_saddr; 336 __be32 cur_saddr;
337 __be32 cur_daddr; 337 __be32 cur_daddr;
338 __u16 ip_id;
338 __u16 cur_udp_dst; 339 __u16 cur_udp_dst;
339 __u16 cur_udp_src; 340 __u16 cur_udp_src;
340 __u16 cur_queue_map; 341 __u16 cur_queue_map;
@@ -362,6 +363,7 @@ struct pktgen_dev {
362 * device name (not when the inject is 363 * device name (not when the inject is
363 * started as it used to do.) 364 * started as it used to do.)
364 */ 365 */
366 char odevname[32];
365 struct flow_state *flows; 367 struct flow_state *flows;
366 unsigned cflows; /* Concurrent flows (config) */ 368 unsigned cflows; /* Concurrent flows (config) */
367 unsigned lflow; /* Flow length (config) */ 369 unsigned lflow; /* Flow length (config) */
@@ -425,7 +427,7 @@ static const char version[] =
425static int pktgen_remove_device(struct pktgen_thread *t, struct pktgen_dev *i); 427static int pktgen_remove_device(struct pktgen_thread *t, struct pktgen_dev *i);
426static int pktgen_add_device(struct pktgen_thread *t, const char *ifname); 428static int pktgen_add_device(struct pktgen_thread *t, const char *ifname);
427static struct pktgen_dev *pktgen_find_dev(struct pktgen_thread *t, 429static struct pktgen_dev *pktgen_find_dev(struct pktgen_thread *t,
428 const char *ifname); 430 const char *ifname, bool exact);
429static int pktgen_device_event(struct notifier_block *, unsigned long, void *); 431static int pktgen_device_event(struct notifier_block *, unsigned long, void *);
430static void pktgen_run_all_threads(void); 432static void pktgen_run_all_threads(void);
431static void pktgen_reset_all_threads(void); 433static void pktgen_reset_all_threads(void);
@@ -527,7 +529,7 @@ static int pktgen_if_show(struct seq_file *seq, void *v)
527 seq_printf(seq, 529 seq_printf(seq,
528 " frags: %d delay: %llu clone_skb: %d ifname: %s\n", 530 " frags: %d delay: %llu clone_skb: %d ifname: %s\n",
529 pkt_dev->nfrags, (unsigned long long) pkt_dev->delay, 531 pkt_dev->nfrags, (unsigned long long) pkt_dev->delay,
530 pkt_dev->clone_skb, pkt_dev->odev->name); 532 pkt_dev->clone_skb, pkt_dev->odevname);
531 533
532 seq_printf(seq, " flows: %u flowlen: %u\n", pkt_dev->cflows, 534 seq_printf(seq, " flows: %u flowlen: %u\n", pkt_dev->cflows,
533 pkt_dev->lflow); 535 pkt_dev->lflow);
@@ -1687,13 +1689,13 @@ static int pktgen_thread_show(struct seq_file *seq, void *v)
1687 if_lock(t); 1689 if_lock(t);
1688 list_for_each_entry(pkt_dev, &t->if_list, list) 1690 list_for_each_entry(pkt_dev, &t->if_list, list)
1689 if (pkt_dev->running) 1691 if (pkt_dev->running)
1690 seq_printf(seq, "%s ", pkt_dev->odev->name); 1692 seq_printf(seq, "%s ", pkt_dev->odevname);
1691 1693
1692 seq_printf(seq, "\nStopped: "); 1694 seq_printf(seq, "\nStopped: ");
1693 1695
1694 list_for_each_entry(pkt_dev, &t->if_list, list) 1696 list_for_each_entry(pkt_dev, &t->if_list, list)
1695 if (!pkt_dev->running) 1697 if (!pkt_dev->running)
1696 seq_printf(seq, "%s ", pkt_dev->odev->name); 1698 seq_printf(seq, "%s ", pkt_dev->odevname);
1697 1699
1698 if (t->result[0]) 1700 if (t->result[0])
1699 seq_printf(seq, "\nResult: %s\n", t->result); 1701 seq_printf(seq, "\nResult: %s\n", t->result);
@@ -1816,9 +1818,10 @@ static struct pktgen_dev *__pktgen_NN_threads(const char *ifname, int remove)
1816{ 1818{
1817 struct pktgen_thread *t; 1819 struct pktgen_thread *t;
1818 struct pktgen_dev *pkt_dev = NULL; 1820 struct pktgen_dev *pkt_dev = NULL;
1821 bool exact = (remove == FIND);
1819 1822
1820 list_for_each_entry(t, &pktgen_threads, th_list) { 1823 list_for_each_entry(t, &pktgen_threads, th_list) {
1821 pkt_dev = pktgen_find_dev(t, ifname); 1824 pkt_dev = pktgen_find_dev(t, ifname, exact);
1822 if (pkt_dev) { 1825 if (pkt_dev) {
1823 if (remove) { 1826 if (remove) {
1824 if_lock(t); 1827 if_lock(t);
@@ -1993,7 +1996,7 @@ static void pktgen_setup_inject(struct pktgen_dev *pkt_dev)
1993 "queue_map_min (zero-based) (%d) exceeds valid range " 1996 "queue_map_min (zero-based) (%d) exceeds valid range "
1994 "[0 - %d] for (%d) queues on %s, resetting\n", 1997 "[0 - %d] for (%d) queues on %s, resetting\n",
1995 pkt_dev->queue_map_min, (ntxq ?: 1) - 1, ntxq, 1998 pkt_dev->queue_map_min, (ntxq ?: 1) - 1, ntxq,
1996 pkt_dev->odev->name); 1999 pkt_dev->odevname);
1997 pkt_dev->queue_map_min = ntxq - 1; 2000 pkt_dev->queue_map_min = ntxq - 1;
1998 } 2001 }
1999 if (pkt_dev->queue_map_max >= ntxq) { 2002 if (pkt_dev->queue_map_max >= ntxq) {
@@ -2001,7 +2004,7 @@ static void pktgen_setup_inject(struct pktgen_dev *pkt_dev)
2001 "queue_map_max (zero-based) (%d) exceeds valid range " 2004 "queue_map_max (zero-based) (%d) exceeds valid range "
2002 "[0 - %d] for (%d) queues on %s, resetting\n", 2005 "[0 - %d] for (%d) queues on %s, resetting\n",
2003 pkt_dev->queue_map_max, (ntxq ?: 1) - 1, ntxq, 2006 pkt_dev->queue_map_max, (ntxq ?: 1) - 1, ntxq,
2004 pkt_dev->odev->name); 2007 pkt_dev->odevname);
2005 pkt_dev->queue_map_max = ntxq - 1; 2008 pkt_dev->queue_map_max = ntxq - 1;
2006 } 2009 }
2007 2010
@@ -2630,6 +2633,8 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev,
2630 iph->protocol = IPPROTO_UDP; /* UDP */ 2633 iph->protocol = IPPROTO_UDP; /* UDP */
2631 iph->saddr = pkt_dev->cur_saddr; 2634 iph->saddr = pkt_dev->cur_saddr;
2632 iph->daddr = pkt_dev->cur_daddr; 2635 iph->daddr = pkt_dev->cur_daddr;
2636 iph->id = htons(pkt_dev->ip_id);
2637 pkt_dev->ip_id++;
2633 iph->frag_off = 0; 2638 iph->frag_off = 0;
2634 iplen = 20 + 8 + datalen; 2639 iplen = 20 + 8 + datalen;
2635 iph->tot_len = htons(iplen); 2640 iph->tot_len = htons(iplen);
@@ -2641,24 +2646,26 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev,
2641 skb->dev = odev; 2646 skb->dev = odev;
2642 skb->pkt_type = PACKET_HOST; 2647 skb->pkt_type = PACKET_HOST;
2643 2648
2644 if (pkt_dev->nfrags <= 0) 2649 if (pkt_dev->nfrags <= 0) {
2645 pgh = (struct pktgen_hdr *)skb_put(skb, datalen); 2650 pgh = (struct pktgen_hdr *)skb_put(skb, datalen);
2646 else { 2651 memset(pgh + 1, 0, datalen - sizeof(struct pktgen_hdr));
2652 } else {
2647 int frags = pkt_dev->nfrags; 2653 int frags = pkt_dev->nfrags;
2648 int i; 2654 int i, len;
2649 2655
2650 pgh = (struct pktgen_hdr *)(((char *)(udph)) + 8); 2656 pgh = (struct pktgen_hdr *)(((char *)(udph)) + 8);
2651 2657
2652 if (frags > MAX_SKB_FRAGS) 2658 if (frags > MAX_SKB_FRAGS)
2653 frags = MAX_SKB_FRAGS; 2659 frags = MAX_SKB_FRAGS;
2654 if (datalen > frags * PAGE_SIZE) { 2660 if (datalen > frags * PAGE_SIZE) {
2655 skb_put(skb, datalen - frags * PAGE_SIZE); 2661 len = datalen - frags * PAGE_SIZE;
2662 memset(skb_put(skb, len), 0, len);
2656 datalen = frags * PAGE_SIZE; 2663 datalen = frags * PAGE_SIZE;
2657 } 2664 }
2658 2665
2659 i = 0; 2666 i = 0;
2660 while (datalen > 0) { 2667 while (datalen > 0) {
2661 struct page *page = alloc_pages(GFP_KERNEL, 0); 2668 struct page *page = alloc_pages(GFP_KERNEL | __GFP_ZERO, 0);
2662 skb_shinfo(skb)->frags[i].page = page; 2669 skb_shinfo(skb)->frags[i].page = page;
2663 skb_shinfo(skb)->frags[i].page_offset = 0; 2670 skb_shinfo(skb)->frags[i].page_offset = 0;
2664 skb_shinfo(skb)->frags[i].size = 2671 skb_shinfo(skb)->frags[i].size =
@@ -3257,7 +3264,7 @@ static int pktgen_stop_device(struct pktgen_dev *pkt_dev)
3257 3264
3258 if (!pkt_dev->running) { 3265 if (!pkt_dev->running) {
3259 printk(KERN_WARNING "pktgen: interface: %s is already " 3266 printk(KERN_WARNING "pktgen: interface: %s is already "
3260 "stopped\n", pkt_dev->odev->name); 3267 "stopped\n", pkt_dev->odevname);
3261 return -EINVAL; 3268 return -EINVAL;
3262 } 3269 }
3263 3270
@@ -3459,7 +3466,7 @@ static void pktgen_xmit(struct pktgen_dev *pkt_dev)
3459 default: /* Drivers are not supposed to return other values! */ 3466 default: /* Drivers are not supposed to return other values! */
3460 if (net_ratelimit()) 3467 if (net_ratelimit())
3461 pr_info("pktgen: %s xmit error: %d\n", 3468 pr_info("pktgen: %s xmit error: %d\n",
3462 odev->name, ret); 3469 pkt_dev->odevname, ret);
3463 pkt_dev->errors++; 3470 pkt_dev->errors++;
3464 /* fallthru */ 3471 /* fallthru */
3465 case NETDEV_TX_LOCKED: 3472 case NETDEV_TX_LOCKED:
@@ -3561,13 +3568,18 @@ static int pktgen_thread_worker(void *arg)
3561} 3568}
3562 3569
3563static struct pktgen_dev *pktgen_find_dev(struct pktgen_thread *t, 3570static struct pktgen_dev *pktgen_find_dev(struct pktgen_thread *t,
3564 const char *ifname) 3571 const char *ifname, bool exact)
3565{ 3572{
3566 struct pktgen_dev *p, *pkt_dev = NULL; 3573 struct pktgen_dev *p, *pkt_dev = NULL;
3567 if_lock(t); 3574 size_t len = strlen(ifname);
3568 3575
3576 if_lock(t);
3569 list_for_each_entry(p, &t->if_list, list) 3577 list_for_each_entry(p, &t->if_list, list)
3570 if (strncmp(p->odev->name, ifname, IFNAMSIZ) == 0) { 3578 if (strncmp(p->odevname, ifname, len) == 0) {
3579 if (p->odevname[len]) {
3580 if (exact || p->odevname[len] != '@')
3581 continue;
3582 }
3571 pkt_dev = p; 3583 pkt_dev = p;
3572 break; 3584 break;
3573 } 3585 }
@@ -3623,6 +3635,7 @@ static int pktgen_add_device(struct pktgen_thread *t, const char *ifname)
3623 if (!pkt_dev) 3635 if (!pkt_dev)
3624 return -ENOMEM; 3636 return -ENOMEM;
3625 3637
3638 strcpy(pkt_dev->odevname, ifname);
3626 pkt_dev->flows = vmalloc(MAX_CFLOWS * sizeof(struct flow_state)); 3639 pkt_dev->flows = vmalloc(MAX_CFLOWS * sizeof(struct flow_state));
3627 if (pkt_dev->flows == NULL) { 3640 if (pkt_dev->flows == NULL) {
3628 kfree(pkt_dev); 3641 kfree(pkt_dev);
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 80a96166df39..ec85681a7dd8 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -2701,7 +2701,8 @@ int skb_gro_receive(struct sk_buff **head, struct sk_buff *skb)
2701 2701
2702 NAPI_GRO_CB(skb)->free = 1; 2702 NAPI_GRO_CB(skb)->free = 1;
2703 goto done; 2703 goto done;
2704 } 2704 } else if (skb_gro_len(p) != pinfo->gso_size)
2705 return -E2BIG;
2705 2706
2706 headroom = skb_headroom(p); 2707 headroom = skb_headroom(p);
2707 nskb = netdev_alloc_skb(p->dev, headroom + skb_gro_offset(p)); 2708 nskb = netdev_alloc_skb(p->dev, headroom + skb_gro_offset(p));