aboutsummaryrefslogtreecommitdiffstats
path: root/net/core/pktgen.c
diff options
context:
space:
mode:
authorCong Wang <amwang@redhat.com>2013-01-28 14:55:53 -0500
committerDavid S. Miller <davem@davemloft.net>2013-01-29 15:17:46 -0500
commit4e58a0275015e5c8988bda9cd0635e2ef405c985 (patch)
tree743245c3e8b10fb83577b590579c3e593aa693c7 /net/core/pktgen.c
parentdc975382d2ef36be7e78fac3717927de1a5abcd8 (diff)
pktgen: support net namespace
v3: make pktgen_threads list per-namespace v2: remove a useless check This patch add net namespace to pktgen, so that we can use pktgen in different namespaces. Cc: Eric W. Biederman <ebiederm@xmission.com> Cc: David S. Miller <davem@davemloft.net> Signed-off-by: Cong Wang <amwang@redhat.com> Acked-by: "Eric W. Biederman" <ebiederm@xmission.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core/pktgen.c')
-rw-r--r--net/core/pktgen.c196
1 files changed, 117 insertions, 79 deletions
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index b29dacf900f9..797769551b91 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -164,6 +164,7 @@
164#ifdef CONFIG_XFRM 164#ifdef CONFIG_XFRM
165#include <net/xfrm.h> 165#include <net/xfrm.h>
166#endif 166#endif
167#include <net/netns/generic.h>
167#include <asm/byteorder.h> 168#include <asm/byteorder.h>
168#include <linux/rcupdate.h> 169#include <linux/rcupdate.h>
169#include <linux/bitops.h> 170#include <linux/bitops.h>
@@ -212,7 +213,6 @@
212#define PKTGEN_MAGIC 0xbe9be955 213#define PKTGEN_MAGIC 0xbe9be955
213#define PG_PROC_DIR "pktgen" 214#define PG_PROC_DIR "pktgen"
214#define PGCTRL "pgctrl" 215#define PGCTRL "pgctrl"
215static struct proc_dir_entry *pg_proc_dir;
216 216
217#define MAX_CFLOWS 65536 217#define MAX_CFLOWS 65536
218 218
@@ -397,7 +397,15 @@ struct pktgen_hdr {
397 __be32 tv_usec; 397 __be32 tv_usec;
398}; 398};
399 399
400static bool pktgen_exiting __read_mostly; 400
401static int pg_net_id __read_mostly;
402
403struct pktgen_net {
404 struct net *net;
405 struct proc_dir_entry *proc_dir;
406 struct list_head pktgen_threads;
407 bool pktgen_exiting;
408};
401 409
402struct pktgen_thread { 410struct pktgen_thread {
403 spinlock_t if_lock; /* for list of devices */ 411 spinlock_t if_lock; /* for list of devices */
@@ -414,6 +422,7 @@ struct pktgen_thread {
414 422
415 wait_queue_head_t queue; 423 wait_queue_head_t queue;
416 struct completion start_done; 424 struct completion start_done;
425 struct pktgen_net *net;
417}; 426};
418 427
419#define REMOVE 1 428#define REMOVE 1
@@ -428,9 +437,9 @@ static int pktgen_add_device(struct pktgen_thread *t, const char *ifname);
428static struct pktgen_dev *pktgen_find_dev(struct pktgen_thread *t, 437static struct pktgen_dev *pktgen_find_dev(struct pktgen_thread *t,
429 const char *ifname, bool exact); 438 const char *ifname, bool exact);
430static int pktgen_device_event(struct notifier_block *, unsigned long, void *); 439static int pktgen_device_event(struct notifier_block *, unsigned long, void *);
431static void pktgen_run_all_threads(void); 440static void pktgen_run_all_threads(struct pktgen_net *pn);
432static void pktgen_reset_all_threads(void); 441static void pktgen_reset_all_threads(struct pktgen_net *pn);
433static void pktgen_stop_all_threads_ifs(void); 442static void pktgen_stop_all_threads_ifs(struct pktgen_net *pn);
434 443
435static void pktgen_stop(struct pktgen_thread *t); 444static void pktgen_stop(struct pktgen_thread *t);
436static void pktgen_clear_counters(struct pktgen_dev *pkt_dev); 445static void pktgen_clear_counters(struct pktgen_dev *pkt_dev);
@@ -442,7 +451,6 @@ static int pg_clone_skb_d __read_mostly;
442static int debug __read_mostly; 451static int debug __read_mostly;
443 452
444static DEFINE_MUTEX(pktgen_thread_lock); 453static DEFINE_MUTEX(pktgen_thread_lock);
445static LIST_HEAD(pktgen_threads);
446 454
447static struct notifier_block pktgen_notifier_block = { 455static struct notifier_block pktgen_notifier_block = {
448 .notifier_call = pktgen_device_event, 456 .notifier_call = pktgen_device_event,
@@ -464,6 +472,7 @@ static ssize_t pgctrl_write(struct file *file, const char __user *buf,
464{ 472{
465 int err = 0; 473 int err = 0;
466 char data[128]; 474 char data[128];
475 struct pktgen_net *pn = net_generic(current->nsproxy->net_ns, pg_net_id);
467 476
468 if (!capable(CAP_NET_ADMIN)) { 477 if (!capable(CAP_NET_ADMIN)) {
469 err = -EPERM; 478 err = -EPERM;
@@ -480,13 +489,13 @@ static ssize_t pgctrl_write(struct file *file, const char __user *buf,
480 data[count - 1] = 0; /* Make string */ 489 data[count - 1] = 0; /* Make string */
481 490
482 if (!strcmp(data, "stop")) 491 if (!strcmp(data, "stop"))
483 pktgen_stop_all_threads_ifs(); 492 pktgen_stop_all_threads_ifs(pn);
484 493
485 else if (!strcmp(data, "start")) 494 else if (!strcmp(data, "start"))
486 pktgen_run_all_threads(); 495 pktgen_run_all_threads(pn);
487 496
488 else if (!strcmp(data, "reset")) 497 else if (!strcmp(data, "reset"))
489 pktgen_reset_all_threads(); 498 pktgen_reset_all_threads(pn);
490 499
491 else 500 else
492 pr_warning("Unknown command: %s\n", data); 501 pr_warning("Unknown command: %s\n", data);
@@ -1824,13 +1833,14 @@ static const struct file_operations pktgen_thread_fops = {
1824}; 1833};
1825 1834
1826/* Think find or remove for NN */ 1835/* Think find or remove for NN */
1827static struct pktgen_dev *__pktgen_NN_threads(const char *ifname, int remove) 1836static struct pktgen_dev *__pktgen_NN_threads(const struct pktgen_net *pn,
1837 const char *ifname, int remove)
1828{ 1838{
1829 struct pktgen_thread *t; 1839 struct pktgen_thread *t;
1830 struct pktgen_dev *pkt_dev = NULL; 1840 struct pktgen_dev *pkt_dev = NULL;
1831 bool exact = (remove == FIND); 1841 bool exact = (remove == FIND);
1832 1842
1833 list_for_each_entry(t, &pktgen_threads, th_list) { 1843 list_for_each_entry(t, &pn->pktgen_threads, th_list) {
1834 pkt_dev = pktgen_find_dev(t, ifname, exact); 1844 pkt_dev = pktgen_find_dev(t, ifname, exact);
1835 if (pkt_dev) { 1845 if (pkt_dev) {
1836 if (remove) { 1846 if (remove) {
@@ -1848,7 +1858,7 @@ static struct pktgen_dev *__pktgen_NN_threads(const char *ifname, int remove)
1848/* 1858/*
1849 * mark a device for removal 1859 * mark a device for removal
1850 */ 1860 */
1851static void pktgen_mark_device(const char *ifname) 1861static void pktgen_mark_device(const struct pktgen_net *pn, const char *ifname)
1852{ 1862{
1853 struct pktgen_dev *pkt_dev = NULL; 1863 struct pktgen_dev *pkt_dev = NULL;
1854 const int max_tries = 10, msec_per_try = 125; 1864 const int max_tries = 10, msec_per_try = 125;
@@ -1859,7 +1869,7 @@ static void pktgen_mark_device(const char *ifname)
1859 1869
1860 while (1) { 1870 while (1) {
1861 1871
1862 pkt_dev = __pktgen_NN_threads(ifname, REMOVE); 1872 pkt_dev = __pktgen_NN_threads(pn, ifname, REMOVE);
1863 if (pkt_dev == NULL) 1873 if (pkt_dev == NULL)
1864 break; /* success */ 1874 break; /* success */
1865 1875
@@ -1880,21 +1890,21 @@ static void pktgen_mark_device(const char *ifname)
1880 mutex_unlock(&pktgen_thread_lock); 1890 mutex_unlock(&pktgen_thread_lock);
1881} 1891}
1882 1892
1883static void pktgen_change_name(struct net_device *dev) 1893static void pktgen_change_name(const struct pktgen_net *pn, struct net_device *dev)
1884{ 1894{
1885 struct pktgen_thread *t; 1895 struct pktgen_thread *t;
1886 1896
1887 list_for_each_entry(t, &pktgen_threads, th_list) { 1897 list_for_each_entry(t, &pn->pktgen_threads, th_list) {
1888 struct pktgen_dev *pkt_dev; 1898 struct pktgen_dev *pkt_dev;
1889 1899
1890 list_for_each_entry(pkt_dev, &t->if_list, list) { 1900 list_for_each_entry(pkt_dev, &t->if_list, list) {
1891 if (pkt_dev->odev != dev) 1901 if (pkt_dev->odev != dev)
1892 continue; 1902 continue;
1893 1903
1894 remove_proc_entry(pkt_dev->entry->name, pg_proc_dir); 1904 remove_proc_entry(pkt_dev->entry->name, pn->proc_dir);
1895 1905
1896 pkt_dev->entry = proc_create_data(dev->name, 0600, 1906 pkt_dev->entry = proc_create_data(dev->name, 0600,
1897 pg_proc_dir, 1907 pn->proc_dir,
1898 &pktgen_if_fops, 1908 &pktgen_if_fops,
1899 pkt_dev); 1909 pkt_dev);
1900 if (!pkt_dev->entry) 1910 if (!pkt_dev->entry)
@@ -1909,8 +1919,9 @@ static int pktgen_device_event(struct notifier_block *unused,
1909 unsigned long event, void *ptr) 1919 unsigned long event, void *ptr)
1910{ 1920{
1911 struct net_device *dev = ptr; 1921 struct net_device *dev = ptr;
1922 struct pktgen_net *pn = net_generic(dev_net(dev), pg_net_id);
1912 1923
1913 if (!net_eq(dev_net(dev), &init_net) || pktgen_exiting) 1924 if (pn->pktgen_exiting)
1914 return NOTIFY_DONE; 1925 return NOTIFY_DONE;
1915 1926
1916 /* It is OK that we do not hold the group lock right now, 1927 /* It is OK that we do not hold the group lock right now,
@@ -1919,18 +1930,19 @@ static int pktgen_device_event(struct notifier_block *unused,
1919 1930
1920 switch (event) { 1931 switch (event) {
1921 case NETDEV_CHANGENAME: 1932 case NETDEV_CHANGENAME:
1922 pktgen_change_name(dev); 1933 pktgen_change_name(pn, dev);
1923 break; 1934 break;
1924 1935
1925 case NETDEV_UNREGISTER: 1936 case NETDEV_UNREGISTER:
1926 pktgen_mark_device(dev->name); 1937 pktgen_mark_device(pn, dev->name);
1927 break; 1938 break;
1928 } 1939 }
1929 1940
1930 return NOTIFY_DONE; 1941 return NOTIFY_DONE;
1931} 1942}
1932 1943
1933static struct net_device *pktgen_dev_get_by_name(struct pktgen_dev *pkt_dev, 1944static struct net_device *pktgen_dev_get_by_name(const struct pktgen_net *pn,
1945 struct pktgen_dev *pkt_dev,
1934 const char *ifname) 1946 const char *ifname)
1935{ 1947{
1936 char b[IFNAMSIZ+5]; 1948 char b[IFNAMSIZ+5];
@@ -1944,13 +1956,14 @@ static struct net_device *pktgen_dev_get_by_name(struct pktgen_dev *pkt_dev,
1944 } 1956 }
1945 b[i] = 0; 1957 b[i] = 0;
1946 1958
1947 return dev_get_by_name(&init_net, b); 1959 return dev_get_by_name(pn->net, b);
1948} 1960}
1949 1961
1950 1962
1951/* Associate pktgen_dev with a device. */ 1963/* Associate pktgen_dev with a device. */
1952 1964
1953static int pktgen_setup_dev(struct pktgen_dev *pkt_dev, const char *ifname) 1965static int pktgen_setup_dev(const struct pktgen_net *pn,
1966 struct pktgen_dev *pkt_dev, const char *ifname)
1954{ 1967{
1955 struct net_device *odev; 1968 struct net_device *odev;
1956 int err; 1969 int err;
@@ -1961,7 +1974,7 @@ static int pktgen_setup_dev(struct pktgen_dev *pkt_dev, const char *ifname)
1961 pkt_dev->odev = NULL; 1974 pkt_dev->odev = NULL;
1962 } 1975 }
1963 1976
1964 odev = pktgen_dev_get_by_name(pkt_dev, ifname); 1977 odev = pktgen_dev_get_by_name(pn, pkt_dev, ifname);
1965 if (!odev) { 1978 if (!odev) {
1966 pr_err("no such netdevice: \"%s\"\n", ifname); 1979 pr_err("no such netdevice: \"%s\"\n", ifname);
1967 return -ENODEV; 1980 return -ENODEV;
@@ -2203,9 +2216,10 @@ static inline int f_pick(struct pktgen_dev *pkt_dev)
2203static void get_ipsec_sa(struct pktgen_dev *pkt_dev, int flow) 2216static void get_ipsec_sa(struct pktgen_dev *pkt_dev, int flow)
2204{ 2217{
2205 struct xfrm_state *x = pkt_dev->flows[flow].x; 2218 struct xfrm_state *x = pkt_dev->flows[flow].x;
2219 struct pktgen_net *pn = net_generic(dev_net(pkt_dev->odev), pg_net_id);
2206 if (!x) { 2220 if (!x) {
2207 /*slow path: we dont already have xfrm_state*/ 2221 /*slow path: we dont already have xfrm_state*/
2208 x = xfrm_stateonly_find(&init_net, DUMMY_MARK, 2222 x = xfrm_stateonly_find(pn->net, DUMMY_MARK,
2209 (xfrm_address_t *)&pkt_dev->cur_daddr, 2223 (xfrm_address_t *)&pkt_dev->cur_daddr,
2210 (xfrm_address_t *)&pkt_dev->cur_saddr, 2224 (xfrm_address_t *)&pkt_dev->cur_saddr,
2211 AF_INET, 2225 AF_INET,
@@ -2912,7 +2926,7 @@ static void pktgen_run(struct pktgen_thread *t)
2912 t->control &= ~(T_STOP); 2926 t->control &= ~(T_STOP);
2913} 2927}
2914 2928
2915static void pktgen_stop_all_threads_ifs(void) 2929static void pktgen_stop_all_threads_ifs(struct pktgen_net *pn)
2916{ 2930{
2917 struct pktgen_thread *t; 2931 struct pktgen_thread *t;
2918 2932
@@ -2920,7 +2934,7 @@ static void pktgen_stop_all_threads_ifs(void)
2920 2934
2921 mutex_lock(&pktgen_thread_lock); 2935 mutex_lock(&pktgen_thread_lock);
2922 2936
2923 list_for_each_entry(t, &pktgen_threads, th_list) 2937 list_for_each_entry(t, &pn->pktgen_threads, th_list)
2924 t->control |= T_STOP; 2938 t->control |= T_STOP;
2925 2939
2926 mutex_unlock(&pktgen_thread_lock); 2940 mutex_unlock(&pktgen_thread_lock);
@@ -2956,28 +2970,28 @@ signal:
2956 return 0; 2970 return 0;
2957} 2971}
2958 2972
2959static int pktgen_wait_all_threads_run(void) 2973static int pktgen_wait_all_threads_run(struct pktgen_net *pn)
2960{ 2974{
2961 struct pktgen_thread *t; 2975 struct pktgen_thread *t;
2962 int sig = 1; 2976 int sig = 1;
2963 2977
2964 mutex_lock(&pktgen_thread_lock); 2978 mutex_lock(&pktgen_thread_lock);
2965 2979
2966 list_for_each_entry(t, &pktgen_threads, th_list) { 2980 list_for_each_entry(t, &pn->pktgen_threads, th_list) {
2967 sig = pktgen_wait_thread_run(t); 2981 sig = pktgen_wait_thread_run(t);
2968 if (sig == 0) 2982 if (sig == 0)
2969 break; 2983 break;
2970 } 2984 }
2971 2985
2972 if (sig == 0) 2986 if (sig == 0)
2973 list_for_each_entry(t, &pktgen_threads, th_list) 2987 list_for_each_entry(t, &pn->pktgen_threads, th_list)
2974 t->control |= (T_STOP); 2988 t->control |= (T_STOP);
2975 2989
2976 mutex_unlock(&pktgen_thread_lock); 2990 mutex_unlock(&pktgen_thread_lock);
2977 return sig; 2991 return sig;
2978} 2992}
2979 2993
2980static void pktgen_run_all_threads(void) 2994static void pktgen_run_all_threads(struct pktgen_net *pn)
2981{ 2995{
2982 struct pktgen_thread *t; 2996 struct pktgen_thread *t;
2983 2997
@@ -2985,7 +2999,7 @@ static void pktgen_run_all_threads(void)
2985 2999
2986 mutex_lock(&pktgen_thread_lock); 3000 mutex_lock(&pktgen_thread_lock);
2987 3001
2988 list_for_each_entry(t, &pktgen_threads, th_list) 3002 list_for_each_entry(t, &pn->pktgen_threads, th_list)
2989 t->control |= (T_RUN); 3003 t->control |= (T_RUN);
2990 3004
2991 mutex_unlock(&pktgen_thread_lock); 3005 mutex_unlock(&pktgen_thread_lock);
@@ -2993,10 +3007,10 @@ static void pktgen_run_all_threads(void)
2993 /* Propagate thread->control */ 3007 /* Propagate thread->control */
2994 schedule_timeout_interruptible(msecs_to_jiffies(125)); 3008 schedule_timeout_interruptible(msecs_to_jiffies(125));
2995 3009
2996 pktgen_wait_all_threads_run(); 3010 pktgen_wait_all_threads_run(pn);
2997} 3011}
2998 3012
2999static void pktgen_reset_all_threads(void) 3013static void pktgen_reset_all_threads(struct pktgen_net *pn)
3000{ 3014{
3001 struct pktgen_thread *t; 3015 struct pktgen_thread *t;
3002 3016
@@ -3004,7 +3018,7 @@ static void pktgen_reset_all_threads(void)
3004 3018
3005 mutex_lock(&pktgen_thread_lock); 3019 mutex_lock(&pktgen_thread_lock);
3006 3020
3007 list_for_each_entry(t, &pktgen_threads, th_list) 3021 list_for_each_entry(t, &pn->pktgen_threads, th_list)
3008 t->control |= (T_REMDEVALL); 3022 t->control |= (T_REMDEVALL);
3009 3023
3010 mutex_unlock(&pktgen_thread_lock); 3024 mutex_unlock(&pktgen_thread_lock);
@@ -3012,7 +3026,7 @@ static void pktgen_reset_all_threads(void)
3012 /* Propagate thread->control */ 3026 /* Propagate thread->control */
3013 schedule_timeout_interruptible(msecs_to_jiffies(125)); 3027 schedule_timeout_interruptible(msecs_to_jiffies(125));
3014 3028
3015 pktgen_wait_all_threads_run(); 3029 pktgen_wait_all_threads_run(pn);
3016} 3030}
3017 3031
3018static void show_results(struct pktgen_dev *pkt_dev, int nr_frags) 3032static void show_results(struct pktgen_dev *pkt_dev, int nr_frags)
@@ -3154,9 +3168,7 @@ static void pktgen_rem_all_ifs(struct pktgen_thread *t)
3154static void pktgen_rem_thread(struct pktgen_thread *t) 3168static void pktgen_rem_thread(struct pktgen_thread *t)
3155{ 3169{
3156 /* Remove from the thread list */ 3170 /* Remove from the thread list */
3157 3171 remove_proc_entry(t->tsk->comm, t->net->proc_dir);
3158 remove_proc_entry(t->tsk->comm, pg_proc_dir);
3159
3160} 3172}
3161 3173
3162static void pktgen_resched(struct pktgen_dev *pkt_dev) 3174static void pktgen_resched(struct pktgen_dev *pkt_dev)
@@ -3302,7 +3314,7 @@ static int pktgen_thread_worker(void *arg)
3302 pkt_dev = next_to_run(t); 3314 pkt_dev = next_to_run(t);
3303 3315
3304 if (unlikely(!pkt_dev && t->control == 0)) { 3316 if (unlikely(!pkt_dev && t->control == 0)) {
3305 if (pktgen_exiting) 3317 if (t->net->pktgen_exiting)
3306 break; 3318 break;
3307 wait_event_interruptible_timeout(t->queue, 3319 wait_event_interruptible_timeout(t->queue,
3308 t->control != 0, 3320 t->control != 0,
@@ -3424,7 +3436,7 @@ static int pktgen_add_device(struct pktgen_thread *t, const char *ifname)
3424 3436
3425 /* We don't allow a device to be on several threads */ 3437 /* We don't allow a device to be on several threads */
3426 3438
3427 pkt_dev = __pktgen_NN_threads(ifname, FIND); 3439 pkt_dev = __pktgen_NN_threads(t->net, ifname, FIND);
3428 if (pkt_dev) { 3440 if (pkt_dev) {
3429 pr_err("ERROR: interface already used\n"); 3441 pr_err("ERROR: interface already used\n");
3430 return -EBUSY; 3442 return -EBUSY;
@@ -3459,13 +3471,13 @@ static int pktgen_add_device(struct pktgen_thread *t, const char *ifname)
3459 pkt_dev->svlan_id = 0xffff; 3471 pkt_dev->svlan_id = 0xffff;
3460 pkt_dev->node = -1; 3472 pkt_dev->node = -1;
3461 3473
3462 err = pktgen_setup_dev(pkt_dev, ifname); 3474 err = pktgen_setup_dev(t->net, pkt_dev, ifname);
3463 if (err) 3475 if (err)
3464 goto out1; 3476 goto out1;
3465 if (pkt_dev->odev->priv_flags & IFF_TX_SKB_SHARING) 3477 if (pkt_dev->odev->priv_flags & IFF_TX_SKB_SHARING)
3466 pkt_dev->clone_skb = pg_clone_skb_d; 3478 pkt_dev->clone_skb = pg_clone_skb_d;
3467 3479
3468 pkt_dev->entry = proc_create_data(ifname, 0600, pg_proc_dir, 3480 pkt_dev->entry = proc_create_data(ifname, 0600, t->net->proc_dir,
3469 &pktgen_if_fops, pkt_dev); 3481 &pktgen_if_fops, pkt_dev);
3470 if (!pkt_dev->entry) { 3482 if (!pkt_dev->entry) {
3471 pr_err("cannot create %s/%s procfs entry\n", 3483 pr_err("cannot create %s/%s procfs entry\n",
@@ -3490,7 +3502,7 @@ out1:
3490 return err; 3502 return err;
3491} 3503}
3492 3504
3493static int __init pktgen_create_thread(int cpu) 3505static int __net_init pktgen_create_thread(int cpu, struct pktgen_net *pn)
3494{ 3506{
3495 struct pktgen_thread *t; 3507 struct pktgen_thread *t;
3496 struct proc_dir_entry *pe; 3508 struct proc_dir_entry *pe;
@@ -3508,7 +3520,7 @@ static int __init pktgen_create_thread(int cpu)
3508 3520
3509 INIT_LIST_HEAD(&t->if_list); 3521 INIT_LIST_HEAD(&t->if_list);
3510 3522
3511 list_add_tail(&t->th_list, &pktgen_threads); 3523 list_add_tail(&t->th_list, &pn->pktgen_threads);
3512 init_completion(&t->start_done); 3524 init_completion(&t->start_done);
3513 3525
3514 p = kthread_create_on_node(pktgen_thread_worker, 3526 p = kthread_create_on_node(pktgen_thread_worker,
@@ -3524,7 +3536,7 @@ static int __init pktgen_create_thread(int cpu)
3524 kthread_bind(p, cpu); 3536 kthread_bind(p, cpu);
3525 t->tsk = p; 3537 t->tsk = p;
3526 3538
3527 pe = proc_create_data(t->tsk->comm, 0600, pg_proc_dir, 3539 pe = proc_create_data(t->tsk->comm, 0600, pn->proc_dir,
3528 &pktgen_thread_fops, t); 3540 &pktgen_thread_fops, t);
3529 if (!pe) { 3541 if (!pe) {
3530 pr_err("cannot create %s/%s procfs entry\n", 3542 pr_err("cannot create %s/%s procfs entry\n",
@@ -3535,6 +3547,7 @@ static int __init pktgen_create_thread(int cpu)
3535 return -EINVAL; 3547 return -EINVAL;
3536 } 3548 }
3537 3549
3550 t->net = pn;
3538 wake_up_process(p); 3551 wake_up_process(p);
3539 wait_for_completion(&t->start_done); 3552 wait_for_completion(&t->start_done);
3540 3553
@@ -3560,6 +3573,7 @@ static void _rem_dev_from_if_list(struct pktgen_thread *t,
3560static int pktgen_remove_device(struct pktgen_thread *t, 3573static int pktgen_remove_device(struct pktgen_thread *t,
3561 struct pktgen_dev *pkt_dev) 3574 struct pktgen_dev *pkt_dev)
3562{ 3575{
3576 struct pktgen_net *pn = t->net;
3563 3577
3564 pr_debug("remove_device pkt_dev=%p\n", pkt_dev); 3578 pr_debug("remove_device pkt_dev=%p\n", pkt_dev);
3565 3579
@@ -3580,7 +3594,7 @@ static int pktgen_remove_device(struct pktgen_thread *t,
3580 _rem_dev_from_if_list(t, pkt_dev); 3594 _rem_dev_from_if_list(t, pkt_dev);
3581 3595
3582 if (pkt_dev->entry) 3596 if (pkt_dev->entry)
3583 remove_proc_entry(pkt_dev->entry->name, pg_proc_dir); 3597 remove_proc_entry(pkt_dev->entry->name, pn->proc_dir);
3584 3598
3585#ifdef CONFIG_XFRM 3599#ifdef CONFIG_XFRM
3586 free_SAs(pkt_dev); 3600 free_SAs(pkt_dev);
@@ -3592,63 +3606,63 @@ static int pktgen_remove_device(struct pktgen_thread *t,
3592 return 0; 3606 return 0;
3593} 3607}
3594 3608
3595static int __init pg_init(void) 3609static int __net_init pg_net_init(struct net *net)
3596{ 3610{
3597 int cpu; 3611 struct pktgen_net *pn = net_generic(net, pg_net_id);
3598 struct proc_dir_entry *pe; 3612 struct proc_dir_entry *pe;
3599 int ret = 0; 3613 int cpu, ret = 0;
3600 3614
3601 pr_info("%s", version); 3615 pn->net = net;
3602 3616 INIT_LIST_HEAD(&pn->pktgen_threads);
3603 pg_proc_dir = proc_mkdir(PG_PROC_DIR, init_net.proc_net); 3617 pn->pktgen_exiting = false;
3604 if (!pg_proc_dir) 3618 pn->proc_dir = proc_mkdir(PG_PROC_DIR, pn->net->proc_net);
3619 if (!pn->proc_dir) {
3620 pr_warn("cannot create /proc/net/%s\n", PG_PROC_DIR);
3605 return -ENODEV; 3621 return -ENODEV;
3606 3622 }
3607 pe = proc_create(PGCTRL, 0600, pg_proc_dir, &pktgen_fops); 3623 pe = proc_create(PGCTRL, 0600, pn->proc_dir, &pktgen_fops);
3608 if (pe == NULL) { 3624 if (pe == NULL) {
3609 pr_err("ERROR: cannot create %s procfs entry\n", PGCTRL); 3625 pr_err("cannot create %s procfs entry\n", PGCTRL);
3610 ret = -EINVAL; 3626 ret = -EINVAL;
3611 goto remove_dir; 3627 goto remove;
3612 } 3628 }
3613 3629
3614 register_netdevice_notifier(&pktgen_notifier_block);
3615
3616 for_each_online_cpu(cpu) { 3630 for_each_online_cpu(cpu) {
3617 int err; 3631 int err;
3618 3632
3619 err = pktgen_create_thread(cpu); 3633 err = pktgen_create_thread(cpu, pn);
3620 if (err) 3634 if (err)
3621 pr_warning("WARNING: Cannot create thread for cpu %d (%d)\n", 3635 pr_warn("Cannot create thread for cpu %d (%d)\n",
3622 cpu, err); 3636 cpu, err);
3623 } 3637 }
3624 3638
3625 if (list_empty(&pktgen_threads)) { 3639 if (list_empty(&pn->pktgen_threads)) {
3626 pr_err("ERROR: Initialization failed for all threads\n"); 3640 pr_err("Initialization failed for all threads\n");
3627 ret = -ENODEV; 3641 ret = -ENODEV;
3628 goto unregister; 3642 goto remove_entry;
3629 } 3643 }
3630 3644
3631 return 0; 3645 return 0;
3632 3646
3633 unregister: 3647remove_entry:
3634 unregister_netdevice_notifier(&pktgen_notifier_block); 3648 remove_proc_entry(PGCTRL, pn->proc_dir);
3635 remove_proc_entry(PGCTRL, pg_proc_dir); 3649remove:
3636 remove_dir: 3650 proc_net_remove(pn->net, PG_PROC_DIR);
3637 proc_net_remove(&init_net, PG_PROC_DIR);
3638 return ret; 3651 return ret;
3639} 3652}
3640 3653
3641static void __exit pg_cleanup(void) 3654static void __net_exit pg_net_exit(struct net *net)
3642{ 3655{
3656 struct pktgen_net *pn = net_generic(net, pg_net_id);
3643 struct pktgen_thread *t; 3657 struct pktgen_thread *t;
3644 struct list_head *q, *n; 3658 struct list_head *q, *n;
3645 LIST_HEAD(list); 3659 LIST_HEAD(list);
3646 3660
3647 /* Stop all interfaces & threads */ 3661 /* Stop all interfaces & threads */
3648 pktgen_exiting = true; 3662 pn->pktgen_exiting = true;
3649 3663
3650 mutex_lock(&pktgen_thread_lock); 3664 mutex_lock(&pktgen_thread_lock);
3651 list_splice_init(&pktgen_threads, &list); 3665 list_splice_init(&pn->pktgen_threads, &list);
3652 mutex_unlock(&pktgen_thread_lock); 3666 mutex_unlock(&pktgen_thread_lock);
3653 3667
3654 list_for_each_safe(q, n, &list) { 3668 list_for_each_safe(q, n, &list) {
@@ -3658,12 +3672,36 @@ static void __exit pg_cleanup(void)
3658 kfree(t); 3672 kfree(t);
3659 } 3673 }
3660 3674
3661 /* Un-register us from receiving netdevice events */ 3675 remove_proc_entry(PGCTRL, pn->proc_dir);
3662 unregister_netdevice_notifier(&pktgen_notifier_block); 3676 proc_net_remove(pn->net, PG_PROC_DIR);
3677}
3678
3679static struct pernet_operations pg_net_ops = {
3680 .init = pg_net_init,
3681 .exit = pg_net_exit,
3682 .id = &pg_net_id,
3683 .size = sizeof(struct pktgen_net),
3684};
3685
3686static int __init pg_init(void)
3687{
3688 int ret = 0;
3663 3689
3664 /* Clean up proc file system */ 3690 pr_info("%s", version);
3665 remove_proc_entry(PGCTRL, pg_proc_dir); 3691 ret = register_pernet_subsys(&pg_net_ops);
3666 proc_net_remove(&init_net, PG_PROC_DIR); 3692 if (ret)
3693 return ret;
3694 ret = register_netdevice_notifier(&pktgen_notifier_block);
3695 if (ret)
3696 unregister_pernet_subsys(&pg_net_ops);
3697
3698 return ret;
3699}
3700
3701static void __exit pg_cleanup(void)
3702{
3703 unregister_netdevice_notifier(&pktgen_notifier_block);
3704 unregister_pernet_subsys(&pg_net_ops);
3667} 3705}
3668 3706
3669module_init(pg_init); 3707module_init(pg_init);