Merge with Linux 2.4.0-test6-pre9.
[linux-2.6/linux-mips.git] / drivers / isdn / isdn_ppp.c
blob20499506114cdd2e76223cc0f69a8521061e3c39
1 /* $Id: isdn_ppp.c,v 1.77 2000/06/12 16:46:34 keil 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)
10 * any later version.
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.
23 #include <linux/config.h>
24 #define __NO_VERSION__
25 #include <linux/module.h>
26 #include <linux/version.h>
27 #include <linux/poll.h>
28 #include <linux/isdn.h>
29 #include <linux/ppp-comp.h>
31 #include "isdn_common.h"
32 #include "isdn_ppp.h"
33 #include "isdn_net.h"
35 #ifndef PPP_IPX
36 #define PPP_IPX 0x002b
37 #endif
39 /* set this if you use dynamic addressing */
41 /* Prototypes */
42 static int isdn_ppp_fill_rq(unsigned char *buf, int len, int proto, int slot);
43 static int isdn_ppp_closewait(int slot);
44 static void isdn_ppp_push_higher(isdn_net_dev * net_dev, isdn_net_local * lp,
45 struct sk_buff *skb, int proto);
46 static int isdn_ppp_if_get_unit(char *namebuf);
47 static int isdn_ppp_set_compressor(struct ippp_struct *is,struct isdn_ppp_comp_data *);
48 static struct sk_buff *isdn_ppp_decompress(struct sk_buff *,
49 struct ippp_struct *,struct ippp_struct *,int proto);
50 static void isdn_ppp_receive_ccp(isdn_net_dev * net_dev, isdn_net_local * lp,
51 struct sk_buff *skb,int proto);
52 static struct sk_buff *isdn_ppp_compress(struct sk_buff *skb_in,int *proto,
53 struct ippp_struct *is,struct ippp_struct *master,int type);
54 static void isdn_ppp_send_ccp(isdn_net_dev *net_dev, isdn_net_local *lp,
55 struct sk_buff *skb);
57 /* New CCP stuff */
58 static void isdn_ppp_ccp_kickup(struct ippp_struct *is);
59 static void isdn_ppp_ccp_xmit_reset(struct ippp_struct *is, int proto,
60 unsigned char code, unsigned char id,
61 unsigned char *data, int len);
62 static struct ippp_ccp_reset *isdn_ppp_ccp_reset_alloc(struct ippp_struct *is);
63 static void isdn_ppp_ccp_reset_free(struct ippp_struct *is);
64 static void isdn_ppp_ccp_reset_free_state(struct ippp_struct *is,
65 unsigned char id);
66 static void isdn_ppp_ccp_timer_callback(unsigned long closure);
67 static struct ippp_ccp_reset_state *isdn_ppp_ccp_reset_alloc_state(struct ippp_struct *is,
68 unsigned char id);
69 static void isdn_ppp_ccp_reset_trans(struct ippp_struct *is,
70 struct isdn_ppp_resetparams *rp);
71 static void isdn_ppp_ccp_reset_ack_rcvd(struct ippp_struct *is,
72 unsigned char id);
76 #ifdef CONFIG_ISDN_MPP
77 static ippp_bundle * isdn_ppp_bundle_arr = NULL;
79 static int isdn_ppp_mp_bundle_array_init(void);
80 static int isdn_ppp_mp_init( isdn_net_local * lp, ippp_bundle * add_to );
81 static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp,
82 struct sk_buff *skb);
83 static void isdn_ppp_mp_cleanup( isdn_net_local * lp );
85 static int isdn_ppp_bundle(struct ippp_struct *, int unit);
86 #endif /* CONFIG_ISDN_MPP */
88 char *isdn_ppp_revision = "$Revision: 1.77 $";
90 static struct ippp_struct *ippp_table[ISDN_MAX_CHANNELS];
92 static struct isdn_ppp_compressor *ipc_head = NULL;
95 * frame log (debug)
97 static void
98 isdn_ppp_frame_log(char *info, char *data, int len, int maxlen,int unit,int slot)
100 int cnt,
103 char buf[80];
105 if (len < maxlen)
106 maxlen = len;
108 for (i = 0, cnt = 0; cnt < maxlen; i++) {
109 for (j = 0; j < 16 && cnt < maxlen; j++, cnt++)
110 sprintf(buf + j * 3, "%02x ", (unsigned char) data[cnt]);
111 printk(KERN_DEBUG "[%d/%d].%s[%d]: %s\n",unit,slot, info, i, buf);
116 * unbind isdn_net_local <=> ippp-device
117 * note: it can happen, that we hangup/free the master before the slaves
118 * in this case we bind another lp to the master device
121 isdn_ppp_free(isdn_net_local * lp)
123 unsigned long flags;
124 struct ippp_struct *is;
126 if (lp->ppp_slot < 0 || lp->ppp_slot > ISDN_MAX_CHANNELS)
127 return 0;
129 save_flags(flags);
130 cli();
132 #ifdef CONFIG_ISDN_MPP
133 spin_lock(&lp->netdev->pb->lock);
134 #endif
135 isdn_net_rm_from_bundle(lp);
136 #ifdef CONFIG_ISDN_MPP
137 if (lp->netdev->pb->ref_ct == 1) /* last link in queue? */
138 isdn_ppp_mp_cleanup(lp);
140 lp->netdev->pb->ref_ct--;
141 spin_unlock(&lp->netdev->pb->lock);
142 #endif /* CONFIG_ISDN_MPP */
144 is = ippp_table[lp->ppp_slot];
145 if ((is->state & IPPP_CONNECT))
146 isdn_ppp_closewait(lp->ppp_slot); /* force wakeup on ippp device */
147 else if (is->state & IPPP_ASSIGNED)
148 is->state = IPPP_OPEN; /* fallback to 'OPEN but not ASSIGNED' state */
150 if (is->debug & 0x1)
151 printk(KERN_DEBUG "isdn_ppp_free %d %lx %lx\n", lp->ppp_slot, (long) lp, (long) is->lp);
153 is->lp = NULL; /* link is down .. set lp to NULL */
154 lp->ppp_slot = -1; /* is this OK ?? */
156 restore_flags(flags);
157 return 0;
161 * bind isdn_net_local <=> ippp-device
164 isdn_ppp_bind(isdn_net_local * lp)
166 int i;
167 int unit = 0;
168 long flags;
169 struct ippp_struct *is;
171 save_flags(flags);
172 cli();
173 if (lp->pppbind < 0) { /* device bounded to ippp device ? */
174 isdn_net_dev *net_dev = dev->netdev;
175 char exclusive[ISDN_MAX_CHANNELS]; /* exclusive flags */
176 memset(exclusive, 0, ISDN_MAX_CHANNELS);
177 while (net_dev) { /* step through net devices to find exclusive minors */
178 isdn_net_local *lp = net_dev->local;
179 if (lp->pppbind >= 0)
180 exclusive[lp->pppbind] = 1;
181 net_dev = net_dev->next;
184 * search a free device / slot
186 for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
187 if (ippp_table[i]->state == IPPP_OPEN && !exclusive[ippp_table[i]->minor]) { /* OPEN, but not connected! */
188 break;
191 } else {
192 for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
193 if (ippp_table[i]->minor == lp->pppbind &&
194 (ippp_table[i]->state & IPPP_OPEN) == IPPP_OPEN)
195 break;
199 if (i >= ISDN_MAX_CHANNELS) {
200 restore_flags(flags);
201 printk(KERN_WARNING "isdn_ppp_bind: Can't find a (free) connection to the ipppd daemon.\n");
202 return -1;
204 unit = isdn_ppp_if_get_unit(lp->name); /* get unit number from interface name .. ugly! */
205 if (unit < 0) {
206 printk(KERN_ERR "isdn_ppp_bind: illegal interface name %s.\n", lp->name);
207 return -1;
210 lp->ppp_slot = i;
211 is = ippp_table[i];
212 is->lp = lp;
213 is->unit = unit;
214 is->state = IPPP_OPEN | IPPP_ASSIGNED; /* assigned to a netdevice but not connected */
215 #ifdef CONFIG_ISDN_MPP
216 if (isdn_ppp_mp_init(lp, NULL) < 0)
217 return -ENOMEM;
218 #endif /* CONFIG_ISDN_MPP */
220 restore_flags(flags);
222 return lp->ppp_slot;
226 * kick the ipppd on the device
227 * (wakes up daemon after B-channel connect)
230 void
231 isdn_ppp_wakeup_daemon(isdn_net_local * lp)
233 if (lp->ppp_slot < 0 || lp->ppp_slot >= ISDN_MAX_CHANNELS)
234 return;
236 ippp_table[lp->ppp_slot]->state = IPPP_OPEN | IPPP_CONNECT | IPPP_NOBLOCK;
238 wake_up_interruptible(&ippp_table[lp->ppp_slot]->wq);
242 * there was a hangup on the netdevice
243 * force wakeup of the ippp device
244 * go into 'device waits for release' state
246 static int
247 isdn_ppp_closewait(int slot)
249 struct ippp_struct *is;
251 if (slot < 0 || slot >= ISDN_MAX_CHANNELS)
252 return 0;
253 is = ippp_table[slot];
255 if (is->state)
256 wake_up_interruptible(&is->wq);
258 is->state = IPPP_CLOSEWAIT;
259 return 1;
263 * isdn_ppp_find_slot / isdn_ppp_free_slot
266 static int
267 isdn_ppp_get_slot(void)
269 int i;
270 for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
271 if (!ippp_table[i]->state)
272 return i;
274 return -1;
278 * isdn_ppp_open
282 isdn_ppp_open(int min, struct file *file)
284 int slot;
285 struct ippp_struct *is;
287 if (min < 0 || min > ISDN_MAX_CHANNELS)
288 return -ENODEV;
290 slot = isdn_ppp_get_slot();
291 if (slot < 0) {
292 return -EBUSY;
294 is = file->private_data = ippp_table[slot];
296 printk(KERN_DEBUG "ippp, open, slot: %d, minor: %d, state: %04x\n", slot, min, is->state);
298 /* compression stuff */
299 is->link_compressor = is->compressor = NULL;
300 is->link_decompressor = is->decompressor = NULL;
301 is->link_comp_stat = is->comp_stat = NULL;
302 is->link_decomp_stat = is->decomp_stat = NULL;
303 is->compflags = 0;
305 is->reset = isdn_ppp_ccp_reset_alloc(is);
307 is->lp = NULL;
308 is->mp_seqno = 0; /* MP sequence number */
309 is->pppcfg = 0; /* ppp configuration */
310 is->mpppcfg = 0; /* mppp configuration */
311 is->last_link_seqno = -1; /* MP: maybe set to Bundle-MIN, when joining a bundle ?? */
312 is->unit = -1; /* set, when we have our interface */
313 is->mru = 1524; /* MRU, default 1524 */
314 is->maxcid = 16; /* VJ: maxcid */
315 is->tk = current;
316 init_waitqueue_head(&is->wq);
317 is->first = is->rq + NUM_RCV_BUFFS - 1; /* receive queue */
318 is->last = is->rq;
319 is->minor = min;
320 #ifdef CONFIG_ISDN_PPP_VJ
322 * VJ header compression init
324 is->slcomp = slhc_init(16, 16); /* not necessary for 2. link in bundle */
325 #endif
327 is->state = IPPP_OPEN;
329 return 0;
333 * release ippp device
335 void
336 isdn_ppp_release(int min, struct file *file)
338 int i;
339 struct ippp_struct *is;
341 if (min < 0 || min >= ISDN_MAX_CHANNELS)
342 return;
343 is = file->private_data;
345 if (is->debug & 0x1)
346 printk(KERN_DEBUG "ippp: release, minor: %d %lx\n", min, (long) is->lp);
348 if (is->lp) { /* a lp address says: this link is still up */
349 isdn_net_dev *p = is->lp->netdev;
351 is->state &= ~IPPP_CONNECT; /* -> effect: no call of wakeup */
353 * isdn_net_hangup() calls isdn_ppp_free()
354 * isdn_ppp_free() sets is->lp to NULL and lp->ppp_slot to -1
355 * removing the IPPP_CONNECT flag omits calling of isdn_ppp_wakeup_daemon()
357 isdn_net_hangup(&p->dev);
359 for (i = 0; i < NUM_RCV_BUFFS; i++) {
360 if (is->rq[i].buf) {
361 kfree(is->rq[i].buf);
362 is->rq[i].buf = NULL;
365 is->first = is->rq + NUM_RCV_BUFFS - 1; /* receive queue */
366 is->last = is->rq;
368 #ifdef CONFIG_ISDN_PPP_VJ
369 /* TODO: if this was the previous master: link the slcomp to the new master */
370 slhc_free(is->slcomp);
371 is->slcomp = NULL;
372 #endif
374 /* TODO: if this was the previous master: link the the stuff to the new master */
375 if(is->comp_stat)
376 is->compressor->free(is->comp_stat);
377 if(is->link_comp_stat)
378 is->link_compressor->free(is->link_comp_stat);
379 if(is->link_decomp_stat)
380 is->link_decompressor->free(is->link_decomp_stat);
381 if(is->decomp_stat)
382 is->decompressor->free(is->decomp_stat);
383 is->compressor = is->link_compressor = NULL;
384 is->decompressor = is->link_decompressor = NULL;
385 is->comp_stat = is->link_comp_stat = NULL;
386 is->decomp_stat = is->link_decomp_stat = NULL;
388 /* Clean up if necessary */
389 if(is->reset)
390 isdn_ppp_ccp_reset_free(is);
392 /* this slot is ready for new connections */
393 is->state = 0;
397 * get_arg .. ioctl helper
399 static int
400 get_arg(void *b, void *val, int len)
402 if (len <= 0)
403 len = sizeof(void *);
404 if (copy_from_user((void *) val, b, len))
405 return -EFAULT;
406 return 0;
410 * set arg .. ioctl helper
412 static int
413 set_arg(void *b, void *val,int len)
415 if(len <= 0)
416 len = sizeof(void *);
417 if (copy_to_user(b, (void *) val, len))
418 return -EFAULT;
419 return 0;
423 * ippp device ioctl
426 isdn_ppp_ioctl(int min, struct file *file, unsigned int cmd, unsigned long arg)
428 unsigned long val;
429 int r,i,j;
430 struct ippp_struct *is;
431 isdn_net_local *lp;
432 struct isdn_ppp_comp_data data;
434 is = (struct ippp_struct *) file->private_data;
435 lp = is->lp;
437 if (is->debug & 0x1)
438 printk(KERN_DEBUG "isdn_ppp_ioctl: minor: %d cmd: %x state: %x\n", min, cmd, is->state);
440 if (!(is->state & IPPP_OPEN))
441 return -EINVAL;
443 switch (cmd) {
444 case PPPIOCBUNDLE:
445 #ifdef CONFIG_ISDN_MPP
446 if (!(is->state & IPPP_CONNECT))
447 return -EINVAL;
448 if ((r = get_arg((void *) arg, &val, sizeof(val) )))
449 return r;
450 printk(KERN_DEBUG "iPPP-bundle: minor: %d, slave unit: %d, master unit: %d\n",
451 (int) min, (int) is->unit, (int) val);
452 return isdn_ppp_bundle(is, val);
453 #else
454 return -1;
455 #endif
456 break;
457 case PPPIOCGUNIT: /* get ppp/isdn unit number */
458 if ((r = set_arg((void *) arg, &is->unit, sizeof(is->unit) )))
459 return r;
460 break;
461 case PPPIOCGIFNAME:
462 if(!lp)
463 return -EINVAL;
464 if ((r = set_arg((void *) arg, lp->name, strlen(lp->name))))
465 return r;
466 break;
467 case PPPIOCGMPFLAGS: /* get configuration flags */
468 if ((r = set_arg((void *) arg, &is->mpppcfg, sizeof(is->mpppcfg) )))
469 return r;
470 break;
471 case PPPIOCSMPFLAGS: /* set configuration flags */
472 if ((r = get_arg((void *) arg, &val, sizeof(val) )))
473 return r;
474 is->mpppcfg = val;
475 break;
476 case PPPIOCGFLAGS: /* get configuration flags */
477 if ((r = set_arg((void *) arg, &is->pppcfg,sizeof(is->pppcfg) )))
478 return r;
479 break;
480 case PPPIOCSFLAGS: /* set configuration flags */
481 if ((r = get_arg((void *) arg, &val, sizeof(val) ))) {
482 return r;
484 if (val & SC_ENABLE_IP && !(is->pppcfg & SC_ENABLE_IP) && (is->state & IPPP_CONNECT)) {
485 if (lp) {
486 /* OK .. we are ready to send buffers */
487 netif_wake_queue(&lp->netdev->dev);
490 is->pppcfg = val;
491 break;
492 case PPPIOCGIDLE: /* get idle time information */
493 if (lp) {
494 struct ppp_idle pidle;
495 pidle.xmit_idle = pidle.recv_idle = lp->huptimer;
496 if ((r = set_arg((void *) arg, &pidle,sizeof(struct ppp_idle))))
497 return r;
499 break;
500 case PPPIOCSMRU: /* set receive unit size for PPP */
501 if ((r = get_arg((void *) arg, &val, sizeof(val) )))
502 return r;
503 is->mru = val;
504 break;
505 case PPPIOCSMPMRU:
506 break;
507 case PPPIOCSMPMTU:
508 break;
509 case PPPIOCSMAXCID: /* set the maximum compression slot id */
510 if ((r = get_arg((void *) arg, &val, sizeof(val) )))
511 return r;
512 val++;
513 if (is->maxcid != val) {
514 #ifdef CONFIG_ISDN_PPP_VJ
515 struct slcompress *sltmp;
516 #endif
517 if (is->debug & 0x1)
518 printk(KERN_DEBUG "ippp, ioctl: changed MAXCID to %ld\n", val);
519 is->maxcid = val;
520 #ifdef CONFIG_ISDN_PPP_VJ
521 sltmp = slhc_init(16, val);
522 if (!sltmp) {
523 printk(KERN_ERR "ippp, can't realloc slhc struct\n");
524 return -ENOMEM;
526 if (is->slcomp)
527 slhc_free(is->slcomp);
528 is->slcomp = sltmp;
529 #endif
531 break;
532 case PPPIOCGDEBUG:
533 if ((r = set_arg((void *) arg, &is->debug, sizeof(is->debug) )))
534 return r;
535 break;
536 case PPPIOCSDEBUG:
537 if ((r = get_arg((void *) arg, &val, sizeof(val) )))
538 return r;
539 is->debug = val;
540 break;
541 case PPPIOCGCOMPRESSORS:
543 unsigned long protos[8] = {0,};
544 struct isdn_ppp_compressor *ipc = ipc_head;
545 while(ipc) {
546 j = ipc->num / (sizeof(long)*8);
547 i = ipc->num % (sizeof(long)*8);
548 if(j < 8)
549 protos[j] |= (0x1<<i);
550 ipc = ipc->next;
552 if ((r = set_arg((void *) arg,protos,8*sizeof(long) )))
553 return r;
555 break;
556 case PPPIOCSCOMPRESSOR:
557 if ((r = get_arg((void *) arg, &data, sizeof(struct isdn_ppp_comp_data))))
558 return r;
559 return isdn_ppp_set_compressor(is, &data);
560 case PPPIOCGCALLINFO:
562 struct pppcallinfo pci;
563 memset((char *) &pci,0,sizeof(struct pppcallinfo));
564 if(lp)
566 strncpy(pci.local_num,lp->msn,63);
567 if(lp->dial) {
568 strncpy(pci.remote_num,lp->dial->num,63);
570 pci.charge_units = lp->charge;
571 if(lp->outgoing)
572 pci.calltype = CALLTYPE_OUTGOING;
573 else
574 pci.calltype = CALLTYPE_INCOMING;
575 if(lp->flags & ISDN_NET_CALLBACK)
576 pci.calltype |= CALLTYPE_CALLBACK;
578 return set_arg((void *)arg,&pci,sizeof(struct pppcallinfo));
580 default:
581 break;
583 return 0;
586 unsigned int
587 isdn_ppp_poll(struct file *file, poll_table * wait)
589 unsigned int mask;
590 struct ippp_buf_queue *bf;
591 struct ippp_buf_queue *bl;
592 unsigned long flags;
593 struct ippp_struct *is;
595 is = file->private_data;
597 if (is->debug & 0x2)
598 printk(KERN_DEBUG "isdn_ppp_poll: minor: %d\n",
599 MINOR(file->f_dentry->d_inode->i_rdev));
601 /* just registers wait_queue hook. This doesn't really wait. */
602 poll_wait(file, &is->wq, wait);
604 if (!(is->state & IPPP_OPEN)) {
605 if(is->state == IPPP_CLOSEWAIT)
606 return POLLHUP;
607 printk(KERN_DEBUG "isdn_ppp: device not open\n");
608 return POLLERR;
610 /* we're always ready to send .. */
611 mask = POLLOUT | POLLWRNORM;
613 save_flags(flags);
614 cli();
615 bl = is->last;
616 bf = is->first;
618 * if IPPP_NOBLOCK is set we return even if we have nothing to read
620 if (bf->next != bl || (is->state & IPPP_NOBLOCK)) {
621 is->state &= ~IPPP_NOBLOCK;
622 mask |= POLLIN | POLLRDNORM;
624 restore_flags(flags);
625 return mask;
629 * fill up isdn_ppp_read() queue ..
632 static int
633 isdn_ppp_fill_rq(unsigned char *buf, int len, int proto, int slot)
635 struct ippp_buf_queue *bf,
636 *bl;
637 unsigned long flags;
638 unsigned char *nbuf;
639 struct ippp_struct *is;
641 if (slot < 0 || slot >= ISDN_MAX_CHANNELS) {
642 printk(KERN_WARNING "ippp: illegal slot.\n");
643 return 0;
645 is = ippp_table[slot];
647 if (!(is->state & IPPP_CONNECT)) {
648 printk(KERN_DEBUG "ippp: device not activated.\n");
649 return 0;
651 nbuf = (unsigned char *) kmalloc(len + 4, GFP_ATOMIC);
652 if (!nbuf) {
653 printk(KERN_WARNING "ippp: Can't alloc buf\n");
654 return 0;
656 nbuf[0] = PPP_ALLSTATIONS;
657 nbuf[1] = PPP_UI;
658 nbuf[2] = proto >> 8;
659 nbuf[3] = proto & 0xff;
660 memcpy(nbuf + 4, buf, len);
662 save_flags(flags);
663 cli();
665 bf = is->first;
666 bl = is->last;
668 if (bf == bl) {
669 printk(KERN_WARNING "ippp: Queue is full; discarding first buffer\n");
670 bf = bf->next;
671 kfree(bf->buf);
672 is->first = bf;
674 bl->buf = (char *) nbuf;
675 bl->len = len + 4;
677 is->last = bl->next;
678 restore_flags(flags);
680 wake_up_interruptible(&is->wq);
682 return len;
686 * read() .. non-blocking: ipppd calls it only after select()
687 * reports, that there is data
691 isdn_ppp_read(int min, struct file *file, char *buf, int count)
693 struct ippp_struct *is;
694 struct ippp_buf_queue *b;
695 int r;
696 unsigned long flags;
697 unsigned char *save_buf;
699 is = file->private_data;
701 if (!(is->state & IPPP_OPEN))
702 return 0;
704 if ((r = verify_area(VERIFY_WRITE, (void *) buf, count)))
705 return r;
707 save_flags(flags);
708 cli();
710 b = is->first->next;
711 save_buf = b->buf;
712 if (!save_buf) {
713 restore_flags(flags);
714 return -EAGAIN;
716 if (b->len < count)
717 count = b->len;
718 b->buf = NULL;
719 is->first = b;
721 restore_flags(flags);
723 copy_to_user(buf, save_buf, count);
724 kfree(save_buf);
726 return count;
730 * ipppd wanna write a packet to the card .. non-blocking
734 isdn_ppp_write(int min, struct file *file, const char *buf, int count)
736 isdn_net_local *lp;
737 struct ippp_struct *is;
738 int proto;
739 unsigned char protobuf[4];
741 is = file->private_data;
743 if (!(is->state & IPPP_CONNECT))
744 return 0;
746 lp = is->lp;
748 /* -> push it directly to the lowlevel interface */
750 if (!lp)
751 printk(KERN_DEBUG "isdn_ppp_write: lp == NULL\n");
752 else {
754 * Don't reset huptimer for
755 * LCP packets. (Echo requests).
757 if (copy_from_user(protobuf, buf, 4))
758 return -EFAULT;
759 proto = PPP_PROTOCOL(protobuf);
760 if (proto != PPP_LCP)
761 lp->huptimer = 0;
763 if (lp->isdn_device < 0 || lp->isdn_channel < 0)
764 return 0;
766 if ((dev->drv[lp->isdn_device]->flags & DRV_FLAG_RUNNING) &&
767 lp->dialstate == 0 &&
768 (lp->flags & ISDN_NET_CONNECTED)) {
769 unsigned short hl;
770 struct sk_buff *skb;
772 * we need to reserve enought space in front of
773 * sk_buff. old call to dev_alloc_skb only reserved
774 * 16 bytes, now we are looking what the driver want
776 hl = dev->drv[lp->isdn_device]->interface->hl_hdrlen;
777 skb = alloc_skb(hl+count, GFP_ATOMIC);
778 if (!skb) {
779 printk(KERN_WARNING "isdn_ppp_write: out of memory!\n");
780 return count;
782 skb_reserve(skb, hl);
783 if (copy_from_user(skb_put(skb, count), buf, count))
784 return -EFAULT;
785 if (is->debug & 0x40) {
786 printk(KERN_DEBUG "ppp xmit: len %d\n", (int) skb->len);
787 isdn_ppp_frame_log("xmit", skb->data, skb->len, 32,is->unit,lp->ppp_slot);
790 isdn_ppp_send_ccp(lp->netdev,lp,skb); /* keeps CCP/compression states in sync */
792 isdn_net_write_super(lp, skb);
795 return count;
799 * init memory, structures etc.
803 isdn_ppp_init(void)
805 int i,
808 #ifdef CONFIG_ISDN_MPP
809 if( isdn_ppp_mp_bundle_array_init() < 0 )
810 return -ENOMEM;
811 #endif /* CONFIG_ISDN_MPP */
813 for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
814 if (!(ippp_table[i] = (struct ippp_struct *)
815 kmalloc(sizeof(struct ippp_struct), GFP_KERNEL))) {
816 printk(KERN_WARNING "isdn_ppp_init: Could not alloc ippp_table\n");
817 for (j = 0; j < i; j++)
818 kfree(ippp_table[i]);
819 return -1;
821 memset((char *) ippp_table[i], 0, sizeof(struct ippp_struct));
822 ippp_table[i]->state = 0;
823 ippp_table[i]->first = ippp_table[i]->rq + NUM_RCV_BUFFS - 1;
824 ippp_table[i]->last = ippp_table[i]->rq;
826 for (j = 0; j < NUM_RCV_BUFFS; j++) {
827 ippp_table[i]->rq[j].buf = NULL;
828 ippp_table[i]->rq[j].last = ippp_table[i]->rq +
829 (NUM_RCV_BUFFS + j - 1) % NUM_RCV_BUFFS;
830 ippp_table[i]->rq[j].next = ippp_table[i]->rq + (j + 1) % NUM_RCV_BUFFS;
833 return 0;
836 void
837 isdn_ppp_cleanup(void)
839 int i;
841 for (i = 0; i < ISDN_MAX_CHANNELS; i++)
842 kfree(ippp_table[i]);
844 #ifdef CONFIG_ISDN_MPP
845 if (isdn_ppp_bundle_arr)
846 kfree(isdn_ppp_bundle_arr);
847 #endif /* CONFIG_ISDN_MPP */
852 * get the PPP protocol header and pull skb
854 static int isdn_ppp_strip_proto(struct sk_buff *skb)
856 int proto;
857 if (skb->data[0] & 0x1) {
858 proto = skb->data[0];
859 skb_pull(skb, 1); /* protocol ID is only 8 bit */
860 } else {
861 proto = ((int) skb->data[0] << 8) + skb->data[1];
862 skb_pull(skb, 2);
864 return proto;
869 * handler for incoming packets on a syncPPP interface
871 void isdn_ppp_receive(isdn_net_dev * net_dev, isdn_net_local * lp, struct sk_buff *skb)
873 struct ippp_struct *is;
874 int slot;
875 int proto;
877 slot = lp->ppp_slot;
878 if (slot < 0 || slot > ISDN_MAX_CHANNELS) {
879 printk(KERN_ERR "isdn_ppp_receive: lp->ppp_slot %d\n", lp->ppp_slot);
880 kfree_skb(skb);
881 return;
883 is = ippp_table[slot];
885 if (is->debug & 0x4) {
886 printk(KERN_DEBUG "ippp_receive: is:%08lx lp:%08lx slot:%d unit:%d len:%d\n",
887 (long)is,(long)lp,lp->ppp_slot,is->unit,(int) skb->len);
888 isdn_ppp_frame_log("receive", skb->data, skb->len, 32,is->unit,lp->ppp_slot);
890 if (net_dev->local->master) {
891 printk(KERN_WARNING "isdn_ppp_receive: net_dev != master\n");
892 net_dev = ((isdn_net_local *) net_dev->local->master->priv)->netdev;
894 if (skb->data[0] == 0xff && skb->data[1] == 0x03)
895 skb_pull(skb, 2);
896 else if (is->pppcfg & SC_REJ_COMP_AC) {
897 dev_kfree_skb(skb);
898 return; /* discard it silently */
901 proto = isdn_ppp_strip_proto(skb);
903 #ifdef CONFIG_ISDN_MPP
904 if (!(is->mpppcfg & SC_REJ_MP_PROT)) {
906 if(is->compflags & SC_LINK_DECOMP_ON) {
907 if(proto == PPP_COMPFRAG) {
908 if(is->debug & 0x10)
909 printk(KERN_DEBUG "received single link compressed frame\n");
910 skb = isdn_ppp_decompress(skb,is,NULL,proto);
911 if(!skb)
912 return;
913 proto = isdn_ppp_strip_proto(skb);
915 else
916 isdn_ppp_decompress(skb,is,NULL,proto);
919 if (proto == PPP_MP) {
920 isdn_ppp_mp_receive(net_dev, lp, skb);
922 else
923 isdn_ppp_push_higher(net_dev, lp, skb, proto);
924 } else
925 #endif /* CONFIG_ISDN_MPP */
926 isdn_ppp_push_higher(net_dev, lp, skb, proto);
930 * push frame to higher layers
931 * note: net_dev has to be master net_dev
933 static void
934 isdn_ppp_push_higher(isdn_net_dev * net_dev, isdn_net_local * lp, struct sk_buff *skb, int proto)
936 struct net_device *dev = &net_dev->dev;
937 struct ippp_struct *is;
938 int slot;
940 slot = lp->ppp_slot;
941 if (slot < 0 || slot > ISDN_MAX_CHANNELS) {
942 printk(KERN_ERR "isdn_ppp_push_higher: lp->ppp_slot %d\n", lp->ppp_slot);
943 kfree_skb(skb);
944 return;
946 is = ippp_table[slot];
947 if (is->debug & 0x10) {
948 printk(KERN_DEBUG "push, skb %d %04x\n", (int) skb->len, proto);
949 isdn_ppp_frame_log("rpush", skb->data, skb->len, 32,is->unit,lp->ppp_slot);
952 if(proto == PPP_COMP) {
953 if(!lp->master)
954 skb = isdn_ppp_decompress(skb,is,is,proto);
955 else
956 skb = isdn_ppp_decompress(skb,is,ippp_table[((isdn_net_local *) (lp->master->priv))->ppp_slot],proto);
958 if(!skb) {
959 printk(KERN_DEBUG "ippp: compressed frame discarded!\n");
960 return;
963 proto = isdn_ppp_strip_proto(skb);
964 if (is->debug & 0x10) {
965 printk(KERN_DEBUG "RPostDecomp, skb %d %04x\n", (int) skb->len, proto);
966 isdn_ppp_frame_log("R-Decomp", skb->data, skb->len, 32,is->unit,lp->ppp_slot);
969 else if(is->compflags & SC_DECOMP_ON) { /* If decomp is ON */
970 if(!lp->master)
971 isdn_ppp_decompress(skb,is,is,proto);
972 else
973 isdn_ppp_decompress(skb,is,ippp_table[((isdn_net_local *) (lp->master->priv))->ppp_slot],proto);
976 switch (proto) {
977 case PPP_IPX: /* untested */
978 if (is->debug & 0x20)
979 printk(KERN_DEBUG "isdn_ppp: IPX\n");
980 skb->dev = dev;
981 skb->mac.raw = skb->data;
982 skb->protocol = htons(ETH_P_IPX);
983 break;
984 #ifdef CONFIG_ISDN_PPP_VJ
985 case PPP_VJC_UNCOMP:
986 if (is->debug & 0x20)
987 printk(KERN_DEBUG "isdn_ppp: VJC_UNCOMP\n");
988 if (slhc_remember(ippp_table[net_dev->local->ppp_slot]->slcomp, skb->data, skb->len) <= 0) {
989 printk(KERN_WARNING "isdn_ppp: received illegal VJC_UNCOMP frame!\n");
990 net_dev->local->stats.rx_dropped++;
991 dev_kfree_skb(skb);
992 return;
994 #endif
995 case PPP_IP:
996 if (is->debug & 0x20)
997 printk(KERN_DEBUG "isdn_ppp: IP\n");
998 skb->dev = dev;
999 skb->mac.raw = skb->data;
1000 skb->protocol = htons(ETH_P_IP);
1001 break;
1002 case PPP_VJC_COMP:
1003 if (is->debug & 0x20)
1004 printk(KERN_DEBUG "isdn_ppp: VJC_COMP\n");
1005 #ifdef CONFIG_ISDN_PPP_VJ
1007 struct sk_buff *skb_old = skb;
1008 int pkt_len;
1009 skb = dev_alloc_skb(skb_old->len + 128);
1011 if (!skb) {
1012 printk(KERN_WARNING "%s: Memory squeeze, dropping packet.\n", dev->name);
1013 net_dev->local->stats.rx_dropped++;
1014 dev_kfree_skb(skb_old);
1015 return;
1017 skb->dev = dev;
1018 skb_put(skb, skb_old->len + 128);
1019 memcpy(skb->data, skb_old->data, skb_old->len);
1020 skb->mac.raw = skb->data;
1021 pkt_len = slhc_uncompress(ippp_table[net_dev->local->ppp_slot]->slcomp,
1022 skb->data, skb_old->len);
1023 dev_kfree_skb(skb_old);
1024 if (pkt_len < 0) {
1025 dev_kfree_skb(skb);
1026 lp->stats.rx_dropped++;
1027 return;
1029 skb_trim(skb, pkt_len);
1030 skb->protocol = htons(ETH_P_IP);
1032 #else
1033 printk(KERN_INFO "isdn: Ooopsa .. VJ-Compression support not compiled into isdn driver.\n");
1034 lp->stats.rx_dropped++;
1035 dev_kfree_skb(skb);
1036 return;
1037 #endif
1038 break;
1039 case PPP_CCP:
1040 case PPP_CCPFRAG:
1041 isdn_ppp_receive_ccp(net_dev,lp,skb,proto);
1042 /* Dont pop up ResetReq/Ack stuff to the daemon any
1043 longer - the job is done already */
1044 if(skb->data[0] == CCP_RESETREQ ||
1045 skb->data[0] == CCP_RESETACK)
1046 break;
1047 /* fall through */
1048 default:
1049 isdn_ppp_fill_rq(skb->data, skb->len, proto, lp->ppp_slot); /* push data to pppd device */
1050 dev_kfree_skb(skb);
1051 return;
1054 /* Reset hangup-timer */
1055 lp->huptimer = 0;
1056 netif_rx(skb);
1057 /* net_dev->local->stats.rx_packets++; *//* done in isdn_net.c */
1059 return;
1063 * isdn_ppp_skb_push ..
1064 * checks whether we have enough space at the beginning of the SKB
1065 * and allocs a new SKB if necessary
1067 static unsigned char *isdn_ppp_skb_push(struct sk_buff **skb_p,int len)
1069 struct sk_buff *skb = *skb_p;
1071 if(skb_headroom(skb) < len) {
1072 struct sk_buff *nskb = skb_realloc_headroom(skb, len);
1074 if (!nskb) {
1075 printk(KERN_ERR "isdn_ppp_skb_push: can't realloc headroom!\n");
1076 dev_kfree_skb(skb);
1077 return NULL;
1079 printk(KERN_DEBUG "isdn_ppp_skb_push:under %d %d\n",skb_headroom(skb),len);
1080 dev_kfree_skb(skb);
1081 *skb_p = nskb;
1082 return skb_push(nskb, len);
1084 return skb_push(skb,len);
1089 * send ppp frame .. we expect a PIDCOMPressable proto --
1090 * (here: currently always PPP_IP,PPP_VJC_COMP,PPP_VJC_UNCOMP)
1092 * VJ compression may change skb pointer!!! .. requeue with old
1093 * skb isn't allowed!!
1097 isdn_ppp_xmit(struct sk_buff *skb, struct net_device *netdev)
1099 isdn_net_local *lp,*mlp;
1100 isdn_net_dev *nd;
1101 unsigned int proto = PPP_IP; /* 0x21 */
1102 struct ippp_struct *ipt,*ipts;
1103 int slot;
1105 mlp = (isdn_net_local *) (netdev->priv);
1106 nd = mlp->netdev; /* get master lp */
1108 slot = mlp->ppp_slot;
1109 if (slot < 0 || slot > ISDN_MAX_CHANNELS) {
1110 printk(KERN_ERR "isdn_ppp_xmit: lp->ppp_slot %d\n", mlp->ppp_slot);
1111 kfree_skb(skb);
1112 return 0;
1114 ipts = ippp_table[slot];
1116 if (!(ipts->pppcfg & SC_ENABLE_IP)) { /* PPP connected ? */
1117 if (ipts->debug & 0x1)
1118 printk(KERN_INFO "%s: IP frame delayed.\n", netdev->name);
1119 return 1;
1122 switch (ntohs(skb->protocol)) {
1123 case ETH_P_IP:
1124 proto = PPP_IP;
1125 break;
1126 case ETH_P_IPX:
1127 proto = PPP_IPX; /* untested */
1128 break;
1129 default:
1130 dev_kfree_skb(skb);
1131 printk(KERN_ERR "isdn_ppp: skipped unsupported protocol: %#x.\n",
1132 skb->protocol);
1133 return 0;
1136 lp = isdn_net_get_locked_lp(nd);
1137 if (!lp) {
1138 printk(KERN_WARNING "%s: all channels busy - requeuing!\n", netdev->name);
1139 return 1;
1141 /* we have our lp locked from now on */
1143 slot = lp->ppp_slot;
1144 if (slot < 0 || slot > ISDN_MAX_CHANNELS) {
1145 printk(KERN_ERR "isdn_ppp_xmit: lp->ppp_slot %d\n", lp->ppp_slot);
1146 kfree_skb(skb);
1147 return 0;
1149 ipt = ippp_table[slot];
1150 lp->huptimer = 0;
1153 * after this line .. requeueing in the device queue is no longer allowed!!!
1156 /* Pull off the fake header we stuck on earlier to keep
1157 * the fragmentation code happy.
1159 skb_pull(skb,IPPP_MAX_HEADER);
1161 if (ipt->debug & 0x4)
1162 printk(KERN_DEBUG "xmit skb, len %d\n", (int) skb->len);
1163 if (ipts->debug & 0x40)
1164 isdn_ppp_frame_log("xmit0", skb->data, skb->len, 32,ipts->unit,lp->ppp_slot);
1166 #ifdef CONFIG_ISDN_PPP_VJ
1167 if (proto == PPP_IP && ipts->pppcfg & SC_COMP_TCP) { /* ipts here? probably yes, but check this again */
1168 struct sk_buff *new_skb;
1169 unsigned short hl;
1171 * we need to reserve enought space in front of
1172 * sk_buff. old call to dev_alloc_skb only reserved
1173 * 16 bytes, now we are looking what the driver want.
1175 hl = dev->drv[lp->isdn_device]->interface->hl_hdrlen + IPPP_MAX_HEADER;
1177 * Note: hl might still be insufficient because the method
1178 * above does not account for a possibible MPPP slave channel
1179 * which had larger HL header space requirements than the
1180 * master.
1182 new_skb = alloc_skb(hl+skb->len, GFP_ATOMIC);
1183 if (new_skb) {
1184 u_char *buf;
1185 int pktlen;
1187 skb_reserve(new_skb, hl);
1188 new_skb->dev = skb->dev;
1189 skb_put(new_skb, skb->len);
1190 buf = skb->data;
1192 pktlen = slhc_compress(ipts->slcomp, skb->data, skb->len, new_skb->data,
1193 &buf, !(ipts->pppcfg & SC_NO_TCP_CCID));
1195 if (buf != skb->data) {
1196 if (new_skb->data != buf)
1197 printk(KERN_ERR "isdn_ppp: FATAL error after slhc_compress!!\n");
1198 dev_kfree_skb(skb);
1199 skb = new_skb;
1200 } else {
1201 dev_kfree_skb(new_skb);
1204 skb_trim(skb, pktlen);
1205 if (skb->data[0] & SL_TYPE_COMPRESSED_TCP) { /* cslip? style -> PPP */
1206 proto = PPP_VJC_COMP;
1207 skb->data[0] ^= SL_TYPE_COMPRESSED_TCP;
1208 } else {
1209 if (skb->data[0] >= SL_TYPE_UNCOMPRESSED_TCP)
1210 proto = PPP_VJC_UNCOMP;
1211 skb->data[0] = (skb->data[0] & 0x0f) | 0x40;
1215 #endif
1218 * normal (single link) or bundle compression
1220 if(ipts->compflags & SC_COMP_ON)
1221 skb = isdn_ppp_compress(skb,&proto,ipt,ipts,0);
1223 if (ipt->debug & 0x24)
1224 printk(KERN_DEBUG "xmit2 skb, len %d, proto %04x\n", (int) skb->len, proto);
1226 #ifdef CONFIG_ISDN_MPP
1227 if (ipt->mpppcfg & SC_MP_PROT) {
1228 /* we get mp_seqno from static isdn_net_local */
1229 long mp_seqno = ipts->mp_seqno;
1230 ipts->mp_seqno++;
1231 if (ipt->mpppcfg & SC_OUT_SHORT_SEQ) {
1232 unsigned char *data = isdn_ppp_skb_push(&skb, 3);
1233 if(!data)
1234 goto unlock;
1235 mp_seqno &= 0xfff;
1236 data[0] = MP_BEGIN_FRAG | MP_END_FRAG | ((mp_seqno >> 8) & 0xf); /* (B)egin & (E)ndbit .. */
1237 data[1] = mp_seqno & 0xff;
1238 data[2] = proto; /* PID compression */
1239 } else {
1240 unsigned char *data = isdn_ppp_skb_push(&skb, 5);
1241 if(!data)
1242 goto unlock;
1243 data[0] = MP_BEGIN_FRAG | MP_END_FRAG; /* (B)egin & (E)ndbit .. */
1244 data[1] = (mp_seqno >> 16) & 0xff; /* sequence number: 24bit */
1245 data[2] = (mp_seqno >> 8) & 0xff;
1246 data[3] = (mp_seqno >> 0) & 0xff;
1247 data[4] = proto; /* PID compression */
1249 proto = PPP_MP; /* MP Protocol, 0x003d */
1251 #endif
1254 * 'link in bundle' compression ...
1256 if(ipt->compflags & SC_LINK_COMP_ON)
1257 skb = isdn_ppp_compress(skb,&proto,ipt,ipts,1);
1259 if( (ipt->pppcfg & SC_COMP_PROT) && (proto <= 0xff) ) {
1260 unsigned char *data = isdn_ppp_skb_push(&skb,1);
1261 if(!data)
1262 goto unlock;
1263 data[0] = proto & 0xff;
1265 else {
1266 unsigned char *data = isdn_ppp_skb_push(&skb,2);
1267 if(!data)
1268 goto unlock;
1269 data[0] = (proto >> 8) & 0xff;
1270 data[1] = proto & 0xff;
1272 if(!(ipt->pppcfg & SC_COMP_AC)) {
1273 unsigned char *data = isdn_ppp_skb_push(&skb,2);
1274 if(!data)
1275 goto unlock;
1276 data[0] = 0xff; /* All Stations */
1277 data[1] = 0x03; /* Unnumbered information */
1280 /* tx-stats are now updated via BSENT-callback */
1282 if (ipts->debug & 0x40) {
1283 printk(KERN_DEBUG "skb xmit: len: %d\n", (int) skb->len);
1284 isdn_ppp_frame_log("xmit", skb->data, skb->len, 32,ipt->unit,lp->ppp_slot);
1287 isdn_net_writebuf_skb(lp, skb);
1289 unlock:
1290 spin_unlock_bh(&lp->xmit_lock);
1291 return 0;
1294 #ifdef CONFIG_ISDN_MPP
1296 /* this is _not_ rfc1990 header, but something we convert both short and long
1297 * headers to for convinience's sake:
1298 * byte 0 is flags as in rfc1990
1299 * bytes 1...4 is 24-bit seqence number converted to host byte order
1301 #define MP_HEADER_LEN 5
1303 #define MP_LONGSEQ_MASK 0x00ffffff
1304 #define MP_SHORTSEQ_MASK 0x00000fff
1305 #define MP_LONGSEQ_MAX MP_LONGSEQ_MASK
1306 #define MP_SHORTSEQ_MAX MP_SHORTSEQ_MASK
1307 #define MP_LONGSEQ_MAXBIT ((MP_LONGSEQ_MASK+1)>>1)
1308 #define MP_SHORTSEQ_MAXBIT ((MP_SHORTSEQ_MASK+1)>>1)
1310 /* sequence-wrap safe comparisions (for long sequence)*/
1311 #define MP_LT(a,b) ((a-b)&MP_LONGSEQ_MAXBIT)
1312 #define MP_LE(a,b) !((b-a)&MP_LONGSEQ_MAXBIT)
1313 #define MP_GT(a,b) ((b-a)&MP_LONGSEQ_MAXBIT)
1314 #define MP_GE(a,b) !((a-b)&MP_LONGSEQ_MAXBIT)
1316 #define MP_SEQ(f) ((*(u32*)(f->data+1)))
1317 #define MP_FLAGS(f) (f->data[0])
1319 static int isdn_ppp_mp_bundle_array_init(void)
1321 int i;
1322 int sz = ISDN_MAX_CHANNELS*sizeof(ippp_bundle);
1323 if( (isdn_ppp_bundle_arr = (ippp_bundle*)kmalloc(sz,
1324 GFP_KERNEL)) == NULL )
1325 return -ENOMEM;
1326 memset(isdn_ppp_bundle_arr, 0, sz);
1327 for( i = 0; i < ISDN_MAX_CHANNELS; i++ )
1328 spin_lock_init(&isdn_ppp_bundle_arr[i].lock);
1329 return 0;
1332 static ippp_bundle * isdn_ppp_mp_bundle_alloc(void)
1334 int i;
1335 for( i = 0; i < ISDN_MAX_CHANNELS; i++ )
1336 if (isdn_ppp_bundle_arr[i].ref_ct <= 0)
1337 return (isdn_ppp_bundle_arr + i);
1338 return NULL;
1341 static int isdn_ppp_mp_init( isdn_net_local * lp, ippp_bundle * add_to )
1343 struct ippp_struct * is = ippp_table[lp->ppp_slot];
1345 if (add_to) {
1346 if( lp->netdev->pb )
1347 lp->netdev->pb->ref_ct--;
1348 lp->netdev->pb = add_to;
1349 } else { /* first link in a bundle */
1350 is->mp_seqno = 0;
1351 if ((lp->netdev->pb = isdn_ppp_mp_bundle_alloc()) == NULL)
1352 return -ENOMEM;
1353 lp->next = lp->last = lp; /* nobody else in a queue */
1354 lp->netdev->pb->frags = NULL;
1355 lp->netdev->pb->frames = 0;
1356 lp->netdev->pb->seq = LONG_MAX;
1358 lp->netdev->pb->ref_ct++;
1360 is->last_link_seqno = 0;
1361 return 0;
1364 static u32 isdn_ppp_mp_get_seq( int short_seq,
1365 struct sk_buff * skb, u32 last_seq );
1366 struct sk_buff * isdn_ppp_mp_discard( ippp_bundle * mp,
1367 struct sk_buff * from, struct sk_buff * to );
1368 void isdn_ppp_mp_reassembly( isdn_net_dev * net_dev, isdn_net_local * lp,
1369 struct sk_buff * from, struct sk_buff * to );
1370 static void isdn_ppp_mp_free_skb( ippp_bundle * mp, struct sk_buff * skb );
1371 static void isdn_ppp_mp_print_recv_pkt( int slot, struct sk_buff * skb );
1373 static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp,
1374 struct sk_buff *skb)
1376 struct ippp_struct *is;
1377 isdn_net_local * lpq;
1378 ippp_bundle * mp;
1379 isdn_mppp_stats * stats;
1380 struct sk_buff * newfrag, * frag, * start, *nextf;
1381 u32 newseq, minseq, thisseq;
1382 unsigned long flags;
1383 int slot;
1385 spin_lock_irqsave(&net_dev->pb->lock, flags);
1386 mp = net_dev->pb;
1387 stats = &mp->stats;
1388 slot = lp->ppp_slot;
1389 if (slot < 0 || slot > ISDN_MAX_CHANNELS) {
1390 printk(KERN_ERR "isdn_ppp_mp_receive: lp->ppp_slot %d\n", lp->ppp_slot);
1391 stats->frame_drops++;
1392 dev_kfree_skb(skb);
1393 spin_unlock_irqrestore(&mp->lock, flags);
1394 return;
1396 is = ippp_table[slot];
1397 if( ++mp->frames > stats->max_queue_len )
1398 stats->max_queue_len = mp->frames;
1400 if (is->debug & 0x8)
1401 isdn_ppp_mp_print_recv_pkt(lp->ppp_slot, skb);
1403 newseq = isdn_ppp_mp_get_seq(is->mpppcfg & SC_IN_SHORT_SEQ,
1404 skb, is->last_link_seqno);
1407 /* if this packet seq # is less than last already processed one,
1408 * toss it right away, but check for sequence start case first
1410 if( mp->seq > MP_LONGSEQ_MAX && (newseq & MP_LONGSEQ_MAXBIT) ) {
1411 mp->seq = newseq; /* the first packet: required for
1412 * rfc1990 non-compliant clients --
1413 * prevents constant packet toss */
1414 } else if( MP_LT(newseq, mp->seq) ) {
1415 stats->frame_drops++;
1416 isdn_ppp_mp_free_skb(mp, skb);
1417 spin_unlock_irqrestore(&mp->lock, flags);
1418 return;
1421 /* find the minimum received sequence number over all links */
1422 is->last_link_seqno = minseq = newseq;
1423 for (lpq = net_dev->queue;;) {
1424 slot = lpq->ppp_slot;
1425 if (slot < 0 || slot > ISDN_MAX_CHANNELS) {
1426 printk(KERN_ERR "isdn_ppp_mp_receive: lpq->ppp_slot %d\n", lpq->ppp_slot);
1427 } else {
1428 u32 lls = ippp_table[slot]->last_link_seqno;
1429 if (MP_LT(lls, minseq))
1430 minseq = lls;
1432 if ((lpq = lpq->next) == net_dev->queue)
1433 break;
1435 if (MP_LT(minseq, mp->seq))
1436 minseq = mp->seq; /* can't go beyond already processed
1437 * packets */
1438 newfrag = skb;
1440 /* if this new fragment is before the first one, then enqueue it now. */
1441 if ((frag = mp->frags) == NULL || MP_LT(newseq, MP_SEQ(frag))) {
1442 newfrag->next = frag;
1443 mp->frags = frag = newfrag;
1444 newfrag = NULL;
1447 start = MP_FLAGS(frag) & MP_BEGIN_FRAG &&
1448 MP_SEQ(frag) == mp->seq ? frag : NULL;
1451 * main fragment traversing loop
1453 * try to accomplish several tasks:
1454 * - insert new fragment into the proper sequence slot (once that's done
1455 * newfrag will be set to NULL)
1456 * - reassemble any complete fragment sequence (non-null 'start'
1457 * indicates there is a continguous sequence present)
1458 * - discard any incomplete sequences that are below minseq -- due
1459 * to the fact that sender always increment sequence number, if there
1460 * is an incomplete sequence below minseq, no new fragments would
1461 * come to complete such sequence and it should be discarded
1463 * loop completes when we accomplished the following tasks:
1464 * - new fragment is inserted in the proper sequence ('newfrag' is
1465 * set to NULL)
1466 * - we hit a gap in the sequence, so no reassembly/processing is
1467 * possible ('start' would be set to NULL)
1469 * algorightm for this code is derived from code in the book
1470 * 'PPP Design And Debugging' by James Carlson (Addison-Wesley)
1472 while (start != NULL || newfrag != NULL) {
1474 thisseq = MP_SEQ(frag);
1475 nextf = frag->next;
1477 /* drop any duplicate fragments */
1478 if (newfrag != NULL && thisseq == newseq) {
1479 isdn_ppp_mp_free_skb(mp, newfrag);
1480 newfrag = NULL;
1483 /* insert new fragment before next element if possible. */
1484 if (newfrag != NULL && (nextf == NULL ||
1485 MP_LT(newseq, MP_SEQ(nextf)))) {
1486 newfrag->next = nextf;
1487 frag->next = nextf = newfrag;
1488 newfrag = NULL;
1491 if (start != NULL) {
1492 /* check for misplaced start */
1493 if (start != frag && (MP_FLAGS(frag) & MP_BEGIN_FRAG)) {
1494 printk(KERN_WARNING"isdn_mppp(seq %d): new "
1495 "BEGIN flag with no prior END", thisseq);
1496 stats->seqerrs++;
1497 stats->frame_drops++;
1498 start = isdn_ppp_mp_discard(mp, start,frag);
1499 nextf = frag->next;
1501 } else if (MP_LE(thisseq, minseq)) {
1502 if (MP_FLAGS(frag) & MP_BEGIN_FRAG)
1503 start = frag;
1504 else {
1505 if (MP_FLAGS(frag) & MP_END_FRAG)
1506 stats->frame_drops++;
1507 if( mp->frags == frag )
1508 mp->frags = nextf;
1509 isdn_ppp_mp_free_skb(mp, frag);
1510 frag = nextf;
1511 continue;
1515 /* if start is non-null and we have end fragment, then
1516 * we have full reassembly sequence -- reassemble
1517 * and process packet now
1519 if (start != NULL && (MP_FLAGS(frag) & MP_END_FRAG)) {
1520 minseq = mp->seq = (thisseq+1) & MP_LONGSEQ_MASK;
1521 /* Reassemble the packet then dispatch it */
1522 isdn_ppp_mp_reassembly(net_dev, lp, start, nextf);
1524 start = NULL;
1525 frag = NULL;
1527 mp->frags = nextf;
1530 /* check if need to update start pointer: if we just
1531 * reassembled the packet and sequence is contiguous
1532 * then next fragment should be the start of new reassembly
1533 * if sequence is contiguous, but we haven't reassembled yet,
1534 * keep going.
1535 * if sequence is not contiguous, either clear everyting
1536 * below low watermark and set start to the next frag or
1537 * clear start ptr.
1539 if (nextf != NULL &&
1540 ((thisseq+1) & MP_LONGSEQ_MASK) == MP_SEQ(nextf)) {
1541 /* if we just reassembled and the next one is here,
1542 * then start another reassembly. */
1544 if (frag == NULL) {
1545 if (MP_FLAGS(nextf) & MP_BEGIN_FRAG)
1546 start = nextf;
1547 else
1549 printk(KERN_WARNING"isdn_mppp(seq %d):"
1550 " END flag with no following "
1551 "BEGIN", thisseq);
1552 stats->seqerrs++;
1556 } else {
1557 if ( nextf != NULL && frag != NULL &&
1558 MP_LT(thisseq, minseq)) {
1559 /* we've got a break in the sequence
1560 * and we not at the end yet
1561 * and we did not just reassembled
1562 *(if we did, there wouldn't be anything before)
1563 * and we below the low watermark
1564 * discard all the frames below low watermark
1565 * and start over */
1566 stats->frame_drops++;
1567 mp->frags = isdn_ppp_mp_discard(mp,start,nextf);
1569 /* break in the sequence, no reassembly */
1570 start = NULL;
1573 frag = nextf;
1574 } /* while -- main loop */
1576 if (mp->frags == NULL)
1577 mp->frags = frag;
1579 /* rather straighforward way to deal with (not very) possible
1580 * queue overflow */
1581 if (mp->frames > MP_MAX_QUEUE_LEN) {
1582 stats->overflows++;
1583 while (mp->frames > MP_MAX_QUEUE_LEN) {
1584 frag = mp->frags->next;
1585 isdn_ppp_mp_free_skb(mp, mp->frags);
1586 mp->frags = frag;
1589 spin_unlock_irqrestore(&mp->lock, flags);
1592 static void isdn_ppp_mp_cleanup( isdn_net_local * lp )
1594 struct sk_buff * frag = lp->netdev->pb->frags;
1595 struct sk_buff * nextfrag;
1596 while( frag ) {
1597 nextfrag = frag->next;
1598 isdn_ppp_mp_free_skb(lp->netdev->pb, frag);
1599 frag = nextfrag;
1601 lp->netdev->pb->frags = NULL;
1604 static u32 isdn_ppp_mp_get_seq( int short_seq,
1605 struct sk_buff * skb, u32 last_seq )
1607 u32 seq;
1608 int flags = skb->data[0] & (MP_BEGIN_FRAG | MP_END_FRAG);
1610 if( !short_seq )
1612 seq = ntohl(*(u32*)skb->data) & MP_LONGSEQ_MASK;
1613 skb_push(skb,1);
1615 else
1617 /* convert 12-bit short seq number to 24-bit long one
1619 seq = ntohs(*(u16*)skb->data) & MP_SHORTSEQ_MASK;
1621 /* check for seqence wrap */
1622 if( !(seq & MP_SHORTSEQ_MAXBIT) &&
1623 (last_seq & MP_SHORTSEQ_MAXBIT) &&
1624 (unsigned long)last_seq <= MP_LONGSEQ_MAX )
1625 seq |= (last_seq + MP_SHORTSEQ_MAX+1) &
1626 (~MP_SHORTSEQ_MASK & MP_LONGSEQ_MASK);
1627 else
1628 seq |= last_seq & (~MP_SHORTSEQ_MASK & MP_LONGSEQ_MASK);
1630 skb_push(skb, 3); /* put converted seqence back in skb */
1632 *(u32*)(skb->data+1) = seq; /* put seqence back in _host_ byte
1633 * order */
1634 skb->data[0] = flags; /* restore flags */
1635 return seq;
1638 struct sk_buff * isdn_ppp_mp_discard( ippp_bundle * mp,
1639 struct sk_buff * from, struct sk_buff * to )
1641 if( from )
1642 while (from != to) {
1643 struct sk_buff * next = from->next;
1644 isdn_ppp_mp_free_skb(mp, from);
1645 from = next;
1647 return from;
1650 void isdn_ppp_mp_reassembly( isdn_net_dev * net_dev, isdn_net_local * lp,
1651 struct sk_buff * from, struct sk_buff * to )
1653 ippp_bundle * mp = net_dev->pb;
1654 int proto;
1655 struct sk_buff * skb;
1656 unsigned int tot_len;
1658 if( MP_FLAGS(from) == (MP_BEGIN_FRAG | MP_END_FRAG) ) {
1659 if( ippp_table[lp->ppp_slot]->debug & 0x40 )
1660 printk(KERN_DEBUG"isdn_mppp: reassembly: frame %d, "
1661 "len %d\n", MP_SEQ(from), from->len );
1662 skb = from;
1663 skb_pull(skb, MP_HEADER_LEN);
1664 mp->frames--;
1665 } else {
1666 struct sk_buff * frag;
1667 int n;
1669 for(tot_len=n=0, frag=from; frag != to; frag=frag->next, n++)
1670 tot_len += frag->len - MP_HEADER_LEN;
1672 if( ippp_table[lp->ppp_slot]->debug & 0x40 )
1673 printk(KERN_DEBUG"isdn_mppp: reassembling frames %d "
1674 "to %d, len %d\n", MP_SEQ(from),
1675 (MP_SEQ(from)+n-1) & MP_LONGSEQ_MASK, tot_len );
1676 if( (skb = dev_alloc_skb(tot_len)) == NULL ) {
1677 printk(KERN_ERR "isdn_mppp: cannot allocate sk buff "
1678 "of size %d\n", tot_len);
1679 isdn_ppp_mp_discard(mp, from, to);
1680 return;
1683 while( from != to ) {
1684 unsigned int len = from->len - MP_HEADER_LEN;
1686 memcpy(skb_put(skb,len), from->data+MP_HEADER_LEN, len);
1687 frag = from->next;
1688 isdn_ppp_mp_free_skb(mp, from);
1689 from = frag;
1692 proto = isdn_ppp_strip_proto(skb);
1693 isdn_ppp_push_higher(net_dev, lp, skb, proto);
1696 static void isdn_ppp_mp_free_skb(ippp_bundle * mp, struct sk_buff * skb)
1698 dev_kfree_skb(skb);
1699 mp->frames--;
1702 static void isdn_ppp_mp_print_recv_pkt( int slot, struct sk_buff * skb )
1704 printk(KERN_DEBUG "mp_recv: %d/%d -> %02x %02x %02x %02x %02x %02x\n",
1705 slot, (int) skb->len,
1706 (int) skb->data[0], (int) skb->data[1], (int) skb->data[2],
1707 (int) skb->data[3], (int) skb->data[4], (int) skb->data[5]);
1710 static int
1711 isdn_ppp_bundle(struct ippp_struct *is, int unit)
1713 char ifn[IFNAMSIZ + 1];
1714 isdn_net_dev *p;
1715 isdn_net_local *lp, *nlp;
1716 int rc;
1717 unsigned long flags;
1719 sprintf(ifn, "ippp%d", unit);
1720 p = isdn_net_findif(ifn);
1721 if (!p) {
1722 printk(KERN_ERR "ippp_bundle: cannot find %s\n", ifn);
1723 return -EINVAL;
1726 spin_lock_irqsave(&p->pb->lock, flags);
1728 nlp = is->lp;
1729 lp = p->queue;
1730 if( nlp->ppp_slot < 0 || nlp->ppp_slot >= ISDN_MAX_CHANNELS ||
1731 lp->ppp_slot < 0 || lp->ppp_slot >= ISDN_MAX_CHANNELS ) {
1732 printk(KERN_ERR "ippp_bundle: binding to invalid slot %d\n",
1733 nlp->ppp_slot < 0 || nlp->ppp_slot >= ISDN_MAX_CHANNELS ?
1734 nlp->ppp_slot : lp->ppp_slot );
1735 rc = -EINVAL;
1736 goto out;
1739 isdn_net_add_to_bundle(p, nlp);
1741 ippp_table[nlp->ppp_slot]->unit = ippp_table[lp->ppp_slot]->unit;
1743 /* maybe also SC_CCP stuff */
1744 ippp_table[nlp->ppp_slot]->pppcfg |= ippp_table[lp->ppp_slot]->pppcfg &
1745 (SC_ENABLE_IP | SC_NO_TCP_CCID | SC_REJ_COMP_TCP);
1746 ippp_table[nlp->ppp_slot]->mpppcfg |= ippp_table[lp->ppp_slot]->mpppcfg &
1747 (SC_MP_PROT | SC_REJ_MP_PROT | SC_OUT_SHORT_SEQ | SC_IN_SHORT_SEQ);
1748 rc = isdn_ppp_mp_init(nlp, p->pb);
1749 out:
1750 spin_unlock_irqrestore(&p->pb->lock, flags);
1751 return rc;
1754 #endif /* CONFIG_ISDN_MPP */
1757 * network device ioctl handlers
1760 static int
1761 isdn_ppp_dev_ioctl_stats(int slot, struct ifreq *ifr, struct net_device *dev)
1763 struct ppp_stats *res,
1765 isdn_net_local *lp = (isdn_net_local *) dev->priv;
1766 int err;
1768 res = (struct ppp_stats *) ifr->ifr_ifru.ifru_data;
1769 err = verify_area(VERIFY_WRITE, res, sizeof(struct ppp_stats));
1771 if (err)
1772 return err;
1774 /* build a temporary stat struct and copy it to user space */
1776 memset(&t, 0, sizeof(struct ppp_stats));
1777 if (dev->flags & IFF_UP) {
1778 t.p.ppp_ipackets = lp->stats.rx_packets;
1779 t.p.ppp_ierrors = lp->stats.rx_errors;
1780 t.p.ppp_opackets = lp->stats.tx_packets;
1781 t.p.ppp_oerrors = lp->stats.tx_errors;
1782 #ifdef CONFIG_ISDN_PPP_VJ
1783 if (slot >= 0 && ippp_table[slot]->slcomp) {
1784 struct slcompress *slcomp = ippp_table[slot]->slcomp;
1785 t.vj.vjs_packets = slcomp->sls_o_compressed + slcomp->sls_o_uncompressed;
1786 t.vj.vjs_compressed = slcomp->sls_o_compressed;
1787 t.vj.vjs_searches = slcomp->sls_o_searches;
1788 t.vj.vjs_misses = slcomp->sls_o_misses;
1789 t.vj.vjs_errorin = slcomp->sls_i_error;
1790 t.vj.vjs_tossed = slcomp->sls_i_tossed;
1791 t.vj.vjs_uncompressedin = slcomp->sls_i_uncompressed;
1792 t.vj.vjs_compressedin = slcomp->sls_i_compressed;
1794 #endif
1796 if( copy_to_user(res, &t, sizeof(struct ppp_stats))) return -EFAULT;
1797 return 0;
1801 isdn_ppp_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
1803 int error=0;
1804 char *r;
1805 int len;
1806 isdn_net_local *lp = (isdn_net_local *) dev->priv;
1809 if (lp->p_encap != ISDN_NET_ENCAP_SYNCPPP)
1810 return -EINVAL;
1812 switch (cmd) {
1813 case SIOCGPPPVER:
1814 r = (char *) ifr->ifr_ifru.ifru_data;
1815 len = strlen(PPP_VERSION) + 1;
1816 if(copy_to_user(r, PPP_VERSION, len)) error = -EFAULT;
1817 break;
1818 case SIOCGPPPSTATS:
1819 error = isdn_ppp_dev_ioctl_stats(lp->ppp_slot, ifr, dev);
1820 break;
1821 default:
1822 error = -EINVAL;
1823 break;
1825 return error;
1828 static int
1829 isdn_ppp_if_get_unit(char *name)
1831 int len,
1833 unit = 0,
1834 deci;
1836 len = strlen(name);
1838 if (strncmp("ippp", name, 4) || len > 8)
1839 return -1;
1841 for (i = 0, deci = 1; i < len; i++, deci *= 10) {
1842 char a = name[len - i - 1];
1843 if (a >= '0' && a <= '9')
1844 unit += (a - '0') * deci;
1845 else
1846 break;
1848 if (!i || len - i != 4)
1849 unit = -1;
1851 return unit;
1856 isdn_ppp_dial_slave(char *name)
1858 #ifdef CONFIG_ISDN_MPP
1859 isdn_net_dev *ndev;
1860 isdn_net_local *lp;
1861 struct net_device *sdev;
1863 if (!(ndev = isdn_net_findif(name)))
1864 return 1;
1865 lp = ndev->local;
1866 if (!(lp->flags & ISDN_NET_CONNECTED))
1867 return 5;
1869 sdev = lp->slave;
1870 while (sdev) {
1871 isdn_net_local *mlp = (isdn_net_local *) sdev->priv;
1872 if (!(mlp->flags & ISDN_NET_CONNECTED))
1873 break;
1874 sdev = mlp->slave;
1876 if (!sdev)
1877 return 2;
1879 isdn_net_dial_req((isdn_net_local *) sdev->priv);
1880 return 0;
1881 #else
1882 return -1;
1883 #endif
1887 isdn_ppp_hangup_slave(char *name)
1889 #ifdef CONFIG_ISDN_MPP
1890 isdn_net_dev *ndev;
1891 isdn_net_local *lp;
1892 struct net_device *sdev;
1894 if (!(ndev = isdn_net_findif(name)))
1895 return 1;
1896 lp = ndev->local;
1897 if (!(lp->flags & ISDN_NET_CONNECTED))
1898 return 5;
1900 sdev = lp->slave;
1901 while (sdev) {
1902 isdn_net_local *mlp = (isdn_net_local *) sdev->priv;
1903 if ((mlp->flags & ISDN_NET_CONNECTED))
1904 break;
1905 sdev = mlp->slave;
1907 if (!sdev)
1908 return 2;
1910 isdn_net_hangup(sdev);
1911 return 0;
1912 #else
1913 return -1;
1914 #endif
1918 * PPP compression stuff
1922 /* Push an empty CCP Data Frame up to the daemon to wake it up and let it
1923 generate a CCP Reset-Request or tear down CCP altogether */
1925 static void isdn_ppp_ccp_kickup(struct ippp_struct *is)
1927 isdn_ppp_fill_rq(NULL, 0, PPP_COMP, is->lp->ppp_slot);
1930 /* In-kernel handling of CCP Reset-Request and Reset-Ack is necessary,
1931 but absolutely nontrivial. The most abstruse problem we are facing is
1932 that the generation, reception and all the handling of timeouts and
1933 resends including proper request id management should be entirely left
1934 to the (de)compressor, but indeed is not covered by the current API to
1935 the (de)compressor. The API is a prototype version from PPP where only
1936 some (de)compressors have yet been implemented and all of them are
1937 rather simple in their reset handling. Especially, their is only one
1938 outstanding ResetAck at a time with all of them and ResetReq/-Acks do
1939 not have parameters. For this very special case it was sufficient to
1940 just return an error code from the decompressor and have a single
1941 reset() entry to communicate all the necessary information between
1942 the framework and the (de)compressor. Bad enough, LZS is different
1943 (and any other compressor may be different, too). It has multiple
1944 histories (eventually) and needs to Reset each of them independently
1945 and thus uses multiple outstanding Acks and history numbers as an
1946 additional parameter to Reqs/Acks.
1947 All that makes it harder to port the reset state engine into the
1948 kernel because it is not just the same simple one as in (i)pppd but
1949 it must be able to pass additional parameters and have multiple out-
1950 standing Acks. We are trying to achieve the impossible by handling
1951 reset transactions independent by their id. The id MUST change when
1952 the data portion changes, thus any (de)compressor who uses more than
1953 one resettable state must provide and recognize individual ids for
1954 each individual reset transaction. The framework itself does _only_
1955 differentiate them by id, because it has no other semantics like the
1956 (de)compressor might.
1957 This looks like a major redesign of the interface would be nice,
1958 but I don't have an idea how to do it better. */
1960 /* Send a CCP Reset-Request or Reset-Ack directly from the kernel. This is
1961 getting that lengthy because there is no simple "send-this-frame-out"
1962 function above but every wrapper does a bit different. Hope I guess
1963 correct in this hack... */
1965 static void isdn_ppp_ccp_xmit_reset(struct ippp_struct *is, int proto,
1966 unsigned char code, unsigned char id,
1967 unsigned char *data, int len)
1969 struct sk_buff *skb;
1970 unsigned char *p;
1971 int hl;
1972 int cnt = 0;
1973 isdn_net_local *lp = is->lp;
1975 /* Alloc large enough skb */
1976 hl = dev->drv[lp->isdn_device]->interface->hl_hdrlen;
1977 skb = alloc_skb(len + hl + 16,GFP_ATOMIC);
1978 if(!skb) {
1979 printk(KERN_WARNING
1980 "ippp: CCP cannot send reset - out of memory\n");
1981 return;
1983 skb_reserve(skb, hl);
1985 /* We may need to stuff an address and control field first */
1986 if(!(is->pppcfg & SC_COMP_AC)) {
1987 p = skb_put(skb, 2);
1988 *p++ = 0xff;
1989 *p++ = 0x03;
1992 /* Stuff proto, code, id and length */
1993 p = skb_put(skb, 6);
1994 *p++ = (proto >> 8);
1995 *p++ = (proto & 0xff);
1996 *p++ = code;
1997 *p++ = id;
1998 cnt = 4 + len;
1999 *p++ = (cnt >> 8);
2000 *p++ = (cnt & 0xff);
2002 /* Now stuff remaining bytes */
2003 if(len) {
2004 p = skb_put(skb, len);
2005 memcpy(p, data, len);
2008 /* skb is now ready for xmit */
2009 printk(KERN_DEBUG "Sending CCP Frame:\n");
2010 isdn_ppp_frame_log("ccp-xmit", skb->data, skb->len, 32, is->unit,lp->ppp_slot);
2012 isdn_net_write_super(lp, skb);
2015 /* Allocate the reset state vector */
2016 static struct ippp_ccp_reset *isdn_ppp_ccp_reset_alloc(struct ippp_struct *is)
2018 struct ippp_ccp_reset *r;
2019 r = kmalloc(sizeof(struct ippp_ccp_reset), GFP_KERNEL);
2020 if(!r) {
2021 printk(KERN_ERR "ippp_ccp: failed to allocate reset data"
2022 " structure - no mem\n");
2023 return NULL;
2025 memset(r, 0, sizeof(struct ippp_ccp_reset));
2026 printk(KERN_DEBUG "ippp_ccp: allocated reset data structure %p\n", r);
2027 is->reset = r;
2028 return r;
2031 /* Destroy the reset state vector. Kill all pending timers first. */
2032 static void isdn_ppp_ccp_reset_free(struct ippp_struct *is)
2034 unsigned int id;
2036 printk(KERN_DEBUG "ippp_ccp: freeing reset data structure %p\n",
2037 is->reset);
2038 for(id = 0; id < 256; id++) {
2039 if(is->reset->rs[id]) {
2040 isdn_ppp_ccp_reset_free_state(is, (unsigned char)id);
2043 kfree(is->reset);
2044 is->reset = NULL;
2047 /* Free a given state and clear everything up for later reallocation */
2048 static void isdn_ppp_ccp_reset_free_state(struct ippp_struct *is,
2049 unsigned char id)
2051 struct ippp_ccp_reset_state *rs;
2053 if(is->reset->rs[id]) {
2054 printk(KERN_DEBUG "ippp_ccp: freeing state for id %d\n", id);
2055 rs = is->reset->rs[id];
2056 /* Make sure the kernel will not call back later */
2057 if(rs->ta)
2058 del_timer(&rs->timer);
2059 is->reset->rs[id] = NULL;
2060 kfree(rs);
2061 } else {
2062 printk(KERN_WARNING "ippp_ccp: id %d is not allocated\n", id);
2066 /* The timer callback function which is called when a ResetReq has timed out,
2067 aka has never been answered by a ResetAck */
2068 static void isdn_ppp_ccp_timer_callback(unsigned long closure)
2070 struct ippp_ccp_reset_state *rs =
2071 (struct ippp_ccp_reset_state *)closure;
2073 if(!rs) {
2074 printk(KERN_ERR "ippp_ccp: timer cb with zero closure.\n");
2075 return;
2077 if(rs->ta && rs->state == CCPResetSentReq) {
2078 /* We are correct here */
2079 printk(KERN_DEBUG "ippp_ccp: CCP Reset timed out for id %d\n",
2080 rs->id);
2081 if(!rs->expra) {
2082 /* Hmm, there is no Ack really expected. We can clean
2083 up the state now, it will be reallocated if the
2084 decompressor insists on another reset */
2085 rs->ta = 0;
2086 isdn_ppp_ccp_reset_free_state(rs->is, rs->id);
2087 return;
2089 /* Push it again */
2090 isdn_ppp_ccp_xmit_reset(rs->is, PPP_CCP, CCP_RESETREQ, rs->id,
2091 rs->data, rs->dlen);
2092 /* Restart timer */
2093 rs->timer.expires = jiffies + HZ*5;
2094 add_timer(&rs->timer);
2095 } else {
2096 printk(KERN_WARNING "ippp_ccp: timer cb in wrong state %d\n",
2097 rs->state);
2101 /* Allocate a new reset transaction state */
2102 static struct ippp_ccp_reset_state *isdn_ppp_ccp_reset_alloc_state(struct ippp_struct *is,
2103 unsigned char id)
2105 struct ippp_ccp_reset_state *rs;
2106 if(is->reset->rs[id]) {
2107 printk(KERN_WARNING "ippp_ccp: old state exists for id %d\n",
2108 id);
2109 return NULL;
2110 } else {
2111 rs = kmalloc(sizeof(struct ippp_ccp_reset_state), GFP_KERNEL);
2112 if(!rs)
2113 return NULL;
2114 memset(rs, 0, sizeof(struct ippp_ccp_reset_state));
2115 rs->state = CCPResetIdle;
2116 rs->is = is;
2117 rs->id = id;
2118 rs->timer.data = (unsigned long)rs;
2119 rs->timer.function = isdn_ppp_ccp_timer_callback;
2120 is->reset->rs[id] = rs;
2122 return rs;
2126 /* A decompressor wants a reset with a set of parameters - do what is
2127 necessary to fulfill it */
2128 static void isdn_ppp_ccp_reset_trans(struct ippp_struct *is,
2129 struct isdn_ppp_resetparams *rp)
2131 struct ippp_ccp_reset_state *rs;
2133 if(rp->valid) {
2134 /* The decompressor defines parameters by itself */
2135 if(rp->rsend) {
2136 /* And he wants us to send a request */
2137 if(!(rp->idval)) {
2138 printk(KERN_ERR "ippp_ccp: decompressor must"
2139 " specify reset id\n");
2140 return;
2142 if(is->reset->rs[rp->id]) {
2143 /* There is already a transaction in existence
2144 for this id. May be still waiting for a
2145 Ack or may be wrong. */
2146 rs = is->reset->rs[rp->id];
2147 if(rs->state == CCPResetSentReq && rs->ta) {
2148 printk(KERN_DEBUG "ippp_ccp: reset"
2149 " trans still in progress"
2150 " for id %d\n", rp->id);
2151 } else {
2152 printk(KERN_WARNING "ippp_ccp: reset"
2153 " trans in wrong state %d for"
2154 " id %d\n", rs->state, rp->id);
2156 } else {
2157 /* Ok, this is a new transaction */
2158 printk(KERN_DEBUG "ippp_ccp: new trans for id"
2159 " %d to be started\n", rp->id);
2160 rs = isdn_ppp_ccp_reset_alloc_state(is, rp->id);
2161 if(!rs) {
2162 printk(KERN_ERR "ippp_ccp: out of mem"
2163 " allocing ccp trans\n");
2164 return;
2166 rs->state = CCPResetSentReq;
2167 rs->expra = rp->expra;
2168 if(rp->dtval) {
2169 rs->dlen = rp->dlen;
2170 memcpy(rs->data, rp->data, rp->dlen);
2172 /* HACK TODO - add link comp here */
2173 isdn_ppp_ccp_xmit_reset(is, PPP_CCP,
2174 CCP_RESETREQ, rs->id,
2175 rs->data, rs->dlen);
2176 /* Start the timer */
2177 rs->timer.expires = jiffies + 5*HZ;
2178 add_timer(&rs->timer);
2179 rs->ta = 1;
2181 } else {
2182 printk(KERN_DEBUG "ippp_ccp: no reset sent\n");
2184 } else {
2185 /* The reset params are invalid. The decompressor does not
2186 care about them, so we just send the minimal requests
2187 and increase ids only when an Ack is received for a
2188 given id */
2189 if(is->reset->rs[is->reset->lastid]) {
2190 /* There is already a transaction in existence
2191 for this id. May be still waiting for a
2192 Ack or may be wrong. */
2193 rs = is->reset->rs[is->reset->lastid];
2194 if(rs->state == CCPResetSentReq && rs->ta) {
2195 printk(KERN_DEBUG "ippp_ccp: reset"
2196 " trans still in progress"
2197 " for id %d\n", rp->id);
2198 } else {
2199 printk(KERN_WARNING "ippp_ccp: reset"
2200 " trans in wrong state %d for"
2201 " id %d\n", rs->state, rp->id);
2203 } else {
2204 printk(KERN_DEBUG "ippp_ccp: new trans for id"
2205 " %d to be started\n", is->reset->lastid);
2206 rs = isdn_ppp_ccp_reset_alloc_state(is,
2207 is->reset->lastid);
2208 if(!rs) {
2209 printk(KERN_ERR "ippp_ccp: out of mem"
2210 " allocing ccp trans\n");
2211 return;
2213 rs->state = CCPResetSentReq;
2214 /* We always expect an Ack if the decompressor doesnt
2215 know better */
2216 rs->expra = 1;
2217 rs->dlen = 0;
2218 /* HACK TODO - add link comp here */
2219 isdn_ppp_ccp_xmit_reset(is, PPP_CCP, CCP_RESETREQ,
2220 rs->id, NULL, 0);
2221 /* Start the timer */
2222 rs->timer.expires = jiffies + 5*HZ;
2223 add_timer(&rs->timer);
2224 rs->ta = 1;
2229 /* An Ack was received for this id. This means we stop the timer and clean
2230 up the state prior to calling the decompressors reset routine. */
2231 static void isdn_ppp_ccp_reset_ack_rcvd(struct ippp_struct *is,
2232 unsigned char id)
2234 struct ippp_ccp_reset_state *rs = is->reset->rs[id];
2236 if(rs) {
2237 if(rs->ta && rs->state == CCPResetSentReq) {
2238 /* Great, we are correct */
2239 if(!rs->expra)
2240 printk(KERN_DEBUG "ippp_ccp: ResetAck received"
2241 " for id %d but not expected\n", id);
2242 } else {
2243 printk(KERN_INFO "ippp_ccp: ResetAck received out of"
2244 "sync for id %d\n", id);
2246 if(rs->ta) {
2247 rs->ta = 0;
2248 del_timer(&rs->timer);
2250 isdn_ppp_ccp_reset_free_state(is, id);
2251 } else {
2252 printk(KERN_INFO "ippp_ccp: ResetAck received for unknown id"
2253 " %d\n", id);
2255 /* Make sure the simple reset stuff uses a new id next time */
2256 is->reset->lastid++;
2259 static struct sk_buff *isdn_ppp_decompress(struct sk_buff *skb,struct ippp_struct *is,struct ippp_struct *master,
2260 int proto)
2262 void *stat = NULL;
2263 struct isdn_ppp_compressor *ipc = NULL;
2264 struct sk_buff *skb_out;
2265 int len;
2266 struct ippp_struct *ri;
2267 struct isdn_ppp_resetparams rsparm;
2268 unsigned char rsdata[IPPP_RESET_MAXDATABYTES];
2270 if(!master) {
2272 * single link decompression
2274 if(!is->link_decompressor) {
2275 printk(KERN_ERR "ippp: no link decompressor defined!\n");
2276 dev_kfree_skb(skb);
2277 return NULL;
2279 if(!is->link_decomp_stat) {
2280 printk(KERN_DEBUG "ippp: no link decompressor data allocated\n");
2281 dev_kfree_skb(skb);
2282 return NULL;
2284 stat = is->link_decomp_stat;
2285 ipc = is->link_decompressor;
2286 ri = is;
2288 else {
2290 * 'normal' or bundle-compression
2292 if(!master->decompressor) {
2293 printk(KERN_ERR "ippp: no decompressor defined!\n");
2294 dev_kfree_skb(skb);
2295 return NULL;
2297 if(!master->decomp_stat) {
2298 printk(KERN_DEBUG "ippp: no decompressor data allocated\n");
2299 dev_kfree_skb(skb);
2300 return NULL;
2302 stat = master->decomp_stat;
2303 ipc = master->decompressor;
2304 ri = master;
2308 printk(KERN_DEBUG "ippp: Decompress valid!\n");
2311 if((master && proto == PPP_COMP) || (!master && proto == PPP_COMPFRAG) ) {
2312 /* Set up reset params for the decompressor */
2313 memset(&rsparm, 0, sizeof(rsparm));
2314 rsparm.data = rsdata;
2315 rsparm.maxdlen = IPPP_RESET_MAXDATABYTES;
2317 /* !!!HACK,HACK,HACK!!! 2048 is only assumed */
2318 skb_out = dev_alloc_skb(2048);
2319 len = ipc->decompress(stat,skb,skb_out, &rsparm);
2320 dev_kfree_skb(skb);
2321 if(len <= 0) {
2322 /* Ok, some error */
2323 switch(len) {
2324 case DECOMP_ERROR:
2325 ri->pppcfg |= SC_DC_ERROR;
2326 printk(KERN_INFO "ippp: decomp wants reset %s params\n",
2327 rsparm.valid ? "with" : "without");
2329 isdn_ppp_ccp_reset_trans(ri, &rsparm);
2331 break;
2332 case DECOMP_FATALERROR:
2333 ri->pppcfg |= SC_DC_FERROR;
2334 /* Kick ipppd to recognize the error */
2335 isdn_ppp_ccp_kickup(ri);
2336 break;
2338 /* Did I see a leak here ? */
2339 dev_kfree_skb(skb_out);
2340 return NULL;
2342 return skb_out;
2344 else {
2346 printk(KERN_DEBUG "isdn_ppp: [%d] Calling incomp with this frame!\n",is->unit);
2348 ipc->incomp(stat,skb,proto);
2349 return skb;
2354 * compress a frame
2355 * type=0: normal/bundle compression
2356 * =1: link compression
2357 * returns original skb if we haven't compressed the frame
2358 * and a new skb pointer if we've done it
2360 static struct sk_buff *isdn_ppp_compress(struct sk_buff *skb_in,int *proto,
2361 struct ippp_struct *is,struct ippp_struct *master,int type)
2363 int ret;
2364 int new_proto;
2365 struct isdn_ppp_compressor *compressor;
2366 void *stat;
2367 struct sk_buff *skb_out;
2369 /* we do not compress control protocols */
2370 if(*proto < 0 || *proto > 0x3fff) {
2371 return skb_in;
2374 if(type) { /* type=1 => Link compression */
2375 return skb_in;
2377 else {
2378 if(!master) {
2379 compressor = is->compressor;
2380 stat = is->comp_stat;
2382 else {
2383 compressor = master->compressor;
2384 stat = master->comp_stat;
2386 new_proto = PPP_COMP;
2389 if(!compressor) {
2390 printk(KERN_ERR "isdn_ppp: No compressor set!\n");
2391 return skb_in;
2393 if(!stat) {
2394 printk(KERN_ERR "isdn_ppp: Compressor not initialized?\n");
2395 return skb_in;
2398 /* Allow for at least 150 % expansion (for now) */
2399 skb_out = alloc_skb(skb_in->len + skb_in->len/2 + 32 +
2400 skb_headroom(skb_in), GFP_ATOMIC);
2401 if(!skb_out)
2402 return skb_in;
2403 skb_reserve(skb_out, skb_headroom(skb_in));
2405 ret = (compressor->compress)(stat,skb_in,skb_out,*proto);
2406 if(!ret) {
2407 dev_kfree_skb(skb_out);
2408 return skb_in;
2411 dev_kfree_skb(skb_in);
2412 *proto = new_proto;
2413 return skb_out;
2417 * we received a CCP frame ..
2418 * not a clean solution, but we MUST handle a few cases in the kernel
2420 static void isdn_ppp_receive_ccp(isdn_net_dev *net_dev, isdn_net_local *lp,
2421 struct sk_buff *skb,int proto)
2423 struct ippp_struct *is = ippp_table[lp->ppp_slot];
2424 struct ippp_struct *mis;
2425 int len;
2426 struct isdn_ppp_resetparams rsparm;
2427 unsigned char rsdata[IPPP_RESET_MAXDATABYTES];
2429 printk(KERN_DEBUG "Received CCP frame from peer\n");
2430 isdn_ppp_frame_log("ccp-rcv", skb->data, skb->len, 32, is->unit,lp->ppp_slot);
2432 if(lp->master)
2433 mis = ippp_table[((isdn_net_local *) (lp->master->priv))->ppp_slot];
2434 else
2435 mis = is;
2437 switch(skb->data[0]) {
2438 case CCP_CONFREQ:
2439 case CCP_TERMREQ:
2440 case CCP_TERMACK:
2441 if(is->debug & 0x10)
2442 printk(KERN_DEBUG "Disable (de)compression here!\n");
2443 if(proto == PPP_CCP)
2444 mis->compflags &= ~(SC_DECOMP_ON|SC_COMP_ON);
2445 else
2446 is->compflags &= ~(SC_LINK_DECOMP_ON|SC_LINK_COMP_ON);
2447 break;
2448 case CCP_CONFACK:
2449 /* if we RECEIVE an ackowledge we enable the decompressor */
2450 if(is->debug & 0x10)
2451 printk(KERN_DEBUG "Enable decompression here!\n");
2452 if(proto == PPP_CCP)
2453 mis->compflags |= SC_DECOMP_ON;
2454 else
2455 is->compflags |= SC_LINK_DECOMP_ON;
2456 break;
2458 case CCP_RESETACK:
2459 printk(KERN_DEBUG "Received ResetAck from peer\n");
2460 len = (skb->data[2] << 8) | skb->data[3];
2461 len -= 4;
2463 if(proto == PPP_CCP) {
2464 /* If a reset Ack was outstanding for this id, then
2465 clean up the state engine */
2466 isdn_ppp_ccp_reset_ack_rcvd(mis, skb->data[1]);
2467 if(mis->decompressor && mis->decomp_stat)
2468 mis->decompressor->
2469 reset(mis->decomp_stat,
2470 skb->data[0],
2471 skb->data[1],
2472 len ? &skb->data[4] : NULL,
2473 len, NULL);
2474 /* TODO: This is not easy to decide here */
2475 mis->compflags &= ~SC_DECOMP_DISCARD;
2476 mis->pppcfg &= ~SC_DC_ERROR;
2478 else {
2479 isdn_ppp_ccp_reset_ack_rcvd(is, skb->data[1]);
2480 if(is->link_decompressor && is->link_decomp_stat)
2481 is->link_decompressor->
2482 reset(is->link_decomp_stat,
2483 skb->data[0],
2484 skb->data[1],
2485 len ? &skb->data[4] : NULL,
2486 len, NULL);
2487 /* TODO: neither here */
2488 is->compflags &= ~SC_LINK_DECOMP_DISCARD;
2489 is->pppcfg &= ~SC_DC_ERROR;
2491 break;
2493 case CCP_RESETREQ:
2494 printk(KERN_DEBUG "Received ResetReq from peer\n");
2495 /* Receiving a ResetReq means we must reset our compressor */
2496 /* Set up reset params for the reset entry */
2497 memset(&rsparm, 0, sizeof(rsparm));
2498 rsparm.data = rsdata;
2499 rsparm.maxdlen = IPPP_RESET_MAXDATABYTES;
2500 /* Isolate data length */
2501 len = (skb->data[2] << 8) | skb->data[3];
2502 len -= 4;
2503 if(proto == PPP_CCP) {
2504 if(mis->compressor && mis->comp_stat)
2505 mis->compressor->
2506 reset(mis->comp_stat,
2507 skb->data[0],
2508 skb->data[1],
2509 len ? &skb->data[4] : NULL,
2510 len, &rsparm);
2512 else {
2513 if(is->link_compressor && is->link_comp_stat)
2514 is->link_compressor->
2515 reset(is->link_comp_stat,
2516 skb->data[0],
2517 skb->data[1],
2518 len ? &skb->data[4] : NULL,
2519 len, &rsparm);
2521 /* Ack the Req as specified by rsparm */
2522 if(rsparm.valid) {
2523 /* Compressor reset handler decided how to answer */
2524 if(rsparm.rsend) {
2525 /* We should send a Frame */
2526 isdn_ppp_ccp_xmit_reset(is, proto, CCP_RESETACK,
2527 rsparm.idval ? rsparm.id
2528 : skb->data[1],
2529 rsparm.dtval ?
2530 rsparm.data : NULL,
2531 rsparm.dtval ?
2532 rsparm.dlen : 0);
2533 } else {
2534 printk(KERN_DEBUG "ResetAck suppressed\n");
2536 } else {
2537 /* We answer with a straight reflected Ack */
2538 isdn_ppp_ccp_xmit_reset(is, proto, CCP_RESETACK,
2539 skb->data[1],
2540 len ? &skb->data[4] : NULL,
2541 len);
2543 break;
2549 * Daemon sends a CCP frame ...
2552 /* TODO: Clean this up with new Reset semantics */
2554 static void isdn_ppp_send_ccp(isdn_net_dev *net_dev, isdn_net_local *lp, struct sk_buff *skb)
2556 struct ippp_struct *mis,*is = ippp_table[lp->ppp_slot];
2557 int proto;
2558 unsigned char *data;
2560 if(!skb || skb->len < 3)
2561 return;
2563 /* Daemon may send with or without address and control field comp */
2564 data = skb->data;
2565 if(!(is->pppcfg & SC_COMP_AC) && data[0] == 0xff && data[1] == 0x03) {
2566 data += 2;
2567 if(skb->len < 5)
2568 return;
2571 proto = ((int)data[0]<<8)+data[1];
2572 if(proto != PPP_CCP && proto != PPP_CCPFRAG)
2573 return;
2575 printk(KERN_DEBUG "Received CCP frame from daemon:\n");
2576 isdn_ppp_frame_log("ccp-xmit", skb->data, skb->len, 32, is->unit,lp->ppp_slot);
2578 if(lp->master)
2579 mis = ippp_table[((isdn_net_local *) (lp->master->priv))->ppp_slot];
2580 else
2581 mis = is;
2583 if(mis != is)
2584 printk(KERN_DEBUG "isdn_ppp: Ouch! Master CCP sends on slave slot!\n");
2586 switch(data[2]) {
2587 case CCP_CONFREQ:
2588 case CCP_TERMREQ:
2589 case CCP_TERMACK:
2590 if(is->debug & 0x10)
2591 printk(KERN_DEBUG "Disable (de)compression here!\n");
2592 if(proto == PPP_CCP)
2593 is->compflags &= ~(SC_DECOMP_ON|SC_COMP_ON);
2594 else
2595 is->compflags &= ~(SC_LINK_DECOMP_ON|SC_LINK_COMP_ON);
2596 break;
2597 case CCP_CONFACK:
2598 /* if we SEND an ackowledge we can/must enable the compressor */
2599 if(is->debug & 0x10)
2600 printk(KERN_DEBUG "Enable compression here!\n");
2601 if(proto == PPP_CCP)
2602 is->compflags |= SC_COMP_ON;
2603 else
2604 is->compflags |= SC_LINK_COMP_ON;
2605 break;
2606 case CCP_RESETACK:
2607 /* If we send a ACK we should reset our compressor */
2608 if(is->debug & 0x10)
2609 printk(KERN_DEBUG "Reset decompression state here!\n");
2610 printk(KERN_DEBUG "ResetAck from daemon passed by\n");
2611 if(proto == PPP_CCP) {
2612 /* link to master? */
2613 if(is->compressor && is->comp_stat)
2614 is->compressor->reset(is->comp_stat, 0, 0,
2615 NULL, 0, NULL);
2616 is->compflags &= ~SC_COMP_DISCARD;
2618 else {
2619 if(is->link_compressor && is->link_comp_stat)
2620 is->link_compressor->reset(is->link_comp_stat,
2621 0, 0, NULL, 0, NULL);
2622 is->compflags &= ~SC_LINK_COMP_DISCARD;
2624 break;
2625 case CCP_RESETREQ:
2626 /* Just let it pass by */
2627 printk(KERN_DEBUG "ResetReq from daemon passed by\n");
2628 break;
2632 int isdn_ppp_register_compressor(struct isdn_ppp_compressor *ipc)
2634 ipc->next = ipc_head;
2635 ipc->prev = NULL;
2636 if(ipc_head) {
2637 ipc_head->prev = ipc;
2639 ipc_head = ipc;
2640 return 0;
2643 int isdn_ppp_unregister_compressor(struct isdn_ppp_compressor *ipc)
2645 if(ipc->prev)
2646 ipc->prev->next = ipc->next;
2647 else
2648 ipc_head = ipc->next;
2649 if(ipc->next)
2650 ipc->next->prev = ipc->prev;
2651 ipc->prev = ipc->next = NULL;
2652 return 0;
2655 static int isdn_ppp_set_compressor(struct ippp_struct *is, struct isdn_ppp_comp_data *data)
2657 struct isdn_ppp_compressor *ipc = ipc_head;
2658 int ret;
2659 void *stat;
2660 int num = data->num;
2662 if(is->debug & 0x10)
2663 printk(KERN_DEBUG "[%d] Set %s type %d\n",is->unit,
2664 (data->flags&IPPP_COMP_FLAG_XMIT)?"compressor":"decompressor",num);
2666 /* If is has no valid reset state vector, we cannot allocate a
2667 decompressor. The decompressor would cause reset transactions
2668 sooner or later, and they need that vector. */
2670 if(!(data->flags & IPPP_COMP_FLAG_XMIT) && !is->reset) {
2671 printk(KERN_ERR "ippp_ccp: no reset data structure - can't"
2672 " allow decompression.\n");
2673 return -ENOMEM;
2676 while(ipc) {
2677 if(ipc->num == num) {
2678 stat = ipc->alloc(data);
2679 if(stat) {
2680 ret = ipc->init(stat,data,is->unit,0);
2681 if(!ret) {
2682 printk(KERN_ERR "Can't init (de)compression!\n");
2683 ipc->free(stat);
2684 stat = NULL;
2685 break;
2688 else {
2689 printk(KERN_ERR "Can't alloc (de)compression!\n");
2690 break;
2693 if(data->flags & IPPP_COMP_FLAG_XMIT) {
2694 if(data->flags & IPPP_COMP_FLAG_LINK) {
2695 if(is->link_comp_stat)
2696 is->link_compressor->free(is->link_comp_stat);
2697 is->link_comp_stat = stat;
2698 is->link_compressor = ipc;
2700 else {
2701 if(is->comp_stat)
2702 is->compressor->free(is->comp_stat);
2703 is->comp_stat = stat;
2704 is->compressor = ipc;
2707 else {
2708 if(data->flags & IPPP_COMP_FLAG_LINK) {
2709 if(is->link_decomp_stat)
2710 is->link_decompressor->free(is->link_decomp_stat);
2711 is->link_decomp_stat = stat;
2712 is->link_decompressor = ipc;
2714 else {
2715 if(is->decomp_stat)
2716 is->decompressor->free(is->decomp_stat);
2717 is->decomp_stat = stat;
2718 is->decompressor = ipc;
2721 return 0;
2723 ipc = ipc->next;
2725 return -EINVAL;