1 /* $Id: isdn_ppp.c,v 1.33 1998/02/20 17:11:54 fritz Exp $
3 * Linux ISDN subsystem, functions for synchronous PPP (linklevel).
5 * Copyright 1995,96 by Michael Hipp (Michael.Hipp@student.uni-tuebingen.de)
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2, or (at your option)
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 * Note: This file differs from the corresponding revision as present in the
22 * isdn4linux CVS repository because some later bug fixes have been extracted
23 * from the repository and merged into this file. -- Henner Eisen
25 * $Log: isdn_ppp.c,v $
26 * Revision 1.33 1998/02/20 17:11:54 fritz
27 * Changes for recent kernels.
29 * Revision 1.32 1998/01/31 19:29:55 calle
30 * Merged changes from and for 2.1.82, not tested only compiled ...
32 * Revision 1.31 1997/10/09 21:29:01 fritz
33 * New HL<->LL interface:
34 * New BSENT callback with nr. of bytes included.
35 * Sending without ACK.
36 * New L1 error status (not yet in use).
37 * Cleaned up obsolete structures.
38 * Implemented Cisco-SLARP.
39 * Changed local net-interface data to be dynamically allocated.
40 * Removed old 2.0 compatibility stuff.
42 * Revision 1.30 1997/10/01 09:20:38 fritz
43 * Removed old compatibility stuff for 2.0.X kernels.
44 * From now on, this code is for 2.1.X ONLY!
45 * Old stuff is still in the separate branch.
47 * Revision 1.29 1997/08/21 23:11:44 fritz
48 * Added changes for kernels >= 2.1.45
50 * Revision 1.28 1997/06/17 13:05:57 hipp
51 * Applied Eric's underflow-patches (slightly modified)
52 * more compression changes (but disabled at the moment)
53 * changed one copy_to_user() to run with enabled IRQs
55 * changed 'proto' handling in the isdn_ppp receive code
57 * Revision 1.27 1997/03/30 16:51:17 calle
58 * changed calls to copy_from_user/copy_to_user and removed verify_area
61 * Revision 1.26 1997/02/23 16:53:44 hipp
63 * some initial changes for future PPP compresion
64 * added AC,PC compression for outgoing frames
66 * Revision 1.25 1997/02/12 20:37:35 hipp
67 * New ioctl() PPPIOCGCALLINFO, minor cleanup
69 * Revision 1.24 1997/02/11 18:32:56 fritz
70 * Bugfix in isdn_ppp_free_mpqueue().
72 * Revision 1.23 1997/02/10 11:12:19 fritz
73 * More changes for Kernel 2.1.X compatibility.
75 * Revision 1.22 1997/02/06 15:03:51 hipp
76 * changed GFP_KERNEL kmalloc to GFP_ATOMIC in isdn_ppp_fill_mpqueue()
78 * Revision 1.21 1997/02/03 23:29:38 fritz
79 * Reformatted according CodingStyle
80 * Bugfix: removed isdn_ppp_skb_destructor, used by upper layers.
81 * Misc changes for Kernel 2.1.X compatibility.
83 * Revision 1.20 1996/10/30 12:21:58 fritz
84 * Cosmetic fix: Compiler warning when compiling without MPP.
86 * Revision 1.19 1996/10/25 19:03:21 hipp
87 * changed/added some defines to (re)allow compilation without MP/VJ
89 * Revision 1.18 1996/10/22 23:14:00 fritz
90 * Changes for compatibility to 2.0.X and 2.1.X kernels.
92 * Revision 1.17 1996/10/22 09:39:49 hipp
93 * a few MP changes and bugfixes
95 * Revision 1.16 1996/09/23 01:58:10 fritz
96 * Fix: With syncPPP encapsulation, discard LCP packets
97 * when calculating hangup timeout.
99 * Revision 1.15 1996/09/07 12:50:12 hipp
100 * bugfixes (unknown device after failed dial attempt, minor bugs)
102 * Revision 1.14 1996/08/12 16:26:47 hipp
104 * changed connection management from minors to slots
106 * Revision 1.13 1996/07/01 19:47:24 hipp
107 * Fixed memory leak in VJ handling and more VJ changes
109 * Revision 1.12 1996/06/24 17:42:03 fritz
112 * Revision 1.11 1996/06/16 17:46:05 tsbogend
113 * changed unsigned long to u32 to make Alpha people happy
115 * Revision 1.10 1996/06/11 14:50:29 hipp
116 * Lot of changes and bugfixes.
117 * New scheme to resend packets to busy LL devices.
119 * Revision 1.9 1996/05/18 01:37:01 fritz
120 * Added spelling corrections and some minor changes
121 * to stay in sync with kernel.
123 * Revision 1.8 1996/05/06 11:34:55 hipp
126 * Revision 1.7 1996/04/30 11:07:42 fritz
127 * Added Michael's ippp-bind patch.
129 * Revision 1.6 1996/04/30 09:33:09 fritz
130 * Removed compatibility-macros.
132 * Revision 1.5 1996/04/20 16:32:32 fritz
133 * Changed ippp_table to an array of pointers, allocating each part
136 * Revision 1.4 1996/02/19 15:25:50 fritz
137 * Bugfix: Sync-PPP packets got compressed twice, when resent due to
138 * send-queue-full reject.
140 * Revision 1.3 1996/02/11 02:27:12 fritz
141 * Lot of Bugfixes my Michael.
142 * Moved calls to skb_push() into isdn_net_header()
143 * Fixed a possible race-condition in isdn_ppp_timer_timeout().
145 * Revision 1.2 1996/01/22 05:08:06 fritz
146 * Merged in Michael's patches for MP.
147 * Minor changes in isdn_ppp_xmit.
149 * Revision 1.1 1996/01/09 04:11:29 fritz
154 /* TODO: right tbusy handling when using MP */
157 * experimental for dynamic addressing: readdress IP frames
159 #undef ISDN_SYNCPPP_READDRESS
161 #include <linux/config.h>
162 #define __NO_VERSION__
163 #include <linux/module.h>
164 #include <linux/version.h>
165 #include <linux/isdn.h>
166 #include <linux/poll.h>
167 #include "isdn_common.h"
168 #include "isdn_ppp.h"
169 #include "isdn_net.h"
172 #define PPP_IPX 0x002b
175 /* set this if you use dynamic addressing */
178 static int isdn_ppp_fill_rq(unsigned char *buf
, int len
, int proto
, int slot
);
179 static int isdn_ppp_closewait(int slot
);
180 static void isdn_ppp_push_higher(isdn_net_dev
* net_dev
, isdn_net_local
* lp
,
181 struct sk_buff
*skb
, int proto
);
182 static int isdn_ppp_if_get_unit(char *namebuf
);
183 static int isdn_ppp_set_compressor(struct ippp_struct
*is
,int num
);
184 static struct sk_buff
*isdn_ppp_decompress(struct sk_buff
*,
185 struct ippp_struct
*,struct ippp_struct
*);
186 static void isdn_ppp_receive_ccp(isdn_net_dev
* net_dev
, isdn_net_local
* lp
,
187 struct sk_buff
*skb
);
188 static struct sk_buff
*isdn_ppp_compress(struct sk_buff
*skb_in
,int *proto
,
189 struct ippp_struct
*is
,struct ippp_struct
*master
,int type
);
191 #ifdef CONFIG_ISDN_MPP
192 static int isdn_ppp_bundle(struct ippp_struct
*, int unit
);
193 static void isdn_ppp_mask_queue(isdn_net_dev
* dev
, long mask
);
194 static void isdn_ppp_cleanup_mpqueue(isdn_net_dev
* dev
, long min
);
195 static void isdn_ppp_cleanup_sqqueue(isdn_net_dev
* dev
, isdn_net_local
*, long min
);
196 static void isdn_ppp_free_sqqueue(isdn_net_dev
*);
197 static int isdn_ppp_fill_mpqueue(isdn_net_dev
*, struct sk_buff
**skb
,
198 int BEbyte
, long *sqno
, int min_sqno
);
199 static void isdn_ppp_free_mpqueue(isdn_net_dev
*);
202 char *isdn_ppp_revision
= "$Revision: 1.33 $";
204 static struct ippp_struct
*ippp_table
[ISDN_MAX_CHANNELS
];
205 static struct isdn_ppp_compressor
*ipc_head
= NULL
;
207 extern int isdn_net_force_dial_lp(isdn_net_local
*);
213 isdn_ppp_frame_log(char *info
, char *data
, int len
, int maxlen
)
223 for (i
= 0, cnt
= 0; cnt
< maxlen
; i
++) {
224 for (j
= 0; j
< 16 && cnt
< maxlen
; j
++, cnt
++)
225 sprintf(buf
+ j
* 3, "%02x ", (unsigned char) data
[cnt
]);
226 printk(KERN_DEBUG
"%s[%d]: %s\n", info
, i
, buf
);
231 * unbind isdn_net_local <=> ippp-device
232 * note: it can happen, that we hangup/free the master before the slaves
235 isdn_ppp_free(isdn_net_local
* lp
)
237 #ifdef CONFIG_ISDN_MPP
238 isdn_net_local
*master_lp
= lp
;
241 struct ippp_struct
*is
;
243 if (lp
->ppp_slot
< 0 || lp
->ppp_slot
> ISDN_MAX_CHANNELS
)
246 is
= ippp_table
[lp
->ppp_slot
];
250 #ifdef CONFIG_ISDN_MPP
252 master_lp
= (isdn_net_local
*) lp
->master
->priv
;
254 lp
->last
->next
= lp
->next
;
255 lp
->next
->last
= lp
->last
;
256 if (master_lp
->netdev
->queue
== lp
) {
257 master_lp
->netdev
->queue
= lp
->next
;
258 if (lp
->next
== lp
) { /* last link in queue? */
259 master_lp
->netdev
->ib
.bundled
= 0;
260 isdn_ppp_free_mpqueue(master_lp
->netdev
);
261 isdn_ppp_free_sqqueue(master_lp
->netdev
);
264 lp
->next
= lp
->last
= lp
; /* (re)set own pointers */
267 if ((is
->state
& IPPP_CONNECT
))
268 isdn_ppp_closewait(lp
->ppp_slot
); /* force wakeup on ippp device */
269 else if (is
->state
& IPPP_ASSIGNED
)
270 is
->state
= IPPP_OPEN
; /* fallback to 'OPEN but not ASSIGEND' staet */
274 printk(KERN_DEBUG
"isdn_ppp_free %d %lx %lx\n", lp
->ppp_slot
, (long) lp
, (long) is
->lp
);
276 is
->lp
= NULL
; /* link is down .. set lp to NULL */
277 #ifdef ISDN_SYNCPPP_READDRESS
278 is
->old_pa_addr
= 0x0;
279 is
->old_pa_dstaddr
= 0x0;
281 lp
->ppp_slot
= -1; /* is this OK ?? */
282 restore_flags(flags
);
288 * bind isdn_net_local <=> ippp-device
291 isdn_ppp_bind(isdn_net_local
* lp
)
296 struct ippp_struct
*is
;
298 if (lp
->p_encap
!= ISDN_NET_ENCAP_SYNCPPP
)
304 if (lp
->pppbind
< 0) { /* device bounded to ippp device ? */
305 isdn_net_dev
*net_dev
= dev
->netdev
;
306 char exclusive
[ISDN_MAX_CHANNELS
]; /* exclusive flags */
307 memset(exclusive
, 0, ISDN_MAX_CHANNELS
);
308 while (net_dev
) { /* step through net devices to find exclusive minors */
309 isdn_net_local
*lp
= net_dev
->local
;
310 if (lp
->pppbind
>= 0)
311 exclusive
[lp
->pppbind
] = 1;
312 net_dev
= net_dev
->next
;
315 * search a free device / slot
317 for (i
= 0; i
< ISDN_MAX_CHANNELS
; i
++) {
318 if (ippp_table
[i
]->state
== IPPP_OPEN
&& !exclusive
[ippp_table
[i
]->minor
]) { /* OPEN, but not connected! */
323 for (i
= 0; i
< ISDN_MAX_CHANNELS
; i
++)
324 if (ippp_table
[i
]->minor
== lp
->pppbind
&& ippp_table
[i
]->state
== IPPP_OPEN
)
328 if (i
>= ISDN_MAX_CHANNELS
) {
329 restore_flags(flags
);
330 printk(KERN_WARNING
"isdn_ppp_bind: Can't find usable ippp device.\n");
333 unit
= isdn_ppp_if_get_unit(lp
->name
); /* get unit number from interface name .. ugly! */
335 printk(KERN_ERR
"isdn_ppp_bind: illegal interface name %s.\n", lp
->name
);
342 is
->state
= IPPP_OPEN
| IPPP_ASSIGNED
; /* assigned to a netdevice but not connected */
344 restore_flags(flags
);
350 * kick the ipppd on the device
351 * (wakes up daemon after B-channel connect)
355 isdn_ppp_wakeup_daemon(isdn_net_local
* lp
)
357 if (lp
->ppp_slot
< 0 || lp
->ppp_slot
>= ISDN_MAX_CHANNELS
)
360 ippp_table
[lp
->ppp_slot
]->state
= IPPP_OPEN
| IPPP_CONNECT
| IPPP_NOBLOCK
;
362 if (ippp_table
[lp
->ppp_slot
]->wq
)
363 wake_up_interruptible(&ippp_table
[lp
->ppp_slot
]->wq
);
367 * there was a hangup on the netdevice
368 * force wakeup of the ippp device
369 * go into 'device waits for release' state
372 isdn_ppp_closewait(int slot
)
374 struct ippp_struct
*is
;
376 if (slot
< 0 || slot
>= ISDN_MAX_CHANNELS
)
378 is
= ippp_table
[slot
];
380 if (is
->state
&& is
->wq
)
381 wake_up_interruptible(&is
->wq
);
383 is
->state
= IPPP_CLOSEWAIT
;
388 * isdn_ppp_find_slot / isdn_ppp_free_slot
392 isdn_ppp_get_slot(void)
395 for (i
= 0; i
< ISDN_MAX_CHANNELS
; i
++) {
396 if (!ippp_table
[i
]->state
)
407 isdn_ppp_open(int min
, struct file
*file
)
410 struct ippp_struct
*is
;
412 if (min
< 0 || min
> ISDN_MAX_CHANNELS
)
415 slot
= isdn_ppp_get_slot();
419 is
= file
->private_data
= ippp_table
[slot
];
422 printk(KERN_DEBUG
"ippp, open, slot: %d, minor: %d, state: %04x\n", slot
, min
, is
->state
);
424 /* compression stuff */
425 is
->compressor
= NULL
;
426 is
->decomp_stat
= is
->comp_stat
= NULL
;
427 is
->link_compressor
= NULL
;
428 is
->link_decomp_stat
= is
->link_comp_stat
= NULL
;
431 is
->mp_seqno
= 0; /* MP sequence number */
432 is
->pppcfg
= 0; /* ppp configuration */
433 is
->mpppcfg
= 0; /* mppp configuration */
434 is
->range
= 0x1000000; /* MP: 24 bit range */
435 is
->last_link_seqno
= -1; /* MP: maybe set to Bundle-MIN, when joining a bundle ?? */
436 is
->unit
= -1; /* set, when we have our interface */
437 is
->mru
= 1524; /* MRU, default 1524 */
438 is
->maxcid
= 16; /* VJ: maxcid */
440 is
->wq
= NULL
; /* read() wait queue */
441 is
->wq1
= NULL
; /* select() wait queue */
442 is
->first
= is
->rq
+ NUM_RCV_BUFFS
- 1; /* receive queue */
445 #ifdef CONFIG_ISDN_PPP_VJ
447 * VJ header compression init
449 is
->slcomp
= slhc_init(16, 16); /* not necessary for 2. link in bundle */
452 is
->state
= IPPP_OPEN
;
458 * release ippp device
461 isdn_ppp_release(int min
, struct file
*file
)
464 struct ippp_struct
*is
;
466 if (min
< 0 || min
>= ISDN_MAX_CHANNELS
)
468 is
= file
->private_data
;
471 printk(KERN_DEBUG
"ippp: release, minor: %d %lx\n", min
, (long) is
->lp
);
473 if (is
->lp
) { /* a lp address says: this link is still up */
474 isdn_net_dev
*p
= is
->lp
->netdev
;
476 is
->state
&= ~IPPP_CONNECT
; /* -> effect: no call of wakeup */
478 * isdn_net_hangup() calls isdn_ppp_free()
479 * isdn_ppp_free() sets is->lp to NULL and lp->ppp_slot to -1
480 * removing the IPPP_CONNECT flag omits calling of isdn_ppp_wakeup_daemon()
482 isdn_net_hangup(&p
->dev
);
484 for (i
= 0; i
< NUM_RCV_BUFFS
; i
++) {
486 kfree(is
->rq
[i
].buf
);
487 is
->rq
[i
].buf
= NULL
;
490 is
->first
= is
->rq
+ NUM_RCV_BUFFS
- 1; /* receive queue */
493 #ifdef CONFIG_ISDN_PPP_VJ
494 slhc_free(is
->slcomp
);
502 * get_arg .. ioctl helper
505 get_arg(void *b
, void *val
, int len
)
508 len
= sizeof(unsigned long);
509 if (copy_from_user((void *) val
, b
, len
))
515 * set arg .. ioctl helper
518 set_arg(void *b
, unsigned long val
, void *str
)
521 if (copy_to_user(b
, (void *) &val
, 4))
524 if (copy_to_user(b
, str
, val
))
534 isdn_ppp_ioctl(int min
, struct file
*file
, unsigned int cmd
, unsigned long arg
)
538 struct ippp_struct
*is
;
541 is
= (struct ippp_struct
*) file
->private_data
;
545 printk(KERN_DEBUG
"isdn_ppp_ioctl: minor: %d cmd: %x state: %x\n", min
, cmd
, is
->state
);
547 if (!(is
->state
& IPPP_OPEN
))
552 #ifdef CONFIG_ISDN_MPP
553 if (!(is
->state
& IPPP_CONNECT
))
555 if ((r
= get_arg((void *) arg
, &val
, 0)))
557 printk(KERN_DEBUG
"iPPP-bundle: minor: %d, slave unit: %d, master unit: %d\n",
558 (int) min
, (int) is
->unit
, (int) val
);
559 return isdn_ppp_bundle(is
, val
);
564 case PPPIOCGUNIT
: /* get ppp/isdn unit number */
565 if ((r
= set_arg((void *) arg
, is
->unit
, NULL
)))
568 case PPPIOCGMPFLAGS
: /* get configuration flags */
569 if ((r
= set_arg((void *) arg
, is
->mpppcfg
, NULL
)))
572 case PPPIOCSMPFLAGS
: /* set configuration flags */
573 if ((r
= get_arg((void *) arg
, &val
, 0)))
577 case PPPIOCGFLAGS
: /* get configuration flags */
578 if ((r
= set_arg((void *) arg
, is
->pppcfg
, NULL
)))
581 case PPPIOCSFLAGS
: /* set configuration flags */
582 if ((r
= get_arg((void *) arg
, &val
, 0))) {
585 if (val
& SC_ENABLE_IP
&& !(is
->pppcfg
& SC_ENABLE_IP
) && (is
->state
& IPPP_CONNECT
)) {
587 lp
->netdev
->dev
.tbusy
= 0;
588 mark_bh(NET_BH
); /* OK .. we are ready to send buffers */
594 case PPPIOCGSTAT
: /* read PPP statistic information */
597 case PPPIOCGIDLE
: /* get idle time information */
599 struct ppp_idle pidle
;
600 pidle
.xmit_idle
= pidle
.recv_idle
= lp
->huptimer
;
601 if ((r
= set_arg((void *) arg
, sizeof(struct ppp_idle
), &pidle
)))
605 case PPPIOCSMRU
: /* set receive unit size for PPP */
606 if ((r
= get_arg((void *) arg
, &val
, 0)))
614 case PPPIOCSMAXCID
: /* set the maximum compression slot id */
615 if ((r
= get_arg((void *) arg
, &val
, 0)))
618 if (is
->maxcid
!= val
) {
619 #ifdef CONFIG_ISDN_PPP_VJ
620 struct slcompress
*sltmp
;
623 printk(KERN_DEBUG
"ippp, ioctl: changed MAXCID to %ld\n", val
);
625 #ifdef CONFIG_ISDN_PPP_VJ
626 sltmp
= slhc_init(16, val
);
628 printk(KERN_ERR
"ippp, can't realloc slhc struct\n");
632 slhc_free(is
->slcomp
);
638 if ((r
= set_arg((void *) arg
, is
->debug
, 0)))
642 if ((r
= get_arg((void *) arg
, &val
, 0)))
646 case PPPIOCGCOMPRESSORS
:
648 unsigned long protos
= 0;
649 struct isdn_ppp_compressor
*ipc
= ipc_head
;
651 protos
|= (0x1<<ipc
->num
);
654 if ((r
= set_arg((void *) arg
, protos
, 0)))
658 case PPPIOCSCOMPRESSOR
:
659 if ((r
= get_arg((void *) arg
, &num
, sizeof(int))))
661 return isdn_ppp_set_compressor(is
, num
);
663 case PPPIOCGCALLINFO
:
665 struct pppcallinfo pci
;
666 memset((char *) &pci
,0,sizeof(struct pppcallinfo
));
669 strncpy(pci
.local_num
,lp
->msn
,63);
671 strncpy(pci
.remote_num
,lp
->dial
->num
,63);
673 pci
.charge_units
= lp
->charge
;
675 pci
.calltype
= CALLTYPE_OUTGOING
;
677 pci
.calltype
= CALLTYPE_INCOMING
;
678 if(lp
->flags
& ISDN_NET_CALLBACK
)
679 pci
.calltype
|= CALLTYPE_CALLBACK
;
681 return set_arg((void *)arg
,sizeof(struct pppcallinfo
),&pci
);
690 isdn_ppp_poll(struct file
*file
, poll_table
* wait
)
693 struct ippp_buf_queue
*bf
;
694 struct ippp_buf_queue
*bl
;
696 struct ippp_struct
*is
;
698 is
= file
->private_data
;
701 printk(KERN_DEBUG
"isdn_ppp_poll: minor: %d\n",
702 MINOR(file
->f_dentry
->d_inode
->i_rdev
));
704 poll_wait(file
, &is
->wq
, wait
);
706 if (!(is
->state
& IPPP_OPEN
)) {
707 printk(KERN_DEBUG
"isdn_ppp: device not open\n");
710 /* we're always ready to send .. */
711 mask
= POLLOUT
| POLLWRNORM
;
718 * if IPPP_NOBLOCK is set we return even if we have nothing to read
720 if (bf
->next
!= bl
|| (is
->state
& IPPP_NOBLOCK
)) {
721 is
->state
&= ~IPPP_NOBLOCK
;
722 mask
|= POLLIN
| POLLRDNORM
;
724 restore_flags(flags
);
729 * fill up isdn_ppp_read() queue ..
733 isdn_ppp_fill_rq(unsigned char *buf
, int len
, int proto
, int slot
)
735 struct ippp_buf_queue
*bf
,
739 struct ippp_struct
*is
;
741 if (slot
< 0 || slot
>= ISDN_MAX_CHANNELS
) {
742 printk(KERN_WARNING
"ippp: illegal slot.\n");
745 is
= ippp_table
[slot
];
747 if (!(is
->state
& IPPP_CONNECT
)) {
748 printk(KERN_DEBUG
"ippp: device not activated.\n");
751 nbuf
= (unsigned char *) kmalloc(len
+ 4, GFP_ATOMIC
);
753 printk(KERN_WARNING
"ippp: Can't alloc buf\n");
756 nbuf
[0] = PPP_ALLSTATIONS
;
758 nbuf
[2] = proto
>> 8;
759 nbuf
[3] = proto
& 0xff;
760 memcpy(nbuf
+ 4, buf
, len
);
769 printk(KERN_WARNING
"ippp: Queue is full; discarding first buffer\n");
774 bl
->buf
= (char *) nbuf
;
778 restore_flags(flags
);
781 wake_up_interruptible(&is
->wq
);
787 * read() .. non-blocking: ipppd calls it only after select()
788 * reports, that there is data
792 isdn_ppp_read(int min
, struct file
*file
, char *buf
, int count
)
794 struct ippp_struct
*is
;
795 struct ippp_buf_queue
*b
;
798 unsigned char *save_buf
;
800 is
= file
->private_data
;
802 if (!(is
->state
& IPPP_OPEN
))
805 if ((r
= verify_area(VERIFY_WRITE
, (void *) buf
, count
)))
814 restore_flags(flags
);
822 restore_flags(flags
);
824 copy_to_user(buf
, save_buf
, count
);
831 * ipppd wanna write a packet to the card .. non-blocking
835 isdn_ppp_write(int min
, struct file
*file
, const char *buf
, int count
)
838 struct ippp_struct
*is
;
840 unsigned char protobuf
[4];
842 is
= file
->private_data
;
844 if (!(is
->state
& IPPP_CONNECT
))
849 /* -> push it directly to the lowlevel interface */
852 printk(KERN_DEBUG
"isdn_ppp_write: lp == NULL\n");
855 * Don't reset huptimer for
856 * LCP packets. (Echo requests).
858 if (copy_from_user(protobuf
, buf
, 4))
860 proto
= PPP_PROTOCOL(protobuf
);
861 if (proto
!= PPP_LCP
)
864 if (lp
->isdn_device
< 0 || lp
->isdn_channel
< 0)
867 if (dev
->drv
[lp
->isdn_device
]->running
&& lp
->dialstate
== 0 &&
868 (lp
->flags
& ISDN_NET_CONNECTED
)) {
871 skb
= dev_alloc_skb(count
);
873 printk(KERN_WARNING
"isdn_ppp_write: out of memory!\n");
876 if (copy_from_user(skb_put(skb
, count
), buf
, count
))
878 if (is
->debug
& 0x40) {
879 printk(KERN_DEBUG
"ppp xmit: len %d\n", (int) skb
->len
);
880 isdn_ppp_frame_log("xmit", skb
->data
, skb
->len
, 32);
882 if ((cnt
= isdn_writebuf_skb_stub(lp
->isdn_device
, lp
->isdn_channel
, 1, skb
)) != count
) {
884 dev_kfree_skb(lp
->sav_skb
);
885 printk(KERN_INFO
"isdn_ppp_write: freeing sav_skb (%d,%d)!\n", cnt
, count
);
887 printk(KERN_INFO
"isdn_ppp_write: Can't write PPP frame to LL (%d,%d)!\n", cnt
, count
);
896 * init memory, structures etc.
905 for (i
= 0; i
< ISDN_MAX_CHANNELS
; i
++) {
906 if (!(ippp_table
[i
] = (struct ippp_struct
*)
907 kmalloc(sizeof(struct ippp_struct
), GFP_KERNEL
))) {
908 printk(KERN_WARNING
"isdn_ppp_init: Could not alloc ippp_table\n");
909 for (j
= 0; j
< i
; j
++)
910 kfree(ippp_table
[i
]);
913 memset((char *) ippp_table
[i
], 0, sizeof(struct ippp_struct
));
914 ippp_table
[i
]->state
= 0;
915 ippp_table
[i
]->first
= ippp_table
[i
]->rq
+ NUM_RCV_BUFFS
- 1;
916 ippp_table
[i
]->last
= ippp_table
[i
]->rq
;
918 for (j
= 0; j
< NUM_RCV_BUFFS
; j
++) {
919 ippp_table
[i
]->rq
[j
].buf
= NULL
;
920 ippp_table
[i
]->rq
[j
].last
= ippp_table
[i
]->rq
+
921 (NUM_RCV_BUFFS
+ j
- 1) % NUM_RCV_BUFFS
;
922 ippp_table
[i
]->rq
[j
].next
= ippp_table
[i
]->rq
+ (j
+ 1) % NUM_RCV_BUFFS
;
929 isdn_ppp_cleanup(void)
933 for (i
= 0; i
< ISDN_MAX_CHANNELS
; i
++)
934 kfree(ippp_table
[i
]);
938 * get the PPP protocol header and pull skb
940 static int isdn_ppp_strip_proto(struct sk_buff
*skb
)
943 if (skb
->data
[0] & 0x1) {
944 proto
= skb
->data
[0];
945 skb_pull(skb
, 1); /* protocol ID is only 8 bit */
947 proto
= ((int) skb
->data
[0] << 8) + skb
->data
[1];
955 * handler for incoming packets on a syncPPP interface
957 void isdn_ppp_receive(isdn_net_dev
* net_dev
, isdn_net_local
* lp
, struct sk_buff
*skb
)
959 struct ippp_struct
*is
;
962 is
= ippp_table
[lp
->ppp_slot
];
964 if (is
->debug
& 0x4) {
965 printk(KERN_DEBUG
"ippp_receive: len: %d\n", (int) skb
->len
);
966 isdn_ppp_frame_log("receive", skb
->data
, skb
->len
, 32);
968 if (net_dev
->local
->master
) {
969 printk(KERN_WARNING
"isdn_ppp_receice: net_dev != master\n");
970 net_dev
= ((isdn_net_local
*) net_dev
->local
->master
->priv
)->netdev
;
972 if (skb
->data
[0] == 0xff && skb
->data
[1] == 0x03)
974 else if (is
->pppcfg
& SC_REJ_COMP_AC
) {
976 return; /* discard it silently */
979 proto
= isdn_ppp_strip_proto(skb
);
981 #ifdef CONFIG_ISDN_MPP
982 if (!(is
->mpppcfg
& SC_REJ_MP_PROT
)) {
985 if(proto
== PPP_LINK_COMP
) {
986 printk(KERN_DEBUG
"received single link compressed frame\n");
987 skb
= isdn_ppp_decompress(skb
,is
,NULL
);
990 proto
= isdn_ppp_strip_proto(skb
);
993 if (proto
== PPP_MP
) {
995 long sqno
, min_sqno
, tseq
;
997 u_char BEbyte
= skb
->data
[0];
999 printk(KERN_DEBUG
"recv: %d/%04x/%d -> %02x %02x %02x %02x %02x %02x\n", lp
->ppp_slot
, proto
,
1000 (int) skb
->len
, (int) skb
->data
[0], (int) skb
->data
[1], (int) skb
->data
[2],
1001 (int) skb
->data
[3], (int) skb
->data
[4], (int) skb
->data
[5]);
1002 if (!(is
->mpppcfg
& SC_IN_SHORT_SEQ
)) {
1003 sqno
= ((int) skb
->data
[1] << 16) + ((int) skb
->data
[2] << 8) + (int) skb
->data
[3];
1006 sqno
= (((int) skb
->data
[0] & 0xf) << 8) + (int) skb
->data
[1];
1011 * new sequence number lower than last number? (this is only allowed
1012 * for overflow case)
1014 if ((tseq
= is
->last_link_seqno
) >= sqno
) {
1015 int range
= is
->range
;
1016 if (tseq
+ 1024 < range
+ sqno
) /* redundancy check .. not MP conform */
1017 printk(KERN_WARNING
"isdn_ppp_receive, MP, detected overflow with sqno: %ld, last: %ld !!!\n", sqno
, tseq
);
1020 is
->last_link_seqno
= sqno
;
1023 /* here, we should also add an redundancy check */
1024 is
->last_link_seqno
= sqno
;
1028 * step over all links to find lowest link number
1030 for (min_sqno
= LONG_MAX
, lpq
= net_dev
->queue
;;) {
1031 long lls
= ippp_table
[lpq
->ppp_slot
]->last_link_seqno
;
1032 if (lls
>= 0 && lls
< min_sqno
)
1035 if (lpq
== net_dev
->queue
)
1040 * for the case, that the last frame numbers of all
1041 * links are overflowed: mask/reduce the sequenece number to
1042 * 'normal' numbering.
1044 if (min_sqno
>= ippp_table
[lpq
->ppp_slot
]->range
) {
1045 int mask
= ippp_table
[lpq
->ppp_slot
]->range
-1; /* range is power of two, so a mask will do the job */
1046 isdn_ppp_mask_queue(net_dev
, mask
);
1047 net_dev
->ib
.next_num
&= mask
;
1049 struct sqqueue
*q
= net_dev
->ib
.sq
;
1051 q
->sqno_start
&= mask
;
1052 q
->sqno_end
&= mask
;
1056 for (lpq
= net_dev
->queue
;;) {
1057 ippp_table
[lpq
->ppp_slot
]->last_link_seqno
&= mask
;
1059 if (lpq
== net_dev
->queue
)
1063 if ((BEbyte
& (MP_BEGIN_FRAG
| MP_END_FRAG
)) != (MP_BEGIN_FRAG
| MP_END_FRAG
)) {
1064 static int dmes
= 0;
1066 printk(KERN_DEBUG
"ippp: trying ;) to fill mp_queue %d .. UNTESTED!!\n", lp
->ppp_slot
);
1069 if ((sqno_end
= isdn_ppp_fill_mpqueue(net_dev
, &skb
, BEbyte
, &sqno
, min_sqno
)) < 0) {
1070 net_dev
->ib
.modify
= 1; /* block timeout-timer */
1071 isdn_ppp_cleanup_sqqueue(net_dev
, lp
, min_sqno
);
1072 net_dev
->ib
.modify
= 0;
1073 return; /* no packet complete */
1078 if (is
->debug
& 0x40)
1079 printk(KERN_DEBUG
"min_sqno: %ld sqno_end %d next: %ld\n", min_sqno
, sqno_end
, net_dev
->ib
.next_num
);
1082 * MP buffer management .. reorders incoming packets ..
1083 * lotsa mem-copies and not heavily tested.
1085 * first check whether there is more than one link in the bundle
1086 * then check whether the number is in order
1088 net_dev
->ib
.modify
= 1; /* block timeout-timer */
1089 if (net_dev
->ib
.bundled
&& net_dev
->ib
.next_num
!= sqno
) {
1091 * packet is not 'in order'
1095 q
= (struct sqqueue
*) kmalloc(sizeof(struct sqqueue
), GFP_ATOMIC
);
1097 net_dev
->ib
.modify
= 0;
1098 printk(KERN_WARNING
"ippp/MPPP: Bad! Can't alloc sq node!\n");
1100 return; /* discard */
1103 q
->sqno_end
= sqno_end
;
1104 q
->sqno_start
= sqno
;
1105 q
->timer
= jiffies
+ (ISDN_TIMER_1SEC
) * 5; /* timeout after 5 seconds */
1107 if (!net_dev
->ib
.sq
) {
1111 struct sqqueue
*ql
= net_dev
->ib
.sq
;
1112 if (ql
->sqno_start
> q
->sqno_start
) {
1116 while (ql
->next
&& ql
->next
->sqno_start
< q
->sqno_start
)
1124 * packet was 'in order' .. push it higher
1126 net_dev
->ib
.next_num
= sqno_end
+ 1;
1127 proto
= isdn_ppp_strip_proto(skb
);
1128 isdn_ppp_push_higher(net_dev
, lp
, skb
, proto
);
1130 isdn_ppp_cleanup_sqqueue(net_dev
, lp
, min_sqno
);
1131 net_dev
->ib
.modify
= 0;
1134 isdn_ppp_push_higher(net_dev
, lp
, skb
, proto
);
1137 isdn_ppp_push_higher(net_dev
, lp
, skb
, proto
);
1141 * push frame to higher layers
1142 * note: net_dev has to be master net_dev
1145 isdn_ppp_push_higher(isdn_net_dev
* net_dev
, isdn_net_local
* lp
, struct sk_buff
*skb
, int proto
)
1147 struct device
*dev
= &net_dev
->dev
;
1148 struct ippp_struct
*is
= ippp_table
[lp
->ppp_slot
];
1150 if (is
->debug
& 0x10) {
1151 printk(KERN_DEBUG
"push, skb %d %04x\n", (int) skb
->len
, proto
);
1152 isdn_ppp_frame_log("rpush", skb
->data
, skb
->len
, 32);
1155 if(proto
== PPP_COMP
) {
1157 skb
= isdn_ppp_decompress(skb
,is
,is
);
1159 skb
= isdn_ppp_decompress(skb
,is
,ippp_table
[((isdn_net_local
*) (lp
->master
->priv
))->ppp_slot
]);
1162 proto
= isdn_ppp_strip_proto(skb
);
1166 case PPP_IPX
: /* untested */
1167 if (is
->debug
& 0x20)
1168 printk(KERN_DEBUG
"isdn_ppp: IPX\n");
1170 skb
->mac
.raw
= skb
->data
;
1171 skb
->protocol
= htons(ETH_P_IPX
);
1173 #ifdef CONFIG_ISDN_PPP_VJ
1174 case PPP_VJC_UNCOMP
:
1175 if (is
->debug
& 0x20)
1176 printk(KERN_DEBUG
"isdn_ppp: VJC_UNCOMP\n");
1177 if (slhc_remember(ippp_table
[net_dev
->local
->ppp_slot
]->slcomp
, skb
->data
, skb
->len
) <= 0) {
1178 printk(KERN_WARNING
"isdn_ppp: received illegal VJC_UNCOMP frame!\n");
1179 net_dev
->local
->stats
.rx_dropped
++;
1185 if (is
->debug
& 0x20)
1186 printk(KERN_DEBUG
"isdn_ppp: IP\n");
1188 skb
->mac
.raw
= skb
->data
;
1189 skb
->protocol
= htons(ETH_P_IP
);
1192 if (is
->debug
& 0x20)
1193 printk(KERN_DEBUG
"isdn_ppp: VJC_COMP\n");
1194 #ifdef CONFIG_ISDN_PPP_VJ
1196 struct sk_buff
*skb_old
= skb
;
1198 skb
= dev_alloc_skb(skb_old
->len
+ 40);
1201 printk(KERN_WARNING
"%s: Memory squeeze, dropping packet.\n", dev
->name
);
1202 net_dev
->local
->stats
.rx_dropped
++;
1203 dev_kfree_skb(skb_old
);
1207 skb_put(skb
, skb_old
->len
+ 40);
1208 memcpy(skb
->data
, skb_old
->data
, skb_old
->len
);
1209 skb
->mac
.raw
= skb
->data
;
1210 pkt_len
= slhc_uncompress(ippp_table
[net_dev
->local
->ppp_slot
]->slcomp
,
1211 skb
->data
, skb_old
->len
);
1212 dev_kfree_skb(skb_old
);
1215 lp
->stats
.rx_dropped
++;
1218 skb_trim(skb
, pkt_len
);
1219 skb
->protocol
= htons(ETH_P_IP
);
1222 printk(KERN_INFO
"isdn: Ooopsa .. VJ-Compression support not compiled into isdn driver.\n");
1223 lp
->stats
.rx_dropped
++;
1229 isdn_ppp_receive_ccp(net_dev
,lp
,skb
);
1232 isdn_ppp_fill_rq(skb
->data
, skb
->len
, proto
, lp
->ppp_slot
); /* push data to pppd device */
1238 /* net_dev->local->stats.rx_packets++; *//* done in isdn_net.c */
1239 /* Reset hangup-timer */
1246 * isdn_ppp_skb_push ..
1247 * checks whether we have enough space at the beginning of the SKB
1248 * and allocs a new SKB if necessary
1250 static unsigned char *isdn_ppp_skb_push(struct sk_buff
**skb_p
,int len
)
1252 struct sk_buff
*skb
= *skb_p
;
1254 if(skb_headroom(skb
) < len
) {
1255 printk(KERN_ERR
"isdn_ppp_skb_push:under %d %d\n",skb_headroom(skb
),len
);
1259 return skb_push(skb
,len
);
1264 * send ppp frame .. we expect a PIDCOMPressable proto --
1265 * (here: currently always PPP_IP,PPP_VJC_COMP,PPP_VJC_UNCOMP)
1267 * VJ compression may change skb pointer!!! .. requeue with old
1268 * skb isn't allowed!!
1272 isdn_ppp_xmit(struct sk_buff
*skb
, struct device
*dev
)
1274 struct device
*mdev
= ((isdn_net_local
*) (dev
->priv
))->master
; /* get master (for redundancy) */
1275 isdn_net_local
*lp
,*mlp
;
1277 unsigned int proto
= PPP_IP
; /* 0x21 */
1278 struct ippp_struct
*ipt
,*ipts
;
1281 mlp
= (isdn_net_local
*) (mdev
->priv
);
1284 mlp
= (isdn_net_local
*) (dev
->priv
);
1286 nd
= mlp
->netdev
; /* get master lp */
1287 ipts
= ippp_table
[mlp
->ppp_slot
];
1289 if (!(ipts
->pppcfg
& SC_ENABLE_IP
)) { /* PPP connected ? */
1290 #ifdef ISDN_SYNCPPP_READDRESS
1291 if (!ipts
->old_pa_addr
)
1292 ipts
->old_pa_addr
= mdev
->pa_addr
;
1293 if (!ipts
->old_pa_dstaddr
)
1294 ipts
->old_pa_dstaddr
= mdev
->pa_dstaddr
;
1296 if (ipts
->debug
& 0x1)
1297 printk(KERN_INFO
"%s: IP frame delayed.\n", dev
->name
);
1301 switch (ntohs(skb
->protocol
)) {
1304 #ifdef ISDN_SYNCPPP_READDRESS
1305 if (ipts
->old_pa_addr
!= mdev
->pa_addr
) {
1307 ipfr
= (struct iphdr
*) skb
->data
;
1308 if(ipts
->debug
& 0x4)
1309 printk(KERN_DEBUG
"IF-address changed from %lx to %lx\n", ipts
->old_pa_addr
, mdev
->pa_addr
);
1310 if (ipfr
->version
== 4) {
1311 if (ipfr
->saddr
== ipts
->old_pa_addr
) {
1312 printk(KERN_DEBUG
"readdressing %lx to %lx\n", ipfr
->saddr
, mdev
->pa_addr
);
1313 ipfr
->saddr
= mdev
->pa_addr
;
1317 /* dstaddr change not so important */
1321 proto
= PPP_IPX
; /* untested */
1325 printk(KERN_ERR
"isdn_ppp: skipped frame with unsupported protocoll: %#x.\n", skb
->protocol
);
1329 lp
= nd
->queue
; /* get lp on top of queue */
1331 if (lp
->sav_skb
) { /* find a non-busy device */
1332 isdn_net_local
*nlp
= lp
->next
;
1333 while (lp
->sav_skb
) {
1336 nlp
= nd
->queue
= nd
->queue
->next
;
1340 ipt
= ippp_table
[lp
->ppp_slot
];
1345 * after this line .. requeueing in the device queue is no longer allowed!!!
1348 /* Pull off the fake header we stuck on earlier to keep
1349 * the fragemntation code happy.
1350 * this will break the ISDN_SYNCPPP_READDRESS hack a few lines
1351 * above. So, enabling this is no longer allowed
1353 skb_pull(skb
,IPPP_MAX_HEADER
);
1355 if (ipt
->debug
& 0x4)
1356 printk(KERN_DEBUG
"xmit skb, len %d\n", (int) skb
->len
);
1358 #ifdef CONFIG_ISDN_PPP_VJ
1359 if (proto
== PPP_IP
&& ipts
->pppcfg
& SC_COMP_TCP
) { /* ipts here? probably yes, but check this again */
1360 struct sk_buff
*new_skb
;
1362 new_skb
= dev_alloc_skb(skb
->len
);
1367 new_skb
->dev
= skb
->dev
;
1368 skb_put(new_skb
, skb
->len
);
1371 pktlen
= slhc_compress(ipts
->slcomp
, skb
->data
, skb
->len
, new_skb
->data
,
1372 &buf
, !(ipts
->pppcfg
& SC_NO_TCP_CCID
));
1374 if (buf
!= skb
->data
) {
1375 if (new_skb
->data
!= buf
)
1376 printk(KERN_ERR
"isdn_ppp: FATAL error after slhc_compress!!\n");
1380 dev_kfree_skb(new_skb
);
1383 skb_trim(skb
, pktlen
);
1384 if (skb
->data
[0] & SL_TYPE_COMPRESSED_TCP
) { /* cslip? style -> PPP */
1385 proto
= PPP_VJC_COMP
;
1386 skb
->data
[0] ^= SL_TYPE_COMPRESSED_TCP
;
1388 if (skb
->data
[0] >= SL_TYPE_UNCOMPRESSED_TCP
)
1389 proto
= PPP_VJC_UNCOMP
;
1390 skb
->data
[0] = (skb
->data
[0] & 0x0f) | 0x40;
1397 * normal or bundle compression
1399 skb
= isdn_ppp_compress(skb
,&proto
,ipt
,ipts
,0);
1401 if (ipt
->debug
& 0x24)
1402 printk(KERN_DEBUG
"xmit2 skb, len %d, proto %04x\n", (int) skb
->len
, proto
);
1404 #ifdef CONFIG_ISDN_MPP
1405 if (ipt
->mpppcfg
& SC_MP_PROT
) {
1406 /* we get mp_seqno from static isdn_net_local */
1407 long mp_seqno
= ipts
->mp_seqno
;
1409 nd
->queue
= nd
->queue
->next
;
1410 if (ipt
->mpppcfg
& SC_OUT_SHORT_SEQ
) {
1411 unsigned char *data
= isdn_ppp_skb_push(&skb
, 3);
1415 data
[0] = MP_BEGIN_FRAG
| MP_END_FRAG
| ((mp_seqno
>> 8) & 0xf); /* (B)egin & (E)ndbit .. */
1416 data
[1] = mp_seqno
& 0xff;
1417 data
[2] = proto
; /* PID compression */
1419 unsigned char *data
= isdn_ppp_skb_push(&skb
, 5);
1422 data
[0] = MP_BEGIN_FRAG
| MP_END_FRAG
; /* (B)egin & (E)ndbit .. */
1423 data
[1] = (mp_seqno
>> 16) & 0xff; /* sequence number: 24bit */
1424 data
[2] = (mp_seqno
>> 8) & 0xff;
1425 data
[3] = (mp_seqno
>> 0) & 0xff;
1426 data
[4] = proto
; /* PID compression */
1428 proto
= PPP_MP
; /* MP Protocol, 0x003d */
1433 * 'link' compression
1435 skb
= isdn_ppp_compress(skb
,&proto
,ipt
,ipts
,1);
1437 if( (ipt
->pppcfg
& SC_COMP_PROT
) && (proto
<= 0xff) ) {
1438 unsigned char *data
= isdn_ppp_skb_push(&skb
,1);
1441 data
[0] = proto
& 0xff;
1444 unsigned char *data
= isdn_ppp_skb_push(&skb
,2);
1447 data
[0] = (proto
>> 8) & 0xff;
1448 data
[1] = proto
& 0xff;
1450 if(!(ipt
->pppcfg
& SC_COMP_AC
)) {
1451 unsigned char *data
= isdn_ppp_skb_push(&skb
,2);
1454 data
[0] = 0xff; /* All Stations */
1455 data
[1] = 0x03; /* Unnumbered information */
1458 /* tx-stats are now updated via BSENT-callback */
1460 if (ipts
->debug
& 0x40) {
1461 printk(KERN_DEBUG
"skb xmit: len: %d\n", (int) skb
->len
);
1462 isdn_ppp_frame_log("xmit", skb
->data
, skb
->len
, 32);
1464 if (isdn_net_send_skb(dev
, lp
, skb
)) {
1465 if (lp
->sav_skb
) { /* whole sav_skb processing with disabled IRQs ?? */
1466 printk(KERN_ERR
"%s: whoops .. there is another stored skb!\n", dev
->name
);
1474 #ifdef CONFIG_ISDN_MPP
1477 isdn_ppp_free_sqqueue(isdn_net_dev
* p
)
1479 struct sqqueue
*q
= p
->ib
.sq
;
1483 struct sqqueue
*qn
= q
->next
;
1485 dev_kfree_skb(q
->skb
);
1493 isdn_ppp_free_mpqueue(isdn_net_dev
* p
)
1495 struct mpqueue
*q
= p
->mp_last
;
1499 struct mpqueue
*ql
= q
->next
;
1500 dev_kfree_skb(q
->skb
);
1507 isdn_ppp_bundle(struct ippp_struct
*is
, int unit
)
1509 char ifn
[IFNAMSIZ
+ 1];
1515 sprintf(ifn
, "ippp%d", unit
);
1516 p
= isdn_net_findif(ifn
);
1520 isdn_timer_ctrl(ISDN_TIMER_IPPP
, 1); /* enable timer for ippp/MP */
1529 nlp
->last
= lp
->last
;
1530 lp
->last
->next
= nlp
;
1535 ippp_table
[nlp
->ppp_slot
]->unit
= ippp_table
[lp
->ppp_slot
]->unit
;
1536 /* maybe also SC_CCP stuff */
1537 ippp_table
[nlp
->ppp_slot
]->pppcfg
|= ippp_table
[lp
->ppp_slot
]->pppcfg
&
1538 (SC_ENABLE_IP
| SC_NO_TCP_CCID
| SC_REJ_COMP_TCP
);
1540 ippp_table
[nlp
->ppp_slot
]->mpppcfg
|= ippp_table
[lp
->ppp_slot
]->mpppcfg
&
1541 (SC_MP_PROT
| SC_REJ_MP_PROT
| SC_OUT_SHORT_SEQ
| SC_IN_SHORT_SEQ
);
1543 if (ippp_table
[nlp
->ppp_slot
]->mpppcfg
!= ippp_table
[lp
->ppp_slot
]->mpppcfg
) {
1544 printk(KERN_WARNING
"isdn_ppp_bundle: different MP options %04x and %04x\n",
1545 ippp_table
[nlp
->ppp_slot
]->mpppcfg
, ippp_table
[lp
->ppp_slot
]->mpppcfg
);
1549 restore_flags(flags
);
1555 isdn_ppp_mask_queue(isdn_net_dev
* dev
, long mask
)
1557 struct mpqueue
*q
= dev
->mp_last
;
1565 isdn_ppp_fill_mpqueue(isdn_net_dev
* dev
, struct sk_buff
**skb
, int BEbyte
, long *sqnop
, int min_sqno
)
1576 q1
= (struct mpqueue
*) kmalloc(sizeof(struct mpqueue
), GFP_ATOMIC
);
1578 printk(KERN_WARNING
"isdn_ppp_fill_mpqueue: Can't alloc struct memory.\n");
1581 isdn_ppp_cleanup_mpqueue(dev
, min_sqno
);
1582 restore_flags(flags
);
1587 q1
->BEbyte
= BEbyte
;
1593 if (!(q
= dev
->mp_last
)) {
1597 isdn_ppp_cleanup_mpqueue(dev
, min_sqno
); /* not necessary */
1598 restore_flags(flags
);
1599 return -1; /* -1 is not an error. Just says, that this fragment hasn't complete a full frame */
1601 for (;;) { /* the faster way would be to step from the queue-end to the start */
1602 if (sqno
> q
->sqno
) {
1612 if (sqno
== q
->sqno
)
1613 printk(KERN_WARNING
"isdn_fill_mpqueue: illegal sqno received!!\n");
1624 /* now we check whether we completed a packet with this fragment */
1625 pktlen
= -q1
->skb
->len
;
1628 while (!(q
->BEbyte
& MP_END_FRAG
)) {
1630 if (!(q
->next
) || q
->next
->sqno
!= cnt
) {
1631 isdn_ppp_cleanup_mpqueue(dev
, min_sqno
);
1632 restore_flags(flags
);
1635 pktlen
+= q
->skb
->len
;
1638 pktlen
+= q
->skb
->len
;
1643 while (!(q
->BEbyte
& MP_BEGIN_FRAG
)) {
1645 if (!(q
->last
) || q
->last
->sqno
!= cnt
) {
1646 isdn_ppp_cleanup_mpqueue(dev
, min_sqno
);
1647 restore_flags(flags
);
1650 pktlen
+= q
->skb
->len
;
1653 pktlen
+= q
->skb
->len
;
1656 q
->last
->next
= qe
->next
;
1658 dev
->mp_last
= qe
->next
;
1661 qe
->next
->last
= q
->last
;
1663 sqno_end
= qe
->sqno
;
1666 isdn_ppp_cleanup_mpqueue(dev
, min_sqno
);
1667 restore_flags(flags
);
1669 *skb
= dev_alloc_skb(pktlen
+ 40); /* not needed: +40 for VJ compression .. */
1673 struct mpqueue
*ql
= q
->next
;
1674 dev_kfree_skb(q
->skb
);
1681 skb_put(*skb
, pktlen
);
1683 struct mpqueue
*ql
= q
->next
;
1684 memcpy((*skb
)->data
+ cnt
, q
->skb
->data
, q
->skb
->len
);
1686 dev_kfree_skb(q
->skb
);
1695 * check sq-queue, whether we have still buffered the next packet(s)
1696 * or packets with a sqno less or equal to min_sqno
1697 * net_dev: master netdevice , lp: 'real' local connection
1700 isdn_ppp_cleanup_sqqueue(isdn_net_dev
* net_dev
, isdn_net_local
* lp
, long min_sqno
)
1704 while ((q
= net_dev
->ib
.sq
) && (q
->sqno_start
== net_dev
->ib
.next_num
|| q
->sqno_end
<= min_sqno
)) {
1706 if (q
->sqno_start
!= net_dev
->ib
.next_num
) {
1707 printk(KERN_DEBUG
"ippp: MP, stepping over missing frame: %ld\n", net_dev
->ib
.next_num
);
1708 #ifdef CONFIG_ISDN_PPP_VJ
1709 slhc_toss(ippp_table
[net_dev
->local
->ppp_slot
]->slcomp
);
1712 proto
= isdn_ppp_strip_proto(q
->skb
);
1713 isdn_ppp_push_higher(net_dev
, lp
, q
->skb
, proto
);
1714 net_dev
->ib
.sq
= q
->next
;
1715 net_dev
->ib
.next_num
= q
->sqno_end
+ 1;
1721 * remove stale packets from list
1724 isdn_ppp_cleanup_mpqueue(isdn_net_dev
* dev
, long min_sqno
)
1726 #ifdef CONFIG_ISDN_PPP_VJ
1729 /* z.z einfaches aussortieren gammeliger pakete. Fuer die Zukunft:
1730 eventuell, solange vorne kein B-paket ist und sqno<=min_sqno: auch rauswerfen
1731 wenn sqno<min_sqno und Luecken vorhanden sind: auch weg (die koennen nicht mehr gefuellt werden)
1732 bei paketen groesser min_sqno: ueber mp_mrru: wenn summe ueber pktlen der rumhaengenden Pakete
1733 groesser als mrru ist: raus damit , Pakete muessen allerdings zusammenhaengen sonst koennte
1734 ja ein Paket mit B und eins mit E dazwischenpassen */
1738 while(q
&& (q
->sqno
< min_sqno
) ) {
1739 if ( (q
->BEbyte
& MP_END_FRAG
) ||
1740 (q
->next
&& (q
->next
->sqno
<= min_sqno
) && (q
->next
->BEbyte
& MP_BEGIN_FRAG
)) ) {
1741 printk(KERN_DEBUG
"ippp: freeing stale packet(s), min_sq: %ld!\n",min_sqno
);
1742 if ((dev
->mp_last
= q
->next
))
1743 q
->next
->last
= NULL
;
1746 printk(KERN_DEBUG
"ippp, freeing packet with sqno: %ld\n",q
->sqno
);
1747 dev_kfree_skb(q
->skb
);
1749 #ifdef CONFIG_ISDN_PPP_VJ
1758 #ifdef CONFIG_ISDN_PPP_VJ
1759 /* did we free a stale frame ? */
1761 slhc_toss(ippp_table
[dev
->local
->ppp_slot
]->slcomp
);
1766 * a buffered packet timed-out?
1772 isdn_ppp_timer_timeout(void)
1774 #ifdef CONFIG_ISDN_MPP
1775 isdn_net_dev
*net_dev
= dev
->netdev
;
1781 isdn_net_local
*lp
= net_dev
->local
;
1782 if (net_dev
->ib
.modify
|| lp
->master
) { /* interface locked or slave? */
1783 net_dev
= net_dev
->next
;
1788 if (q
->sqno_start
== net_dev
->ib
.next_num
|| q
->timer
< jiffies
) {
1790 #ifdef CONFIG_ISDN_PPP_VJ
1791 /* did we step over a missing frame ? */
1792 if (q
->sqno_start
!= net_dev
->ib
.next_num
)
1793 slhc_toss(ippp_table
[lp
->ppp_slot
]->slcomp
);
1796 ql
= net_dev
->ib
.sq
;
1797 net_dev
->ib
.sq
= q
->next
;
1798 net_dev
->ib
.next_num
= q
->sqno_end
+ 1;
1801 int proto
= isdn_ppp_strip_proto(ql
->skb
);
1802 isdn_ppp_push_higher(net_dev
, lp
, ql
->skb
, proto
);
1811 net_dev
= net_dev
->next
;
1817 * network device ioctl handlers
1821 isdn_ppp_dev_ioctl_stats(int slot
, struct ifreq
*ifr
, struct device
*dev
)
1823 struct ppp_stats
*res
,
1825 isdn_net_local
*lp
= (isdn_net_local
*) dev
->priv
;
1828 res
= (struct ppp_stats
*) ifr
->ifr_ifru
.ifru_data
;
1829 err
= verify_area(VERIFY_WRITE
, res
, sizeof(struct ppp_stats
));
1834 /* build a temporary stat struct and copy it to user space */
1836 memset(&t
, 0, sizeof(struct ppp_stats
));
1837 if (dev
->flags
& IFF_UP
) {
1838 t
.p
.ppp_ipackets
= lp
->stats
.rx_packets
;
1839 t
.p
.ppp_ierrors
= lp
->stats
.rx_errors
;
1840 t
.p
.ppp_opackets
= lp
->stats
.tx_packets
;
1841 t
.p
.ppp_oerrors
= lp
->stats
.tx_errors
;
1842 #ifdef CONFIG_ISDN_PPP_VJ
1843 if (slot
>= 0 && ippp_table
[slot
]->slcomp
) {
1844 struct slcompress
*slcomp
= ippp_table
[slot
]->slcomp
;
1845 t
.vj
.vjs_packets
= slcomp
->sls_o_compressed
+ slcomp
->sls_o_uncompressed
;
1846 t
.vj
.vjs_compressed
= slcomp
->sls_o_compressed
;
1847 t
.vj
.vjs_searches
= slcomp
->sls_o_searches
;
1848 t
.vj
.vjs_misses
= slcomp
->sls_o_misses
;
1849 t
.vj
.vjs_errorin
= slcomp
->sls_i_error
;
1850 t
.vj
.vjs_tossed
= slcomp
->sls_i_tossed
;
1851 t
.vj
.vjs_uncompressedin
= slcomp
->sls_i_uncompressed
;
1852 t
.vj
.vjs_compressedin
= slcomp
->sls_i_compressed
;
1856 if( copy_to_user(res
, &t
, sizeof(struct ppp_stats
))) return -EFAULT
;
1861 isdn_ppp_dev_ioctl(struct device
*dev
, struct ifreq
*ifr
, int cmd
)
1866 isdn_net_local
*lp
= (isdn_net_local
*) dev
->priv
;
1869 printk(KERN_DEBUG
"ippp, dev_ioctl: cmd %#08x , %d \n", cmd
, lp
->ppp_slot
);
1872 if (lp
->p_encap
!= ISDN_NET_ENCAP_SYNCPPP
)
1877 r
= (char *) ifr
->ifr_ifru
.ifru_data
;
1878 len
= strlen(PPP_VERSION
) + 1;
1879 if(copy_to_user(r
, PPP_VERSION
, len
)) error
= -EFAULT
;
1882 error
= isdn_ppp_dev_ioctl_stats(lp
->ppp_slot
, ifr
, dev
);
1892 isdn_ppp_if_get_unit(char *name
)
1901 if (strncmp("ippp", name
, 4) || len
> 8)
1904 for (i
= 0, deci
= 1; i
< len
; i
++, deci
*= 10) {
1905 char a
= name
[len
- i
- 1];
1906 if (a
>= '0' && a
<= '9')
1907 unit
+= (a
- '0') * deci
;
1911 if (!i
|| len
- i
!= 4)
1919 isdn_ppp_dial_slave(char *name
)
1921 #ifdef CONFIG_ISDN_MPP
1924 struct device
*sdev
;
1926 if (!(ndev
= isdn_net_findif(name
)))
1929 if (!(lp
->flags
& ISDN_NET_CONNECTED
))
1934 isdn_net_local
*mlp
= (isdn_net_local
*) sdev
->priv
;
1935 if (!(mlp
->flags
& ISDN_NET_CONNECTED
))
1942 isdn_net_force_dial_lp((isdn_net_local
*) sdev
->priv
);
1950 isdn_ppp_hangup_slave(char *name
)
1952 #ifdef CONFIG_ISDN_MPP
1955 struct device
*sdev
;
1957 if (!(ndev
= isdn_net_findif(name
)))
1960 if (!(lp
->flags
& ISDN_NET_CONNECTED
))
1965 isdn_net_local
*mlp
= (isdn_net_local
*) sdev
->priv
;
1966 if ((mlp
->flags
& ISDN_NET_CONNECTED
))
1973 isdn_net_hangup(sdev
);
1981 * PPP compression stuff
1983 static struct sk_buff
*isdn_ppp_decompress(struct sk_buff
*skb
,struct ippp_struct
*is
,struct ippp_struct
*master
)
1986 printk(KERN_ERR
"compression not included!\n");
1992 * single link compression
1994 if(!is
->link_compressor
) {
1995 printk(KERN_ERR
"ippp: no (link) compressor defined!\n");
1999 if(!is
->link_decomp_stat
) {
2000 printk(KERN_DEBUG
"ippp: initialize link compressor\n");
2008 * 'normal' or bundle-compression
2010 if(!master
->compressor
) {
2011 printk(KERN_ERR
"ippp: no (link) compressor defined!\n");
2015 if(!master
->decomp_stat
) {
2017 master
->decomp_stat
= (master
->compressor
->decomp_alloc
)( .. );
2019 printk(KERN_DEBUG
"ippp: initialize compressor\n");
2029 * type=0: normal/bundle compression
2030 * =1: link compression
2031 * returns original skb if we haven't compressed the frame
2032 * and a new skb pointer if we've done it
2034 static struct sk_buff
*isdn_ppp_compress(struct sk_buff
*skb_in
,int *proto
,
2035 struct ippp_struct
*is
,struct ippp_struct
*master
,int type
)
2042 struct isdn_ppp_compressor
*compressor
;
2044 struct sk_buff
*skb_out
;
2046 if(type
) { /* type=1 => Link compression */
2047 compressor
= is
->link_compressor
;
2048 stat
= is
->link_comp_stat
;
2049 new_proto
= PPP_LINK_COMP
;
2053 compressor
= is
->compressor
;
2054 stat
= is
->comp_stat
;
2057 compressor
= master
->compressor
;
2058 stat
= master
->comp_stat
;
2060 new_proto
= PPP_COMP
;
2064 printk(KERN_ERR
"No compressor set!\n");
2072 skb_out
= dev_alloc_skb(skb_in
->len
);
2076 ret
= (compressor
->compress
)(stat
,skb_in
,skb_out
,*proto
);
2078 dev_kfree_skb(skb_out
);
2082 dev_kfree_skb(skb_in
);
2090 * we received a CCP frame ..
2091 * not a clean solution, but we SHOULD handle a few cased in the kernel
2093 static void isdn_ppp_receive_ccp(isdn_net_dev
*net_dev
, isdn_net_local
*lp
,
2094 struct sk_buff
*skb
)
2097 printk(KERN_DEBUG
"isdn_ppp_receive_cpp: %02x %02x %02x %02x %02x %02x %02x %02x\n",
2098 skb
->data
[0],skb
->data
[1],skb
->data
[2],skb
->data
[3],
2099 skb
->data
[4],skb
->data
[5],skb
->data
[6],skb
->data
[7] );
2103 int isdn_ppp_register_compressor(struct isdn_ppp_compressor
*ipc
)
2105 ipc
->next
= ipc_head
;
2108 ipc_head
->prev
= ipc
;
2114 int isdn_ppp_unregister_compressor(struct isdn_ppp_compressor
*ipc
)
2117 ipc
->prev
->next
= ipc
->next
;
2119 ipc_head
= ipc
->next
;
2121 ipc
->next
->prev
= ipc
->prev
;
2122 ipc
->prev
= ipc
->next
= NULL
;
2126 static int isdn_ppp_set_compressor(struct ippp_struct
*is
,int num
)
2128 struct isdn_ppp_compressor
*ipc
= ipc_head
;
2131 if(ipc
->num
== num
) {
2133 is
->compressor
= ipc
;
2134 is
->link_compressor
= ipc
;
2143 static struct symbol_table isdn_ppp_syms
=
2145 #include <linux/symtab_begin.h>
2146 X(isdn_ppp_register_compressor
),
2147 X(isdn_ppp_unregister_compressor
),
2148 #include <linux/symtab_end.h>