2 * Lightweight Autonomic Network Architecture
4 * PF_LANA userspace module.
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>
21 #include "xt_fblock.h"
22 #include "xt_builder.h"
25 #include "xt_engine.h"
26 #include "xt_builder.h"
28 #define AF_LANA 66 /* For now.. */
29 #define PF_LANA AF_LANA
31 struct fb_pflana_priv
{
32 idp_t port
[NUM_TYPES
];
36 static struct proto lana_proto
;
37 static const struct proto_ops lana_ui_ops
;
39 static int fb_pflana_netrx(const struct fblock
* const fb
,
40 struct sk_buff
* const skb
,
41 enum path_type
* const dir
)
46 static int fb_pflana_event(struct notifier_block
*self
, unsigned long cmd
,
53 /* struct sock must be the first member of lana_sock */
58 static int lana_backlog_rcv(struct sock
*sk
, struct sk_buff
*skb
)
60 printk(KERN_INFO
"packet in backlog queue\n");
65 static void lana_ui_sk_init(struct socket
*sock
, struct sock
*sk
)
68 sk
->sk_type
= sock
->type
;
69 sock
->ops
= &lana_ui_ops
;
72 static void lana_sk_init(struct sock
* sk
)
74 /* default struct vals*/
75 sk
->sk_backlog_rcv
= lana_backlog_rcv
;
78 static struct sock
*lana_sk_alloc(struct net
*net
, int family
, gfp_t priority
,
81 struct sock
*sk
= sk_alloc(net
, family
, priority
, prot
);
85 sock_init_data(NULL
, sk
);
89 static void lana_sk_free(struct sock
*sk
)
91 skb_queue_purge(&sk
->sk_receive_queue
);
92 skb_queue_purge(&sk
->sk_write_queue
);
96 static int lana_ui_create(struct net
*net
, struct socket
*sock
, int protocol
,
100 int rc
= -ESOCKTNOSUPPORT
;
102 if (!net_eq(net
, &init_net
))
103 return -EAFNOSUPPORT
;
104 if (likely(sock
->type
== SOCK_DGRAM
||
105 sock
->type
== SOCK_STREAM
)) {
107 sk
= lana_sk_alloc(net
, PF_LANA
, GFP_KERNEL
, &lana_proto
);
110 lana_ui_sk_init(sock
, sk
);
116 static int lana_ui_release(struct socket
*sock
)
118 struct sock
*sk
= sock
->sk
;
120 if (unlikely(sk
== NULL
))
131 static const struct net_proto_family lana_ui_family_ops
= {
133 .create
= lana_ui_create
,
134 .owner
= THIS_MODULE
,
137 static const struct proto_ops lana_ui_ops
= {
139 .owner
= THIS_MODULE
,
140 .release
= lana_ui_release
,
141 .bind
= sock_no_bind
,
142 .connect
= sock_no_connect
,
143 .socketpair
= sock_no_socketpair
,
144 .accept
= sock_no_accept
,
145 .getname
= sock_no_getname
,
146 .poll
= sock_no_poll
,
147 .ioctl
= sock_no_ioctl
,
148 .listen
= sock_no_listen
,
149 .shutdown
= sock_no_shutdown
,
150 .setsockopt
= sock_no_setsockopt
,
151 .getsockopt
= sock_no_getsockopt
,
152 .sendmsg
= sock_no_sendmsg
,
153 .recvmsg
= sock_no_recvmsg
,
154 .mmap
= sock_no_mmap
,
155 .sendpage
= sock_no_sendpage
,
158 static struct proto lana_proto
= {
160 .owner
= THIS_MODULE
,
161 .obj_size
= sizeof(struct lana_sock
),
162 .slab_flags
= SLAB_DESTROY_BY_RCU
,
165 static int init_fb_pflana(void)
168 ret
= proto_register(&lana_proto
, 0);
171 ret
= sock_register(&lana_ui_family_ops
);
173 proto_unregister(&lana_proto
);
179 static void cleanup_fb_pflana(void)
181 sock_unregister(PF_LANA
);
182 proto_unregister(&lana_proto
);
185 static struct fblock
*fb_pflana_ctor(char *name
)
190 struct fb_pflana_priv __percpu
*fb_priv
;
193 fb
= alloc_fblock(GFP_ATOMIC
);
197 fb_priv
= alloc_percpu(struct fb_pflana_priv
);
202 for_each_online_cpu(cpu
) {
203 struct fb_pflana_priv
*fb_priv_cpu
;
204 fb_priv_cpu
= per_cpu_ptr(fb_priv
, cpu
);
205 seqlock_init(&fb_priv_cpu
->lock
);
206 for (i
= 0; i
< NUM_TYPES
; ++i
)
207 fb_priv_cpu
->port
[i
] = IDP_UNKNOWN
;
211 ret
= init_fblock(fb
, name
, fb_priv
);
214 fb
->netfb_rx
= fb_pflana_netrx
;
215 fb
->event_rx
= fb_pflana_event
;
216 ret
= register_fblock_namespace(fb
);
219 __module_get(THIS_MODULE
);
222 cleanup_fblock_ctor(fb
);
224 free_percpu(fb_priv
);
231 static void fb_pflana_dtor(struct fblock
*fb
)
233 free_percpu(rcu_dereference_raw(fb
->private_data
));
234 module_put(THIS_MODULE
);
237 static struct fblock_factory fb_pflana_factory
= {
240 .ctor
= fb_pflana_ctor
,
241 .dtor
= fb_pflana_dtor
,
242 .owner
= THIS_MODULE
,
245 static int __init
init_fb_pflana_module(void)
248 ret
= init_fb_pflana();
251 ret
= register_fblock_type(&fb_pflana_factory
);
257 static void __exit
cleanup_fb_pflana_module(void)
260 unregister_fblock_type(&fb_pflana_factory
);
263 module_init(init_fb_pflana_module
);
264 module_exit(cleanup_fb_pflana_module
);
266 MODULE_LICENSE("GPL");
267 MODULE_AUTHOR("Daniel Borkmann <dborkma@tik.ee.ethz.ch>");
268 MODULE_DESCRIPTION("LANA PF_LANA module");