Skip to content

Commit

Permalink
added kfifo to dentries with current skbuff
Browse files Browse the repository at this point in the history
  • Loading branch information
beraldoleal committed Jun 5, 2013
1 parent fc9ff06 commit c4cb634
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 25 deletions.
57 changes: 33 additions & 24 deletions inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include <linux/magic.h>
#include <linux/slab.h>
#include <asm/uaccess.h>
#include <linux/kfifo.h>
#include <linux/netdevice.h>

#include "internal.h"
Expand All @@ -31,43 +32,50 @@
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Beraldo Leal");

#define STREAM_BUF_LEN 4096

static struct packet_type netsfs_pseudo_proto;
static struct dentry *netsfs_root;
static const struct inode_operations netsfs_file_inode_operations;

struct netsfs_file_private {
netsfs_file_type_t type;
};

struct netsfs_dir_private {
u64 count; // how many frames/packets
u64 errors; // how many errors
loff_t bytes; // total bytes
};

static ssize_t netsfs_file_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{
ssize_t length;
struct netsfs_file_private *f_private;
struct netsfs_dir_private *d_private;
char line[100];
char *stream_buf;
struct sk_buff *skb;

int size;

size_t len = STREAM_BUF_LEN, ret = 0, rv = 0;

length = -ENOMEM;
f_private = file->f_dentry->d_inode->i_private;
d_private = file->f_dentry->d_parent->d_inode->i_private;

stream_buf = kzalloc(STREAM_BUF_LEN, GFP_KERNEL);

if (f_private->type == NETSFS_STATS) {
length = sprintf(line, "bytes: %lld\ncount: %lld\n", d_private->bytes, d_private->count);
if (length >0)
length = simple_read_from_buffer(buf, count, ppos, line, length);
return length;
/* stats read */
ret = sprintf(stream_buf, "bytes: %lld\ncount: %lld\n", d_private->bytes, d_private->count);
} else if (f_private->type == NETSFS_STREAM) {
/* stream read */
skb = cq_get(&d_private->queue_skbuff);
ret = sprintf(stream_buf, "%llu %s %d %d\n",
skb->tstamp.tv64,
skb->dev->name,
skb->len,
skb->protocol);
}
printk("count: %lld ppos: %lld ret: %d\n",count, *ppos, ret);

return 0;
if (ret > 0)
rv = simple_read_from_buffer(buf, count, ppos, stream_buf, ret);
kfree(stream_buf);
return rv;
}

/* Comment options here to disable operations to user */
const struct inode_operations netsfs_dir_inode_operations = {
.create = netsfs_create,
.lookup = simple_lookup,
Expand Down Expand Up @@ -101,7 +109,7 @@ const match_table_t tokens = {
extern void netsfs_inc_inode_size(struct inode *inode, loff_t inc)
{
loff_t oldsize, newsize;
struct netsfs_dir_private *private;
struct netsfs_dir_private *d_private;

//printk(KERN_INFO "%s: Updating inode %lu size to %lld\n",
// THIS_MODULE->name,
Expand All @@ -114,10 +122,11 @@ extern void netsfs_inc_inode_size(struct inode *inode, loff_t inc)
i_size_write(inode, newsize);

if (inode->i_private == NULL) {
private = kmalloc(sizeof(struct netsfs_dir_private), GFP_KERNEL);
private->bytes = newsize;
private->count = 1;
inode->i_private = private; // LOCK HERE
d_private = kmalloc(sizeof(struct netsfs_dir_private), GFP_KERNEL);
cq_new(&d_private->queue_skbuff, FIFO_SIZE);
d_private->bytes = newsize;
d_private->count = 1;
inode->i_private = d_private; // LOCK HERE
}else{
((struct netsfs_dir_private *) inode->i_private)->bytes = newsize;
((struct netsfs_dir_private *) inode->i_private)->count += 1;
Expand Down Expand Up @@ -202,6 +211,7 @@ extern int netsfs_mkdir(struct inode * dir, struct dentry * dentry, int mode)

if (!retval) {
inc_nlink(dir);
// printk("Alloc fifo for %s\n", dentry->d_iname);
//printk("%s:%s:%d - End. inode->i_ino == %lu, dentry->d_iname == %s\n",
// THIS_MODULE->name,
// __FUNCTION__,
Expand Down Expand Up @@ -247,7 +257,6 @@ extern int netsfs_parse_options(char *data, struct netsfs_mount_opts *opts)
*/
}
}

return 0;
}

Expand Down
50 changes: 50 additions & 0 deletions internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,22 @@ typedef enum {
NETSFS_STREAM = 2
} netsfs_file_type_t;

struct netsfs_file_private {
netsfs_file_type_t type;
};

struct netsfs_dir_private {
struct kfifo queue_skbuff;
u64 count; // how many frames/packets
u64 errors; // how many errors
loff_t bytes; // total bytes
};

/* fifo size in elements (struct sk_buff) */
#define FIFO_SIZE 32

/* Declare and INIT kfifo */
static DEFINE_KFIFO(test, struct sk_buff, FIFO_SIZE);

struct inode *netsfs_get_inode(struct super_block *sb,
const struct inode *dir, int mode, dev_t dev);
Expand Down Expand Up @@ -58,4 +74,38 @@ struct netsfs_fs_info {
};



/* fifo of pointers */
static inline int cq_new(struct kfifo *fifo, int size)
{
return kfifo_alloc(fifo, size * sizeof(void *), GFP_KERNEL);
}

static inline void cq_delete(struct kfifo *kfifo)
{
kfifo_free(kfifo);
}

static inline unsigned int cq_howmany(struct kfifo *kfifo)
{
return kfifo_len(kfifo) / sizeof(void *);
}

static inline int cq_put(struct kfifo *kfifo, void *p)
{
return kfifo_in(kfifo, (void *)&p, sizeof(p));
}

static inline void *cq_get(struct kfifo *kfifo)
{
unsigned int sz;
void *p;

sz = kfifo_out(kfifo, (void *)&p, sizeof(p));
if (sz != sizeof(p))
return NULL;

return p;
}

#endif
11 changes: 10 additions & 1 deletion proto.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include <net/ipv6.h>
#include <linux/workqueue.h>
#include <linux/export.h>
#include <linux/kfifo.h>

#include "proto.h"
#include "internal.h"
Expand Down Expand Up @@ -182,6 +183,9 @@ static void netsfs_top(struct work_struct *work)
struct dentry *network_dentry, *transport_dentry, *app_dentry;
unsigned int len;

struct sk_buff *buff;
struct netsfs_dir_private *d_private;

netsfsinfo = container_of(work, struct netsfs_skb_info, my_work);
len = get_skb_len(netsfsinfo->skb);

Expand All @@ -198,6 +202,11 @@ static void netsfs_top(struct work_struct *work)
netsfs_inc_inode_size(network_dentry->d_parent->d_inode, len);
netsfs_inc_inode_size(network_dentry->d_inode, len);

/* Put skbuff in kfifo */
buff = netsfsinfo->skb;
d_private = network_dentry->d_inode->i_private;
cq_put(&d_private->queue_skbuff, buff);

/* Create L4 dir */
netsfs_create_dir(get_ip_protocol(netsfsinfo->skb), network_dentry, &transport_dentry);
if (transport_dentry) {
Expand All @@ -219,7 +228,7 @@ static void netsfs_top(struct work_struct *work)


/* Free stuff */
dev_kfree_skb(netsfsinfo->skb);
// dev_kfree_skb(netsfsinfo->skb);
kfree( (void *) work);
}

Expand Down

0 comments on commit c4cb634

Please sign in to comment.