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 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 int lana_ui_create(struct net
*net
, struct socket
*sock
, int protocol
,
93 int rc
= -ESOCKTNOSUPPORT
;
95 if (!net_eq(net
, &init_net
))
97 if (likely(sock
->type
== SOCK_DGRAM
||
98 sock
->type
== SOCK_STREAM
)) {
100 sk
= lana_sk_alloc(net
, PF_LANA
, GFP_KERNEL
, &lana_proto
);
103 lana_ui_sk_init(sock
, sk
);
109 static const struct net_proto_family lana_ui_family_ops
= {
111 .create
= lana_ui_create
,
112 .owner
= THIS_MODULE
,
115 static const struct proto_ops lana_ui_ops
= {
117 .owner
= THIS_MODULE
,
118 // .release = lana_ui_release,
119 // .bind = lana_ui_bind,
120 // .connect = lana_ui_connect,
121 .socketpair
= sock_no_socketpair
,
122 // .accept = lana_ui_accept,
123 // .getname = lana_ui_getname,
124 .poll
= datagram_poll
,
125 // .ioctl = lana_ui_ioctl,
126 // .listen = lana_ui_listen,
127 // .shutdown = lana_ui_shutdown,
128 // .setsockopt = lana_ui_setsockopt,
129 // .getsockopt = lana_ui_getsockopt,
130 // .sendmsg = lana_ui_sendmsg,
131 // .recvmsg = lana_ui_recvmsg,
132 .mmap
= sock_no_mmap
,
133 .sendpage
= sock_no_sendpage
,
136 static struct proto lana_proto
= {
138 .owner
= THIS_MODULE
,
139 .obj_size
= sizeof(struct lana_sock
),
140 .slab_flags
= SLAB_DESTROY_BY_RCU
,
143 static int init_fb_pflana(void)
146 ret
= proto_register(&lana_proto
, 0);
149 ret
= sock_register(&lana_ui_family_ops
);
151 proto_unregister(&lana_proto
);
157 static void cleanup_fb_pflana(void)
159 sock_unregister(PF_LANA
);
160 proto_unregister(&lana_proto
);
163 static struct fblock
*fb_pflana_ctor(char *name
)
168 struct fb_pflana_priv __percpu
*fb_priv
;
171 fb
= alloc_fblock(GFP_ATOMIC
);
175 fb_priv
= alloc_percpu(struct fb_pflana_priv
);
180 for_each_online_cpu(cpu
) {
181 struct fb_pflana_priv
*fb_priv_cpu
;
182 fb_priv_cpu
= per_cpu_ptr(fb_priv
, cpu
);
183 seqlock_init(&fb_priv_cpu
->lock
);
184 for (i
= 0; i
< NUM_TYPES
; ++i
)
185 fb_priv_cpu
->port
[i
] = IDP_UNKNOWN
;
189 ret
= init_fblock(fb
, name
, fb_priv
);
192 fb
->netfb_rx
= fb_pflana_netrx
;
193 fb
->event_rx
= fb_pflana_event
;
194 ret
= register_fblock_namespace(fb
);
197 __module_get(THIS_MODULE
);
200 cleanup_fblock_ctor(fb
);
202 free_percpu(fb_priv
);
209 static void fb_pflana_dtor(struct fblock
*fb
)
211 free_percpu(rcu_dereference_raw(fb
->private_data
));
212 module_put(THIS_MODULE
);
215 static struct fblock_factory fb_pflana_factory
= {
218 .ctor
= fb_pflana_ctor
,
219 .dtor
= fb_pflana_dtor
,
220 .owner
= THIS_MODULE
,
223 static int __init
init_fb_pflana_module(void)
226 ret
= init_fb_pflana();
229 ret
= register_fblock_type(&fb_pflana_factory
);
235 static void __exit
cleanup_fb_pflana_module(void)
238 unregister_fblock_type(&fb_pflana_factory
);
241 module_init(init_fb_pflana_module
);
242 module_exit(cleanup_fb_pflana_module
);
244 MODULE_LICENSE("GPL");
245 MODULE_AUTHOR("Daniel Borkmann <dborkma@tik.ee.ethz.ch>");
246 MODULE_DESCRIPTION("LANA PF_LANA module");