init/cleanup functions pflana
[ana-net.git] / src / fb_pflana.c
blob504bb0b2a8227e71f9b3977937c9c3bc8040fdde
1 /*
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)
8 * Subject to the GPL.
9 */
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>
19 #include <net/sock.h>
21 #include "xt_fblock.h"
22 #include "xt_builder.h"
23 #include "xt_idp.h"
24 #include "xt_skb.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];
33 seqlock_t lock;
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)
43 return PPE_SUCCESS;
46 static int fb_pflana_event(struct notifier_block *self, unsigned long cmd,
47 void *args)
49 return 0;
52 struct lana_sock {
53 /* struct sock must be the first member of lana_sock */
54 struct sock sk;
55 /* ... */
58 static int lana_backlog_rcv(struct sock *sk, struct sk_buff *skb)
60 printk(KERN_INFO "packet in backlog queue\n");
61 kfree_skb(skb);
62 return 0;
65 static void lana_ui_sk_init(struct socket *sock, struct sock *sk)
67 sock_graft(sk, sock);
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,
79 struct proto *prot)
81 struct sock *sk = sk_alloc(net, family, priority, prot);
82 if (!sk)
83 return NULL;
84 lana_sk_init(sk);
85 sock_init_data(NULL, sk);
86 return sk;
89 static int lana_ui_create(struct net *net, struct socket *sock, int protocol,
90 int kern)
92 struct sock *sk;
93 int rc = -ESOCKTNOSUPPORT;
95 if (!net_eq(net, &init_net))
96 return -EAFNOSUPPORT;
97 if (likely(sock->type == SOCK_DGRAM ||
98 sock->type == SOCK_STREAM)) {
99 rc = -ENOMEM;
100 sk = lana_sk_alloc(net, PF_LANA, GFP_KERNEL, &lana_proto);
101 if (sk) {
102 rc = 0;
103 lana_ui_sk_init(sock, sk);
106 return rc;
109 static const struct net_proto_family lana_ui_family_ops = {
110 .family = PF_LANA,
111 .create = lana_ui_create,
112 .owner = THIS_MODULE,
115 static const struct proto_ops lana_ui_ops = {
116 .family = PF_LANA,
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 = {
137 .name = "LANA",
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)
145 int ret;
146 ret = proto_register(&lana_proto, 0);
147 if (ret)
148 return ret;
149 ret = sock_register(&lana_ui_family_ops);
150 if (ret) {
151 proto_unregister(&lana_proto);
152 return ret;
154 return 0;
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)
165 int i, ret = 0;
166 unsigned int cpu;
167 struct fblock *fb;
168 struct fb_pflana_priv __percpu *fb_priv;
170 return NULL;
171 fb = alloc_fblock(GFP_ATOMIC);
172 if (!fb)
173 return NULL;
175 fb_priv = alloc_percpu(struct fb_pflana_priv);
176 if (!fb_priv)
177 goto err;
179 get_online_cpus();
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;
187 put_online_cpus();
189 ret = init_fblock(fb, name, fb_priv);
190 if (ret)
191 goto err2;
192 fb->netfb_rx = fb_pflana_netrx;
193 fb->event_rx = fb_pflana_event;
194 ret = register_fblock_namespace(fb);
195 if (ret)
196 goto err3;
197 __module_get(THIS_MODULE);
198 return fb;
199 err3:
200 cleanup_fblock_ctor(fb);
201 err2:
202 free_percpu(fb_priv);
203 err:
204 kfree_fblock(fb);
205 fb = NULL;
206 return NULL;
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 = {
216 .type = "pflana",
217 .mode = MODE_SINK,
218 .ctor = fb_pflana_ctor,
219 .dtor = fb_pflana_dtor,
220 .owner = THIS_MODULE,
223 static int __init init_fb_pflana_module(void)
225 int ret;
226 ret = init_fb_pflana();
227 if (ret)
228 return ret;
229 ret = register_fblock_type(&fb_pflana_factory);
230 if (ret)
231 cleanup_fb_pflana();
232 return ret;
235 static void __exit cleanup_fb_pflana_module(void)
237 cleanup_fb_pflana();
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");