2 * Lightweight Autonomic Network Architecture
4 * Copyright 2011 Daniel Borkmann <dborkma@tik.ee.ethz.ch>,
5 * Swiss federal institute of technology (ETH Zurich)
14 #include <linux/proc_fs.h>
16 #include <linux/cpu.h>
17 #include <linux/module.h>
18 #include <linux/spinlock.h>
19 #include <linux/skbuff.h>
20 #include <linux/notifier.h>
21 #include <linux/radix-tree.h>
27 #define TYPE_INGRESS TYPE_INGRESS
29 #define TYPE_EGRESS TYPE_EGRESS
33 extern const char *path_names
[];
37 #define MODE_SOURCE MODE_SOURCE
39 #define MODE_SINK MODE_SINK
41 #define MODE_DUAL MODE_DUAL
44 #define NUM_TYPES _TYPE_MAX
46 #define FBLOCK_BIND_IDP 0x0001
47 #define FBLOCK_UNBIND_IDP 0x0002
48 #define FBLOCK_SET_OPT 0x0003
49 #define FBLOCK_DOWN_PREPARE 0x0004
50 #define FBLOCK_DOWN 0x0005
52 #endif /* __KERNEL__ */
54 #define FBNAMSIZ IFNAMSIZ
55 #define TYPNAMSIZ FBNAMSIZ
59 extern struct proc_dir_entry
*fblock_proc_dir
;
61 struct fblock_bind_msg
{
66 struct fblock_opt_msg
{
73 struct fblock_factory
{
75 enum fblock_mode mode
;
77 struct fblock
*(*ctor
)(char *name
);
78 void (*dtor
)(struct fblock
*fb
);
79 void (*dtor_outside_rcu
)(struct fblock
*fb
);
80 } ____cacheline_aligned
;
82 struct fblock_notifier
{
84 struct notifier_block nb
;
85 struct fblock_notifier
*next
;
89 struct fblock_subscrib
{
90 struct atomic_notifier_head subscribers
;
95 void __percpu
*private_data
;
96 int (*netfb_rx
)(const struct fblock
* const fb
,
97 struct sk_buff
* const skb
,
98 enum path_type
* const dir
);
99 int (*event_rx
)(struct notifier_block
*self
, unsigned long cmd
,
101 struct fblock_factory
*factory
;
102 struct fblock_notifier
*notifiers
;
103 struct fblock_subscrib
*others
;
107 spinlock_t lock
; /* Used in notifiers */
108 } ____cacheline_aligned
;
110 extern void free_fblock_rcu(struct rcu_head
*rp
);
112 static inline void get_fblock(struct fblock
*fb
)
114 atomic_inc(&fb
->refcnt
);
117 static inline void put_fblock(struct fblock
*fb
)
119 if (likely(!atomic_dec_and_test(&fb
->refcnt
)))
122 if (fb
->factory
->dtor_outside_rcu
)
123 fb
->factory
->dtor_outside_rcu(fb
);
124 call_rcu(&fb
->rcu
, free_fblock_rcu
);
129 * Note: __* variants do not hold the rcu_read_lock!
132 /* Allocate/free a new fblock object. */
133 extern struct fblock
*alloc_fblock(gfp_t flags
);
134 extern void kfree_fblock(struct fblock
*p
);
136 /* Initialize/cleanup a fblock object. */
137 extern int init_fblock(struct fblock
*fb
, char *name
, void __percpu
*priv
);
138 extern void cleanup_fblock(struct fblock
*fb
);
139 extern void cleanup_fblock_ctor(struct fblock
*fb
);
142 * Registers a fblock object to the stack. Latter variant allocates
143 * a new unused idp, former uses a given _free_ idp.
145 extern int register_fblock(struct fblock
*p
, idp_t idp
);
146 extern int register_fblock_namespace(struct fblock
*p
);
149 * Unregisters a fblock object from the stack. Former variant does not
150 * release the idp to name mapping, latter variant frees it, too.
152 extern void unregister_fblock(struct fblock
*p
);
153 extern void unregister_fblock_namespace(struct fblock
*p
);
154 extern void unregister_fblock_namespace_no_rcu(struct fblock
*p
);
156 extern struct radix_tree_root fblmap
;
158 /* Caller needs to do a put_fblock() after his work is done! */
159 /* Called within RCU read lock! */
160 #define __search_fblock(idp) \
162 struct fblock *ret = radix_tree_lookup(&fblmap, idp); \
168 /* Returns fblock object specified by idp or name. */
169 extern struct fblock
*search_fblock(idp_t idp
);
170 extern struct fblock
*search_fblock_n(char *name
);
172 /* Migrate state from src to dst and drop of dst states */
173 extern void fblock_migrate_p(struct fblock
*dst
, struct fblock
*src
);
174 extern void fblock_migrate_r(struct fblock
*dst
, struct fblock
*src
);
176 /* Notify fblock of new option. */
177 extern int fblock_set_option(struct fblock
*fb
, char *opt_string
);
178 extern int __fblock_set_option(struct fblock
*fb
, char *opt_string
);
180 /* Binds two fblock objects, increments refcount each. */
181 extern int fblock_bind(struct fblock
*fb1
, struct fblock
*fb2
);
182 extern int __fblock_bind(struct fblock
*fb1
, struct fblock
*fb2
);
184 /* Unbinds two fblock objects, decrements refcount each. */
185 extern int fblock_unbind(struct fblock
*fb1
, struct fblock
*fb2
);
186 extern int __fblock_unbind(struct fblock
*fb1
, struct fblock
*fb2
);
188 /* Lookup idp by fblock name. */
189 extern idp_t
get_fblock_namespace_mapping(char *name
);
190 extern idp_t
__get_fblock_namespace_mapping(char *name
);
193 * Maps existing fblock name to a new idp, can be used if object has been
194 * removed via unregister_fblock.
196 extern int change_fblock_namespace_mapping(char *name
, idp_t
new);
197 extern int __change_fblock_namespace_mapping(char *name
, idp_t
new);
199 extern int subscribe_to_remote_fblock(struct fblock
*us
,
200 struct fblock
*remote
);
201 extern void unsubscribe_from_remote_fblock(struct fblock
*us
,
202 struct fblock
*remote
);
204 static inline void init_fblock_subscriber(struct fblock
*fb
,
205 struct notifier_block
*nb
)
208 nb
->notifier_call
= fb
->event_rx
;
213 fblock_register_foreign_subscriber(struct fblock
*us
,
214 struct notifier_block
*remote
)
216 return atomic_notifier_chain_register(&rcu_dereference_raw(us
->others
)->subscribers
,
221 fblock_unregister_foreign_subscriber(struct fblock
*us
,
222 struct notifier_block
*remote
)
224 atomic_notifier_chain_unregister(&rcu_dereference_raw(us
->others
)->subscribers
,
228 static inline int notify_fblock_subscribers(struct fblock
*us
,
229 unsigned long cmd
, void *arg
)
231 if (unlikely(!rcu_dereference_raw(us
->others
)))
233 return atomic_notifier_call_chain(&rcu_dereference_raw(us
->others
)->subscribers
,
237 extern int init_fblock_tables(void);
238 extern void cleanup_fblock_tables(void);
240 /* here is the address, e.g. __builtin_return_address(0) */
241 static inline void fblock_over_panic(struct fblock
*fb
, void *here
)
243 printk(KERN_EMERG
"fblock_over_panic: text:%p ptr:%p idp:%u refs:%d "
244 "name:%s priv:%p fac:%p not:%p others: %p\n",
245 here
, fb
, fb
->idp
, atomic_read(&fb
->refcnt
), fb
->name
,
246 fb
->private_data
, fb
->factory
, fb
->notifiers
, fb
->others
);
250 #endif /* __KERNEL__ */
251 #endif /* XT_FBLOCK_H */