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