1 /* $NetBSD: if_sl.c,v 1.114 2008/12/17 20:51:36 cegger Exp $ */
4 * Copyright (c) 1987, 1989, 1992, 1993
5 * The Regents of the University of California. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * @(#)if_sl.c 8.9 (Berkeley) 1/9/95
35 * Serial Line interface
38 * Center for Seismic Studies
39 * 1300 N 17th Street, Suite 1450
40 * Arlington, Virginia 22209
45 * Pounded on heavily by Chris Torek (chris@mimsy.umd.edu, umcp-cs!chris).
46 * N.B.: this belongs in netinet, not net, the way it stands now.
47 * Should have a link-layer type designation, but wouldn't be
48 * backwards-compatible.
50 * Converted to 4.3BSD Beta by Chris Torek.
51 * Other changes made at Berkeley, based in part on code by Kirk Smith.
52 * W. Jolitz added slip abort.
54 * Hacked almost beyond recognition by Van Jacobson (van@helios.ee.lbl.gov).
55 * Added priority queuing for "interactive" traffic; hooks for TCP
56 * header compression; ICMP filtering (at 2400 baud, some cretin
57 * pinging you can use up all your bandwidth). Made low clist behavior
58 * more robust and slightly less likely to hang serial line.
59 * Sped up a bunch of things.
62 #include <sys/cdefs.h>
63 __KERNEL_RCSID(0, "$NetBSD: if_sl.c,v 1.114 2008/12/17 20:51:36 cegger Exp $");
68 #include <sys/param.h>
70 #include <sys/malloc.h>
73 #include <sys/dkstat.h>
74 #include <sys/socket.h>
75 #include <sys/ioctl.h>
79 #include <sys/kernel.h>
80 #include <sys/socketvar.h>
82 #include <sys/systm.h>
83 #include <sys/kauth.h>
89 #include <net/if_types.h>
90 #include <net/netisr.h>
91 #include <net/route.h>
94 #include <netinet/in.h>
95 #include <netinet/in_systm.h>
96 #include <netinet/in_var.h>
97 #include <netinet/ip.h>
100 #include <net/slcompress.h>
101 #include <net/if_slvar.h>
102 #include <net/slip.h>
103 #include <net/ppp_defs.h>
104 #include <net/if_ppp.h>
107 #include <sys/time.h>
112 * SLMAX is a hard limit on input packet size. To simplify the code
113 * and improve performance, we require that packets fit in an mbuf
114 * cluster, and if we get a compressed packet, there's enough extra
115 * room to expand the header into a max length tcp/ip header (128
116 * bytes). So, SLMAX can be at most
119 * SLMTU is a hard limit on output packet size. To insure good
120 * interactive response, SLMTU wants to be the smallest size that
121 * amortizes the header cost. (Remember that even with
122 * type-of-service queuing, we have to wait for any in-progress
123 * packet to finish. I.e., we wait, on the average, 1/2 * mtu /
124 * cps, where cps is the line speed in characters per second.
125 * E.g., 533ms wait for a 1024 byte MTU on a 9600 baud line. The
126 * average compressed header size is 6-8 bytes so any MTU > 90
127 * bytes will give us 90% of the line bandwidth. A 100ms wait is
128 * tolerable (500ms is not), so want an MTU around 296. (Since TCP
129 * will send 256 byte segments (to allow for 40 byte headers), the
130 * typical packet size on the wire will be around 260 bytes). In
131 * 4.3tahoe+ systems, we can set an MTU in a route so we do that &
132 * leave the interface MTU relatively high (so we don't IP fragment
133 * when acting as a gateway to someone using a stupid MTU).
135 * Similar considerations apply to SLIP_HIWAT: It's the amount of
136 * data that will be queued 'downstream' of us (i.e., in clists
137 * waiting to be picked up by the tty output interrupt). If we
138 * queue a lot of data downstream, it's immune to our t.o.s. queuing.
139 * E.g., if SLIP_HIWAT is 1024, the interactive traffic in mixed
140 * telnet/ftp will see a 1 sec wait, independent of the mtu (the
141 * wait is dependent on the ftp window size but that's typically
142 * 1k - 4k). So, we want SLIP_HIWAT just big enough to amortize
143 * the cost (in idle time on the wire) of the tty driver running
144 * off the end of its clists & having to call back slstart for a
145 * new packet. For a tty interface with any buffering at all, this
146 * cost will be zero. Even with a totally brain dead interface (like
147 * the one on a typical workstation), the cost will be <= 1 character
148 * time. So, setting SLIP_HIWAT to ~100 guarantees that we'll lose
149 * at most 1% while maintaining good interactive response.
151 #define BUFOFFSET (128+sizeof(struct ifnet **)+SLIP_HDRLEN)
152 #define SLMAX (MCLBYTES - BUFOFFSET)
153 #define SLBUFSIZE (SLMAX + BUFOFFSET)
158 #error SLMTU way too small.
160 #define SLIP_HIWAT roundup(50,CBSIZE)
161 #ifndef __NetBSD__ /* XXX - cgd */
162 #define CLISTRESERVE 1024 /* Can't let clists get too low */
163 #endif /* !__NetBSD__ */
166 * SLIP ABORT ESCAPE MECHANISM:
167 * (inspired by HAYES modem escape arrangement)
168 * 1sec escape 1sec escape 1sec escape { 1sec escape 1sec escape }
169 * within window time signals a "soft" exit from slip mode by remote end
170 * if the IFF_DEBUG flag is on.
172 #define ABT_ESC '\033' /* can't be t_intr - distant host must know it*/
173 #define ABT_IDLE 1 /* in seconds - idle before an escape */
174 #define ABT_COUNT 3 /* count of escapes for abort */
175 #define ABT_WINDOW (ABT_COUNT*2+2) /* in seconds - time to count */
177 static int sl_clone_create(struct if_clone
*, int);
178 static int sl_clone_destroy(struct ifnet
*);
180 static LIST_HEAD(, sl_softc
) sl_softc_list
;
182 struct if_clone sl_cloner
=
183 IF_CLONE_INITIALIZER("sl", sl_clone_create
, sl_clone_destroy
);
185 #define FRAME_END 0xc0 /* Frame End */
186 #define FRAME_ESCAPE 0xdb /* Frame Esc */
187 #define TRANS_FRAME_END 0xdc /* transposed frame end */
188 #define TRANS_FRAME_ESCAPE 0xdd /* transposed frame esc */
190 static void slintr(void *);
192 static int slinit(struct sl_softc
*);
193 static struct mbuf
*sl_btom(struct sl_softc
*, int);
195 static int slclose(struct tty
*, int);
196 static int slinput(int, struct tty
*);
197 static int slioctl(struct ifnet
*, u_long
, void *);
198 static int slopen(dev_t
, struct tty
*);
199 static int sloutput(struct ifnet
*, struct mbuf
*, const struct sockaddr
*,
201 static int slstart(struct tty
*);
202 static int sltioctl(struct tty
*, u_long
, void *, int, struct lwp
*);
204 static struct linesw slip_disc
= {
213 .l_modem
= nullmodem
,
223 if (ttyldisc_attach(&slip_disc
) != 0)
225 LIST_INIT(&sl_softc_list
);
226 if_clone_attach(&sl_cloner
);
230 sl_clone_create(struct if_clone
*ifc
, int unit
)
234 sc
= malloc(sizeof(*sc
), M_DEVBUF
, M_WAIT
|M_ZERO
);
236 if_initname(&sc
->sc_if
, ifc
->ifc_name
, unit
);
237 sc
->sc_if
.if_softc
= sc
;
238 sc
->sc_if
.if_mtu
= SLMTU
;
239 sc
->sc_if
.if_flags
= IFF_POINTOPOINT
| SC_AUTOCOMP
| IFF_MULTICAST
;
240 sc
->sc_if
.if_type
= IFT_SLIP
;
241 sc
->sc_if
.if_ioctl
= slioctl
;
242 sc
->sc_if
.if_output
= sloutput
;
243 sc
->sc_if
.if_dlt
= DLT_SLIP
;
244 sc
->sc_fastq
.ifq_maxlen
= 32;
245 IFQ_SET_READY(&sc
->sc_if
.if_snd
);
246 if_attach(&sc
->sc_if
);
247 if_alloc_sadl(&sc
->sc_if
);
249 bpfattach(&sc
->sc_if
, DLT_SLIP
, SLIP_HDRLEN
);
251 LIST_INSERT_HEAD(&sl_softc_list
, sc
, sc_iflist
);
256 sl_clone_destroy(struct ifnet
*ifp
)
258 struct sl_softc
*sc
= (struct sl_softc
*)ifp
->if_softc
;
260 if (sc
->sc_ttyp
!= NULL
)
261 return EBUSY
; /* Not removing it */
263 LIST_REMOVE(sc
, sc_iflist
);
275 slinit(struct sl_softc
*sc
)
278 if (sc
->sc_mbuf
== NULL
) {
279 sc
->sc_mbuf
= m_gethdr(M_WAIT
, MT_DATA
);
280 m_clget(sc
->sc_mbuf
, M_WAIT
);
282 sc
->sc_ep
= (u_char
*)sc
->sc_mbuf
->m_ext
.ext_buf
+
283 sc
->sc_mbuf
->m_ext
.ext_size
;
284 sc
->sc_mp
= sc
->sc_pktstart
= (u_char
*)sc
->sc_mbuf
->m_ext
.ext_buf
+
288 sl_compress_init(&sc
->sc_comp
);
295 * Line specific open routine.
296 * Attach the given tty to the first available sl unit.
300 slopen(dev_t dev
, struct tty
*tp
)
302 struct lwp
*l
= curlwp
; /* XXX */
306 error
= kauth_authorize_network(l
->l_cred
, KAUTH_NETWORK_INTERFACE_SLIP
,
307 KAUTH_REQ_NETWORK_INTERFACE_SLIP_ADD
, NULL
, NULL
, NULL
);
311 if (tp
->t_linesw
== &slip_disc
)
314 LIST_FOREACH(sc
, &sl_softc_list
, sc_iflist
)
315 if (sc
->sc_ttyp
== NULL
) {
316 sc
->sc_si
= softint_establish(SOFTINT_NET
,
318 if (sc
->sc_si
== NULL
)
320 if (slinit(sc
) == 0) {
321 softint_disestablish(sc
->sc_si
);
324 tp
->t_sc
= (void *)sc
;
326 sc
->sc_if
.if_baudrate
= tp
->t_ospeed
;
327 mutex_spin_enter(&tty_lock
);
328 tp
->t_state
|= TS_ISOPEN
| TS_XCLUDE
;
329 ttyflush(tp
, FREAD
| FWRITE
);
331 * make sure tty output queue is large enough
332 * to hold a full-sized packet (including frame
333 * end, and a possible extra frame end). full-sized
334 * packet occupies a max of 2*SLMAX bytes (because
335 * of possible escapes), and add two on for frame
338 if (tp
->t_outq
.c_cn
< 2 * SLMAX
+ 2) {
339 sc
->sc_oldbufsize
= tp
->t_outq
.c_cn
;
340 sc
->sc_oldbufquot
= tp
->t_outq
.c_cq
!= 0;
343 mutex_spin_exit(&tty_lock
);
344 error
= clalloc(&tp
->t_outq
, 2 * SLMAX
+ 2, 0);
346 softint_disestablish(sc
->sc_si
);
348 * clalloc() might return -1 which
349 * is no good, so we need to return
352 return ENOMEM
; /* XXX ?! */
355 sc
->sc_oldbufsize
= sc
->sc_oldbufquot
= 0;
356 mutex_spin_exit(&tty_lock
);
364 * Line specific close routine.
365 * Detach the tty from the sl unit.
368 slclose(struct tty
*tp
, int flag
)
377 softint_disestablish(sc
->sc_si
);
380 IF_PURGE(&sc
->sc_fastq
);
384 ttyldisc_release(tp
->t_linesw
);
385 tp
->t_linesw
= ttyldisc_default();
391 m_freem(sc
->sc_mbuf
);
393 sc
->sc_ep
= sc
->sc_mp
= sc
->sc_pktstart
= NULL
;
394 IF_PURGE(&sc
->sc_inq
);
397 * If necessary, install a new outq buffer of the
400 if (sc
->sc_oldbufsize
!= 0) {
402 clalloc(&tp
->t_outq
, sc
->sc_oldbufsize
,
412 * Line specific (tty) ioctl routine.
413 * Provide a way to get the sl unit number.
417 sltioctl(struct tty
*tp
, u_long cmd
, void *data
, int flag
,
420 struct sl_softc
*sc
= (struct sl_softc
*)tp
->t_sc
;
424 *(int *)data
= sc
->sc_unit
; /* XXX */
434 * Queue a packet. Start transmission if not active.
435 * Compression happens in slintr(); if we do it here, IP TOS
436 * will cause us to not compress "background" packets, because
437 * ordering gets trashed. It can be done for all packets in slintr().
440 sloutput(struct ifnet
*ifp
, struct mbuf
*m
, const struct sockaddr
*dst
,
443 struct sl_softc
*sc
= ifp
->if_softc
;
445 struct ifqueue
*ifq
= NULL
;
447 ALTQ_DECL(struct altq_pktattr pktattr
;)
449 IFQ_CLASSIFY(&ifp
->if_snd
, m
, dst
->sa_family
, &pktattr
);
452 * `Cannot happen' (see slioctl). Someday we will extend
453 * the line protocol to support other address families.
455 if (dst
->sa_family
!= AF_INET
) {
456 printf("%s: af%d not supported\n", sc
->sc_if
.if_xname
,
459 sc
->sc_if
.if_noproto
++;
463 if (sc
->sc_ttyp
== NULL
) {
465 return ENETDOWN
; /* sort of */
467 if ((sc
->sc_ttyp
->t_state
& TS_CARR_ON
) == 0 &&
468 (sc
->sc_ttyp
->t_cflag
& CLOCAL
) == 0) {
470 printf("%s: no carrier and not local\n", sc
->sc_if
.if_xname
);
473 ip
= mtod(m
, struct ip
*);
475 if (sc
->sc_if
.if_flags
& SC_NOICMP
&& ip
->ip_p
== IPPROTO_ICMP
) {
477 return ENETRESET
; /* XXX ? */
482 if (sc
->sc_oqlen
&& sc
->sc_ttyp
->t_outq
.c_cc
== sc
->sc_oqlen
) {
485 /* if output's been stalled for too long, and restart */
487 bintime_sub(&bt
, &sc
->sc_lastpacket
);
490 slstart(sc
->sc_ttyp
);
497 if ((ip
->ip_tos
& IPTOS_LOWDELAY
) != 0)
500 if ((error
= ifq_enqueue2(ifp
, ifq
, m ALTQ_COMMA
501 ALTQ_DECL(&pktattr
))) != 0) {
505 getbinuptime(&sc
->sc_lastpacket
);
509 if ((sc
->sc_oqlen
= sc
->sc_ttyp
->t_outq
.c_cc
) == 0)
510 slstart(sc
->sc_ttyp
);
517 * Start output on interface. Get another datagram
518 * to send from the interface queue and map it to
519 * the interface before starting output.
522 slstart(struct tty
*tp
)
524 struct sl_softc
*sc
= tp
->t_sc
;
527 * If there is more in the output queue, just send it now.
528 * We are being called in lieu of ttstart and must do what
531 if (tp
->t_outq
.c_cc
!= 0) {
533 if (tp
->t_outq
.c_cc
> SLIP_HIWAT
)
538 * This happens briefly when the line shuts down.
542 softint_schedule(sc
->sc_si
);
547 * Copy data buffer to mbuf chain; add ifnet pointer.
550 sl_btom(struct sl_softc
*sc
, int len
)
555 * Allocate a new input buffer and swap.
558 MGETHDR(sc
->sc_mbuf
, M_DONTWAIT
, MT_DATA
);
559 if (sc
->sc_mbuf
== NULL
) {
563 MCLGET(sc
->sc_mbuf
, M_DONTWAIT
);
564 if ((sc
->sc_mbuf
->m_flags
& M_EXT
) == 0) {
565 m_freem(sc
->sc_mbuf
);
569 sc
->sc_ep
= (u_char
*)sc
->sc_mbuf
->m_ext
.ext_buf
+
570 sc
->sc_mbuf
->m_ext
.ext_size
;
572 m
->m_data
= sc
->sc_pktstart
;
574 m
->m_pkthdr
.len
= m
->m_len
= len
;
575 m
->m_pkthdr
.rcvif
= &sc
->sc_if
;
580 * tty interface receiver interrupt.
583 slinput(int c
, struct tty
*tp
)
590 sc
= (struct sl_softc
*)tp
->t_sc
;
593 if ((c
& TTY_ERRORMASK
) || ((tp
->t_state
& TS_CARR_ON
) == 0 &&
594 (tp
->t_cflag
& CLOCAL
) == 0)) {
595 sc
->sc_flags
|= SC_ERROR
;
600 ++sc
->sc_if
.if_ibytes
;
602 if (sc
->sc_if
.if_flags
& IFF_DEBUG
) {
605 * If we have a previous abort, see whether
606 * this one is within the time limit.
608 if (sc
->sc_abortcount
&&
609 time_second
>= sc
->sc_starttime
+ ABT_WINDOW
)
610 sc
->sc_abortcount
= 0;
612 * If we see an abort after "idle" time, count it;
613 * record when the first abort escape arrived.
615 if (time_second
>= sc
->sc_lasttime
+ ABT_IDLE
) {
616 if (++sc
->sc_abortcount
== 1)
617 sc
->sc_starttime
= time_second
;
618 if (sc
->sc_abortcount
>= ABT_COUNT
) {
624 sc
->sc_abortcount
= 0;
625 sc
->sc_lasttime
= time_second
;
630 case TRANS_FRAME_ESCAPE
:
635 case TRANS_FRAME_END
:
645 if (sc
->sc_flags
& SC_ERROR
) {
646 sc
->sc_flags
&= ~SC_ERROR
;
649 len
= sc
->sc_mp
- sc
->sc_pktstart
;
651 /* less than min length packet - ignore */
654 m
= sl_btom(sc
, len
);
658 IF_ENQUEUE(&sc
->sc_inq
, m
);
659 softint_schedule(sc
->sc_si
);
662 if (sc
->sc_mp
< sc
->sc_ep
) {
668 /* can't put lower; would miss an extra frame */
669 sc
->sc_flags
|= SC_ERROR
;
672 sc
->sc_if
.if_ierrors
++;
674 sc
->sc_mp
= sc
->sc_pktstart
= (u_char
*)sc
->sc_mbuf
->m_ext
.ext_buf
+
684 struct sl_softc
*sc
= arg
;
685 struct tty
*tp
= sc
->sc_ttyp
;
693 u_char chdr
[CHDR_LEN
];
699 * Output processing loop.
701 mutex_enter(softnet_lock
);
712 * Do not remove the packet from the queue if it
713 * doesn't look like it will fit into the current
714 * serial output queue. With a packet full of
715 * escapes, this could be as bad as MTU*2+2.
718 if (tp
->t_outq
.c_cn
- tp
->t_outq
.c_cc
<
719 2 * sc
->sc_if
.if_mtu
+ 2) {
726 * Get a packet and send it to the interface.
729 IF_DEQUEUE(&sc
->sc_fastq
, m
);
731 sc
->sc_if
.if_omcasts
++; /* XXX */
733 IFQ_DEQUEUE(&sc
->sc_if
.if_snd
, m
);
740 * We do the header compression here rather than in
741 * sloutput() because the packets will be out of order
742 * if we are using TOS queueing, and the connection
743 * ID compression will get munged when this happens.
746 if (sc
->sc_if
.if_bpf
) {
748 * We need to save the TCP/IP header before
749 * it's compressed. To avoid complicated
750 * code, we just make a deep copy of the
751 * entire packet (since this is a serial
752 * line, packets should be short and/or the
753 * copy should be negligible cost compared
754 * to the packet transmission time).
756 bpf_m
= m_dup(m
, 0, M_COPYALL
, M_DONTWAIT
);
761 if ((ip
= mtod(m
, struct ip
*))->ip_p
== IPPROTO_TCP
) {
762 if (sc
->sc_if
.if_flags
& SC_COMPRESS
)
763 *mtod(m
, u_char
*) |=
764 sl_compress_tcp(m
, ip
, &sc
->sc_comp
, 1);
768 if (sc
->sc_if
.if_bpf
&& bpf_m
!= NULL
)
769 bpf_mtap_sl_out(sc
->sc_if
.if_bpf
, mtod(m
, u_char
*),
772 getbinuptime(&sc
->sc_lastpacket
);
777 * The extra FRAME_END will start up a new packet,
778 * and thus will flush any accumulated garbage. We
779 * do this whenever the line may have been idle for
782 if (tp
->t_outq
.c_cc
== 0) {
783 sc
->sc_if
.if_obytes
++;
784 (void)putc(FRAME_END
, &tp
->t_outq
);
788 u_char
*bp
, *cp
, *ep
;
790 bp
= cp
= mtod(m
, u_char
*);
794 * Find out how many bytes in the
795 * string we can handle without
796 * doing something special.
809 * Put N characters at once
810 * into the tty output queue.
812 if (b_to_q(bp
, cp
- bp
, &tp
->t_outq
))
814 sc
->sc_if
.if_obytes
+= cp
- bp
;
817 * If there are characters left in
818 * the mbuf, the first one must be
819 * special.. Put it out in a different
823 if (putc(FRAME_ESCAPE
, &tp
->t_outq
))
825 if (putc(*cp
++ == FRAME_ESCAPE
?
829 (void)unputc(&tp
->t_outq
);
832 sc
->sc_if
.if_obytes
+= 2;
840 if (putc(FRAME_END
, &tp
->t_outq
)) {
842 * Not enough room. Remove a char to make
843 * room and end the packet normally. If
844 * you get many collisions (more than one
845 * or two a day), you probably do not have
846 * enough clists and you should increase
847 * "nclist" in param.c
849 (void)unputc(&tp
->t_outq
);
850 (void)putc(FRAME_END
, &tp
->t_outq
);
851 sc
->sc_if
.if_collisions
++;
853 sc
->sc_if
.if_obytes
++;
854 sc
->sc_if
.if_opackets
++;
858 * We now have characters in the output queue,
859 * kick the serial port.
866 * Input processing loop.
870 IF_DEQUEUE(&sc
->sc_inq
, m
);
874 pktstart
= mtod(m
, u_char
*);
875 len
= m
->m_pkthdr
.len
;
877 if (sc
->sc_if
.if_bpf
) {
879 * Save the compressed header, so we
880 * can tack it on later. Note that we
881 * will end up copying garbage in some
882 * cases but this is okay. We remember
883 * where the buffer started so we can
884 * compute the new header length.
886 memcpy(chdr
, pktstart
, CHDR_LEN
);
888 #endif /* NBPFILTER > 0 */
890 if ((c
= (*pktstart
& 0xf0)) != (IPVERSION
<< 4)) {
892 c
= TYPE_COMPRESSED_TCP
;
893 else if (c
== TYPE_UNCOMPRESSED_TCP
)
894 *pktstart
&= 0x4f; /* XXX */
896 * We've got something that's not an IP
897 * packet. If compression is enabled,
898 * try to decompress it. Otherwise, if
899 * `auto-enable' compression is on and
900 * it's a reasonable packet, decompress
901 * it and then enable compression.
902 * Otherwise, drop it.
904 if (sc
->sc_if
.if_flags
& SC_COMPRESS
) {
905 len
= sl_uncompress_tcp(&pktstart
, len
,
906 (u_int
)c
, &sc
->sc_comp
);
911 } else if ((sc
->sc_if
.if_flags
& SC_AUTOCOMP
) &&
912 c
== TYPE_UNCOMPRESSED_TCP
&& len
>= 40) {
913 len
= sl_uncompress_tcp(&pktstart
, len
,
914 (u_int
)c
, &sc
->sc_comp
);
919 sc
->sc_if
.if_flags
|= SC_COMPRESS
;
926 m
->m_data
= (void *) pktstart
;
927 m
->m_pkthdr
.len
= m
->m_len
= len
;
929 if (sc
->sc_if
.if_bpf
) {
930 bpf_mtap_sl_in(sc
->sc_if
.if_bpf
, chdr
, &m
);
934 #endif /* NBPFILTER > 0 */
936 * If the packet will fit into a single
937 * header mbuf, copy it into one, to save
940 if (m
->m_pkthdr
.len
< MHLEN
) {
944 MGETHDR(n
, M_DONTWAIT
, MT_DATA
);
945 pktlen
= m
->m_pkthdr
.len
;
947 memcpy(mtod(n
, void *), mtod(m
, void *), pktlen
);
953 sc
->sc_if
.if_ipackets
++;
954 getbinuptime(&sc
->sc_lastpacket
);
958 if (IF_QFULL(&ipintrq
)) {
960 sc
->sc_if
.if_ierrors
++;
961 sc
->sc_if
.if_iqdrops
++;
964 IF_ENQUEUE(&ipintrq
, m
);
965 schednetisr(NETISR_IP
);
970 mutex_exit(softnet_lock
);
974 * Process an ioctl request.
977 slioctl(struct ifnet
*ifp
, u_long cmd
, void *data
)
979 struct ifaddr
*ifa
= (struct ifaddr
*)data
;
980 struct ifreq
*ifr
= (struct ifreq
*)data
;
981 int s
= splnet(), error
= 0;
982 struct sl_softc
*sc
= ifp
->if_softc
;
983 struct ppp_stats
*psp
;
984 struct ppp_comp_stats
*pcp
;
989 if (ifa
->ifa_addr
->sa_family
== AF_INET
)
990 ifp
->if_flags
|= IFF_UP
;
992 error
= EAFNOSUPPORT
;
996 if (ifa
->ifa_addr
->sa_family
!= AF_INET
)
997 error
= EAFNOSUPPORT
;
1001 if ((ifr
->ifr_mtu
< 3) || (ifr
->ifr_mtu
> SLMAX
)) {
1007 if ((error
= ifioctl_common(&sc
->sc_if
, cmd
, data
)) == ENETRESET
)
1014 error
= EAFNOSUPPORT
; /* XXX */
1017 switch (ifreq_getaddr(cmd
, ifr
)->sa_family
) {
1025 error
= EAFNOSUPPORT
;
1031 psp
= &((struct ifpppstatsreq
*) data
)->stats
;
1032 (void)memset(psp
, 0, sizeof(*psp
));
1033 psp
->p
.ppp_ibytes
= sc
->sc_if
.if_ibytes
;
1034 psp
->p
.ppp_ipackets
= sc
->sc_if
.if_ipackets
;
1035 psp
->p
.ppp_ierrors
= sc
->sc_if
.if_ierrors
;
1036 psp
->p
.ppp_obytes
= sc
->sc_if
.if_obytes
;
1037 psp
->p
.ppp_opackets
= sc
->sc_if
.if_opackets
;
1038 psp
->p
.ppp_oerrors
= sc
->sc_if
.if_oerrors
;
1040 psp
->vj
.vjs_packets
= sc
->sc_comp
.sls_packets
;
1041 psp
->vj
.vjs_compressed
= sc
->sc_comp
.sls_compressed
;
1042 psp
->vj
.vjs_searches
= sc
->sc_comp
.sls_searches
;
1043 psp
->vj
.vjs_misses
= sc
->sc_comp
.sls_misses
;
1044 psp
->vj
.vjs_uncompressedin
= sc
->sc_comp
.sls_uncompressedin
;
1045 psp
->vj
.vjs_compressedin
= sc
->sc_comp
.sls_compressedin
;
1046 psp
->vj
.vjs_errorin
= sc
->sc_comp
.sls_errorin
;
1047 psp
->vj
.vjs_tossed
= sc
->sc_comp
.sls_tossed
;
1051 case SIOCGPPPCSTATS
:
1052 pcp
= &((struct ifpppcstatsreq
*) data
)->stats
;
1053 (void)memset(pcp
, 0, sizeof(*pcp
));
1057 error
= ifioctl_common(ifp
, cmd
, data
);