pktgen.c (4e58a0275015e5c8988bda9cd0635e2ef405c985) | pktgen.c (604dfd6efc9b79bce432f2394791708d8e8f6efc) |
---|---|
1/* 2 * Authors: 3 * Copyright 2001, 2002 by Robert Olsson <robert.olsson@its.uu.se> 4 * Uppsala University and 5 * Swedish University of Agricultural Sciences 6 * 7 * Alexey Kuznetsov <kuznet@ms2.inr.ac.ru> 8 * Ben Greear <greearb@candelatech.com> --- 150 unchanged lines hidden (view full) --- 159#include <linux/prefetch.h> 160#include <net/net_namespace.h> 161#include <net/checksum.h> 162#include <net/ipv6.h> 163#include <net/addrconf.h> 164#ifdef CONFIG_XFRM 165#include <net/xfrm.h> 166#endif | 1/* 2 * Authors: 3 * Copyright 2001, 2002 by Robert Olsson <robert.olsson@its.uu.se> 4 * Uppsala University and 5 * Swedish University of Agricultural Sciences 6 * 7 * Alexey Kuznetsov <kuznet@ms2.inr.ac.ru> 8 * Ben Greear <greearb@candelatech.com> --- 150 unchanged lines hidden (view full) --- 159#include <linux/prefetch.h> 160#include <net/net_namespace.h> 161#include <net/checksum.h> 162#include <net/ipv6.h> 163#include <net/addrconf.h> 164#ifdef CONFIG_XFRM 165#include <net/xfrm.h> 166#endif |
167#include <net/netns/generic.h> | |
168#include <asm/byteorder.h> 169#include <linux/rcupdate.h> 170#include <linux/bitops.h> 171#include <linux/io.h> 172#include <linux/timex.h> 173#include <linux/uaccess.h> 174#include <asm/dma.h> 175#include <asm/div64.h> /* do_div */ --- 32 unchanged lines hidden (view full) --- 208/* If lock -- can be removed after some work */ 209#define if_lock(t) spin_lock(&(t->if_lock)); 210#define if_unlock(t) spin_unlock(&(t->if_lock)); 211 212/* Used to help with determining the pkts on receive */ 213#define PKTGEN_MAGIC 0xbe9be955 214#define PG_PROC_DIR "pktgen" 215#define PGCTRL "pgctrl" | 167#include <asm/byteorder.h> 168#include <linux/rcupdate.h> 169#include <linux/bitops.h> 170#include <linux/io.h> 171#include <linux/timex.h> 172#include <linux/uaccess.h> 173#include <asm/dma.h> 174#include <asm/div64.h> /* do_div */ --- 32 unchanged lines hidden (view full) --- 207/* If lock -- can be removed after some work */ 208#define if_lock(t) spin_lock(&(t->if_lock)); 209#define if_unlock(t) spin_unlock(&(t->if_lock)); 210 211/* Used to help with determining the pkts on receive */ 212#define PKTGEN_MAGIC 0xbe9be955 213#define PG_PROC_DIR "pktgen" 214#define PGCTRL "pgctrl" |
215static struct proc_dir_entry *pg_proc_dir; |
|
216 217#define MAX_CFLOWS 65536 218 219#define VLAN_TAG_SIZE(x) ((x)->vlan_id == 0xffff ? 0 : 4) 220#define SVLAN_TAG_SIZE(x) ((x)->svlan_id == 0xffff ? 0 : 4) 221 222struct flow_state { 223 __be32 cur_daddr; --- 168 unchanged lines hidden (view full) --- 392 393struct pktgen_hdr { 394 __be32 pgh_magic; 395 __be32 seq_num; 396 __be32 tv_sec; 397 __be32 tv_usec; 398}; 399 | 216 217#define MAX_CFLOWS 65536 218 219#define VLAN_TAG_SIZE(x) ((x)->vlan_id == 0xffff ? 0 : 4) 220#define SVLAN_TAG_SIZE(x) ((x)->svlan_id == 0xffff ? 0 : 4) 221 222struct flow_state { 223 __be32 cur_daddr; --- 168 unchanged lines hidden (view full) --- 392 393struct pktgen_hdr { 394 __be32 pgh_magic; 395 __be32 seq_num; 396 __be32 tv_sec; 397 __be32 tv_usec; 398}; 399 |
400static bool pktgen_exiting __read_mostly; |
|
400 | 401 |
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}; 409 | |
410struct pktgen_thread { 411 spinlock_t if_lock; /* for list of devices */ 412 struct list_head if_list; /* All device here */ 413 struct list_head th_list; 414 struct task_struct *tsk; 415 char result[512]; 416 417 /* Field for thread to receive "posted" events terminate, 418 stop ifs etc. */ 419 420 u32 control; 421 int cpu; 422 423 wait_queue_head_t queue; 424 struct completion start_done; | 402struct pktgen_thread { 403 spinlock_t if_lock; /* for list of devices */ 404 struct list_head if_list; /* All device here */ 405 struct list_head th_list; 406 struct task_struct *tsk; 407 char result[512]; 408 409 /* Field for thread to receive "posted" events terminate, 410 stop ifs etc. */ 411 412 u32 control; 413 int cpu; 414 415 wait_queue_head_t queue; 416 struct completion start_done; |
425 struct pktgen_net *net; | |
426}; 427 428#define REMOVE 1 429#define FIND 0 430 431static const char version[] = 432 "Packet Generator for packet performance testing. " 433 "Version: " VERSION "\n"; 434 435static int pktgen_remove_device(struct pktgen_thread *t, struct pktgen_dev *i); 436static int pktgen_add_device(struct pktgen_thread *t, const char *ifname); 437static struct pktgen_dev *pktgen_find_dev(struct pktgen_thread *t, 438 const char *ifname, bool exact); 439static int pktgen_device_event(struct notifier_block *, unsigned long, void *); | 417}; 418 419#define REMOVE 1 420#define FIND 0 421 422static const char version[] = 423 "Packet Generator for packet performance testing. " 424 "Version: " VERSION "\n"; 425 426static int pktgen_remove_device(struct pktgen_thread *t, struct pktgen_dev *i); 427static int pktgen_add_device(struct pktgen_thread *t, const char *ifname); 428static struct pktgen_dev *pktgen_find_dev(struct pktgen_thread *t, 429 const char *ifname, bool exact); 430static int pktgen_device_event(struct notifier_block *, unsigned long, void *); |
440static void pktgen_run_all_threads(struct pktgen_net *pn); 441static void pktgen_reset_all_threads(struct pktgen_net *pn); 442static void pktgen_stop_all_threads_ifs(struct pktgen_net *pn); | 431static void pktgen_run_all_threads(void); 432static void pktgen_reset_all_threads(void); 433static void pktgen_stop_all_threads_ifs(void); |
443 444static void pktgen_stop(struct pktgen_thread *t); 445static void pktgen_clear_counters(struct pktgen_dev *pkt_dev); 446 447/* Module parameters, defaults. */ 448static int pg_count_d __read_mostly = 1000; 449static int pg_delay_d __read_mostly; 450static int pg_clone_skb_d __read_mostly; 451static int debug __read_mostly; 452 453static DEFINE_MUTEX(pktgen_thread_lock); | 434 435static void pktgen_stop(struct pktgen_thread *t); 436static void pktgen_clear_counters(struct pktgen_dev *pkt_dev); 437 438/* Module parameters, defaults. */ 439static int pg_count_d __read_mostly = 1000; 440static int pg_delay_d __read_mostly; 441static int pg_clone_skb_d __read_mostly; 442static int debug __read_mostly; 443 444static DEFINE_MUTEX(pktgen_thread_lock); |
445static LIST_HEAD(pktgen_threads); |
|
454 455static struct notifier_block pktgen_notifier_block = { 456 .notifier_call = pktgen_device_event, 457}; 458 459/* 460 * /proc handling functions 461 * --- 5 unchanged lines hidden (view full) --- 467 return 0; 468} 469 470static ssize_t pgctrl_write(struct file *file, const char __user *buf, 471 size_t count, loff_t *ppos) 472{ 473 int err = 0; 474 char data[128]; | 446 447static struct notifier_block pktgen_notifier_block = { 448 .notifier_call = pktgen_device_event, 449}; 450 451/* 452 * /proc handling functions 453 * --- 5 unchanged lines hidden (view full) --- 459 return 0; 460} 461 462static ssize_t pgctrl_write(struct file *file, const char __user *buf, 463 size_t count, loff_t *ppos) 464{ 465 int err = 0; 466 char data[128]; |
475 struct pktgen_net *pn = net_generic(current->nsproxy->net_ns, pg_net_id); | |
476 477 if (!capable(CAP_NET_ADMIN)) { 478 err = -EPERM; 479 goto out; 480 } 481 482 if (count > sizeof(data)) 483 count = sizeof(data); 484 485 if (copy_from_user(data, buf, count)) { 486 err = -EFAULT; 487 goto out; 488 } 489 data[count - 1] = 0; /* Make string */ 490 491 if (!strcmp(data, "stop")) | 467 468 if (!capable(CAP_NET_ADMIN)) { 469 err = -EPERM; 470 goto out; 471 } 472 473 if (count > sizeof(data)) 474 count = sizeof(data); 475 476 if (copy_from_user(data, buf, count)) { 477 err = -EFAULT; 478 goto out; 479 } 480 data[count - 1] = 0; /* Make string */ 481 482 if (!strcmp(data, "stop")) |
492 pktgen_stop_all_threads_ifs(pn); | 483 pktgen_stop_all_threads_ifs(); |
493 494 else if (!strcmp(data, "start")) | 484 485 else if (!strcmp(data, "start")) |
495 pktgen_run_all_threads(pn); | 486 pktgen_run_all_threads(); |
496 497 else if (!strcmp(data, "reset")) | 487 488 else if (!strcmp(data, "reset")) |
498 pktgen_reset_all_threads(pn); | 489 pktgen_reset_all_threads(); |
499 500 else 501 pr_warning("Unknown command: %s\n", data); 502 503 err = count; 504 505out: 506 return err; --- 1278 unchanged lines hidden (view full) --- 1785 if (len < 0) { 1786 ret = len; 1787 goto out; 1788 } 1789 if (copy_from_user(f, &user_buffer[i], len)) 1790 return -EFAULT; 1791 i += len; 1792 mutex_lock(&pktgen_thread_lock); | 490 491 else 492 pr_warning("Unknown command: %s\n", data); 493 494 err = count; 495 496out: 497 return err; --- 1278 unchanged lines hidden (view full) --- 1776 if (len < 0) { 1777 ret = len; 1778 goto out; 1779 } 1780 if (copy_from_user(f, &user_buffer[i], len)) 1781 return -EFAULT; 1782 i += len; 1783 mutex_lock(&pktgen_thread_lock); |
1793 pktgen_add_device(t, f); | 1784 ret = pktgen_add_device(t, f); |
1794 mutex_unlock(&pktgen_thread_lock); | 1785 mutex_unlock(&pktgen_thread_lock); |
1795 ret = count; 1796 sprintf(pg_result, "OK: add_device=%s", f); | 1786 if (!ret) { 1787 ret = count; 1788 sprintf(pg_result, "OK: add_device=%s", f); 1789 } else 1790 sprintf(pg_result, "ERROR: can not add device %s", f); |
1797 goto out; 1798 } 1799 1800 if (!strcmp(name, "rem_device_all")) { 1801 mutex_lock(&pktgen_thread_lock); 1802 t->control |= T_REMDEVALL; 1803 mutex_unlock(&pktgen_thread_lock); 1804 schedule_timeout_interruptible(msecs_to_jiffies(125)); /* Propagate thread->control */ --- 23 unchanged lines hidden (view full) --- 1828 .open = pktgen_thread_open, 1829 .read = seq_read, 1830 .llseek = seq_lseek, 1831 .write = pktgen_thread_write, 1832 .release = single_release, 1833}; 1834 1835/* Think find or remove for NN */ | 1791 goto out; 1792 } 1793 1794 if (!strcmp(name, "rem_device_all")) { 1795 mutex_lock(&pktgen_thread_lock); 1796 t->control |= T_REMDEVALL; 1797 mutex_unlock(&pktgen_thread_lock); 1798 schedule_timeout_interruptible(msecs_to_jiffies(125)); /* Propagate thread->control */ --- 23 unchanged lines hidden (view full) --- 1822 .open = pktgen_thread_open, 1823 .read = seq_read, 1824 .llseek = seq_lseek, 1825 .write = pktgen_thread_write, 1826 .release = single_release, 1827}; 1828 1829/* Think find or remove for NN */ |
1836static struct pktgen_dev *__pktgen_NN_threads(const struct pktgen_net *pn, 1837 const char *ifname, int remove) | 1830static struct pktgen_dev *__pktgen_NN_threads(const char *ifname, int remove) |
1838{ 1839 struct pktgen_thread *t; 1840 struct pktgen_dev *pkt_dev = NULL; 1841 bool exact = (remove == FIND); 1842 | 1831{ 1832 struct pktgen_thread *t; 1833 struct pktgen_dev *pkt_dev = NULL; 1834 bool exact = (remove == FIND); 1835 |
1843 list_for_each_entry(t, &pn->pktgen_threads, th_list) { | 1836 list_for_each_entry(t, &pktgen_threads, th_list) { |
1844 pkt_dev = pktgen_find_dev(t, ifname, exact); 1845 if (pkt_dev) { 1846 if (remove) { 1847 if_lock(t); 1848 pkt_dev->removal_mark = 1; 1849 t->control |= T_REMDEV; 1850 if_unlock(t); 1851 } 1852 break; 1853 } 1854 } 1855 return pkt_dev; 1856} 1857 1858/* 1859 * mark a device for removal 1860 */ | 1837 pkt_dev = pktgen_find_dev(t, ifname, exact); 1838 if (pkt_dev) { 1839 if (remove) { 1840 if_lock(t); 1841 pkt_dev->removal_mark = 1; 1842 t->control |= T_REMDEV; 1843 if_unlock(t); 1844 } 1845 break; 1846 } 1847 } 1848 return pkt_dev; 1849} 1850 1851/* 1852 * mark a device for removal 1853 */ |
1861static void pktgen_mark_device(const struct pktgen_net *pn, const char *ifname) | 1854static void pktgen_mark_device(const char *ifname) |
1862{ 1863 struct pktgen_dev *pkt_dev = NULL; 1864 const int max_tries = 10, msec_per_try = 125; 1865 int i = 0; 1866 1867 mutex_lock(&pktgen_thread_lock); 1868 pr_debug("%s: marking %s for removal\n", __func__, ifname); 1869 1870 while (1) { 1871 | 1855{ 1856 struct pktgen_dev *pkt_dev = NULL; 1857 const int max_tries = 10, msec_per_try = 125; 1858 int i = 0; 1859 1860 mutex_lock(&pktgen_thread_lock); 1861 pr_debug("%s: marking %s for removal\n", __func__, ifname); 1862 1863 while (1) { 1864 |
1872 pkt_dev = __pktgen_NN_threads(pn, ifname, REMOVE); | 1865 pkt_dev = __pktgen_NN_threads(ifname, REMOVE); |
1873 if (pkt_dev == NULL) 1874 break; /* success */ 1875 1876 mutex_unlock(&pktgen_thread_lock); 1877 pr_debug("%s: waiting for %s to disappear....\n", 1878 __func__, ifname); 1879 schedule_timeout_interruptible(msecs_to_jiffies(msec_per_try)); 1880 mutex_lock(&pktgen_thread_lock); --- 4 unchanged lines hidden (view full) --- 1885 break; 1886 } 1887 1888 } 1889 1890 mutex_unlock(&pktgen_thread_lock); 1891} 1892 | 1866 if (pkt_dev == NULL) 1867 break; /* success */ 1868 1869 mutex_unlock(&pktgen_thread_lock); 1870 pr_debug("%s: waiting for %s to disappear....\n", 1871 __func__, ifname); 1872 schedule_timeout_interruptible(msecs_to_jiffies(msec_per_try)); 1873 mutex_lock(&pktgen_thread_lock); --- 4 unchanged lines hidden (view full) --- 1878 break; 1879 } 1880 1881 } 1882 1883 mutex_unlock(&pktgen_thread_lock); 1884} 1885 |
1893static void pktgen_change_name(const struct pktgen_net *pn, struct net_device *dev) | 1886static void pktgen_change_name(struct net_device *dev) |
1894{ 1895 struct pktgen_thread *t; 1896 | 1887{ 1888 struct pktgen_thread *t; 1889 |
1897 list_for_each_entry(t, &pn->pktgen_threads, th_list) { | 1890 list_for_each_entry(t, &pktgen_threads, th_list) { |
1898 struct pktgen_dev *pkt_dev; 1899 1900 list_for_each_entry(pkt_dev, &t->if_list, list) { 1901 if (pkt_dev->odev != dev) 1902 continue; 1903 | 1891 struct pktgen_dev *pkt_dev; 1892 1893 list_for_each_entry(pkt_dev, &t->if_list, list) { 1894 if (pkt_dev->odev != dev) 1895 continue; 1896 |
1904 remove_proc_entry(pkt_dev->entry->name, pn->proc_dir); | 1897 remove_proc_entry(pkt_dev->entry->name, pg_proc_dir); |
1905 1906 pkt_dev->entry = proc_create_data(dev->name, 0600, | 1898 1899 pkt_dev->entry = proc_create_data(dev->name, 0600, |
1907 pn->proc_dir, | 1900 pg_proc_dir, |
1908 &pktgen_if_fops, 1909 pkt_dev); 1910 if (!pkt_dev->entry) 1911 pr_err("can't move proc entry for '%s'\n", 1912 dev->name); 1913 break; 1914 } 1915 } 1916} 1917 1918static int pktgen_device_event(struct notifier_block *unused, 1919 unsigned long event, void *ptr) 1920{ 1921 struct net_device *dev = ptr; | 1901 &pktgen_if_fops, 1902 pkt_dev); 1903 if (!pkt_dev->entry) 1904 pr_err("can't move proc entry for '%s'\n", 1905 dev->name); 1906 break; 1907 } 1908 } 1909} 1910 1911static int pktgen_device_event(struct notifier_block *unused, 1912 unsigned long event, void *ptr) 1913{ 1914 struct net_device *dev = ptr; |
1922 struct pktgen_net *pn = net_generic(dev_net(dev), pg_net_id); | |
1923 | 1915 |
1924 if (pn->pktgen_exiting) | 1916 if (!net_eq(dev_net(dev), &init_net) || pktgen_exiting) |
1925 return NOTIFY_DONE; 1926 1927 /* It is OK that we do not hold the group lock right now, 1928 * as we run under the RTNL lock. 1929 */ 1930 1931 switch (event) { 1932 case NETDEV_CHANGENAME: | 1917 return NOTIFY_DONE; 1918 1919 /* It is OK that we do not hold the group lock right now, 1920 * as we run under the RTNL lock. 1921 */ 1922 1923 switch (event) { 1924 case NETDEV_CHANGENAME: |
1933 pktgen_change_name(pn, dev); | 1925 pktgen_change_name(dev); |
1934 break; 1935 1936 case NETDEV_UNREGISTER: | 1926 break; 1927 1928 case NETDEV_UNREGISTER: |
1937 pktgen_mark_device(pn, dev->name); | 1929 pktgen_mark_device(dev->name); |
1938 break; 1939 } 1940 1941 return NOTIFY_DONE; 1942} 1943 | 1930 break; 1931 } 1932 1933 return NOTIFY_DONE; 1934} 1935 |
1944static struct net_device *pktgen_dev_get_by_name(const struct pktgen_net *pn, 1945 struct pktgen_dev *pkt_dev, | 1936static struct net_device *pktgen_dev_get_by_name(struct pktgen_dev *pkt_dev, |
1946 const char *ifname) 1947{ 1948 char b[IFNAMSIZ+5]; 1949 int i; 1950 1951 for (i = 0; ifname[i] != '@'; i++) { 1952 if (i == IFNAMSIZ) 1953 break; 1954 1955 b[i] = ifname[i]; 1956 } 1957 b[i] = 0; 1958 | 1937 const char *ifname) 1938{ 1939 char b[IFNAMSIZ+5]; 1940 int i; 1941 1942 for (i = 0; ifname[i] != '@'; i++) { 1943 if (i == IFNAMSIZ) 1944 break; 1945 1946 b[i] = ifname[i]; 1947 } 1948 b[i] = 0; 1949 |
1959 return dev_get_by_name(pn->net, b); | 1950 return dev_get_by_name(&init_net, b); |
1960} 1961 1962 1963/* Associate pktgen_dev with a device. */ 1964 | 1951} 1952 1953 1954/* Associate pktgen_dev with a device. */ 1955 |
1965static int pktgen_setup_dev(const struct pktgen_net *pn, 1966 struct pktgen_dev *pkt_dev, const char *ifname) | 1956static int pktgen_setup_dev(struct pktgen_dev *pkt_dev, const char *ifname) |
1967{ 1968 struct net_device *odev; 1969 int err; 1970 1971 /* Clean old setups */ 1972 if (pkt_dev->odev) { 1973 dev_put(pkt_dev->odev); 1974 pkt_dev->odev = NULL; 1975 } 1976 | 1957{ 1958 struct net_device *odev; 1959 int err; 1960 1961 /* Clean old setups */ 1962 if (pkt_dev->odev) { 1963 dev_put(pkt_dev->odev); 1964 pkt_dev->odev = NULL; 1965 } 1966 |
1977 odev = pktgen_dev_get_by_name(pn, pkt_dev, ifname); | 1967 odev = pktgen_dev_get_by_name(pkt_dev, ifname); |
1978 if (!odev) { 1979 pr_err("no such netdevice: \"%s\"\n", ifname); 1980 return -ENODEV; 1981 } 1982 1983 if (odev->type != ARPHRD_ETHER) { 1984 pr_err("not an ethernet device: \"%s\"\n", ifname); 1985 err = -EINVAL; --- 225 unchanged lines hidden (view full) --- 2211#ifdef CONFIG_XFRM 2212/* If there was already an IPSEC SA, we keep it as is, else 2213 * we go look for it ... 2214*/ 2215#define DUMMY_MARK 0 2216static void get_ipsec_sa(struct pktgen_dev *pkt_dev, int flow) 2217{ 2218 struct xfrm_state *x = pkt_dev->flows[flow].x; | 1968 if (!odev) { 1969 pr_err("no such netdevice: \"%s\"\n", ifname); 1970 return -ENODEV; 1971 } 1972 1973 if (odev->type != ARPHRD_ETHER) { 1974 pr_err("not an ethernet device: \"%s\"\n", ifname); 1975 err = -EINVAL; --- 225 unchanged lines hidden (view full) --- 2201#ifdef CONFIG_XFRM 2202/* If there was already an IPSEC SA, we keep it as is, else 2203 * we go look for it ... 2204*/ 2205#define DUMMY_MARK 0 2206static void get_ipsec_sa(struct pktgen_dev *pkt_dev, int flow) 2207{ 2208 struct xfrm_state *x = pkt_dev->flows[flow].x; |
2219 struct pktgen_net *pn = net_generic(dev_net(pkt_dev->odev), pg_net_id); | |
2220 if (!x) { 2221 /*slow path: we dont already have xfrm_state*/ | 2209 if (!x) { 2210 /*slow path: we dont already have xfrm_state*/ |
2222 x = xfrm_stateonly_find(pn->net, DUMMY_MARK, | 2211 x = xfrm_stateonly_find(&init_net, DUMMY_MARK, |
2223 (xfrm_address_t *)&pkt_dev->cur_daddr, 2224 (xfrm_address_t *)&pkt_dev->cur_saddr, 2225 AF_INET, 2226 pkt_dev->ipsmode, 2227 pkt_dev->ipsproto, 0); 2228 if (x) { 2229 pkt_dev->flows[flow].x = x; 2230 set_pkt_overhead(pkt_dev); --- 690 unchanged lines hidden (view full) --- 2921 } else 2922 strcpy(pkt_dev->result, "Error starting"); 2923 } 2924 if_unlock(t); 2925 if (started) 2926 t->control &= ~(T_STOP); 2927} 2928 | 2212 (xfrm_address_t *)&pkt_dev->cur_daddr, 2213 (xfrm_address_t *)&pkt_dev->cur_saddr, 2214 AF_INET, 2215 pkt_dev->ipsmode, 2216 pkt_dev->ipsproto, 0); 2217 if (x) { 2218 pkt_dev->flows[flow].x = x; 2219 set_pkt_overhead(pkt_dev); --- 690 unchanged lines hidden (view full) --- 2910 } else 2911 strcpy(pkt_dev->result, "Error starting"); 2912 } 2913 if_unlock(t); 2914 if (started) 2915 t->control &= ~(T_STOP); 2916} 2917 |
2929static void pktgen_stop_all_threads_ifs(struct pktgen_net *pn) | 2918static void pktgen_stop_all_threads_ifs(void) |
2930{ 2931 struct pktgen_thread *t; 2932 2933 func_enter(); 2934 2935 mutex_lock(&pktgen_thread_lock); 2936 | 2919{ 2920 struct pktgen_thread *t; 2921 2922 func_enter(); 2923 2924 mutex_lock(&pktgen_thread_lock); 2925 |
2937 list_for_each_entry(t, &pn->pktgen_threads, th_list) | 2926 list_for_each_entry(t, &pktgen_threads, th_list) |
2938 t->control |= T_STOP; 2939 2940 mutex_unlock(&pktgen_thread_lock); 2941} 2942 2943static int thread_is_running(const struct pktgen_thread *t) 2944{ 2945 const struct pktgen_dev *pkt_dev; --- 19 unchanged lines hidden (view full) --- 2965 if_lock(t); 2966 } 2967 if_unlock(t); 2968 return 1; 2969signal: 2970 return 0; 2971} 2972 | 2927 t->control |= T_STOP; 2928 2929 mutex_unlock(&pktgen_thread_lock); 2930} 2931 2932static int thread_is_running(const struct pktgen_thread *t) 2933{ 2934 const struct pktgen_dev *pkt_dev; --- 19 unchanged lines hidden (view full) --- 2954 if_lock(t); 2955 } 2956 if_unlock(t); 2957 return 1; 2958signal: 2959 return 0; 2960} 2961 |
2973static int pktgen_wait_all_threads_run(struct pktgen_net *pn) | 2962static int pktgen_wait_all_threads_run(void) |
2974{ 2975 struct pktgen_thread *t; 2976 int sig = 1; 2977 2978 mutex_lock(&pktgen_thread_lock); 2979 | 2963{ 2964 struct pktgen_thread *t; 2965 int sig = 1; 2966 2967 mutex_lock(&pktgen_thread_lock); 2968 |
2980 list_for_each_entry(t, &pn->pktgen_threads, th_list) { | 2969 list_for_each_entry(t, &pktgen_threads, th_list) { |
2981 sig = pktgen_wait_thread_run(t); 2982 if (sig == 0) 2983 break; 2984 } 2985 2986 if (sig == 0) | 2970 sig = pktgen_wait_thread_run(t); 2971 if (sig == 0) 2972 break; 2973 } 2974 2975 if (sig == 0) |
2987 list_for_each_entry(t, &pn->pktgen_threads, th_list) | 2976 list_for_each_entry(t, &pktgen_threads, th_list) |
2988 t->control |= (T_STOP); 2989 2990 mutex_unlock(&pktgen_thread_lock); 2991 return sig; 2992} 2993 | 2977 t->control |= (T_STOP); 2978 2979 mutex_unlock(&pktgen_thread_lock); 2980 return sig; 2981} 2982 |
2994static void pktgen_run_all_threads(struct pktgen_net *pn) | 2983static void pktgen_run_all_threads(void) |
2995{ 2996 struct pktgen_thread *t; 2997 2998 func_enter(); 2999 3000 mutex_lock(&pktgen_thread_lock); 3001 | 2984{ 2985 struct pktgen_thread *t; 2986 2987 func_enter(); 2988 2989 mutex_lock(&pktgen_thread_lock); 2990 |
3002 list_for_each_entry(t, &pn->pktgen_threads, th_list) | 2991 list_for_each_entry(t, &pktgen_threads, th_list) |
3003 t->control |= (T_RUN); 3004 3005 mutex_unlock(&pktgen_thread_lock); 3006 3007 /* Propagate thread->control */ 3008 schedule_timeout_interruptible(msecs_to_jiffies(125)); 3009 | 2992 t->control |= (T_RUN); 2993 2994 mutex_unlock(&pktgen_thread_lock); 2995 2996 /* Propagate thread->control */ 2997 schedule_timeout_interruptible(msecs_to_jiffies(125)); 2998 |
3010 pktgen_wait_all_threads_run(pn); | 2999 pktgen_wait_all_threads_run(); |
3011} 3012 | 3000} 3001 |
3013static void pktgen_reset_all_threads(struct pktgen_net *pn) | 3002static void pktgen_reset_all_threads(void) |
3014{ 3015 struct pktgen_thread *t; 3016 3017 func_enter(); 3018 3019 mutex_lock(&pktgen_thread_lock); 3020 | 3003{ 3004 struct pktgen_thread *t; 3005 3006 func_enter(); 3007 3008 mutex_lock(&pktgen_thread_lock); 3009 |
3021 list_for_each_entry(t, &pn->pktgen_threads, th_list) | 3010 list_for_each_entry(t, &pktgen_threads, th_list) |
3022 t->control |= (T_REMDEVALL); 3023 3024 mutex_unlock(&pktgen_thread_lock); 3025 3026 /* Propagate thread->control */ 3027 schedule_timeout_interruptible(msecs_to_jiffies(125)); 3028 | 3011 t->control |= (T_REMDEVALL); 3012 3013 mutex_unlock(&pktgen_thread_lock); 3014 3015 /* Propagate thread->control */ 3016 schedule_timeout_interruptible(msecs_to_jiffies(125)); 3017 |
3029 pktgen_wait_all_threads_run(pn); | 3018 pktgen_wait_all_threads_run(); |
3030} 3031 3032static void show_results(struct pktgen_dev *pkt_dev, int nr_frags) 3033{ 3034 __u64 bps, mbps, pps; 3035 char *p = pkt_dev->result; 3036 ktime_t elapsed = ktime_sub(pkt_dev->stopped_at, 3037 pkt_dev->started_at); --- 125 unchanged lines hidden (view full) --- 3163 } 3164 3165 if_unlock(t); 3166} 3167 3168static void pktgen_rem_thread(struct pktgen_thread *t) 3169{ 3170 /* Remove from the thread list */ | 3019} 3020 3021static void show_results(struct pktgen_dev *pkt_dev, int nr_frags) 3022{ 3023 __u64 bps, mbps, pps; 3024 char *p = pkt_dev->result; 3025 ktime_t elapsed = ktime_sub(pkt_dev->stopped_at, 3026 pkt_dev->started_at); --- 125 unchanged lines hidden (view full) --- 3152 } 3153 3154 if_unlock(t); 3155} 3156 3157static void pktgen_rem_thread(struct pktgen_thread *t) 3158{ 3159 /* Remove from the thread list */ |
3171 remove_proc_entry(t->tsk->comm, t->net->proc_dir); | 3160 3161 remove_proc_entry(t->tsk->comm, pg_proc_dir); 3162 |
3172} 3173 3174static void pktgen_resched(struct pktgen_dev *pkt_dev) 3175{ 3176 ktime_t idle_start = ktime_get(); 3177 schedule(); 3178 pkt_dev->idle_acc += ktime_to_ns(ktime_sub(ktime_get(), idle_start)); 3179} --- 129 unchanged lines hidden (view full) --- 3309 set_current_state(TASK_INTERRUPTIBLE); 3310 3311 set_freezable(); 3312 3313 while (!kthread_should_stop()) { 3314 pkt_dev = next_to_run(t); 3315 3316 if (unlikely(!pkt_dev && t->control == 0)) { | 3163} 3164 3165static void pktgen_resched(struct pktgen_dev *pkt_dev) 3166{ 3167 ktime_t idle_start = ktime_get(); 3168 schedule(); 3169 pkt_dev->idle_acc += ktime_to_ns(ktime_sub(ktime_get(), idle_start)); 3170} --- 129 unchanged lines hidden (view full) --- 3300 set_current_state(TASK_INTERRUPTIBLE); 3301 3302 set_freezable(); 3303 3304 while (!kthread_should_stop()) { 3305 pkt_dev = next_to_run(t); 3306 3307 if (unlikely(!pkt_dev && t->control == 0)) { |
3317 if (t->net->pktgen_exiting) | 3308 if (pktgen_exiting) |
3318 break; 3319 wait_event_interruptible_timeout(t->queue, 3320 t->control != 0, 3321 HZ/10); 3322 try_to_freeze(); 3323 continue; 3324 } 3325 --- 105 unchanged lines hidden (view full) --- 3431static int pktgen_add_device(struct pktgen_thread *t, const char *ifname) 3432{ 3433 struct pktgen_dev *pkt_dev; 3434 int err; 3435 int node = cpu_to_node(t->cpu); 3436 3437 /* We don't allow a device to be on several threads */ 3438 | 3309 break; 3310 wait_event_interruptible_timeout(t->queue, 3311 t->control != 0, 3312 HZ/10); 3313 try_to_freeze(); 3314 continue; 3315 } 3316 --- 105 unchanged lines hidden (view full) --- 3422static int pktgen_add_device(struct pktgen_thread *t, const char *ifname) 3423{ 3424 struct pktgen_dev *pkt_dev; 3425 int err; 3426 int node = cpu_to_node(t->cpu); 3427 3428 /* We don't allow a device to be on several threads */ 3429 |
3439 pkt_dev = __pktgen_NN_threads(t->net, ifname, FIND); | 3430 pkt_dev = __pktgen_NN_threads(ifname, FIND); |
3440 if (pkt_dev) { 3441 pr_err("ERROR: interface already used\n"); 3442 return -EBUSY; 3443 } 3444 3445 pkt_dev = kzalloc_node(sizeof(struct pktgen_dev), GFP_KERNEL, node); 3446 if (!pkt_dev) 3447 return -ENOMEM; --- 18 unchanged lines hidden (view full) --- 3466 pkt_dev->vlan_p = 0; 3467 pkt_dev->vlan_cfi = 0; 3468 pkt_dev->vlan_id = 0xffff; 3469 pkt_dev->svlan_p = 0; 3470 pkt_dev->svlan_cfi = 0; 3471 pkt_dev->svlan_id = 0xffff; 3472 pkt_dev->node = -1; 3473 | 3431 if (pkt_dev) { 3432 pr_err("ERROR: interface already used\n"); 3433 return -EBUSY; 3434 } 3435 3436 pkt_dev = kzalloc_node(sizeof(struct pktgen_dev), GFP_KERNEL, node); 3437 if (!pkt_dev) 3438 return -ENOMEM; --- 18 unchanged lines hidden (view full) --- 3457 pkt_dev->vlan_p = 0; 3458 pkt_dev->vlan_cfi = 0; 3459 pkt_dev->vlan_id = 0xffff; 3460 pkt_dev->svlan_p = 0; 3461 pkt_dev->svlan_cfi = 0; 3462 pkt_dev->svlan_id = 0xffff; 3463 pkt_dev->node = -1; 3464 |
3474 err = pktgen_setup_dev(t->net, pkt_dev, ifname); | 3465 err = pktgen_setup_dev(pkt_dev, ifname); |
3475 if (err) 3476 goto out1; 3477 if (pkt_dev->odev->priv_flags & IFF_TX_SKB_SHARING) 3478 pkt_dev->clone_skb = pg_clone_skb_d; 3479 | 3466 if (err) 3467 goto out1; 3468 if (pkt_dev->odev->priv_flags & IFF_TX_SKB_SHARING) 3469 pkt_dev->clone_skb = pg_clone_skb_d; 3470 |
3480 pkt_dev->entry = proc_create_data(ifname, 0600, t->net->proc_dir, | 3471 pkt_dev->entry = proc_create_data(ifname, 0600, pg_proc_dir, |
3481 &pktgen_if_fops, pkt_dev); 3482 if (!pkt_dev->entry) { 3483 pr_err("cannot create %s/%s procfs entry\n", 3484 PG_PROC_DIR, ifname); 3485 err = -EINVAL; 3486 goto out2; 3487 } 3488#ifdef CONFIG_XFRM --- 8 unchanged lines hidden (view full) --- 3497#ifdef CONFIG_XFRM 3498 free_SAs(pkt_dev); 3499#endif 3500 vfree(pkt_dev->flows); 3501 kfree(pkt_dev); 3502 return err; 3503} 3504 | 3472 &pktgen_if_fops, pkt_dev); 3473 if (!pkt_dev->entry) { 3474 pr_err("cannot create %s/%s procfs entry\n", 3475 PG_PROC_DIR, ifname); 3476 err = -EINVAL; 3477 goto out2; 3478 } 3479#ifdef CONFIG_XFRM --- 8 unchanged lines hidden (view full) --- 3488#ifdef CONFIG_XFRM 3489 free_SAs(pkt_dev); 3490#endif 3491 vfree(pkt_dev->flows); 3492 kfree(pkt_dev); 3493 return err; 3494} 3495 |
3505static int __net_init pktgen_create_thread(int cpu, struct pktgen_net *pn) | 3496static int __init pktgen_create_thread(int cpu) |
3506{ 3507 struct pktgen_thread *t; 3508 struct proc_dir_entry *pe; 3509 struct task_struct *p; 3510 3511 t = kzalloc_node(sizeof(struct pktgen_thread), GFP_KERNEL, 3512 cpu_to_node(cpu)); 3513 if (!t) { 3514 pr_err("ERROR: out of memory, can't create new thread\n"); 3515 return -ENOMEM; 3516 } 3517 3518 spin_lock_init(&t->if_lock); 3519 t->cpu = cpu; 3520 3521 INIT_LIST_HEAD(&t->if_list); 3522 | 3497{ 3498 struct pktgen_thread *t; 3499 struct proc_dir_entry *pe; 3500 struct task_struct *p; 3501 3502 t = kzalloc_node(sizeof(struct pktgen_thread), GFP_KERNEL, 3503 cpu_to_node(cpu)); 3504 if (!t) { 3505 pr_err("ERROR: out of memory, can't create new thread\n"); 3506 return -ENOMEM; 3507 } 3508 3509 spin_lock_init(&t->if_lock); 3510 t->cpu = cpu; 3511 3512 INIT_LIST_HEAD(&t->if_list); 3513 |
3523 list_add_tail(&t->th_list, &pn->pktgen_threads); | 3514 list_add_tail(&t->th_list, &pktgen_threads); |
3524 init_completion(&t->start_done); 3525 3526 p = kthread_create_on_node(pktgen_thread_worker, 3527 t, 3528 cpu_to_node(cpu), 3529 "kpktgend_%d", cpu); 3530 if (IS_ERR(p)) { 3531 pr_err("kernel_thread() failed for cpu %d\n", t->cpu); 3532 list_del(&t->th_list); 3533 kfree(t); 3534 return PTR_ERR(p); 3535 } 3536 kthread_bind(p, cpu); 3537 t->tsk = p; 3538 | 3515 init_completion(&t->start_done); 3516 3517 p = kthread_create_on_node(pktgen_thread_worker, 3518 t, 3519 cpu_to_node(cpu), 3520 "kpktgend_%d", cpu); 3521 if (IS_ERR(p)) { 3522 pr_err("kernel_thread() failed for cpu %d\n", t->cpu); 3523 list_del(&t->th_list); 3524 kfree(t); 3525 return PTR_ERR(p); 3526 } 3527 kthread_bind(p, cpu); 3528 t->tsk = p; 3529 |
3539 pe = proc_create_data(t->tsk->comm, 0600, pn->proc_dir, | 3530 pe = proc_create_data(t->tsk->comm, 0600, pg_proc_dir, |
3540 &pktgen_thread_fops, t); 3541 if (!pe) { 3542 pr_err("cannot create %s/%s procfs entry\n", 3543 PG_PROC_DIR, t->tsk->comm); 3544 kthread_stop(p); 3545 list_del(&t->th_list); 3546 kfree(t); 3547 return -EINVAL; 3548 } 3549 | 3531 &pktgen_thread_fops, t); 3532 if (!pe) { 3533 pr_err("cannot create %s/%s procfs entry\n", 3534 PG_PROC_DIR, t->tsk->comm); 3535 kthread_stop(p); 3536 list_del(&t->th_list); 3537 kfree(t); 3538 return -EINVAL; 3539 } 3540 |
3550 t->net = pn; | |
3551 wake_up_process(p); 3552 wait_for_completion(&t->start_done); 3553 3554 return 0; 3555} 3556 3557/* 3558 * Removes a device from the thread if_list. --- 9 unchanged lines hidden (view full) --- 3568 if (p == pkt_dev) 3569 list_del(&p->list); 3570 } 3571} 3572 3573static int pktgen_remove_device(struct pktgen_thread *t, 3574 struct pktgen_dev *pkt_dev) 3575{ | 3541 wake_up_process(p); 3542 wait_for_completion(&t->start_done); 3543 3544 return 0; 3545} 3546 3547/* 3548 * Removes a device from the thread if_list. --- 9 unchanged lines hidden (view full) --- 3558 if (p == pkt_dev) 3559 list_del(&p->list); 3560 } 3561} 3562 3563static int pktgen_remove_device(struct pktgen_thread *t, 3564 struct pktgen_dev *pkt_dev) 3565{ |
3576 struct pktgen_net *pn = t->net; | |
3577 3578 pr_debug("remove_device pkt_dev=%p\n", pkt_dev); 3579 3580 if (pkt_dev->running) { 3581 pr_warning("WARNING: trying to remove a running interface, stopping it now\n"); 3582 pktgen_stop_device(pkt_dev); 3583 } 3584 --- 4 unchanged lines hidden (view full) --- 3589 pkt_dev->odev = NULL; 3590 } 3591 3592 /* And update the thread if_list */ 3593 3594 _rem_dev_from_if_list(t, pkt_dev); 3595 3596 if (pkt_dev->entry) | 3566 3567 pr_debug("remove_device pkt_dev=%p\n", pkt_dev); 3568 3569 if (pkt_dev->running) { 3570 pr_warning("WARNING: trying to remove a running interface, stopping it now\n"); 3571 pktgen_stop_device(pkt_dev); 3572 } 3573 --- 4 unchanged lines hidden (view full) --- 3578 pkt_dev->odev = NULL; 3579 } 3580 3581 /* And update the thread if_list */ 3582 3583 _rem_dev_from_if_list(t, pkt_dev); 3584 3585 if (pkt_dev->entry) |
3597 remove_proc_entry(pkt_dev->entry->name, pn->proc_dir); | 3586 remove_proc_entry(pkt_dev->entry->name, pg_proc_dir); |
3598 3599#ifdef CONFIG_XFRM 3600 free_SAs(pkt_dev); 3601#endif 3602 vfree(pkt_dev->flows); 3603 if (pkt_dev->page) 3604 put_page(pkt_dev->page); 3605 kfree(pkt_dev); 3606 return 0; 3607} 3608 | 3587 3588#ifdef CONFIG_XFRM 3589 free_SAs(pkt_dev); 3590#endif 3591 vfree(pkt_dev->flows); 3592 if (pkt_dev->page) 3593 put_page(pkt_dev->page); 3594 kfree(pkt_dev); 3595 return 0; 3596} 3597 |
3609static int __net_init pg_net_init(struct net *net) | 3598static int __init pg_init(void) |
3610{ | 3599{ |
3611 struct pktgen_net *pn = net_generic(net, pg_net_id); | 3600 int cpu; |
3612 struct proc_dir_entry *pe; | 3601 struct proc_dir_entry *pe; |
3613 int cpu, ret = 0; | 3602 int ret = 0; |
3614 | 3603 |
3615 pn->net = net; 3616 INIT_LIST_HEAD(&pn->pktgen_threads); 3617 pn->pktgen_exiting = false; 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); | 3604 pr_info("%s", version); 3605 3606 pg_proc_dir = proc_mkdir(PG_PROC_DIR, init_net.proc_net); 3607 if (!pg_proc_dir) |
3621 return -ENODEV; | 3608 return -ENODEV; |
3622 } 3623 pe = proc_create(PGCTRL, 0600, pn->proc_dir, &pktgen_fops); | 3609 3610 pe = proc_create(PGCTRL, 0600, pg_proc_dir, &pktgen_fops); |
3624 if (pe == NULL) { | 3611 if (pe == NULL) { |
3625 pr_err("cannot create %s procfs entry\n", PGCTRL); | 3612 pr_err("ERROR: cannot create %s procfs entry\n", PGCTRL); |
3626 ret = -EINVAL; | 3613 ret = -EINVAL; |
3627 goto remove; | 3614 goto remove_dir; |
3628 } 3629 | 3615 } 3616 |
3617 register_netdevice_notifier(&pktgen_notifier_block); 3618 |
|
3630 for_each_online_cpu(cpu) { 3631 int err; 3632 | 3619 for_each_online_cpu(cpu) { 3620 int err; 3621 |
3633 err = pktgen_create_thread(cpu, pn); | 3622 err = pktgen_create_thread(cpu); |
3634 if (err) | 3623 if (err) |
3635 pr_warn("Cannot create thread for cpu %d (%d)\n", | 3624 pr_warning("WARNING: Cannot create thread for cpu %d (%d)\n", |
3636 cpu, err); 3637 } 3638 | 3625 cpu, err); 3626 } 3627 |
3639 if (list_empty(&pn->pktgen_threads)) { 3640 pr_err("Initialization failed for all threads\n"); | 3628 if (list_empty(&pktgen_threads)) { 3629 pr_err("ERROR: Initialization failed for all threads\n"); |
3641 ret = -ENODEV; | 3630 ret = -ENODEV; |
3642 goto remove_entry; | 3631 goto unregister; |
3643 } 3644 3645 return 0; 3646 | 3632 } 3633 3634 return 0; 3635 |
3647remove_entry: 3648 remove_proc_entry(PGCTRL, pn->proc_dir); 3649remove: 3650 proc_net_remove(pn->net, PG_PROC_DIR); | 3636 unregister: 3637 unregister_netdevice_notifier(&pktgen_notifier_block); 3638 remove_proc_entry(PGCTRL, pg_proc_dir); 3639 remove_dir: 3640 proc_net_remove(&init_net, PG_PROC_DIR); |
3651 return ret; 3652} 3653 | 3641 return ret; 3642} 3643 |
3654static void __net_exit pg_net_exit(struct net *net) | 3644static void __exit pg_cleanup(void) |
3655{ | 3645{ |
3656 struct pktgen_net *pn = net_generic(net, pg_net_id); | |
3657 struct pktgen_thread *t; 3658 struct list_head *q, *n; 3659 LIST_HEAD(list); 3660 3661 /* Stop all interfaces & threads */ | 3646 struct pktgen_thread *t; 3647 struct list_head *q, *n; 3648 LIST_HEAD(list); 3649 3650 /* Stop all interfaces & threads */ |
3662 pn->pktgen_exiting = true; | 3651 pktgen_exiting = true; |
3663 3664 mutex_lock(&pktgen_thread_lock); | 3652 3653 mutex_lock(&pktgen_thread_lock); |
3665 list_splice_init(&pn->pktgen_threads, &list); | 3654 list_splice_init(&pktgen_threads, &list); |
3666 mutex_unlock(&pktgen_thread_lock); 3667 3668 list_for_each_safe(q, n, &list) { 3669 t = list_entry(q, struct pktgen_thread, th_list); 3670 list_del(&t->th_list); 3671 kthread_stop(t->tsk); 3672 kfree(t); 3673 } 3674 | 3655 mutex_unlock(&pktgen_thread_lock); 3656 3657 list_for_each_safe(q, n, &list) { 3658 t = list_entry(q, struct pktgen_thread, th_list); 3659 list_del(&t->th_list); 3660 kthread_stop(t->tsk); 3661 kfree(t); 3662 } 3663 |
3675 remove_proc_entry(PGCTRL, pn->proc_dir); 3676 proc_net_remove(pn->net, PG_PROC_DIR); 3677} | 3664 /* Un-register us from receiving netdevice events */ 3665 unregister_netdevice_notifier(&pktgen_notifier_block); |
3678 | 3666 |
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; 3689 3690 pr_info("%s", version); 3691 ret = register_pernet_subsys(&pg_net_ops); 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; | 3667 /* Clean up proc file system */ 3668 remove_proc_entry(PGCTRL, pg_proc_dir); 3669 proc_net_remove(&init_net, PG_PROC_DIR); |
3699} 3700 | 3670} 3671 |
3701static void __exit pg_cleanup(void) 3702{ 3703 unregister_netdevice_notifier(&pktgen_notifier_block); 3704 unregister_pernet_subsys(&pg_net_ops); 3705} 3706 | |
3707module_init(pg_init); 3708module_exit(pg_cleanup); 3709 3710MODULE_AUTHOR("Robert Olsson <robert.olsson@its.uu.se>"); 3711MODULE_DESCRIPTION("Packet Generator tool"); 3712MODULE_LICENSE("GPL"); 3713MODULE_VERSION(VERSION); 3714module_param(pg_count_d, int, 0); 3715MODULE_PARM_DESC(pg_count_d, "Default number of packets to inject"); 3716module_param(pg_delay_d, int, 0); 3717MODULE_PARM_DESC(pg_delay_d, "Default delay between packets (nanoseconds)"); 3718module_param(pg_clone_skb_d, int, 0); 3719MODULE_PARM_DESC(pg_clone_skb_d, "Default number of copies of the same packet"); 3720module_param(debug, int, 0); 3721MODULE_PARM_DESC(debug, "Enable debugging of pktgen module"); | 3672module_init(pg_init); 3673module_exit(pg_cleanup); 3674 3675MODULE_AUTHOR("Robert Olsson <robert.olsson@its.uu.se>"); 3676MODULE_DESCRIPTION("Packet Generator tool"); 3677MODULE_LICENSE("GPL"); 3678MODULE_VERSION(VERSION); 3679module_param(pg_count_d, int, 0); 3680MODULE_PARM_DESC(pg_count_d, "Default number of packets to inject"); 3681module_param(pg_delay_d, int, 0); 3682MODULE_PARM_DESC(pg_delay_d, "Default delay between packets (nanoseconds)"); 3683module_param(pg_clone_skb_d, int, 0); 3684MODULE_PARM_DESC(pg_clone_skb_d, "Default number of copies of the same packet"); 3685module_param(debug, int, 0); 3686MODULE_PARM_DESC(debug, "Enable debugging of pktgen module"); |