aboutsummaryrefslogtreecommitdiffstats
path: root/net/econet
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /net/econet
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
Diffstat (limited to 'net/econet')
-rw-r--r--net/econet/Makefile7
-rw-r--r--net/econet/af_econet.c1129
2 files changed, 1136 insertions, 0 deletions
diff --git a/net/econet/Makefile b/net/econet/Makefile
new file mode 100644
index 000000000000..39f0a77abdbd
--- /dev/null
+++ b/net/econet/Makefile
@@ -0,0 +1,7 @@
1#
2# Makefile for Econet support code.
3#
4
5obj-$(CONFIG_ECONET) += econet.o
6
7econet-objs := af_econet.o
diff --git a/net/econet/af_econet.c b/net/econet/af_econet.c
new file mode 100644
index 000000000000..de691e119e17
--- /dev/null
+++ b/net/econet/af_econet.c
@@ -0,0 +1,1129 @@
1/*
2 * An implementation of the Acorn Econet and AUN protocols.
3 * Philip Blundell <philb@gnu.org>
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version
8 * 2 of the License, or (at your option) any later version.
9 *
10 */
11
12#include <linux/config.h>
13#include <linux/module.h>
14
15#include <linux/types.h>
16#include <linux/kernel.h>
17#include <linux/sched.h>
18#include <linux/string.h>
19#include <linux/mm.h>
20#include <linux/socket.h>
21#include <linux/sockios.h>
22#include <linux/in.h>
23#include <linux/errno.h>
24#include <linux/interrupt.h>
25#include <linux/if_ether.h>
26#include <linux/netdevice.h>
27#include <linux/inetdevice.h>
28#include <linux/route.h>
29#include <linux/inet.h>
30#include <linux/etherdevice.h>
31#include <linux/if_arp.h>
32#include <linux/wireless.h>
33#include <linux/skbuff.h>
34#include <net/sock.h>
35#include <net/inet_common.h>
36#include <linux/stat.h>
37#include <linux/init.h>
38#include <linux/if_ec.h>
39#include <net/udp.h>
40#include <net/ip.h>
41#include <linux/spinlock.h>
42#include <linux/rcupdate.h>
43#include <linux/bitops.h>
44
45#include <asm/uaccess.h>
46#include <asm/system.h>
47
48static struct proto_ops econet_ops;
49static struct hlist_head econet_sklist;
50static DEFINE_RWLOCK(econet_lock);
51
52/* Since there are only 256 possible network numbers (or fewer, depends
53 how you count) it makes sense to use a simple lookup table. */
54static struct net_device *net2dev_map[256];
55
56#define EC_PORT_IP 0xd2
57
58#ifdef CONFIG_ECONET_AUNUDP
59static spinlock_t aun_queue_lock;
60static struct socket *udpsock;
61#define AUN_PORT 0x8000
62
63
64struct aunhdr
65{
66 unsigned char code; /* AUN magic protocol byte */
67 unsigned char port;
68 unsigned char cb;
69 unsigned char pad;
70 unsigned long handle;
71};
72
73static unsigned long aun_seq;
74
75/* Queue of packets waiting to be transmitted. */
76static struct sk_buff_head aun_queue;
77static struct timer_list ab_cleanup_timer;
78
79#endif /* CONFIG_ECONET_AUNUDP */
80
81/* Per-packet information */
82struct ec_cb
83{
84 struct sockaddr_ec sec;
85 unsigned long cookie; /* Supplied by user. */
86#ifdef CONFIG_ECONET_AUNUDP
87 int done;
88 unsigned long seq; /* Sequencing */
89 unsigned long timeout; /* Timeout */
90 unsigned long start; /* jiffies */
91#endif
92#ifdef CONFIG_ECONET_NATIVE
93 void (*sent)(struct sk_buff *, int result);
94#endif
95};
96
97static void econet_remove_socket(struct hlist_head *list, struct sock *sk)
98{
99 write_lock_bh(&econet_lock);
100 sk_del_node_init(sk);
101 write_unlock_bh(&econet_lock);
102}
103
104static void econet_insert_socket(struct hlist_head *list, struct sock *sk)
105{
106 write_lock_bh(&econet_lock);
107 sk_add_node(sk, list);
108 write_unlock_bh(&econet_lock);
109}
110
111/*
112 * Pull a packet from our receive queue and hand it to the user.
113 * If necessary we block.
114 */
115
116static int econet_recvmsg(struct kiocb *iocb, struct socket *sock,
117 struct msghdr *msg, size_t len, int flags)
118{
119 struct sock *sk = sock->sk;
120 struct sk_buff *skb;
121 size_t copied;
122 int err;
123
124 msg->msg_namelen = sizeof(struct sockaddr_ec);
125
126 /*
127 * Call the generic datagram receiver. This handles all sorts
128 * of horrible races and re-entrancy so we can forget about it
129 * in the protocol layers.
130 *
131 * Now it will return ENETDOWN, if device have just gone down,
132 * but then it will block.
133 */
134
135 skb=skb_recv_datagram(sk,flags,flags&MSG_DONTWAIT,&err);
136
137 /*
138 * An error occurred so return it. Because skb_recv_datagram()
139 * handles the blocking we don't see and worry about blocking
140 * retries.
141 */
142
143 if(skb==NULL)
144 goto out;
145
146 /*
147 * You lose any data beyond the buffer you gave. If it worries a
148 * user program they can ask the device for its MTU anyway.
149 */
150
151 copied = skb->len;
152 if (copied > len)
153 {
154 copied=len;
155 msg->msg_flags|=MSG_TRUNC;
156 }
157
158 /* We can't use skb_copy_datagram here */
159 err = memcpy_toiovec(msg->msg_iov, skb->data, copied);
160 if (err)
161 goto out_free;
162 sk->sk_stamp = skb->stamp;
163
164 if (msg->msg_name)
165 memcpy(msg->msg_name, skb->cb, msg->msg_namelen);
166
167 /*
168 * Free or return the buffer as appropriate. Again this
169 * hides all the races and re-entrancy issues from us.
170 */
171 err = copied;
172
173out_free:
174 skb_free_datagram(sk, skb);
175out:
176 return err;
177}
178
179/*
180 * Bind an Econet socket.
181 */
182
183static int econet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
184{
185 struct sockaddr_ec *sec = (struct sockaddr_ec *)uaddr;
186 struct sock *sk=sock->sk;
187 struct econet_sock *eo = ec_sk(sk);
188
189 /*
190 * Check legality
191 */
192
193 if (addr_len < sizeof(struct sockaddr_ec) ||
194 sec->sec_family != AF_ECONET)
195 return -EINVAL;
196
197 eo->cb = sec->cb;
198 eo->port = sec->port;
199 eo->station = sec->addr.station;
200 eo->net = sec->addr.net;
201
202 return 0;
203}
204
205#if defined(CONFIG_ECONET_AUNUDP) || defined(CONFIG_ECONET_NATIVE)
206/*
207 * Queue a transmit result for the user to be told about.
208 */
209
210static void tx_result(struct sock *sk, unsigned long cookie, int result)
211{
212 struct sk_buff *skb = alloc_skb(0, GFP_ATOMIC);
213 struct ec_cb *eb;
214 struct sockaddr_ec *sec;
215
216 if (skb == NULL)
217 {
218 printk(KERN_DEBUG "ec: memory squeeze, transmit result dropped.\n");
219 return;
220 }
221
222 eb = (struct ec_cb *)&skb->cb;
223 sec = (struct sockaddr_ec *)&eb->sec;
224 memset(sec, 0, sizeof(struct sockaddr_ec));
225 sec->cookie = cookie;
226 sec->type = ECTYPE_TRANSMIT_STATUS | result;
227 sec->sec_family = AF_ECONET;
228
229 if (sock_queue_rcv_skb(sk, skb) < 0)
230 kfree_skb(skb);
231}
232#endif
233
234#ifdef CONFIG_ECONET_NATIVE
235/*
236 * Called by the Econet hardware driver when a packet transmit
237 * has completed. Tell the user.
238 */
239
240static void ec_tx_done(struct sk_buff *skb, int result)
241{
242 struct ec_cb *eb = (struct ec_cb *)&skb->cb;
243 tx_result(skb->sk, eb->cookie, result);
244}
245#endif
246
247/*
248 * Send a packet. We have to work out which device it's going out on
249 * and hence whether to use real Econet or the UDP emulation.
250 */
251
252static int econet_sendmsg(struct kiocb *iocb, struct socket *sock,
253 struct msghdr *msg, size_t len)
254{
255 struct sock *sk = sock->sk;
256 struct sockaddr_ec *saddr=(struct sockaddr_ec *)msg->msg_name;
257 struct net_device *dev;
258 struct ec_addr addr;
259 int err;
260 unsigned char port, cb;
261#if defined(CONFIG_ECONET_AUNUDP) || defined(CONFIG_ECONET_NATIVE)
262 struct sk_buff *skb;
263 struct ec_cb *eb;
264#endif
265#ifdef CONFIG_ECONET_AUNUDP
266 struct msghdr udpmsg;
267 struct iovec iov[msg->msg_iovlen+1];
268 struct aunhdr ah;
269 struct sockaddr_in udpdest;
270 __kernel_size_t size;
271 int i;
272 mm_segment_t oldfs;
273#endif
274
275 /*
276 * Check the flags.
277 */
278
279 if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_CMSG_COMPAT))
280 return -EINVAL;
281
282 /*
283 * Get and verify the address.
284 */
285
286 if (saddr == NULL) {
287 struct econet_sock *eo = ec_sk(sk);
288
289 addr.station = eo->station;
290 addr.net = eo->net;
291 port = eo->port;
292 cb = eo->cb;
293 } else {
294 if (msg->msg_namelen < sizeof(struct sockaddr_ec))
295 return -EINVAL;
296 addr.station = saddr->addr.station;
297 addr.net = saddr->addr.net;
298 port = saddr->port;
299 cb = saddr->cb;
300 }
301
302 /* Look for a device with the right network number. */
303 dev = net2dev_map[addr.net];
304
305 /* If not directly reachable, use some default */
306 if (dev == NULL)
307 {
308 dev = net2dev_map[0];
309 /* No interfaces at all? */
310 if (dev == NULL)
311 return -ENETDOWN;
312 }
313
314 if (len + 15 > dev->mtu)
315 return -EMSGSIZE;
316
317 if (dev->type == ARPHRD_ECONET)
318 {
319 /* Real hardware Econet. We're not worthy etc. */
320#ifdef CONFIG_ECONET_NATIVE
321 unsigned short proto = 0;
322
323 dev_hold(dev);
324
325 skb = sock_alloc_send_skb(sk, len+LL_RESERVED_SPACE(dev),
326 msg->msg_flags & MSG_DONTWAIT, &err);
327 if (skb==NULL)
328 goto out_unlock;
329
330 skb_reserve(skb, LL_RESERVED_SPACE(dev));
331 skb->nh.raw = skb->data;
332
333 eb = (struct ec_cb *)&skb->cb;
334
335 /* BUG: saddr may be NULL */
336 eb->cookie = saddr->cookie;
337 eb->sec = *saddr;
338 eb->sent = ec_tx_done;
339
340 if (dev->hard_header) {
341 int res;
342 struct ec_framehdr *fh;
343 err = -EINVAL;
344 res = dev->hard_header(skb, dev, ntohs(proto),
345 &addr, NULL, len);
346 /* Poke in our control byte and
347 port number. Hack, hack. */
348 fh = (struct ec_framehdr *)(skb->data);
349 fh->cb = cb;
350 fh->port = port;
351 if (sock->type != SOCK_DGRAM) {
352 skb->tail = skb->data;
353 skb->len = 0;
354 } else if (res < 0)
355 goto out_free;
356 }
357
358 /* Copy the data. Returns -EFAULT on error */
359 err = memcpy_fromiovec(skb_put(skb,len), msg->msg_iov, len);
360 skb->protocol = proto;
361 skb->dev = dev;
362 skb->priority = sk->sk_priority;
363 if (err)
364 goto out_free;
365
366 err = -ENETDOWN;
367 if (!(dev->flags & IFF_UP))
368 goto out_free;
369
370 /*
371 * Now send it
372 */
373
374 dev_queue_xmit(skb);
375 dev_put(dev);
376 return(len);
377
378 out_free:
379 kfree_skb(skb);
380 out_unlock:
381 if (dev)
382 dev_put(dev);
383#else
384 err = -EPROTOTYPE;
385#endif
386 return err;
387 }
388
389#ifdef CONFIG_ECONET_AUNUDP
390 /* AUN virtual Econet. */
391
392 if (udpsock == NULL)
393 return -ENETDOWN; /* No socket - can't send */
394
395 /* Make up a UDP datagram and hand it off to some higher intellect. */
396
397 memset(&udpdest, 0, sizeof(udpdest));
398 udpdest.sin_family = AF_INET;
399 udpdest.sin_port = htons(AUN_PORT);
400
401 /* At the moment we use the stupid Acorn scheme of Econet address
402 y.x maps to IP a.b.c.x. This should be replaced with something
403 more flexible and more aware of subnet masks. */
404 {
405 struct in_device *idev;
406 unsigned long network = 0;
407
408 rcu_read_lock();
409 idev = __in_dev_get(dev);
410 if (idev) {
411 if (idev->ifa_list)
412 network = ntohl(idev->ifa_list->ifa_address) &
413 0xffffff00; /* !!! */
414 }
415 rcu_read_unlock();
416 udpdest.sin_addr.s_addr = htonl(network | addr.station);
417 }
418
419 ah.port = port;
420 ah.cb = cb & 0x7f;
421 ah.code = 2; /* magic */
422 ah.pad = 0;
423
424 /* tack our header on the front of the iovec */
425 size = sizeof(struct aunhdr);
426 /*
427 * XXX: that is b0rken. We can't mix userland and kernel pointers
428 * in iovec, since on a lot of platforms copy_from_user() will
429 * *not* work with the kernel and userland ones at the same time,
430 * regardless of what we do with set_fs(). And we are talking about
431 * econet-over-ethernet here, so "it's only ARM anyway" doesn't
432 * apply. Any suggestions on fixing that code? -- AV
433 */
434 iov[0].iov_base = (void *)&ah;
435 iov[0].iov_len = size;
436 for (i = 0; i < msg->msg_iovlen; i++) {
437 void __user *base = msg->msg_iov[i].iov_base;
438 size_t len = msg->msg_iov[i].iov_len;
439 /* Check it now since we switch to KERNEL_DS later. */
440 if (!access_ok(VERIFY_READ, base, len))
441 return -EFAULT;
442 iov[i+1].iov_base = base;
443 iov[i+1].iov_len = len;
444 size += len;
445 }
446
447 /* Get a skbuff (no data, just holds our cb information) */
448 if ((skb = sock_alloc_send_skb(sk, 0,
449 msg->msg_flags & MSG_DONTWAIT, &err)) == NULL)
450 return err;
451
452 eb = (struct ec_cb *)&skb->cb;
453
454 eb->cookie = saddr->cookie;
455 eb->timeout = (5*HZ);
456 eb->start = jiffies;
457 ah.handle = aun_seq;
458 eb->seq = (aun_seq++);
459 eb->sec = *saddr;
460
461 skb_queue_tail(&aun_queue, skb);
462
463 udpmsg.msg_name = (void *)&udpdest;
464 udpmsg.msg_namelen = sizeof(udpdest);
465 udpmsg.msg_iov = &iov[0];
466 udpmsg.msg_iovlen = msg->msg_iovlen + 1;
467 udpmsg.msg_control = NULL;
468 udpmsg.msg_controllen = 0;
469 udpmsg.msg_flags=0;
470
471 oldfs = get_fs(); set_fs(KERNEL_DS); /* More privs :-) */
472 err = sock_sendmsg(udpsock, &udpmsg, size);
473 set_fs(oldfs);
474#else
475 err = -EPROTOTYPE;
476#endif
477 return err;
478}
479
480/*
481 * Look up the address of a socket.
482 */
483
484static int econet_getname(struct socket *sock, struct sockaddr *uaddr,
485 int *uaddr_len, int peer)
486{
487 struct sock *sk = sock->sk;
488 struct econet_sock *eo = ec_sk(sk);
489 struct sockaddr_ec *sec = (struct sockaddr_ec *)uaddr;
490
491 if (peer)
492 return -EOPNOTSUPP;
493
494 sec->sec_family = AF_ECONET;
495 sec->port = eo->port;
496 sec->addr.station = eo->station;
497 sec->addr.net = eo->net;
498
499 *uaddr_len = sizeof(*sec);
500 return 0;
501}
502
503static void econet_destroy_timer(unsigned long data)
504{
505 struct sock *sk=(struct sock *)data;
506
507 if (!atomic_read(&sk->sk_wmem_alloc) &&
508 !atomic_read(&sk->sk_rmem_alloc)) {
509 sk_free(sk);
510 return;
511 }
512
513 sk->sk_timer.expires = jiffies + 10 * HZ;
514 add_timer(&sk->sk_timer);
515 printk(KERN_DEBUG "econet socket destroy delayed\n");
516}
517
518/*
519 * Close an econet socket.
520 */
521
522static int econet_release(struct socket *sock)
523{
524 struct sock *sk = sock->sk;
525
526 if (!sk)
527 return 0;
528
529 econet_remove_socket(&econet_sklist, sk);
530
531 /*
532 * Now the socket is dead. No more input will appear.
533 */
534
535 sk->sk_state_change(sk); /* It is useless. Just for sanity. */
536
537 sock->sk = NULL;
538 sk->sk_socket = NULL;
539 sock_set_flag(sk, SOCK_DEAD);
540
541 /* Purge queues */
542
543 skb_queue_purge(&sk->sk_receive_queue);
544
545 if (atomic_read(&sk->sk_rmem_alloc) ||
546 atomic_read(&sk->sk_wmem_alloc)) {
547 sk->sk_timer.data = (unsigned long)sk;
548 sk->sk_timer.expires = jiffies + HZ;
549 sk->sk_timer.function = econet_destroy_timer;
550 add_timer(&sk->sk_timer);
551 return 0;
552 }
553
554 sk_free(sk);
555 return 0;
556}
557
558static struct proto econet_proto = {
559 .name = "ECONET",
560 .owner = THIS_MODULE,
561 .obj_size = sizeof(struct econet_sock),
562};
563
564/*
565 * Create an Econet socket
566 */
567
568static int econet_create(struct socket *sock, int protocol)
569{
570 struct sock *sk;
571 struct econet_sock *eo;
572 int err;
573
574 /* Econet only provides datagram services. */
575 if (sock->type != SOCK_DGRAM)
576 return -ESOCKTNOSUPPORT;
577
578 sock->state = SS_UNCONNECTED;
579
580 err = -ENOBUFS;
581 sk = sk_alloc(PF_ECONET, GFP_KERNEL, &econet_proto, 1);
582 if (sk == NULL)
583 goto out;
584
585 sk->sk_reuse = 1;
586 sock->ops = &econet_ops;
587 sock_init_data(sock, sk);
588
589 eo = ec_sk(sk);
590 sock_reset_flag(sk, SOCK_ZAPPED);
591 sk->sk_family = PF_ECONET;
592 eo->num = protocol;
593
594 econet_insert_socket(&econet_sklist, sk);
595 return(0);
596out:
597 return err;
598}
599
600/*
601 * Handle Econet specific ioctls
602 */
603
604static int ec_dev_ioctl(struct socket *sock, unsigned int cmd, void __user *arg)
605{
606 struct ifreq ifr;
607 struct ec_device *edev;
608 struct net_device *dev;
609 struct sockaddr_ec *sec;
610
611 /*
612 * Fetch the caller's info block into kernel space
613 */
614
615 if (copy_from_user(&ifr, arg, sizeof(struct ifreq)))
616 return -EFAULT;
617
618 if ((dev = dev_get_by_name(ifr.ifr_name)) == NULL)
619 return -ENODEV;
620
621 sec = (struct sockaddr_ec *)&ifr.ifr_addr;
622
623 switch (cmd)
624 {
625 case SIOCSIFADDR:
626 edev = dev->ec_ptr;
627 if (edev == NULL)
628 {
629 /* Magic up a new one. */
630 edev = kmalloc(sizeof(struct ec_device), GFP_KERNEL);
631 if (edev == NULL) {
632 printk("af_ec: memory squeeze.\n");
633 dev_put(dev);
634 return -ENOMEM;
635 }
636 memset(edev, 0, sizeof(struct ec_device));
637 dev->ec_ptr = edev;
638 }
639 else
640 net2dev_map[edev->net] = NULL;
641 edev->station = sec->addr.station;
642 edev->net = sec->addr.net;
643 net2dev_map[sec->addr.net] = dev;
644 if (!net2dev_map[0])
645 net2dev_map[0] = dev;
646 dev_put(dev);
647 return 0;
648
649 case SIOCGIFADDR:
650 edev = dev->ec_ptr;
651 if (edev == NULL)
652 {
653 dev_put(dev);
654 return -ENODEV;
655 }
656 memset(sec, 0, sizeof(struct sockaddr_ec));
657 sec->addr.station = edev->station;
658 sec->addr.net = edev->net;
659 sec->sec_family = AF_ECONET;
660 dev_put(dev);
661 if (copy_to_user(arg, &ifr, sizeof(struct ifreq)))
662 return -EFAULT;
663 return 0;
664 }
665
666 dev_put(dev);
667 return -EINVAL;
668}
669
670/*
671 * Handle generic ioctls
672 */
673
674static int econet_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
675{
676 struct sock *sk = sock->sk;
677 void __user *argp = (void __user *)arg;
678
679 switch(cmd) {
680 case SIOCGSTAMP:
681 return sock_get_timestamp(sk, argp);
682
683 case SIOCSIFADDR:
684 case SIOCGIFADDR:
685 return ec_dev_ioctl(sock, cmd, argp);
686 break;
687
688 default:
689 return dev_ioctl(cmd, argp);
690 }
691 /*NOTREACHED*/
692 return 0;
693}
694
695static struct net_proto_family econet_family_ops = {
696 .family = PF_ECONET,
697 .create = econet_create,
698 .owner = THIS_MODULE,
699};
700
701static struct proto_ops SOCKOPS_WRAPPED(econet_ops) = {
702 .family = PF_ECONET,
703 .owner = THIS_MODULE,
704 .release = econet_release,
705 .bind = econet_bind,
706 .connect = sock_no_connect,
707 .socketpair = sock_no_socketpair,
708 .accept = sock_no_accept,
709 .getname = econet_getname,
710 .poll = datagram_poll,
711 .ioctl = econet_ioctl,
712 .listen = sock_no_listen,
713 .shutdown = sock_no_shutdown,
714 .setsockopt = sock_no_setsockopt,
715 .getsockopt = sock_no_getsockopt,
716 .sendmsg = econet_sendmsg,
717 .recvmsg = econet_recvmsg,
718 .mmap = sock_no_mmap,
719 .sendpage = sock_no_sendpage,
720};
721
722#include <linux/smp_lock.h>
723SOCKOPS_WRAP(econet, PF_ECONET);
724
725#if defined(CONFIG_ECONET_AUNUDP) || defined(CONFIG_ECONET_NATIVE)
726/*
727 * Find the listening socket, if any, for the given data.
728 */
729
730static struct sock *ec_listening_socket(unsigned char port, unsigned char
731 station, unsigned char net)
732{
733 struct sock *sk;
734 struct hlist_node *node;
735
736 sk_for_each(sk, node, &econet_sklist) {
737 struct econet_sock *opt = ec_sk(sk);
738 if ((opt->port == port || opt->port == 0) &&
739 (opt->station == station || opt->station == 0) &&
740 (opt->net == net || opt->net == 0))
741 goto found;
742 }
743 sk = NULL;
744found:
745 return sk;
746}
747
748/*
749 * Queue a received packet for a socket.
750 */
751
752static int ec_queue_packet(struct sock *sk, struct sk_buff *skb,
753 unsigned char stn, unsigned char net,
754 unsigned char cb, unsigned char port)
755{
756 struct ec_cb *eb = (struct ec_cb *)&skb->cb;
757 struct sockaddr_ec *sec = (struct sockaddr_ec *)&eb->sec;
758
759 memset(sec, 0, sizeof(struct sockaddr_ec));
760 sec->sec_family = AF_ECONET;
761 sec->type = ECTYPE_PACKET_RECEIVED;
762 sec->port = port;
763 sec->cb = cb;
764 sec->addr.net = net;
765 sec->addr.station = stn;
766
767 return sock_queue_rcv_skb(sk, skb);
768}
769#endif
770
771#ifdef CONFIG_ECONET_AUNUDP
772/*
773 * Send an AUN protocol response.
774 */
775
776static void aun_send_response(__u32 addr, unsigned long seq, int code, int cb)
777{
778 struct sockaddr_in sin = {
779 .sin_family = AF_INET,
780 .sin_port = htons(AUN_PORT),
781 .sin_addr = {.s_addr = addr}
782 };
783 struct aunhdr ah = {.code = code, .cb = cb, .handle = seq};
784 struct kvec iov = {.iov_base = (void *)&ah, .iov_len = sizeof(ah)};
785 struct msghdr udpmsg;
786
787 udpmsg.msg_name = (void *)&sin;
788 udpmsg.msg_namelen = sizeof(sin);
789 udpmsg.msg_control = NULL;
790 udpmsg.msg_controllen = 0;
791 udpmsg.msg_flags=0;
792
793 kernel_sendmsg(udpsock, &udpmsg, &iov, 1, sizeof(ah));
794}
795
796
797/*
798 * Handle incoming AUN packets. Work out if anybody wants them,
799 * and send positive or negative acknowledgements as appropriate.
800 */
801
802static void aun_incoming(struct sk_buff *skb, struct aunhdr *ah, size_t len)
803{
804 struct iphdr *ip = skb->nh.iph;
805 unsigned char stn = ntohl(ip->saddr) & 0xff;
806 struct sock *sk;
807 struct sk_buff *newskb;
808 struct ec_device *edev = skb->dev->ec_ptr;
809
810 if (! edev)
811 goto bad;
812
813 if ((sk = ec_listening_socket(ah->port, stn, edev->net)) == NULL)
814 goto bad; /* Nobody wants it */
815
816 newskb = alloc_skb((len - sizeof(struct aunhdr) + 15) & ~15,
817 GFP_ATOMIC);
818 if (newskb == NULL)
819 {
820 printk(KERN_DEBUG "AUN: memory squeeze, dropping packet.\n");
821 /* Send nack and hope sender tries again */
822 goto bad;
823 }
824
825 memcpy(skb_put(newskb, len - sizeof(struct aunhdr)), (void *)(ah+1),
826 len - sizeof(struct aunhdr));
827
828 if (ec_queue_packet(sk, newskb, stn, edev->net, ah->cb, ah->port))
829 {
830 /* Socket is bankrupt. */
831 kfree_skb(newskb);
832 goto bad;
833 }
834
835 aun_send_response(ip->saddr, ah->handle, 3, 0);
836 return;
837
838bad:
839 aun_send_response(ip->saddr, ah->handle, 4, 0);
840}
841
842/*
843 * Handle incoming AUN transmit acknowledgements. If the sequence
844 * number matches something in our backlog then kill it and tell
845 * the user. If the remote took too long to reply then we may have
846 * dropped the packet already.
847 */
848
849static void aun_tx_ack(unsigned long seq, int result)
850{
851 struct sk_buff *skb;
852 unsigned long flags;
853 struct ec_cb *eb;
854
855 spin_lock_irqsave(&aun_queue_lock, flags);
856 skb = skb_peek(&aun_queue);
857 while (skb && skb != (struct sk_buff *)&aun_queue)
858 {
859 struct sk_buff *newskb = skb->next;
860 eb = (struct ec_cb *)&skb->cb;
861 if (eb->seq == seq)
862 goto foundit;
863
864 skb = newskb;
865 }
866 spin_unlock_irqrestore(&aun_queue_lock, flags);
867 printk(KERN_DEBUG "AUN: unknown sequence %ld\n", seq);
868 return;
869
870foundit:
871 tx_result(skb->sk, eb->cookie, result);
872 skb_unlink(skb);
873 spin_unlock_irqrestore(&aun_queue_lock, flags);
874 kfree_skb(skb);
875}
876
877/*
878 * Deal with received AUN frames - sort out what type of thing it is
879 * and hand it to the right function.
880 */
881
882static void aun_data_available(struct sock *sk, int slen)
883{
884 int err;
885 struct sk_buff *skb;
886 unsigned char *data;
887 struct aunhdr *ah;
888 struct iphdr *ip;
889 size_t len;
890
891 while ((skb = skb_recv_datagram(sk, 0, 1, &err)) == NULL) {
892 if (err == -EAGAIN) {
893 printk(KERN_ERR "AUN: no data available?!");
894 return;
895 }
896 printk(KERN_DEBUG "AUN: recvfrom() error %d\n", -err);
897 }
898
899 data = skb->h.raw + sizeof(struct udphdr);
900 ah = (struct aunhdr *)data;
901 len = skb->len - sizeof(struct udphdr);
902 ip = skb->nh.iph;
903
904 switch (ah->code)
905 {
906 case 2:
907 aun_incoming(skb, ah, len);
908 break;
909 case 3:
910 aun_tx_ack(ah->handle, ECTYPE_TRANSMIT_OK);
911 break;
912 case 4:
913 aun_tx_ack(ah->handle, ECTYPE_TRANSMIT_NOT_LISTENING);
914 break;
915#if 0
916 /* This isn't quite right yet. */
917 case 5:
918 aun_send_response(ip->saddr, ah->handle, 6, ah->cb);
919 break;
920#endif
921 default:
922 printk(KERN_DEBUG "unknown AUN packet (type %d)\n", data[0]);
923 }
924
925 skb_free_datagram(sk, skb);
926}
927
928/*
929 * Called by the timer to manage the AUN transmit queue. If a packet
930 * was sent to a dead or nonexistent host then we will never get an
931 * acknowledgement back. After a few seconds we need to spot this and
932 * drop the packet.
933 */
934
935static void ab_cleanup(unsigned long h)
936{
937 struct sk_buff *skb;
938 unsigned long flags;
939
940 spin_lock_irqsave(&aun_queue_lock, flags);
941 skb = skb_peek(&aun_queue);
942 while (skb && skb != (struct sk_buff *)&aun_queue)
943 {
944 struct sk_buff *newskb = skb->next;
945 struct ec_cb *eb = (struct ec_cb *)&skb->cb;
946 if ((jiffies - eb->start) > eb->timeout)
947 {
948 tx_result(skb->sk, eb->cookie,
949 ECTYPE_TRANSMIT_NOT_PRESENT);
950 skb_unlink(skb);
951 kfree_skb(skb);
952 }
953 skb = newskb;
954 }
955 spin_unlock_irqrestore(&aun_queue_lock, flags);
956
957 mod_timer(&ab_cleanup_timer, jiffies + (HZ*2));
958}
959
960static int __init aun_udp_initialise(void)
961{
962 int error;
963 struct sockaddr_in sin;
964
965 skb_queue_head_init(&aun_queue);
966 spin_lock_init(&aun_queue_lock);
967 init_timer(&ab_cleanup_timer);
968 ab_cleanup_timer.expires = jiffies + (HZ*2);
969 ab_cleanup_timer.function = ab_cleanup;
970 add_timer(&ab_cleanup_timer);
971
972 memset(&sin, 0, sizeof(sin));
973 sin.sin_port = htons(AUN_PORT);
974
975 /* We can count ourselves lucky Acorn machines are too dim to
976 speak IPv6. :-) */
977 if ((error = sock_create_kern(PF_INET, SOCK_DGRAM, 0, &udpsock)) < 0)
978 {
979 printk("AUN: socket error %d\n", -error);
980 return error;
981 }
982
983 udpsock->sk->sk_reuse = 1;
984 udpsock->sk->sk_allocation = GFP_ATOMIC; /* we're going to call it
985 from interrupts */
986
987 error = udpsock->ops->bind(udpsock, (struct sockaddr *)&sin,
988 sizeof(sin));
989 if (error < 0)
990 {
991 printk("AUN: bind error %d\n", -error);
992 goto release;
993 }
994
995 udpsock->sk->sk_data_ready = aun_data_available;
996
997 return 0;
998
999release:
1000 sock_release(udpsock);
1001 udpsock = NULL;
1002 return error;
1003}
1004#endif
1005
1006#ifdef CONFIG_ECONET_NATIVE
1007
1008/*
1009 * Receive an Econet frame from a device.
1010 */
1011
1012static int econet_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt)
1013{
1014 struct ec_framehdr *hdr;
1015 struct sock *sk;
1016 struct ec_device *edev = dev->ec_ptr;
1017
1018 if (skb->pkt_type == PACKET_OTHERHOST)
1019 goto drop;
1020
1021 if (!edev)
1022 goto drop;
1023
1024 if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL)
1025 return NET_RX_DROP;
1026
1027 if (!pskb_may_pull(skb, sizeof(struct ec_framehdr)))
1028 goto drop;
1029
1030 hdr = (struct ec_framehdr *) skb->data;
1031
1032 /* First check for encapsulated IP */
1033 if (hdr->port == EC_PORT_IP) {
1034 skb->protocol = htons(ETH_P_IP);
1035 skb_pull(skb, sizeof(struct ec_framehdr));
1036 netif_rx(skb);
1037 return 0;
1038 }
1039
1040 sk = ec_listening_socket(hdr->port, hdr->src_stn, hdr->src_net);
1041 if (!sk)
1042 goto drop;
1043
1044 if (ec_queue_packet(sk, skb, edev->net, hdr->src_stn, hdr->cb,
1045 hdr->port))
1046 goto drop;
1047
1048 return 0;
1049
1050drop:
1051 kfree_skb(skb);
1052 return NET_RX_DROP;
1053}
1054
1055static struct packet_type econet_packet_type = {
1056 .type = __constant_htons(ETH_P_ECONET),
1057 .func = econet_rcv,
1058};
1059
1060static void econet_hw_initialise(void)
1061{
1062 dev_add_pack(&econet_packet_type);
1063}
1064
1065#endif
1066
1067static int econet_notifier(struct notifier_block *this, unsigned long msg, void *data)
1068{
1069 struct net_device *dev = (struct net_device *)data;
1070 struct ec_device *edev;
1071
1072 switch (msg) {
1073 case NETDEV_UNREGISTER:
1074 /* A device has gone down - kill any data we hold for it. */
1075 edev = dev->ec_ptr;
1076 if (edev)
1077 {
1078 if (net2dev_map[0] == dev)
1079 net2dev_map[0] = NULL;
1080 net2dev_map[edev->net] = NULL;
1081 kfree(edev);
1082 dev->ec_ptr = NULL;
1083 }
1084 break;
1085 }
1086
1087 return NOTIFY_DONE;
1088}
1089
1090static struct notifier_block econet_netdev_notifier = {
1091 .notifier_call =econet_notifier,
1092};
1093
1094static void __exit econet_proto_exit(void)
1095{
1096#ifdef CONFIG_ECONET_AUNUDP
1097 del_timer(&ab_cleanup_timer);
1098 if (udpsock)
1099 sock_release(udpsock);
1100#endif
1101 unregister_netdevice_notifier(&econet_netdev_notifier);
1102 sock_unregister(econet_family_ops.family);
1103 proto_unregister(&econet_proto);
1104}
1105
1106static int __init econet_proto_init(void)
1107{
1108 int err = proto_register(&econet_proto, 0);
1109
1110 if (err != 0)
1111 goto out;
1112 sock_register(&econet_family_ops);
1113#ifdef CONFIG_ECONET_AUNUDP
1114 spin_lock_init(&aun_queue_lock);
1115 aun_udp_initialise();
1116#endif
1117#ifdef CONFIG_ECONET_NATIVE
1118 econet_hw_initialise();
1119#endif
1120 register_netdevice_notifier(&econet_netdev_notifier);
1121out:
1122 return err;
1123}
1124
1125module_init(econet_proto_init);
1126module_exit(econet_proto_exit);
1127
1128MODULE_LICENSE("GPL");
1129MODULE_ALIAS_NETPROTO(PF_ECONET);