]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blame - drivers/isdn/i4l/isdn_ppp.c
isdn/i4l: fetch the ppp_write buffer in one shot
[mirror_ubuntu-artful-kernel.git] / drivers / isdn / i4l / isdn_ppp.c
CommitLineData
1da177e4
LT
1/* $Id: isdn_ppp.c,v 1.1.2.3 2004/02/10 01:07:13 keil Exp $
2 *
3 * Linux ISDN subsystem, functions for synchronous PPP (linklevel).
4 *
5 * Copyright 1995,96 by Michael Hipp (Michael.Hipp@student.uni-tuebingen.de)
6 *
7 * This software may be used and distributed according to the terms
8 * of the GNU General Public License, incorporated herein by reference.
9 *
10 */
11
1da177e4
LT
12#include <linux/isdn.h>
13#include <linux/poll.h>
14#include <linux/ppp-comp.h>
5a0e3ad6 15#include <linux/slab.h>
1da177e4
LT
16#ifdef CONFIG_IPPP_FILTER
17#include <linux/filter.h>
18#endif
19
20#include "isdn_common.h"
21#include "isdn_ppp.h"
22#include "isdn_net.h"
23
24#ifndef PPP_IPX
25#define PPP_IPX 0x002b
26#endif
27
28/* Prototypes */
29static int isdn_ppp_fill_rq(unsigned char *buf, int len, int proto, int slot);
30static int isdn_ppp_closewait(int slot);
475be4d8 31static void isdn_ppp_push_higher(isdn_net_dev *net_dev, isdn_net_local *lp,
1da177e4
LT
32 struct sk_buff *skb, int proto);
33static int isdn_ppp_if_get_unit(char *namebuf);
475be4d8 34static int isdn_ppp_set_compressor(struct ippp_struct *is, struct isdn_ppp_comp_data *);
1da177e4 35static struct sk_buff *isdn_ppp_decompress(struct sk_buff *,
475be4d8
JP
36 struct ippp_struct *, struct ippp_struct *, int *proto);
37static void isdn_ppp_receive_ccp(isdn_net_dev *net_dev, isdn_net_local *lp,
38 struct sk_buff *skb, int proto);
39static struct sk_buff *isdn_ppp_compress(struct sk_buff *skb_in, int *proto,
40 struct ippp_struct *is, struct ippp_struct *master, int type);
1da177e4 41static void isdn_ppp_send_ccp(isdn_net_dev *net_dev, isdn_net_local *lp,
475be4d8 42 struct sk_buff *skb);
1da177e4
LT
43
44/* New CCP stuff */
45static void isdn_ppp_ccp_kickup(struct ippp_struct *is);
46static void isdn_ppp_ccp_xmit_reset(struct ippp_struct *is, int proto,
47 unsigned char code, unsigned char id,
48 unsigned char *data, int len);
49static struct ippp_ccp_reset *isdn_ppp_ccp_reset_alloc(struct ippp_struct *is);
50static void isdn_ppp_ccp_reset_free(struct ippp_struct *is);
51static void isdn_ppp_ccp_reset_free_state(struct ippp_struct *is,
52 unsigned char id);
53static void isdn_ppp_ccp_timer_callback(unsigned long closure);
54static struct ippp_ccp_reset_state *isdn_ppp_ccp_reset_alloc_state(struct ippp_struct *is,
475be4d8 55 unsigned char id);
1da177e4
LT
56static void isdn_ppp_ccp_reset_trans(struct ippp_struct *is,
57 struct isdn_ppp_resetparams *rp);
58static void isdn_ppp_ccp_reset_ack_rcvd(struct ippp_struct *is,
59 unsigned char id);
60
61
62
63#ifdef CONFIG_ISDN_MPP
475be4d8
JP
64static ippp_bundle *isdn_ppp_bundle_arr = NULL;
65
1da177e4 66static int isdn_ppp_mp_bundle_array_init(void);
475be4d8
JP
67static int isdn_ppp_mp_init(isdn_net_local *lp, ippp_bundle *add_to);
68static void isdn_ppp_mp_receive(isdn_net_dev *net_dev, isdn_net_local *lp,
69 struct sk_buff *skb);
70static void isdn_ppp_mp_cleanup(isdn_net_local *lp);
1da177e4
LT
71
72static int isdn_ppp_bundle(struct ippp_struct *, int unit);
73#endif /* CONFIG_ISDN_MPP */
475be4d8 74
1da177e4
LT
75char *isdn_ppp_revision = "$Revision: 1.1.2.3 $";
76
77static struct ippp_struct *ippp_table[ISDN_MAX_CHANNELS];
78
79static struct isdn_ppp_compressor *ipc_head = NULL;
80
81/*
82 * frame log (debug)
83 */
84static void
475be4d8 85isdn_ppp_frame_log(char *info, char *data, int len, int maxlen, int unit, int slot)
1da177e4
LT
86{
87 int cnt,
475be4d8
JP
88 j,
89 i;
1da177e4
LT
90 char buf[80];
91
92 if (len < maxlen)
93 maxlen = len;
94
95 for (i = 0, cnt = 0; cnt < maxlen; i++) {
96 for (j = 0; j < 16 && cnt < maxlen; j++, cnt++)
475be4d8
JP
97 sprintf(buf + j * 3, "%02x ", (unsigned char)data[cnt]);
98 printk(KERN_DEBUG "[%d/%d].%s[%d]: %s\n", unit, slot, info, i, buf);
1da177e4
LT
99 }
100}
101
102/*
103 * unbind isdn_net_local <=> ippp-device
104 * note: it can happen, that we hangup/free the master before the slaves
105 * in this case we bind another lp to the master device
106 */
107int
475be4d8 108isdn_ppp_free(isdn_net_local *lp)
1da177e4
LT
109{
110 struct ippp_struct *is;
111
052bb88e 112 if (lp->ppp_slot < 0 || lp->ppp_slot >= ISDN_MAX_CHANNELS) {
1da177e4 113 printk(KERN_ERR "%s: ppp_slot(%d) out of range\n",
475be4d8 114 __func__, lp->ppp_slot);
1da177e4
LT
115 return 0;
116 }
117
118#ifdef CONFIG_ISDN_MPP
119 spin_lock(&lp->netdev->pb->lock);
120#endif
121 isdn_net_rm_from_bundle(lp);
122#ifdef CONFIG_ISDN_MPP
123 if (lp->netdev->pb->ref_ct == 1) /* last link in queue? */
124 isdn_ppp_mp_cleanup(lp);
125
126 lp->netdev->pb->ref_ct--;
127 spin_unlock(&lp->netdev->pb->lock);
128#endif /* CONFIG_ISDN_MPP */
052bb88e 129 if (lp->ppp_slot < 0 || lp->ppp_slot >= ISDN_MAX_CHANNELS) {
1da177e4 130 printk(KERN_ERR "%s: ppp_slot(%d) now invalid\n",
475be4d8 131 __func__, lp->ppp_slot);
1da177e4
LT
132 return 0;
133 }
134 is = ippp_table[lp->ppp_slot];
135 if ((is->state & IPPP_CONNECT))
136 isdn_ppp_closewait(lp->ppp_slot); /* force wakeup on ippp device */
137 else if (is->state & IPPP_ASSIGNED)
138 is->state = IPPP_OPEN; /* fallback to 'OPEN but not ASSIGNED' state */
139
140 if (is->debug & 0x1)
141 printk(KERN_DEBUG "isdn_ppp_free %d %lx %lx\n", lp->ppp_slot, (long) lp, (long) is->lp);
142
143 is->lp = NULL; /* link is down .. set lp to NULL */
144 lp->ppp_slot = -1; /* is this OK ?? */
145
146 return 0;
147}
148
149/*
150 * bind isdn_net_local <=> ippp-device
151 *
152 * This function is allways called with holding dev->lock so
153 * no additional lock is needed
154 */
155int
475be4d8 156isdn_ppp_bind(isdn_net_local *lp)
1da177e4
LT
157{
158 int i;
159 int unit = 0;
160 struct ippp_struct *is;
161 int retval;
162
163 if (lp->pppbind < 0) { /* device bounded to ippp device ? */
164 isdn_net_dev *net_dev = dev->netdev;
165 char exclusive[ISDN_MAX_CHANNELS]; /* exclusive flags */
166 memset(exclusive, 0, ISDN_MAX_CHANNELS);
167 while (net_dev) { /* step through net devices to find exclusive minors */
168 isdn_net_local *lp = net_dev->local;
169 if (lp->pppbind >= 0)
170 exclusive[lp->pppbind] = 1;
171 net_dev = net_dev->next;
172 }
173 /*
174 * search a free device / slot
175 */
176 for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
177 if (ippp_table[i]->state == IPPP_OPEN && !exclusive[ippp_table[i]->minor]) { /* OPEN, but not connected! */
178 break;
179 }
180 }
181 } else {
182 for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
183 if (ippp_table[i]->minor == lp->pppbind &&
184 (ippp_table[i]->state & IPPP_OPEN) == IPPP_OPEN)
185 break;
186 }
187 }
188
189 if (i >= ISDN_MAX_CHANNELS) {
190 printk(KERN_WARNING "isdn_ppp_bind: Can't find a (free) connection to the ipppd daemon.\n");
191 retval = -1;
192 goto out;
193 }
faca94ff
KK
194 /* get unit number from interface name .. ugly! */
195 unit = isdn_ppp_if_get_unit(lp->netdev->dev->name);
1da177e4 196 if (unit < 0) {
faca94ff 197 printk(KERN_ERR "isdn_ppp_bind: illegal interface name %s.\n",
475be4d8 198 lp->netdev->dev->name);
1da177e4
LT
199 retval = -1;
200 goto out;
201 }
475be4d8 202
1da177e4
LT
203 lp->ppp_slot = i;
204 is = ippp_table[i];
205 is->lp = lp;
206 is->unit = unit;
207 is->state = IPPP_OPEN | IPPP_ASSIGNED; /* assigned to a netdevice but not connected */
208#ifdef CONFIG_ISDN_MPP
209 retval = isdn_ppp_mp_init(lp, NULL);
210 if (retval < 0)
211 goto out;
212#endif /* CONFIG_ISDN_MPP */
213
214 retval = lp->ppp_slot;
215
475be4d8 216out:
1da177e4
LT
217 return retval;
218}
219
220/*
221 * kick the ipppd on the device
222 * (wakes up daemon after B-channel connect)
223 */
224
225void
475be4d8 226isdn_ppp_wakeup_daemon(isdn_net_local *lp)
1da177e4
LT
227{
228 if (lp->ppp_slot < 0 || lp->ppp_slot >= ISDN_MAX_CHANNELS) {
229 printk(KERN_ERR "%s: ppp_slot(%d) out of range\n",
475be4d8 230 __func__, lp->ppp_slot);
1da177e4
LT
231 return;
232 }
233 ippp_table[lp->ppp_slot]->state = IPPP_OPEN | IPPP_CONNECT | IPPP_NOBLOCK;
234 wake_up_interruptible(&ippp_table[lp->ppp_slot]->wq);
235}
236
237/*
238 * there was a hangup on the netdevice
239 * force wakeup of the ippp device
240 * go into 'device waits for release' state
241 */
242static int
243isdn_ppp_closewait(int slot)
244{
245 struct ippp_struct *is;
246
247 if (slot < 0 || slot >= ISDN_MAX_CHANNELS) {
248 printk(KERN_ERR "%s: slot(%d) out of range\n",
475be4d8 249 __func__, slot);
1da177e4
LT
250 return 0;
251 }
252 is = ippp_table[slot];
253 if (is->state)
254 wake_up_interruptible(&is->wq);
255 is->state = IPPP_CLOSEWAIT;
256 return 1;
257}
258
259/*
260 * isdn_ppp_find_slot / isdn_ppp_free_slot
261 */
262
263static int
264isdn_ppp_get_slot(void)
265{
266 int i;
267 for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
268 if (!ippp_table[i]->state)
269 return i;
270 }
271 return -1;
272}
273
274/*
275 * isdn_ppp_open
276 */
277
278int
279isdn_ppp_open(int min, struct file *file)
280{
281 int slot;
282 struct ippp_struct *is;
283
052bb88e 284 if (min < 0 || min >= ISDN_MAX_CHANNELS)
1da177e4
LT
285 return -ENODEV;
286
287 slot = isdn_ppp_get_slot();
288 if (slot < 0) {
289 return -EBUSY;
290 }
291 is = file->private_data = ippp_table[slot];
475be4d8 292
1da177e4
LT
293 printk(KERN_DEBUG "ippp, open, slot: %d, minor: %d, state: %04x\n",
294 slot, min, is->state);
295
296 /* compression stuff */
297 is->link_compressor = is->compressor = NULL;
298 is->link_decompressor = is->decompressor = NULL;
299 is->link_comp_stat = is->comp_stat = NULL;
300 is->link_decomp_stat = is->decomp_stat = NULL;
301 is->compflags = 0;
302
303 is->reset = isdn_ppp_ccp_reset_alloc(is);
0baa57d8
BH
304 if (!is->reset)
305 return -ENOMEM;
1da177e4
LT
306
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
321 /*
322 * VJ header compression init
323 */
324 is->slcomp = slhc_init(16, 16); /* not necessary for 2. link in bundle */
4ab42d78 325 if (IS_ERR(is->slcomp)) {
0baa57d8 326 isdn_ppp_ccp_reset_free(is);
4ab42d78 327 return PTR_ERR(is->slcomp);
0baa57d8 328 }
1da177e4
LT
329#endif
330#ifdef CONFIG_IPPP_FILTER
331 is->pass_filter = NULL;
332 is->active_filter = NULL;
333#endif
334 is->state = IPPP_OPEN;
335
336 return 0;
337}
338
339/*
340 * release ippp device
341 */
342void
343isdn_ppp_release(int min, struct file *file)
344{
345 int i;
346 struct ippp_struct *is;
347
348 if (min < 0 || min >= ISDN_MAX_CHANNELS)
349 return;
350 is = file->private_data;
351
352 if (!is) {
156f1ed6 353 printk(KERN_ERR "%s: no file->private_data\n", __func__);
1da177e4
LT
354 return;
355 }
356 if (is->debug & 0x1)
357 printk(KERN_DEBUG "ippp: release, minor: %d %lx\n", min, (long) is->lp);
358
359 if (is->lp) { /* a lp address says: this link is still up */
360 isdn_net_dev *p = is->lp->netdev;
361
362 if (!p) {
156f1ed6 363 printk(KERN_ERR "%s: no lp->netdev\n", __func__);
1da177e4
LT
364 return;
365 }
366 is->state &= ~IPPP_CONNECT; /* -> effect: no call of wakeup */
367 /*
368 * isdn_net_hangup() calls isdn_ppp_free()
369 * isdn_ppp_free() sets is->lp to NULL and lp->ppp_slot to -1
370 * removing the IPPP_CONNECT flag omits calling of isdn_ppp_wakeup_daemon()
371 */
d62a38d1 372 isdn_net_hangup(p->dev);
1da177e4
LT
373 }
374 for (i = 0; i < NUM_RCV_BUFFS; i++) {
3c7208f2
JJ
375 kfree(is->rq[i].buf);
376 is->rq[i].buf = NULL;
1da177e4
LT
377 }
378 is->first = is->rq + NUM_RCV_BUFFS - 1; /* receive queue */
379 is->last = is->rq;
380
381#ifdef CONFIG_ISDN_PPP_VJ
382/* TODO: if this was the previous master: link the slcomp to the new master */
383 slhc_free(is->slcomp);
384 is->slcomp = NULL;
385#endif
386#ifdef CONFIG_IPPP_FILTER
77e0114a 387 if (is->pass_filter) {
7ae457c1 388 bpf_prog_destroy(is->pass_filter);
77e0114a
DB
389 is->pass_filter = NULL;
390 }
391
392 if (is->active_filter) {
7ae457c1 393 bpf_prog_destroy(is->active_filter);
77e0114a
DB
394 is->active_filter = NULL;
395 }
1da177e4
LT
396#endif
397
398/* TODO: if this was the previous master: link the stuff to the new master */
475be4d8 399 if (is->comp_stat)
1da177e4 400 is->compressor->free(is->comp_stat);
475be4d8 401 if (is->link_comp_stat)
1da177e4 402 is->link_compressor->free(is->link_comp_stat);
475be4d8 403 if (is->link_decomp_stat)
1da177e4 404 is->link_decompressor->free(is->link_decomp_stat);
475be4d8 405 if (is->decomp_stat)
1da177e4 406 is->decompressor->free(is->decomp_stat);
475be4d8
JP
407 is->compressor = is->link_compressor = NULL;
408 is->decompressor = is->link_decompressor = NULL;
1da177e4 409 is->comp_stat = is->link_comp_stat = NULL;
475be4d8 410 is->decomp_stat = is->link_decomp_stat = NULL;
1da177e4
LT
411
412 /* Clean up if necessary */
475be4d8 413 if (is->reset)
1da177e4
LT
414 isdn_ppp_ccp_reset_free(is);
415
416 /* this slot is ready for new connections */
417 is->state = 0;
418}
419
420/*
421 * get_arg .. ioctl helper
422 */
423static int
424get_arg(void __user *b, void *val, int len)
425{
426 if (len <= 0)
427 len = sizeof(void *);
428 if (copy_from_user(val, b, len))
429 return -EFAULT;
430 return 0;
431}
432
433/*
434 * set arg .. ioctl helper
435 */
436static int
475be4d8 437set_arg(void __user *b, void *val, int len)
1da177e4 438{
475be4d8 439 if (len <= 0)
1da177e4
LT
440 len = sizeof(void *);
441 if (copy_to_user(b, val, len))
442 return -EFAULT;
443 return 0;
444}
445
26285ba3 446#ifdef CONFIG_IPPP_FILTER
1da177e4
LT
447static int get_filter(void __user *arg, struct sock_filter **p)
448{
449 struct sock_fprog uprog;
450 struct sock_filter *code = NULL;
3916a319 451 int len;
1da177e4
LT
452
453 if (copy_from_user(&uprog, arg, sizeof(uprog)))
454 return -EFAULT;
455
456 if (!uprog.len) {
457 *p = NULL;
458 return 0;
459 }
460
461 /* uprog.len is unsigned short, so no overflow here */
462 len = uprog.len * sizeof(struct sock_filter);
024cb8a6
JL
463 code = memdup_user(uprog.filter, len);
464 if (IS_ERR(code))
465 return PTR_ERR(code);
1da177e4 466
1da177e4
LT
467 *p = code;
468 return uprog.len;
469}
26285ba3 470#endif /* CONFIG_IPPP_FILTER */
1da177e4
LT
471
472/*
473 * ippp device ioctl
474 */
475int
476isdn_ppp_ioctl(int min, struct file *file, unsigned int cmd, unsigned long arg)
477{
478 unsigned long val;
475be4d8 479 int r, i, j;
1da177e4
LT
480 struct ippp_struct *is;
481 isdn_net_local *lp;
482 struct isdn_ppp_comp_data data;
483 void __user *argp = (void __user *)arg;
484
54cbb1ca 485 is = file->private_data;
1da177e4
LT
486 lp = is->lp;
487
488 if (is->debug & 0x1)
489 printk(KERN_DEBUG "isdn_ppp_ioctl: minor: %d cmd: %x state: %x\n", min, cmd, is->state);
490
491 if (!(is->state & IPPP_OPEN))
492 return -EINVAL;
493
494 switch (cmd) {
475be4d8 495 case PPPIOCBUNDLE:
1da177e4 496#ifdef CONFIG_ISDN_MPP
475be4d8
JP
497 if (!(is->state & IPPP_CONNECT))
498 return -EINVAL;
499 if ((r = get_arg(argp, &val, sizeof(val))))
500 return r;
501 printk(KERN_DEBUG "iPPP-bundle: minor: %d, slave unit: %d, master unit: %d\n",
502 (int) min, (int) is->unit, (int) val);
503 return isdn_ppp_bundle(is, val);
1da177e4 504#else
475be4d8 505 return -1;
1da177e4 506#endif
475be4d8
JP
507 break;
508 case PPPIOCGUNIT: /* get ppp/isdn unit number */
509 if ((r = set_arg(argp, &is->unit, sizeof(is->unit))))
510 return r;
511 break;
512 case PPPIOCGIFNAME:
513 if (!lp)
514 return -EINVAL;
515 if ((r = set_arg(argp, lp->netdev->dev->name,
516 strlen(lp->netdev->dev->name))))
517 return r;
518 break;
519 case PPPIOCGMPFLAGS: /* get configuration flags */
520 if ((r = set_arg(argp, &is->mpppcfg, sizeof(is->mpppcfg))))
521 return r;
522 break;
523 case PPPIOCSMPFLAGS: /* set configuration flags */
524 if ((r = get_arg(argp, &val, sizeof(val))))
525 return r;
526 is->mpppcfg = val;
527 break;
528 case PPPIOCGFLAGS: /* get configuration flags */
529 if ((r = set_arg(argp, &is->pppcfg, sizeof(is->pppcfg))))
530 return r;
531 break;
532 case PPPIOCSFLAGS: /* set configuration flags */
533 if ((r = get_arg(argp, &val, sizeof(val)))) {
534 return r;
535 }
536 if (val & SC_ENABLE_IP && !(is->pppcfg & SC_ENABLE_IP) && (is->state & IPPP_CONNECT)) {
1da177e4 537 if (lp) {
475be4d8
JP
538 /* OK .. we are ready to send buffers */
539 is->pppcfg = val; /* isdn_ppp_xmit test for SC_ENABLE_IP !!! */
540 netif_wake_queue(lp->netdev->dev);
541 break;
1da177e4 542 }
475be4d8
JP
543 }
544 is->pppcfg = val;
545 break;
546 case PPPIOCGIDLE: /* get idle time information */
547 if (lp) {
548 struct ppp_idle pidle;
549 pidle.xmit_idle = pidle.recv_idle = lp->huptimer;
550 if ((r = set_arg(argp, &pidle, sizeof(struct ppp_idle))))
1da177e4 551 return r;
475be4d8
JP
552 }
553 break;
554 case PPPIOCSMRU: /* set receive unit size for PPP */
555 if ((r = get_arg(argp, &val, sizeof(val))))
556 return r;
557 is->mru = val;
558 break;
559 case PPPIOCSMPMRU:
560 break;
561 case PPPIOCSMPMTU:
562 break;
563 case PPPIOCSMAXCID: /* set the maximum compression slot id */
564 if ((r = get_arg(argp, &val, sizeof(val))))
565 return r;
566 val++;
567 if (is->maxcid != val) {
1da177e4 568#ifdef CONFIG_ISDN_PPP_VJ
475be4d8 569 struct slcompress *sltmp;
1da177e4 570#endif
475be4d8
JP
571 if (is->debug & 0x1)
572 printk(KERN_DEBUG "ippp, ioctl: changed MAXCID to %ld\n", val);
573 is->maxcid = val;
1da177e4 574#ifdef CONFIG_ISDN_PPP_VJ
475be4d8 575 sltmp = slhc_init(16, val);
4ab42d78
BH
576 if (IS_ERR(sltmp))
577 return PTR_ERR(sltmp);
475be4d8
JP
578 if (is->slcomp)
579 slhc_free(is->slcomp);
580 is->slcomp = sltmp;
581#endif
582 }
583 break;
584 case PPPIOCGDEBUG:
585 if ((r = set_arg(argp, &is->debug, sizeof(is->debug))))
586 return r;
587 break;
588 case PPPIOCSDEBUG:
589 if ((r = get_arg(argp, &val, sizeof(val))))
590 return r;
591 is->debug = val;
592 break;
593 case PPPIOCGCOMPRESSORS:
594 {
595 unsigned long protos[8] = {0,};
596 struct isdn_ppp_compressor *ipc = ipc_head;
597 while (ipc) {
598 j = ipc->num / (sizeof(long) * 8);
599 i = ipc->num % (sizeof(long) * 8);
600 if (j < 8)
435f08a7 601 protos[j] |= (1UL << i);
475be4d8
JP
602 ipc = ipc->next;
603 }
604 if ((r = set_arg(argp, protos, 8 * sizeof(long))))
605 return r;
606 }
607 break;
608 case PPPIOCSCOMPRESSOR:
609 if ((r = get_arg(argp, &data, sizeof(struct isdn_ppp_comp_data))))
610 return r;
611 return isdn_ppp_set_compressor(is, &data);
612 case PPPIOCGCALLINFO:
613 {
614 struct pppcallinfo pci;
615 memset((char *)&pci, 0, sizeof(struct pppcallinfo));
616 if (lp)
617 {
618 strncpy(pci.local_num, lp->msn, 63);
619 if (lp->dial) {
620 strncpy(pci.remote_num, lp->dial->num, 63);
1da177e4 621 }
475be4d8
JP
622 pci.charge_units = lp->charge;
623 if (lp->outgoing)
624 pci.calltype = CALLTYPE_OUTGOING;
625 else
626 pci.calltype = CALLTYPE_INCOMING;
627 if (lp->flags & ISDN_NET_CALLBACK)
628 pci.calltype |= CALLTYPE_CALLBACK;
629 }
630 return set_arg(argp, &pci, sizeof(struct pppcallinfo));
631 }
1da177e4 632#ifdef CONFIG_IPPP_FILTER
475be4d8
JP
633 case PPPIOCSPASS:
634 {
b1fcd35c 635 struct sock_fprog_kern fprog;
475be4d8 636 struct sock_filter *code;
77e0114a
DB
637 int err, len = get_filter(argp, &code);
638
475be4d8
JP
639 if (len < 0)
640 return len;
77e0114a
DB
641
642 fprog.len = len;
643 fprog.filter = code;
644
cc25eaae 645 if (is->pass_filter) {
7ae457c1 646 bpf_prog_destroy(is->pass_filter);
cc25eaae
CS
647 is->pass_filter = NULL;
648 }
649 if (fprog.filter != NULL)
7ae457c1 650 err = bpf_prog_create(&is->pass_filter, &fprog);
cc25eaae
CS
651 else
652 err = 0;
77e0114a
DB
653 kfree(code);
654
655 return err;
475be4d8
JP
656 }
657 case PPPIOCSACTIVE:
658 {
b1fcd35c 659 struct sock_fprog_kern fprog;
475be4d8 660 struct sock_filter *code;
77e0114a
DB
661 int err, len = get_filter(argp, &code);
662
475be4d8
JP
663 if (len < 0)
664 return len;
77e0114a
DB
665
666 fprog.len = len;
667 fprog.filter = code;
668
cc25eaae 669 if (is->active_filter) {
7ae457c1 670 bpf_prog_destroy(is->active_filter);
cc25eaae
CS
671 is->active_filter = NULL;
672 }
673 if (fprog.filter != NULL)
7ae457c1 674 err = bpf_prog_create(&is->active_filter, &fprog);
cc25eaae
CS
675 else
676 err = 0;
77e0114a
DB
677 kfree(code);
678
679 return err;
475be4d8 680 }
1da177e4 681#endif /* CONFIG_IPPP_FILTER */
475be4d8
JP
682 default:
683 break;
1da177e4
LT
684 }
685 return 0;
686}
687
688unsigned int
475be4d8 689isdn_ppp_poll(struct file *file, poll_table *wait)
1da177e4
LT
690{
691 u_int mask;
692 struct ippp_buf_queue *bf, *bl;
693 u_long flags;
694 struct ippp_struct *is;
695
696 is = file->private_data;
697
698 if (is->debug & 0x2)
699 printk(KERN_DEBUG "isdn_ppp_poll: minor: %d\n",
496ad9aa 700 iminor(file_inode(file)));
1da177e4
LT
701
702 /* just registers wait_queue hook. This doesn't really wait. */
703 poll_wait(file, &is->wq, wait);
704
705 if (!(is->state & IPPP_OPEN)) {
475be4d8 706 if (is->state == IPPP_CLOSEWAIT)
1da177e4
LT
707 return POLLHUP;
708 printk(KERN_DEBUG "isdn_ppp: device not open\n");
709 return POLLERR;
710 }
711 /* we're always ready to send .. */
712 mask = POLLOUT | POLLWRNORM;
713
714 spin_lock_irqsave(&is->buflock, flags);
715 bl = is->last;
716 bf = is->first;
717 /*
718 * if IPPP_NOBLOCK is set we return even if we have nothing to read
719 */
720 if (bf->next != bl || (is->state & IPPP_NOBLOCK)) {
721 is->state &= ~IPPP_NOBLOCK;
722 mask |= POLLIN | POLLRDNORM;
723 }
724 spin_unlock_irqrestore(&is->buflock, flags);
725 return mask;
726}
727
728/*
729 * fill up isdn_ppp_read() queue ..
730 */
731
732static int
733isdn_ppp_fill_rq(unsigned char *buf, int len, int proto, int slot)
734{
735 struct ippp_buf_queue *bf, *bl;
736 u_long flags;
737 u_char *nbuf;
738 struct ippp_struct *is;
739
740 if (slot < 0 || slot >= ISDN_MAX_CHANNELS) {
741 printk(KERN_WARNING "ippp: illegal slot(%d).\n", slot);
742 return 0;
743 }
744 is = ippp_table[slot];
745
746 if (!(is->state & IPPP_CONNECT)) {
747 printk(KERN_DEBUG "ippp: device not activated.\n");
748 return 0;
749 }
5cbded58 750 nbuf = kmalloc(len + 4, GFP_ATOMIC);
1da177e4
LT
751 if (!nbuf) {
752 printk(KERN_WARNING "ippp: Can't alloc buf\n");
753 return 0;
754 }
755 nbuf[0] = PPP_ALLSTATIONS;
756 nbuf[1] = PPP_UI;
757 nbuf[2] = proto >> 8;
758 nbuf[3] = proto & 0xff;
759 memcpy(nbuf + 4, buf, len);
760
761 spin_lock_irqsave(&is->buflock, flags);
762 bf = is->first;
763 bl = is->last;
764
765 if (bf == bl) {
766 printk(KERN_WARNING "ippp: Queue is full; discarding first buffer\n");
767 bf = bf->next;
768 kfree(bf->buf);
769 is->first = bf;
770 }
771 bl->buf = (char *) nbuf;
772 bl->len = len + 4;
773
774 is->last = bl->next;
775 spin_unlock_irqrestore(&is->buflock, flags);
776 wake_up_interruptible(&is->wq);
777 return len;
778}
779
780/*
781 * read() .. non-blocking: ipppd calls it only after select()
782 * reports, that there is data
783 */
784
785int
786isdn_ppp_read(int min, struct file *file, char __user *buf, int count)
787{
788 struct ippp_struct *is;
789 struct ippp_buf_queue *b;
790 u_long flags;
791 u_char *save_buf;
792
793 is = file->private_data;
794
795 if (!(is->state & IPPP_OPEN))
796 return 0;
797
1da177e4
LT
798 spin_lock_irqsave(&is->buflock, flags);
799 b = is->first->next;
800 save_buf = b->buf;
801 if (!save_buf) {
802 spin_unlock_irqrestore(&is->buflock, flags);
803 return -EAGAIN;
804 }
805 if (b->len < count)
806 count = b->len;
807 b->buf = NULL;
808 is->first = b;
809
810 spin_unlock_irqrestore(&is->buflock, flags);
c41a24ce
JJ
811 if (copy_to_user(buf, save_buf, count))
812 count = -EFAULT;
1da177e4
LT
813 kfree(save_buf);
814
815 return count;
816}
817
818/*
819 * ipppd wanna write a packet to the card .. non-blocking
820 */
821
822int
823isdn_ppp_write(int min, struct file *file, const char __user *buf, int count)
824{
825 isdn_net_local *lp;
826 struct ippp_struct *is;
827 int proto;
1da177e4
LT
828
829 is = file->private_data;
830
831 if (!(is->state & IPPP_CONNECT))
832 return 0;
833
834 lp = is->lp;
835
836 /* -> push it directly to the lowlevel interface */
837
838 if (!lp)
839 printk(KERN_DEBUG "isdn_ppp_write: lp == NULL\n");
840 else {
905b785c
MX
841 if (lp->isdn_device < 0 || lp->isdn_channel < 0) {
842 unsigned char protobuf[4];
843 /*
844 * Don't reset huptimer for
845 * LCP packets. (Echo requests).
846 */
847 if (copy_from_user(protobuf, buf, 4))
848 return -EFAULT;
849
850 proto = PPP_PROTOCOL(protobuf);
851 if (proto != PPP_LCP)
852 lp->huptimer = 0;
1da177e4 853
1da177e4 854 return 0;
905b785c 855 }
1da177e4
LT
856
857 if ((dev->drv[lp->isdn_device]->flags & DRV_FLAG_RUNNING) &&
475be4d8 858 lp->dialstate == 0 &&
1da177e4
LT
859 (lp->flags & ISDN_NET_CONNECTED)) {
860 unsigned short hl;
861 struct sk_buff *skb;
905b785c 862 unsigned char *cpy_buf;
1da177e4 863 /*
af901ca1 864 * we need to reserve enough space in front of
1da177e4
LT
865 * sk_buff. old call to dev_alloc_skb only reserved
866 * 16 bytes, now we are looking what the driver want
867 */
868 hl = dev->drv[lp->isdn_device]->interface->hl_hdrlen;
475be4d8 869 skb = alloc_skb(hl + count, GFP_ATOMIC);
1da177e4
LT
870 if (!skb) {
871 printk(KERN_WARNING "isdn_ppp_write: out of memory!\n");
872 return count;
873 }
874 skb_reserve(skb, hl);
905b785c
MX
875 cpy_buf = skb_put(skb, count);
876 if (copy_from_user(cpy_buf, buf, count))
1da177e4
LT
877 {
878 kfree_skb(skb);
879 return -EFAULT;
880 }
905b785c
MX
881
882 /*
883 * Don't reset huptimer for
884 * LCP packets. (Echo requests).
885 */
886 proto = PPP_PROTOCOL(cpy_buf);
887 if (proto != PPP_LCP)
888 lp->huptimer = 0;
889
1da177e4
LT
890 if (is->debug & 0x40) {
891 printk(KERN_DEBUG "ppp xmit: len %d\n", (int) skb->len);
475be4d8 892 isdn_ppp_frame_log("xmit", skb->data, skb->len, 32, is->unit, lp->ppp_slot);
1da177e4
LT
893 }
894
475be4d8 895 isdn_ppp_send_ccp(lp->netdev, lp, skb); /* keeps CCP/compression states in sync */
1da177e4
LT
896
897 isdn_net_write_super(lp, skb);
898 }
899 }
900 return count;
901}
902
903/*
904 * init memory, structures etc.
905 */
906
907int
908isdn_ppp_init(void)
909{
910 int i,
475be4d8
JP
911 j;
912
1da177e4 913#ifdef CONFIG_ISDN_MPP
475be4d8 914 if (isdn_ppp_mp_bundle_array_init() < 0)
1da177e4
LT
915 return -ENOMEM;
916#endif /* CONFIG_ISDN_MPP */
917
918 for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
41f96935 919 if (!(ippp_table[i] = kzalloc(sizeof(struct ippp_struct), GFP_KERNEL))) {
1da177e4
LT
920 printk(KERN_WARNING "isdn_ppp_init: Could not alloc ippp_table\n");
921 for (j = 0; j < i; j++)
922 kfree(ippp_table[j]);
923 return -1;
924 }
1da177e4
LT
925 spin_lock_init(&ippp_table[i]->buflock);
926 ippp_table[i]->state = 0;
927 ippp_table[i]->first = ippp_table[i]->rq + NUM_RCV_BUFFS - 1;
928 ippp_table[i]->last = ippp_table[i]->rq;
929
930 for (j = 0; j < NUM_RCV_BUFFS; j++) {
931 ippp_table[i]->rq[j].buf = NULL;
932 ippp_table[i]->rq[j].last = ippp_table[i]->rq +
475be4d8 933 (NUM_RCV_BUFFS + j - 1) % NUM_RCV_BUFFS;
1da177e4
LT
934 ippp_table[i]->rq[j].next = ippp_table[i]->rq + (j + 1) % NUM_RCV_BUFFS;
935 }
936 }
937 return 0;
938}
939
940void
941isdn_ppp_cleanup(void)
942{
943 int i;
944
945 for (i = 0; i < ISDN_MAX_CHANNELS; i++)
946 kfree(ippp_table[i]);
947
948#ifdef CONFIG_ISDN_MPP
3c7208f2 949 kfree(isdn_ppp_bundle_arr);
1da177e4
LT
950#endif /* CONFIG_ISDN_MPP */
951
952}
953
954/*
955 * check for address/control field and skip if allowed
956 * retval != 0 -> discard packet silently
957 */
475be4d8 958static int isdn_ppp_skip_ac(struct ippp_struct *is, struct sk_buff *skb)
1da177e4
LT
959{
960 if (skb->len < 1)
961 return -1;
962
963 if (skb->data[0] == 0xff) {
964 if (skb->len < 2)
965 return -1;
966
967 if (skb->data[1] != 0x03)
968 return -1;
969
970 // skip address/control (AC) field
971 skb_pull(skb, 2);
475be4d8 972 } else {
1da177e4
LT
973 if (is->pppcfg & SC_REJ_COMP_AC)
974 // if AC compression was not negotiated, but used, discard packet
975 return -1;
976 }
977 return 0;
978}
979
980/*
981 * get the PPP protocol header and pull skb
982 * retval < 0 -> discard packet silently
983 */
475be4d8 984static int isdn_ppp_strip_proto(struct sk_buff *skb)
1da177e4
LT
985{
986 int proto;
475be4d8 987
1da177e4
LT
988 if (skb->len < 1)
989 return -1;
990
991 if (skb->data[0] & 0x1) {
992 // protocol field is compressed
993 proto = skb->data[0];
994 skb_pull(skb, 1);
995 } else {
996 if (skb->len < 2)
997 return -1;
998 proto = ((int) skb->data[0] << 8) + skb->data[1];
999 skb_pull(skb, 2);
1000 }
1001 return proto;
1002}
1003
1004
1005/*
1006 * handler for incoming packets on a syncPPP interface
1007 */
475be4d8 1008void isdn_ppp_receive(isdn_net_dev *net_dev, isdn_net_local *lp, struct sk_buff *skb)
1da177e4
LT
1009{
1010 struct ippp_struct *is;
1011 int slot;
1012 int proto;
1013
6dd44a74 1014 BUG_ON(net_dev->local->master); // we're called with the master device always
1da177e4
LT
1015
1016 slot = lp->ppp_slot;
1017 if (slot < 0 || slot >= ISDN_MAX_CHANNELS) {
1018 printk(KERN_ERR "isdn_ppp_receive: lp->ppp_slot(%d)\n",
475be4d8 1019 lp->ppp_slot);
1da177e4
LT
1020 kfree_skb(skb);
1021 return;
1022 }
1023 is = ippp_table[slot];
1024
1025 if (is->debug & 0x4) {
1026 printk(KERN_DEBUG "ippp_receive: is:%08lx lp:%08lx slot:%d unit:%d len:%d\n",
475be4d8
JP
1027 (long)is, (long)lp, lp->ppp_slot, is->unit, (int)skb->len);
1028 isdn_ppp_frame_log("receive", skb->data, skb->len, 32, is->unit, lp->ppp_slot);
1029 }
1030
1031 if (isdn_ppp_skip_ac(is, skb) < 0) {
1032 kfree_skb(skb);
1033 return;
1034 }
1035 proto = isdn_ppp_strip_proto(skb);
1036 if (proto < 0) {
1037 kfree_skb(skb);
1038 return;
1039 }
1040
1da177e4 1041#ifdef CONFIG_ISDN_MPP
475be4d8
JP
1042 if (is->compflags & SC_LINK_DECOMP_ON) {
1043 skb = isdn_ppp_decompress(skb, is, NULL, &proto);
1044 if (!skb) // decompression error
1045 return;
1046 }
1047
1048 if (!(is->mpppcfg & SC_REJ_MP_PROT)) { // we agreed to receive MPPP
1049 if (proto == PPP_MP) {
1050 isdn_ppp_mp_receive(net_dev, lp, skb);
1051 return;
1052 }
1053 }
1da177e4 1054#endif
475be4d8 1055 isdn_ppp_push_higher(net_dev, lp, skb, proto);
1da177e4
LT
1056}
1057
1058/*
1059 * we receive a reassembled frame, MPPP has been taken care of before.
1060 * address/control and protocol have been stripped from the skb
1061 * note: net_dev has to be master net_dev
1062 */
1063static void
475be4d8 1064isdn_ppp_push_higher(isdn_net_dev *net_dev, isdn_net_local *lp, struct sk_buff *skb, int proto)
1da177e4 1065{
d62a38d1 1066 struct net_device *dev = net_dev->dev;
475be4d8 1067 struct ippp_struct *is, *mis;
1da177e4
LT
1068 isdn_net_local *mlp = NULL;
1069 int slot;
1070
1071 slot = lp->ppp_slot;
1072 if (slot < 0 || slot >= ISDN_MAX_CHANNELS) {
1073 printk(KERN_ERR "isdn_ppp_push_higher: lp->ppp_slot(%d)\n",
475be4d8 1074 lp->ppp_slot);
1da177e4
LT
1075 goto drop_packet;
1076 }
1077 is = ippp_table[slot];
475be4d8
JP
1078
1079 if (lp->master) { // FIXME?
838361fe 1080 mlp = ISDN_MASTER_PRIV(lp);
475be4d8
JP
1081 slot = mlp->ppp_slot;
1082 if (slot < 0 || slot >= ISDN_MAX_CHANNELS) {
1083 printk(KERN_ERR "isdn_ppp_push_higher: master->ppp_slot(%d)\n",
1084 lp->ppp_slot);
1da177e4 1085 goto drop_packet;
475be4d8
JP
1086 }
1087 }
1088 mis = ippp_table[slot];
1da177e4
LT
1089
1090 if (is->debug & 0x10) {
1091 printk(KERN_DEBUG "push, skb %d %04x\n", (int) skb->len, proto);
475be4d8 1092 isdn_ppp_frame_log("rpush", skb->data, skb->len, 32, is->unit, lp->ppp_slot);
1da177e4
LT
1093 }
1094 if (mis->compflags & SC_DECOMP_ON) {
1095 skb = isdn_ppp_decompress(skb, is, mis, &proto);
1096 if (!skb) // decompression error
475be4d8
JP
1097 return;
1098 }
1da177e4 1099 switch (proto) {
475be4d8
JP
1100 case PPP_IPX: /* untested */
1101 if (is->debug & 0x20)
1102 printk(KERN_DEBUG "isdn_ppp: IPX\n");
1103 skb->protocol = htons(ETH_P_IPX);
1104 break;
1105 case PPP_IP:
1106 if (is->debug & 0x20)
1107 printk(KERN_DEBUG "isdn_ppp: IP\n");
1108 skb->protocol = htons(ETH_P_IP);
1109 break;
1110 case PPP_COMP:
1111 case PPP_COMPFRAG:
1112 printk(KERN_INFO "isdn_ppp: unexpected compressed frame dropped\n");
1113 goto drop_packet;
1da177e4 1114#ifdef CONFIG_ISDN_PPP_VJ
475be4d8
JP
1115 case PPP_VJC_UNCOMP:
1116 if (is->debug & 0x20)
1117 printk(KERN_DEBUG "isdn_ppp: VJC_UNCOMP\n");
1118 if (net_dev->local->ppp_slot < 0) {
1119 printk(KERN_ERR "%s: net_dev->local->ppp_slot(%d) out of range\n",
1120 __func__, net_dev->local->ppp_slot);
1121 goto drop_packet;
1122 }
1123 if (slhc_remember(ippp_table[net_dev->local->ppp_slot]->slcomp, skb->data, skb->len) <= 0) {
1124 printk(KERN_WARNING "isdn_ppp: received illegal VJC_UNCOMP frame!\n");
1125 goto drop_packet;
1126 }
1127 skb->protocol = htons(ETH_P_IP);
1128 break;
1129 case PPP_VJC_COMP:
1130 if (is->debug & 0x20)
1131 printk(KERN_DEBUG "isdn_ppp: VJC_COMP\n");
1132 {
1133 struct sk_buff *skb_old = skb;
1134 int pkt_len;
1135 skb = dev_alloc_skb(skb_old->len + 128);
1136
1137 if (!skb) {
1138 printk(KERN_WARNING "%s: Memory squeeze, dropping packet.\n", dev->name);
1139 skb = skb_old;
1140 goto drop_packet;
1141 }
1142 skb_put(skb, skb_old->len + 128);
1143 skb_copy_from_linear_data(skb_old, skb->data,
1144 skb_old->len);
1da177e4
LT
1145 if (net_dev->local->ppp_slot < 0) {
1146 printk(KERN_ERR "%s: net_dev->local->ppp_slot(%d) out of range\n",
475be4d8 1147 __func__, net_dev->local->ppp_slot);
1da177e4
LT
1148 goto drop_packet;
1149 }
475be4d8
JP
1150 pkt_len = slhc_uncompress(ippp_table[net_dev->local->ppp_slot]->slcomp,
1151 skb->data, skb_old->len);
1152 kfree_skb(skb_old);
1153 if (pkt_len < 0)
1da177e4 1154 goto drop_packet;
475be4d8
JP
1155
1156 skb_trim(skb, pkt_len);
1da177e4 1157 skb->protocol = htons(ETH_P_IP);
475be4d8
JP
1158 }
1159 break;
1da177e4 1160#endif
475be4d8
JP
1161 case PPP_CCP:
1162 case PPP_CCPFRAG:
1163 isdn_ppp_receive_ccp(net_dev, lp, skb, proto);
1164 /* Dont pop up ResetReq/Ack stuff to the daemon any
1165 longer - the job is done already */
1166 if (skb->data[0] == CCP_RESETREQ ||
1167 skb->data[0] == CCP_RESETACK)
1168 break;
1169 /* fall through */
1170 default:
1171 isdn_ppp_fill_rq(skb->data, skb->len, proto, lp->ppp_slot); /* push data to pppd device */
1172 kfree_skb(skb);
1173 return;
1da177e4
LT
1174 }
1175
1176#ifdef CONFIG_IPPP_FILTER
1177 /* check if the packet passes the pass and active filters
1178 * the filter instructions are constructed assuming
1179 * a four-byte PPP header on each packet (which is still present) */
1180 skb_push(skb, 4);
1181
1182 {
1183 u_int16_t *p = (u_int16_t *) skb->data;
1184
d8470b7c 1185 *p = 0; /* indicate inbound */
1da177e4
LT
1186 }
1187
1188 if (is->pass_filter
7ae457c1 1189 && BPF_PROG_RUN(is->pass_filter, skb) == 0) {
1da177e4
LT
1190 if (is->debug & 0x2)
1191 printk(KERN_DEBUG "IPPP: inbound frame filtered.\n");
1192 kfree_skb(skb);
1193 return;
1194 }
1195 if (!(is->active_filter
7ae457c1 1196 && BPF_PROG_RUN(is->active_filter, skb) == 0)) {
1da177e4 1197 if (is->debug & 0x2)
ee556fe5 1198 printk(KERN_DEBUG "IPPP: link-active filter: resetting huptimer.\n");
1da177e4
LT
1199 lp->huptimer = 0;
1200 if (mlp)
1201 mlp->huptimer = 0;
1202 }
1203 skb_pull(skb, 4);
1204#else /* CONFIG_IPPP_FILTER */
1205 lp->huptimer = 0;
1206 if (mlp)
1207 mlp->huptimer = 0;
1208#endif /* CONFIG_IPPP_FILTER */
1209 skb->dev = dev;
459a98ed 1210 skb_reset_mac_header(skb);
1da177e4
LT
1211 netif_rx(skb);
1212 /* net_dev->local->stats.rx_packets++; done in isdn_net.c */
1213 return;
1214
475be4d8 1215drop_packet:
1da177e4
LT
1216 net_dev->local->stats.rx_dropped++;
1217 kfree_skb(skb);
1218}
1219
1220/*
1221 * isdn_ppp_skb_push ..
1222 * checks whether we have enough space at the beginning of the skb
1223 * and allocs a new SKB if necessary
1224 */
475be4d8 1225static unsigned char *isdn_ppp_skb_push(struct sk_buff **skb_p, int len)
1da177e4
LT
1226{
1227 struct sk_buff *skb = *skb_p;
1228
475be4d8 1229 if (skb_headroom(skb) < len) {
1da177e4
LT
1230 struct sk_buff *nskb = skb_realloc_headroom(skb, len);
1231
1232 if (!nskb) {
1233 printk(KERN_ERR "isdn_ppp_skb_push: can't realloc headroom!\n");
1234 dev_kfree_skb(skb);
1235 return NULL;
1236 }
475be4d8 1237 printk(KERN_DEBUG "isdn_ppp_skb_push:under %d %d\n", skb_headroom(skb), len);
1da177e4
LT
1238 dev_kfree_skb(skb);
1239 *skb_p = nskb;
1240 return skb_push(nskb, len);
1241 }
475be4d8 1242 return skb_push(skb, len);
1da177e4
LT
1243}
1244
1245/*
1246 * send ppp frame .. we expect a PIDCOMPressable proto --
1247 * (here: currently always PPP_IP,PPP_VJC_COMP,PPP_VJC_UNCOMP)
1248 *
1249 * VJ compression may change skb pointer!!! .. requeue with old
1250 * skb isn't allowed!!
1251 */
1252
1253int
1254isdn_ppp_xmit(struct sk_buff *skb, struct net_device *netdev)
1255{
475be4d8 1256 isdn_net_local *lp, *mlp;
1da177e4
LT
1257 isdn_net_dev *nd;
1258 unsigned int proto = PPP_IP; /* 0x21 */
475be4d8 1259 struct ippp_struct *ipt, *ipts;
ec634fe3 1260 int slot, retval = NETDEV_TX_OK;
1da177e4 1261
a17531fa 1262 mlp = netdev_priv(netdev);
1da177e4
LT
1263 nd = mlp->netdev; /* get master lp */
1264
1265 slot = mlp->ppp_slot;
1266 if (slot < 0 || slot >= ISDN_MAX_CHANNELS) {
1267 printk(KERN_ERR "isdn_ppp_xmit: lp->ppp_slot(%d)\n",
475be4d8 1268 mlp->ppp_slot);
1da177e4
LT
1269 kfree_skb(skb);
1270 goto out;
1271 }
1272 ipts = ippp_table[slot];
1273
1274 if (!(ipts->pppcfg & SC_ENABLE_IP)) { /* PPP connected ? */
1275 if (ipts->debug & 0x1)
1276 printk(KERN_INFO "%s: IP frame delayed.\n", netdev->name);
ec634fe3 1277 retval = NETDEV_TX_BUSY;
1da177e4
LT
1278 goto out;
1279 }
1280
1281 switch (ntohs(skb->protocol)) {
475be4d8
JP
1282 case ETH_P_IP:
1283 proto = PPP_IP;
1284 break;
1285 case ETH_P_IPX:
1286 proto = PPP_IPX; /* untested */
1287 break;
1288 default:
1289 printk(KERN_ERR "isdn_ppp: skipped unsupported protocol: %#x.\n",
1290 skb->protocol);
1291 dev_kfree_skb(skb);
1292 goto out;
1da177e4
LT
1293 }
1294
1295 lp = isdn_net_get_locked_lp(nd);
1296 if (!lp) {
1297 printk(KERN_WARNING "%s: all channels busy - requeuing!\n", netdev->name);
ec634fe3 1298 retval = NETDEV_TX_BUSY;
1da177e4
LT
1299 goto out;
1300 }
1301 /* we have our lp locked from now on */
1302
1303 slot = lp->ppp_slot;
052bb88e 1304 if (slot < 0 || slot >= ISDN_MAX_CHANNELS) {
1da177e4 1305 printk(KERN_ERR "isdn_ppp_xmit: lp->ppp_slot(%d)\n",
475be4d8 1306 lp->ppp_slot);
1da177e4
LT
1307 kfree_skb(skb);
1308 goto unlock;
1309 }
1310 ipt = ippp_table[slot];
1311
1312 /*
1313 * after this line .. requeueing in the device queue is no longer allowed!!!
1314 */
1315
1316 /* Pull off the fake header we stuck on earlier to keep
1317 * the fragmentation code happy.
1318 */
475be4d8 1319 skb_pull(skb, IPPP_MAX_HEADER);
1da177e4
LT
1320
1321#ifdef CONFIG_IPPP_FILTER
1322 /* check if we should pass this packet
1323 * the filter instructions are constructed assuming
1324 * a four-byte PPP header on each packet */
d58ff351 1325 *(u8 *)skb_push(skb, 4) = 1; /* indicate outbound */
1da177e4
LT
1326
1327 {
c19d0369 1328 __be16 *p = (__be16 *)skb->data;
1da177e4 1329
d8470b7c 1330 p++;
c19d0369 1331 *p = htons(proto);
1da177e4
LT
1332 }
1333
1334 if (ipt->pass_filter
7ae457c1 1335 && BPF_PROG_RUN(ipt->pass_filter, skb) == 0) {
1da177e4
LT
1336 if (ipt->debug & 0x4)
1337 printk(KERN_DEBUG "IPPP: outbound frame filtered.\n");
1338 kfree_skb(skb);
1339 goto unlock;
1340 }
1341 if (!(ipt->active_filter
7ae457c1 1342 && BPF_PROG_RUN(ipt->active_filter, skb) == 0)) {
1da177e4 1343 if (ipt->debug & 0x4)
ee556fe5 1344 printk(KERN_DEBUG "IPPP: link-active filter: resetting huptimer.\n");
1da177e4
LT
1345 lp->huptimer = 0;
1346 }
1347 skb_pull(skb, 4);
1348#else /* CONFIG_IPPP_FILTER */
1349 lp->huptimer = 0;
1350#endif /* CONFIG_IPPP_FILTER */
1351
1352 if (ipt->debug & 0x4)
1353 printk(KERN_DEBUG "xmit skb, len %d\n", (int) skb->len);
475be4d8
JP
1354 if (ipts->debug & 0x40)
1355 isdn_ppp_frame_log("xmit0", skb->data, skb->len, 32, ipts->unit, lp->ppp_slot);
1da177e4
LT
1356
1357#ifdef CONFIG_ISDN_PPP_VJ
1358 if (proto == PPP_IP && ipts->pppcfg & SC_COMP_TCP) { /* ipts here? probably yes, but check this again */
1359 struct sk_buff *new_skb;
475be4d8 1360 unsigned short hl;
1da177e4 1361 /*
af901ca1 1362 * we need to reserve enough space in front of
1da177e4
LT
1363 * sk_buff. old call to dev_alloc_skb only reserved
1364 * 16 bytes, now we are looking what the driver want.
1365 */
1366 hl = dev->drv[lp->isdn_device]->interface->hl_hdrlen + IPPP_MAX_HEADER;
475be4d8 1367 /*
1da177e4
LT
1368 * Note: hl might still be insufficient because the method
1369 * above does not account for a possibible MPPP slave channel
1370 * which had larger HL header space requirements than the
1371 * master.
1372 */
475be4d8 1373 new_skb = alloc_skb(hl + skb->len, GFP_ATOMIC);
1da177e4
LT
1374 if (new_skb) {
1375 u_char *buf;
1376 int pktlen;
1377
1378 skb_reserve(new_skb, hl);
1379 new_skb->dev = skb->dev;
1380 skb_put(new_skb, skb->len);
1381 buf = skb->data;
1382
1383 pktlen = slhc_compress(ipts->slcomp, skb->data, skb->len, new_skb->data,
475be4d8 1384 &buf, !(ipts->pppcfg & SC_NO_TCP_CCID));
1da177e4 1385
475be4d8 1386 if (buf != skb->data) {
1da177e4
LT
1387 if (new_skb->data != buf)
1388 printk(KERN_ERR "isdn_ppp: FATAL error after slhc_compress!!\n");
1389 dev_kfree_skb(skb);
1390 skb = new_skb;
1391 } else {
1392 dev_kfree_skb(new_skb);
1393 }
1394
1395 skb_trim(skb, pktlen);
1396 if (skb->data[0] & SL_TYPE_COMPRESSED_TCP) { /* cslip? style -> PPP */
1397 proto = PPP_VJC_COMP;
1398 skb->data[0] ^= SL_TYPE_COMPRESSED_TCP;
1399 } else {
1400 if (skb->data[0] >= SL_TYPE_UNCOMPRESSED_TCP)
1401 proto = PPP_VJC_UNCOMP;
1402 skb->data[0] = (skb->data[0] & 0x0f) | 0x40;
1403 }
1404 }
1405 }
1406#endif
1407
1408 /*
1409 * normal (single link) or bundle compression
1410 */
475be4d8 1411 if (ipts->compflags & SC_COMP_ON) {
1da177e4
LT
1412 /* We send compressed only if both down- und upstream
1413 compression is negotiated, that means, CCP is up */
475be4d8
JP
1414 if (ipts->compflags & SC_DECOMP_ON) {
1415 skb = isdn_ppp_compress(skb, &proto, ipt, ipts, 0);
1da177e4
LT
1416 } else {
1417 printk(KERN_DEBUG "isdn_ppp: CCP not yet up - sending as-is\n");
1418 }
1419 }
1420
1421 if (ipt->debug & 0x24)
1422 printk(KERN_DEBUG "xmit2 skb, len %d, proto %04x\n", (int) skb->len, proto);
1423
1424#ifdef CONFIG_ISDN_MPP
1425 if (ipt->mpppcfg & SC_MP_PROT) {
1426 /* we get mp_seqno from static isdn_net_local */
1427 long mp_seqno = ipts->mp_seqno;
1428 ipts->mp_seqno++;
1429 if (ipt->mpppcfg & SC_OUT_SHORT_SEQ) {
1430 unsigned char *data = isdn_ppp_skb_push(&skb, 3);
475be4d8 1431 if (!data)
1da177e4
LT
1432 goto unlock;
1433 mp_seqno &= 0xfff;
1434 data[0] = MP_BEGIN_FRAG | MP_END_FRAG | ((mp_seqno >> 8) & 0xf); /* (B)egin & (E)ndbit .. */
1435 data[1] = mp_seqno & 0xff;
1436 data[2] = proto; /* PID compression */
1437 } else {
1438 unsigned char *data = isdn_ppp_skb_push(&skb, 5);
475be4d8 1439 if (!data)
1da177e4
LT
1440 goto unlock;
1441 data[0] = MP_BEGIN_FRAG | MP_END_FRAG; /* (B)egin & (E)ndbit .. */
1442 data[1] = (mp_seqno >> 16) & 0xff; /* sequence number: 24bit */
1443 data[2] = (mp_seqno >> 8) & 0xff;
1444 data[3] = (mp_seqno >> 0) & 0xff;
1445 data[4] = proto; /* PID compression */
1446 }
1447 proto = PPP_MP; /* MP Protocol, 0x003d */
1448 }
1449#endif
1450
1451 /*
1452 * 'link in bundle' compression ...
1453 */
475be4d8
JP
1454 if (ipt->compflags & SC_LINK_COMP_ON)
1455 skb = isdn_ppp_compress(skb, &proto, ipt, ipts, 1);
1da177e4 1456
475be4d8
JP
1457 if ((ipt->pppcfg & SC_COMP_PROT) && (proto <= 0xff)) {
1458 unsigned char *data = isdn_ppp_skb_push(&skb, 1);
1459 if (!data)
1da177e4
LT
1460 goto unlock;
1461 data[0] = proto & 0xff;
1462 }
1463 else {
475be4d8
JP
1464 unsigned char *data = isdn_ppp_skb_push(&skb, 2);
1465 if (!data)
1da177e4
LT
1466 goto unlock;
1467 data[0] = (proto >> 8) & 0xff;
1468 data[1] = proto & 0xff;
1469 }
475be4d8
JP
1470 if (!(ipt->pppcfg & SC_COMP_AC)) {
1471 unsigned char *data = isdn_ppp_skb_push(&skb, 2);
1472 if (!data)
1da177e4
LT
1473 goto unlock;
1474 data[0] = 0xff; /* All Stations */
1475 data[1] = 0x03; /* Unnumbered information */
1476 }
1477
1478 /* tx-stats are now updated via BSENT-callback */
1479
1480 if (ipts->debug & 0x40) {
1481 printk(KERN_DEBUG "skb xmit: len: %d\n", (int) skb->len);
475be4d8 1482 isdn_ppp_frame_log("xmit", skb->data, skb->len, 32, ipt->unit, lp->ppp_slot);
1da177e4 1483 }
475be4d8 1484
1da177e4
LT
1485 isdn_net_writebuf_skb(lp, skb);
1486
475be4d8 1487unlock:
1da177e4 1488 spin_unlock_bh(&lp->xmit_lock);
475be4d8 1489out:
1da177e4
LT
1490 return retval;
1491}
1492
1493#ifdef CONFIG_IPPP_FILTER
1494/*
1495 * check if this packet may trigger auto-dial.
1496 */
1497
1498int isdn_ppp_autodial_filter(struct sk_buff *skb, isdn_net_local *lp)
1499{
1500 struct ippp_struct *is = ippp_table[lp->ppp_slot];
1501 u_int16_t proto;
1502 int drop = 0;
1503
1504 switch (ntohs(skb->protocol)) {
1505 case ETH_P_IP:
1506 proto = PPP_IP;
1507 break;
1508 case ETH_P_IPX:
1509 proto = PPP_IPX;
1510 break;
1511 default:
1512 printk(KERN_ERR "isdn_ppp_autodial_filter: unsupported protocol 0x%x.\n",
1513 skb->protocol);
1514 return 1;
1515 }
1516
1517 /* the filter instructions are constructed assuming
1518 * a four-byte PPP header on each packet. we have to
1519 * temporarily remove part of the fake header stuck on
1520 * earlier.
1521 */
af72868b 1522 *(u8 *)skb_pull(skb, IPPP_MAX_HEADER - 4) = 1; /* indicate outbound */
1da177e4
LT
1523
1524 {
c19d0369 1525 __be16 *p = (__be16 *)skb->data;
1da177e4 1526
d8470b7c 1527 p++;
c19d0369 1528 *p = htons(proto);
1da177e4 1529 }
475be4d8 1530
1da177e4 1531 drop |= is->pass_filter
7ae457c1 1532 && BPF_PROG_RUN(is->pass_filter, skb) == 0;
1da177e4 1533 drop |= is->active_filter
7ae457c1 1534 && BPF_PROG_RUN(is->active_filter, skb) == 0;
475be4d8 1535
1da177e4
LT
1536 skb_push(skb, IPPP_MAX_HEADER - 4);
1537 return drop;
1538}
1539#endif
1540#ifdef CONFIG_ISDN_MPP
1541
1542/* this is _not_ rfc1990 header, but something we convert both short and long
1543 * headers to for convinience's sake:
475be4d8
JP
1544 * byte 0 is flags as in rfc1990
1545 * bytes 1...4 is 24-bit seqence number converted to host byte order
1da177e4
LT
1546 */
1547#define MP_HEADER_LEN 5
1548
1549#define MP_LONGSEQ_MASK 0x00ffffff
1550#define MP_SHORTSEQ_MASK 0x00000fff
1551#define MP_LONGSEQ_MAX MP_LONGSEQ_MASK
1552#define MP_SHORTSEQ_MAX MP_SHORTSEQ_MASK
475be4d8
JP
1553#define MP_LONGSEQ_MAXBIT ((MP_LONGSEQ_MASK + 1) >> 1)
1554#define MP_SHORTSEQ_MAXBIT ((MP_SHORTSEQ_MASK + 1) >> 1)
1da177e4 1555
25985edc 1556/* sequence-wrap safe comparisons (for long sequence)*/
475be4d8
JP
1557#define MP_LT(a, b) ((a - b) & MP_LONGSEQ_MAXBIT)
1558#define MP_LE(a, b) !((b - a) & MP_LONGSEQ_MAXBIT)
1559#define MP_GT(a, b) ((b - a) & MP_LONGSEQ_MAXBIT)
1560#define MP_GE(a, b) !((a - b) & MP_LONGSEQ_MAXBIT)
1da177e4 1561
475be4d8 1562#define MP_SEQ(f) ((*(u32 *)(f->data + 1)))
1da177e4
LT
1563#define MP_FLAGS(f) (f->data[0])
1564
1565static int isdn_ppp_mp_bundle_array_init(void)
1566{
1567 int i;
475be4d8
JP
1568 int sz = ISDN_MAX_CHANNELS * sizeof(ippp_bundle);
1569 if ((isdn_ppp_bundle_arr = kzalloc(sz, GFP_KERNEL)) == NULL)
1da177e4 1570 return -ENOMEM;
475be4d8 1571 for (i = 0; i < ISDN_MAX_CHANNELS; i++)
1da177e4
LT
1572 spin_lock_init(&isdn_ppp_bundle_arr[i].lock);
1573 return 0;
1574}
1575
475be4d8 1576static ippp_bundle *isdn_ppp_mp_bundle_alloc(void)
1da177e4
LT
1577{
1578 int i;
475be4d8 1579 for (i = 0; i < ISDN_MAX_CHANNELS; i++)
1da177e4
LT
1580 if (isdn_ppp_bundle_arr[i].ref_ct <= 0)
1581 return (isdn_ppp_bundle_arr + i);
1582 return NULL;
1583}
1584
475be4d8 1585static int isdn_ppp_mp_init(isdn_net_local *lp, ippp_bundle *add_to)
1da177e4 1586{
475be4d8 1587 struct ippp_struct *is;
1da177e4
LT
1588
1589 if (lp->ppp_slot < 0) {
1590 printk(KERN_ERR "%s: lp->ppp_slot(%d) out of range\n",
475be4d8
JP
1591 __func__, lp->ppp_slot);
1592 return (-EINVAL);
1da177e4
LT
1593 }
1594
1595 is = ippp_table[lp->ppp_slot];
1596 if (add_to) {
475be4d8 1597 if (lp->netdev->pb)
1da177e4
LT
1598 lp->netdev->pb->ref_ct--;
1599 lp->netdev->pb = add_to;
1600 } else { /* first link in a bundle */
1601 is->mp_seqno = 0;
1602 if ((lp->netdev->pb = isdn_ppp_mp_bundle_alloc()) == NULL)
1603 return -ENOMEM;
1604 lp->next = lp->last = lp; /* nobody else in a queue */
e29d4363 1605 lp->netdev->pb->frags = NULL;
1da177e4
LT
1606 lp->netdev->pb->frames = 0;
1607 lp->netdev->pb->seq = UINT_MAX;
1608 }
1609 lp->netdev->pb->ref_ct++;
475be4d8 1610
1da177e4
LT
1611 is->last_link_seqno = 0;
1612 return 0;
1613}
1614
475be4d8
JP
1615static u32 isdn_ppp_mp_get_seq(int short_seq,
1616 struct sk_buff *skb, u32 last_seq);
1617static struct sk_buff *isdn_ppp_mp_discard(ippp_bundle *mp,
1618 struct sk_buff *from, struct sk_buff *to);
1619static void isdn_ppp_mp_reassembly(isdn_net_dev *net_dev, isdn_net_local *lp,
1620 struct sk_buff *from, struct sk_buff *to);
1621static void isdn_ppp_mp_free_skb(ippp_bundle *mp, struct sk_buff *skb);
1622static void isdn_ppp_mp_print_recv_pkt(int slot, struct sk_buff *skb);
1623
1624static void isdn_ppp_mp_receive(isdn_net_dev *net_dev, isdn_net_local *lp,
1625 struct sk_buff *skb)
1da177e4 1626{
38783e67 1627 struct ippp_struct *is;
475be4d8
JP
1628 isdn_net_local *lpq;
1629 ippp_bundle *mp;
1630 isdn_mppp_stats *stats;
1631 struct sk_buff *newfrag, *frag, *start, *nextf;
e29d4363 1632 u32 newseq, minseq, thisseq;
1da177e4
LT
1633 unsigned long flags;
1634 int slot;
1635
1636 spin_lock_irqsave(&net_dev->pb->lock, flags);
475be4d8
JP
1637 mp = net_dev->pb;
1638 stats = &mp->stats;
1da177e4 1639 slot = lp->ppp_slot;
052bb88e 1640 if (slot < 0 || slot >= ISDN_MAX_CHANNELS) {
1da177e4 1641 printk(KERN_ERR "%s: lp->ppp_slot(%d)\n",
475be4d8 1642 __func__, lp->ppp_slot);
1da177e4
LT
1643 stats->frame_drops++;
1644 dev_kfree_skb(skb);
1645 spin_unlock_irqrestore(&mp->lock, flags);
1646 return;
1647 }
1648 is = ippp_table[slot];
475be4d8 1649 if (++mp->frames > stats->max_queue_len)
1da177e4 1650 stats->max_queue_len = mp->frames;
475be4d8 1651
1da177e4
LT
1652 if (is->debug & 0x8)
1653 isdn_ppp_mp_print_recv_pkt(lp->ppp_slot, skb);
1654
475be4d8
JP
1655 newseq = isdn_ppp_mp_get_seq(is->mpppcfg & SC_IN_SHORT_SEQ,
1656 skb, is->last_link_seqno);
e29d4363 1657
1da177e4
LT
1658
1659 /* if this packet seq # is less than last already processed one,
475be4d8 1660 * toss it right away, but check for sequence start case first
1da177e4 1661 */
475be4d8 1662 if (mp->seq > MP_LONGSEQ_MAX && (newseq & MP_LONGSEQ_MAXBIT)) {
1da177e4
LT
1663 mp->seq = newseq; /* the first packet: required for
1664 * rfc1990 non-compliant clients --
1665 * prevents constant packet toss */
475be4d8 1666 } else if (MP_LT(newseq, mp->seq)) {
1da177e4
LT
1667 stats->frame_drops++;
1668 isdn_ppp_mp_free_skb(mp, skb);
1669 spin_unlock_irqrestore(&mp->lock, flags);
1670 return;
1671 }
475be4d8 1672
1da177e4
LT
1673 /* find the minimum received sequence number over all links */
1674 is->last_link_seqno = minseq = newseq;
1675 for (lpq = net_dev->queue;;) {
1676 slot = lpq->ppp_slot;
052bb88e 1677 if (slot < 0 || slot >= ISDN_MAX_CHANNELS) {
1da177e4 1678 printk(KERN_ERR "%s: lpq->ppp_slot(%d)\n",
475be4d8 1679 __func__, lpq->ppp_slot);
1da177e4
LT
1680 } else {
1681 u32 lls = ippp_table[slot]->last_link_seqno;
1682 if (MP_LT(lls, minseq))
1683 minseq = lls;
1684 }
1685 if ((lpq = lpq->next) == net_dev->queue)
1686 break;
1687 }
1688 if (MP_LT(minseq, mp->seq))
1689 minseq = mp->seq; /* can't go beyond already processed
1690 * packets */
1691 newfrag = skb;
1692
475be4d8
JP
1693 /* if this new fragment is before the first one, then enqueue it now. */
1694 if ((frag = mp->frags) == NULL || MP_LT(newseq, MP_SEQ(frag))) {
e29d4363 1695 newfrag->next = frag;
475be4d8
JP
1696 mp->frags = frag = newfrag;
1697 newfrag = NULL;
1698 }
1da177e4 1699
475be4d8
JP
1700 start = MP_FLAGS(frag) & MP_BEGIN_FRAG &&
1701 MP_SEQ(frag) == mp->seq ? frag : NULL;
1da177e4 1702
475be4d8 1703 /*
e29d4363 1704 * main fragment traversing loop
1da177e4
LT
1705 *
1706 * try to accomplish several tasks:
e29d4363
DM
1707 * - insert new fragment into the proper sequence slot (once that's done
1708 * newfrag will be set to NULL)
1da177e4 1709 * - reassemble any complete fragment sequence (non-null 'start'
af901ca1 1710 * indicates there is a contiguous sequence present)
1da177e4
LT
1711 * - discard any incomplete sequences that are below minseq -- due
1712 * to the fact that sender always increment sequence number, if there
1713 * is an incomplete sequence below minseq, no new fragments would
1714 * come to complete such sequence and it should be discarded
1715 *
1716 * loop completes when we accomplished the following tasks:
475be4d8 1717 * - new fragment is inserted in the proper sequence ('newfrag' is
e29d4363 1718 * set to NULL)
475be4d8 1719 * - we hit a gap in the sequence, so no reassembly/processing is
1da177e4
LT
1720 * possible ('start' would be set to NULL)
1721 *
d08df601 1722 * algorithm for this code is derived from code in the book
1da177e4
LT
1723 * 'PPP Design And Debugging' by James Carlson (Addison-Wesley)
1724 */
475be4d8
JP
1725 while (start != NULL || newfrag != NULL) {
1726
1727 thisseq = MP_SEQ(frag);
1728 nextf = frag->next;
1729
1730 /* drop any duplicate fragments */
1731 if (newfrag != NULL && thisseq == newseq) {
1732 isdn_ppp_mp_free_skb(mp, newfrag);
1733 newfrag = NULL;
1734 }
1735
1736 /* insert new fragment before next element if possible. */
1737 if (newfrag != NULL && (nextf == NULL ||
1738 MP_LT(newseq, MP_SEQ(nextf)))) {
1739 newfrag->next = nextf;
1740 frag->next = nextf = newfrag;
1741 newfrag = NULL;
1742 }
1743
1744 if (start != NULL) {
1745 /* check for misplaced start */
1746 if (start != frag && (MP_FLAGS(frag) & MP_BEGIN_FRAG)) {
e29d4363 1747 printk(KERN_WARNING"isdn_mppp(seq %d): new "
475be4d8 1748 "BEGIN flag with no prior END", thisseq);
e29d4363
DM
1749 stats->seqerrs++;
1750 stats->frame_drops++;
475be4d8 1751 start = isdn_ppp_mp_discard(mp, start, frag);
e29d4363 1752 nextf = frag->next;
475be4d8
JP
1753 }
1754 } else if (MP_LE(thisseq, minseq)) {
1755 if (MP_FLAGS(frag) & MP_BEGIN_FRAG)
1da177e4 1756 start = frag;
475be4d8 1757 else {
1da177e4 1758 if (MP_FLAGS(frag) & MP_END_FRAG)
475be4d8
JP
1759 stats->frame_drops++;
1760 if (mp->frags == frag)
1761 mp->frags = nextf;
1da177e4 1762 isdn_ppp_mp_free_skb(mp, frag);
e29d4363 1763 frag = nextf;
1da177e4 1764 continue;
475be4d8 1765 }
1da177e4 1766 }
475be4d8 1767
e29d4363 1768 /* if start is non-null and we have end fragment, then
475be4d8 1769 * we have full reassembly sequence -- reassemble
e29d4363 1770 * and process packet now
1da177e4 1771 */
475be4d8
JP
1772 if (start != NULL && (MP_FLAGS(frag) & MP_END_FRAG)) {
1773 minseq = mp->seq = (thisseq + 1) & MP_LONGSEQ_MASK;
1774 /* Reassemble the packet then dispatch it */
e29d4363 1775 isdn_ppp_mp_reassembly(net_dev, lp, start, nextf);
1da177e4 1776
475be4d8
JP
1777 start = NULL;
1778 frag = NULL;
1779
1780 mp->frags = nextf;
1781 }
1da177e4
LT
1782
1783 /* check if need to update start pointer: if we just
1784 * reassembled the packet and sequence is contiguous
1785 * then next fragment should be the start of new reassembly
1786 * if sequence is contiguous, but we haven't reassembled yet,
1787 * keep going.
25985edc 1788 * if sequence is not contiguous, either clear everything
1da177e4
LT
1789 * below low watermark and set start to the next frag or
1790 * clear start ptr.
475be4d8
JP
1791 */
1792 if (nextf != NULL &&
1793 ((thisseq + 1) & MP_LONGSEQ_MASK) == MP_SEQ(nextf)) {
1794 /* if we just reassembled and the next one is here,
e29d4363
DM
1795 * then start another reassembly. */
1796
475be4d8 1797 if (frag == NULL) {
1da177e4 1798 if (MP_FLAGS(nextf) & MP_BEGIN_FRAG)
475be4d8 1799 start = nextf;
e29d4363
DM
1800 else
1801 {
475be4d8
JP
1802 printk(KERN_WARNING"isdn_mppp(seq %d):"
1803 " END flag with no following "
1804 "BEGIN", thisseq);
1da177e4
LT
1805 stats->seqerrs++;
1806 }
1807 }
e29d4363 1808
475be4d8
JP
1809 } else {
1810 if (nextf != NULL && frag != NULL &&
1811 MP_LT(thisseq, minseq)) {
1da177e4
LT
1812 /* we've got a break in the sequence
1813 * and we not at the end yet
1814 * and we did not just reassembled
1815 *(if we did, there wouldn't be anything before)
475be4d8
JP
1816 * and we below the low watermark
1817 * discard all the frames below low watermark
1da177e4
LT
1818 * and start over */
1819 stats->frame_drops++;
475be4d8 1820 mp->frags = isdn_ppp_mp_discard(mp, start, nextf);
1da177e4
LT
1821 }
1822 /* break in the sequence, no reassembly */
475be4d8
JP
1823 start = NULL;
1824 }
1825
1826 frag = nextf;
1827 } /* while -- main loop */
1828
1829 if (mp->frags == NULL)
1830 mp->frags = frag;
1831
1832 /* rather straighforward way to deal with (not very) possible
e29d4363 1833 * queue overflow */
1da177e4
LT
1834 if (mp->frames > MP_MAX_QUEUE_LEN) {
1835 stats->overflows++;
e29d4363
DM
1836 while (mp->frames > MP_MAX_QUEUE_LEN) {
1837 frag = mp->frags->next;
1838 isdn_ppp_mp_free_skb(mp, mp->frags);
1839 mp->frags = frag;
1da177e4
LT
1840 }
1841 }
1842 spin_unlock_irqrestore(&mp->lock, flags);
1843}
1844
475be4d8 1845static void isdn_ppp_mp_cleanup(isdn_net_local *lp)
1da177e4 1846{
475be4d8
JP
1847 struct sk_buff *frag = lp->netdev->pb->frags;
1848 struct sk_buff *nextfrag;
1849 while (frag) {
e29d4363
DM
1850 nextfrag = frag->next;
1851 isdn_ppp_mp_free_skb(lp->netdev->pb, frag);
1852 frag = nextfrag;
1853 }
1854 lp->netdev->pb->frags = NULL;
1da177e4
LT
1855}
1856
475be4d8
JP
1857static u32 isdn_ppp_mp_get_seq(int short_seq,
1858 struct sk_buff *skb, u32 last_seq)
1da177e4
LT
1859{
1860 u32 seq;
1861 int flags = skb->data[0] & (MP_BEGIN_FRAG | MP_END_FRAG);
475be4d8
JP
1862
1863 if (!short_seq)
1da177e4 1864 {
c19d0369 1865 seq = ntohl(*(__be32 *)skb->data) & MP_LONGSEQ_MASK;
475be4d8 1866 skb_push(skb, 1);
1da177e4
LT
1867 }
1868 else
1869 {
475be4d8
JP
1870 /* convert 12-bit short seq number to 24-bit long one
1871 */
c19d0369 1872 seq = ntohs(*(__be16 *)skb->data) & MP_SHORTSEQ_MASK;
475be4d8 1873
1da177e4 1874 /* check for seqence wrap */
475be4d8
JP
1875 if (!(seq & MP_SHORTSEQ_MAXBIT) &&
1876 (last_seq & MP_SHORTSEQ_MAXBIT) &&
1877 (unsigned long)last_seq <= MP_LONGSEQ_MAX)
1878 seq |= (last_seq + MP_SHORTSEQ_MAX + 1) &
1879 (~MP_SHORTSEQ_MASK & MP_LONGSEQ_MASK);
1da177e4
LT
1880 else
1881 seq |= last_seq & (~MP_SHORTSEQ_MASK & MP_LONGSEQ_MASK);
475be4d8 1882
1da177e4
LT
1883 skb_push(skb, 3); /* put converted seqence back in skb */
1884 }
475be4d8 1885 *(u32 *)(skb->data + 1) = seq; /* put seqence back in _host_ byte
1da177e4
LT
1886 * order */
1887 skb->data[0] = flags; /* restore flags */
1888 return seq;
1889}
1890
475be4d8
JP
1891struct sk_buff *isdn_ppp_mp_discard(ippp_bundle *mp,
1892 struct sk_buff *from, struct sk_buff *to)
1da177e4 1893{
475be4d8 1894 if (from)
e29d4363 1895 while (from != to) {
475be4d8 1896 struct sk_buff *next = from->next;
e29d4363 1897 isdn_ppp_mp_free_skb(mp, from);
475be4d8 1898 from = next;
1da177e4 1899 }
e29d4363 1900 return from;
38783e67
DM
1901}
1902
475be4d8
JP
1903void isdn_ppp_mp_reassembly(isdn_net_dev *net_dev, isdn_net_local *lp,
1904 struct sk_buff *from, struct sk_buff *to)
38783e67 1905{
475be4d8 1906 ippp_bundle *mp = net_dev->pb;
38783e67 1907 int proto;
475be4d8 1908 struct sk_buff *skb;
e29d4363 1909 unsigned int tot_len;
1da177e4
LT
1910
1911 if (lp->ppp_slot < 0 || lp->ppp_slot >= ISDN_MAX_CHANNELS) {
1912 printk(KERN_ERR "%s: lp->ppp_slot(%d) out of range\n",
475be4d8 1913 __func__, lp->ppp_slot);
1da177e4
LT
1914 return;
1915 }
475be4d8
JP
1916 if (MP_FLAGS(from) == (MP_BEGIN_FRAG | MP_END_FRAG)) {
1917 if (ippp_table[lp->ppp_slot]->debug & 0x40)
1da177e4 1918 printk(KERN_DEBUG "isdn_mppp: reassembly: frame %d, "
475be4d8 1919 "len %d\n", MP_SEQ(from), from->len);
1da177e4
LT
1920 skb = from;
1921 skb_pull(skb, MP_HEADER_LEN);
475be4d8 1922 mp->frames--;
1da177e4 1923 } else {
475be4d8 1924 struct sk_buff *frag;
e29d4363 1925 int n;
1da177e4 1926
475be4d8 1927 for (tot_len = n = 0, frag = from; frag != to; frag = frag->next, n++)
e29d4363 1928 tot_len += frag->len - MP_HEADER_LEN;
38783e67 1929
475be4d8 1930 if (ippp_table[lp->ppp_slot]->debug & 0x40)
e29d4363 1931 printk(KERN_DEBUG"isdn_mppp: reassembling frames %d "
475be4d8
JP
1932 "to %d, len %d\n", MP_SEQ(from),
1933 (MP_SEQ(from) + n - 1) & MP_LONGSEQ_MASK, tot_len);
1934 if ((skb = dev_alloc_skb(tot_len)) == NULL) {
1da177e4 1935 printk(KERN_ERR "isdn_mppp: cannot allocate sk buff "
475be4d8 1936 "of size %d\n", tot_len);
e29d4363
DM
1937 isdn_ppp_mp_discard(mp, from, to);
1938 return;
1939 }
1da177e4 1940
475be4d8 1941 while (from != to) {
e29d4363 1942 unsigned int len = from->len - MP_HEADER_LEN;
1da177e4 1943
e29d4363 1944 skb_copy_from_linear_data_offset(from, MP_HEADER_LEN,
475be4d8 1945 skb_put(skb, len),
e29d4363
DM
1946 len);
1947 frag = from->next;
1948 isdn_ppp_mp_free_skb(mp, from);
475be4d8 1949 from = frag;
1da177e4
LT
1950 }
1951 }
475be4d8 1952 proto = isdn_ppp_strip_proto(skb);
1da177e4
LT
1953 isdn_ppp_push_higher(net_dev, lp, skb, proto);
1954}
1955
475be4d8 1956static void isdn_ppp_mp_free_skb(ippp_bundle *mp, struct sk_buff *skb)
1da177e4
LT
1957{
1958 dev_kfree_skb(skb);
1959 mp->frames--;
1960}
1961
475be4d8 1962static void isdn_ppp_mp_print_recv_pkt(int slot, struct sk_buff *skb)
1da177e4 1963{
475be4d8
JP
1964 printk(KERN_DEBUG "mp_recv: %d/%d -> %02x %02x %02x %02x %02x %02x\n",
1965 slot, (int) skb->len,
1966 (int) skb->data[0], (int) skb->data[1], (int) skb->data[2],
1967 (int) skb->data[3], (int) skb->data[4], (int) skb->data[5]);
1da177e4
LT
1968}
1969
1970static int
1971isdn_ppp_bundle(struct ippp_struct *is, int unit)
1972{
1973 char ifn[IFNAMSIZ + 1];
1974 isdn_net_dev *p;
1975 isdn_net_local *lp, *nlp;
1976 int rc;
1977 unsigned long flags;
1978
1979 sprintf(ifn, "ippp%d", unit);
1980 p = isdn_net_findif(ifn);
1981 if (!p) {
1982 printk(KERN_ERR "ippp_bundle: cannot find %s\n", ifn);
1983 return -EINVAL;
1984 }
1985
475be4d8 1986 spin_lock_irqsave(&p->pb->lock, flags);
1da177e4
LT
1987
1988 nlp = is->lp;
1989 lp = p->queue;
475be4d8
JP
1990 if (nlp->ppp_slot < 0 || nlp->ppp_slot >= ISDN_MAX_CHANNELS ||
1991 lp->ppp_slot < 0 || lp->ppp_slot >= ISDN_MAX_CHANNELS) {
1da177e4 1992 printk(KERN_ERR "ippp_bundle: binding to invalid slot %d\n",
475be4d8
JP
1993 nlp->ppp_slot < 0 || nlp->ppp_slot >= ISDN_MAX_CHANNELS ?
1994 nlp->ppp_slot : lp->ppp_slot);
1da177e4
LT
1995 rc = -EINVAL;
1996 goto out;
475be4d8 1997 }
1da177e4
LT
1998
1999 isdn_net_add_to_bundle(p, nlp);
2000
2001 ippp_table[nlp->ppp_slot]->unit = ippp_table[lp->ppp_slot]->unit;
2002
2003 /* maybe also SC_CCP stuff */
2004 ippp_table[nlp->ppp_slot]->pppcfg |= ippp_table[lp->ppp_slot]->pppcfg &
2005 (SC_ENABLE_IP | SC_NO_TCP_CCID | SC_REJ_COMP_TCP);
2006 ippp_table[nlp->ppp_slot]->mpppcfg |= ippp_table[lp->ppp_slot]->mpppcfg &
2007 (SC_MP_PROT | SC_REJ_MP_PROT | SC_OUT_SHORT_SEQ | SC_IN_SHORT_SEQ);
2008 rc = isdn_ppp_mp_init(nlp, p->pb);
2009out:
2010 spin_unlock_irqrestore(&p->pb->lock, flags);
2011 return rc;
2012}
475be4d8 2013
1da177e4 2014#endif /* CONFIG_ISDN_MPP */
475be4d8 2015
1da177e4
LT
2016/*
2017 * network device ioctl handlers
2018 */
2019
2020static int
2021isdn_ppp_dev_ioctl_stats(int slot, struct ifreq *ifr, struct net_device *dev)
2022{
2023 struct ppp_stats __user *res = ifr->ifr_data;
2024 struct ppp_stats t;
a17531fa 2025 isdn_net_local *lp = netdev_priv(dev);
1da177e4 2026
1da177e4
LT
2027 /* build a temporary stat struct and copy it to user space */
2028
2029 memset(&t, 0, sizeof(struct ppp_stats));
2030 if (dev->flags & IFF_UP) {
2031 t.p.ppp_ipackets = lp->stats.rx_packets;
2032 t.p.ppp_ibytes = lp->stats.rx_bytes;
2033 t.p.ppp_ierrors = lp->stats.rx_errors;
2034 t.p.ppp_opackets = lp->stats.tx_packets;
2035 t.p.ppp_obytes = lp->stats.tx_bytes;
2036 t.p.ppp_oerrors = lp->stats.tx_errors;
2037#ifdef CONFIG_ISDN_PPP_VJ
2038 if (slot >= 0 && ippp_table[slot]->slcomp) {
2039 struct slcompress *slcomp = ippp_table[slot]->slcomp;
2040 t.vj.vjs_packets = slcomp->sls_o_compressed + slcomp->sls_o_uncompressed;
2041 t.vj.vjs_compressed = slcomp->sls_o_compressed;
2042 t.vj.vjs_searches = slcomp->sls_o_searches;
2043 t.vj.vjs_misses = slcomp->sls_o_misses;
2044 t.vj.vjs_errorin = slcomp->sls_i_error;
2045 t.vj.vjs_tossed = slcomp->sls_i_tossed;
2046 t.vj.vjs_uncompressedin = slcomp->sls_i_uncompressed;
2047 t.vj.vjs_compressedin = slcomp->sls_i_compressed;
2048 }
2049#endif
2050 }
2051 if (copy_to_user(res, &t, sizeof(struct ppp_stats)))
2052 return -EFAULT;
2053 return 0;
2054}
2055
2056int
2057isdn_ppp_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
2058{
475be4d8 2059 int error = 0;
1da177e4 2060 int len;
a17531fa 2061 isdn_net_local *lp = netdev_priv(dev);
1da177e4
LT
2062
2063
2064 if (lp->p_encap != ISDN_NET_ENCAP_SYNCPPP)
2065 return -EINVAL;
2066
2067 switch (cmd) {
2068#define PPP_VERSION "2.3.7"
475be4d8
JP
2069 case SIOCGPPPVER:
2070 len = strlen(PPP_VERSION) + 1;
2071 if (copy_to_user(ifr->ifr_data, PPP_VERSION, len))
2072 error = -EFAULT;
2073 break;
1da177e4 2074
475be4d8
JP
2075 case SIOCGPPPSTATS:
2076 error = isdn_ppp_dev_ioctl_stats(lp->ppp_slot, ifr, dev);
2077 break;
2078 default:
2079 error = -EINVAL;
2080 break;
1da177e4
LT
2081 }
2082 return error;
2083}
2084
2085static int
2086isdn_ppp_if_get_unit(char *name)
2087{
2088 int len,
475be4d8
JP
2089 i,
2090 unit = 0,
2091 deci;
1da177e4
LT
2092
2093 len = strlen(name);
2094
2095 if (strncmp("ippp", name, 4) || len > 8)
2096 return -1;
2097
2098 for (i = 0, deci = 1; i < len; i++, deci *= 10) {
2099 char a = name[len - i - 1];
2100 if (a >= '0' && a <= '9')
2101 unit += (a - '0') * deci;
2102 else
2103 break;
2104 }
2105 if (!i || len - i != 4)
2106 unit = -1;
2107
2108 return unit;
2109}
2110
2111
2112int
2113isdn_ppp_dial_slave(char *name)
2114{
2115#ifdef CONFIG_ISDN_MPP
2116 isdn_net_dev *ndev;
2117 isdn_net_local *lp;
2118 struct net_device *sdev;
2119
2120 if (!(ndev = isdn_net_findif(name)))
2121 return 1;
2122 lp = ndev->local;
2123 if (!(lp->flags & ISDN_NET_CONNECTED))
2124 return 5;
2125
2126 sdev = lp->slave;
2127 while (sdev) {
a17531fa 2128 isdn_net_local *mlp = netdev_priv(sdev);
1da177e4
LT
2129 if (!(mlp->flags & ISDN_NET_CONNECTED))
2130 break;
2131 sdev = mlp->slave;
2132 }
2133 if (!sdev)
2134 return 2;
2135
a17531fa 2136 isdn_net_dial_req(netdev_priv(sdev));
1da177e4
LT
2137 return 0;
2138#else
2139 return -1;
2140#endif
2141}
2142
2143int
2144isdn_ppp_hangup_slave(char *name)
2145{
2146#ifdef CONFIG_ISDN_MPP
2147 isdn_net_dev *ndev;
2148 isdn_net_local *lp;
2149 struct net_device *sdev;
2150
2151 if (!(ndev = isdn_net_findif(name)))
2152 return 1;
2153 lp = ndev->local;
2154 if (!(lp->flags & ISDN_NET_CONNECTED))
2155 return 5;
2156
2157 sdev = lp->slave;
2158 while (sdev) {
a17531fa 2159 isdn_net_local *mlp = netdev_priv(sdev);
1da177e4
LT
2160
2161 if (mlp->slave) { /* find last connected link in chain */
838361fe 2162 isdn_net_local *nlp = ISDN_SLAVE_PRIV(mlp);
1da177e4
LT
2163
2164 if (!(nlp->flags & ISDN_NET_CONNECTED))
2165 break;
2166 } else if (mlp->flags & ISDN_NET_CONNECTED)
2167 break;
475be4d8 2168
1da177e4
LT
2169 sdev = mlp->slave;
2170 }
2171 if (!sdev)
2172 return 2;
2173
2174 isdn_net_hangup(sdev);
2175 return 0;
2176#else
2177 return -1;
2178#endif
2179}
2180
2181/*
2182 * PPP compression stuff
2183 */
2184
2185
2186/* Push an empty CCP Data Frame up to the daemon to wake it up and let it
2187 generate a CCP Reset-Request or tear down CCP altogether */
2188
2189static void isdn_ppp_ccp_kickup(struct ippp_struct *is)
2190{
2191 isdn_ppp_fill_rq(NULL, 0, PPP_COMP, is->lp->ppp_slot);
2192}
2193
2194/* In-kernel handling of CCP Reset-Request and Reset-Ack is necessary,
2195 but absolutely nontrivial. The most abstruse problem we are facing is
2196 that the generation, reception and all the handling of timeouts and
2197 resends including proper request id management should be entirely left
2198 to the (de)compressor, but indeed is not covered by the current API to
2199 the (de)compressor. The API is a prototype version from PPP where only
2200 some (de)compressors have yet been implemented and all of them are
2201 rather simple in their reset handling. Especially, their is only one
2202 outstanding ResetAck at a time with all of them and ResetReq/-Acks do
2203 not have parameters. For this very special case it was sufficient to
2204 just return an error code from the decompressor and have a single
2205 reset() entry to communicate all the necessary information between
2206 the framework and the (de)compressor. Bad enough, LZS is different
2207 (and any other compressor may be different, too). It has multiple
2208 histories (eventually) and needs to Reset each of them independently
2209 and thus uses multiple outstanding Acks and history numbers as an
2210 additional parameter to Reqs/Acks.
2211 All that makes it harder to port the reset state engine into the
2212 kernel because it is not just the same simple one as in (i)pppd but
2213 it must be able to pass additional parameters and have multiple out-
2214 standing Acks. We are trying to achieve the impossible by handling
2215 reset transactions independent by their id. The id MUST change when
2216 the data portion changes, thus any (de)compressor who uses more than
2217 one resettable state must provide and recognize individual ids for
2218 each individual reset transaction. The framework itself does _only_
2219 differentiate them by id, because it has no other semantics like the
2220 (de)compressor might.
2221 This looks like a major redesign of the interface would be nice,
2222 but I don't have an idea how to do it better. */
2223
2224/* Send a CCP Reset-Request or Reset-Ack directly from the kernel. This is
2225 getting that lengthy because there is no simple "send-this-frame-out"
2226 function above but every wrapper does a bit different. Hope I guess
2227 correct in this hack... */
2228
2229static void isdn_ppp_ccp_xmit_reset(struct ippp_struct *is, int proto,
2230 unsigned char code, unsigned char id,
2231 unsigned char *data, int len)
2232{
2233 struct sk_buff *skb;
2234 unsigned char *p;
2235 int hl;
2236 int cnt = 0;
2237 isdn_net_local *lp = is->lp;
2238
2239 /* Alloc large enough skb */
2240 hl = dev->drv[lp->isdn_device]->interface->hl_hdrlen;
475be4d8
JP
2241 skb = alloc_skb(len + hl + 16, GFP_ATOMIC);
2242 if (!skb) {
1da177e4
LT
2243 printk(KERN_WARNING
2244 "ippp: CCP cannot send reset - out of memory\n");
2245 return;
2246 }
2247 skb_reserve(skb, hl);
2248
2249 /* We may need to stuff an address and control field first */
475be4d8 2250 if (!(is->pppcfg & SC_COMP_AC)) {
1da177e4
LT
2251 p = skb_put(skb, 2);
2252 *p++ = 0xff;
2253 *p++ = 0x03;
2254 }
2255
2256 /* Stuff proto, code, id and length */
2257 p = skb_put(skb, 6);
2258 *p++ = (proto >> 8);
2259 *p++ = (proto & 0xff);
2260 *p++ = code;
2261 *p++ = id;
2262 cnt = 4 + len;
2263 *p++ = (cnt >> 8);
2264 *p++ = (cnt & 0xff);
2265
2266 /* Now stuff remaining bytes */
475be4d8 2267 if (len) {
b952f4df 2268 skb_put_data(skb, data, len);
1da177e4
LT
2269 }
2270
2271 /* skb is now ready for xmit */
2272 printk(KERN_DEBUG "Sending CCP Frame:\n");
475be4d8 2273 isdn_ppp_frame_log("ccp-xmit", skb->data, skb->len, 32, is->unit, lp->ppp_slot);
1da177e4
LT
2274
2275 isdn_net_write_super(lp, skb);
2276}
2277
2278/* Allocate the reset state vector */
2279static struct ippp_ccp_reset *isdn_ppp_ccp_reset_alloc(struct ippp_struct *is)
2280{
2281 struct ippp_ccp_reset *r;
41f96935 2282 r = kzalloc(sizeof(struct ippp_ccp_reset), GFP_KERNEL);
475be4d8 2283 if (!r) {
1da177e4
LT
2284 printk(KERN_ERR "ippp_ccp: failed to allocate reset data"
2285 " structure - no mem\n");
2286 return NULL;
2287 }
1da177e4
LT
2288 printk(KERN_DEBUG "ippp_ccp: allocated reset data structure %p\n", r);
2289 is->reset = r;
2290 return r;
2291}
2292
2293/* Destroy the reset state vector. Kill all pending timers first. */
2294static void isdn_ppp_ccp_reset_free(struct ippp_struct *is)
2295{
2296 unsigned int id;
2297
2298 printk(KERN_DEBUG "ippp_ccp: freeing reset data structure %p\n",
2299 is->reset);
475be4d8
JP
2300 for (id = 0; id < 256; id++) {
2301 if (is->reset->rs[id]) {
1da177e4
LT
2302 isdn_ppp_ccp_reset_free_state(is, (unsigned char)id);
2303 }
2304 }
2305 kfree(is->reset);
2306 is->reset = NULL;
2307}
2308
2309/* Free a given state and clear everything up for later reallocation */
2310static void isdn_ppp_ccp_reset_free_state(struct ippp_struct *is,
2311 unsigned char id)
2312{
2313 struct ippp_ccp_reset_state *rs;
2314
475be4d8 2315 if (is->reset->rs[id]) {
1da177e4
LT
2316 printk(KERN_DEBUG "ippp_ccp: freeing state for id %d\n", id);
2317 rs = is->reset->rs[id];
2318 /* Make sure the kernel will not call back later */
475be4d8 2319 if (rs->ta)
1da177e4
LT
2320 del_timer(&rs->timer);
2321 is->reset->rs[id] = NULL;
2322 kfree(rs);
2323 } else {
2324 printk(KERN_WARNING "ippp_ccp: id %d is not allocated\n", id);
2325 }
2326}
2327
2328/* The timer callback function which is called when a ResetReq has timed out,
2329 aka has never been answered by a ResetAck */
2330static void isdn_ppp_ccp_timer_callback(unsigned long closure)
2331{
2332 struct ippp_ccp_reset_state *rs =
2333 (struct ippp_ccp_reset_state *)closure;
2334
475be4d8 2335 if (!rs) {
1da177e4
LT
2336 printk(KERN_ERR "ippp_ccp: timer cb with zero closure.\n");
2337 return;
2338 }
475be4d8 2339 if (rs->ta && rs->state == CCPResetSentReq) {
1da177e4 2340 /* We are correct here */
475be4d8 2341 if (!rs->expra) {
1da177e4
LT
2342 /* Hmm, there is no Ack really expected. We can clean
2343 up the state now, it will be reallocated if the
2344 decompressor insists on another reset */
2345 rs->ta = 0;
2346 isdn_ppp_ccp_reset_free_state(rs->is, rs->id);
2347 return;
2348 }
2349 printk(KERN_DEBUG "ippp_ccp: CCP Reset timed out for id %d\n",
2350 rs->id);
2351 /* Push it again */
2352 isdn_ppp_ccp_xmit_reset(rs->is, PPP_CCP, CCP_RESETREQ, rs->id,
2353 rs->data, rs->dlen);
2354 /* Restart timer */
475be4d8 2355 rs->timer.expires = jiffies + HZ * 5;
1da177e4
LT
2356 add_timer(&rs->timer);
2357 } else {
2358 printk(KERN_WARNING "ippp_ccp: timer cb in wrong state %d\n",
2359 rs->state);
2360 }
2361}
2362
2363/* Allocate a new reset transaction state */
2364static struct ippp_ccp_reset_state *isdn_ppp_ccp_reset_alloc_state(struct ippp_struct *is,
475be4d8 2365 unsigned char id)
1da177e4
LT
2366{
2367 struct ippp_ccp_reset_state *rs;
475be4d8 2368 if (is->reset->rs[id]) {
1da177e4
LT
2369 printk(KERN_WARNING "ippp_ccp: old state exists for id %d\n",
2370 id);
2371 return NULL;
2372 } else {
e8f4ae85 2373 rs = kzalloc(sizeof(struct ippp_ccp_reset_state), GFP_ATOMIC);
475be4d8 2374 if (!rs)
1da177e4 2375 return NULL;
1da177e4
LT
2376 rs->state = CCPResetIdle;
2377 rs->is = is;
2378 rs->id = id;
aff55a36
GT
2379 setup_timer(&rs->timer, isdn_ppp_ccp_timer_callback,
2380 (unsigned long)rs);
1da177e4
LT
2381 is->reset->rs[id] = rs;
2382 }
2383 return rs;
2384}
2385
2386
2387/* A decompressor wants a reset with a set of parameters - do what is
2388 necessary to fulfill it */
2389static void isdn_ppp_ccp_reset_trans(struct ippp_struct *is,
2390 struct isdn_ppp_resetparams *rp)
2391{
2392 struct ippp_ccp_reset_state *rs;
2393
475be4d8 2394 if (rp->valid) {
1da177e4 2395 /* The decompressor defines parameters by itself */
475be4d8 2396 if (rp->rsend) {
1da177e4 2397 /* And he wants us to send a request */
475be4d8 2398 if (!(rp->idval)) {
1da177e4
LT
2399 printk(KERN_ERR "ippp_ccp: decompressor must"
2400 " specify reset id\n");
2401 return;
2402 }
475be4d8 2403 if (is->reset->rs[rp->id]) {
1da177e4
LT
2404 /* There is already a transaction in existence
2405 for this id. May be still waiting for a
2406 Ack or may be wrong. */
2407 rs = is->reset->rs[rp->id];
475be4d8 2408 if (rs->state == CCPResetSentReq && rs->ta) {
1da177e4
LT
2409 printk(KERN_DEBUG "ippp_ccp: reset"
2410 " trans still in progress"
2411 " for id %d\n", rp->id);
2412 } else {
2413 printk(KERN_WARNING "ippp_ccp: reset"
2414 " trans in wrong state %d for"
2415 " id %d\n", rs->state, rp->id);
2416 }
2417 } else {
2418 /* Ok, this is a new transaction */
2419 printk(KERN_DEBUG "ippp_ccp: new trans for id"
2420 " %d to be started\n", rp->id);
2421 rs = isdn_ppp_ccp_reset_alloc_state(is, rp->id);
475be4d8 2422 if (!rs) {
1da177e4
LT
2423 printk(KERN_ERR "ippp_ccp: out of mem"
2424 " allocing ccp trans\n");
2425 return;
2426 }
2427 rs->state = CCPResetSentReq;
2428 rs->expra = rp->expra;
475be4d8 2429 if (rp->dtval) {
1da177e4
LT
2430 rs->dlen = rp->dlen;
2431 memcpy(rs->data, rp->data, rp->dlen);
2432 }
2433 /* HACK TODO - add link comp here */
2434 isdn_ppp_ccp_xmit_reset(is, PPP_CCP,
2435 CCP_RESETREQ, rs->id,
2436 rs->data, rs->dlen);
2437 /* Start the timer */
475be4d8 2438 rs->timer.expires = jiffies + 5 * HZ;
1da177e4
LT
2439 add_timer(&rs->timer);
2440 rs->ta = 1;
2441 }
2442 } else {
2443 printk(KERN_DEBUG "ippp_ccp: no reset sent\n");
2444 }
2445 } else {
2446 /* The reset params are invalid. The decompressor does not
2447 care about them, so we just send the minimal requests
2448 and increase ids only when an Ack is received for a
2449 given id */
475be4d8 2450 if (is->reset->rs[is->reset->lastid]) {
1da177e4
LT
2451 /* There is already a transaction in existence
2452 for this id. May be still waiting for a
2453 Ack or may be wrong. */
2454 rs = is->reset->rs[is->reset->lastid];
475be4d8 2455 if (rs->state == CCPResetSentReq && rs->ta) {
1da177e4
LT
2456 printk(KERN_DEBUG "ippp_ccp: reset"
2457 " trans still in progress"
2458 " for id %d\n", rp->id);
2459 } else {
2460 printk(KERN_WARNING "ippp_ccp: reset"
2461 " trans in wrong state %d for"
2462 " id %d\n", rs->state, rp->id);
2463 }
2464 } else {
2465 printk(KERN_DEBUG "ippp_ccp: new trans for id"
2466 " %d to be started\n", is->reset->lastid);
2467 rs = isdn_ppp_ccp_reset_alloc_state(is,
2468 is->reset->lastid);
475be4d8 2469 if (!rs) {
1da177e4
LT
2470 printk(KERN_ERR "ippp_ccp: out of mem"
2471 " allocing ccp trans\n");
2472 return;
2473 }
2474 rs->state = CCPResetSentReq;
2475 /* We always expect an Ack if the decompressor doesn't
2476 know better */
2477 rs->expra = 1;
2478 rs->dlen = 0;
2479 /* HACK TODO - add link comp here */
2480 isdn_ppp_ccp_xmit_reset(is, PPP_CCP, CCP_RESETREQ,
2481 rs->id, NULL, 0);
2482 /* Start the timer */
475be4d8 2483 rs->timer.expires = jiffies + 5 * HZ;
1da177e4
LT
2484 add_timer(&rs->timer);
2485 rs->ta = 1;
2486 }
2487 }
2488}
2489
2490/* An Ack was received for this id. This means we stop the timer and clean
2491 up the state prior to calling the decompressors reset routine. */
2492static void isdn_ppp_ccp_reset_ack_rcvd(struct ippp_struct *is,
2493 unsigned char id)
2494{
2495 struct ippp_ccp_reset_state *rs = is->reset->rs[id];
2496
475be4d8
JP
2497 if (rs) {
2498 if (rs->ta && rs->state == CCPResetSentReq) {
1da177e4 2499 /* Great, we are correct */
475be4d8 2500 if (!rs->expra)
1da177e4
LT
2501 printk(KERN_DEBUG "ippp_ccp: ResetAck received"
2502 " for id %d but not expected\n", id);
2503 } else {
2504 printk(KERN_INFO "ippp_ccp: ResetAck received out of"
2505 "sync for id %d\n", id);
2506 }
475be4d8 2507 if (rs->ta) {
1da177e4
LT
2508 rs->ta = 0;
2509 del_timer(&rs->timer);
2510 }
2511 isdn_ppp_ccp_reset_free_state(is, id);
2512 } else {
2513 printk(KERN_INFO "ippp_ccp: ResetAck received for unknown id"
2514 " %d\n", id);
2515 }
2516 /* Make sure the simple reset stuff uses a new id next time */
2517 is->reset->lastid++;
2518}
2519
475be4d8 2520/*
1da177e4
LT
2521 * decompress packet
2522 *
2523 * if master = 0, we're trying to uncompress an per-link compressed packet,
2524 * as opposed to an compressed reconstructed-from-MPPP packet.
2525 * proto is updated to protocol field of uncompressed packet.
2526 *
2527 * retval: decompressed packet,
2528 * same packet if uncompressed,
2529 * NULL if decompression error
2530 */
2531
475be4d8
JP
2532static struct sk_buff *isdn_ppp_decompress(struct sk_buff *skb, struct ippp_struct *is, struct ippp_struct *master,
2533 int *proto)
1da177e4
LT
2534{
2535 void *stat = NULL;
2536 struct isdn_ppp_compressor *ipc = NULL;
2537 struct sk_buff *skb_out;
2538 int len;
2539 struct ippp_struct *ri;
2540 struct isdn_ppp_resetparams rsparm;
2541 unsigned char rsdata[IPPP_RESET_MAXDATABYTES];
2542
475be4d8
JP
2543 if (!master) {
2544 // per-link decompression
1da177e4
LT
2545 stat = is->link_decomp_stat;
2546 ipc = is->link_decompressor;
2547 ri = is;
2548 } else {
2549 stat = master->decomp_stat;
2550 ipc = master->decompressor;
2551 ri = master;
2552 }
2553
2554 if (!ipc) {
2555 // no decompressor -> we can't decompress.
2556 printk(KERN_DEBUG "ippp: no decompressor defined!\n");
2557 return skb;
2558 }
6dd44a74 2559 BUG_ON(!stat); // if we have a compressor, stat has been set as well
1da177e4 2560
475be4d8 2561 if ((master && *proto == PPP_COMP) || (!master && *proto == PPP_COMPFRAG)) {
1da177e4
LT
2562 // compressed packets are compressed by their protocol type
2563
2564 // Set up reset params for the decompressor
475be4d8
JP
2565 memset(&rsparm, 0, sizeof(rsparm));
2566 rsparm.data = rsdata;
2567 rsparm.maxdlen = IPPP_RESET_MAXDATABYTES;
2568
2569 skb_out = dev_alloc_skb(is->mru + PPP_HDRLEN);
2570 if (!skb_out) {
2571 kfree_skb(skb);
2572 printk(KERN_ERR "ippp: decomp memory allocation failure\n");
f6e2cdc8 2573 return NULL;
475be4d8 2574 }
1da177e4
LT
2575 len = ipc->decompress(stat, skb, skb_out, &rsparm);
2576 kfree_skb(skb);
2577 if (len <= 0) {
475be4d8 2578 switch (len) {
1da177e4
LT
2579 case DECOMP_ERROR:
2580 printk(KERN_INFO "ippp: decomp wants reset %s params\n",
2581 rsparm.valid ? "with" : "without");
475be4d8 2582
1da177e4
LT
2583 isdn_ppp_ccp_reset_trans(ri, &rsparm);
2584 break;
2585 case DECOMP_FATALERROR:
2586 ri->pppcfg |= SC_DC_FERROR;
2587 /* Kick ipppd to recognize the error */
2588 isdn_ppp_ccp_kickup(ri);
2589 break;
2590 }
2591 kfree_skb(skb_out);
2592 return NULL;
2593 }
2594 *proto = isdn_ppp_strip_proto(skb_out);
2595 if (*proto < 0) {
2596 kfree_skb(skb_out);
2597 return NULL;
2598 }
2599 return skb_out;
475be4d8 2600 } else {
1da177e4
LT
2601 // uncompressed packets are fed through the decompressor to
2602 // update the decompressor state
2603 ipc->incomp(stat, skb, *proto);
2604 return skb;
2605 }
2606}
2607
2608/*
475be4d8 2609 * compress a frame
1da177e4
LT
2610 * type=0: normal/bundle compression
2611 * =1: link compression
2612 * returns original skb if we haven't compressed the frame
2613 * and a new skb pointer if we've done it
2614 */
475be4d8
JP
2615static struct sk_buff *isdn_ppp_compress(struct sk_buff *skb_in, int *proto,
2616 struct ippp_struct *is, struct ippp_struct *master, int type)
1da177e4 2617{
475be4d8
JP
2618 int ret;
2619 int new_proto;
2620 struct isdn_ppp_compressor *compressor;
2621 void *stat;
2622 struct sk_buff *skb_out;
1da177e4
LT
2623
2624 /* we do not compress control protocols */
475be4d8
JP
2625 if (*proto < 0 || *proto > 0x3fff) {
2626 return skb_in;
2627 }
1da177e4 2628
475be4d8 2629 if (type) { /* type=1 => Link compression */
1da177e4
LT
2630 return skb_in;
2631 }
2632 else {
475be4d8 2633 if (!master) {
1da177e4
LT
2634 compressor = is->compressor;
2635 stat = is->comp_stat;
2636 }
2637 else {
2638 compressor = master->compressor;
2639 stat = master->comp_stat;
2640 }
2641 new_proto = PPP_COMP;
2642 }
2643
475be4d8 2644 if (!compressor) {
1da177e4
LT
2645 printk(KERN_ERR "isdn_ppp: No compressor set!\n");
2646 return skb_in;
2647 }
475be4d8 2648 if (!stat) {
1da177e4
LT
2649 printk(KERN_ERR "isdn_ppp: Compressor not initialized?\n");
2650 return skb_in;
2651 }
2652
2653 /* Allow for at least 150 % expansion (for now) */
475be4d8
JP
2654 skb_out = alloc_skb(skb_in->len + skb_in->len / 2 + 32 +
2655 skb_headroom(skb_in), GFP_ATOMIC);
2656 if (!skb_out)
1da177e4
LT
2657 return skb_in;
2658 skb_reserve(skb_out, skb_headroom(skb_in));
2659
475be4d8
JP
2660 ret = (compressor->compress)(stat, skb_in, skb_out, *proto);
2661 if (!ret) {
1da177e4
LT
2662 dev_kfree_skb(skb_out);
2663 return skb_in;
2664 }
475be4d8 2665
1da177e4
LT
2666 dev_kfree_skb(skb_in);
2667 *proto = new_proto;
2668 return skb_out;
2669}
2670
2671/*
475be4d8 2672 * we received a CCP frame ..
1da177e4
LT
2673 * not a clean solution, but we MUST handle a few cases in the kernel
2674 */
2675static void isdn_ppp_receive_ccp(isdn_net_dev *net_dev, isdn_net_local *lp,
475be4d8 2676 struct sk_buff *skb, int proto)
1da177e4
LT
2677{
2678 struct ippp_struct *is;
2679 struct ippp_struct *mis;
2680 int len;
2681 struct isdn_ppp_resetparams rsparm;
475be4d8 2682 unsigned char rsdata[IPPP_RESET_MAXDATABYTES];
1da177e4
LT
2683
2684 printk(KERN_DEBUG "Received CCP frame from peer slot(%d)\n",
475be4d8 2685 lp->ppp_slot);
052bb88e 2686 if (lp->ppp_slot < 0 || lp->ppp_slot >= ISDN_MAX_CHANNELS) {
1da177e4 2687 printk(KERN_ERR "%s: lp->ppp_slot(%d) out of range\n",
475be4d8 2688 __func__, lp->ppp_slot);
1da177e4
LT
2689 return;
2690 }
2691 is = ippp_table[lp->ppp_slot];
475be4d8 2692 isdn_ppp_frame_log("ccp-rcv", skb->data, skb->len, 32, is->unit, lp->ppp_slot);
1da177e4 2693
475be4d8 2694 if (lp->master) {
838361fe 2695 int slot = ISDN_MASTER_PRIV(lp)->ppp_slot;
052bb88e 2696 if (slot < 0 || slot >= ISDN_MAX_CHANNELS) {
1da177e4 2697 printk(KERN_ERR "%s: slot(%d) out of range\n",
475be4d8 2698 __func__, slot);
1da177e4 2699 return;
475be4d8 2700 }
1da177e4
LT
2701 mis = ippp_table[slot];
2702 } else
2703 mis = is;
2704
475be4d8 2705 switch (skb->data[0]) {
1da177e4 2706 case CCP_CONFREQ:
475be4d8 2707 if (is->debug & 0x10)
1da177e4 2708 printk(KERN_DEBUG "Disable compression here!\n");
475be4d8
JP
2709 if (proto == PPP_CCP)
2710 mis->compflags &= ~SC_COMP_ON;
1da177e4 2711 else
475be4d8 2712 is->compflags &= ~SC_LINK_COMP_ON;
1da177e4
LT
2713 break;
2714 case CCP_TERMREQ:
2715 case CCP_TERMACK:
475be4d8 2716 if (is->debug & 0x10)
1da177e4 2717 printk(KERN_DEBUG "Disable (de)compression here!\n");
475be4d8
JP
2718 if (proto == PPP_CCP)
2719 mis->compflags &= ~(SC_DECOMP_ON | SC_COMP_ON);
1da177e4 2720 else
475be4d8 2721 is->compflags &= ~(SC_LINK_DECOMP_ON | SC_LINK_COMP_ON);
1da177e4
LT
2722 break;
2723 case CCP_CONFACK:
2724 /* if we RECEIVE an ackowledge we enable the decompressor */
475be4d8 2725 if (is->debug & 0x10)
1da177e4 2726 printk(KERN_DEBUG "Enable decompression here!\n");
475be4d8 2727 if (proto == PPP_CCP) {
1da177e4
LT
2728 if (!mis->decompressor)
2729 break;
2730 mis->compflags |= SC_DECOMP_ON;
2731 } else {
2732 if (!is->decompressor)
2733 break;
2734 is->compflags |= SC_LINK_DECOMP_ON;
2735 }
2736 break;
2737
2738 case CCP_RESETACK:
2739 printk(KERN_DEBUG "Received ResetAck from peer\n");
2740 len = (skb->data[2] << 8) | skb->data[3];
2741 len -= 4;
2742
475be4d8 2743 if (proto == PPP_CCP) {
1da177e4
LT
2744 /* If a reset Ack was outstanding for this id, then
2745 clean up the state engine */
2746 isdn_ppp_ccp_reset_ack_rcvd(mis, skb->data[1]);
475be4d8 2747 if (mis->decompressor && mis->decomp_stat)
1da177e4
LT
2748 mis->decompressor->
2749 reset(mis->decomp_stat,
2750 skb->data[0],
2751 skb->data[1],
2752 len ? &skb->data[4] : NULL,
2753 len, NULL);
2754 /* TODO: This is not easy to decide here */
2755 mis->compflags &= ~SC_DECOMP_DISCARD;
2756 }
2757 else {
2758 isdn_ppp_ccp_reset_ack_rcvd(is, skb->data[1]);
475be4d8 2759 if (is->link_decompressor && is->link_decomp_stat)
1da177e4
LT
2760 is->link_decompressor->
2761 reset(is->link_decomp_stat,
2762 skb->data[0],
2763 skb->data[1],
2764 len ? &skb->data[4] : NULL,
2765 len, NULL);
2766 /* TODO: neither here */
2767 is->compflags &= ~SC_LINK_DECOMP_DISCARD;
2768 }
2769 break;
2770
2771 case CCP_RESETREQ:
2772 printk(KERN_DEBUG "Received ResetReq from peer\n");
2773 /* Receiving a ResetReq means we must reset our compressor */
2774 /* Set up reset params for the reset entry */
2775 memset(&rsparm, 0, sizeof(rsparm));
2776 rsparm.data = rsdata;
475be4d8 2777 rsparm.maxdlen = IPPP_RESET_MAXDATABYTES;
1da177e4
LT
2778 /* Isolate data length */
2779 len = (skb->data[2] << 8) | skb->data[3];
2780 len -= 4;
475be4d8
JP
2781 if (proto == PPP_CCP) {
2782 if (mis->compressor && mis->comp_stat)
1da177e4
LT
2783 mis->compressor->
2784 reset(mis->comp_stat,
2785 skb->data[0],
2786 skb->data[1],
2787 len ? &skb->data[4] : NULL,
2788 len, &rsparm);
2789 }
2790 else {
475be4d8 2791 if (is->link_compressor && is->link_comp_stat)
1da177e4
LT
2792 is->link_compressor->
2793 reset(is->link_comp_stat,
2794 skb->data[0],
2795 skb->data[1],
2796 len ? &skb->data[4] : NULL,
2797 len, &rsparm);
2798 }
2799 /* Ack the Req as specified by rsparm */
475be4d8 2800 if (rsparm.valid) {
1da177e4 2801 /* Compressor reset handler decided how to answer */
475be4d8 2802 if (rsparm.rsend) {
1da177e4
LT
2803 /* We should send a Frame */
2804 isdn_ppp_ccp_xmit_reset(is, proto, CCP_RESETACK,
2805 rsparm.idval ? rsparm.id
2806 : skb->data[1],
2807 rsparm.dtval ?
2808 rsparm.data : NULL,
2809 rsparm.dtval ?
2810 rsparm.dlen : 0);
2811 } else {
2812 printk(KERN_DEBUG "ResetAck suppressed\n");
2813 }
2814 } else {
2815 /* We answer with a straight reflected Ack */
2816 isdn_ppp_ccp_xmit_reset(is, proto, CCP_RESETACK,
2817 skb->data[1],
2818 len ? &skb->data[4] : NULL,
2819 len);
2820 }
2821 break;
2822 }
2823}
2824
2825
2826/*
2827 * Daemon sends a CCP frame ...
2828 */
2829
2830/* TODO: Clean this up with new Reset semantics */
2831
2832/* I believe the CCP handling as-is is done wrong. Compressed frames
2833 * should only be sent/received after CCP reaches UP state, which means
2834 * both sides have sent CONF_ACK. Currently, we handle both directions
2835 * independently, which means we may accept compressed frames too early
2836 * (supposedly not a problem), but may also mean we send compressed frames
2837 * too early, which may turn out to be a problem.
2838 * This part of state machine should actually be handled by (i)pppd, but
2839 * that's too big of a change now. --kai
2840 */
2841
2842/* Actually, we might turn this into an advantage: deal with the RFC in
2843 * the old tradition of beeing generous on what we accept, but beeing
2844 * strict on what we send. Thus we should just
2845 * - accept compressed frames as soon as decompression is negotiated
2846 * - send compressed frames only when decomp *and* comp are negotiated
2847 * - drop rx compressed frames if we cannot decomp (instead of pushing them
2848 * up to ipppd)
2849 * and I tried to modify this file according to that. --abp
2850 */
2851
2852static void isdn_ppp_send_ccp(isdn_net_dev *net_dev, isdn_net_local *lp, struct sk_buff *skb)
2853{
475be4d8 2854 struct ippp_struct *mis, *is;
1da177e4
LT
2855 int proto, slot = lp->ppp_slot;
2856 unsigned char *data;
2857
475be4d8 2858 if (!skb || skb->len < 3)
1da177e4
LT
2859 return;
2860 if (slot < 0 || slot >= ISDN_MAX_CHANNELS) {
2861 printk(KERN_ERR "%s: lp->ppp_slot(%d) out of range\n",
475be4d8 2862 __func__, slot);
1da177e4 2863 return;
475be4d8 2864 }
1da177e4
LT
2865 is = ippp_table[slot];
2866 /* Daemon may send with or without address and control field comp */
2867 data = skb->data;
475be4d8 2868 if (!(is->pppcfg & SC_COMP_AC) && data[0] == 0xff && data[1] == 0x03) {
1da177e4 2869 data += 2;
475be4d8 2870 if (skb->len < 5)
1da177e4
LT
2871 return;
2872 }
2873
475be4d8
JP
2874 proto = ((int)data[0]<<8) + data[1];
2875 if (proto != PPP_CCP && proto != PPP_CCPFRAG)
1da177e4
LT
2876 return;
2877
2878 printk(KERN_DEBUG "Received CCP frame from daemon:\n");
475be4d8 2879 isdn_ppp_frame_log("ccp-xmit", skb->data, skb->len, 32, is->unit, lp->ppp_slot);
1da177e4
LT
2880
2881 if (lp->master) {
838361fe 2882 slot = ISDN_MASTER_PRIV(lp)->ppp_slot;
052bb88e 2883 if (slot < 0 || slot >= ISDN_MAX_CHANNELS) {
1da177e4 2884 printk(KERN_ERR "%s: slot(%d) out of range\n",
475be4d8 2885 __func__, slot);
1da177e4 2886 return;
475be4d8 2887 }
1da177e4
LT
2888 mis = ippp_table[slot];
2889 } else
2890 mis = is;
2891 if (mis != is)
2892 printk(KERN_DEBUG "isdn_ppp: Ouch! Master CCP sends on slave slot!\n");
475be4d8
JP
2893
2894 switch (data[2]) {
1da177e4 2895 case CCP_CONFREQ:
475be4d8 2896 if (is->debug & 0x10)
1da177e4 2897 printk(KERN_DEBUG "Disable decompression here!\n");
475be4d8 2898 if (proto == PPP_CCP)
1da177e4
LT
2899 is->compflags &= ~SC_DECOMP_ON;
2900 else
2901 is->compflags &= ~SC_LINK_DECOMP_ON;
2902 break;
2903 case CCP_TERMREQ:
2904 case CCP_TERMACK:
475be4d8 2905 if (is->debug & 0x10)
1da177e4 2906 printk(KERN_DEBUG "Disable (de)compression here!\n");
475be4d8
JP
2907 if (proto == PPP_CCP)
2908 is->compflags &= ~(SC_DECOMP_ON | SC_COMP_ON);
1da177e4 2909 else
475be4d8 2910 is->compflags &= ~(SC_LINK_DECOMP_ON | SC_LINK_COMP_ON);
1da177e4
LT
2911 break;
2912 case CCP_CONFACK:
2913 /* if we SEND an ackowledge we can/must enable the compressor */
475be4d8 2914 if (is->debug & 0x10)
1da177e4 2915 printk(KERN_DEBUG "Enable compression here!\n");
475be4d8 2916 if (proto == PPP_CCP) {
1da177e4
LT
2917 if (!is->compressor)
2918 break;
2919 is->compflags |= SC_COMP_ON;
2920 } else {
2921 if (!is->compressor)
2922 break;
2923 is->compflags |= SC_LINK_COMP_ON;
2924 }
2925 break;
2926 case CCP_RESETACK:
2927 /* If we send a ACK we should reset our compressor */
475be4d8 2928 if (is->debug & 0x10)
1da177e4
LT
2929 printk(KERN_DEBUG "Reset decompression state here!\n");
2930 printk(KERN_DEBUG "ResetAck from daemon passed by\n");
475be4d8 2931 if (proto == PPP_CCP) {
1da177e4 2932 /* link to master? */
475be4d8 2933 if (is->compressor && is->comp_stat)
1da177e4
LT
2934 is->compressor->reset(is->comp_stat, 0, 0,
2935 NULL, 0, NULL);
475be4d8 2936 is->compflags &= ~SC_COMP_DISCARD;
1da177e4
LT
2937 }
2938 else {
475be4d8 2939 if (is->link_compressor && is->link_comp_stat)
1da177e4
LT
2940 is->link_compressor->reset(is->link_comp_stat,
2941 0, 0, NULL, 0, NULL);
475be4d8 2942 is->compflags &= ~SC_LINK_COMP_DISCARD;
1da177e4
LT
2943 }
2944 break;
2945 case CCP_RESETREQ:
2946 /* Just let it pass by */
2947 printk(KERN_DEBUG "ResetReq from daemon passed by\n");
2948 break;
2949 }
2950}
2951
2952int isdn_ppp_register_compressor(struct isdn_ppp_compressor *ipc)
2953{
2954 ipc->next = ipc_head;
2955 ipc->prev = NULL;
475be4d8 2956 if (ipc_head) {
1da177e4
LT
2957 ipc_head->prev = ipc;
2958 }
2959 ipc_head = ipc;
2960 return 0;
2961}
2962
2963int isdn_ppp_unregister_compressor(struct isdn_ppp_compressor *ipc)
2964{
475be4d8 2965 if (ipc->prev)
1da177e4
LT
2966 ipc->prev->next = ipc->next;
2967 else
2968 ipc_head = ipc->next;
475be4d8 2969 if (ipc->next)
1da177e4
LT
2970 ipc->next->prev = ipc->prev;
2971 ipc->prev = ipc->next = NULL;
2972 return 0;
2973}
2974
2975static int isdn_ppp_set_compressor(struct ippp_struct *is, struct isdn_ppp_comp_data *data)
2976{
2977 struct isdn_ppp_compressor *ipc = ipc_head;
2978 int ret;
2979 void *stat;
2980 int num = data->num;
2981
475be4d8
JP
2982 if (is->debug & 0x10)
2983 printk(KERN_DEBUG "[%d] Set %s type %d\n", is->unit,
2984 (data->flags & IPPP_COMP_FLAG_XMIT) ? "compressor" : "decompressor", num);
1da177e4
LT
2985
2986 /* If is has no valid reset state vector, we cannot allocate a
2987 decompressor. The decompressor would cause reset transactions
2988 sooner or later, and they need that vector. */
2989
475be4d8 2990 if (!(data->flags & IPPP_COMP_FLAG_XMIT) && !is->reset) {
1da177e4
LT
2991 printk(KERN_ERR "ippp_ccp: no reset data structure - can't"
2992 " allow decompression.\n");
2993 return -ENOMEM;
2994 }
2995
475be4d8
JP
2996 while (ipc) {
2997 if (ipc->num == num) {
1da177e4 2998 stat = ipc->alloc(data);
475be4d8
JP
2999 if (stat) {
3000 ret = ipc->init(stat, data, is->unit, 0);
3001 if (!ret) {
1da177e4
LT
3002 printk(KERN_ERR "Can't init (de)compression!\n");
3003 ipc->free(stat);
3004 stat = NULL;
3005 break;
3006 }
3007 }
3008 else {
3009 printk(KERN_ERR "Can't alloc (de)compression!\n");
3010 break;
3011 }
3012
475be4d8
JP
3013 if (data->flags & IPPP_COMP_FLAG_XMIT) {
3014 if (data->flags & IPPP_COMP_FLAG_LINK) {
3015 if (is->link_comp_stat)
1da177e4
LT
3016 is->link_compressor->free(is->link_comp_stat);
3017 is->link_comp_stat = stat;
475be4d8 3018 is->link_compressor = ipc;
1da177e4
LT
3019 }
3020 else {
475be4d8 3021 if (is->comp_stat)
1da177e4
LT
3022 is->compressor->free(is->comp_stat);
3023 is->comp_stat = stat;
475be4d8 3024 is->compressor = ipc;
1da177e4
LT
3025 }
3026 }
475be4d8
JP
3027 else {
3028 if (data->flags & IPPP_COMP_FLAG_LINK) {
3029 if (is->link_decomp_stat)
1da177e4
LT
3030 is->link_decompressor->free(is->link_decomp_stat);
3031 is->link_decomp_stat = stat;
475be4d8 3032 is->link_decompressor = ipc;
1da177e4
LT
3033 }
3034 else {
475be4d8 3035 if (is->decomp_stat)
1da177e4
LT
3036 is->decompressor->free(is->decomp_stat);
3037 is->decomp_stat = stat;
475be4d8 3038 is->decompressor = ipc;
1da177e4
LT
3039 }
3040 }
3041 return 0;
3042 }
3043 ipc = ipc->next;
3044 }
3045 return -EINVAL;
3046}