blob: 251a3ce376ac60828fea0389b97316c649b6adcc [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * slip.c This module implements the SLIP protocol for kernel-based
3 * devices like TTY. It interfaces between a raw TTY, and the
4 * kernel's INET protocol layers.
5 *
6 * Version: @(#)slip.c 0.8.3 12/24/94
7 *
8 * Authors: Laurence Culhane, <loz@holmes.demon.co.uk>
9 * Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org>
10 *
11 * Fixes:
12 * Alan Cox : Sanity checks and avoid tx overruns.
13 * Has a new sl->mtu field.
14 * Alan Cox : Found cause of overrun. ifconfig sl0 mtu upwards.
15 * Driver now spots this and grows/shrinks its buffers(hack!).
16 * Memory leak if you run out of memory setting up a slip driver fixed.
17 * Matt Dillon : Printable slip (borrowed from NET2E)
18 * Pauline Middelink : Slip driver fixes.
19 * Alan Cox : Honours the old SL_COMPRESSED flag
20 * Alan Cox : KISS AX.25 and AXUI IP support
21 * Michael Riepe : Automatic CSLIP recognition added
22 * Charles Hedrick : CSLIP header length problem fix.
23 * Alan Cox : Corrected non-IP cases of the above.
24 * Alan Cox : Now uses hardware type as per FvK.
25 * Alan Cox : Default to 192.168.0.0 (RFC 1597)
26 * A.N.Kuznetsov : dev_tint() recursion fix.
27 * Dmitry Gorodchanin : SLIP memory leaks
28 * Dmitry Gorodchanin : Code cleanup. Reduce tty driver
29 * buffering from 4096 to 256 bytes.
30 * Improving SLIP response time.
31 * CONFIG_SLIP_MODE_SLIP6.
32 * ifconfig sl? up & down now works correctly.
33 * Modularization.
34 * Alan Cox : Oops - fix AX.25 buffer lengths
35 * Dmitry Gorodchanin : Even more cleanups. Preserve CSLIP
36 * statistics. Include CSLIP code only
37 * if it really needed.
38 * Alan Cox : Free slhc buffers in the right place.
39 * Alan Cox : Allow for digipeated IP over AX.25
40 * Matti Aarnio : Dynamic SLIP devices, with ideas taken
41 * from Jim Freeman's <jfree@caldera.com>
42 * dynamic PPP devices. We do NOT kfree()
43 * device entries, just reg./unreg. them
44 * as they are needed. We kfree() them
45 * at module cleanup.
46 * With MODULE-loading ``insmod'', user can
47 * issue parameter: slip_maxdev=1024
48 * (Or how much he/she wants.. Default is 256)
49 * * Stanislav Voronyi : Slip line checking, with ideas taken
50 * from multislip BSDI driver which was written
51 * by Igor Chechik, RELCOM Corp. Only algorithms
52 * have been ported to Linux SLIP driver.
53 * Vitaly E. Lavrov : Sane behaviour on tty hangup.
54 * Alexey Kuznetsov : Cleanup interfaces to tty&netdevice modules.
55 */
56
57#define SL_CHECK_TRANSMIT
Linus Torvalds1da177e2005-04-16 15:20:36 -070058#include <linux/module.h>
59#include <linux/moduleparam.h>
60
61#include <asm/system.h>
62#include <asm/uaccess.h>
63#include <linux/bitops.h>
64#include <linux/string.h>
65#include <linux/mm.h>
66#include <linux/interrupt.h>
67#include <linux/in.h>
68#include <linux/tty.h>
69#include <linux/errno.h>
70#include <linux/netdevice.h>
71#include <linux/etherdevice.h>
72#include <linux/skbuff.h>
73#include <linux/rtnetlink.h>
74#include <linux/if_arp.h>
75#include <linux/if_slip.h>
David S. Miller12dc2fd2005-06-28 16:27:32 -070076#include <linux/delay.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070077#include <linux/init.h>
78#include "slip.h"
79#ifdef CONFIG_INET
80#include <linux/ip.h>
81#include <linux/tcp.h>
82#include <net/slhc_vj.h>
83#endif
84
85#define SLIP_VERSION "0.8.4-NET3.019-NEWTTY"
86
87static struct net_device **slip_devs;
88
89static int slip_maxdev = SL_NRUNIT;
90module_param(slip_maxdev, int, 0);
91MODULE_PARM_DESC(slip_maxdev, "Maximum number of slip devices");
92
93static int slip_esc(unsigned char *p, unsigned char *d, int len);
94static void slip_unesc(struct slip *sl, unsigned char c);
95#ifdef CONFIG_SLIP_MODE_SLIP6
96static int slip_esc6(unsigned char *p, unsigned char *d, int len);
97static void slip_unesc6(struct slip *sl, unsigned char c);
98#endif
99#ifdef CONFIG_SLIP_SMART
100static void sl_keepalive(unsigned long sls);
101static void sl_outfill(unsigned long sls);
102static int sl_ioctl(struct net_device *dev,struct ifreq *rq,int cmd);
103#endif
104
105/********************************
106* Buffer administration routines:
107* sl_alloc_bufs()
108* sl_free_bufs()
109* sl_realloc_bufs()
110*
111* NOTE: sl_realloc_bufs != sl_free_bufs + sl_alloc_bufs, because
112* sl_realloc_bufs provides strong atomicity and reallocation
113* on actively running device.
114*********************************/
115
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400116/*
Linus Torvalds1da177e2005-04-16 15:20:36 -0700117 Allocate channel buffers.
118 */
119
120static int
121sl_alloc_bufs(struct slip *sl, int mtu)
122{
123 int err = -ENOBUFS;
124 unsigned long len;
125 char * rbuff = NULL;
126 char * xbuff = NULL;
127#ifdef SL_INCLUDE_CSLIP
128 char * cbuff = NULL;
129 struct slcompress *slcomp = NULL;
130#endif
131
132 /*
133 * Allocate the SLIP frame buffers:
134 *
135 * rbuff Receive buffer.
136 * xbuff Transmit buffer.
137 * cbuff Temporary compression buffer.
138 */
139 len = mtu * 2;
140
141 /*
142 * allow for arrival of larger UDP packets, even if we say not to
143 * also fixes a bug in which SunOS sends 512-byte packets even with
144 * an MSS of 128
145 */
146 if (len < 576 * 2)
147 len = 576 * 2;
148 rbuff = kmalloc(len + 4, GFP_KERNEL);
149 if (rbuff == NULL)
150 goto err_exit;
151 xbuff = kmalloc(len + 4, GFP_KERNEL);
152 if (xbuff == NULL)
153 goto err_exit;
154#ifdef SL_INCLUDE_CSLIP
155 cbuff = kmalloc(len + 4, GFP_KERNEL);
156 if (cbuff == NULL)
157 goto err_exit;
158 slcomp = slhc_init(16, 16);
159 if (slcomp == NULL)
160 goto err_exit;
161#endif
162 spin_lock_bh(&sl->lock);
163 if (sl->tty == NULL) {
164 spin_unlock_bh(&sl->lock);
165 err = -ENODEV;
166 goto err_exit;
167 }
168 sl->mtu = mtu;
169 sl->buffsize = len;
170 sl->rcount = 0;
171 sl->xleft = 0;
172 rbuff = xchg(&sl->rbuff, rbuff);
173 xbuff = xchg(&sl->xbuff, xbuff);
174#ifdef SL_INCLUDE_CSLIP
175 cbuff = xchg(&sl->cbuff, cbuff);
176 slcomp = xchg(&sl->slcomp, slcomp);
177#ifdef CONFIG_SLIP_MODE_SLIP6
178 sl->xdata = 0;
179 sl->xbits = 0;
180#endif
181#endif
182 spin_unlock_bh(&sl->lock);
183 err = 0;
184
185 /* Cleanup */
186err_exit:
187#ifdef SL_INCLUDE_CSLIP
Jesper Juhl158a0e42005-04-24 18:59:30 -0700188 kfree(cbuff);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700189 if (slcomp)
190 slhc_free(slcomp);
191#endif
Jesper Juhl158a0e42005-04-24 18:59:30 -0700192 kfree(xbuff);
193 kfree(rbuff);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700194 return err;
195}
196
197/* Free a SLIP channel buffers. */
198static void
199sl_free_bufs(struct slip *sl)
200{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700201 /* Free all SLIP frame buffers. */
Jesper Juhl9b200b02005-06-23 21:06:56 -0700202 kfree(xchg(&sl->rbuff, NULL));
203 kfree(xchg(&sl->xbuff, NULL));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700204#ifdef SL_INCLUDE_CSLIP
Jesper Juhl9b200b02005-06-23 21:06:56 -0700205 kfree(xchg(&sl->cbuff, NULL));
206 slhc_free(xchg(&sl->slcomp, NULL));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700207#endif
208}
209
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400210/*
Linus Torvalds1da177e2005-04-16 15:20:36 -0700211 Reallocate slip channel buffers.
212 */
213
214static int sl_realloc_bufs(struct slip *sl, int mtu)
215{
216 int err = 0;
217 struct net_device *dev = sl->dev;
218 unsigned char *xbuff, *rbuff;
219#ifdef SL_INCLUDE_CSLIP
220 unsigned char *cbuff;
221#endif
222 int len = mtu * 2;
223
224/*
225 * allow for arrival of larger UDP packets, even if we say not to
226 * also fixes a bug in which SunOS sends 512-byte packets even with
227 * an MSS of 128
228 */
229 if (len < 576 * 2)
230 len = 576 * 2;
231
Robert P. J. Day5cbded52006-12-13 00:35:56 -0800232 xbuff = kmalloc(len + 4, GFP_ATOMIC);
233 rbuff = kmalloc(len + 4, GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700234#ifdef SL_INCLUDE_CSLIP
Robert P. J. Day5cbded52006-12-13 00:35:56 -0800235 cbuff = kmalloc(len + 4, GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700236#endif
237
238
239#ifdef SL_INCLUDE_CSLIP
240 if (xbuff == NULL || rbuff == NULL || cbuff == NULL) {
241#else
242 if (xbuff == NULL || rbuff == NULL) {
243#endif
244 if (mtu >= sl->mtu) {
245 printk(KERN_WARNING "%s: unable to grow slip buffers, MTU change cancelled.\n",
246 dev->name);
247 err = -ENOBUFS;
248 }
249 goto done;
250 }
251
252 spin_lock_bh(&sl->lock);
253
254 err = -ENODEV;
255 if (sl->tty == NULL)
256 goto done_on_bh;
257
258 xbuff = xchg(&sl->xbuff, xbuff);
259 rbuff = xchg(&sl->rbuff, rbuff);
260#ifdef SL_INCLUDE_CSLIP
261 cbuff = xchg(&sl->cbuff, cbuff);
262#endif
263 if (sl->xleft) {
264 if (sl->xleft <= len) {
265 memcpy(sl->xbuff, sl->xhead, sl->xleft);
266 } else {
267 sl->xleft = 0;
268 sl->tx_dropped++;
269 }
270 }
271 sl->xhead = sl->xbuff;
272
273 if (sl->rcount) {
274 if (sl->rcount <= len) {
275 memcpy(sl->rbuff, rbuff, sl->rcount);
276 } else {
277 sl->rcount = 0;
278 sl->rx_over_errors++;
279 set_bit(SLF_ERROR, &sl->flags);
280 }
281 }
282 sl->mtu = mtu;
283 dev->mtu = mtu;
284 sl->buffsize = len;
285 err = 0;
286
287done_on_bh:
288 spin_unlock_bh(&sl->lock);
289
290done:
Jesper Juhl158a0e42005-04-24 18:59:30 -0700291 kfree(xbuff);
292 kfree(rbuff);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700293#ifdef SL_INCLUDE_CSLIP
Jesper Juhl158a0e42005-04-24 18:59:30 -0700294 kfree(cbuff);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700295#endif
296 return err;
297}
298
299
300/* Set the "sending" flag. This must be atomic hence the set_bit. */
301static inline void
302sl_lock(struct slip *sl)
303{
304 netif_stop_queue(sl->dev);
305}
306
307
308/* Clear the "sending" flag. This must be atomic, hence the ASM. */
309static inline void
310sl_unlock(struct slip *sl)
311{
312 netif_wake_queue(sl->dev);
313}
314
315/* Send one completely decapsulated IP datagram to the IP layer. */
316static void
317sl_bump(struct slip *sl)
318{
319 struct sk_buff *skb;
320 int count;
321
322 count = sl->rcount;
323#ifdef SL_INCLUDE_CSLIP
324 if (sl->mode & (SL_MODE_ADAPTIVE | SL_MODE_CSLIP)) {
325 unsigned char c;
326 if ((c = sl->rbuff[0]) & SL_TYPE_COMPRESSED_TCP) {
327 /* ignore compressed packets when CSLIP is off */
328 if (!(sl->mode & SL_MODE_CSLIP)) {
329 printk(KERN_WARNING "%s: compressed packet ignored\n", sl->dev->name);
330 return;
331 }
332 /* make sure we've reserved enough space for uncompress to use */
333 if (count + 80 > sl->buffsize) {
334 sl->rx_over_errors++;
335 return;
336 }
337 count = slhc_uncompress(sl->slcomp, sl->rbuff, count);
338 if (count <= 0) {
339 return;
340 }
341 } else if (c >= SL_TYPE_UNCOMPRESSED_TCP) {
342 if (!(sl->mode & SL_MODE_CSLIP)) {
343 /* turn on header compression */
344 sl->mode |= SL_MODE_CSLIP;
345 sl->mode &= ~SL_MODE_ADAPTIVE;
346 printk(KERN_INFO "%s: header compression turned on\n", sl->dev->name);
347 }
348 sl->rbuff[0] &= 0x4f;
349 if (slhc_remember(sl->slcomp, sl->rbuff, count) <= 0) {
350 return;
351 }
352 }
353 }
354#endif /* SL_INCLUDE_CSLIP */
355
356 sl->rx_bytes+=count;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400357
Linus Torvalds1da177e2005-04-16 15:20:36 -0700358 skb = dev_alloc_skb(count);
359 if (skb == NULL) {
360 printk(KERN_WARNING "%s: memory squeeze, dropping packet.\n", sl->dev->name);
361 sl->rx_dropped++;
362 return;
363 }
364 skb->dev = sl->dev;
365 memcpy(skb_put(skb,count), sl->rbuff, count);
Arnaldo Carvalho de Melo98e399f2007-03-19 15:33:04 -0700366 skb_reset_mac_header(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700367 skb->protocol=htons(ETH_P_IP);
368 netif_rx(skb);
369 sl->dev->last_rx = jiffies;
370 sl->rx_packets++;
371}
372
373/* Encapsulate one IP datagram and stuff into a TTY queue. */
374static void
375sl_encaps(struct slip *sl, unsigned char *icp, int len)
376{
377 unsigned char *p;
378 int actual, count;
379
380 if (len > sl->mtu) { /* Sigh, shouldn't occur BUT ... */
381 printk(KERN_WARNING "%s: truncating oversized transmit packet!\n", sl->dev->name);
382 sl->tx_dropped++;
383 sl_unlock(sl);
384 return;
385 }
386
387 p = icp;
388#ifdef SL_INCLUDE_CSLIP
389 if (sl->mode & SL_MODE_CSLIP) {
390 len = slhc_compress(sl->slcomp, p, len, sl->cbuff, &p, 1);
391 }
392#endif
393#ifdef CONFIG_SLIP_MODE_SLIP6
394 if(sl->mode & SL_MODE_SLIP6)
395 count = slip_esc6(p, (unsigned char *) sl->xbuff, len);
396 else
397#endif
398 count = slip_esc(p, (unsigned char *) sl->xbuff, len);
399
400 /* Order of next two lines is *very* important.
401 * When we are sending a little amount of data,
402 * the transfer may be completed inside driver.write()
403 * routine, because it's running with interrupts enabled.
404 * In this case we *never* got WRITE_WAKEUP event,
405 * if we did not request it before write operation.
406 * 14 Oct 1994 Dmitry Gorodchanin.
407 */
408 sl->tty->flags |= (1 << TTY_DO_WRITE_WAKEUP);
409 actual = sl->tty->driver->write(sl->tty, sl->xbuff, count);
410#ifdef SL_CHECK_TRANSMIT
411 sl->dev->trans_start = jiffies;
412#endif
413 sl->xleft = count - actual;
414 sl->xhead = sl->xbuff + actual;
415#ifdef CONFIG_SLIP_SMART
416 /* VSV */
417 clear_bit(SLF_OUTWAIT, &sl->flags); /* reset outfill flag */
418#endif
419}
420
421/*
422 * Called by the driver when there's room for more data. If we have
423 * more packets to send, we send them here.
424 */
425static void slip_write_wakeup(struct tty_struct *tty)
426{
427 int actual;
428 struct slip *sl = (struct slip *) tty->disc_data;
429
430 /* First make sure we're connected. */
431 if (!sl || sl->magic != SLIP_MAGIC || !netif_running(sl->dev)) {
432 return;
433 }
434 if (sl->xleft <= 0) {
435 /* Now serial buffer is almost free & we can start
436 * transmission of another packet */
437 sl->tx_packets++;
438 tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
439 sl_unlock(sl);
440 return;
441 }
442
443 actual = tty->driver->write(tty, sl->xhead, sl->xleft);
444 sl->xleft -= actual;
445 sl->xhead += actual;
446}
447
448static void sl_tx_timeout(struct net_device *dev)
449{
450 struct slip *sl = netdev_priv(dev);
451
452 spin_lock(&sl->lock);
453
454 if (netif_queue_stopped(dev)) {
455 if (!netif_running(dev))
456 goto out;
457
458 /* May be we must check transmitter timeout here ?
459 * 14 Oct 1994 Dmitry Gorodchanin.
460 */
461#ifdef SL_CHECK_TRANSMIT
462 if (time_before(jiffies, dev->trans_start + 20 * HZ)) {
463 /* 20 sec timeout not reached */
464 goto out;
465 }
466 printk(KERN_WARNING "%s: transmit timed out, %s?\n", dev->name,
467 (sl->tty->driver->chars_in_buffer(sl->tty) || sl->xleft) ?
468 "bad line quality" : "driver error");
469 sl->xleft = 0;
470 sl->tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
471 sl_unlock(sl);
472#endif
473 }
474
475out:
476 spin_unlock(&sl->lock);
477}
478
479
480/* Encapsulate an IP datagram and kick it into a TTY queue. */
481static int
482sl_xmit(struct sk_buff *skb, struct net_device *dev)
483{
484 struct slip *sl = netdev_priv(dev);
485
486 spin_lock(&sl->lock);
487 if (!netif_running(dev)) {
488 spin_unlock(&sl->lock);
489 printk(KERN_WARNING "%s: xmit call when iface is down\n", dev->name);
490 dev_kfree_skb(skb);
491 return 0;
492 }
493 if (sl->tty == NULL) {
494 spin_unlock(&sl->lock);
495 dev_kfree_skb(skb);
496 return 0;
497 }
498
499 sl_lock(sl);
500 sl->tx_bytes+=skb->len;
501 sl_encaps(sl, skb->data, skb->len);
502 spin_unlock(&sl->lock);
503
504 dev_kfree_skb(skb);
505 return 0;
506}
507
508
509/******************************************
510 * Routines looking at netdevice side.
511 ******************************************/
512
513/* Netdevice UP -> DOWN routine */
514
515static int
516sl_close(struct net_device *dev)
517{
518 struct slip *sl = netdev_priv(dev);
519
520 spin_lock_bh(&sl->lock);
521 if (sl->tty) {
522 /* TTY discipline is running. */
523 sl->tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
524 }
525 netif_stop_queue(dev);
526 sl->rcount = 0;
527 sl->xleft = 0;
528 spin_unlock_bh(&sl->lock);
529
530 return 0;
531}
532
533/* Netdevice DOWN -> UP routine */
534
535static int sl_open(struct net_device *dev)
536{
537 struct slip *sl = netdev_priv(dev);
538
539 if (sl->tty==NULL)
540 return -ENODEV;
541
542 sl->flags &= (1 << SLF_INUSE);
543 netif_start_queue(dev);
544 return 0;
545}
546
547/* Netdevice change MTU request */
548
549static int sl_change_mtu(struct net_device *dev, int new_mtu)
550{
551 struct slip *sl = netdev_priv(dev);
552
553 if (new_mtu < 68 || new_mtu > 65534)
554 return -EINVAL;
555
556 if (new_mtu != dev->mtu)
557 return sl_realloc_bufs(sl, new_mtu);
558 return 0;
559}
560
561/* Netdevice get statistics request */
562
563static struct net_device_stats *
564sl_get_stats(struct net_device *dev)
565{
566 static struct net_device_stats stats;
567 struct slip *sl = netdev_priv(dev);
568#ifdef SL_INCLUDE_CSLIP
569 struct slcompress *comp;
570#endif
571
572 memset(&stats, 0, sizeof(struct net_device_stats));
573
574 stats.rx_packets = sl->rx_packets;
575 stats.tx_packets = sl->tx_packets;
576 stats.rx_bytes = sl->rx_bytes;
577 stats.tx_bytes = sl->tx_bytes;
578 stats.rx_dropped = sl->rx_dropped;
579 stats.tx_dropped = sl->tx_dropped;
580 stats.tx_errors = sl->tx_errors;
581 stats.rx_errors = sl->rx_errors;
582 stats.rx_over_errors = sl->rx_over_errors;
583#ifdef SL_INCLUDE_CSLIP
584 stats.rx_fifo_errors = sl->rx_compressed;
585 stats.tx_fifo_errors = sl->tx_compressed;
586 stats.collisions = sl->tx_misses;
587 comp = sl->slcomp;
588 if (comp) {
589 stats.rx_fifo_errors += comp->sls_i_compressed;
590 stats.rx_dropped += comp->sls_i_tossed;
591 stats.tx_fifo_errors += comp->sls_o_compressed;
592 stats.collisions += comp->sls_o_misses;
593 }
594#endif /* CONFIG_INET */
595 return (&stats);
596}
597
598/* Netdevice register callback */
599
600static int sl_init(struct net_device *dev)
601{
602 struct slip *sl = netdev_priv(dev);
603
604 /*
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400605 * Finish setting up the DEVICE info.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700606 */
607
608 dev->mtu = sl->mtu;
609 dev->type = ARPHRD_SLIP + sl->mode;
610#ifdef SL_CHECK_TRANSMIT
611 dev->tx_timeout = sl_tx_timeout;
612 dev->watchdog_timeo = 20*HZ;
613#endif
614 return 0;
615}
616
617
618static void sl_uninit(struct net_device *dev)
619{
620 struct slip *sl = netdev_priv(dev);
621
622 sl_free_bufs(sl);
623}
624
625static void sl_setup(struct net_device *dev)
626{
627 dev->init = sl_init;
628 dev->uninit = sl_uninit;
629 dev->open = sl_open;
630 dev->destructor = free_netdev;
631 dev->stop = sl_close;
632 dev->get_stats = sl_get_stats;
633 dev->change_mtu = sl_change_mtu;
634 dev->hard_start_xmit = sl_xmit;
635#ifdef CONFIG_SLIP_SMART
636 dev->do_ioctl = sl_ioctl;
637#endif
638 dev->hard_header_len = 0;
639 dev->addr_len = 0;
640 dev->tx_queue_len = 10;
641
Linus Torvalds1da177e2005-04-16 15:20:36 -0700642 /* New-style flags. */
643 dev->flags = IFF_NOARP|IFF_POINTOPOINT|IFF_MULTICAST;
644}
645
646/******************************************
647 Routines looking at TTY side.
648 ******************************************/
649
650
Linus Torvalds1da177e2005-04-16 15:20:36 -0700651/*
652 * Handle the 'receiver data ready' interrupt.
653 * This function is called by the 'tty_io' module in the kernel when
654 * a block of SLIP data has been received, which can now be decapsulated
655 * and sent on to some IP layer for further processing. This will not
656 * be re-entered while running but other ldisc functions may be called
657 * in parallel
658 */
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400659
Linus Torvalds1da177e2005-04-16 15:20:36 -0700660static void slip_receive_buf(struct tty_struct *tty, const unsigned char *cp, char *fp, int count)
661{
662 struct slip *sl = (struct slip *) tty->disc_data;
663
664 if (!sl || sl->magic != SLIP_MAGIC ||
665 !netif_running(sl->dev))
666 return;
667
668 /* Read the characters out of the buffer */
669 while (count--) {
670 if (fp && *fp++) {
671 if (!test_and_set_bit(SLF_ERROR, &sl->flags)) {
672 sl->rx_errors++;
673 }
674 cp++;
675 continue;
676 }
677#ifdef CONFIG_SLIP_MODE_SLIP6
678 if (sl->mode & SL_MODE_SLIP6)
679 slip_unesc6(sl, *cp++);
680 else
681#endif
682 slip_unesc(sl, *cp++);
683 }
684}
685
686/************************************
687 * slip_open helper routines.
688 ************************************/
689
690/* Collect hanged up channels */
691
692static void sl_sync(void)
693{
694 int i;
695 struct net_device *dev;
696 struct slip *sl;
697
698 for (i = 0; i < slip_maxdev; i++) {
699 if ((dev = slip_devs[i]) == NULL)
700 break;
701
702 sl = netdev_priv(dev);
703 if (sl->tty || sl->leased)
704 continue;
705 if (dev->flags&IFF_UP)
706 dev_close(dev);
707 }
708}
709
710
711/* Find a free SLIP channel, and link in this `tty' line. */
712static struct slip *
713sl_alloc(dev_t line)
714{
715 int i;
716 int sel = -1;
717 int score = -1;
718 struct net_device *dev = NULL;
719 struct slip *sl;
720
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400721 if (slip_devs == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700722 return NULL; /* Master array missing ! */
723
724 for (i = 0; i < slip_maxdev; i++) {
725 dev = slip_devs[i];
726 if (dev == NULL)
727 break;
728
729 sl = netdev_priv(dev);
730 if (sl->leased) {
731 if (sl->line != line)
732 continue;
733 if (sl->tty)
734 return NULL;
735
736 /* Clear ESCAPE & ERROR flags */
737 sl->flags &= (1 << SLF_INUSE);
738 return sl;
739 }
740
741 if (sl->tty)
742 continue;
743
744 if (current->pid == sl->pid) {
745 if (sl->line == line && score < 3) {
746 sel = i;
747 score = 3;
748 continue;
749 }
750 if (score < 2) {
751 sel = i;
752 score = 2;
753 }
754 continue;
755 }
756 if (sl->line == line && score < 1) {
757 sel = i;
758 score = 1;
759 continue;
760 }
761 if (score < 0) {
762 sel = i;
763 score = 0;
764 }
765 }
766
767 if (sel >= 0) {
768 i = sel;
769 dev = slip_devs[i];
770 if (score > 1) {
771 sl = netdev_priv(dev);
772 sl->flags &= (1 << SLF_INUSE);
773 return sl;
774 }
775 }
776
777 /* Sorry, too many, all slots in use */
778 if (i >= slip_maxdev)
779 return NULL;
780
781 if (dev) {
782 sl = netdev_priv(dev);
783 if (test_bit(SLF_INUSE, &sl->flags)) {
784 unregister_netdevice(dev);
785 dev = NULL;
786 slip_devs[i] = NULL;
787 }
788 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400789
Linus Torvalds1da177e2005-04-16 15:20:36 -0700790 if (!dev) {
791 char name[IFNAMSIZ];
792 sprintf(name, "sl%d", i);
793
794 dev = alloc_netdev(sizeof(*sl), name, sl_setup);
795 if (!dev)
796 return NULL;
797 dev->base_addr = i;
798 }
799
800 sl = netdev_priv(dev);
801
802 /* Initialize channel control data */
803 sl->magic = SLIP_MAGIC;
804 sl->dev = dev;
805 spin_lock_init(&sl->lock);
806 sl->mode = SL_MODE_DEFAULT;
807#ifdef CONFIG_SLIP_SMART
808 init_timer(&sl->keepalive_timer); /* initialize timer_list struct */
809 sl->keepalive_timer.data=(unsigned long)sl;
810 sl->keepalive_timer.function=sl_keepalive;
811 init_timer(&sl->outfill_timer);
812 sl->outfill_timer.data=(unsigned long)sl;
813 sl->outfill_timer.function=sl_outfill;
814#endif
815 slip_devs[i] = dev;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400816
Linus Torvalds1da177e2005-04-16 15:20:36 -0700817 return sl;
818}
819
820/*
821 * Open the high-level part of the SLIP channel.
822 * This function is called by the TTY module when the
823 * SLIP line discipline is called for. Because we are
824 * sure the tty line exists, we only have to link it to
825 * a free SLIP channel...
826 *
827 * Called in process context serialized from other ldisc calls.
828 */
829
830static int slip_open(struct tty_struct *tty)
831{
832 struct slip *sl;
833 int err;
834
835 if(!capable(CAP_NET_ADMIN))
836 return -EPERM;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400837
Linus Torvalds1da177e2005-04-16 15:20:36 -0700838 /* RTnetlink lock is misused here to serialize concurrent
839 opens of slip channels. There are better ways, but it is
840 the simplest one.
841 */
842 rtnl_lock();
843
844 /* Collect hanged up channels. */
845 sl_sync();
846
847 sl = (struct slip *) tty->disc_data;
848
849 err = -EEXIST;
850 /* First make sure we're not already connected. */
851 if (sl && sl->magic == SLIP_MAGIC)
852 goto err_exit;
853
854 /* OK. Find a free SLIP channel to use. */
855 err = -ENFILE;
856 if ((sl = sl_alloc(tty_devnum(tty))) == NULL)
857 goto err_exit;
858
859 sl->tty = tty;
860 tty->disc_data = sl;
861 sl->line = tty_devnum(tty);
862 sl->pid = current->pid;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400863
Linus Torvalds1da177e2005-04-16 15:20:36 -0700864 if (!test_bit(SLF_INUSE, &sl->flags)) {
865 /* Perform the low-level SLIP initialization. */
866 if ((err = sl_alloc_bufs(sl, SL_MTU)) != 0)
867 goto err_free_chan;
868
869 set_bit(SLF_INUSE, &sl->flags);
870
871 if ((err = register_netdevice(sl->dev)))
872 goto err_free_bufs;
873 }
874
875#ifdef CONFIG_SLIP_SMART
876 if (sl->keepalive) {
877 sl->keepalive_timer.expires=jiffies+sl->keepalive*HZ;
878 add_timer (&sl->keepalive_timer);
879 }
880 if (sl->outfill) {
881 sl->outfill_timer.expires=jiffies+sl->outfill*HZ;
882 add_timer (&sl->outfill_timer);
883 }
884#endif
885
886 /* Done. We have linked the TTY line to a channel. */
887 rtnl_unlock();
Alan Cox33f0f882006-01-09 20:54:13 -0800888 tty->receive_room = 65536; /* We don't flow control */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700889 return sl->dev->base_addr;
890
891err_free_bufs:
892 sl_free_bufs(sl);
893
894err_free_chan:
895 sl->tty = NULL;
896 tty->disc_data = NULL;
897 clear_bit(SLF_INUSE, &sl->flags);
898
899err_exit:
900 rtnl_unlock();
901
902 /* Count references from TTY module */
903 return err;
904}
905
906/*
907
908 FIXME: 1,2 are fixed 3 was never true anyway.
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400909
Linus Torvalds1da177e2005-04-16 15:20:36 -0700910 Let me to blame a bit.
911 1. TTY module calls this funstion on soft interrupt.
912 2. TTY module calls this function WITH MASKED INTERRUPTS!
913 3. TTY module does not notify us about line discipline
914 shutdown,
915
916 Seems, now it is clean. The solution is to consider netdevice and
917 line discipline sides as two independent threads.
918
919 By-product (not desired): sl? does not feel hangups and remains open.
920 It is supposed, that user level program (dip, diald, slattach...)
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400921 will catch SIGHUP and make the rest of work.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700922
923 I see no way to make more with current tty code. --ANK
924 */
925
926/*
927 * Close down a SLIP channel.
928 * This means flushing out any pending queues, and then returning. This
929 * call is serialized against other ldisc functions.
930 */
931static void
932slip_close(struct tty_struct *tty)
933{
934 struct slip *sl = (struct slip *) tty->disc_data;
935
936 /* First make sure we're connected. */
937 if (!sl || sl->magic != SLIP_MAGIC || sl->tty != tty)
938 return;
939
940 tty->disc_data = NULL;
941 sl->tty = NULL;
942 if (!sl->leased)
943 sl->line = 0;
944
945 /* VSV = very important to remove timers */
946#ifdef CONFIG_SLIP_SMART
947 del_timer_sync(&sl->keepalive_timer);
948 del_timer_sync(&sl->outfill_timer);
949#endif
950
951 /* Count references from TTY module */
952}
953
954 /************************************************************************
955 * STANDARD SLIP ENCAPSULATION *
956 ************************************************************************/
957
Stephen Hemminger97a1ad42007-08-24 22:38:26 -0700958static int
Linus Torvalds1da177e2005-04-16 15:20:36 -0700959slip_esc(unsigned char *s, unsigned char *d, int len)
960{
961 unsigned char *ptr = d;
962 unsigned char c;
963
964 /*
965 * Send an initial END character to flush out any
966 * data that may have accumulated in the receiver
967 * due to line noise.
968 */
969
970 *ptr++ = END;
971
972 /*
973 * For each byte in the packet, send the appropriate
974 * character sequence, according to the SLIP protocol.
975 */
976
977 while (len-- > 0) {
978 switch(c = *s++) {
979 case END:
980 *ptr++ = ESC;
981 *ptr++ = ESC_END;
982 break;
983 case ESC:
984 *ptr++ = ESC;
985 *ptr++ = ESC_ESC;
986 break;
987 default:
988 *ptr++ = c;
989 break;
990 }
991 }
992 *ptr++ = END;
993 return (ptr - d);
994}
995
996static void slip_unesc(struct slip *sl, unsigned char s)
997{
998
999 switch(s) {
1000 case END:
1001#ifdef CONFIG_SLIP_SMART
1002 /* drop keeptest bit = VSV */
1003 if (test_bit(SLF_KEEPTEST, &sl->flags))
1004 clear_bit(SLF_KEEPTEST, &sl->flags);
1005#endif
1006
1007 if (!test_and_clear_bit(SLF_ERROR, &sl->flags) && (sl->rcount > 2)) {
1008 sl_bump(sl);
1009 }
1010 clear_bit(SLF_ESCAPE, &sl->flags);
1011 sl->rcount = 0;
1012 return;
1013
1014 case ESC:
1015 set_bit(SLF_ESCAPE, &sl->flags);
1016 return;
1017 case ESC_ESC:
1018 if (test_and_clear_bit(SLF_ESCAPE, &sl->flags)) {
1019 s = ESC;
1020 }
1021 break;
1022 case ESC_END:
1023 if (test_and_clear_bit(SLF_ESCAPE, &sl->flags)) {
1024 s = END;
1025 }
1026 break;
1027 }
1028 if (!test_bit(SLF_ERROR, &sl->flags)) {
1029 if (sl->rcount < sl->buffsize) {
1030 sl->rbuff[sl->rcount++] = s;
1031 return;
1032 }
1033 sl->rx_over_errors++;
1034 set_bit(SLF_ERROR, &sl->flags);
1035 }
1036}
1037
1038
1039#ifdef CONFIG_SLIP_MODE_SLIP6
1040/************************************************************************
1041 * 6 BIT SLIP ENCAPSULATION *
1042 ************************************************************************/
1043
1044int
1045slip_esc6(unsigned char *s, unsigned char *d, int len)
1046{
1047 unsigned char *ptr = d;
1048 unsigned char c;
1049 int i;
1050 unsigned short v = 0;
1051 short bits = 0;
1052
1053 /*
1054 * Send an initial END character to flush out any
1055 * data that may have accumulated in the receiver
1056 * due to line noise.
1057 */
1058
1059 *ptr++ = 0x70;
1060
1061 /*
1062 * Encode the packet into printable ascii characters
1063 */
1064
1065 for (i = 0; i < len; ++i) {
1066 v = (v << 8) | s[i];
1067 bits += 8;
1068 while (bits >= 6) {
1069 bits -= 6;
1070 c = 0x30 + ((v >> bits) & 0x3F);
1071 *ptr++ = c;
1072 }
1073 }
1074 if (bits) {
1075 c = 0x30 + ((v << (6 - bits)) & 0x3F);
1076 *ptr++ = c;
1077 }
1078 *ptr++ = 0x70;
1079 return ptr - d;
1080}
1081
1082void
1083slip_unesc6(struct slip *sl, unsigned char s)
1084{
1085 unsigned char c;
1086
1087 if (s == 0x70) {
1088#ifdef CONFIG_SLIP_SMART
1089 /* drop keeptest bit = VSV */
1090 if (test_bit(SLF_KEEPTEST, &sl->flags))
1091 clear_bit(SLF_KEEPTEST, &sl->flags);
1092#endif
1093
1094 if (!test_and_clear_bit(SLF_ERROR, &sl->flags) && (sl->rcount > 2)) {
1095 sl_bump(sl);
1096 }
1097 sl->rcount = 0;
1098 sl->xbits = 0;
1099 sl->xdata = 0;
1100 } else if (s >= 0x30 && s < 0x70) {
1101 sl->xdata = (sl->xdata << 6) | ((s - 0x30) & 0x3F);
1102 sl->xbits += 6;
1103 if (sl->xbits >= 8) {
1104 sl->xbits -= 8;
1105 c = (unsigned char)(sl->xdata >> sl->xbits);
1106 if (!test_bit(SLF_ERROR, &sl->flags)) {
1107 if (sl->rcount < sl->buffsize) {
1108 sl->rbuff[sl->rcount++] = c;
1109 return;
1110 }
1111 sl->rx_over_errors++;
1112 set_bit(SLF_ERROR, &sl->flags);
1113 }
1114 }
1115 }
1116}
1117#endif /* CONFIG_SLIP_MODE_SLIP6 */
1118
1119/* Perform I/O control on an active SLIP channel. */
1120static int slip_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg)
1121{
1122 struct slip *sl = (struct slip *) tty->disc_data;
1123 unsigned int tmp;
1124 int __user *p = (int __user *)arg;
1125
1126 /* First make sure we're connected. */
1127 if (!sl || sl->magic != SLIP_MAGIC) {
1128 return -EINVAL;
1129 }
1130
1131 switch(cmd) {
1132 case SIOCGIFNAME:
1133 tmp = strlen(sl->dev->name) + 1;
1134 if (copy_to_user((void __user *)arg, sl->dev->name, tmp))
1135 return -EFAULT;
1136 return 0;
1137
1138 case SIOCGIFENCAP:
1139 if (put_user(sl->mode, p))
1140 return -EFAULT;
1141 return 0;
1142
1143 case SIOCSIFENCAP:
1144 if (get_user(tmp, p))
1145 return -EFAULT;
1146#ifndef SL_INCLUDE_CSLIP
1147 if (tmp & (SL_MODE_CSLIP|SL_MODE_ADAPTIVE)) {
1148 return -EINVAL;
1149 }
1150#else
1151 if ((tmp & (SL_MODE_ADAPTIVE | SL_MODE_CSLIP)) ==
1152 (SL_MODE_ADAPTIVE | SL_MODE_CSLIP)) {
1153 /* return -EINVAL; */
1154 tmp &= ~SL_MODE_ADAPTIVE;
1155 }
1156#endif
1157#ifndef CONFIG_SLIP_MODE_SLIP6
1158 if (tmp & SL_MODE_SLIP6) {
1159 return -EINVAL;
1160 }
1161#endif
1162 sl->mode = tmp;
1163 sl->dev->type = ARPHRD_SLIP+sl->mode;
1164 return 0;
1165
1166 case SIOCSIFHWADDR:
1167 return -EINVAL;
1168
1169#ifdef CONFIG_SLIP_SMART
1170 /* VSV changes start here */
1171 case SIOCSKEEPALIVE:
1172 if (get_user(tmp, p))
1173 return -EFAULT;
1174 if (tmp > 255) /* max for unchar */
1175 return -EINVAL;
1176
1177 spin_lock_bh(&sl->lock);
1178 if (!sl->tty) {
1179 spin_unlock_bh(&sl->lock);
1180 return -ENODEV;
1181 }
1182 if ((sl->keepalive = (unchar) tmp) != 0) {
1183 mod_timer(&sl->keepalive_timer, jiffies+sl->keepalive*HZ);
1184 set_bit(SLF_KEEPTEST, &sl->flags);
1185 } else {
1186 del_timer (&sl->keepalive_timer);
1187 }
1188 spin_unlock_bh(&sl->lock);
1189 return 0;
1190
1191 case SIOCGKEEPALIVE:
1192 if (put_user(sl->keepalive, p))
1193 return -EFAULT;
1194 return 0;
1195
1196 case SIOCSOUTFILL:
1197 if (get_user(tmp, p))
1198 return -EFAULT;
1199 if (tmp > 255) /* max for unchar */
1200 return -EINVAL;
1201 spin_lock_bh(&sl->lock);
1202 if (!sl->tty) {
1203 spin_unlock_bh(&sl->lock);
1204 return -ENODEV;
1205 }
1206 if ((sl->outfill = (unchar) tmp) != 0){
1207 mod_timer(&sl->outfill_timer, jiffies+sl->outfill*HZ);
1208 set_bit(SLF_OUTWAIT, &sl->flags);
1209 } else {
1210 del_timer (&sl->outfill_timer);
1211 }
1212 spin_unlock_bh(&sl->lock);
1213 return 0;
1214
1215 case SIOCGOUTFILL:
1216 if (put_user(sl->outfill, p))
1217 return -EFAULT;
1218 return 0;
1219 /* VSV changes end */
1220#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07001221 default:
Alan Coxd0127532007-11-07 01:27:34 -08001222 return tty_mode_ioctl(tty, file, cmd, arg);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001223 }
1224}
1225
1226/* VSV changes start here */
1227#ifdef CONFIG_SLIP_SMART
1228/* function do_ioctl called from net/core/dev.c
1229 to allow get/set outfill/keepalive parameter
1230 by ifconfig */
1231
1232static int sl_ioctl(struct net_device *dev,struct ifreq *rq,int cmd)
1233{
1234 struct slip *sl = netdev_priv(dev);
1235 unsigned long *p = (unsigned long *)&rq->ifr_ifru;
1236
1237 if (sl == NULL) /* Allocation failed ?? */
1238 return -ENODEV;
1239
1240 spin_lock_bh(&sl->lock);
1241
1242 if (!sl->tty) {
1243 spin_unlock_bh(&sl->lock);
1244 return -ENODEV;
1245 }
1246
1247 switch(cmd){
1248 case SIOCSKEEPALIVE:
1249 /* max for unchar */
1250 if ((unsigned)*p > 255) {
1251 spin_unlock_bh(&sl->lock);
1252 return -EINVAL;
1253 }
1254 sl->keepalive = (unchar) *p;
1255 if (sl->keepalive != 0) {
1256 sl->keepalive_timer.expires=jiffies+sl->keepalive*HZ;
1257 mod_timer(&sl->keepalive_timer, jiffies+sl->keepalive*HZ);
1258 set_bit(SLF_KEEPTEST, &sl->flags);
1259 } else {
1260 del_timer(&sl->keepalive_timer);
1261 }
1262 break;
1263
1264 case SIOCGKEEPALIVE:
1265 *p = sl->keepalive;
1266 break;
1267
1268 case SIOCSOUTFILL:
1269 if ((unsigned)*p > 255) { /* max for unchar */
1270 spin_unlock_bh(&sl->lock);
1271 return -EINVAL;
1272 }
1273 if ((sl->outfill = (unchar)*p) != 0){
1274 mod_timer(&sl->outfill_timer, jiffies+sl->outfill*HZ);
1275 set_bit(SLF_OUTWAIT, &sl->flags);
1276 } else {
1277 del_timer (&sl->outfill_timer);
1278 }
1279 break;
1280
1281 case SIOCGOUTFILL:
1282 *p = sl->outfill;
1283 break;
1284
1285 case SIOCSLEASE:
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001286 /* Resolve race condition, when ioctl'ing hanged up
Linus Torvalds1da177e2005-04-16 15:20:36 -07001287 and opened by another process device.
1288 */
1289 if (sl->tty != current->signal->tty && sl->pid != current->pid) {
1290 spin_unlock_bh(&sl->lock);
1291 return -EPERM;
1292 }
1293 sl->leased = 0;
1294 if (*p)
1295 sl->leased = 1;
1296 break;
1297
1298 case SIOCGLEASE:
1299 *p = sl->leased;
1300 };
1301 spin_unlock_bh(&sl->lock);
1302 return 0;
1303}
1304#endif
1305/* VSV changes end */
1306
1307static struct tty_ldisc sl_ldisc = {
1308 .owner = THIS_MODULE,
1309 .magic = TTY_LDISC_MAGIC,
1310 .name = "slip",
1311 .open = slip_open,
1312 .close = slip_close,
1313 .ioctl = slip_ioctl,
1314 .receive_buf = slip_receive_buf,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001315 .write_wakeup = slip_write_wakeup,
1316};
1317
1318static int __init slip_init(void)
1319{
1320 int status;
1321
1322 if (slip_maxdev < 4)
1323 slip_maxdev = 4; /* Sanity */
1324
1325 printk(KERN_INFO "SLIP: version %s (dynamic channels, max=%d)"
1326#ifdef CONFIG_SLIP_MODE_SLIP6
1327 " (6 bit encapsulation enabled)"
1328#endif
1329 ".\n",
1330 SLIP_VERSION, slip_maxdev );
1331#if defined(SL_INCLUDE_CSLIP)
1332 printk(KERN_INFO "CSLIP: code copyright 1989 Regents of the University of California.\n");
1333#endif
1334#ifdef CONFIG_SLIP_SMART
1335 printk(KERN_INFO "SLIP linefill/keepalive option.\n");
1336#endif
1337
Joe Jin919afbd2007-02-05 18:08:47 -08001338 slip_devs = kzalloc(sizeof(struct net_device *)*slip_maxdev, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001339 if (!slip_devs) {
1340 printk(KERN_ERR "SLIP: Can't allocate slip devices array! Uaargh! (-> No SLIP available)\n");
1341 return -ENOMEM;
1342 }
1343
Linus Torvalds1da177e2005-04-16 15:20:36 -07001344 /* Fill in our line protocol discipline, and register it */
1345 if ((status = tty_register_ldisc(N_SLIP, &sl_ldisc)) != 0) {
1346 printk(KERN_ERR "SLIP: can't register line discipline (err = %d)\n", status);
1347 kfree(slip_devs);
1348 }
1349 return status;
1350}
1351
1352static void __exit slip_exit(void)
1353{
1354 int i;
1355 struct net_device *dev;
1356 struct slip *sl;
1357 unsigned long timeout = jiffies + HZ;
1358 int busy = 0;
1359
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001360 if (slip_devs == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001361 return;
1362
1363 /* First of all: check for active disciplines and hangup them.
1364 */
1365 do {
Nishanth Aravamudana9fc2512005-05-01 23:34:57 -07001366 if (busy)
1367 msleep_interruptible(100);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001368
1369 busy = 0;
1370 for (i = 0; i < slip_maxdev; i++) {
1371 dev = slip_devs[i];
1372 if (!dev)
1373 continue;
1374 sl = netdev_priv(dev);
1375 spin_lock_bh(&sl->lock);
1376 if (sl->tty) {
1377 busy++;
1378 tty_hangup(sl->tty);
1379 }
1380 spin_unlock_bh(&sl->lock);
1381 }
1382 } while (busy && time_before(jiffies, timeout));
1383
1384
1385 for (i = 0; i < slip_maxdev; i++) {
1386 dev = slip_devs[i];
1387 if (!dev)
1388 continue;
1389 slip_devs[i] = NULL;
1390
1391 sl = netdev_priv(dev);
1392 if (sl->tty) {
1393 printk(KERN_ERR "%s: tty discipline still running\n",
1394 dev->name);
1395 /* Intentionally leak the control block. */
1396 dev->destructor = NULL;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001397 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001398
1399 unregister_netdev(dev);
1400 }
1401
1402 kfree(slip_devs);
1403 slip_devs = NULL;
1404
Alexey Dobriyan64ccd712005-06-23 00:10:33 -07001405 if ((i = tty_unregister_ldisc(N_SLIP)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001406 {
1407 printk(KERN_ERR "SLIP: can't unregister line discipline (err = %d)\n", i);
1408 }
1409}
1410
1411module_init(slip_init);
1412module_exit(slip_exit);
1413
1414#ifdef CONFIG_SLIP_SMART
1415/*
1416 * This is start of the code for multislip style line checking
1417 * added by Stanislav Voronyi. All changes before marked VSV
1418 */
1419
1420static void sl_outfill(unsigned long sls)
1421{
1422 struct slip *sl=(struct slip *)sls;
1423
1424 spin_lock(&sl->lock);
1425
1426 if (sl->tty == NULL)
1427 goto out;
1428
1429 if(sl->outfill)
1430 {
1431 if( test_bit(SLF_OUTWAIT, &sl->flags) )
1432 {
1433 /* no packets were transmitted, do outfill */
1434#ifdef CONFIG_SLIP_MODE_SLIP6
1435 unsigned char s = (sl->mode & SL_MODE_SLIP6)?0x70:END;
1436#else
1437 unsigned char s = END;
1438#endif
1439 /* put END into tty queue. Is it right ??? */
1440 if (!netif_queue_stopped(sl->dev))
1441 {
1442 /* if device busy no outfill */
1443 sl->tty->driver->write(sl->tty, &s, 1);
1444 }
1445 }
1446 else
1447 set_bit(SLF_OUTWAIT, &sl->flags);
1448
1449 mod_timer(&sl->outfill_timer, jiffies+sl->outfill*HZ);
1450 }
1451out:
1452 spin_unlock(&sl->lock);
1453}
1454
1455static void sl_keepalive(unsigned long sls)
1456{
1457 struct slip *sl=(struct slip *)sls;
1458
1459 spin_lock(&sl->lock);
1460
1461 if (sl->tty == NULL)
1462 goto out;
1463
1464 if( sl->keepalive)
1465 {
1466 if(test_bit(SLF_KEEPTEST, &sl->flags))
1467 {
1468 /* keepalive still high :(, we must hangup */
1469 if( sl->outfill ) /* outfill timer must be deleted too */
1470 (void)del_timer(&sl->outfill_timer);
1471 printk(KERN_DEBUG "%s: no packets received during keepalive timeout, hangup.\n", sl->dev->name);
1472 tty_hangup(sl->tty); /* this must hangup tty & close slip */
1473 /* I think we need not something else */
1474 goto out;
1475 }
1476 else
1477 set_bit(SLF_KEEPTEST, &sl->flags);
1478
1479 mod_timer(&sl->keepalive_timer, jiffies+sl->keepalive*HZ);
1480 }
1481
1482out:
1483 spin_unlock(&sl->lock);
1484}
1485
1486#endif
1487MODULE_LICENSE("GPL");
1488MODULE_ALIAS_LDISC(N_SLIP);