X-Git-Url: http://git.ozlabs.org/?p=ppp.git;a=blobdiff_plain;f=linux%2Fppp.c;h=0fa98fd1eebffd00101716061106ed3f8a0f342a;hp=f465e066029d62962e78fd6b36eaf877a5bc4df7;hb=fea937ca274527cce12ff493be219aa0c93f9d53;hpb=699e067418e4de59d75c0de252b1bc066d4fe8c0 diff --git a/linux/ppp.c b/linux/ppp.c index f465e06..0fa98fd 100644 --- a/linux/ppp.c +++ b/linux/ppp.c @@ -4,7 +4,7 @@ * Al Longyear * Extensively rewritten by Paul Mackerras * - * ==FILEVERSION 981004== + * ==FILEVERSION 990910== * * NOTE TO MAINTAINERS: * If you modify this file at all, please set the number above to the @@ -45,7 +45,7 @@ #define PPP_MAX_RCV_QLEN 32 /* max # frames we queue up for pppd */ -/* $Id: ppp.c,v 1.20 1999/01/19 23:57:44 paulus Exp $ */ +/* $Id: ppp.c,v 1.33 1999/12/23 01:48:45 paulus Exp $ */ #include #include @@ -103,7 +103,8 @@ #include #endif -#define PPP_VERSION "2.3.5" +#undef PPP_VERSION +#define PPP_VERSION "2.3.11" #if LINUX_VERSION_CODE >= VERSION(2,1,4) @@ -144,7 +145,7 @@ #endif #if LINUX_VERSION_CODE < VERSION(2,1,57) -#define signal_pending(tsk) ((tsk)->pending & ~(tsk)->blocked) +#define signal_pending(tsk) ((tsk)->signal & ~(tsk)->blocked) #endif #if LINUX_VERSION_CODE < VERSION(2,1,60) @@ -155,20 +156,43 @@ typedef ssize_t rw_ret_t; typedef size_t rw_count_t; #endif +#if LINUX_VERSION_CODE < VERSION(2,1,86) +#define KFREE_SKB(s) dev_kfree_skb((s), FREE_WRITE) +#else +#define KFREE_SKB(s) kfree_skb(s) +#endif + +#if LINUX_VERSION_CODE < VERSION(2,1,15) +#define LIBERATE_SKB(s) ((s)->free = 1) +#else +#define LIBERATE_SKB(s) do { } while (0) +#endif + +#if LINUX_VERSION_CODE < VERSION(2,1,95) +#define SUSER() suser() +#else +#define SUSER() capable(CAP_NET_ADMIN) +#endif + +#if LINUX_VERSION_CODE < VERSION(2,2,0) +#define wmb() mb() +#endif + /* * Local functions */ -#ifdef CONFIG_MODULES static int ppp_register_compressor (struct compressor *cp); static void ppp_unregister_compressor (struct compressor *cp); -#endif static void ppp_async_init(struct ppp *ppp); static void ppp_async_release(struct ppp *ppp); +static int ppp_tty_sync_push(struct ppp *ppp); static int ppp_tty_push(struct ppp *ppp); static int ppp_async_encode(struct ppp *ppp); static int ppp_async_send(struct ppp *, struct sk_buff *); +static int ppp_sync_send(struct ppp *, struct sk_buff *); +static void ppp_tty_flush_output(struct ppp *); static int ppp_ioctl(struct ppp *, unsigned int, unsigned long); static int ppp_set_compression (struct ppp *ppp, struct ppp_option_data *odp); @@ -241,7 +265,6 @@ static struct symbol_table ppp_syms = { #include X(ppp_register_compressor), X(ppp_unregister_compressor), - X(ppp_crc16_table), #include }; #else @@ -318,7 +341,9 @@ __u16 ppp_crc16_table[256] = 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78 }; +#if LINUX_VERSION_CODE >= VERSION(2,1,18) EXPORT_SYMBOL(ppp_crc16_table); +#endif #ifdef CHECK_CHARACTERS static __u32 paritytab[8] = @@ -353,7 +378,9 @@ ppp_first_time(void) */ (void) memset (&ppp_ldisc, 0, sizeof (ppp_ldisc)); ppp_ldisc.magic = TTY_LDISC_MAGIC; +#if LINUX_VERSION_CODE >= VERSION(2,1,28) ppp_ldisc.name = "ppp"; +#endif ppp_ldisc.open = ppp_tty_open; ppp_ldisc.close = ppp_tty_close; ppp_ldisc.read = ppp_tty_read; @@ -441,10 +468,10 @@ ppp_async_release(struct ppp *ppp) struct sk_buff *skb; if ((skb = ppp->rpkt) != NULL) - kfree_skb(skb); + KFREE_SKB(skb); ppp->rpkt = NULL; if ((skb = ppp->tpkt) != NULL) - kfree_skb(skb); + KFREE_SKB(skb); ppp->tpkt = NULL; } @@ -531,6 +558,7 @@ ppp_tty_close (struct tty_struct *tty) ppp->tty = ppp->backup_tty; if (ppp_tty_push(ppp)) ppp_output_wakeup(ppp); + wake_up_interruptible(&ppp->read_wait); } else { ppp->tty = 0; ppp->sc_xfer = 0; @@ -596,7 +624,6 @@ ppp_tty_read(struct tty_struct *tty, struct file *file, __u8 * buf, if (file->f_flags & O_NONBLOCK) break; - current->timeout = 0; interruptible_sleep_on(&ppp->read_wait); err = -EINTR; if (signal_pending(current)) @@ -629,7 +656,7 @@ ppp_tty_read(struct tty_struct *tty, struct file *file, __u8 * buf, err = -EFAULT; out: - kfree_skb(skb); + KFREE_SKB(skb); return err; } @@ -676,13 +703,14 @@ ppp_tty_write(struct tty_struct *tty, struct file *file, const __u8 * data, printk(KERN_ERR "ppp_tty_write: no memory\n"); return 0; } + LIBERATE_SKB(skb); new_data = skb_put(skb, count); /* * Retrieve the user's buffer */ if (COPY_FROM_USER(new_data, data, count)) { - kfree_skb(skb); + KFREE_SKB(skb); return -EFAULT; } @@ -716,7 +744,7 @@ ppp_tty_ioctl (struct tty_struct *tty, struct file * file, /* * The user must have an euid of root to do these requests. */ - if (!capable(CAP_NET_ADMIN)) + if (!SUSER()) return -EPERM; switch (param2) { @@ -810,6 +838,21 @@ ppp_tty_ioctl (struct tty_struct *tty, struct file * file, error = n_tty_ioctl (tty, file, param2, param3); break; + case TCFLSH: + /* + * Flush our buffers, then call the generic code to + * flush the serial port's buffer. + */ + if (param3 == TCIFLUSH || param3 == TCIOFLUSH) { + struct sk_buff *skb; + while ((skb = skb_dequeue(&ppp->rcv_q)) != NULL) + KFREE_SKB(skb); + } + if (param3 == TCIOFLUSH || param3 == TCOFLUSH) + ppp_tty_flush_output(ppp); + error = n_tty_ioctl (tty, file, param2, param3); + break; + case FIONREAD: /* * Returns how many bytes are available for a read(). @@ -935,6 +978,135 @@ ppp_tty_wakeup (struct tty_struct *tty) ppp_output_wakeup(ppp); } +/* + * Send a packet to the peer over a synchronous tty line. + * All encoding and FCS are handled by hardware. + * Addr/Ctrl and Protocol field compression implemented. + * Returns -1 iff the packet could not be accepted at present, + * 0 if the packet was accepted but we can't accept another yet, or + * 1 if we can accept another packet immediately. + * If this procedure returns 0, ppp_output_wakeup will be called + * exactly once. + */ +static int +ppp_sync_send(struct ppp *ppp, struct sk_buff *skb) +{ + unsigned char *data; + int islcp; + + CHECK_PPP(0); + + if (ppp->tpkt != NULL) + return -1; + ppp->tpkt = skb; + + data = ppp->tpkt->data; + + /* + * LCP packets with code values between 1 (configure-reqest) + * and 7 (code-reject) must be sent as though no options + * had been negotiated. + */ + islcp = PPP_PROTOCOL(data) == PPP_LCP + && 1 <= data[PPP_HDRLEN] && data[PPP_HDRLEN] <= 7; + + /* only reset idle time for data packets */ + if (PPP_PROTOCOL(data) < 0x8000) + ppp->last_xmit = jiffies; + ++ppp->stats.ppp_opackets; + ppp->stats.ppp_ooctects += ppp->tpkt->len; + + if ( !(data[2]) && (ppp->flags & SC_COMP_PROT) ) { + /* compress protocol field */ + data[2] = data[1]; + data[1] = data[0]; + skb_pull(ppp->tpkt,1); + data = ppp->tpkt->data; + } + + /* + * Do address/control compression + */ + if ((ppp->flags & SC_COMP_AC) && !islcp + && PPP_ADDRESS(data) == PPP_ALLSTATIONS + && PPP_CONTROL(data) == PPP_UI) { + /* strip addr and control field */ + skb_pull(ppp->tpkt,2); + } + + return ppp_tty_sync_push(ppp); +} + +/* + * Push a synchronous frame out to the tty. + * Returns 1 if frame accepted (or discarded), 0 otherwise. + */ +static int +ppp_tty_sync_push(struct ppp *ppp) +{ + int sent; + struct tty_struct *tty = ppp2tty(ppp); + unsigned long flags; + + CHECK_PPP(0); + + if (ppp->tpkt == NULL) + return 0; + + /* prevent reentrancy with tty_pushing flag */ + save_flags(flags); + cli(); + if (ppp->tty_pushing) { + /* record wakeup attempt so we don't lose */ + /* a wakeup call while doing push processing */ + ppp->woke_up=1; + restore_flags(flags); + return 0; + } + ppp->tty_pushing = 1; + restore_flags(flags); + + if (tty == NULL || tty->disc_data != (void *) ppp) + goto flush; + + for(;;){ + ppp->woke_up=0; + + /* Note: Sync driver accepts complete frame or nothing */ + tty->flags |= (1 << TTY_DO_WRITE_WAKEUP); + sent = tty->driver.write(tty, 0, ppp->tpkt->data, ppp->tpkt->len); + if (sent < 0) { + /* write error (possible loss of CD) */ + /* record error and discard current packet */ + ppp->stats.ppp_oerrors++; + break; + } + ppp->stats.ppp_obytes += sent; + if (sent < ppp->tpkt->len) { + /* driver unable to accept frame just yet */ + save_flags(flags); + cli(); + if (ppp->woke_up) { + /* wake up called while processing */ + /* try to send the frame again */ + restore_flags(flags); + continue; + } + /* wait for wakeup callback to try send again */ + ppp->tty_pushing = 0; + restore_flags(flags); + return 0; + } + break; + } +flush: + /* done with current packet (sent or discarded) */ + KFREE_SKB(ppp->tpkt); + ppp->tpkt = 0; + ppp->tty_pushing = 0; + return 1; +} + /* * Send a packet to the peer over an async tty line. * Returns -1 iff the packet could not be accepted at present, @@ -967,14 +1139,21 @@ ppp_tty_push(struct ppp *ppp) { int avail, sent, done = 0; struct tty_struct *tty = ppp2tty(ppp); + + if (ppp->flags & SC_SYNC) + return ppp_tty_sync_push(ppp); CHECK_PPP(0); - if (ppp->tty_pushing) + if (ppp->tty_pushing) { + ppp->woke_up = 1; return 0; + } if (tty == NULL || tty->disc_data != (void *) ppp) goto flush; while (ppp->optr < ppp->olim || ppp->tpkt != 0) { ppp->tty_pushing = 1; + mb(); + ppp->woke_up = 0; avail = ppp->olim - ppp->optr; if (avail > 0) { tty->flags |= (1 << TTY_DO_WRITE_WAKEUP); @@ -984,25 +1163,32 @@ ppp_tty_push(struct ppp *ppp) ppp->stats.ppp_obytes += sent; ppp->optr += sent; if (sent < avail) { + wmb(); ppp->tty_pushing = 0; + mb(); + if (ppp->woke_up) + continue; return done; } } if (ppp->tpkt != 0) done = ppp_async_encode(ppp); + wmb(); ppp->tty_pushing = 0; } return done; flush: ppp->tty_pushing = 1; + mb(); ppp->stats.ppp_oerrors++; if (ppp->tpkt != 0) { - kfree_skb(ppp->tpkt); + KFREE_SKB(ppp->tpkt); ppp->tpkt = 0; done = 1; } ppp->optr = ppp->olim; + wmb(); ppp->tty_pushing = 0; return done; } @@ -1102,7 +1288,7 @@ ppp_async_encode(struct ppp *ppp) *buf++ = PPP_FLAG; ppp->olim = buf; - kfree_skb(ppp->tpkt); + KFREE_SKB(ppp->tpkt); ppp->tpkt = 0; return 1; } @@ -1116,6 +1302,32 @@ ppp_async_encode(struct ppp *ppp) return 0; } +/* + * Flush output from our internal buffers. + * Called for the TCFLSH ioctl. + */ +static void +ppp_tty_flush_output(struct ppp *ppp) +{ + struct sk_buff *skb; + int done = 0; + + while ((skb = skb_dequeue(&ppp->xmt_q)) != NULL) + KFREE_SKB(skb); + ppp->tty_pushing = 1; + mb(); + ppp->optr = ppp->olim; + if (ppp->tpkt != NULL) { + KFREE_SKB(ppp->tpkt); + ppp->tpkt = 0; + done = 1; + } + wmb(); + ppp->tty_pushing = 0; + if (done) + ppp_output_wakeup(ppp); +} + /* * Callback function from tty driver. Return the amount of space left * in the receiver's buffer to decide if remote transmitter is to be @@ -1165,6 +1377,74 @@ ppp_tty_receive (struct tty_struct *tty, const __u8 * data, ppp->stats.ppp_ibytes += count; skb = ppp->rpkt; + + if ( ppp->flags & SC_SYNC ) { + /* synchronous mode */ + + if (ppp->toss==0xE0) { + /* this is the 1st frame, reset vj comp */ + ppp_receive_error(ppp); + ppp->toss = 0; + } + + /* + * Allocate an skbuff for frame. + * The 128 is room for VJ header expansion. + */ + + if (skb == NULL) + skb = dev_alloc_skb(ppp->mru + 128 + PPP_HDRLEN); + + if (skb == NULL) { + if (ppp->flags & SC_DEBUG) + printk(KERN_DEBUG "couldn't " + "alloc skb for recv\n"); + } else { + LIBERATE_SKB(skb); + /* + * Decompress A/C and protocol compression here. + */ + p = skb_put(skb, 2); + p[0] = PPP_ALLSTATIONS; + p[1] = PPP_UI; + if (*data == PPP_ALLSTATIONS) { + data += 2; + count -= 2; + } + if ((*data & 1) != 0) { + p = skb_put(skb, 1); + p[0] = 0; + } + + /* copy frame to socket buffer */ + p = skb_put(skb, count); + memcpy(p,data,count); + + /* + * Check if we've overflowed the MRU + */ + if (skb->len >= ppp->mru + PPP_HDRLEN + 2 + || skb_tailroom(skb) <= 0) { + ++ppp->estats.rx_length_errors; + if (ppp->flags & SC_DEBUG) + printk(KERN_DEBUG "rcv frame too long: " + "len=%d mru=%d hroom=%d troom=%d\n", + skb->len, ppp->mru, skb_headroom(skb), + skb_tailroom(skb)); + } else { + if (!ppp_receive_frame(ppp, skb)) { + KFREE_SKB(skb); + ppp_receive_error(ppp); + } + } + + /* Reset for the next frame */ + skb = NULL; + } + ppp->rpkt = skb; + return; + } + while (count-- > 0) { /* * Collect the character and error condition for the character. @@ -1231,7 +1511,7 @@ ppp_tty_receive (struct tty_struct *tty, const __u8 * data, "ppp: tossing frame (%x)\n", ppp->toss); if (skb != NULL) - kfree_skb(skb); + KFREE_SKB(skb); if (!(ppp->toss == 0xE0 || ppp->toss == 0x80)) ++ppp->stats.ppp_ierrors; ppp_receive_error(ppp); @@ -1280,6 +1560,7 @@ ppp_tty_receive (struct tty_struct *tty, const __u8 * data, ppp->toss = 1; continue; } + LIBERATE_SKB(skb); } /* @@ -1359,6 +1640,7 @@ typedef struct ppp_proto_struct { } ppp_proto_type; static int rcv_proto_ip (struct ppp *, struct sk_buff *); +static int rcv_proto_ipv6 (struct ppp *, struct sk_buff *); static int rcv_proto_ipx (struct ppp *, struct sk_buff *); static int rcv_proto_at (struct ppp *, struct sk_buff *); static int rcv_proto_vjc_comp (struct ppp *, struct sk_buff *); @@ -1369,6 +1651,7 @@ static int rcv_proto_unknown (struct ppp *, struct sk_buff *); static ppp_proto_type proto_list[] = { { PPP_IP, rcv_proto_ip }, + { PPP_IPV6, rcv_proto_ipv6 }, { PPP_IPX, rcv_proto_ipx }, { PPP_AT, rcv_proto_at }, { PPP_VJC_COMP, rcv_proto_vjc_comp }, @@ -1531,7 +1814,7 @@ ppp_ioctl(struct ppp *ppp, unsigned int param2, unsigned long param3) /* * The user must have an euid of root to do these requests. */ - if (!capable(CAP_NET_ADMIN)) + if (!SUSER()) return -EPERM; switch (param2) { @@ -1680,6 +1963,9 @@ ppp_ioctl(struct ppp *ppp, unsigned int param2, unsigned long param3) break; switch (npi.protocol) { + case PPP_IPV6: + npi.protocol = NP_IPV6; + break; case PPP_IP: npi.protocol = NP_IP; break; @@ -1985,7 +2271,7 @@ ppp_receive_frame(struct ppp *ppp, struct sk_buff *skb) if (skb == NULL) return 1; if (skb->len == 0) { - kfree_skb(skb); + KFREE_SKB(skb); return 1; } data = skb->data; @@ -2002,23 +2288,25 @@ ppp_receive_frame(struct ppp *ppp, struct sk_buff *skb) return 0; } - /* - * Verify the FCS of the frame and discard the FCS characters - * from the end of the buffer. - */ - if (ppp->rfcs != PPP_GOODFCS) { - if (ppp->flags & SC_DEBUG) { - printk(KERN_DEBUG - "ppp: frame with bad fcs, length = %d\n", - count); - ppp_print_buffer("bad frame", data, count); + if ( !(ppp->flags & SC_SYNC) ) { + /* + * Verify the FCS of the frame and discard the FCS characters + * from the end of the buffer. + */ + if (ppp->rfcs != PPP_GOODFCS) { + if (ppp->flags & SC_DEBUG) { + printk(KERN_DEBUG + "ppp: frame with bad fcs, length = %d\n", + count); + ppp_print_buffer("bad frame", data, count); + } + ++ppp->estats.rx_crc_errors; + return 0; } - ++ppp->estats.rx_crc_errors; - return 0; + count -= 2; /* ignore the fcs characters */ + skb_trim(skb, count); } - count -= 2; /* ignore the fcs characters */ - skb_trim(skb, count); - + /* * Process the active decompressor. */ @@ -2034,13 +2322,14 @@ ppp_receive_frame(struct ppp *ppp, struct sk_buff *skb) printk(KERN_ERR "ppp_recv_frame: no memory\n"); new_count = DECOMP_ERROR; } else { + LIBERATE_SKB(new_skb); new_count = (*ppp->sc_rcomp->decompress) (ppp->sc_rc_state, data, count, new_skb->data, ppp->mru + PPP_HDRLEN); } if (new_count > 0) { /* Frame was decompressed OK */ - kfree_skb(skb); + KFREE_SKB(skb); skb = new_skb; count = new_count; data = skb_put(skb, count); @@ -2055,7 +2344,7 @@ ppp_receive_frame(struct ppp *ppp, struct sk_buff *skb) printk(KERN_INFO "%s: decomp err %d\n", ppp->name, new_count); if (new_skb != 0) - kfree_skb(new_skb); + KFREE_SKB(new_skb); if (ppp->slcomp != 0) slhc_toss(ppp->slcomp); ++ppp->stats.ppp_ierrors; @@ -2103,7 +2392,7 @@ ppp_receive_frame(struct ppp *ppp, struct sk_buff *skb) * Update the appropriate statistic counter. */ if (!(*proto_ptr->func)(ppp, skb)) { - kfree_skb(skb); + KFREE_SKB(skb); ++ppp->stats.ppp_discards; } @@ -2138,9 +2427,6 @@ ppp_rcv_rx(struct ppp *ppp, __u16 proto, struct sk_buff *skb) skb_pull(skb, PPP_HDRLEN); /* pull off ppp header */ skb->mac.raw = skb->data; ppp->last_recv = jiffies; -#if LINUX_VERSION_CODE < VERSION(2,1,15) - skb->free = 1; -#endif netif_rx (skb); return 1; } @@ -2158,6 +2444,19 @@ rcv_proto_ip(struct ppp *ppp, struct sk_buff *skb) return 0; } +/* + * Process the receipt of an IPv6 frame + */ +static int +rcv_proto_ipv6(struct ppp *ppp, struct sk_buff *skb) +{ + CHECK_PPP(0); + if ((ppp2dev(ppp)->flags & IFF_UP) && (skb->len > 0) + && ppp->sc_npmode[NP_IPV6] == NPMODE_PASS) + return ppp_rcv_rx(ppp, ETH_P_IPV6, skb); + return 0; +} + /* * Process the receipt of an IPX frame */ @@ -2197,13 +2496,17 @@ rcv_proto_vjc_comp(struct ppp *ppp, struct sk_buff *skb) return 0; new_count = slhc_uncompress(ppp->slcomp, skb->data + PPP_HDRLEN, skb->len - PPP_HDRLEN); - if (new_count < 0) { + if (new_count <= 0) { if (ppp->flags & SC_DEBUG) printk(KERN_NOTICE "ppp: error in VJ decompression\n"); return 0; } - skb_put(skb, new_count + PPP_HDRLEN - skb->len); + new_count += PPP_HDRLEN; + if (new_count > skb->len) + skb_put(skb, new_count - skb->len); + else + skb_trim(skb, new_count); return rcv_proto_ip(ppp, skb); } @@ -2248,7 +2551,7 @@ rcv_proto_unknown(struct ppp *ppp, struct sk_buff *skb) while (ppp->rcv_q.qlen > PPP_MAX_RCV_QLEN) { struct sk_buff *skb = skb_dequeue(&ppp->rcv_q); if (skb) - kfree_skb(skb); + KFREE_SKB(skb); } wake_up_interruptible (&ppp->read_wait); @@ -2345,10 +2648,11 @@ ppp_send_frame(struct ppp *ppp, struct sk_buff *skb) new_skb = alloc_skb(ppp->mtu + PPP_HDRLEN, GFP_ATOMIC); if (new_skb == NULL) { printk(KERN_ERR "ppp_send_frame: no memory\n"); - kfree_skb(skb); + KFREE_SKB(skb); ppp->xmit_busy = 0; return; } + LIBERATE_SKB(new_skb); /* Compress the frame. */ new_count = (*ppp->sc_xcomp->compress) @@ -2358,21 +2662,24 @@ ppp_send_frame(struct ppp *ppp, struct sk_buff *skb) /* Did it compress? */ if (new_count > 0 && (ppp->flags & SC_CCP_UP)) { skb_put(new_skb, new_count); - kfree_skb(skb); + KFREE_SKB(skb); skb = new_skb; } else { /* * The frame could not be compressed, or it could not * be sent in compressed form because CCP is down. */ - kfree_skb(new_skb); + KFREE_SKB(new_skb); } } /* * Send the frame */ - ret = ppp_async_send(ppp, skb); + if ( ppp->flags & SC_SYNC ) + ret = ppp_sync_send(ppp, skb); + else + ret = ppp_async_send(ppp, skb); if (ret > 0) { /* we can release the lock */ ppp->xmit_busy = 0; @@ -2397,6 +2704,7 @@ ppp_vj_compress(struct ppp *ppp, struct sk_buff *skb) printk(KERN_ERR "ppp: no memory for vj compression\n"); return skb; } + LIBERATE_SKB(new_skb); orig_data = data = skb->data + PPP_HDRLEN; len = slhc_compress(ppp->slcomp, data, skb->len - PPP_HDRLEN, @@ -2405,7 +2713,7 @@ ppp_vj_compress(struct ppp *ppp, struct sk_buff *skb) if (data == orig_data) { /* Couldn't compress the data */ - kfree_skb(new_skb); + KFREE_SKB(new_skb); return skb; } @@ -2427,7 +2735,7 @@ ppp_vj_compress(struct ppp *ppp, struct sk_buff *skb) data[2] = 0; data[3] = proto; - kfree_skb(skb); + KFREE_SKB(skb); return new_skb; } @@ -2505,7 +2813,7 @@ ppp_dev_xmit(struct sk_buff *skb, struct device *dev) if (skb == NULL) return 0; if (skb->data == NULL) { - kfree_skb(skb); + KFREE_SKB(skb); return 0; } @@ -2514,7 +2822,7 @@ ppp_dev_xmit(struct sk_buff *skb, struct device *dev) * queued to be sent. */ if (!ppp->inuse) { - dev_kfree_skb(skb); + KFREE_SKB(skb); return 0; } @@ -2526,7 +2834,7 @@ ppp_dev_xmit(struct sk_buff *skb, struct device *dev) printk(KERN_ERR "ppp_dev_xmit: %s not connected to a TTY!\n", dev->name); - dev_kfree_skb(skb); + KFREE_SKB(skb); return 0; } @@ -2539,6 +2847,10 @@ ppp_dev_xmit(struct sk_buff *skb, struct device *dev) proto = PPP_IP; npmode = ppp->sc_npmode[NP_IP]; break; + case ETH_P_IPV6: + proto = PPP_IPV6; + npmode = ppp->sc_npmode[NP_IPV6]; + break; case ETH_P_IPX: proto = PPP_IPX; npmode = ppp->sc_npmode[NP_IPX]; @@ -2552,7 +2864,7 @@ ppp_dev_xmit(struct sk_buff *skb, struct device *dev) if (ppp->flags & SC_DEBUG) printk(KERN_INFO "%s: packet for unknown proto %x\n", ppp->name, ntohs(skb->protocol)); - dev_kfree_skb(skb); + KFREE_SKB(skb); return 0; } @@ -2571,7 +2883,7 @@ ppp_dev_xmit(struct sk_buff *skb, struct device *dev) */ if (ppp->flags & SC_DEBUG) printk(KERN_DEBUG "%s: returning frame\n", ppp->name); - dev_kfree_skb(skb); + KFREE_SKB(skb); return 0; case NPMODE_ERROR: @@ -2580,7 +2892,7 @@ ppp_dev_xmit(struct sk_buff *skb, struct device *dev) printk(KERN_DEBUG "ppp_dev_xmit: dropping (npmode = %d) on %s\n", npmode, ppp->name); - dev_kfree_skb(skb); + KFREE_SKB(skb); return 0; } @@ -2609,14 +2921,15 @@ ppp_dev_xmit(struct sk_buff *skb, struct device *dev) if (new_skb == NULL) { printk(KERN_ERR "%s: skb hdr alloc failed\n", ppp->name); - dev_kfree_skb(skb); + KFREE_SKB(skb); ppp->xmit_busy = 0; ppp_send_frames(ppp); return 0; } + LIBERATE_SKB(new_skb); skb_reserve(new_skb, PPP_HDRLEN); memcpy(skb_put(new_skb, skb->len), skb->data, skb->len); - dev_kfree_skb(skb); + KFREE_SKB(skb); skb = new_skb; } @@ -2738,7 +3051,12 @@ ppp_alloc(void) */ dev = ppp2dev(ppp); dev->name = ppp->name; +#if LINUX_VERSION_CODE < VERSION(2,1,31) + if_num = (ppp_list == 0)? 0: ppp_last->line + 1; + sprintf(ppp->name, "ppp%d", if_num); +#else if_num = dev_alloc_name(dev, "ppp%d"); +#endif if (if_num < 0) { printk(KERN_ERR "ppp: dev_alloc_name failed (%d)\n", if_num); kfree(ppp); @@ -2830,9 +3148,9 @@ ppp_release(struct ppp *ppp) } while ((skb = skb_dequeue(&ppp->rcv_q)) != NULL) - kfree_skb(skb); + KFREE_SKB(skb); while ((skb = skb_dequeue(&ppp->xmt_q)) != NULL) - kfree_skb(skb); + KFREE_SKB(skb); ppp->inuse = 0; if (ppp->dev.tbusy) { @@ -2934,7 +3252,6 @@ static struct compressor *find_compressor (int type) return (struct compressor *) 0; } -#ifdef CONFIG_MODULES static int ppp_register_compressor (struct compressor *cp) { struct compressor_link *new; @@ -2987,7 +3304,6 @@ static void ppp_unregister_compressor (struct compressor *cp) } restore_flags(flags); } -#endif /************************************************************* * Module support routines