/* * Sample kfifo byte stream implementation * * Copyright (C) 2010 Stefani Seibold * * Released under the GPL version 2 only. * */ #include #include #include #include #include /* * This module shows how to create a byte stream fifo. */ /* fifo size in elements (bytes) */ #define FIFO_SIZE 32 /* name of the proc entry */ #define PROC_FIFO "bytestream-fifo" /* lock for procfs read access */ static DEFINE_MUTEX(read_lock); /* lock for procfs write access */ static DEFINE_MUTEX(write_lock); /* * define DYNAMIC in this example for a dynamically allocated fifo. * * Otherwise the fifo storage will be a part of the fifo structure. */ #if 0 #define DYNAMIC #endif #ifdef DYNAMIC static struct kfifo test; #else static DECLARE_KFIFO(test, unsigned char, FIFO_SIZE); #endif static const unsigned char expected_result[FIFO_SIZE] = { 3, 4, 5, 6, 7, 8, 9, 0, 1, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, }; static int __init testfunc(void) { unsigned char buf[6]; unsigned char i, j; unsigned int ret; printk(KERN_INFO "byte stream fifo test start\n"); /* put string into the fifo */ kfifo_in(&test, "hello", 5); /* put values into the fifo */ for (i = 0; i != 10; i++) kfifo_put(&test, i); /* show the number of used elements */ printk(KERN_INFO "fifo len: %u\n", kfifo_len(&test)); /* get max of 5 bytes from the fifo */ i = kfifo_out(&test, buf, 5); printk(KERN_INFO "buf: %.*s\n", i, buf); /* get max of 2 elements from the fifo */ ret = kfifo_out(&test, buf, 2); printk(KERN_INFO "ret: %d\n", ret); /* and put it back to the end of the fifo */ ret = kfifo_in(&test, buf, ret); printk(KERN_INFO "ret: %d\n", ret); /* skip first element of the fifo */ printk(KERN_INFO "skip 1st element\n"); kfifo_skip(&test); /* put values into the fifo until is full */ for (i = 20; kfifo_put(&test, i); i++) ; printk(KERN_INFO "queue len: %u\n", kfifo_len(&test)); /* show the first value without removing from the fifo */ if (kfifo_peek(&test, &i)) printk(KERN_INFO "%d\n", i); /* check the correctness of all values in the fifo */ j = 0; while (kfifo_get(&test, &i)) { printk(KERN_INFO "item = %d\n", i); if (i != expected_result[j++]) { printk(KERN_WARNING "value mismatch: test failed\n"); return -EIO; } } if (j != ARRAY_SIZE(expected_result)) { printk(KERN_WARNING "size mismatch: test failed\n"); return -EIO; } printk(KERN_INFO "test passed\n"); return 0; } static ssize_t fifo_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { int ret; unsigned int copied; if (mutex_lock_interruptible(&write_lock)) return -ERESTARTSYS; ret = kfifo_from_user(&test, buf, count, &copied); mutex_unlock(&write_lock); return ret ? ret : copied; } static ssize_t fifo_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { int ret; unsigned int copied; if (mutex_lock_interruptible(&read_lock)) return -ERESTARTSYS; ret = kfifo_to_user(&test, buf, count, &copied); mutex_unlock(&read_lock); return ret ? ret : copied; } static const struct file_operations fifo_fops = { .owner = THIS_MODULE, .read = fifo_read, .write = fifo_write, .llseek = noop_llseek, }; static int __init example_init(void) { #ifdef DYNAMIC int ret; ret = kfifo_alloc(&test, FIFO_SIZE, GFP_KERNEL); if (ret) { printk(KERN_ERR "error kfifo_alloc\n"); return ret; } #else INIT_KFIFO(test); #endif if (testfunc() < 0) { #ifdef DYNAMIC kfifo_free(&test); #endif return -EIO; } if (proc_create(PROC_FIFO, 0, NULL, &fifo_fops) == NULL) { #ifdef DYNAMIC kfifo_free(&test); #endif return -ENOMEM; } return 0; } static void __exit example_exit(void) { remove_proc_entry(PROC_FIFO, NULL); #ifdef DYNAMIC kfifo_free(&test); #endif } module_init(example_init); module_exit(example_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Stefani Seibold "); ption value='0' selected='selected'>includemode:
authorDavid S. Miller <davem@davemloft.net>2017-01-30 15:55:48 -0500
committerDavid S. Miller <davem@davemloft.net>2017-01-30 15:56:40 -0500
commit1930b60352e7e195f55b27cde15d2a8f43342a8b (patch)
treeec3f66cd8d8110bf7b4f61e0446bdea505915db9 /net/openvswitch/vport-netdev.h
parent4be9993493bc7ee3fdf950a83bc050a3e6cf2a45 (diff)
parentec960de61503ef349588dccfa3ae02efabcc2762 (diff)
Merge branch 'dsa-port-mirroring'
Florian Fainelli says: ==================== net: dsa: Port mirroring support This patch series adds support for port mirroring in the two Broadcom switch drivers. The major part of the functional are actually with the plumbing between tc and the drivers. Changes in v5: - Added Jiri's Reviewed-by tag to first patch - rebase against latest net-next/master after bcm_sf2 CFP series Changes in v4: - rebased against latest net-next/master after Vivien's changes Changes in v3: - removed multiline comments from added structures - simplify error handling in dsa_slave_add_cls_matchall Changes in v2: - fixed filter removal logic to disable the ingress or egress mirroring when there are no longer ports being monitored in ingress or egress - removed a stray list_head in dsa_port structure that is not used Tested using the two iproute2 examples: tc qdisc add dev eth1 handle ffff: ingress tc filter add dev eth1 parent ffff: \ matchall skip_sw \ action mirred egress mirror \ dev eth2 tc qdisc add dev eth1 handle 1: root prio tc filter add dev eth1 parent 1: \ matchall skip_sw \ action mirred egress mirror \ dev eth2 ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/openvswitch/vport-netdev.h')