removed ifpps as std tool
[ana-net.git] / src / fb_pflana.c
blob539d7b9935f175b28dae986b66985c34ad4a433f
1 /*
2 * Lightweight Autonomic Network Architecture
4 * LANA BSD Socket interface for communication with user level.
5 * PF_LANA protocol family socket handler.
7 * Copyright 2011 Daniel Borkmann <dborkma@tik.ee.ethz.ch>,
8 * Swiss federal institute of technology (ETH Zurich)
9 * Subject to the GPL.
12 #include <linux/kernel.h>
13 #include <linux/module.h>
14 #include <linux/spinlock.h>
15 #include <linux/notifier.h>
16 #include <linux/rcupdate.h>
17 #include <linux/seqlock.h>
18 #include <linux/bug.h>
19 #include <linux/percpu.h>
20 #include <linux/prefetch.h>
21 #include <linux/atomic.h>
22 #include <linux/slab.h>
23 #include <net/sock.h>
25 #include "xt_fblock.h"
26 #include "xt_builder.h"
27 #include "xt_idp.h"
28 #include "xt_skb.h"
29 #include "xt_engine.h"
30 #include "xt_builder.h"
32 #define AF_LANA 27 /* For now.. */
33 #define PF_LANA AF_LANA
35 /* LANA protocol types on top of the PF_LANA family */
36 #define LANA_PROTO_AUTO 0
37 #define LANA_PROTO_RAW 1
38 #define LANA_NPROTO 2
40 /* Protocols in LANA family */
41 struct lana_protocol {
42 int protocol;
43 const struct proto_ops *ops;
44 struct proto *proto;
45 struct module *owner;
48 struct fb_pflana_priv {
49 idp_t port[2];
50 seqlock_t lock;
51 struct lana_sock *sock_self;
54 struct lana_sock {
55 struct sock sk;
56 struct fblock *fb;
57 int ifindex;
58 int bound;
61 static DEFINE_MUTEX(proto_tab_lock);
63 static struct lana_protocol *proto_tab[LANA_NPROTO] __read_mostly;
65 static int fb_pflana_netrx(const struct fblock * const fb,
66 struct sk_buff *skb,
67 enum path_type * const dir)
69 u8 *skb_head = skb->data;
70 int skb_len = skb->len;
71 struct sock *sk;
72 struct fb_pflana_priv __percpu *fb_priv_cpu;
74 fb_priv_cpu = this_cpu_ptr(rcu_dereference_raw(fb->private_data));
75 sk = &fb_priv_cpu->sock_self->sk;
77 if (skb_shared(skb)) {
78 struct sk_buff *nskb = skb_clone(skb, GFP_ATOMIC);
79 if (skb_head != skb->data) {
80 skb->data = skb_head;
81 skb->len = skb_len;
83 if (nskb == NULL)
84 goto out;
85 kfree_skb(skb);
86 skb = nskb;
88 sk_receive_skb(sk, skb, 0);
89 out:
90 write_next_idp_to_skb(skb, fb->idp, IDP_UNKNOWN);
91 return PPE_HALT;
94 static int fb_pflana_event(struct notifier_block *self, unsigned long cmd,
95 void *args)
97 return 0;
100 static struct fblock *get_bound_fblock(struct fblock *self, enum path_type dir)
102 idp_t fbidp;
103 unsigned int seq;
104 struct fb_pflana_priv __percpu *fb_priv_cpu;
105 fb_priv_cpu = this_cpu_ptr(rcu_dereference_raw(self->private_data));
106 do {
107 seq = read_seqbegin(&fb_priv_cpu->lock);
108 fbidp = fb_priv_cpu->port[dir];
109 } while (read_seqretry(&fb_priv_cpu->lock, seq));
110 return search_fblock(fbidp);
113 static inline struct lana_sock *to_lana_sk(const struct sock *sk)
115 return container_of(sk, struct lana_sock, sk);
118 static struct fblock *fb_pflana_ctor(char *name);
120 static int lana_sk_init(struct sock* sk)
122 int cpu;
123 char name[32];
124 struct lana_sock *lana = to_lana_sk(sk);
126 memset(name, 0, sizeof(name));
127 snprintf(name, sizeof(name), "%p", &lana->sk);
128 lana->fb = fb_pflana_ctor(name);
129 if (!lana->fb)
130 return -ENOMEM;
131 get_online_cpus();
132 for_each_online_cpu(cpu) {
133 struct fb_pflana_priv *fb_priv_cpu;
134 fb_priv_cpu = per_cpu_ptr(lana->fb->private_data, cpu);
135 fb_priv_cpu->sock_self = lana;
137 put_online_cpus();
138 smp_wmb();
139 return 0;
142 static void lana_sk_free(struct sock *sk)
144 struct fblock *fb_bound;
145 struct lana_sock *lana;
147 lana = to_lana_sk(sk);
148 fb_bound = get_bound_fblock(lana->fb, TYPE_INGRESS);
149 if (fb_bound) {
150 fblock_unbind(fb_bound, lana->fb);
151 put_fblock(fb_bound);
153 fb_bound = get_bound_fblock(lana->fb, TYPE_EGRESS);
154 if (fb_bound) {
155 fblock_unbind(lana->fb, fb_bound);
156 put_fblock(fb_bound);
158 unregister_fblock_namespace(lana->fb);
161 static int lana_raw_release(struct socket *sock)
163 struct sock *sk = sock->sk;
164 if (sk) {
165 sock->sk = NULL;
166 sk->sk_prot->close(sk, 0);
167 lana_sk_free(sk);
169 return 0;
172 static int lana_raw_bind(struct socket *sock, struct sockaddr *addr, int len)
174 int idx;
175 struct sock *sk = sock->sk;
176 struct net_device *dev = NULL;
177 struct lana_sock *lana = to_lana_sk(sk);
179 if (len < sizeof(struct sockaddr))
180 return -EINVAL;
181 if (addr->sa_family != AF_LANA)
182 return -EINVAL;
184 idx = addr->sa_data[0];
185 dev = dev_get_by_index(sock_net(sk), idx);
186 if (dev == NULL)
187 return -ENODEV;
188 lana->ifindex = idx;
189 lana->bound = 1;
190 dev_put(dev);
192 return 0;
195 static unsigned int lana_raw_poll(struct file *file, struct socket *sock,
196 poll_table *wait)
198 unsigned int mask = 0;
199 struct sock *sk = sock->sk;
200 poll_wait(file, sk_sleep(sk), wait);
201 if (!skb_queue_empty(&sk->sk_receive_queue))
202 mask |= POLLIN | POLLRDNORM;
203 return mask;
206 static int lana_raw_sendmsg(struct kiocb *iocb, struct socket *sock,
207 struct msghdr *msg, size_t len)
209 struct sock *sk = sock->sk;
210 return sk->sk_prot->sendmsg(iocb, sk, msg, len);
213 static int lana_proto_sendmsg(struct kiocb *iocb, struct sock *sk,
214 struct msghdr *msg, size_t len)
216 int err;
217 unsigned int seq;
218 struct net *net = sock_net(sk);
219 struct net_device *dev;
220 struct sockaddr *target;
221 struct sk_buff *skb;
222 struct lana_sock *lana = to_lana_sk(sk);
223 struct fblock *fb = lana->fb;
224 struct fb_pflana_priv *fb_priv_cpu;
226 if (msg->msg_name == NULL)
227 return -EDESTADDRREQ;
228 if (msg->msg_namelen < sizeof(struct sockaddr))
229 return -EINVAL;
231 target = (struct sockaddr *) msg->msg_name;
232 if (target->sa_family != AF_LANA)
233 return -EAFNOSUPPORT;
234 if (sk->sk_bound_dev_if || lana->bound)
235 dev = dev_get_by_index(net, lana->bound ? lana->ifindex :
236 sk->sk_bound_dev_if);
237 else
238 return -ENOTCONN;
239 if (!dev || !(dev->flags & IFF_UP)) {
240 err = -EIO;
241 goto drop_put;
244 skb = sock_alloc_send_skb(sk, LL_ALLOCATED_SPACE(dev) + len,
245 msg->msg_flags & MSG_DONTWAIT, &err);
246 if (!skb)
247 goto drop_put;
249 skb_reserve(skb, LL_RESERVED_SPACE(dev));
250 skb_reset_mac_header(skb);
251 skb_reset_network_header(skb);
253 skb->pkt_type = PACKET_OUTGOING;
254 skb->dev = dev;
255 skb->sk = sk;
256 skb->protocol = htons(ETH_P_ALL); //FIXME
257 skb->priority = sk->sk_priority;
258 skb->mark = sk->sk_mark;
260 err = memcpy_fromiovec((void *) skb_put(skb, len), msg->msg_iov, len);
261 if (err < 0)
262 goto drop;
263 if (skb->pkt_type == PACKET_LOOPBACK) {
264 err = -EOPNOTSUPP;
265 goto drop;
268 fb_priv_cpu = this_cpu_ptr(rcu_dereference(fb->private_data));
269 do {
270 seq = read_seqbegin(&fb_priv_cpu->lock);
271 write_next_idp_to_skb(skb, fb->idp, 1
272 /*fb_priv_cpu->port[TYPE_EGRESS]*/);
273 } while (read_seqretry(&fb_priv_cpu->lock, seq));
275 dev_put(dev);
276 process_packet(skb, TYPE_EGRESS);
278 return (err >= 0) ? len : err;
279 drop:
280 kfree_skb(skb);
281 drop_put:
282 dev_put(dev);
283 return err;
286 static int lana_proto_recvmsg(struct kiocb *iocb, struct sock *sk,
287 struct msghdr *msg, size_t len, int noblock,
288 int flags, int *addr_len)
290 int err = 0;
291 struct sk_buff *skb;
292 size_t copied = 0;
294 skb = skb_recv_datagram(sk, flags, noblock, &err);
295 if (!skb) {
296 if (sk->sk_shutdown & RCV_SHUTDOWN)
297 return 0;
298 return err;
300 msg->msg_namelen = 0;
301 if (addr_len)
302 *addr_len = msg->msg_namelen;
303 copied = skb->len;
304 if (len < copied) {
305 msg->msg_flags |= MSG_TRUNC;
306 copied = len;
308 err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
309 if (err == 0)
310 sock_recv_ts_and_drops(msg, sk, skb);
311 skb_free_datagram(sk, skb);
313 return err ? : copied;
316 static int lana_proto_backlog_rcv(struct sock *sk, struct sk_buff *skb)
318 int err = -EPROTONOSUPPORT;
320 switch (sk->sk_protocol) {
321 case LANA_PROTO_RAW:
322 err = sock_queue_rcv_skb(sk, skb);
323 if (err != 0)
324 kfree_skb(skb);
325 break;
326 default:
327 kfree_skb(skb);
328 err = -EPROTONOSUPPORT;
329 break;
332 return err ? NET_RX_DROP : NET_RX_SUCCESS;
335 #if 0 /* unused */
336 static int lana_common_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
337 struct msghdr *msg, size_t len, int flags)
339 int err = 0;
340 long timeout;
341 size_t target, chunk, copied = 0;
342 struct sock *sk = sock->sk;
343 struct sk_buff *skb;
345 msg->msg_namelen = 0;
346 lock_sock(sk);
347 timeout = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
348 target = sock_rcvlowat(sk, flags & MSG_WAITALL, len);
349 do {
350 skb = skb_dequeue(&sk->sk_receive_queue);
351 if (!skb) {
352 if (copied >= target)
353 break;
354 err = sock_error(sk);
355 if (err || sk->sk_shutdown & RCV_SHUTDOWN)
356 break;
357 err = -EAGAIN;
358 if (!timeout)
359 break;
360 timeout = sk_wait_data(sk, &timeout);
361 if (signal_pending(current)) {
362 err = sock_intr_errno(timeout);
363 break;
365 continue;
367 chunk = min_t(size_t, skb->len, len);
368 if (memcpy_toiovec(msg->msg_iov, skb->data, chunk)) {
369 skb_queue_head(&sk->sk_receive_queue, skb);
370 if (!copied)
371 copied = -EFAULT;
372 break;
374 copied += chunk;
375 len -= chunk;
376 sock_recv_ts_and_drops(msg, sk, skb);
377 if (!(flags & MSG_PEEK)) {
378 skb_pull(skb, chunk);
379 if (skb->len) {
380 skb_queue_head(&sk->sk_receive_queue, skb);
381 break;
383 kfree_skb(skb);
384 } else {
385 /* put message back and return */
386 skb_queue_head(&sk->sk_receive_queue, skb);
387 break;
389 } while (len > 0);
391 release_sock(sk);
392 return copied ? : err;
394 #endif
396 static void lana_proto_destruct(struct sock *sk)
398 skb_queue_purge(&sk->sk_receive_queue);
401 static int lana_proto_init(struct sock *sk)
403 sk->sk_destruct = lana_proto_destruct;
404 return 0;
407 static void lana_proto_close(struct sock *sk, long timeout)
409 sk_common_release(sk);
412 static void lana_proto_hash(struct sock *sk)
416 static void lana_proto_unhash(struct sock *sk)
420 static int lana_proto_get_port(struct sock *sk, unsigned short sport)
422 return 0;
425 static struct lana_protocol *pflana_proto_get(int proto)
427 struct lana_protocol *ret = NULL;
429 if (proto < 0 || proto >= LANA_NPROTO)
430 return NULL;
431 rcu_read_lock();
432 ret = rcu_dereference_raw(proto_tab[proto]);
433 rcu_read_unlock();
435 return ret;
438 static int lana_family_create(struct net *net, struct socket *sock,
439 int protocol, int kern)
441 struct sock *sk;
442 struct lana_protocol *lp;
443 struct lana_sock *ls;
445 if (!net_eq(net, &init_net))
446 return -EAFNOSUPPORT;
448 if (protocol == LANA_PROTO_AUTO) {
449 switch (sock->type) {
450 case SOCK_RAW:
451 if (!capable(CAP_SYS_ADMIN))
452 return -EPERM;
453 protocol = LANA_PROTO_RAW;
454 break;
455 default:
456 return -EPROTONOSUPPORT;
460 lp = pflana_proto_get(protocol);
461 if (!lp)
462 return -EPROTONOSUPPORT;
464 sk = sk_alloc(net, PF_LANA, GFP_KERNEL, lp->proto);
465 if (!sk)
466 return -ENOMEM;
467 if (lana_sk_init(sk) < 0) {
468 sock_put(sk);
469 return -ENOMEM;
472 sock_init_data(sock, sk);
473 sock->state = SS_UNCONNECTED;
474 sock->ops = lp->ops;
476 sk->sk_backlog_rcv = sk->sk_prot->backlog_rcv;
477 sk->sk_protocol = protocol;
478 sk->sk_family = PF_LANA;
479 sk->sk_type = sock->type;
480 sk->sk_prot->init(sk);
482 ls = to_lana_sk(sk);
483 ls->bound = 0;
485 return 0;
488 static const struct net_proto_family lana_family_ops = {
489 .family = PF_LANA,
490 .create = lana_family_create,
491 .owner = THIS_MODULE,
494 static const struct proto_ops lana_raw_ops = {
495 .family = PF_LANA,
496 .owner = THIS_MODULE,
497 /* v- supported */
498 .release = lana_raw_release,
499 .recvmsg = sock_common_recvmsg,
500 .sendmsg = lana_raw_sendmsg,
501 .poll = lana_raw_poll,
502 .bind = lana_raw_bind,
503 /* v- not supported */
504 .setsockopt = sock_no_setsockopt,
505 .getsockopt = sock_no_getsockopt,
506 .connect = sock_no_connect,
507 .socketpair = sock_no_socketpair,
508 .accept = sock_no_accept,
509 .getname = sock_no_getname,
510 .ioctl = sock_no_ioctl,
511 .listen = sock_no_listen,
512 .shutdown = sock_no_shutdown,
513 .mmap = sock_no_mmap,
514 .sendpage = sock_no_sendpage,
517 static struct proto lana_proto __read_mostly = {
518 .name = "LANA",
519 .owner = THIS_MODULE,
520 .obj_size = sizeof(struct lana_sock),
521 .backlog_rcv = lana_proto_backlog_rcv,
522 .close = lana_proto_close,
523 .init = lana_proto_init,
524 .recvmsg = lana_proto_recvmsg,
525 .sendmsg = lana_proto_sendmsg,
526 .hash = lana_proto_hash,
527 .unhash = lana_proto_unhash,
528 .get_port = lana_proto_get_port,
531 static struct lana_protocol lana_proto_raw __read_mostly = {
532 .protocol = LANA_PROTO_RAW,
533 .ops = &lana_raw_ops,
534 .proto = &lana_proto,
535 .owner = THIS_MODULE,
538 int pflana_proto_register(int proto, struct lana_protocol *lp)
540 int err;
542 if (!lp || proto < 0 || proto >= LANA_NPROTO)
543 return -EINVAL;
544 if (rcu_dereference_raw(proto_tab[proto]))
545 return -EBUSY;
547 err = proto_register(lp->proto, 1);
548 if (err)
549 return err;
551 mutex_lock(&proto_tab_lock);
552 lp->protocol = proto;
553 rcu_assign_pointer(proto_tab[proto], lp);
554 mutex_unlock(&proto_tab_lock);
555 synchronize_rcu();
557 if (lp->owner != THIS_MODULE)
558 __module_get(lp->owner);
559 return 0;
561 EXPORT_SYMBOL(pflana_proto_register);
563 void pflana_proto_unregister(struct lana_protocol *lp)
565 if (!lp)
566 return;
567 if (lp->protocol < 0 || lp->protocol >= LANA_NPROTO)
568 return;
569 if (!rcu_dereference_raw(proto_tab[lp->protocol]))
570 return;
572 BUG_ON(proto_tab[lp->protocol] != lp);
574 mutex_lock(&proto_tab_lock);
575 rcu_assign_pointer(proto_tab[lp->protocol], NULL);
576 mutex_unlock(&proto_tab_lock);
577 synchronize_rcu();
579 proto_unregister(lp->proto);
580 if (lp->owner != THIS_MODULE)
581 module_put(lp->owner);
583 EXPORT_SYMBOL(pflana_proto_unregister);
585 static int init_fb_pflana(void)
587 int ret, i;
588 for (i = 0; i < LANA_NPROTO; ++i)
589 rcu_assign_pointer(proto_tab[i], NULL);
591 /* Default proto types we definately want to load */
592 ret = pflana_proto_register(LANA_PROTO_RAW, &lana_proto_raw);
593 if (ret)
594 return ret;
596 ret = sock_register(&lana_family_ops);
597 if (ret) {
598 pflana_proto_unregister(&lana_proto_raw);
599 return ret;
601 return 0;
604 static void cleanup_fb_pflana(void)
606 int i;
607 sock_unregister(PF_LANA);
608 for (i = 0; i < LANA_NPROTO; ++i)
609 pflana_proto_unregister(rcu_dereference_raw(proto_tab[i]));
612 static struct fblock_factory fb_pflana_factory;
614 static struct fblock *fb_pflana_ctor(char *name)
616 int ret = 0;
617 unsigned int cpu;
618 struct fblock *fb;
619 struct fb_pflana_priv __percpu *fb_priv;
621 fb = alloc_fblock(GFP_ATOMIC);
622 if (!fb)
623 return NULL;
624 fb_priv = alloc_percpu(struct fb_pflana_priv);
625 if (!fb_priv)
626 goto err;
627 get_online_cpus();
628 for_each_online_cpu(cpu) {
629 struct fb_pflana_priv *fb_priv_cpu;
630 fb_priv_cpu = per_cpu_ptr(fb_priv, cpu);
631 seqlock_init(&fb_priv_cpu->lock);
632 fb_priv_cpu->port[0] = IDP_UNKNOWN;
633 fb_priv_cpu->port[1] = IDP_UNKNOWN;
635 put_online_cpus();
637 ret = init_fblock(fb, name, fb_priv);
638 if (ret)
639 goto err2;
640 fb->netfb_rx = fb_pflana_netrx;
641 fb->event_rx = fb_pflana_event;
642 fb->factory = &fb_pflana_factory;
643 ret = register_fblock_namespace(fb);
644 if (ret)
645 goto err3;
646 __module_get(THIS_MODULE);
647 return fb;
648 err3:
649 cleanup_fblock_ctor(fb);
650 err2:
651 free_percpu(fb_priv);
652 err:
653 kfree_fblock(fb);
654 fb = NULL;
655 return NULL;
658 static void fb_pflana_dtor(struct fblock *fb)
660 free_percpu(rcu_dereference_raw(fb->private_data));
661 module_put(THIS_MODULE);
664 static struct fblock_factory fb_pflana_factory = {
665 .type = "pflana",
666 .mode = MODE_SINK,
667 .ctor = fb_pflana_ctor,
668 .dtor = fb_pflana_dtor,
669 .owner = THIS_MODULE,
672 static int __init init_fb_pflana_module(void)
674 int ret;
675 ret = init_fb_pflana();
676 if (ret)
677 return ret;
678 ret = register_fblock_type(&fb_pflana_factory);
679 if (ret)
680 cleanup_fb_pflana();
681 return ret;
684 static void __exit cleanup_fb_pflana_module(void)
686 cleanup_fb_pflana();
687 unregister_fblock_type(&fb_pflana_factory);
690 module_init(init_fb_pflana_module);
691 module_exit(cleanup_fb_pflana_module);
693 MODULE_LICENSE("GPL");
694 MODULE_AUTHOR("Daniel Borkmann <dborkma@tik.ee.ethz.ch>");
695 MODULE_DESCRIPTION("LANA PF_LANA module");