From 65a4a5bf4e9ea6797f74b94ea913ba4153c5d654 Mon Sep 17 00:00:00 2001 From: Daniel Borkmann Date: Wed, 13 Jul 2011 14:58:02 +0200 Subject: [PATCH] added tee fb --- src/Makefile | 1 + src/fb_tee.c | 230 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 231 insertions(+) create mode 100644 src/fb_tee.c diff --git a/src/Makefile b/src/Makefile index 249e5a7..cadf72e 100644 --- a/src/Makefile +++ b/src/Makefile @@ -28,6 +28,7 @@ obj-m += fb_ethvlink.o obj-m += fb_pflana.o obj-m += fb_bpf.o obj-m += fb_counter.o +obj-m += fb_tee.o MDIR := /lib/modules/$(shell uname -r) KDIR := $(MDIR)/build diff --git a/src/fb_tee.c b/src/fb_tee.c new file mode 100644 index 0000000..5a539c8 --- /dev/null +++ b/src/fb_tee.c @@ -0,0 +1,230 @@ +/* + * Lightweight Autonomic Network Architecture + * + * Tee module. + * + * Copyright 2011 Daniel Borkmann , + * Swiss federal institute of technology (ETH Zurich) + * Subject to the GPL. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "xt_fblock.h" +#include "xt_builder.h" +#include "xt_idp.h" +#include "xt_skb.h" +#include "xt_engine.h" +#include "xt_builder.h" + +struct fb_tee_priv { + idp_t port[2]; + idp_t port_clone; + seqlock_t lock; +}; + +static int fb_tee_netrx(const struct fblock * const fb, + struct sk_buff * const skb, + enum path_type * const dir) +{ + idp_t port_clone = 0; + int drop = 0; + unsigned int seq; + struct sk_buff *cloned_skb = NULL; + struct fb_tee_priv __percpu *fb_priv_cpu; + + fb_priv_cpu = this_cpu_ptr(rcu_dereference_raw(fb->private_data)); +#ifdef __DEBUG + printk("Got skb on %p on ppe%d!\n", fb, smp_processor_id()); +#endif + prefetchw(skb->cb); + do { + seq = read_seqbegin(&fb_priv_cpu->lock); + write_next_idp_to_skb(skb, fb->idp, fb_priv_cpu->port[*dir]); + if (fb_priv_cpu->port[*dir] == IDP_UNKNOWN) + drop = 1; + if (fb_priv_cpu->port_clone != IDP_UNKNOWN) + port_clone = fb_priv_cpu->port_clone; + } while (read_seqretry(&fb_priv_cpu->lock, seq)); + + if (port_clone != 0) { + cloned_skb = skb_copy(skb, GFP_ATOMIC); + if (cloned_skb) { + write_next_idp_to_skb(cloned_skb, fb->idp, port_clone); + engine_backlog_tail(cloned_skb, *dir); + } + } + if (drop) { + kfree_skb(skb); + return PPE_DROPPED; + } + return PPE_SUCCESS; +} + +static int fb_tee_event(struct notifier_block *self, unsigned long cmd, + void *args) +{ + int ret = NOTIFY_OK; + unsigned int cpu; + struct fblock *fb; + struct fb_tee_priv __percpu *fb_priv; + + rcu_read_lock(); + fb = rcu_dereference_raw(container_of(self, struct fblock_notifier, nb)->self); + fb_priv = (struct fb_tee_priv __percpu *) rcu_dereference_raw(fb->private_data); + rcu_read_unlock(); + +#ifdef __DEBUG + printk("Got event %lu on %p!\n", cmd, fb); +#endif + + switch (cmd) { + case FBLOCK_BIND_IDP: { + int bound = 0; + struct fblock_bind_msg *msg = args; + get_online_cpus(); + for_each_online_cpu(cpu) { + struct fb_tee_priv *fb_priv_cpu; + fb_priv_cpu = per_cpu_ptr(fb_priv, cpu); + if (fb_priv_cpu->port[msg->dir] == IDP_UNKNOWN) { + write_seqlock(&fb_priv_cpu->lock); + fb_priv_cpu->port[msg->dir] = msg->idp; + write_sequnlock(&fb_priv_cpu->lock); + bound = 1; + } else if (fb_priv_cpu->port_clone == IDP_UNKNOWN) { + write_seqlock(&fb_priv_cpu->lock); + fb_priv_cpu->port_clone = msg->idp; + write_sequnlock(&fb_priv_cpu->lock); + bound = 1; + } else { + ret = NOTIFY_BAD; + break; + } + } + put_online_cpus(); + if (bound) + printk(KERN_INFO "[%s::%s] port %s bound to IDP%u\n", + fb->name, fb->factory->type, + path_names[msg->dir], msg->idp); + } break; + case FBLOCK_UNBIND_IDP: { + int unbound = 0; + struct fblock_bind_msg *msg = args; + get_online_cpus(); + for_each_online_cpu(cpu) { + struct fb_tee_priv *fb_priv_cpu; + fb_priv_cpu = per_cpu_ptr(fb_priv, cpu); + if (fb_priv_cpu->port[msg->dir] == msg->idp) { + write_seqlock(&fb_priv_cpu->lock); + fb_priv_cpu->port[msg->dir] = IDP_UNKNOWN; + write_sequnlock(&fb_priv_cpu->lock); + unbound = 1; + } else if (fb_priv_cpu->port_clone == msg->idp) { + write_seqlock(&fb_priv_cpu->lock); + fb_priv_cpu->port_clone = IDP_UNKNOWN; + write_sequnlock(&fb_priv_cpu->lock); + unbound = 1; + } else { + ret = NOTIFY_BAD; + break; + } + } + put_online_cpus(); + if (unbound) + printk(KERN_INFO "[%s::%s] port %s unbound\n", + fb->name, fb->factory->type, + path_names[msg->dir]); + } break; + case FBLOCK_SET_OPT: { + struct fblock_opt_msg *msg = args; + printk("Set option %s to %s!\n", msg->key, msg->val); + } break; + default: + break; + } + + return ret; +} + +static struct fblock *fb_tee_ctor(char *name) +{ + int ret = 0; + unsigned int cpu; + struct fblock *fb; + struct fb_tee_priv __percpu *fb_priv; + + fb = alloc_fblock(GFP_ATOMIC); + if (!fb) + return NULL; + + fb_priv = alloc_percpu(struct fb_tee_priv); + if (!fb_priv) + goto err; + + get_online_cpus(); + for_each_online_cpu(cpu) { + struct fb_tee_priv *fb_priv_cpu; + fb_priv_cpu = per_cpu_ptr(fb_priv, cpu); + seqlock_init(&fb_priv_cpu->lock); + fb_priv_cpu->port[0] = IDP_UNKNOWN; + fb_priv_cpu->port[1] = IDP_UNKNOWN; + fb_priv_cpu->port_clone = IDP_UNKNOWN; + } + put_online_cpus(); + + ret = init_fblock(fb, name, fb_priv); + if (ret) + goto err2; + fb->netfb_rx = fb_tee_netrx; + fb->event_rx = fb_tee_event; + ret = register_fblock_namespace(fb); + if (ret) + goto err3; + __module_get(THIS_MODULE); + return fb; +err3: + cleanup_fblock_ctor(fb); +err2: + free_percpu(fb_priv); +err: + kfree_fblock(fb); + return NULL; +} + +static void fb_tee_dtor(struct fblock *fb) +{ + free_percpu(rcu_dereference_raw(fb->private_data)); + module_put(THIS_MODULE); +} + +static struct fblock_factory fb_tee_factory = { + .type = "tee", + .mode = MODE_DUAL, + .ctor = fb_tee_ctor, + .dtor = fb_tee_dtor, + .owner = THIS_MODULE, +}; + +static int __init init_fb_tee_module(void) +{ + return register_fblock_type(&fb_tee_factory); +} + +static void __exit cleanup_fb_tee_module(void) +{ + unregister_fblock_type(&fb_tee_factory); +} + +module_init(init_fb_tee_module); +module_exit(cleanup_fb_tee_module); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Daniel Borkmann "); +MODULE_DESCRIPTION("LANA tee module"); -- 2.11.4.GIT