730 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * PPP synchronous tty channel driver for Linux.4 *5 * This is a ppp channel driver that can be used with tty device drivers6 * that are frame oriented, such as synchronous HDLC devices.7 *8 * Complete PPP frames without encoding/decoding are exchanged between9 * the channel driver and the device driver.10 *11 * The async map IOCTL codes are implemented to keep the user mode12 * applications happy if they call them. Synchronous PPP does not use13 * the async maps.14 *15 * Copyright 1999 Paul Mackerras.16 *17 * Also touched by the grubby hands of Paul Fulghum paulkf@microgate.com18 *19 * This driver provides the encapsulation and framing for sending20 * and receiving PPP frames over sync serial lines. It relies on21 * the generic PPP layer to give it frames to send and to process22 * received frames. It implements the PPP line discipline.23 *24 * Part of the code in this driver was inspired by the old async-only25 * PPP driver, written by Michael Callahan and Al Longyear, and26 * subsequently hacked by Paul Mackerras.27 *28 * ==FILEVERSION 20040616==29 */30 31#include <linux/module.h>32#include <linux/kernel.h>33#include <linux/skbuff.h>34#include <linux/tty.h>35#include <linux/netdevice.h>36#include <linux/poll.h>37#include <linux/ppp_defs.h>38#include <linux/ppp-ioctl.h>39#include <linux/ppp_channel.h>40#include <linux/spinlock.h>41#include <linux/completion.h>42#include <linux/init.h>43#include <linux/interrupt.h>44#include <linux/slab.h>45#include <linux/refcount.h>46#include <linux/unaligned.h>47#include <linux/uaccess.h>48 49#define PPP_VERSION "2.4.2"50 51/* Structure for storing local state. */52struct syncppp {53 struct tty_struct *tty;54 unsigned int flags;55 unsigned int rbits;56 int mru;57 spinlock_t xmit_lock;58 spinlock_t recv_lock;59 unsigned long xmit_flags;60 u32 xaccm[8];61 u32 raccm;62 unsigned int bytes_sent;63 unsigned int bytes_rcvd;64 65 struct sk_buff *tpkt;66 unsigned long last_xmit;67 68 struct sk_buff_head rqueue;69 70 struct tasklet_struct tsk;71 72 refcount_t refcnt;73 struct completion dead_cmp;74 struct ppp_channel chan; /* interface to generic ppp layer */75};76 77/* Bit numbers in xmit_flags */78#define XMIT_WAKEUP 079#define XMIT_FULL 180 81/* Bits in rbits */82#define SC_RCV_BITS (SC_RCV_B7_1|SC_RCV_B7_0|SC_RCV_ODDP|SC_RCV_EVNP)83 84#define PPPSYNC_MAX_RQLEN 32 /* arbitrary */85 86/*87 * Prototypes.88 */89static struct sk_buff* ppp_sync_txmunge(struct syncppp *ap, struct sk_buff *);90static int ppp_sync_send(struct ppp_channel *chan, struct sk_buff *skb);91static int ppp_sync_ioctl(struct ppp_channel *chan, unsigned int cmd,92 unsigned long arg);93static void ppp_sync_process(struct tasklet_struct *t);94static int ppp_sync_push(struct syncppp *ap);95static void ppp_sync_flush_output(struct syncppp *ap);96static void ppp_sync_input(struct syncppp *ap, const u8 *buf, const u8 *flags,97 int count);98 99static const struct ppp_channel_ops sync_ops = {100 .start_xmit = ppp_sync_send,101 .ioctl = ppp_sync_ioctl,102};103 104/*105 * Utility procedure to print a buffer in hex/ascii106 */107static void108ppp_print_buffer (const char *name, const __u8 *buf, int count)109{110 if (name != NULL)111 printk(KERN_DEBUG "ppp_synctty: %s, count = %d\n", name, count);112 113 print_hex_dump_bytes("", DUMP_PREFIX_NONE, buf, count);114}115 116 117/*118 * Routines implementing the synchronous PPP line discipline.119 */120 121/*122 * We have a potential race on dereferencing tty->disc_data,123 * because the tty layer provides no locking at all - thus one124 * cpu could be running ppp_synctty_receive while another125 * calls ppp_synctty_close, which zeroes tty->disc_data and126 * frees the memory that ppp_synctty_receive is using. The best127 * way to fix this is to use a rwlock in the tty struct, but for now128 * we use a single global rwlock for all ttys in ppp line discipline.129 *130 * FIXME: Fixed in tty_io nowadays.131 */132static DEFINE_RWLOCK(disc_data_lock);133 134static struct syncppp *sp_get(struct tty_struct *tty)135{136 struct syncppp *ap;137 138 read_lock(&disc_data_lock);139 ap = tty->disc_data;140 if (ap != NULL)141 refcount_inc(&ap->refcnt);142 read_unlock(&disc_data_lock);143 return ap;144}145 146static void sp_put(struct syncppp *ap)147{148 if (refcount_dec_and_test(&ap->refcnt))149 complete(&ap->dead_cmp);150}151 152/*153 * Called when a tty is put into sync-PPP line discipline.154 */155static int156ppp_sync_open(struct tty_struct *tty)157{158 struct syncppp *ap;159 int err;160 int speed;161 162 if (tty->ops->write == NULL)163 return -EOPNOTSUPP;164 165 ap = kzalloc(sizeof(*ap), GFP_KERNEL);166 err = -ENOMEM;167 if (!ap)168 goto out;169 170 /* initialize the syncppp structure */171 ap->tty = tty;172 ap->mru = PPP_MRU;173 spin_lock_init(&ap->xmit_lock);174 spin_lock_init(&ap->recv_lock);175 ap->xaccm[0] = ~0U;176 ap->xaccm[3] = 0x60000000U;177 ap->raccm = ~0U;178 179 skb_queue_head_init(&ap->rqueue);180 tasklet_setup(&ap->tsk, ppp_sync_process);181 182 refcount_set(&ap->refcnt, 1);183 init_completion(&ap->dead_cmp);184 185 ap->chan.private = ap;186 ap->chan.ops = &sync_ops;187 ap->chan.mtu = PPP_MRU;188 ap->chan.hdrlen = 2; /* for A/C bytes */189 speed = tty_get_baud_rate(tty);190 ap->chan.speed = speed;191 err = ppp_register_channel(&ap->chan);192 if (err)193 goto out_free;194 195 tty->disc_data = ap;196 tty->receive_room = 65536;197 return 0;198 199 out_free:200 kfree(ap);201 out:202 return err;203}204 205/*206 * Called when the tty is put into another line discipline207 * or it hangs up. We have to wait for any cpu currently208 * executing in any of the other ppp_synctty_* routines to209 * finish before we can call ppp_unregister_channel and free210 * the syncppp struct. This routine must be called from211 * process context, not interrupt or softirq context.212 */213static void214ppp_sync_close(struct tty_struct *tty)215{216 struct syncppp *ap;217 218 write_lock_irq(&disc_data_lock);219 ap = tty->disc_data;220 tty->disc_data = NULL;221 write_unlock_irq(&disc_data_lock);222 if (!ap)223 return;224 225 /*226 * We have now ensured that nobody can start using ap from now227 * on, but we have to wait for all existing users to finish.228 * Note that ppp_unregister_channel ensures that no calls to229 * our channel ops (i.e. ppp_sync_send/ioctl) are in progress230 * by the time it returns.231 */232 if (!refcount_dec_and_test(&ap->refcnt))233 wait_for_completion(&ap->dead_cmp);234 tasklet_kill(&ap->tsk);235 236 ppp_unregister_channel(&ap->chan);237 skb_queue_purge(&ap->rqueue);238 kfree_skb(ap->tpkt);239 kfree(ap);240}241 242/*243 * Called on tty hangup in process context.244 *245 * Wait for I/O to driver to complete and unregister PPP channel.246 * This is already done by the close routine, so just call that.247 */248static void ppp_sync_hangup(struct tty_struct *tty)249{250 ppp_sync_close(tty);251}252 253/*254 * Read does nothing - no data is ever available this way.255 * Pppd reads and writes packets via /dev/ppp instead.256 */257static ssize_t258ppp_sync_read(struct tty_struct *tty, struct file *file, u8 *buf, size_t count,259 void **cookie, unsigned long offset)260{261 return -EAGAIN;262}263 264/*265 * Write on the tty does nothing, the packets all come in266 * from the ppp generic stuff.267 */268static ssize_t269ppp_sync_write(struct tty_struct *tty, struct file *file, const u8 *buf,270 size_t count)271{272 return -EAGAIN;273}274 275static int276ppp_synctty_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg)277{278 struct syncppp *ap = sp_get(tty);279 int __user *p = (int __user *)arg;280 int err, val;281 282 if (!ap)283 return -ENXIO;284 err = -EFAULT;285 switch (cmd) {286 case PPPIOCGCHAN:287 err = -EFAULT;288 if (put_user(ppp_channel_index(&ap->chan), p))289 break;290 err = 0;291 break;292 293 case PPPIOCGUNIT:294 err = -EFAULT;295 if (put_user(ppp_unit_number(&ap->chan), p))296 break;297 err = 0;298 break;299 300 case TCFLSH:301 /* flush our buffers and the serial port's buffer */302 if (arg == TCIOFLUSH || arg == TCOFLUSH)303 ppp_sync_flush_output(ap);304 err = n_tty_ioctl_helper(tty, cmd, arg);305 break;306 307 case FIONREAD:308 val = 0;309 if (put_user(val, p))310 break;311 err = 0;312 break;313 314 default:315 err = tty_mode_ioctl(tty, cmd, arg);316 break;317 }318 319 sp_put(ap);320 return err;321}322 323/* May sleep, don't call from interrupt level or with interrupts disabled */324static void325ppp_sync_receive(struct tty_struct *tty, const u8 *buf, const u8 *cflags,326 size_t count)327{328 struct syncppp *ap = sp_get(tty);329 unsigned long flags;330 331 if (!ap)332 return;333 spin_lock_irqsave(&ap->recv_lock, flags);334 ppp_sync_input(ap, buf, cflags, count);335 spin_unlock_irqrestore(&ap->recv_lock, flags);336 if (!skb_queue_empty(&ap->rqueue))337 tasklet_schedule(&ap->tsk);338 sp_put(ap);339 tty_unthrottle(tty);340}341 342static void343ppp_sync_wakeup(struct tty_struct *tty)344{345 struct syncppp *ap = sp_get(tty);346 347 clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);348 if (!ap)349 return;350 set_bit(XMIT_WAKEUP, &ap->xmit_flags);351 tasklet_schedule(&ap->tsk);352 sp_put(ap);353}354 355 356static struct tty_ldisc_ops ppp_sync_ldisc = {357 .owner = THIS_MODULE,358 .num = N_SYNC_PPP,359 .name = "pppsync",360 .open = ppp_sync_open,361 .close = ppp_sync_close,362 .hangup = ppp_sync_hangup,363 .read = ppp_sync_read,364 .write = ppp_sync_write,365 .ioctl = ppp_synctty_ioctl,366 .receive_buf = ppp_sync_receive,367 .write_wakeup = ppp_sync_wakeup,368};369 370static int __init371ppp_sync_init(void)372{373 int err;374 375 err = tty_register_ldisc(&ppp_sync_ldisc);376 if (err != 0)377 printk(KERN_ERR "PPP_sync: error %d registering line disc.\n",378 err);379 return err;380}381 382/*383 * The following routines provide the PPP channel interface.384 */385static int386ppp_sync_ioctl(struct ppp_channel *chan, unsigned int cmd, unsigned long arg)387{388 struct syncppp *ap = chan->private;389 int err, val;390 u32 accm[8];391 void __user *argp = (void __user *)arg;392 u32 __user *p = argp;393 394 err = -EFAULT;395 switch (cmd) {396 case PPPIOCGFLAGS:397 val = ap->flags | ap->rbits;398 if (put_user(val, (int __user *) argp))399 break;400 err = 0;401 break;402 case PPPIOCSFLAGS:403 if (get_user(val, (int __user *) argp))404 break;405 ap->flags = val & ~SC_RCV_BITS;406 spin_lock_irq(&ap->recv_lock);407 ap->rbits = val & SC_RCV_BITS;408 spin_unlock_irq(&ap->recv_lock);409 err = 0;410 break;411 412 case PPPIOCGASYNCMAP:413 if (put_user(ap->xaccm[0], p))414 break;415 err = 0;416 break;417 case PPPIOCSASYNCMAP:418 if (get_user(ap->xaccm[0], p))419 break;420 err = 0;421 break;422 423 case PPPIOCGRASYNCMAP:424 if (put_user(ap->raccm, p))425 break;426 err = 0;427 break;428 case PPPIOCSRASYNCMAP:429 if (get_user(ap->raccm, p))430 break;431 err = 0;432 break;433 434 case PPPIOCGXASYNCMAP:435 if (copy_to_user(argp, ap->xaccm, sizeof(ap->xaccm)))436 break;437 err = 0;438 break;439 case PPPIOCSXASYNCMAP:440 if (copy_from_user(accm, argp, sizeof(accm)))441 break;442 accm[2] &= ~0x40000000U; /* can't escape 0x5e */443 accm[3] |= 0x60000000U; /* must escape 0x7d, 0x7e */444 memcpy(ap->xaccm, accm, sizeof(ap->xaccm));445 err = 0;446 break;447 448 case PPPIOCGMRU:449 if (put_user(ap->mru, (int __user *) argp))450 break;451 err = 0;452 break;453 case PPPIOCSMRU:454 if (get_user(val, (int __user *) argp))455 break;456 if (val > U16_MAX) {457 err = -EINVAL;458 break;459 }460 if (val < PPP_MRU)461 val = PPP_MRU;462 ap->mru = val;463 err = 0;464 break;465 466 default:467 err = -ENOTTY;468 }469 return err;470}471 472/*473 * This is called at softirq level to deliver received packets474 * to the ppp_generic code, and to tell the ppp_generic code475 * if we can accept more output now.476 */477static void ppp_sync_process(struct tasklet_struct *t)478{479 struct syncppp *ap = from_tasklet(ap, t, tsk);480 struct sk_buff *skb;481 482 /* process received packets */483 while ((skb = skb_dequeue(&ap->rqueue)) != NULL) {484 if (skb->len == 0) {485 /* zero length buffers indicate error */486 ppp_input_error(&ap->chan, 0);487 kfree_skb(skb);488 }489 else490 ppp_input(&ap->chan, skb);491 }492 493 /* try to push more stuff out */494 if (test_bit(XMIT_WAKEUP, &ap->xmit_flags) && ppp_sync_push(ap))495 ppp_output_wakeup(&ap->chan);496}497 498/*499 * Procedures for encapsulation and framing.500 */501 502static struct sk_buff*503ppp_sync_txmunge(struct syncppp *ap, struct sk_buff *skb)504{505 int proto;506 unsigned char *data;507 int islcp;508 509 data = skb->data;510 proto = get_unaligned_be16(data);511 512 /* LCP packets with codes between 1 (configure-request)513 * and 7 (code-reject) must be sent as though no options514 * have been negotiated.515 */516 islcp = proto == PPP_LCP && 1 <= data[2] && data[2] <= 7;517 518 /* compress protocol field if option enabled */519 if (data[0] == 0 && (ap->flags & SC_COMP_PROT) && !islcp)520 skb_pull(skb,1);521 522 /* prepend address/control fields if necessary */523 if ((ap->flags & SC_COMP_AC) == 0 || islcp) {524 if (skb_headroom(skb) < 2) {525 struct sk_buff *npkt = dev_alloc_skb(skb->len + 2);526 if (npkt == NULL) {527 kfree_skb(skb);528 return NULL;529 }530 skb_reserve(npkt,2);531 skb_copy_from_linear_data(skb,532 skb_put(npkt, skb->len), skb->len);533 consume_skb(skb);534 skb = npkt;535 }536 skb_push(skb,2);537 skb->data[0] = PPP_ALLSTATIONS;538 skb->data[1] = PPP_UI;539 }540 541 ap->last_xmit = jiffies;542 543 if (skb && ap->flags & SC_LOG_OUTPKT)544 ppp_print_buffer ("send buffer", skb->data, skb->len);545 546 return skb;547}548 549/*550 * Transmit-side routines.551 */552 553/*554 * Send a packet to the peer over an sync tty line.555 * Returns 1 iff the packet was accepted.556 * If the packet was not accepted, we will call ppp_output_wakeup557 * at some later time.558 */559static int560ppp_sync_send(struct ppp_channel *chan, struct sk_buff *skb)561{562 struct syncppp *ap = chan->private;563 564 ppp_sync_push(ap);565 566 if (test_and_set_bit(XMIT_FULL, &ap->xmit_flags))567 return 0; /* already full */568 skb = ppp_sync_txmunge(ap, skb);569 if (skb != NULL)570 ap->tpkt = skb;571 else572 clear_bit(XMIT_FULL, &ap->xmit_flags);573 574 ppp_sync_push(ap);575 return 1;576}577 578/*579 * Push as much data as possible out to the tty.580 */581static int582ppp_sync_push(struct syncppp *ap)583{584 int sent, done = 0;585 struct tty_struct *tty = ap->tty;586 int tty_stuffed = 0;587 588 if (!spin_trylock_bh(&ap->xmit_lock))589 return 0;590 for (;;) {591 if (test_and_clear_bit(XMIT_WAKEUP, &ap->xmit_flags))592 tty_stuffed = 0;593 if (!tty_stuffed && ap->tpkt) {594 set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);595 sent = tty->ops->write(tty, ap->tpkt->data, ap->tpkt->len);596 if (sent < 0)597 goto flush; /* error, e.g. loss of CD */598 if (sent < ap->tpkt->len) {599 tty_stuffed = 1;600 } else {601 consume_skb(ap->tpkt);602 ap->tpkt = NULL;603 clear_bit(XMIT_FULL, &ap->xmit_flags);604 done = 1;605 }606 continue;607 }608 /* haven't made any progress */609 spin_unlock_bh(&ap->xmit_lock);610 if (!(test_bit(XMIT_WAKEUP, &ap->xmit_flags) ||611 (!tty_stuffed && ap->tpkt)))612 break;613 if (!spin_trylock_bh(&ap->xmit_lock))614 break;615 }616 return done;617 618flush:619 if (ap->tpkt) {620 kfree_skb(ap->tpkt);621 ap->tpkt = NULL;622 clear_bit(XMIT_FULL, &ap->xmit_flags);623 done = 1;624 }625 spin_unlock_bh(&ap->xmit_lock);626 return done;627}628 629/*630 * Flush output from our internal buffers.631 * Called for the TCFLSH ioctl.632 */633static void634ppp_sync_flush_output(struct syncppp *ap)635{636 int done = 0;637 638 spin_lock_bh(&ap->xmit_lock);639 if (ap->tpkt != NULL) {640 kfree_skb(ap->tpkt);641 ap->tpkt = NULL;642 clear_bit(XMIT_FULL, &ap->xmit_flags);643 done = 1;644 }645 spin_unlock_bh(&ap->xmit_lock);646 if (done)647 ppp_output_wakeup(&ap->chan);648}649 650/*651 * Receive-side routines.652 */653 654/* called when the tty driver has data for us.655 *656 * Data is frame oriented: each call to ppp_sync_input is considered657 * a whole frame. If the 1st flag byte is non-zero then the whole658 * frame is considered to be in error and is tossed.659 */660static void661ppp_sync_input(struct syncppp *ap, const u8 *buf, const u8 *flags, int count)662{663 struct sk_buff *skb;664 unsigned char *p;665 666 if (count == 0)667 return;668 669 if (ap->flags & SC_LOG_INPKT)670 ppp_print_buffer ("receive buffer", buf, count);671 672 /* stuff the chars in the skb */673 skb = dev_alloc_skb(ap->mru + PPP_HDRLEN + 2);674 if (!skb) {675 printk(KERN_ERR "PPPsync: no memory (input pkt)\n");676 goto err;677 }678 /* Try to get the payload 4-byte aligned */679 if (buf[0] != PPP_ALLSTATIONS)680 skb_reserve(skb, 2 + (buf[0] & 1));681 682 if (flags && *flags) {683 /* error flag set, ignore frame */684 goto err;685 } else if (count > skb_tailroom(skb)) {686 /* packet overflowed MRU */687 goto err;688 }689 690 skb_put_data(skb, buf, count);691 692 /* strip address/control field if present */693 p = skb->data;694 if (skb->len >= 2 && p[0] == PPP_ALLSTATIONS && p[1] == PPP_UI) {695 /* chop off address/control */696 if (skb->len < 3)697 goto err;698 p = skb_pull(skb, 2);699 }700 701 /* PPP packet length should be >= 2 bytes when protocol field is not702 * compressed.703 */704 if (!(p[0] & 0x01) && skb->len < 2)705 goto err;706 707 /* queue the frame to be processed */708 skb_queue_tail(&ap->rqueue, skb);709 return;710 711err:712 /* queue zero length packet as error indication */713 if (skb || (skb = dev_alloc_skb(0))) {714 skb_trim(skb, 0);715 skb_queue_tail(&ap->rqueue, skb);716 }717}718 719static void __exit720ppp_sync_cleanup(void)721{722 tty_unregister_ldisc(&ppp_sync_ldisc);723}724 725module_init(ppp_sync_init);726module_exit(ppp_sync_cleanup);727MODULE_DESCRIPTION("PPP synchronous TTY channel module");728MODULE_LICENSE("GPL");729MODULE_ALIAS_LDISC(N_SYNC_PPP);730