aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/slip
diff options
context:
space:
mode:
authorJeff Kirsher <jeffrey.t.kirsher@intel.com>2011-08-03 06:17:13 -0400
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2011-08-27 03:58:36 -0400
commitb5451d783ade99308dfccdf5ca284ed07affa4ff (patch)
tree98830cee17e38f3351bb3f1cc839ee3c29ec68a3 /drivers/net/slip
parent18e635f4b3e1e1b43cb239321f6120918ba38d46 (diff)
slip: Move the SLIP drivers
Move the Serial Line Internet Protocol (SLIP) drivers into drivers/net/slip/ and make the necessary Kconfig and Makefile changes. Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com> Acked-by: Alan Cox <alan@linux.intel.com>
Diffstat (limited to 'drivers/net/slip')
-rw-r--r--drivers/net/slip/Kconfig79
-rw-r--r--drivers/net/slip/Makefile6
-rw-r--r--drivers/net/slip/slhc.c742
-rw-r--r--drivers/net/slip/slip.c1444
-rw-r--r--drivers/net/slip/slip.h101
5 files changed, 2372 insertions, 0 deletions
diff --git a/drivers/net/slip/Kconfig b/drivers/net/slip/Kconfig
new file mode 100644
index 00000000000..211b160e4e9
--- /dev/null
+++ b/drivers/net/slip/Kconfig
@@ -0,0 +1,79 @@
1#
2# SLIP network device configuration
3#
4
5config SLIP
6 tristate "SLIP (serial line) support"
7 ---help---
8 Say Y if you intend to use SLIP or CSLIP (compressed SLIP) to
9 connect to your Internet service provider or to connect to some
10 other local Unix box or if you want to configure your Linux box as a
11 Slip/CSlip server for other people to dial in. SLIP (Serial Line
12 Internet Protocol) is a protocol used to send Internet traffic over
13 serial connections such as telephone lines or null modem cables;
14 nowadays, the protocol PPP is more commonly used for this same
15 purpose.
16
17 Normally, your access provider has to support SLIP in order for you
18 to be able to use it, but there is now a SLIP emulator called SLiRP
19 around (available from
20 <ftp://ibiblio.org/pub/Linux/system/network/serial/>) which
21 allows you to use SLIP over a regular dial up shell connection. If
22 you plan to use SLiRP, make sure to say Y to CSLIP, below. The
23 NET-3-HOWTO, available from
24 <http://www.tldp.org/docs.html#howto>, explains how to
25 configure SLIP. Note that you don't need this option if you just
26 want to run term (term is a program which gives you almost full
27 Internet connectivity if you have a regular dial up shell account on
28 some Internet connected Unix computer. Read
29 <http://www.bart.nl/~patrickr/term-howto/Term-HOWTO.html>). SLIP
30 support will enlarge your kernel by about 4 KB. If unsure, say N.
31
32 To compile this driver as a module, choose M here. The module
33 will be called slip.
34
35config SLHC
36 tristate
37 ---help---
38 This option enables Van Jacobsen serial line header compression
39 routines.
40
41if SLIP
42
43config SLIP_COMPRESSED
44 bool "CSLIP compressed headers"
45 depends on SLIP
46 select SLHC
47 ---help---
48 This protocol is faster than SLIP because it uses compression on the
49 TCP/IP headers (not on the data itself), but it has to be supported
50 on both ends. Ask your access provider if you are not sure and
51 answer Y, just in case. You will still be able to use plain SLIP. If
52 you plan to use SLiRP, the SLIP emulator (available from
53 <ftp://ibiblio.org/pub/Linux/system/network/serial/>) which
54 allows you to use SLIP over a regular dial up shell connection, you
55 definitely want to say Y here. The NET-3-HOWTO, available from
56 <http://www.tldp.org/docs.html#howto>, explains how to configure
57 CSLIP. This won't enlarge your kernel.
58
59config SLIP_SMART
60 bool "Keepalive and linefill"
61 depends on SLIP
62 ---help---
63 Adds additional capabilities to the SLIP driver to support the
64 RELCOM line fill and keepalive monitoring. Ideal on poor quality
65 analogue lines.
66
67config SLIP_MODE_SLIP6
68 bool "Six bit SLIP encapsulation"
69 depends on SLIP
70 ---help---
71 Just occasionally you may need to run IP over hostile serial
72 networks that don't pass all control characters or are only seven
73 bit. Saying Y here adds an extra mode you can use with SLIP:
74 "slip6". In this mode, SLIP will only send normal ASCII symbols over
75 the serial device. Naturally, this has to be supported at the other
76 end of the link as well. It's good enough, for example, to run IP
77 over the async ports of a Camtec JNT Pad. If unsure, say N.
78
79endif # SLIP
diff --git a/drivers/net/slip/Makefile b/drivers/net/slip/Makefile
new file mode 100644
index 00000000000..e3ebc59e6fb
--- /dev/null
+++ b/drivers/net/slip/Makefile
@@ -0,0 +1,6 @@
1#
2# Makefile for the SLIP network device drivers.
3#
4
5obj-$(CONFIG_SLIP) += slip.o
6obj-$(CONFIG_SLHC) += slhc.o
diff --git a/drivers/net/slip/slhc.c b/drivers/net/slip/slhc.c
new file mode 100644
index 00000000000..0a0a6643cf3
--- /dev/null
+++ b/drivers/net/slip/slhc.c
@@ -0,0 +1,742 @@
1/*
2 * Routines to compress and uncompress tcp packets (for transmission
3 * over low speed serial lines).
4 *
5 * Copyright (c) 1989 Regents of the University of California.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms are permitted
9 * provided that the above copyright notice and this paragraph are
10 * duplicated in all such forms and that any documentation,
11 * advertising materials, and other materials related to such
12 * distribution and use acknowledge that the software was developed
13 * by the University of California, Berkeley. The name of the
14 * University may not be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
19 *
20 * Van Jacobson (van@helios.ee.lbl.gov), Dec 31, 1989:
21 * - Initial distribution.
22 *
23 *
24 * modified for KA9Q Internet Software Package by
25 * Katie Stevens (dkstevens@ucdavis.edu)
26 * University of California, Davis
27 * Computing Services
28 * - 01-31-90 initial adaptation (from 1.19)
29 * PPP.05 02-15-90 [ks]
30 * PPP.08 05-02-90 [ks] use PPP protocol field to signal compression
31 * PPP.15 09-90 [ks] improve mbuf handling
32 * PPP.16 11-02 [karn] substantially rewritten to use NOS facilities
33 *
34 * - Feb 1991 Bill_Simpson@um.cc.umich.edu
35 * variable number of conversation slots
36 * allow zero or one slots
37 * separate routines
38 * status display
39 * - Jul 1994 Dmitry Gorodchanin
40 * Fixes for memory leaks.
41 * - Oct 1994 Dmitry Gorodchanin
42 * Modularization.
43 * - Jan 1995 Bjorn Ekwall
44 * Use ip_fast_csum from ip.h
45 * - July 1995 Christos A. Polyzols
46 * Spotted bug in tcp option checking
47 *
48 *
49 * This module is a difficult issue. It's clearly inet code but it's also clearly
50 * driver code belonging close to PPP and SLIP
51 */
52
53#include <linux/module.h>
54#include <linux/slab.h>
55#include <linux/types.h>
56#include <linux/string.h>
57#include <linux/errno.h>
58#include <linux/kernel.h>
59#include <net/slhc_vj.h>
60
61#ifdef CONFIG_INET
62/* Entire module is for IP only */
63#include <linux/mm.h>
64#include <linux/socket.h>
65#include <linux/sockios.h>
66#include <linux/termios.h>
67#include <linux/in.h>
68#include <linux/fcntl.h>
69#include <linux/inet.h>
70#include <linux/netdevice.h>
71#include <net/ip.h>
72#include <net/protocol.h>
73#include <net/icmp.h>
74#include <net/tcp.h>
75#include <linux/skbuff.h>
76#include <net/sock.h>
77#include <linux/timer.h>
78#include <asm/system.h>
79#include <asm/uaccess.h>
80#include <net/checksum.h>
81#include <asm/unaligned.h>
82
83static unsigned char *encode(unsigned char *cp, unsigned short n);
84static long decode(unsigned char **cpp);
85static unsigned char * put16(unsigned char *cp, unsigned short x);
86static unsigned short pull16(unsigned char **cpp);
87
88/* Initialize compression data structure
89 * slots must be in range 0 to 255 (zero meaning no compression)
90 */
91struct slcompress *
92slhc_init(int rslots, int tslots)
93{
94 register short i;
95 register struct cstate *ts;
96 struct slcompress *comp;
97
98 comp = kzalloc(sizeof(struct slcompress), GFP_KERNEL);
99 if (! comp)
100 goto out_fail;
101
102 if ( rslots > 0 && rslots < 256 ) {
103 size_t rsize = rslots * sizeof(struct cstate);
104 comp->rstate = kzalloc(rsize, GFP_KERNEL);
105 if (! comp->rstate)
106 goto out_free;
107 comp->rslot_limit = rslots - 1;
108 }
109
110 if ( tslots > 0 && tslots < 256 ) {
111 size_t tsize = tslots * sizeof(struct cstate);
112 comp->tstate = kzalloc(tsize, GFP_KERNEL);
113 if (! comp->tstate)
114 goto out_free2;
115 comp->tslot_limit = tslots - 1;
116 }
117
118 comp->xmit_oldest = 0;
119 comp->xmit_current = 255;
120 comp->recv_current = 255;
121 /*
122 * don't accept any packets with implicit index until we get
123 * one with an explicit index. Otherwise the uncompress code
124 * will try to use connection 255, which is almost certainly
125 * out of range
126 */
127 comp->flags |= SLF_TOSS;
128
129 if ( tslots > 0 ) {
130 ts = comp->tstate;
131 for(i = comp->tslot_limit; i > 0; --i){
132 ts[i].cs_this = i;
133 ts[i].next = &(ts[i - 1]);
134 }
135 ts[0].next = &(ts[comp->tslot_limit]);
136 ts[0].cs_this = 0;
137 }
138 return comp;
139
140out_free2:
141 kfree(comp->rstate);
142out_free:
143 kfree(comp);
144out_fail:
145 return NULL;
146}
147
148
149/* Free a compression data structure */
150void
151slhc_free(struct slcompress *comp)
152{
153 if ( comp == NULLSLCOMPR )
154 return;
155
156 if ( comp->tstate != NULLSLSTATE )
157 kfree( comp->tstate );
158
159 if ( comp->rstate != NULLSLSTATE )
160 kfree( comp->rstate );
161
162 kfree( comp );
163}
164
165
166/* Put a short in host order into a char array in network order */
167static inline unsigned char *
168put16(unsigned char *cp, unsigned short x)
169{
170 *cp++ = x >> 8;
171 *cp++ = x;
172
173 return cp;
174}
175
176
177/* Encode a number */
178static unsigned char *
179encode(unsigned char *cp, unsigned short n)
180{
181 if(n >= 256 || n == 0){
182 *cp++ = 0;
183 cp = put16(cp,n);
184 } else {
185 *cp++ = n;
186 }
187 return cp;
188}
189
190/* Pull a 16-bit integer in host order from buffer in network byte order */
191static unsigned short
192pull16(unsigned char **cpp)
193{
194 short rval;
195
196 rval = *(*cpp)++;
197 rval <<= 8;
198 rval |= *(*cpp)++;
199 return rval;
200}
201
202/* Decode a number */
203static long
204decode(unsigned char **cpp)
205{
206 register int x;
207
208 x = *(*cpp)++;
209 if(x == 0){
210 return pull16(cpp) & 0xffff; /* pull16 returns -1 on error */
211 } else {
212 return x & 0xff; /* -1 if PULLCHAR returned error */
213 }
214}
215
216/*
217 * icp and isize are the original packet.
218 * ocp is a place to put a copy if necessary.
219 * cpp is initially a pointer to icp. If the copy is used,
220 * change it to ocp.
221 */
222
223int
224slhc_compress(struct slcompress *comp, unsigned char *icp, int isize,
225 unsigned char *ocp, unsigned char **cpp, int compress_cid)
226{
227 register struct cstate *ocs = &(comp->tstate[comp->xmit_oldest]);
228 register struct cstate *lcs = ocs;
229 register struct cstate *cs = lcs->next;
230 register unsigned long deltaS, deltaA;
231 register short changes = 0;
232 int hlen;
233 unsigned char new_seq[16];
234 register unsigned char *cp = new_seq;
235 struct iphdr *ip;
236 struct tcphdr *th, *oth;
237 __sum16 csum;
238
239
240 /*
241 * Don't play with runt packets.
242 */
243
244 if(isize<sizeof(struct iphdr))
245 return isize;
246
247 ip = (struct iphdr *) icp;
248
249 /* Bail if this packet isn't TCP, or is an IP fragment */
250 if (ip->protocol != IPPROTO_TCP || (ntohs(ip->frag_off) & 0x3fff)) {
251 /* Send as regular IP */
252 if(ip->protocol != IPPROTO_TCP)
253 comp->sls_o_nontcp++;
254 else
255 comp->sls_o_tcp++;
256 return isize;
257 }
258 /* Extract TCP header */
259
260 th = (struct tcphdr *)(((unsigned char *)ip) + ip->ihl*4);
261 hlen = ip->ihl*4 + th->doff*4;
262
263 /* Bail if the TCP packet isn't `compressible' (i.e., ACK isn't set or
264 * some other control bit is set). Also uncompressible if
265 * it's a runt.
266 */
267 if(hlen > isize || th->syn || th->fin || th->rst ||
268 ! (th->ack)){
269 /* TCP connection stuff; send as regular IP */
270 comp->sls_o_tcp++;
271 return isize;
272 }
273 /*
274 * Packet is compressible -- we're going to send either a
275 * COMPRESSED_TCP or UNCOMPRESSED_TCP packet. Either way,
276 * we need to locate (or create) the connection state.
277 *
278 * States are kept in a circularly linked list with
279 * xmit_oldest pointing to the end of the list. The
280 * list is kept in lru order by moving a state to the
281 * head of the list whenever it is referenced. Since
282 * the list is short and, empirically, the connection
283 * we want is almost always near the front, we locate
284 * states via linear search. If we don't find a state
285 * for the datagram, the oldest state is (re-)used.
286 */
287 for ( ; ; ) {
288 if( ip->saddr == cs->cs_ip.saddr
289 && ip->daddr == cs->cs_ip.daddr
290 && th->source == cs->cs_tcp.source
291 && th->dest == cs->cs_tcp.dest)
292 goto found;
293
294 /* if current equal oldest, at end of list */
295 if ( cs == ocs )
296 break;
297 lcs = cs;
298 cs = cs->next;
299 comp->sls_o_searches++;
300 }
301 /*
302 * Didn't find it -- re-use oldest cstate. Send an
303 * uncompressed packet that tells the other side what
304 * connection number we're using for this conversation.
305 *
306 * Note that since the state list is circular, the oldest
307 * state points to the newest and we only need to set
308 * xmit_oldest to update the lru linkage.
309 */
310 comp->sls_o_misses++;
311 comp->xmit_oldest = lcs->cs_this;
312 goto uncompressed;
313
314found:
315 /*
316 * Found it -- move to the front on the connection list.
317 */
318 if(lcs == ocs) {
319 /* found at most recently used */
320 } else if (cs == ocs) {
321 /* found at least recently used */
322 comp->xmit_oldest = lcs->cs_this;
323 } else {
324 /* more than 2 elements */
325 lcs->next = cs->next;
326 cs->next = ocs->next;
327 ocs->next = cs;
328 }
329
330 /*
331 * Make sure that only what we expect to change changed.
332 * Check the following:
333 * IP protocol version, header length & type of service.
334 * The "Don't fragment" bit.
335 * The time-to-live field.
336 * The TCP header length.
337 * IP options, if any.
338 * TCP options, if any.
339 * If any of these things are different between the previous &
340 * current datagram, we send the current datagram `uncompressed'.
341 */
342 oth = &cs->cs_tcp;
343
344 if(ip->version != cs->cs_ip.version || ip->ihl != cs->cs_ip.ihl
345 || ip->tos != cs->cs_ip.tos
346 || (ip->frag_off & htons(0x4000)) != (cs->cs_ip.frag_off & htons(0x4000))
347 || ip->ttl != cs->cs_ip.ttl
348 || th->doff != cs->cs_tcp.doff
349 || (ip->ihl > 5 && memcmp(ip+1,cs->cs_ipopt,((ip->ihl)-5)*4) != 0)
350 || (th->doff > 5 && memcmp(th+1,cs->cs_tcpopt,((th->doff)-5)*4) != 0)){
351 goto uncompressed;
352 }
353
354 /*
355 * Figure out which of the changing fields changed. The
356 * receiver expects changes in the order: urgent, window,
357 * ack, seq (the order minimizes the number of temporaries
358 * needed in this section of code).
359 */
360 if(th->urg){
361 deltaS = ntohs(th->urg_ptr);
362 cp = encode(cp,deltaS);
363 changes |= NEW_U;
364 } else if(th->urg_ptr != oth->urg_ptr){
365 /* argh! URG not set but urp changed -- a sensible
366 * implementation should never do this but RFC793
367 * doesn't prohibit the change so we have to deal
368 * with it. */
369 goto uncompressed;
370 }
371 if((deltaS = ntohs(th->window) - ntohs(oth->window)) != 0){
372 cp = encode(cp,deltaS);
373 changes |= NEW_W;
374 }
375 if((deltaA = ntohl(th->ack_seq) - ntohl(oth->ack_seq)) != 0L){
376 if(deltaA > 0x0000ffff)
377 goto uncompressed;
378 cp = encode(cp,deltaA);
379 changes |= NEW_A;
380 }
381 if((deltaS = ntohl(th->seq) - ntohl(oth->seq)) != 0L){
382 if(deltaS > 0x0000ffff)
383 goto uncompressed;
384 cp = encode(cp,deltaS);
385 changes |= NEW_S;
386 }
387
388 switch(changes){
389 case 0: /* Nothing changed. If this packet contains data and the
390 * last one didn't, this is probably a data packet following
391 * an ack (normal on an interactive connection) and we send
392 * it compressed. Otherwise it's probably a retransmit,
393 * retransmitted ack or window probe. Send it uncompressed
394 * in case the other side missed the compressed version.
395 */
396 if(ip->tot_len != cs->cs_ip.tot_len &&
397 ntohs(cs->cs_ip.tot_len) == hlen)
398 break;
399 goto uncompressed;
400 break;
401 case SPECIAL_I:
402 case SPECIAL_D:
403 /* actual changes match one of our special case encodings --
404 * send packet uncompressed.
405 */
406 goto uncompressed;
407 case NEW_S|NEW_A:
408 if(deltaS == deltaA &&
409 deltaS == ntohs(cs->cs_ip.tot_len) - hlen){
410 /* special case for echoed terminal traffic */
411 changes = SPECIAL_I;
412 cp = new_seq;
413 }
414 break;
415 case NEW_S:
416 if(deltaS == ntohs(cs->cs_ip.tot_len) - hlen){
417 /* special case for data xfer */
418 changes = SPECIAL_D;
419 cp = new_seq;
420 }
421 break;
422 }
423 deltaS = ntohs(ip->id) - ntohs(cs->cs_ip.id);
424 if(deltaS != 1){
425 cp = encode(cp,deltaS);
426 changes |= NEW_I;
427 }
428 if(th->psh)
429 changes |= TCP_PUSH_BIT;
430 /* Grab the cksum before we overwrite it below. Then update our
431 * state with this packet's header.
432 */
433 csum = th->check;
434 memcpy(&cs->cs_ip,ip,20);
435 memcpy(&cs->cs_tcp,th,20);
436 /* We want to use the original packet as our compressed packet.
437 * (cp - new_seq) is the number of bytes we need for compressed
438 * sequence numbers. In addition we need one byte for the change
439 * mask, one for the connection id and two for the tcp checksum.
440 * So, (cp - new_seq) + 4 bytes of header are needed.
441 */
442 deltaS = cp - new_seq;
443 if(compress_cid == 0 || comp->xmit_current != cs->cs_this){
444 cp = ocp;
445 *cpp = ocp;
446 *cp++ = changes | NEW_C;
447 *cp++ = cs->cs_this;
448 comp->xmit_current = cs->cs_this;
449 } else {
450 cp = ocp;
451 *cpp = ocp;
452 *cp++ = changes;
453 }
454 *(__sum16 *)cp = csum;
455 cp += 2;
456/* deltaS is now the size of the change section of the compressed header */
457 memcpy(cp,new_seq,deltaS); /* Write list of deltas */
458 memcpy(cp+deltaS,icp+hlen,isize-hlen);
459 comp->sls_o_compressed++;
460 ocp[0] |= SL_TYPE_COMPRESSED_TCP;
461 return isize - hlen + deltaS + (cp - ocp);
462
463 /* Update connection state cs & send uncompressed packet (i.e.,
464 * a regular ip/tcp packet but with the 'conversation id' we hope
465 * to use on future compressed packets in the protocol field).
466 */
467uncompressed:
468 memcpy(&cs->cs_ip,ip,20);
469 memcpy(&cs->cs_tcp,th,20);
470 if (ip->ihl > 5)
471 memcpy(cs->cs_ipopt, ip+1, ((ip->ihl) - 5) * 4);
472 if (th->doff > 5)
473 memcpy(cs->cs_tcpopt, th+1, ((th->doff) - 5) * 4);
474 comp->xmit_current = cs->cs_this;
475 comp->sls_o_uncompressed++;
476 memcpy(ocp, icp, isize);
477 *cpp = ocp;
478 ocp[9] = cs->cs_this;
479 ocp[0] |= SL_TYPE_UNCOMPRESSED_TCP;
480 return isize;
481}
482
483
484int
485slhc_uncompress(struct slcompress *comp, unsigned char *icp, int isize)
486{
487 register int changes;
488 long x;
489 register struct tcphdr *thp;
490 register struct iphdr *ip;
491 register struct cstate *cs;
492 int len, hdrlen;
493 unsigned char *cp = icp;
494
495 /* We've got a compressed packet; read the change byte */
496 comp->sls_i_compressed++;
497 if(isize < 3){
498 comp->sls_i_error++;
499 return 0;
500 }
501 changes = *cp++;
502 if(changes & NEW_C){
503 /* Make sure the state index is in range, then grab the state.
504 * If we have a good state index, clear the 'discard' flag.
505 */
506 x = *cp++; /* Read conn index */
507 if(x < 0 || x > comp->rslot_limit)
508 goto bad;
509
510 comp->flags &=~ SLF_TOSS;
511 comp->recv_current = x;
512 } else {
513 /* this packet has an implicit state index. If we've
514 * had a line error since the last time we got an
515 * explicit state index, we have to toss the packet. */
516 if(comp->flags & SLF_TOSS){
517 comp->sls_i_tossed++;
518 return 0;
519 }
520 }
521 cs = &comp->rstate[comp->recv_current];
522 thp = &cs->cs_tcp;
523 ip = &cs->cs_ip;
524
525 thp->check = *(__sum16 *)cp;
526 cp += 2;
527
528 thp->psh = (changes & TCP_PUSH_BIT) ? 1 : 0;
529/*
530 * we can use the same number for the length of the saved header and
531 * the current one, because the packet wouldn't have been sent
532 * as compressed unless the options were the same as the previous one
533 */
534
535 hdrlen = ip->ihl * 4 + thp->doff * 4;
536
537 switch(changes & SPECIALS_MASK){
538 case SPECIAL_I: /* Echoed terminal traffic */
539 {
540 register short i;
541 i = ntohs(ip->tot_len) - hdrlen;
542 thp->ack_seq = htonl( ntohl(thp->ack_seq) + i);
543 thp->seq = htonl( ntohl(thp->seq) + i);
544 }
545 break;
546
547 case SPECIAL_D: /* Unidirectional data */
548 thp->seq = htonl( ntohl(thp->seq) +
549 ntohs(ip->tot_len) - hdrlen);
550 break;
551
552 default:
553 if(changes & NEW_U){
554 thp->urg = 1;
555 if((x = decode(&cp)) == -1) {
556 goto bad;
557 }
558 thp->urg_ptr = htons(x);
559 } else
560 thp->urg = 0;
561 if(changes & NEW_W){
562 if((x = decode(&cp)) == -1) {
563 goto bad;
564 }
565 thp->window = htons( ntohs(thp->window) + x);
566 }
567 if(changes & NEW_A){
568 if((x = decode(&cp)) == -1) {
569 goto bad;
570 }
571 thp->ack_seq = htonl( ntohl(thp->ack_seq) + x);
572 }
573 if(changes & NEW_S){
574 if((x = decode(&cp)) == -1) {
575 goto bad;
576 }
577 thp->seq = htonl( ntohl(thp->seq) + x);
578 }
579 break;
580 }
581 if(changes & NEW_I){
582 if((x = decode(&cp)) == -1) {
583 goto bad;
584 }
585 ip->id = htons (ntohs (ip->id) + x);
586 } else
587 ip->id = htons (ntohs (ip->id) + 1);
588
589 /*
590 * At this point, cp points to the first byte of data in the
591 * packet. Put the reconstructed TCP and IP headers back on the
592 * packet. Recalculate IP checksum (but not TCP checksum).
593 */
594
595 len = isize - (cp - icp);
596 if (len < 0)
597 goto bad;
598 len += hdrlen;
599 ip->tot_len = htons(len);
600 ip->check = 0;
601
602 memmove(icp + hdrlen, cp, len - hdrlen);
603
604 cp = icp;
605 memcpy(cp, ip, 20);
606 cp += 20;
607
608 if (ip->ihl > 5) {
609 memcpy(cp, cs->cs_ipopt, (ip->ihl - 5) * 4);
610 cp += (ip->ihl - 5) * 4;
611 }
612
613 put_unaligned(ip_fast_csum(icp, ip->ihl),
614 &((struct iphdr *)icp)->check);
615
616 memcpy(cp, thp, 20);
617 cp += 20;
618
619 if (thp->doff > 5) {
620 memcpy(cp, cs->cs_tcpopt, ((thp->doff) - 5) * 4);
621 cp += ((thp->doff) - 5) * 4;
622 }
623
624 return len;
625bad:
626 comp->sls_i_error++;
627 return slhc_toss( comp );
628}
629
630
631int
632slhc_remember(struct slcompress *comp, unsigned char *icp, int isize)
633{
634 register struct cstate *cs;
635 unsigned ihl;
636
637 unsigned char index;
638
639 if(isize < 20) {
640 /* The packet is shorter than a legal IP header */
641 comp->sls_i_runt++;
642 return slhc_toss( comp );
643 }
644 /* Peek at the IP header's IHL field to find its length */
645 ihl = icp[0] & 0xf;
646 if(ihl < 20 / 4){
647 /* The IP header length field is too small */
648 comp->sls_i_runt++;
649 return slhc_toss( comp );
650 }
651 index = icp[9];
652 icp[9] = IPPROTO_TCP;
653
654 if (ip_fast_csum(icp, ihl)) {
655 /* Bad IP header checksum; discard */
656 comp->sls_i_badcheck++;
657 return slhc_toss( comp );
658 }
659 if(index > comp->rslot_limit) {
660 comp->sls_i_error++;
661 return slhc_toss(comp);
662 }
663
664 /* Update local state */
665 cs = &comp->rstate[comp->recv_current = index];
666 comp->flags &=~ SLF_TOSS;
667 memcpy(&cs->cs_ip,icp,20);
668 memcpy(&cs->cs_tcp,icp + ihl*4,20);
669 if (ihl > 5)
670 memcpy(cs->cs_ipopt, icp + sizeof(struct iphdr), (ihl - 5) * 4);
671 if (cs->cs_tcp.doff > 5)
672 memcpy(cs->cs_tcpopt, icp + ihl*4 + sizeof(struct tcphdr), (cs->cs_tcp.doff - 5) * 4);
673 cs->cs_hsize = ihl*2 + cs->cs_tcp.doff*2;
674 /* Put headers back on packet
675 * Neither header checksum is recalculated
676 */
677 comp->sls_i_uncompressed++;
678 return isize;
679}
680
681int
682slhc_toss(struct slcompress *comp)
683{
684 if ( comp == NULLSLCOMPR )
685 return 0;
686
687 comp->flags |= SLF_TOSS;
688 return 0;
689}
690
691#else /* CONFIG_INET */
692
693int
694slhc_toss(struct slcompress *comp)
695{
696 printk(KERN_DEBUG "Called IP function on non IP-system: slhc_toss");
697 return -EINVAL;
698}
699int
700slhc_uncompress(struct slcompress *comp, unsigned char *icp, int isize)
701{
702 printk(KERN_DEBUG "Called IP function on non IP-system: slhc_uncompress");
703 return -EINVAL;
704}
705int
706slhc_compress(struct slcompress *comp, unsigned char *icp, int isize,
707 unsigned char *ocp, unsigned char **cpp, int compress_cid)
708{
709 printk(KERN_DEBUG "Called IP function on non IP-system: slhc_compress");
710 return -EINVAL;
711}
712
713int
714slhc_remember(struct slcompress *comp, unsigned char *icp, int isize)
715{
716 printk(KERN_DEBUG "Called IP function on non IP-system: slhc_remember");
717 return -EINVAL;
718}
719
720void
721slhc_free(struct slcompress *comp)
722{
723 printk(KERN_DEBUG "Called IP function on non IP-system: slhc_free");
724}
725struct slcompress *
726slhc_init(int rslots, int tslots)
727{
728 printk(KERN_DEBUG "Called IP function on non IP-system: slhc_init");
729 return NULL;
730}
731
732#endif /* CONFIG_INET */
733
734/* VJ header compression */
735EXPORT_SYMBOL(slhc_init);
736EXPORT_SYMBOL(slhc_free);
737EXPORT_SYMBOL(slhc_remember);
738EXPORT_SYMBOL(slhc_compress);
739EXPORT_SYMBOL(slhc_uncompress);
740EXPORT_SYMBOL(slhc_toss);
741
742MODULE_LICENSE("Dual BSD/GPL");
diff --git a/drivers/net/slip/slip.c b/drivers/net/slip/slip.c
new file mode 100644
index 00000000000..ba08341fb92
--- /dev/null
+++ b/drivers/net/slip/slip.c
@@ -0,0 +1,1444 @@
1/*
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
15 * mtu upwards. Driver now spots this
16 * and grows/shrinks its buffers(hack!).
17 * Memory leak if you run out of memory
18 * setting up a slip driver fixed.
19 * Matt Dillon : Printable slip (borrowed from NET2E)
20 * Pauline Middelink : Slip driver fixes.
21 * Alan Cox : Honours the old SL_COMPRESSED flag
22 * Alan Cox : KISS AX.25 and AXUI IP support
23 * Michael Riepe : Automatic CSLIP recognition added
24 * Charles Hedrick : CSLIP header length problem fix.
25 * Alan Cox : Corrected non-IP cases of the above.
26 * Alan Cox : Now uses hardware type as per FvK.
27 * Alan Cox : Default to 192.168.0.0 (RFC 1597)
28 * A.N.Kuznetsov : dev_tint() recursion fix.
29 * Dmitry Gorodchanin : SLIP memory leaks
30 * Dmitry Gorodchanin : Code cleanup. Reduce tty driver
31 * buffering from 4096 to 256 bytes.
32 * Improving SLIP response time.
33 * CONFIG_SLIP_MODE_SLIP6.
34 * ifconfig sl? up & down now works
35 * correctly.
36 * Modularization.
37 * Alan Cox : Oops - fix AX.25 buffer lengths
38 * Dmitry Gorodchanin : Even more cleanups. Preserve CSLIP
39 * statistics. Include CSLIP code only
40 * if it really needed.
41 * Alan Cox : Free slhc buffers in the right place.
42 * Alan Cox : Allow for digipeated IP over AX.25
43 * Matti Aarnio : Dynamic SLIP devices, with ideas taken
44 * from Jim Freeman's <jfree@caldera.com>
45 * dynamic PPP devices. We do NOT kfree()
46 * device entries, just reg./unreg. them
47 * as they are needed. We kfree() them
48 * at module cleanup.
49 * With MODULE-loading ``insmod'', user
50 * can issue parameter: slip_maxdev=1024
51 * (Or how much he/she wants.. Default
52 * is 256)
53 * Stanislav Voronyi : Slip line checking, with ideas taken
54 * from multislip BSDI driver which was
55 * written by Igor Chechik, RELCOM Corp.
56 * Only algorithms have been ported to
57 * Linux SLIP driver.
58 * Vitaly E. Lavrov : Sane behaviour on tty hangup.
59 * Alexey Kuznetsov : Cleanup interfaces to tty & netdevice
60 * modules.
61 */
62
63#define SL_CHECK_TRANSMIT
64#include <linux/module.h>
65#include <linux/moduleparam.h>
66
67#include <asm/system.h>
68#include <asm/uaccess.h>
69#include <linux/bitops.h>
70#include <linux/sched.h>
71#include <linux/string.h>
72#include <linux/mm.h>
73#include <linux/interrupt.h>
74#include <linux/in.h>
75#include <linux/tty.h>
76#include <linux/errno.h>
77#include <linux/netdevice.h>
78#include <linux/etherdevice.h>
79#include <linux/skbuff.h>
80#include <linux/rtnetlink.h>
81#include <linux/if_arp.h>
82#include <linux/if_slip.h>
83#include <linux/compat.h>
84#include <linux/delay.h>
85#include <linux/init.h>
86#include <linux/slab.h>
87#include "slip.h"
88#ifdef CONFIG_INET
89#include <linux/ip.h>
90#include <linux/tcp.h>
91#include <net/slhc_vj.h>
92#endif
93
94#define SLIP_VERSION "0.8.4-NET3.019-NEWTTY"
95
96static struct net_device **slip_devs;
97
98static int slip_maxdev = SL_NRUNIT;
99module_param(slip_maxdev, int, 0);
100MODULE_PARM_DESC(slip_maxdev, "Maximum number of slip devices");
101
102static int slip_esc(unsigned char *p, unsigned char *d, int len);
103static void slip_unesc(struct slip *sl, unsigned char c);
104#ifdef CONFIG_SLIP_MODE_SLIP6
105static int slip_esc6(unsigned char *p, unsigned char *d, int len);
106static void slip_unesc6(struct slip *sl, unsigned char c);
107#endif
108#ifdef CONFIG_SLIP_SMART
109static void sl_keepalive(unsigned long sls);
110static void sl_outfill(unsigned long sls);
111static int sl_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
112#endif
113
114/********************************
115* Buffer administration routines:
116* sl_alloc_bufs()
117* sl_free_bufs()
118* sl_realloc_bufs()
119*
120* NOTE: sl_realloc_bufs != sl_free_bufs + sl_alloc_bufs, because
121* sl_realloc_bufs provides strong atomicity and reallocation
122* on actively running device.
123*********************************/
124
125/*
126 Allocate channel buffers.
127 */
128
129static int sl_alloc_bufs(struct slip *sl, int mtu)
130{
131 int err = -ENOBUFS;
132 unsigned long len;
133 char *rbuff = NULL;
134 char *xbuff = NULL;
135#ifdef SL_INCLUDE_CSLIP
136 char *cbuff = NULL;
137 struct slcompress *slcomp = NULL;
138#endif
139
140 /*
141 * Allocate the SLIP frame buffers:
142 *
143 * rbuff Receive buffer.
144 * xbuff Transmit buffer.
145 * cbuff Temporary compression buffer.
146 */
147 len = mtu * 2;
148
149 /*
150 * allow for arrival of larger UDP packets, even if we say not to
151 * also fixes a bug in which SunOS sends 512-byte packets even with
152 * an MSS of 128
153 */
154 if (len < 576 * 2)
155 len = 576 * 2;
156 rbuff = kmalloc(len + 4, GFP_KERNEL);
157 if (rbuff == NULL)
158 goto err_exit;
159 xbuff = kmalloc(len + 4, GFP_KERNEL);
160 if (xbuff == NULL)
161 goto err_exit;
162#ifdef SL_INCLUDE_CSLIP
163 cbuff = kmalloc(len + 4, GFP_KERNEL);
164 if (cbuff == NULL)
165 goto err_exit;
166 slcomp = slhc_init(16, 16);
167 if (slcomp == NULL)
168 goto err_exit;
169#endif
170 spin_lock_bh(&sl->lock);
171 if (sl->tty == NULL) {
172 spin_unlock_bh(&sl->lock);
173 err = -ENODEV;
174 goto err_exit;
175 }
176 sl->mtu = mtu;
177 sl->buffsize = len;
178 sl->rcount = 0;
179 sl->xleft = 0;
180 rbuff = xchg(&sl->rbuff, rbuff);
181 xbuff = xchg(&sl->xbuff, xbuff);
182#ifdef SL_INCLUDE_CSLIP
183 cbuff = xchg(&sl->cbuff, cbuff);
184 slcomp = xchg(&sl->slcomp, slcomp);
185#endif
186#ifdef CONFIG_SLIP_MODE_SLIP6
187 sl->xdata = 0;
188 sl->xbits = 0;
189#endif
190 spin_unlock_bh(&sl->lock);
191 err = 0;
192
193 /* Cleanup */
194err_exit:
195#ifdef SL_INCLUDE_CSLIP
196 kfree(cbuff);
197 slhc_free(slcomp);
198#endif
199 kfree(xbuff);
200 kfree(rbuff);
201 return err;
202}
203
204/* Free a SLIP channel buffers. */
205static void sl_free_bufs(struct slip *sl)
206{
207 /* Free all SLIP frame buffers. */
208 kfree(xchg(&sl->rbuff, NULL));
209 kfree(xchg(&sl->xbuff, NULL));
210#ifdef SL_INCLUDE_CSLIP
211 kfree(xchg(&sl->cbuff, NULL));
212 slhc_free(xchg(&sl->slcomp, NULL));
213#endif
214}
215
216/*
217 Reallocate slip channel buffers.
218 */
219
220static int sl_realloc_bufs(struct slip *sl, int mtu)
221{
222 int err = 0;
223 struct net_device *dev = sl->dev;
224 unsigned char *xbuff, *rbuff;
225#ifdef SL_INCLUDE_CSLIP
226 unsigned char *cbuff;
227#endif
228 int len = mtu * 2;
229
230/*
231 * allow for arrival of larger UDP packets, even if we say not to
232 * also fixes a bug in which SunOS sends 512-byte packets even with
233 * an MSS of 128
234 */
235 if (len < 576 * 2)
236 len = 576 * 2;
237
238 xbuff = kmalloc(len + 4, GFP_ATOMIC);
239 rbuff = kmalloc(len + 4, GFP_ATOMIC);
240#ifdef SL_INCLUDE_CSLIP
241 cbuff = kmalloc(len + 4, GFP_ATOMIC);
242#endif
243
244
245#ifdef SL_INCLUDE_CSLIP
246 if (xbuff == NULL || rbuff == NULL || cbuff == NULL) {
247#else
248 if (xbuff == NULL || rbuff == NULL) {
249#endif
250 if (mtu > sl->mtu) {
251 printk(KERN_WARNING "%s: unable to grow slip buffers, MTU change cancelled.\n",
252 dev->name);
253 err = -ENOBUFS;
254 }
255 goto done;
256 }
257 spin_lock_bh(&sl->lock);
258
259 err = -ENODEV;
260 if (sl->tty == NULL)
261 goto done_on_bh;
262
263 xbuff = xchg(&sl->xbuff, xbuff);
264 rbuff = xchg(&sl->rbuff, rbuff);
265#ifdef SL_INCLUDE_CSLIP
266 cbuff = xchg(&sl->cbuff, cbuff);
267#endif
268 if (sl->xleft) {
269 if (sl->xleft <= len) {
270 memcpy(sl->xbuff, sl->xhead, sl->xleft);
271 } else {
272 sl->xleft = 0;
273 dev->stats.tx_dropped++;
274 }
275 }
276 sl->xhead = sl->xbuff;
277
278 if (sl->rcount) {
279 if (sl->rcount <= len) {
280 memcpy(sl->rbuff, rbuff, sl->rcount);
281 } else {
282 sl->rcount = 0;
283 dev->stats.rx_over_errors++;
284 set_bit(SLF_ERROR, &sl->flags);
285 }
286 }
287 sl->mtu = mtu;
288 dev->mtu = mtu;
289 sl->buffsize = len;
290 err = 0;
291
292done_on_bh:
293 spin_unlock_bh(&sl->lock);
294
295done:
296 kfree(xbuff);
297 kfree(rbuff);
298#ifdef SL_INCLUDE_CSLIP
299 kfree(cbuff);
300#endif
301 return err;
302}
303
304
305/* Set the "sending" flag. This must be atomic hence the set_bit. */
306static inline void sl_lock(struct slip *sl)
307{
308 netif_stop_queue(sl->dev);
309}
310
311
312/* Clear the "sending" flag. This must be atomic, hence the ASM. */
313static inline void sl_unlock(struct slip *sl)
314{
315 netif_wake_queue(sl->dev);
316}
317
318/* Send one completely decapsulated IP datagram to the IP layer. */
319static void sl_bump(struct slip *sl)
320{
321 struct net_device *dev = sl->dev;
322 struct sk_buff *skb;
323 int count;
324
325 count = sl->rcount;
326#ifdef SL_INCLUDE_CSLIP
327 if (sl->mode & (SL_MODE_ADAPTIVE | SL_MODE_CSLIP)) {
328 unsigned char c = sl->rbuff[0];
329 if (c & SL_TYPE_COMPRESSED_TCP) {
330 /* ignore compressed packets when CSLIP is off */
331 if (!(sl->mode & SL_MODE_CSLIP)) {
332 printk(KERN_WARNING "%s: compressed packet ignored\n", dev->name);
333 return;
334 }
335 /* make sure we've reserved enough space for uncompress
336 to use */
337 if (count + 80 > sl->buffsize) {
338 dev->stats.rx_over_errors++;
339 return;
340 }
341 count = slhc_uncompress(sl->slcomp, sl->rbuff, count);
342 if (count <= 0)
343 return;
344 } else if (c >= SL_TYPE_UNCOMPRESSED_TCP) {
345 if (!(sl->mode & SL_MODE_CSLIP)) {
346 /* turn on header compression */
347 sl->mode |= SL_MODE_CSLIP;
348 sl->mode &= ~SL_MODE_ADAPTIVE;
349 printk(KERN_INFO "%s: header compression turned on\n", dev->name);
350 }
351 sl->rbuff[0] &= 0x4f;
352 if (slhc_remember(sl->slcomp, sl->rbuff, count) <= 0)
353 return;
354 }
355 }
356#endif /* SL_INCLUDE_CSLIP */
357
358 dev->stats.rx_bytes += count;
359
360 skb = dev_alloc_skb(count);
361 if (skb == NULL) {
362 printk(KERN_WARNING "%s: memory squeeze, dropping packet.\n", dev->name);
363 dev->stats.rx_dropped++;
364 return;
365 }
366 skb->dev = dev;
367 memcpy(skb_put(skb, count), sl->rbuff, count);
368 skb_reset_mac_header(skb);
369 skb->protocol = htons(ETH_P_IP);
370 netif_rx_ni(skb);
371 dev->stats.rx_packets++;
372}
373
374/* Encapsulate one IP datagram and stuff into a TTY queue. */
375static void sl_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->dev->stats.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#endif
392#ifdef CONFIG_SLIP_MODE_SLIP6
393 if (sl->mode & SL_MODE_SLIP6)
394 count = slip_esc6(p, (unsigned char *) sl->xbuff, len);
395 else
396#endif
397 count = slip_esc(p, (unsigned char *) sl->xbuff, len);
398
399 /* Order of next two lines is *very* important.
400 * When we are sending a little amount of data,
401 * the transfer may be completed inside the ops->write()
402 * routine, because it's running with interrupts enabled.
403 * In this case we *never* got WRITE_WAKEUP event,
404 * if we did not request it before write operation.
405 * 14 Oct 1994 Dmitry Gorodchanin.
406 */
407 set_bit(TTY_DO_WRITE_WAKEUP, &sl->tty->flags);
408 actual = sl->tty->ops->write(sl->tty, sl->xbuff, count);
409#ifdef SL_CHECK_TRANSMIT
410 sl->dev->trans_start = jiffies;
411#endif
412 sl->xleft = count - actual;
413 sl->xhead = sl->xbuff + actual;
414#ifdef CONFIG_SLIP_SMART
415 /* VSV */
416 clear_bit(SLF_OUTWAIT, &sl->flags); /* reset outfill flag */
417#endif
418}
419
420/*
421 * Called by the driver when there's room for more data. If we have
422 * more packets to send, we send them here.
423 */
424static void slip_write_wakeup(struct tty_struct *tty)
425{
426 int actual;
427 struct slip *sl = tty->disc_data;
428
429 /* First make sure we're connected. */
430 if (!sl || sl->magic != SLIP_MAGIC || !netif_running(sl->dev))
431 return;
432
433 if (sl->xleft <= 0) {
434 /* Now serial buffer is almost free & we can start
435 * transmission of another packet */
436 sl->dev->stats.tx_packets++;
437 clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
438 sl_unlock(sl);
439 return;
440 }
441
442 actual = tty->ops->write(tty, sl->xhead, sl->xleft);
443 sl->xleft -= actual;
444 sl->xhead += actual;
445}
446
447static void sl_tx_timeout(struct net_device *dev)
448{
449 struct slip *sl = netdev_priv(dev);
450
451 spin_lock(&sl->lock);
452
453 if (netif_queue_stopped(dev)) {
454 if (!netif_running(dev))
455 goto out;
456
457 /* May be we must check transmitter timeout here ?
458 * 14 Oct 1994 Dmitry Gorodchanin.
459 */
460#ifdef SL_CHECK_TRANSMIT
461 if (time_before(jiffies, dev_trans_start(dev) + 20 * HZ)) {
462 /* 20 sec timeout not reached */
463 goto out;
464 }
465 printk(KERN_WARNING "%s: transmit timed out, %s?\n",
466 dev->name,
467 (tty_chars_in_buffer(sl->tty) || sl->xleft) ?
468 "bad line quality" : "driver error");
469 sl->xleft = 0;
470 clear_bit(TTY_DO_WRITE_WAKEUP, &sl->tty->flags);
471 sl_unlock(sl);
472#endif
473 }
474out:
475 spin_unlock(&sl->lock);
476}
477
478
479/* Encapsulate an IP datagram and kick it into a TTY queue. */
480static netdev_tx_t
481sl_xmit(struct sk_buff *skb, struct net_device *dev)
482{
483 struct slip *sl = netdev_priv(dev);
484
485 spin_lock(&sl->lock);
486 if (!netif_running(dev)) {
487 spin_unlock(&sl->lock);
488 printk(KERN_WARNING "%s: xmit call when iface is down\n", dev->name);
489 dev_kfree_skb(skb);
490 return NETDEV_TX_OK;
491 }
492 if (sl->tty == NULL) {
493 spin_unlock(&sl->lock);
494 dev_kfree_skb(skb);
495 return NETDEV_TX_OK;
496 }
497
498 sl_lock(sl);
499 dev->stats.tx_bytes += skb->len;
500 sl_encaps(sl, skb->data, skb->len);
501 spin_unlock(&sl->lock);
502
503 dev_kfree_skb(skb);
504 return NETDEV_TX_OK;
505}
506
507
508/******************************************
509 * Routines looking at netdevice side.
510 ******************************************/
511
512/* Netdevice UP -> DOWN routine */
513
514static int
515sl_close(struct net_device *dev)
516{
517 struct slip *sl = netdev_priv(dev);
518
519 spin_lock_bh(&sl->lock);
520 if (sl->tty)
521 /* TTY discipline is running. */
522 clear_bit(TTY_DO_WRITE_WAKEUP, &sl->tty->flags);
523 netif_stop_queue(dev);
524 sl->rcount = 0;
525 sl->xleft = 0;
526 spin_unlock_bh(&sl->lock);
527
528 return 0;
529}
530
531/* Netdevice DOWN -> UP routine */
532
533static int sl_open(struct net_device *dev)
534{
535 struct slip *sl = netdev_priv(dev);
536
537 if (sl->tty == NULL)
538 return -ENODEV;
539
540 sl->flags &= (1 << SLF_INUSE);
541 netif_start_queue(dev);
542 return 0;
543}
544
545/* Netdevice change MTU request */
546
547static int sl_change_mtu(struct net_device *dev, int new_mtu)
548{
549 struct slip *sl = netdev_priv(dev);
550
551 if (new_mtu < 68 || new_mtu > 65534)
552 return -EINVAL;
553
554 if (new_mtu != dev->mtu)
555 return sl_realloc_bufs(sl, new_mtu);
556 return 0;
557}
558
559/* Netdevice get statistics request */
560
561static struct rtnl_link_stats64 *
562sl_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats)
563{
564 struct net_device_stats *devstats = &dev->stats;
565#ifdef SL_INCLUDE_CSLIP
566 struct slip *sl = netdev_priv(dev);
567 struct slcompress *comp = sl->slcomp;
568#endif
569 stats->rx_packets = devstats->rx_packets;
570 stats->tx_packets = devstats->tx_packets;
571 stats->rx_bytes = devstats->rx_bytes;
572 stats->tx_bytes = devstats->tx_bytes;
573 stats->rx_dropped = devstats->rx_dropped;
574 stats->tx_dropped = devstats->tx_dropped;
575 stats->tx_errors = devstats->tx_errors;
576 stats->rx_errors = devstats->rx_errors;
577 stats->rx_over_errors = devstats->rx_over_errors;
578
579#ifdef SL_INCLUDE_CSLIP
580 if (comp) {
581 /* Generic compressed statistics */
582 stats->rx_compressed = comp->sls_i_compressed;
583 stats->tx_compressed = comp->sls_o_compressed;
584
585 /* Are we really still needs this? */
586 stats->rx_fifo_errors += comp->sls_i_compressed;
587 stats->rx_dropped += comp->sls_i_tossed;
588 stats->tx_fifo_errors += comp->sls_o_compressed;
589 stats->collisions += comp->sls_o_misses;
590 }
591#endif
592 return stats;
593}
594
595/* Netdevice register callback */
596
597static int sl_init(struct net_device *dev)
598{
599 struct slip *sl = netdev_priv(dev);
600
601 /*
602 * Finish setting up the DEVICE info.
603 */
604
605 dev->mtu = sl->mtu;
606 dev->type = ARPHRD_SLIP + sl->mode;
607#ifdef SL_CHECK_TRANSMIT
608 dev->watchdog_timeo = 20*HZ;
609#endif
610 return 0;
611}
612
613
614static void sl_uninit(struct net_device *dev)
615{
616 struct slip *sl = netdev_priv(dev);
617
618 sl_free_bufs(sl);
619}
620
621/* Hook the destructor so we can free slip devices at the right point in time */
622static void sl_free_netdev(struct net_device *dev)
623{
624 int i = dev->base_addr;
625 free_netdev(dev);
626 slip_devs[i] = NULL;
627}
628
629static const struct net_device_ops sl_netdev_ops = {
630 .ndo_init = sl_init,
631 .ndo_uninit = sl_uninit,
632 .ndo_open = sl_open,
633 .ndo_stop = sl_close,
634 .ndo_start_xmit = sl_xmit,
635 .ndo_get_stats64 = sl_get_stats64,
636 .ndo_change_mtu = sl_change_mtu,
637 .ndo_tx_timeout = sl_tx_timeout,
638#ifdef CONFIG_SLIP_SMART
639 .ndo_do_ioctl = sl_ioctl,
640#endif
641};
642
643
644static void sl_setup(struct net_device *dev)
645{
646 dev->netdev_ops = &sl_netdev_ops;
647 dev->destructor = sl_free_netdev;
648
649 dev->hard_header_len = 0;
650 dev->addr_len = 0;
651 dev->tx_queue_len = 10;
652
653 /* New-style flags. */
654 dev->flags = IFF_NOARP|IFF_POINTOPOINT|IFF_MULTICAST;
655}
656
657/******************************************
658 Routines looking at TTY side.
659 ******************************************/
660
661
662/*
663 * Handle the 'receiver data ready' interrupt.
664 * This function is called by the 'tty_io' module in the kernel when
665 * a block of SLIP data has been received, which can now be decapsulated
666 * and sent on to some IP layer for further processing. This will not
667 * be re-entered while running but other ldisc functions may be called
668 * in parallel
669 */
670
671static void slip_receive_buf(struct tty_struct *tty, const unsigned char *cp,
672 char *fp, int count)
673{
674 struct slip *sl = tty->disc_data;
675
676 if (!sl || sl->magic != SLIP_MAGIC || !netif_running(sl->dev))
677 return;
678
679 /* Read the characters out of the buffer */
680 while (count--) {
681 if (fp && *fp++) {
682 if (!test_and_set_bit(SLF_ERROR, &sl->flags))
683 sl->dev->stats.rx_errors++;
684 cp++;
685 continue;
686 }
687#ifdef CONFIG_SLIP_MODE_SLIP6
688 if (sl->mode & SL_MODE_SLIP6)
689 slip_unesc6(sl, *cp++);
690 else
691#endif
692 slip_unesc(sl, *cp++);
693 }
694}
695
696/************************************
697 * slip_open helper routines.
698 ************************************/
699
700/* Collect hanged up channels */
701static void sl_sync(void)
702{
703 int i;
704 struct net_device *dev;
705 struct slip *sl;
706
707 for (i = 0; i < slip_maxdev; i++) {
708 dev = slip_devs[i];
709 if (dev == NULL)
710 break;
711
712 sl = netdev_priv(dev);
713 if (sl->tty || sl->leased)
714 continue;
715 if (dev->flags & IFF_UP)
716 dev_close(dev);
717 }
718}
719
720
721/* Find a free SLIP channel, and link in this `tty' line. */
722static struct slip *sl_alloc(dev_t line)
723{
724 int i;
725 char name[IFNAMSIZ];
726 struct net_device *dev = NULL;
727 struct slip *sl;
728
729 for (i = 0; i < slip_maxdev; i++) {
730 dev = slip_devs[i];
731 if (dev == NULL)
732 break;
733 }
734 /* Sorry, too many, all slots in use */
735 if (i >= slip_maxdev)
736 return NULL;
737
738 sprintf(name, "sl%d", i);
739 dev = alloc_netdev(sizeof(*sl), name, sl_setup);
740 if (!dev)
741 return NULL;
742
743 dev->base_addr = i;
744 sl = netdev_priv(dev);
745
746 /* Initialize channel control data */
747 sl->magic = SLIP_MAGIC;
748 sl->dev = dev;
749 spin_lock_init(&sl->lock);
750 sl->mode = SL_MODE_DEFAULT;
751#ifdef CONFIG_SLIP_SMART
752 /* initialize timer_list struct */
753 init_timer(&sl->keepalive_timer);
754 sl->keepalive_timer.data = (unsigned long)sl;
755 sl->keepalive_timer.function = sl_keepalive;
756 init_timer(&sl->outfill_timer);
757 sl->outfill_timer.data = (unsigned long)sl;
758 sl->outfill_timer.function = sl_outfill;
759#endif
760 slip_devs[i] = dev;
761 return sl;
762}
763
764/*
765 * Open the high-level part of the SLIP channel.
766 * This function is called by the TTY module when the
767 * SLIP line discipline is called for. Because we are
768 * sure the tty line exists, we only have to link it to
769 * a free SLIP channel...
770 *
771 * Called in process context serialized from other ldisc calls.
772 */
773
774static int slip_open(struct tty_struct *tty)
775{
776 struct slip *sl;
777 int err;
778
779 if (!capable(CAP_NET_ADMIN))
780 return -EPERM;
781
782 if (tty->ops->write == NULL)
783 return -EOPNOTSUPP;
784
785 /* RTnetlink lock is misused here to serialize concurrent
786 opens of slip channels. There are better ways, but it is
787 the simplest one.
788 */
789 rtnl_lock();
790
791 /* Collect hanged up channels. */
792 sl_sync();
793
794 sl = tty->disc_data;
795
796 err = -EEXIST;
797 /* First make sure we're not already connected. */
798 if (sl && sl->magic == SLIP_MAGIC)
799 goto err_exit;
800
801 /* OK. Find a free SLIP channel to use. */
802 err = -ENFILE;
803 sl = sl_alloc(tty_devnum(tty));
804 if (sl == NULL)
805 goto err_exit;
806
807 sl->tty = tty;
808 tty->disc_data = sl;
809 sl->pid = current->pid;
810
811 if (!test_bit(SLF_INUSE, &sl->flags)) {
812 /* Perform the low-level SLIP initialization. */
813 err = sl_alloc_bufs(sl, SL_MTU);
814 if (err)
815 goto err_free_chan;
816
817 set_bit(SLF_INUSE, &sl->flags);
818
819 err = register_netdevice(sl->dev);
820 if (err)
821 goto err_free_bufs;
822 }
823
824#ifdef CONFIG_SLIP_SMART
825 if (sl->keepalive) {
826 sl->keepalive_timer.expires = jiffies + sl->keepalive * HZ;
827 add_timer(&sl->keepalive_timer);
828 }
829 if (sl->outfill) {
830 sl->outfill_timer.expires = jiffies + sl->outfill * HZ;
831 add_timer(&sl->outfill_timer);
832 }
833#endif
834
835 /* Done. We have linked the TTY line to a channel. */
836 rtnl_unlock();
837 tty->receive_room = 65536; /* We don't flow control */
838
839 /* TTY layer expects 0 on success */
840 return 0;
841
842err_free_bufs:
843 sl_free_bufs(sl);
844
845err_free_chan:
846 sl->tty = NULL;
847 tty->disc_data = NULL;
848 clear_bit(SLF_INUSE, &sl->flags);
849
850err_exit:
851 rtnl_unlock();
852
853 /* Count references from TTY module */
854 return err;
855}
856
857/*
858 * Close down a SLIP channel.
859 * This means flushing out any pending queues, and then returning. This
860 * call is serialized against other ldisc functions.
861 *
862 * We also use this method fo a hangup event
863 */
864
865static void slip_close(struct tty_struct *tty)
866{
867 struct slip *sl = tty->disc_data;
868
869 /* First make sure we're connected. */
870 if (!sl || sl->magic != SLIP_MAGIC || sl->tty != tty)
871 return;
872
873 tty->disc_data = NULL;
874 sl->tty = NULL;
875
876 /* VSV = very important to remove timers */
877#ifdef CONFIG_SLIP_SMART
878 del_timer_sync(&sl->keepalive_timer);
879 del_timer_sync(&sl->outfill_timer);
880#endif
881 /* Flush network side */
882 unregister_netdev(sl->dev);
883 /* This will complete via sl_free_netdev */
884}
885
886static int slip_hangup(struct tty_struct *tty)
887{
888 slip_close(tty);
889 return 0;
890}
891 /************************************************************************
892 * STANDARD SLIP ENCAPSULATION *
893 ************************************************************************/
894
895static int slip_esc(unsigned char *s, unsigned char *d, int len)
896{
897 unsigned char *ptr = d;
898 unsigned char c;
899
900 /*
901 * Send an initial END character to flush out any
902 * data that may have accumulated in the receiver
903 * due to line noise.
904 */
905
906 *ptr++ = END;
907
908 /*
909 * For each byte in the packet, send the appropriate
910 * character sequence, according to the SLIP protocol.
911 */
912
913 while (len-- > 0) {
914 switch (c = *s++) {
915 case END:
916 *ptr++ = ESC;
917 *ptr++ = ESC_END;
918 break;
919 case ESC:
920 *ptr++ = ESC;
921 *ptr++ = ESC_ESC;
922 break;
923 default:
924 *ptr++ = c;
925 break;
926 }
927 }
928 *ptr++ = END;
929 return ptr - d;
930}
931
932static void slip_unesc(struct slip *sl, unsigned char s)
933{
934
935 switch (s) {
936 case END:
937#ifdef CONFIG_SLIP_SMART
938 /* drop keeptest bit = VSV */
939 if (test_bit(SLF_KEEPTEST, &sl->flags))
940 clear_bit(SLF_KEEPTEST, &sl->flags);
941#endif
942
943 if (!test_and_clear_bit(SLF_ERROR, &sl->flags) &&
944 (sl->rcount > 2))
945 sl_bump(sl);
946 clear_bit(SLF_ESCAPE, &sl->flags);
947 sl->rcount = 0;
948 return;
949
950 case ESC:
951 set_bit(SLF_ESCAPE, &sl->flags);
952 return;
953 case ESC_ESC:
954 if (test_and_clear_bit(SLF_ESCAPE, &sl->flags))
955 s = ESC;
956 break;
957 case ESC_END:
958 if (test_and_clear_bit(SLF_ESCAPE, &sl->flags))
959 s = END;
960 break;
961 }
962 if (!test_bit(SLF_ERROR, &sl->flags)) {
963 if (sl->rcount < sl->buffsize) {
964 sl->rbuff[sl->rcount++] = s;
965 return;
966 }
967 sl->dev->stats.rx_over_errors++;
968 set_bit(SLF_ERROR, &sl->flags);
969 }
970}
971
972
973#ifdef CONFIG_SLIP_MODE_SLIP6
974/************************************************************************
975 * 6 BIT SLIP ENCAPSULATION *
976 ************************************************************************/
977
978static int slip_esc6(unsigned char *s, unsigned char *d, int len)
979{
980 unsigned char *ptr = d;
981 unsigned char c;
982 int i;
983 unsigned short v = 0;
984 short bits = 0;
985
986 /*
987 * Send an initial END character to flush out any
988 * data that may have accumulated in the receiver
989 * due to line noise.
990 */
991
992 *ptr++ = 0x70;
993
994 /*
995 * Encode the packet into printable ascii characters
996 */
997
998 for (i = 0; i < len; ++i) {
999 v = (v << 8) | s[i];
1000 bits += 8;
1001 while (bits >= 6) {
1002 bits -= 6;
1003 c = 0x30 + ((v >> bits) & 0x3F);
1004 *ptr++ = c;
1005 }
1006 }
1007 if (bits) {
1008 c = 0x30 + ((v << (6 - bits)) & 0x3F);
1009 *ptr++ = c;
1010 }
1011 *ptr++ = 0x70;
1012 return ptr - d;
1013}
1014
1015static void slip_unesc6(struct slip *sl, unsigned char s)
1016{
1017 unsigned char c;
1018
1019 if (s == 0x70) {
1020#ifdef CONFIG_SLIP_SMART
1021 /* drop keeptest bit = VSV */
1022 if (test_bit(SLF_KEEPTEST, &sl->flags))
1023 clear_bit(SLF_KEEPTEST, &sl->flags);
1024#endif
1025
1026 if (!test_and_clear_bit(SLF_ERROR, &sl->flags) &&
1027 (sl->rcount > 2))
1028 sl_bump(sl);
1029 sl->rcount = 0;
1030 sl->xbits = 0;
1031 sl->xdata = 0;
1032 } else if (s >= 0x30 && s < 0x70) {
1033 sl->xdata = (sl->xdata << 6) | ((s - 0x30) & 0x3F);
1034 sl->xbits += 6;
1035 if (sl->xbits >= 8) {
1036 sl->xbits -= 8;
1037 c = (unsigned char)(sl->xdata >> sl->xbits);
1038 if (!test_bit(SLF_ERROR, &sl->flags)) {
1039 if (sl->rcount < sl->buffsize) {
1040 sl->rbuff[sl->rcount++] = c;
1041 return;
1042 }
1043 sl->dev->stats.rx_over_errors++;
1044 set_bit(SLF_ERROR, &sl->flags);
1045 }
1046 }
1047 }
1048}
1049#endif /* CONFIG_SLIP_MODE_SLIP6 */
1050
1051/* Perform I/O control on an active SLIP channel. */
1052static int slip_ioctl(struct tty_struct *tty, struct file *file,
1053 unsigned int cmd, unsigned long arg)
1054{
1055 struct slip *sl = tty->disc_data;
1056 unsigned int tmp;
1057 int __user *p = (int __user *)arg;
1058
1059 /* First make sure we're connected. */
1060 if (!sl || sl->magic != SLIP_MAGIC)
1061 return -EINVAL;
1062
1063 switch (cmd) {
1064 case SIOCGIFNAME:
1065 tmp = strlen(sl->dev->name) + 1;
1066 if (copy_to_user((void __user *)arg, sl->dev->name, tmp))
1067 return -EFAULT;
1068 return 0;
1069
1070 case SIOCGIFENCAP:
1071 if (put_user(sl->mode, p))
1072 return -EFAULT;
1073 return 0;
1074
1075 case SIOCSIFENCAP:
1076 if (get_user(tmp, p))
1077 return -EFAULT;
1078#ifndef SL_INCLUDE_CSLIP
1079 if (tmp & (SL_MODE_CSLIP|SL_MODE_ADAPTIVE))
1080 return -EINVAL;
1081#else
1082 if ((tmp & (SL_MODE_ADAPTIVE | SL_MODE_CSLIP)) ==
1083 (SL_MODE_ADAPTIVE | SL_MODE_CSLIP))
1084 /* return -EINVAL; */
1085 tmp &= ~SL_MODE_ADAPTIVE;
1086#endif
1087#ifndef CONFIG_SLIP_MODE_SLIP6
1088 if (tmp & SL_MODE_SLIP6)
1089 return -EINVAL;
1090#endif
1091 sl->mode = tmp;
1092 sl->dev->type = ARPHRD_SLIP + sl->mode;
1093 return 0;
1094
1095 case SIOCSIFHWADDR:
1096 return -EINVAL;
1097
1098#ifdef CONFIG_SLIP_SMART
1099 /* VSV changes start here */
1100 case SIOCSKEEPALIVE:
1101 if (get_user(tmp, p))
1102 return -EFAULT;
1103 if (tmp > 255) /* max for unchar */
1104 return -EINVAL;
1105
1106 spin_lock_bh(&sl->lock);
1107 if (!sl->tty) {
1108 spin_unlock_bh(&sl->lock);
1109 return -ENODEV;
1110 }
1111 sl->keepalive = (u8)tmp;
1112 if (sl->keepalive != 0) {
1113 mod_timer(&sl->keepalive_timer,
1114 jiffies + sl->keepalive * HZ);
1115 set_bit(SLF_KEEPTEST, &sl->flags);
1116 } else
1117 del_timer(&sl->keepalive_timer);
1118 spin_unlock_bh(&sl->lock);
1119 return 0;
1120
1121 case SIOCGKEEPALIVE:
1122 if (put_user(sl->keepalive, p))
1123 return -EFAULT;
1124 return 0;
1125
1126 case SIOCSOUTFILL:
1127 if (get_user(tmp, p))
1128 return -EFAULT;
1129 if (tmp > 255) /* max for unchar */
1130 return -EINVAL;
1131 spin_lock_bh(&sl->lock);
1132 if (!sl->tty) {
1133 spin_unlock_bh(&sl->lock);
1134 return -ENODEV;
1135 }
1136 sl->outfill = (u8)tmp;
1137 if (sl->outfill != 0) {
1138 mod_timer(&sl->outfill_timer,
1139 jiffies + sl->outfill * HZ);
1140 set_bit(SLF_OUTWAIT, &sl->flags);
1141 } else
1142 del_timer(&sl->outfill_timer);
1143 spin_unlock_bh(&sl->lock);
1144 return 0;
1145
1146 case SIOCGOUTFILL:
1147 if (put_user(sl->outfill, p))
1148 return -EFAULT;
1149 return 0;
1150 /* VSV changes end */
1151#endif
1152 default:
1153 return tty_mode_ioctl(tty, file, cmd, arg);
1154 }
1155}
1156
1157#ifdef CONFIG_COMPAT
1158static long slip_compat_ioctl(struct tty_struct *tty, struct file *file,
1159 unsigned int cmd, unsigned long arg)
1160{
1161 switch (cmd) {
1162 case SIOCGIFNAME:
1163 case SIOCGIFENCAP:
1164 case SIOCSIFENCAP:
1165 case SIOCSIFHWADDR:
1166 case SIOCSKEEPALIVE:
1167 case SIOCGKEEPALIVE:
1168 case SIOCSOUTFILL:
1169 case SIOCGOUTFILL:
1170 return slip_ioctl(tty, file, cmd,
1171 (unsigned long)compat_ptr(arg));
1172 }
1173
1174 return -ENOIOCTLCMD;
1175}
1176#endif
1177
1178/* VSV changes start here */
1179#ifdef CONFIG_SLIP_SMART
1180/* function do_ioctl called from net/core/dev.c
1181 to allow get/set outfill/keepalive parameter
1182 by ifconfig */
1183
1184static int sl_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
1185{
1186 struct slip *sl = netdev_priv(dev);
1187 unsigned long *p = (unsigned long *)&rq->ifr_ifru;
1188
1189 if (sl == NULL) /* Allocation failed ?? */
1190 return -ENODEV;
1191
1192 spin_lock_bh(&sl->lock);
1193
1194 if (!sl->tty) {
1195 spin_unlock_bh(&sl->lock);
1196 return -ENODEV;
1197 }
1198
1199 switch (cmd) {
1200 case SIOCSKEEPALIVE:
1201 /* max for unchar */
1202 if ((unsigned)*p > 255) {
1203 spin_unlock_bh(&sl->lock);
1204 return -EINVAL;
1205 }
1206 sl->keepalive = (u8)*p;
1207 if (sl->keepalive != 0) {
1208 sl->keepalive_timer.expires =
1209 jiffies + sl->keepalive * HZ;
1210 mod_timer(&sl->keepalive_timer,
1211 jiffies + sl->keepalive * HZ);
1212 set_bit(SLF_KEEPTEST, &sl->flags);
1213 } else
1214 del_timer(&sl->keepalive_timer);
1215 break;
1216
1217 case SIOCGKEEPALIVE:
1218 *p = sl->keepalive;
1219 break;
1220
1221 case SIOCSOUTFILL:
1222 if ((unsigned)*p > 255) { /* max for unchar */
1223 spin_unlock_bh(&sl->lock);
1224 return -EINVAL;
1225 }
1226 sl->outfill = (u8)*p;
1227 if (sl->outfill != 0) {
1228 mod_timer(&sl->outfill_timer,
1229 jiffies + sl->outfill * HZ);
1230 set_bit(SLF_OUTWAIT, &sl->flags);
1231 } else
1232 del_timer(&sl->outfill_timer);
1233 break;
1234
1235 case SIOCGOUTFILL:
1236 *p = sl->outfill;
1237 break;
1238
1239 case SIOCSLEASE:
1240 /* Resolve race condition, when ioctl'ing hanged up
1241 and opened by another process device.
1242 */
1243 if (sl->tty != current->signal->tty &&
1244 sl->pid != current->pid) {
1245 spin_unlock_bh(&sl->lock);
1246 return -EPERM;
1247 }
1248 sl->leased = 0;
1249 if (*p)
1250 sl->leased = 1;
1251 break;
1252
1253 case SIOCGLEASE:
1254 *p = sl->leased;
1255 }
1256 spin_unlock_bh(&sl->lock);
1257 return 0;
1258}
1259#endif
1260/* VSV changes end */
1261
1262static struct tty_ldisc_ops sl_ldisc = {
1263 .owner = THIS_MODULE,
1264 .magic = TTY_LDISC_MAGIC,
1265 .name = "slip",
1266 .open = slip_open,
1267 .close = slip_close,
1268 .hangup = slip_hangup,
1269 .ioctl = slip_ioctl,
1270#ifdef CONFIG_COMPAT
1271 .compat_ioctl = slip_compat_ioctl,
1272#endif
1273 .receive_buf = slip_receive_buf,
1274 .write_wakeup = slip_write_wakeup,
1275};
1276
1277static int __init slip_init(void)
1278{
1279 int status;
1280
1281 if (slip_maxdev < 4)
1282 slip_maxdev = 4; /* Sanity */
1283
1284 printk(KERN_INFO "SLIP: version %s (dynamic channels, max=%d)"
1285#ifdef CONFIG_SLIP_MODE_SLIP6
1286 " (6 bit encapsulation enabled)"
1287#endif
1288 ".\n",
1289 SLIP_VERSION, slip_maxdev);
1290#if defined(SL_INCLUDE_CSLIP)
1291 printk(KERN_INFO "CSLIP: code copyright 1989 Regents of the University of California.\n");
1292#endif
1293#ifdef CONFIG_SLIP_SMART
1294 printk(KERN_INFO "SLIP linefill/keepalive option.\n");
1295#endif
1296
1297 slip_devs = kzalloc(sizeof(struct net_device *)*slip_maxdev,
1298 GFP_KERNEL);
1299 if (!slip_devs) {
1300 printk(KERN_ERR "SLIP: Can't allocate slip devices array.\n");
1301 return -ENOMEM;
1302 }
1303
1304 /* Fill in our line protocol discipline, and register it */
1305 status = tty_register_ldisc(N_SLIP, &sl_ldisc);
1306 if (status != 0) {
1307 printk(KERN_ERR "SLIP: can't register line discipline (err = %d)\n", status);
1308 kfree(slip_devs);
1309 }
1310 return status;
1311}
1312
1313static void __exit slip_exit(void)
1314{
1315 int i;
1316 struct net_device *dev;
1317 struct slip *sl;
1318 unsigned long timeout = jiffies + HZ;
1319 int busy = 0;
1320
1321 if (slip_devs == NULL)
1322 return;
1323
1324 /* First of all: check for active disciplines and hangup them.
1325 */
1326 do {
1327 if (busy)
1328 msleep_interruptible(100);
1329
1330 busy = 0;
1331 for (i = 0; i < slip_maxdev; i++) {
1332 dev = slip_devs[i];
1333 if (!dev)
1334 continue;
1335 sl = netdev_priv(dev);
1336 spin_lock_bh(&sl->lock);
1337 if (sl->tty) {
1338 busy++;
1339 tty_hangup(sl->tty);
1340 }
1341 spin_unlock_bh(&sl->lock);
1342 }
1343 } while (busy && time_before(jiffies, timeout));
1344
1345 /* FIXME: hangup is async so we should wait when doing this second
1346 phase */
1347
1348 for (i = 0; i < slip_maxdev; i++) {
1349 dev = slip_devs[i];
1350 if (!dev)
1351 continue;
1352 slip_devs[i] = NULL;
1353
1354 sl = netdev_priv(dev);
1355 if (sl->tty) {
1356 printk(KERN_ERR "%s: tty discipline still running\n",
1357 dev->name);
1358 /* Intentionally leak the control block. */
1359 dev->destructor = NULL;
1360 }
1361
1362 unregister_netdev(dev);
1363 }
1364
1365 kfree(slip_devs);
1366 slip_devs = NULL;
1367
1368 i = tty_unregister_ldisc(N_SLIP);
1369 if (i != 0)
1370 printk(KERN_ERR "SLIP: can't unregister line discipline (err = %d)\n", i);
1371}
1372
1373module_init(slip_init);
1374module_exit(slip_exit);
1375
1376#ifdef CONFIG_SLIP_SMART
1377/*
1378 * This is start of the code for multislip style line checking
1379 * added by Stanislav Voronyi. All changes before marked VSV
1380 */
1381
1382static void sl_outfill(unsigned long sls)
1383{
1384 struct slip *sl = (struct slip *)sls;
1385
1386 spin_lock(&sl->lock);
1387
1388 if (sl->tty == NULL)
1389 goto out;
1390
1391 if (sl->outfill) {
1392 if (test_bit(SLF_OUTWAIT, &sl->flags)) {
1393 /* no packets were transmitted, do outfill */
1394#ifdef CONFIG_SLIP_MODE_SLIP6
1395 unsigned char s = (sl->mode & SL_MODE_SLIP6)?0x70:END;
1396#else
1397 unsigned char s = END;
1398#endif
1399 /* put END into tty queue. Is it right ??? */
1400 if (!netif_queue_stopped(sl->dev)) {
1401 /* if device busy no outfill */
1402 sl->tty->ops->write(sl->tty, &s, 1);
1403 }
1404 } else
1405 set_bit(SLF_OUTWAIT, &sl->flags);
1406
1407 mod_timer(&sl->outfill_timer, jiffies+sl->outfill*HZ);
1408 }
1409out:
1410 spin_unlock(&sl->lock);
1411}
1412
1413static void sl_keepalive(unsigned long sls)
1414{
1415 struct slip *sl = (struct slip *)sls;
1416
1417 spin_lock(&sl->lock);
1418
1419 if (sl->tty == NULL)
1420 goto out;
1421
1422 if (sl->keepalive) {
1423 if (test_bit(SLF_KEEPTEST, &sl->flags)) {
1424 /* keepalive still high :(, we must hangup */
1425 if (sl->outfill)
1426 /* outfill timer must be deleted too */
1427 (void)del_timer(&sl->outfill_timer);
1428 printk(KERN_DEBUG "%s: no packets received during keepalive timeout, hangup.\n", sl->dev->name);
1429 /* this must hangup tty & close slip */
1430 tty_hangup(sl->tty);
1431 /* I think we need not something else */
1432 goto out;
1433 } else
1434 set_bit(SLF_KEEPTEST, &sl->flags);
1435
1436 mod_timer(&sl->keepalive_timer, jiffies+sl->keepalive*HZ);
1437 }
1438out:
1439 spin_unlock(&sl->lock);
1440}
1441
1442#endif
1443MODULE_LICENSE("GPL");
1444MODULE_ALIAS_LDISC(N_SLIP);
diff --git a/drivers/net/slip/slip.h b/drivers/net/slip/slip.h
new file mode 100644
index 00000000000..67673cf1266
--- /dev/null
+++ b/drivers/net/slip/slip.h
@@ -0,0 +1,101 @@
1/*
2 * slip.h Define the SLIP device driver interface and constants.
3 *
4 * NOTE: THIS FILE WILL BE MOVED TO THE LINUX INCLUDE DIRECTORY
5 * AS SOON AS POSSIBLE!
6 *
7 * Version: @(#)slip.h 1.2.0 03/28/93
8 *
9 * Fixes:
10 * Alan Cox : Added slip mtu field.
11 * Matt Dillon : Printable slip (borrowed from net2e)
12 * Alan Cox : Added SL_SLIP_LOTS
13 * Dmitry Gorodchanin : A lot of changes in the 'struct slip'
14 * Dmitry Gorodchanin : Added CSLIP statistics.
15 * Stanislav Voronyi : Make line checking as created by
16 * Igor Chechik, RELCOM Corp.
17 * Craig Schlenter : Fixed #define bug that caused
18 * CSLIP telnets to hang in 1.3.61-6
19 *
20 * Author: Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org>
21 */
22#ifndef _LINUX_SLIP_H
23#define _LINUX_SLIP_H
24
25
26#if defined(CONFIG_INET) && defined(CONFIG_SLIP_COMPRESSED)
27# define SL_INCLUDE_CSLIP
28#endif
29
30#ifdef SL_INCLUDE_CSLIP
31# define SL_MODE_DEFAULT SL_MODE_ADAPTIVE
32#else
33# define SL_MODE_DEFAULT SL_MODE_SLIP
34#endif
35
36/* SLIP configuration. */
37#define SL_NRUNIT 256 /* MAX number of SLIP channels;
38 This can be overridden with
39 insmod -oslip_maxdev=nnn */
40#define SL_MTU 296 /* 296; I am used to 600- FvK */
41
42/* SLIP protocol characters. */
43#define END 0300 /* indicates end of frame */
44#define ESC 0333 /* indicates byte stuffing */
45#define ESC_END 0334 /* ESC ESC_END means END 'data' */
46#define ESC_ESC 0335 /* ESC ESC_ESC means ESC 'data' */
47
48
49struct slip {
50 int magic;
51
52 /* Various fields. */
53 struct tty_struct *tty; /* ptr to TTY structure */
54 struct net_device *dev; /* easy for intr handling */
55 spinlock_t lock;
56
57#ifdef SL_INCLUDE_CSLIP
58 struct slcompress *slcomp; /* for header compression */
59 unsigned char *cbuff; /* compression buffer */
60#endif
61
62 /* These are pointers to the malloc()ed frame buffers. */
63 unsigned char *rbuff; /* receiver buffer */
64 int rcount; /* received chars counter */
65 unsigned char *xbuff; /* transmitter buffer */
66 unsigned char *xhead; /* pointer to next byte to XMIT */
67 int xleft; /* bytes left in XMIT queue */
68 int mtu; /* Our mtu (to spot changes!) */
69 int buffsize; /* Max buffers sizes */
70
71#ifdef CONFIG_SLIP_MODE_SLIP6
72 int xdata, xbits; /* 6 bit slip controls */
73#endif
74
75 unsigned long flags; /* Flag values/ mode etc */
76#define SLF_INUSE 0 /* Channel in use */
77#define SLF_ESCAPE 1 /* ESC received */
78#define SLF_ERROR 2 /* Parity, etc. error */
79#define SLF_KEEPTEST 3 /* Keepalive test flag */
80#define SLF_OUTWAIT 4 /* is outpacket was flag */
81
82 unsigned char mode; /* SLIP mode */
83 unsigned char leased;
84 pid_t pid;
85#define SL_MODE_SLIP 0
86#define SL_MODE_CSLIP 1
87#define SL_MODE_SLIP6 2 /* Matt Dillon's printable slip */
88#define SL_MODE_CSLIP6 (SL_MODE_SLIP6|SL_MODE_CSLIP)
89#define SL_MODE_AX25 4
90#define SL_MODE_ADAPTIVE 8
91#ifdef CONFIG_SLIP_SMART
92 unsigned char outfill; /* # of sec between outfill packet */
93 unsigned char keepalive; /* keepalive seconds */
94 struct timer_list outfill_timer;
95 struct timer_list keepalive_timer;
96#endif
97};
98
99#define SLIP_MAGIC 0x5302
100
101#endif /* _LINUX_SLIP.H */