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
{
28 idp_t port
[NUM_TYPES
];
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
: {
77 struct fblock_bind_msg
*msg
= args
;
79 for_each_online_cpu(cpu
) {
80 struct fb_dummy_priv
*fb_priv_cpu
;
81 fb_priv_cpu
= per_cpu_ptr(fb_priv
, cpu
);
82 if (fb_priv_cpu
->port
[msg
->dir
] == IDP_UNKNOWN
) {
83 write_seqlock(&fb_priv_cpu
->lock
);
84 fb_priv_cpu
->port
[msg
->dir
] = msg
->idp
;
85 write_sequnlock(&fb_priv_cpu
->lock
);
93 case FBLOCK_UNBIND_IDP
: {
94 struct fblock_bind_msg
*msg
= args
;
96 for_each_online_cpu(cpu
) {
97 struct fb_dummy_priv
*fb_priv_cpu
;
98 fb_priv_cpu
= per_cpu_ptr(fb_priv
, cpu
);
99 if (fb_priv_cpu
->port
[msg
->dir
] == msg
->idp
) {
100 write_seqlock(&fb_priv_cpu
->lock
);
101 fb_priv_cpu
->port
[msg
->dir
] = IDP_UNKNOWN
;
102 write_sequnlock(&fb_priv_cpu
->lock
);
111 case FBLOCK_SET_OPT
: {
112 struct fblock_opt_msg
*msg
= args
;
113 printk("Set option %s to %s!\n", msg
->key
, msg
->val
);
122 static struct fblock
*fb_dummy_ctor(char *name
)
127 struct fb_dummy_priv __percpu
*fb_priv
;
129 fb
= alloc_fblock(GFP_ATOMIC
);
133 fb_priv
= alloc_percpu(struct fb_dummy_priv
);
138 for_each_online_cpu(cpu
) {
139 struct fb_dummy_priv
*fb_priv_cpu
;
140 fb_priv_cpu
= per_cpu_ptr(fb_priv
, cpu
);
141 seqlock_init(&fb_priv_cpu
->lock
);
142 for (i
= 0; i
< NUM_TYPES
; ++i
)
143 fb_priv_cpu
->port
[i
] = IDP_UNKNOWN
;
147 ret
= init_fblock(fb
, name
, fb_priv
);
150 fb
->netfb_rx
= fb_dummy_netrx
;
151 fb
->event_rx
= fb_dummy_event
;
152 ret
= register_fblock_namespace(fb
);
155 __module_get(THIS_MODULE
);
158 cleanup_fblock_ctor(fb
);
160 free_percpu(fb_priv
);
166 static void fb_dummy_dtor(struct fblock
*fb
)
168 free_percpu(rcu_dereference_raw(fb
->private_data
));
169 module_put(THIS_MODULE
);
172 static struct fblock_factory fb_dummy_factory
= {
175 .ctor
= fb_dummy_ctor
,
176 .dtor
= fb_dummy_dtor
,
177 .owner
= THIS_MODULE
,
180 static int __init
init_fb_dummy_module(void)
182 return register_fblock_type(&fb_dummy_factory
);
185 static void __exit
cleanup_fb_dummy_module(void)
187 unregister_fblock_type(&fb_dummy_factory
);
190 module_init(init_fb_dummy_module
);
191 module_exit(cleanup_fb_dummy_module
);
193 MODULE_LICENSE("GPL");
194 MODULE_AUTHOR("Daniel Borkmann <dborkma@tik.ee.ethz.ch>");
195 MODULE_DESCRIPTION("LANA dummy/test module");