fb migration, part 2
[ana-net.git] / src / fb_dummy.c
blob631f274cbabf7f6d2561e9cf12cc595b3719eede
1 /*
2 * Lightweight Autonomic Network Architecture
4 * Dummy test module.
6 * Copyright 2011 Daniel Borkmann <dborkma@tik.ee.ethz.ch>,
7 * Swiss federal institute of technology (ETH Zurich)
8 * Subject to the GPL.
9 */
11 #include <linux/kernel.h>
12 #include <linux/module.h>
13 #include <linux/spinlock.h>
14 #include <linux/notifier.h>
15 #include <linux/rcupdate.h>
17 #include "xt_fblock.h"
18 #include "xt_builder.h"
19 #include "xt_idp.h"
20 #include "xt_skb.h"
21 #include "xt_engine.h"
23 struct fb_dummy_priv {
24 idp_t port[NUM_TYPES];
25 spinlock_t lock;
28 static struct fblock_ops fb_dummy_ops;
30 static int fb_dummy_netrx(struct fblock *fb, struct sk_buff *skb,
31 enum path_type *dir)
33 unsigned long flags;
34 struct fb_dummy_priv *fb_priv = rcu_dereference_raw(fb->private_data);
36 printk("Got skb on %p on ppe%d!\n", fb, smp_processor_id());
38 spin_lock_irqsave(&fb_priv->lock, flags);
39 write_next_idp_to_skb(skb, fb->idp, fb_priv->port[*dir]);
40 spin_unlock_irqrestore(&fb_priv->lock, flags);
42 return PPE_SUCCESS;
45 static int fb_dummy_event(struct notifier_block *self, unsigned long cmd,
46 void *args)
48 int ret = NOTIFY_OK;
49 unsigned long flags;
50 struct fblock *fb = rcu_dereference_raw(container_of(self, struct fblock_notifier, nb)->self);
51 struct fb_dummy_priv *fb_priv = rcu_dereference_raw(fb->private_data);
53 printk("Got event %lu on %p!\n", cmd, fb);
55 switch (cmd) {
56 case FBLOCK_BIND_IDP: {
57 struct fblock_bind_msg *msg = args;
58 spin_lock_irqsave(&fb_priv->lock, flags);
59 if (fb_priv->port[msg->dir] == IDP_UNKNOWN)
60 fb_priv->port[msg->dir] = msg->idp;
61 else
62 ret = NOTIFY_BAD;
63 spin_unlock_irqrestore(&fb_priv->lock, flags);
64 } break;
65 case FBLOCK_UNBIND_IDP: {
66 struct fblock_bind_msg *msg = args;
67 spin_lock_irqsave(&fb_priv->lock, flags);
68 if (fb_priv->port[msg->dir] == msg->idp)
69 fb_priv->port[msg->dir] = IDP_UNKNOWN;
70 else
71 ret = NOTIFY_BAD;
72 spin_unlock_irqrestore(&fb_priv->lock, flags);
73 } break;
74 case FBLOCK_SET_OPT: {
75 struct fblock_opt_msg *msg = args;
76 printk("Set option %s to %s!\n", msg->key, msg->val);
77 } break;
78 default:
79 break;
82 return ret;
85 static struct fblock *fb_dummy_ctor(char *name)
87 int i, ret = 0;
88 struct fblock *fb;
89 struct fb_dummy_priv *fb_priv;
91 fb = alloc_fblock(GFP_ATOMIC);
92 if (!fb)
93 return NULL;
94 fb_priv = kmalloc(sizeof(*fb_priv), GFP_ATOMIC);
95 if (!fb_priv)
96 goto err;
97 for (i = 0; i < NUM_TYPES; ++i)
98 fb_priv->port[i] = IDP_UNKNOWN;
99 spin_lock_init(&fb_priv->lock);
100 ret = init_fblock(fb, name, fb_priv, &fb_dummy_ops);
101 if (ret)
102 goto err2;
103 ret = register_fblock_namespace(fb);
104 if (ret)
105 goto err3;
106 __module_get(THIS_MODULE);
107 return fb;
108 err3:
109 cleanup_fblock_ctor(fb);
110 err2:
111 kfree(fb_priv);
112 err:
113 kfree_fblock(fb);
114 return NULL;
117 static void fb_dummy_dtor(struct fblock *fb)
119 kfree(rcu_dereference_raw(fb->private_data));
120 module_put(THIS_MODULE);
123 static struct fblock_ops fb_dummy_ops = {
124 .netfb_rx = fb_dummy_netrx,
125 .event_rx = fb_dummy_event,
128 static struct fblock_factory fb_dummy_factory = {
129 .type = "dummy",
130 .ctor = fb_dummy_ctor,
131 .dtor = fb_dummy_dtor,
132 .owner = THIS_MODULE,
135 static int __init init_fb_dummy_module(void)
137 return register_fblock_type(&fb_dummy_factory);
140 static void __exit cleanup_fb_dummy_module(void)
142 unregister_fblock_type(&fb_dummy_factory);
145 module_init(init_fb_dummy_module);
146 module_exit(cleanup_fb_dummy_module);
148 MODULE_LICENSE("GPL");
149 MODULE_AUTHOR("Daniel Borkmann <dborkma@tik.ee.ethz.ch>");
150 MODULE_DESCRIPTION("LANA dummy/test module");