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/rwlock.h>
19 #include <linux/skbuff.h>
20 #include <linux/notifier.h>
26 #define TYPE_INGRESS TYPE_INGRESS
28 #define TYPE_EGRESS TYPE_EGRESS
32 #define NUM_TYPES _TYPE_MAX
34 #define FBLOCK_BIND_IDP 0x0001
35 #define FBLOCK_UNBIND_IDP 0x0002
36 #define FBLOCK_SET_OPT 0x0003
37 #define FBLOCK_DOWN_PREPARE 0x0004
38 #define FBLOCK_DOWN 0x0005
40 #endif /* __KERNEL__ */
42 #define FBNAMSIZ IFNAMSIZ
43 #define TYPNAMSIZ FBNAMSIZ
47 extern struct proc_dir_entry
*fblock_proc_dir
;
49 struct fblock_bind_msg
{
54 struct fblock_opt_msg
{
62 int (*netfb_rx
)(struct fblock
*fb
, struct sk_buff
*skb
,
64 int (*event_rx
)(struct notifier_block
*self
, unsigned long cmd
,
68 struct fblock_factory
{
71 struct fblock
*(*ctor
)(char *name
);
72 void (*dtor
)(struct fblock
*fb
);
73 } ____cacheline_aligned
;
75 struct fblock_notifier
{
77 struct fblock
*remote
;
78 struct notifier_block nb
;
79 struct fblock_notifier
*next
;
80 } ____cacheline_aligned
;
82 struct fblock_subscrib
{
83 struct atomic_notifier_head subscribers
;
89 struct fblock_ops
*ops
;
90 struct fblock_factory
*factory
;
91 struct fblock_notifier
*notifiers
;
92 struct fblock_subscrib
*others
;
97 rwlock_t lock
; /* Used in notifiers */
98 } ____cacheline_aligned
;
101 * Note: __* variants do not hold the rcu_read_lock!
104 /* Allocate/free a new fblock object. */
105 extern struct fblock
*alloc_fblock(gfp_t flags
);
106 extern void kfree_fblock(struct fblock
*p
);
108 /* Initialize/cleanup a fblock object. */
109 extern int init_fblock(struct fblock
*fb
, char *name
, void *priv
,
110 struct fblock_ops
*ops
);
111 extern void cleanup_fblock(struct fblock
*fb
);
112 extern void cleanup_fblock_ctor(struct fblock
*fb
);
115 * Registers a fblock object to the stack. Latter variant allocates
116 * a new unused idp, former uses a given _free_ idp.
118 extern int register_fblock(struct fblock
*p
, idp_t idp
);
119 extern int register_fblock_namespace(struct fblock
*p
);
122 * Unregisters a fblock object from the stack. Former variant does not
123 * release the idp to name mapping, latter variant frees it, too.
125 extern int unregister_fblock(struct fblock
*p
);
126 extern void unregister_fblock_namespace(struct fblock
*p
);
127 extern void unregister_fblock_namespace_no_rcu(struct fblock
*p
);
129 /* Returns fblock object specified by idp or name. */
130 extern struct fblock
*search_fblock(idp_t idp
);
131 extern struct fblock
*__search_fblock(idp_t idp
);
132 extern struct fblock
*search_fblock_n(char *name
);
133 extern struct fblock
*__search_fblock_n(char *name
);
135 /* Migrate state from src to dst and drop of dst states */
136 extern void fblock_migrate_p(struct fblock
*dst
, struct fblock
*src
);
137 extern void fblock_migrate_r(struct fblock
*dst
, struct fblock
*src
);
139 /* Notify fblock of new option. */
140 extern int fblock_set_option(struct fblock
*fb
, char *opt_string
);
141 extern int __fblock_set_option(struct fblock
*fb
, char *opt_string
);
143 /* Binds two fblock objects, increments refcount each. */
144 extern int fblock_bind(struct fblock
*fb1
, struct fblock
*fb2
);
145 extern int __fblock_bind(struct fblock
*fb1
, struct fblock
*fb2
);
147 /* Unbinds two fblock objects, decrements refcount each. */
148 extern int fblock_unbind(struct fblock
*fb1
, struct fblock
*fb2
);
149 extern int __fblock_unbind(struct fblock
*fb1
, struct fblock
*fb2
);
151 /* Lookup idp by fblock name. */
152 extern idp_t
get_fblock_namespace_mapping(char *name
);
153 extern idp_t
__get_fblock_namespace_mapping(char *name
);
156 * Maps existing fblock name to a new idp, can be used if object has been
157 * removed via unregister_fblock.
159 extern int change_fblock_namespace_mapping(char *name
, idp_t
new);
160 extern int __change_fblock_namespace_mapping(char *name
, idp_t
new);
162 extern int subscribe_to_remote_fblock(struct fblock
*us
,
163 struct fblock
*remote
);
164 extern void unsubscribe_from_remote_fblock(struct fblock
*us
,
165 struct fblock
*remote
);
167 static inline void init_fblock_subscriber(struct fblock
*fb
,
168 struct notifier_block
*nb
)
171 nb
->notifier_call
= fb
->ops
->event_rx
;
176 fblock_register_foreign_subscriber(struct fblock
*us
,
177 struct notifier_block
*remote
)
179 return atomic_notifier_chain_register(&rcu_dereference_raw(us
->others
)->subscribers
,
184 fblock_unregister_foreign_subscriber(struct fblock
*us
,
185 struct notifier_block
*remote
)
187 atomic_notifier_chain_unregister(&rcu_dereference_raw(us
->others
)->subscribers
,
191 static inline int notify_fblock_subscribers(struct fblock
*us
,
192 unsigned long cmd
, void *arg
)
194 if (unlikely(!rcu_dereference_raw(us
->others
)))
196 return atomic_notifier_call_chain(&rcu_dereference_raw(us
->others
)->subscribers
,
200 static inline void get_fblock(struct fblock
*fb
)
202 atomic_inc(&fb
->refcnt
);
205 static inline void put_fblock(struct fblock
*fb
)
207 if (likely(!atomic_dec_and_test(&fb
->refcnt
)))
213 extern int init_fblock_tables(void);
214 extern void cleanup_fblock_tables(void);
216 #endif /* __KERNEL__ */
217 #endif /* XT_FBLOCK_H */