2 * Lightweight Autonomic Network Architecture
6 * Copyright 2011 Daniel Borkmann <dborkma@tik.ee.ethz.ch>,
7 * Swiss federal institute of technology (ETH Zurich)
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>
16 #include <linux/seqlock.h>
17 #include <linux/percpu.h>
18 #include <linux/prefetch.h>
20 #include "xt_fblock.h"
21 #include "xt_builder.h"
24 #include "xt_engine.h"
25 #include "xt_builder.h"
27 struct fb_dummy_priv
{
32 static int fb_dummy_netrx(const struct fblock
* const fb
,
33 struct sk_buff
* const skb
,
34 enum path_type
* const dir
)
38 struct fb_dummy_priv __percpu
*fb_priv_cpu
;
40 fb_priv_cpu
= this_cpu_ptr(rcu_dereference_raw(fb
->private_data
));
42 printk("Got skb on %p on ppe%d!\n", fb
, smp_processor_id());
46 seq
= read_seqbegin(&fb_priv_cpu
->lock
);
47 write_next_idp_to_skb(skb
, fb
->idp
, fb_priv_cpu
->port
[*dir
]);
48 if (fb_priv_cpu
->port
[*dir
] == IDP_UNKNOWN
)
50 } while (read_seqretry(&fb_priv_cpu
->lock
, seq
));
58 static int fb_dummy_event(struct notifier_block
*self
, unsigned long cmd
,
64 struct fb_dummy_priv __percpu
*fb_priv
;
67 fb
= rcu_dereference_raw(container_of(self
, struct fblock_notifier
, nb
)->self
);
68 fb_priv
= (struct fb_dummy_priv __percpu
*) rcu_dereference_raw(fb
->private_data
);
72 printk("Got event %lu on %p!\n", cmd
, fb
);
76 case FBLOCK_BIND_IDP
: {
78 struct fblock_bind_msg
*msg
= args
;
80 for_each_online_cpu(cpu
) {
81 struct fb_dummy_priv
*fb_priv_cpu
;
82 fb_priv_cpu
= per_cpu_ptr(fb_priv
, cpu
);
83 if (fb_priv_cpu
->port
[msg
->dir
] == IDP_UNKNOWN
) {
84 write_seqlock(&fb_priv_cpu
->lock
);
85 fb_priv_cpu
->port
[msg
->dir
] = msg
->idp
;
86 write_sequnlock(&fb_priv_cpu
->lock
);
95 printk(KERN_INFO
"[%s::%s] port %s bound to IDP%u\n",
96 fb
->name
, fb
->factory
->type
,
97 path_names
[msg
->dir
], msg
->idp
);
99 case FBLOCK_UNBIND_IDP
: {
101 struct fblock_bind_msg
*msg
= args
;
103 for_each_online_cpu(cpu
) {
104 struct fb_dummy_priv
*fb_priv_cpu
;
105 fb_priv_cpu
= per_cpu_ptr(fb_priv
, cpu
);
106 if (fb_priv_cpu
->port
[msg
->dir
] == msg
->idp
) {
107 write_seqlock(&fb_priv_cpu
->lock
);
108 fb_priv_cpu
->port
[msg
->dir
] = IDP_UNKNOWN
;
109 write_sequnlock(&fb_priv_cpu
->lock
);
118 printk(KERN_INFO
"[%s::%s] port %s unbound\n",
119 fb
->name
, fb
->factory
->type
,
120 path_names
[msg
->dir
]);
122 case FBLOCK_SET_OPT
: {
123 struct fblock_opt_msg
*msg
= args
;
124 printk("Set option %s to %s!\n", msg
->key
, msg
->val
);
133 static struct fblock
*fb_dummy_ctor(char *name
)
138 struct fb_dummy_priv __percpu
*fb_priv
;
140 fb
= alloc_fblock(GFP_ATOMIC
);
144 fb_priv
= alloc_percpu(struct fb_dummy_priv
);
149 for_each_online_cpu(cpu
) {
150 struct fb_dummy_priv
*fb_priv_cpu
;
151 fb_priv_cpu
= per_cpu_ptr(fb_priv
, cpu
);
152 seqlock_init(&fb_priv_cpu
->lock
);
153 fb_priv_cpu
->port
[0] = IDP_UNKNOWN
;
154 fb_priv_cpu
->port
[1] = IDP_UNKNOWN
;
158 ret
= init_fblock(fb
, name
, fb_priv
);
161 fb
->netfb_rx
= fb_dummy_netrx
;
162 fb
->event_rx
= fb_dummy_event
;
163 ret
= register_fblock_namespace(fb
);
166 __module_get(THIS_MODULE
);
169 cleanup_fblock_ctor(fb
);
171 free_percpu(fb_priv
);
177 static void fb_dummy_dtor(struct fblock
*fb
)
179 free_percpu(rcu_dereference_raw(fb
->private_data
));
180 module_put(THIS_MODULE
);
183 static struct fblock_factory fb_dummy_factory
= {
186 .ctor
= fb_dummy_ctor
,
187 .dtor
= fb_dummy_dtor
,
188 .owner
= THIS_MODULE
,
191 static int __init
init_fb_dummy_module(void)
193 return register_fblock_type(&fb_dummy_factory
);
196 static void __exit
cleanup_fb_dummy_module(void)
198 unregister_fblock_type(&fb_dummy_factory
);
201 module_init(init_fb_dummy_module
);
202 module_exit(cleanup_fb_dummy_module
);
204 MODULE_LICENSE("GPL");
205 MODULE_AUTHOR("Daniel Borkmann <dborkma@tik.ee.ethz.ch>");
206 MODULE_DESCRIPTION("LANA dummy/test module");