^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Generic PPP layer for Linux.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright 1999-2002 Paul Mackerras.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * The generic PPP layer handles the PPP network interfaces, the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * /dev/ppp device, packet and VJ compression, and multilink.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * It talks to PPP `channels' via the interface defined in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * include/linux/ppp_channel.h. Channels provide the basic means for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * sending and receiving PPP frames on some kind of communications
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * channel.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * Part of the code in this driver was inspired by the old async-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * PPP driver, written by Michael Callahan and Al Longyear, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * subsequently hacked by Paul Mackerras.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * ==FILEVERSION 20041108==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/sched/signal.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/kmod.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/list.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/idr.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/netdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/poll.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/ppp_defs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/filter.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <linux/ppp-ioctl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <linux/ppp_channel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <linux/ppp-comp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <linux/skbuff.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include <linux/rtnetlink.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include <linux/if_arp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include <linux/ip.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include <linux/tcp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #include <linux/rwsem.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #include <linux/stddef.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #include <linux/file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #include <asm/unaligned.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #include <net/slhc_vj.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #include <linux/atomic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #include <linux/refcount.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #include <linux/nsproxy.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #include <net/net_namespace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #include <net/netns/generic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define PPP_VERSION "2.4.2"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) * Network protocols we support.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define NP_IP 0 /* Internet Protocol V4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define NP_IPV6 1 /* Internet Protocol V6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define NP_IPX 2 /* IPX protocol */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define NP_AT 3 /* Appletalk protocol */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define NP_MPLS_UC 4 /* MPLS unicast */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define NP_MPLS_MC 5 /* MPLS multicast */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define NUM_NP 6 /* Number of NPs. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define MPHDRLEN 6 /* multilink protocol header length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define MPHDRLEN_SSN 4 /* ditto with short sequence numbers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define PPP_PROTO_LEN 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) * An instance of /dev/ppp can be associated with either a ppp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) * interface unit or a ppp channel. In both cases, file->private_data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) * points to one of these.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) struct ppp_file {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) INTERFACE=1, CHANNEL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) } kind;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) struct sk_buff_head xq; /* pppd transmit queue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) struct sk_buff_head rq; /* receive queue for pppd */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) wait_queue_head_t rwait; /* for poll on reading /dev/ppp */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) refcount_t refcnt; /* # refs (incl /dev/ppp attached) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) int hdrlen; /* space to leave for headers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) int index; /* interface unit / channel number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) int dead; /* unit/channel has been shut down */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) #define PF_TO_X(pf, X) container_of(pf, X, file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) #define PF_TO_PPP(pf) PF_TO_X(pf, struct ppp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) #define PF_TO_CHANNEL(pf) PF_TO_X(pf, struct channel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) * Data structure to hold primary network stats for which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) * we want to use 64 bit storage. Other network stats
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) * are stored in dev->stats of the ppp strucute.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) struct ppp_link_stats {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) u64 rx_packets;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) u64 tx_packets;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) u64 rx_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) u64 tx_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) * Data structure describing one ppp unit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) * A ppp unit corresponds to a ppp network interface device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) * and represents a multilink bundle.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) * It can have 0 or more ppp channels connected to it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) struct ppp {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) struct ppp_file file; /* stuff for read/write/poll 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) struct file *owner; /* file that owns this unit 48 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) struct list_head channels; /* list of attached channels 4c */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) int n_channels; /* how many channels are attached 54 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) spinlock_t rlock; /* lock for receive side 58 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) spinlock_t wlock; /* lock for transmit side 5c */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) int __percpu *xmit_recursion; /* xmit recursion detect */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) int mru; /* max receive unit 60 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) unsigned int flags; /* control bits 64 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) unsigned int xstate; /* transmit state bits 68 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) unsigned int rstate; /* receive state bits 6c */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) int debug; /* debug flags 70 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) struct slcompress *vj; /* state for VJ header compression */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) enum NPmode npmode[NUM_NP]; /* what to do with each net proto 78 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) struct sk_buff *xmit_pending; /* a packet ready to go out 88 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) struct compressor *xcomp; /* transmit packet compressor 8c */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) void *xc_state; /* its internal state 90 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) struct compressor *rcomp; /* receive decompressor 94 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) void *rc_state; /* its internal state 98 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) unsigned long last_xmit; /* jiffies when last pkt sent 9c */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) unsigned long last_recv; /* jiffies when last pkt rcvd a0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) struct net_device *dev; /* network interface device a4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) int closing; /* is device closing down? a8 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) #ifdef CONFIG_PPP_MULTILINK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) int nxchan; /* next channel to send something on */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) u32 nxseq; /* next sequence number to send */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) int mrru; /* MP: max reconst. receive unit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) u32 nextseq; /* MP: seq no of next packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) u32 minseq; /* MP: min of most recent seqnos */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) struct sk_buff_head mrq; /* MP: receive reconstruction queue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) #endif /* CONFIG_PPP_MULTILINK */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) #ifdef CONFIG_PPP_FILTER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) struct bpf_prog *pass_filter; /* filter for packets to pass */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) struct bpf_prog *active_filter; /* filter for pkts to reset idle */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) #endif /* CONFIG_PPP_FILTER */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) struct net *ppp_net; /* the net we belong to */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) struct ppp_link_stats stats64; /* 64 bit network stats */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) * Bits in flags: SC_NO_TCP_CCID, SC_CCP_OPEN, SC_CCP_UP, SC_LOOP_TRAFFIC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) * SC_MULTILINK, SC_MP_SHORTSEQ, SC_MP_XSHORTSEQ, SC_COMP_TCP, SC_REJ_COMP_TCP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) * SC_MUST_COMP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) * Bits in rstate: SC_DECOMP_RUN, SC_DC_ERROR, SC_DC_FERROR.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) * Bits in xstate: SC_COMP_RUN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) #define SC_FLAG_BITS (SC_NO_TCP_CCID|SC_CCP_OPEN|SC_CCP_UP|SC_LOOP_TRAFFIC \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) |SC_MULTILINK|SC_MP_SHORTSEQ|SC_MP_XSHORTSEQ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) |SC_COMP_TCP|SC_REJ_COMP_TCP|SC_MUST_COMP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) * Private data structure for each channel.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) * This includes the data structure used for multilink.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) struct channel {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) struct ppp_file file; /* stuff for read/write/poll */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) struct list_head list; /* link in all/new_channels list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) struct ppp_channel *chan; /* public channel data structure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) struct rw_semaphore chan_sem; /* protects `chan' during chan ioctl */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) spinlock_t downl; /* protects `chan', file.xq dequeue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) struct ppp *ppp; /* ppp unit we're connected to */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) struct net *chan_net; /* the net channel belongs to */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) struct list_head clist; /* link in list of channels per unit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) rwlock_t upl; /* protects `ppp' */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) #ifdef CONFIG_PPP_MULTILINK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) u8 avail; /* flag used in multilink stuff */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) u8 had_frag; /* >= 1 fragments have been sent */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) u32 lastseq; /* MP: last sequence # received */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) int speed; /* speed of the corresponding ppp channel*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) #endif /* CONFIG_PPP_MULTILINK */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) struct ppp_config {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) struct file *file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) s32 unit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) bool ifname_is_set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) * SMP locking issues:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) * Both the ppp.rlock and ppp.wlock locks protect the ppp.channels
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) * list and the ppp.n_channels field, you need to take both locks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) * before you modify them.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) * The lock ordering is: channel.upl -> ppp.wlock -> ppp.rlock ->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) * channel.downl.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) static DEFINE_MUTEX(ppp_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) static atomic_t ppp_unit_count = ATOMIC_INIT(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) static atomic_t channel_count = ATOMIC_INIT(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) /* per-net private data for this module */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) static unsigned int ppp_net_id __read_mostly;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) struct ppp_net {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) /* units to ppp mapping */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) struct idr units_idr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) * all_ppp_mutex protects the units_idr mapping.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) * It also ensures that finding a ppp unit in the units_idr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) * map and updating its file.refcnt field is atomic.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) struct mutex all_ppp_mutex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) /* channels */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) struct list_head all_channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) struct list_head new_channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) int last_channel_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) * all_channels_lock protects all_channels and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) * last_channel_index, and the atomicity of find
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) * a channel and updating its file.refcnt field.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) spinlock_t all_channels_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) /* Get the PPP protocol number from a skb */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) #define PPP_PROTO(skb) get_unaligned_be16((skb)->data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) /* We limit the length of ppp->file.rq to this (arbitrary) value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) #define PPP_MAX_RQLEN 32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) * Maximum number of multilink fragments queued up.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) * This has to be large enough to cope with the maximum latency of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) * the slowest channel relative to the others. Strictly it should
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) * depend on the number of channels and their characteristics.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) #define PPP_MP_MAX_QLEN 128
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) /* Multilink header bits. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) #define B 0x80 /* this fragment begins a packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) #define E 0x40 /* this fragment ends a packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) /* Compare multilink sequence numbers (assumed to be 32 bits wide) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) #define seq_before(a, b) ((s32)((a) - (b)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) #define seq_after(a, b) ((s32)((a) - (b)) > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) /* Prototypes. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) static int ppp_unattached_ioctl(struct net *net, struct ppp_file *pf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) struct file *file, unsigned int cmd, unsigned long arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) static void ppp_xmit_process(struct ppp *ppp, struct sk_buff *skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) static void ppp_send_frame(struct ppp *ppp, struct sk_buff *skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) static void ppp_push(struct ppp *ppp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) static void ppp_channel_push(struct channel *pch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) static void ppp_receive_frame(struct ppp *ppp, struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) struct channel *pch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) static void ppp_receive_error(struct ppp *ppp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) static void ppp_receive_nonmp_frame(struct ppp *ppp, struct sk_buff *skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) static struct sk_buff *ppp_decompress_frame(struct ppp *ppp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) struct sk_buff *skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) #ifdef CONFIG_PPP_MULTILINK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) static void ppp_receive_mp_frame(struct ppp *ppp, struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) struct channel *pch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) static void ppp_mp_insert(struct ppp *ppp, struct sk_buff *skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) static struct sk_buff *ppp_mp_reconstruct(struct ppp *ppp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) static int ppp_mp_explode(struct ppp *ppp, struct sk_buff *skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) #endif /* CONFIG_PPP_MULTILINK */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) static int ppp_set_compress(struct ppp *ppp, struct ppp_option_data *data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) static void ppp_ccp_peek(struct ppp *ppp, struct sk_buff *skb, int inbound);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) static void ppp_ccp_closed(struct ppp *ppp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) static struct compressor *find_compressor(int type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) static void ppp_get_stats(struct ppp *ppp, struct ppp_stats *st);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) static int ppp_create_interface(struct net *net, struct file *file, int *unit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) static void init_ppp_file(struct ppp_file *pf, int kind);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) static void ppp_destroy_interface(struct ppp *ppp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) static struct ppp *ppp_find_unit(struct ppp_net *pn, int unit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) static struct channel *ppp_find_channel(struct ppp_net *pn, int unit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) static int ppp_connect_channel(struct channel *pch, int unit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) static int ppp_disconnect_channel(struct channel *pch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) static void ppp_destroy_channel(struct channel *pch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) static int unit_get(struct idr *p, void *ptr, int min);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) static int unit_set(struct idr *p, void *ptr, int n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) static void unit_put(struct idr *p, int n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) static void *unit_find(struct idr *p, int n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) static void ppp_setup(struct net_device *dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) static const struct net_device_ops ppp_netdev_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) static struct class *ppp_class;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) /* per net-namespace data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) static inline struct ppp_net *ppp_pernet(struct net *net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) return net_generic(net, ppp_net_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) /* Translates a PPP protocol number to a NP index (NP == network protocol) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) static inline int proto_to_npindex(int proto)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) switch (proto) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) case PPP_IP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) return NP_IP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) case PPP_IPV6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) return NP_IPV6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) case PPP_IPX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) return NP_IPX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) case PPP_AT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) return NP_AT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) case PPP_MPLS_UC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) return NP_MPLS_UC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) case PPP_MPLS_MC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) return NP_MPLS_MC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) /* Translates an NP index into a PPP protocol number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) static const int npindex_to_proto[NUM_NP] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) PPP_IP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) PPP_IPV6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) PPP_IPX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) PPP_AT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) PPP_MPLS_UC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) PPP_MPLS_MC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) /* Translates an ethertype into an NP index */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) static inline int ethertype_to_npindex(int ethertype)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) switch (ethertype) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) case ETH_P_IP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) return NP_IP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) case ETH_P_IPV6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) return NP_IPV6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) case ETH_P_IPX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) return NP_IPX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) case ETH_P_PPPTALK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) case ETH_P_ATALK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) return NP_AT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) case ETH_P_MPLS_UC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) return NP_MPLS_UC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) case ETH_P_MPLS_MC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) return NP_MPLS_MC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) /* Translates an NP index into an ethertype */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) static const int npindex_to_ethertype[NUM_NP] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) ETH_P_IP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) ETH_P_IPV6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) ETH_P_IPX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) ETH_P_PPPTALK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) ETH_P_MPLS_UC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) ETH_P_MPLS_MC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) * Locking shorthand.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) #define ppp_xmit_lock(ppp) spin_lock_bh(&(ppp)->wlock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) #define ppp_xmit_unlock(ppp) spin_unlock_bh(&(ppp)->wlock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) #define ppp_recv_lock(ppp) spin_lock_bh(&(ppp)->rlock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) #define ppp_recv_unlock(ppp) spin_unlock_bh(&(ppp)->rlock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) #define ppp_lock(ppp) do { ppp_xmit_lock(ppp); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) ppp_recv_lock(ppp); } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) #define ppp_unlock(ppp) do { ppp_recv_unlock(ppp); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) ppp_xmit_unlock(ppp); } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) * /dev/ppp device routines.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) * The /dev/ppp device is used by pppd to control the ppp unit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) * It supports the read, write, ioctl and poll functions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) * Open instances of /dev/ppp can be in one of three states:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) * unattached, attached to a ppp unit, or attached to a ppp channel.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) static int ppp_open(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) * This could (should?) be enforced by the permissions on /dev/ppp.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) if (!ns_capable(file->f_cred->user_ns, CAP_NET_ADMIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) static int ppp_release(struct inode *unused, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) struct ppp_file *pf = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) struct ppp *ppp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) if (pf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) file->private_data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) if (pf->kind == INTERFACE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) ppp = PF_TO_PPP(pf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) rtnl_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) if (file == ppp->owner)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) unregister_netdevice(ppp->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) rtnl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) if (refcount_dec_and_test(&pf->refcnt)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) switch (pf->kind) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) case INTERFACE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) ppp_destroy_interface(PF_TO_PPP(pf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) case CHANNEL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) ppp_destroy_channel(PF_TO_CHANNEL(pf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) static ssize_t ppp_read(struct file *file, char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) struct ppp_file *pf = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) DECLARE_WAITQUEUE(wait, current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) ssize_t ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) struct sk_buff *skb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) struct iovec iov;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) struct iov_iter to;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) ret = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) if (!pf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) add_wait_queue(&pf->rwait, &wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) set_current_state(TASK_INTERRUPTIBLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) skb = skb_dequeue(&pf->rq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) if (skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) if (pf->dead)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) if (pf->kind == INTERFACE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) * Return 0 (EOF) on an interface that has no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) * channels connected, unless it is looping
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) * network traffic (demand mode).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) struct ppp *ppp = PF_TO_PPP(pf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) ppp_recv_lock(ppp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) if (ppp->n_channels == 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) (ppp->flags & SC_LOOP_TRAFFIC) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) ppp_recv_unlock(ppp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) ppp_recv_unlock(ppp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) ret = -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) if (file->f_flags & O_NONBLOCK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) ret = -ERESTARTSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) if (signal_pending(current))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) schedule();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) set_current_state(TASK_RUNNING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) remove_wait_queue(&pf->rwait, &wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) ret = -EOVERFLOW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) if (skb->len > count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) goto outf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) ret = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) iov.iov_base = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) iov.iov_len = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) iov_iter_init(&to, READ, &iov, 1, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) if (skb_copy_datagram_iter(skb, 0, &to, skb->len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) goto outf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) ret = skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) outf:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) static ssize_t ppp_write(struct file *file, const char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) struct ppp_file *pf = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) ssize_t ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) if (!pf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) /* All PPP packets should start with the 2-byte protocol */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) if (count < PPP_PROTO_LEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) skb = alloc_skb(count + pf->hdrlen, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) skb_reserve(skb, pf->hdrlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) ret = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) if (copy_from_user(skb_put(skb, count), buf, count)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) switch (pf->kind) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) case INTERFACE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) ppp_xmit_process(PF_TO_PPP(pf), skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) case CHANNEL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) skb_queue_tail(&pf->xq, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) ppp_channel_push(PF_TO_CHANNEL(pf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) ret = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) /* No kernel lock - fine */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) static __poll_t ppp_poll(struct file *file, poll_table *wait)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) struct ppp_file *pf = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) __poll_t mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) if (!pf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) poll_wait(file, &pf->rwait, wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) mask = EPOLLOUT | EPOLLWRNORM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) if (skb_peek(&pf->rq))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) mask |= EPOLLIN | EPOLLRDNORM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) if (pf->dead)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) mask |= EPOLLHUP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) else if (pf->kind == INTERFACE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) /* see comment in ppp_read */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) struct ppp *ppp = PF_TO_PPP(pf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) ppp_recv_lock(ppp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) if (ppp->n_channels == 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) (ppp->flags & SC_LOOP_TRAFFIC) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) mask |= EPOLLIN | EPOLLRDNORM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) ppp_recv_unlock(ppp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) return mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) #ifdef CONFIG_PPP_FILTER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) static struct bpf_prog *get_filter(struct sock_fprog *uprog)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) struct sock_fprog_kern fprog;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) struct bpf_prog *res = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) if (!uprog->len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) /* uprog->len is unsigned short, so no overflow here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) fprog.len = uprog->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) fprog.filter = memdup_user(uprog->filter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) uprog->len * sizeof(struct sock_filter));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) if (IS_ERR(fprog.filter))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) return ERR_CAST(fprog.filter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) err = bpf_prog_create(&res, &fprog);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) kfree(fprog.filter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) return err ? ERR_PTR(err) : res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) static struct bpf_prog *ppp_get_filter(struct sock_fprog __user *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) struct sock_fprog uprog;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) if (copy_from_user(&uprog, p, sizeof(struct sock_fprog)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) return ERR_PTR(-EFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) return get_filter(&uprog);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) #ifdef CONFIG_COMPAT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) struct sock_fprog32 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) unsigned short len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) compat_caddr_t filter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) #define PPPIOCSPASS32 _IOW('t', 71, struct sock_fprog32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) #define PPPIOCSACTIVE32 _IOW('t', 70, struct sock_fprog32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) static struct bpf_prog *compat_ppp_get_filter(struct sock_fprog32 __user *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) struct sock_fprog32 uprog32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) struct sock_fprog uprog;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) if (copy_from_user(&uprog32, p, sizeof(struct sock_fprog32)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) return ERR_PTR(-EFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) uprog.len = uprog32.len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) uprog.filter = compat_ptr(uprog32.filter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) return get_filter(&uprog);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) static long ppp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) struct ppp_file *pf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) struct ppp *ppp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) int err = -EFAULT, val, val2, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) struct ppp_idle32 idle32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) struct ppp_idle64 idle64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) struct npioctl npi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) int unit, cflags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) struct slcompress *vj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) void __user *argp = (void __user *)arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) int __user *p = argp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) mutex_lock(&ppp_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) pf = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) if (!pf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) err = ppp_unattached_ioctl(current->nsproxy->net_ns,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) pf, file, cmd, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) if (cmd == PPPIOCDETACH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) * PPPIOCDETACH is no longer supported as it was heavily broken,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) * and is only known to have been used by pppd older than
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) * ppp-2.4.2 (released November 2003).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) pr_warn_once("%s (%d) used obsolete PPPIOCDETACH ioctl\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) current->comm, current->pid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) if (pf->kind == CHANNEL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) struct channel *pch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) struct ppp_channel *chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) pch = PF_TO_CHANNEL(pf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) case PPPIOCCONNECT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) if (get_user(unit, p))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) err = ppp_connect_channel(pch, unit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) case PPPIOCDISCONN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) err = ppp_disconnect_channel(pch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) down_read(&pch->chan_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) chan = pch->chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) err = -ENOTTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) if (chan && chan->ops->ioctl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) err = chan->ops->ioctl(chan, cmd, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) up_read(&pch->chan_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) if (pf->kind != INTERFACE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) /* can't happen */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) pr_err("PPP: not interface or channel??\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) ppp = PF_TO_PPP(pf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) case PPPIOCSMRU:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) if (get_user(val, p))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) ppp->mru = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) case PPPIOCSFLAGS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) if (get_user(val, p))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) ppp_lock(ppp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) cflags = ppp->flags & ~val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) #ifdef CONFIG_PPP_MULTILINK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) if (!(ppp->flags & SC_MULTILINK) && (val & SC_MULTILINK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) ppp->nextseq = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) ppp->flags = val & SC_FLAG_BITS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) ppp_unlock(ppp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) if (cflags & SC_CCP_OPEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) ppp_ccp_closed(ppp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) case PPPIOCGFLAGS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) val = ppp->flags | ppp->xstate | ppp->rstate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) if (put_user(val, p))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) case PPPIOCSCOMPRESS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) struct ppp_option_data data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) if (copy_from_user(&data, argp, sizeof(data)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) err = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) err = ppp_set_compress(ppp, &data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) case PPPIOCGUNIT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) if (put_user(ppp->file.index, p))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) case PPPIOCSDEBUG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) if (get_user(val, p))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) ppp->debug = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) case PPPIOCGDEBUG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) if (put_user(ppp->debug, p))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) case PPPIOCGIDLE32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) idle32.xmit_idle = (jiffies - ppp->last_xmit) / HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) idle32.recv_idle = (jiffies - ppp->last_recv) / HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) if (copy_to_user(argp, &idle32, sizeof(idle32)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) case PPPIOCGIDLE64:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) idle64.xmit_idle = (jiffies - ppp->last_xmit) / HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) idle64.recv_idle = (jiffies - ppp->last_recv) / HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) if (copy_to_user(argp, &idle64, sizeof(idle64)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) case PPPIOCSMAXCID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) if (get_user(val, p))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) val2 = 15;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) if ((val >> 16) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) val2 = val >> 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) val &= 0xffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) vj = slhc_init(val2+1, val+1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) if (IS_ERR(vj)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) err = PTR_ERR(vj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) ppp_lock(ppp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) if (ppp->vj)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) slhc_free(ppp->vj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) ppp->vj = vj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) ppp_unlock(ppp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) case PPPIOCGNPMODE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) case PPPIOCSNPMODE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) if (copy_from_user(&npi, argp, sizeof(npi)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) err = proto_to_npindex(npi.protocol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) i = err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) if (cmd == PPPIOCGNPMODE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) err = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) npi.mode = ppp->npmode[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) if (copy_to_user(argp, &npi, sizeof(npi)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) ppp->npmode[i] = npi.mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) /* we may be able to transmit more packets now (??) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) netif_wake_queue(ppp->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) #ifdef CONFIG_PPP_FILTER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) case PPPIOCSPASS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) case PPPIOCSACTIVE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) struct bpf_prog *filter = ppp_get_filter(argp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) struct bpf_prog **which;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) if (IS_ERR(filter)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) err = PTR_ERR(filter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) if (cmd == PPPIOCSPASS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) which = &ppp->pass_filter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) which = &ppp->active_filter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) ppp_lock(ppp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) if (*which)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) bpf_prog_destroy(*which);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) *which = filter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) ppp_unlock(ppp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) #endif /* CONFIG_PPP_FILTER */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) #ifdef CONFIG_PPP_MULTILINK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) case PPPIOCSMRRU:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) if (get_user(val, p))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) ppp_recv_lock(ppp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) ppp->mrru = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) ppp_recv_unlock(ppp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) #endif /* CONFIG_PPP_MULTILINK */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) err = -ENOTTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) mutex_unlock(&ppp_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) #ifdef CONFIG_COMPAT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) struct ppp_option_data32 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) compat_uptr_t ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) u32 length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) compat_int_t transmit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) #define PPPIOCSCOMPRESS32 _IOW('t', 77, struct ppp_option_data32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) static long ppp_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) struct ppp_file *pf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) int err = -ENOIOCTLCMD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) void __user *argp = (void __user *)arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) mutex_lock(&ppp_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) pf = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) if (pf && pf->kind == INTERFACE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) struct ppp *ppp = PF_TO_PPP(pf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) #ifdef CONFIG_PPP_FILTER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) case PPPIOCSPASS32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) case PPPIOCSACTIVE32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) struct bpf_prog *filter = compat_ppp_get_filter(argp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) struct bpf_prog **which;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) if (IS_ERR(filter)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) err = PTR_ERR(filter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) if (cmd == PPPIOCSPASS32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) which = &ppp->pass_filter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) which = &ppp->active_filter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) ppp_lock(ppp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) if (*which)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) bpf_prog_destroy(*which);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) *which = filter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) ppp_unlock(ppp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) #endif /* CONFIG_PPP_FILTER */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) case PPPIOCSCOMPRESS32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) struct ppp_option_data32 data32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) if (copy_from_user(&data32, argp, sizeof(data32))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) err = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) struct ppp_option_data data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) .ptr = compat_ptr(data32.ptr),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) .length = data32.length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) .transmit = data32.transmit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) err = ppp_set_compress(ppp, &data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) mutex_unlock(&ppp_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) /* all other commands have compatible arguments */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) if (err == -ENOIOCTLCMD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) err = ppp_ioctl(file, cmd, (unsigned long)compat_ptr(arg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) static int ppp_unattached_ioctl(struct net *net, struct ppp_file *pf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) struct file *file, unsigned int cmd, unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) int unit, err = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) struct ppp *ppp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) struct channel *chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) struct ppp_net *pn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) int __user *p = (int __user *)arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) case PPPIOCNEWUNIT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) /* Create a new ppp unit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) if (get_user(unit, p))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) err = ppp_create_interface(net, file, &unit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) err = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) if (put_user(unit, p))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) case PPPIOCATTACH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) /* Attach to an existing ppp unit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) if (get_user(unit, p))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) err = -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) pn = ppp_pernet(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) mutex_lock(&pn->all_ppp_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) ppp = ppp_find_unit(pn, unit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) if (ppp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) refcount_inc(&ppp->file.refcnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) file->private_data = &ppp->file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) mutex_unlock(&pn->all_ppp_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) case PPPIOCATTCHAN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) if (get_user(unit, p))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) err = -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) pn = ppp_pernet(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) spin_lock_bh(&pn->all_channels_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) chan = ppp_find_channel(pn, unit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) if (chan) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) refcount_inc(&chan->file.refcnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) file->private_data = &chan->file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) spin_unlock_bh(&pn->all_channels_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) err = -ENOTTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) static const struct file_operations ppp_device_fops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) .read = ppp_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) .write = ppp_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) .poll = ppp_poll,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) .unlocked_ioctl = ppp_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) #ifdef CONFIG_COMPAT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) .compat_ioctl = ppp_compat_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) .open = ppp_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) .release = ppp_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) .llseek = noop_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) static __net_init int ppp_init_net(struct net *net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) struct ppp_net *pn = net_generic(net, ppp_net_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) idr_init(&pn->units_idr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) mutex_init(&pn->all_ppp_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) INIT_LIST_HEAD(&pn->all_channels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) INIT_LIST_HEAD(&pn->new_channels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) spin_lock_init(&pn->all_channels_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) static __net_exit void ppp_exit_net(struct net *net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) struct ppp_net *pn = net_generic(net, ppp_net_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) struct net_device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) struct net_device *aux;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) struct ppp *ppp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) LIST_HEAD(list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) int id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) rtnl_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) for_each_netdev_safe(net, dev, aux) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) if (dev->netdev_ops == &ppp_netdev_ops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) unregister_netdevice_queue(dev, &list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) idr_for_each_entry(&pn->units_idr, ppp, id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) /* Skip devices already unregistered by previous loop */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) if (!net_eq(dev_net(ppp->dev), net))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) unregister_netdevice_queue(ppp->dev, &list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) unregister_netdevice_many(&list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) rtnl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) mutex_destroy(&pn->all_ppp_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) idr_destroy(&pn->units_idr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) WARN_ON_ONCE(!list_empty(&pn->all_channels));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) WARN_ON_ONCE(!list_empty(&pn->new_channels));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) static struct pernet_operations ppp_net_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) .init = ppp_init_net,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) .exit = ppp_exit_net,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) .id = &ppp_net_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) .size = sizeof(struct ppp_net),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) static int ppp_unit_register(struct ppp *ppp, int unit, bool ifname_is_set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) struct ppp_net *pn = ppp_pernet(ppp->ppp_net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) mutex_lock(&pn->all_ppp_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) if (unit < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) ret = unit_get(&pn->units_idr, ppp, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) if (!ifname_is_set) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) while (1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) snprintf(ppp->dev->name, IFNAMSIZ, "ppp%i", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) if (!__dev_get_by_name(ppp->ppp_net, ppp->dev->name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) unit_put(&pn->units_idr, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) ret = unit_get(&pn->units_idr, ppp, ret + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) /* Caller asked for a specific unit number. Fail with -EEXIST
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) * if unavailable. For backward compatibility, return -EEXIST
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) * too if idr allocation fails; this makes pppd retry without
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) * requesting a specific unit number.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) if (unit_find(&pn->units_idr, unit)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) ret = -EEXIST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) ret = unit_set(&pn->units_idr, ppp, unit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) /* Rewrite error for backward compatibility */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) ret = -EEXIST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) ppp->file.index = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) if (!ifname_is_set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) snprintf(ppp->dev->name, IFNAMSIZ, "ppp%i", ppp->file.index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) mutex_unlock(&pn->all_ppp_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) ret = register_netdevice(ppp->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) goto err_unit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) atomic_inc(&ppp_unit_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) err_unit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) mutex_lock(&pn->all_ppp_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) unit_put(&pn->units_idr, ppp->file.index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) mutex_unlock(&pn->all_ppp_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) static int ppp_dev_configure(struct net *src_net, struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) const struct ppp_config *conf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) struct ppp *ppp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) int indx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) int cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) ppp->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) ppp->ppp_net = src_net;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) ppp->mru = PPP_MRU;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) ppp->owner = conf->file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) init_ppp_file(&ppp->file, INTERFACE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) ppp->file.hdrlen = PPP_HDRLEN - 2; /* don't count proto bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) for (indx = 0; indx < NUM_NP; ++indx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) ppp->npmode[indx] = NPMODE_PASS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) INIT_LIST_HEAD(&ppp->channels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) spin_lock_init(&ppp->rlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) spin_lock_init(&ppp->wlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) ppp->xmit_recursion = alloc_percpu(int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) if (!ppp->xmit_recursion) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) goto err1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) for_each_possible_cpu(cpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) (*per_cpu_ptr(ppp->xmit_recursion, cpu)) = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) #ifdef CONFIG_PPP_MULTILINK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) ppp->minseq = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) skb_queue_head_init(&ppp->mrq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) #endif /* CONFIG_PPP_MULTILINK */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) #ifdef CONFIG_PPP_FILTER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) ppp->pass_filter = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) ppp->active_filter = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) #endif /* CONFIG_PPP_FILTER */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) err = ppp_unit_register(ppp, conf->unit, conf->ifname_is_set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) goto err2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) conf->file->private_data = &ppp->file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) err2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) free_percpu(ppp->xmit_recursion);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) err1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) static const struct nla_policy ppp_nl_policy[IFLA_PPP_MAX + 1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) [IFLA_PPP_DEV_FD] = { .type = NLA_S32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) static int ppp_nl_validate(struct nlattr *tb[], struct nlattr *data[],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) struct netlink_ext_ack *extack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) if (!data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) if (!data[IFLA_PPP_DEV_FD])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) if (nla_get_s32(data[IFLA_PPP_DEV_FD]) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) return -EBADF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) static int ppp_nl_newlink(struct net *src_net, struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) struct nlattr *tb[], struct nlattr *data[],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) struct netlink_ext_ack *extack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) struct ppp_config conf = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) .unit = -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) .ifname_is_set = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) struct file *file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) file = fget(nla_get_s32(data[IFLA_PPP_DEV_FD]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) if (!file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) return -EBADF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) /* rtnl_lock is already held here, but ppp_create_interface() locks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) * ppp_mutex before holding rtnl_lock. Using mutex_trylock() avoids
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) * possible deadlock due to lock order inversion, at the cost of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) * pushing the problem back to userspace.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) if (!mutex_trylock(&ppp_mutex)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) err = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) if (file->f_op != &ppp_device_fops || file->private_data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) err = -EBADF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) conf.file = file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) /* Don't use device name generated by the rtnetlink layer when ifname
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) * isn't specified. Let ppp_dev_configure() set the device name using
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) * the PPP unit identifer as suffix (i.e. ppp<unit_id>). This allows
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) * userspace to infer the device name using to the PPPIOCGUNIT ioctl.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) if (!tb[IFLA_IFNAME] || !nla_len(tb[IFLA_IFNAME]) || !*(char *)nla_data(tb[IFLA_IFNAME]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) conf.ifname_is_set = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) err = ppp_dev_configure(src_net, dev, &conf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) out_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) mutex_unlock(&ppp_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) fput(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) static void ppp_nl_dellink(struct net_device *dev, struct list_head *head)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) unregister_netdevice_queue(dev, head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) static size_t ppp_nl_get_size(const struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) static int ppp_nl_fill_info(struct sk_buff *skb, const struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) static struct net *ppp_nl_get_link_net(const struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) struct ppp *ppp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) return ppp->ppp_net;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) static struct rtnl_link_ops ppp_link_ops __read_mostly = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) .kind = "ppp",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) .maxtype = IFLA_PPP_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) .policy = ppp_nl_policy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) .priv_size = sizeof(struct ppp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) .setup = ppp_setup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) .validate = ppp_nl_validate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) .newlink = ppp_nl_newlink,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) .dellink = ppp_nl_dellink,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) .get_size = ppp_nl_get_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) .fill_info = ppp_nl_fill_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) .get_link_net = ppp_nl_get_link_net,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) #define PPP_MAJOR 108
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) /* Called at boot time if ppp is compiled into the kernel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) or at module load time (from init_module) if compiled as a module. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) static int __init ppp_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) pr_info("PPP generic driver version " PPP_VERSION "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) err = register_pernet_device(&ppp_net_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) pr_err("failed to register PPP pernet device (%d)\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) err = register_chrdev(PPP_MAJOR, "ppp", &ppp_device_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) pr_err("failed to register PPP device (%d)\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) goto out_net;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) ppp_class = class_create(THIS_MODULE, "ppp");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) if (IS_ERR(ppp_class)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) err = PTR_ERR(ppp_class);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) goto out_chrdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) err = rtnl_link_register(&ppp_link_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) pr_err("failed to register rtnetlink PPP handler\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) goto out_class;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) /* not a big deal if we fail here :-) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) device_create(ppp_class, NULL, MKDEV(PPP_MAJOR, 0), NULL, "ppp");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) out_class:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) class_destroy(ppp_class);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) out_chrdev:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) unregister_chrdev(PPP_MAJOR, "ppp");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) out_net:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) unregister_pernet_device(&ppp_net_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) * Network interface unit routines.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) static netdev_tx_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) ppp_start_xmit(struct sk_buff *skb, struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) struct ppp *ppp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) int npi, proto;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) unsigned char *pp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) npi = ethertype_to_npindex(ntohs(skb->protocol));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) if (npi < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) goto outf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) /* Drop, accept or reject the packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) switch (ppp->npmode[npi]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) case NPMODE_PASS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) case NPMODE_QUEUE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) /* it would be nice to have a way to tell the network
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) system to queue this one up for later. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) goto outf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) case NPMODE_DROP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) case NPMODE_ERROR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) goto outf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) /* Put the 2-byte PPP protocol number on the front,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) making sure there is room for the address and control fields. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) if (skb_cow_head(skb, PPP_HDRLEN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) goto outf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) pp = skb_push(skb, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) proto = npindex_to_proto[npi];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) put_unaligned_be16(proto, pp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) skb_scrub_packet(skb, !net_eq(ppp->ppp_net, dev_net(dev)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) ppp_xmit_process(ppp, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) return NETDEV_TX_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) outf:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) ++dev->stats.tx_dropped;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) return NETDEV_TX_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) ppp_net_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) struct ppp *ppp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) int err = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) void __user *addr = (void __user *) ifr->ifr_ifru.ifru_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) struct ppp_stats stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) struct ppp_comp_stats cstats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) char *vers;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) case SIOCGPPPSTATS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) ppp_get_stats(ppp, &stats);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) if (copy_to_user(addr, &stats, sizeof(stats)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) case SIOCGPPPCSTATS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) memset(&cstats, 0, sizeof(cstats));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) if (ppp->xc_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) ppp->xcomp->comp_stat(ppp->xc_state, &cstats.c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) if (ppp->rc_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) ppp->rcomp->decomp_stat(ppp->rc_state, &cstats.d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) if (copy_to_user(addr, &cstats, sizeof(cstats)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) case SIOCGPPPVER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) vers = PPP_VERSION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) if (copy_to_user(addr, vers, strlen(vers) + 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) ppp_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) struct ppp *ppp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) ppp_recv_lock(ppp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) stats64->rx_packets = ppp->stats64.rx_packets;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) stats64->rx_bytes = ppp->stats64.rx_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) ppp_recv_unlock(ppp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) ppp_xmit_lock(ppp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) stats64->tx_packets = ppp->stats64.tx_packets;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) stats64->tx_bytes = ppp->stats64.tx_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) ppp_xmit_unlock(ppp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) stats64->rx_errors = dev->stats.rx_errors;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) stats64->tx_errors = dev->stats.tx_errors;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) stats64->rx_dropped = dev->stats.rx_dropped;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) stats64->tx_dropped = dev->stats.tx_dropped;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) stats64->rx_length_errors = dev->stats.rx_length_errors;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) static int ppp_dev_init(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) struct ppp *ppp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) netdev_lockdep_set_classes(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) ppp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) /* Let the netdevice take a reference on the ppp file. This ensures
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) * that ppp_destroy_interface() won't run before the device gets
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) * unregistered.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) refcount_inc(&ppp->file.refcnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) static void ppp_dev_uninit(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) struct ppp *ppp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) struct ppp_net *pn = ppp_pernet(ppp->ppp_net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) ppp_lock(ppp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) ppp->closing = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) ppp_unlock(ppp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) mutex_lock(&pn->all_ppp_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) unit_put(&pn->units_idr, ppp->file.index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) mutex_unlock(&pn->all_ppp_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) ppp->owner = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) ppp->file.dead = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) wake_up_interruptible(&ppp->file.rwait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) static void ppp_dev_priv_destructor(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) struct ppp *ppp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) ppp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) if (refcount_dec_and_test(&ppp->file.refcnt))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) ppp_destroy_interface(ppp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) static const struct net_device_ops ppp_netdev_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) .ndo_init = ppp_dev_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) .ndo_uninit = ppp_dev_uninit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) .ndo_start_xmit = ppp_start_xmit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) .ndo_do_ioctl = ppp_net_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) .ndo_get_stats64 = ppp_get_stats64,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) static struct device_type ppp_type = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) .name = "ppp",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) static void ppp_setup(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) dev->netdev_ops = &ppp_netdev_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) SET_NETDEV_DEVTYPE(dev, &ppp_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) dev->features |= NETIF_F_LLTX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) dev->hard_header_len = PPP_HDRLEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) dev->mtu = PPP_MRU;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) dev->addr_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) dev->tx_queue_len = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) dev->type = ARPHRD_PPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) dev->flags = IFF_POINTOPOINT | IFF_NOARP | IFF_MULTICAST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) dev->priv_destructor = ppp_dev_priv_destructor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) netif_keep_dst(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) * Transmit-side routines.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) /* Called to do any work queued up on the transmit side that can now be done */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) static void __ppp_xmit_process(struct ppp *ppp, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) ppp_xmit_lock(ppp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) if (!ppp->closing) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) ppp_push(ppp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) if (skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) skb_queue_tail(&ppp->file.xq, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) while (!ppp->xmit_pending &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) (skb = skb_dequeue(&ppp->file.xq)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) ppp_send_frame(ppp, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) /* If there's no work left to do, tell the core net
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) code that we can accept some more. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) if (!ppp->xmit_pending && !skb_peek(&ppp->file.xq))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) netif_wake_queue(ppp->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) netif_stop_queue(ppp->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) ppp_xmit_unlock(ppp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) static void ppp_xmit_process(struct ppp *ppp, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) local_bh_disable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) if (unlikely(*this_cpu_ptr(ppp->xmit_recursion)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) (*this_cpu_ptr(ppp->xmit_recursion))++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) __ppp_xmit_process(ppp, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) (*this_cpu_ptr(ppp->xmit_recursion))--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) local_bh_enable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) local_bh_enable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) if (net_ratelimit())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) netdev_err(ppp->dev, "recursion detected\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) static inline struct sk_buff *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) pad_compress_skb(struct ppp *ppp, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) struct sk_buff *new_skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) int new_skb_size = ppp->dev->mtu +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) ppp->xcomp->comp_extra + ppp->dev->hard_header_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) int compressor_skb_size = ppp->dev->mtu +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) ppp->xcomp->comp_extra + PPP_HDRLEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) new_skb = alloc_skb(new_skb_size, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) if (!new_skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) if (net_ratelimit())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) netdev_err(ppp->dev, "PPP: no memory (comp pkt)\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) if (ppp->dev->hard_header_len > PPP_HDRLEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) skb_reserve(new_skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) ppp->dev->hard_header_len - PPP_HDRLEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) /* compressor still expects A/C bytes in hdr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) len = ppp->xcomp->compress(ppp->xc_state, skb->data - 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) new_skb->data, skb->len + 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) compressor_skb_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) if (len > 0 && (ppp->flags & SC_CCP_UP)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) consume_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) skb = new_skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) skb_put(skb, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) skb_pull(skb, 2); /* pull off A/C bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) } else if (len == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) /* didn't compress, or CCP not up yet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) consume_skb(new_skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) new_skb = skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) * (len < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) * MPPE requires that we do not send unencrypted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) * frames. The compressor will return -1 if we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) * should drop the frame. We cannot simply test
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) * the compress_proto because MPPE and MPPC share
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) * the same number.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) if (net_ratelimit())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) netdev_err(ppp->dev, "ppp: compressor dropped pkt\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) consume_skb(new_skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) new_skb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) return new_skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) * Compress and send a frame.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) * The caller should have locked the xmit path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) * and xmit_pending should be 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) ppp_send_frame(struct ppp *ppp, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) int proto = PPP_PROTO(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) struct sk_buff *new_skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) unsigned char *cp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) if (proto < 0x8000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) #ifdef CONFIG_PPP_FILTER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) /* check if we should pass this packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) /* the filter instructions are constructed assuming
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) a four-byte PPP header on each packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) *(u8 *)skb_push(skb, 2) = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) if (ppp->pass_filter &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) BPF_PROG_RUN(ppp->pass_filter, skb) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) if (ppp->debug & 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) netdev_printk(KERN_DEBUG, ppp->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) "PPP: outbound frame "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) "not passed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) /* if this packet passes the active filter, record the time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) if (!(ppp->active_filter &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) BPF_PROG_RUN(ppp->active_filter, skb) == 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) ppp->last_xmit = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) skb_pull(skb, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) /* for data packets, record the time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) ppp->last_xmit = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) #endif /* CONFIG_PPP_FILTER */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) ++ppp->stats64.tx_packets;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) ppp->stats64.tx_bytes += skb->len - PPP_PROTO_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) switch (proto) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) case PPP_IP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) if (!ppp->vj || (ppp->flags & SC_COMP_TCP) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) /* try to do VJ TCP header compression */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) new_skb = alloc_skb(skb->len + ppp->dev->hard_header_len - 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) if (!new_skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) netdev_err(ppp->dev, "PPP: no memory (VJ comp pkt)\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) goto drop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) skb_reserve(new_skb, ppp->dev->hard_header_len - 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) cp = skb->data + 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) len = slhc_compress(ppp->vj, cp, skb->len - 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) new_skb->data + 2, &cp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) !(ppp->flags & SC_NO_TCP_CCID));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) if (cp == skb->data + 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) /* didn't compress */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) consume_skb(new_skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) if (cp[0] & SL_TYPE_COMPRESSED_TCP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) proto = PPP_VJC_COMP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) cp[0] &= ~SL_TYPE_COMPRESSED_TCP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) proto = PPP_VJC_UNCOMP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) cp[0] = skb->data[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) consume_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) skb = new_skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) cp = skb_put(skb, len + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) cp[0] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) cp[1] = proto;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) case PPP_CCP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) /* peek at outbound CCP frames */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) ppp_ccp_peek(ppp, skb, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) /* try to do packet compression */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) if ((ppp->xstate & SC_COMP_RUN) && ppp->xc_state &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) proto != PPP_LCP && proto != PPP_CCP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) if (!(ppp->flags & SC_CCP_UP) && (ppp->flags & SC_MUST_COMP)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) if (net_ratelimit())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) netdev_err(ppp->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) "ppp: compression required but "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) "down - pkt dropped.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) goto drop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) skb = pad_compress_skb(ppp, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) goto drop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) * If we are waiting for traffic (demand dialling),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) * queue it up for pppd to receive.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) if (ppp->flags & SC_LOOP_TRAFFIC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) if (ppp->file.rq.qlen > PPP_MAX_RQLEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) goto drop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) skb_queue_tail(&ppp->file.rq, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) wake_up_interruptible(&ppp->file.rwait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) ppp->xmit_pending = skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) ppp_push(ppp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) drop:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) ++ppp->dev->stats.tx_errors;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) * Try to send the frame in xmit_pending.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) * The caller should have the xmit path locked.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) ppp_push(struct ppp *ppp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) struct list_head *list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) struct channel *pch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) struct sk_buff *skb = ppp->xmit_pending;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) list = &ppp->channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) if (list_empty(list)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) /* nowhere to send the packet, just drop it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) ppp->xmit_pending = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) if ((ppp->flags & SC_MULTILINK) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) /* not doing multilink: send it down the first channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) list = list->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) pch = list_entry(list, struct channel, clist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) spin_lock(&pch->downl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) if (pch->chan) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) if (pch->chan->ops->start_xmit(pch->chan, skb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) ppp->xmit_pending = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) /* channel got unregistered */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) ppp->xmit_pending = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) spin_unlock(&pch->downl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) #ifdef CONFIG_PPP_MULTILINK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) /* Multilink: fragment the packet over as many links
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) as can take the packet at the moment. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) if (!ppp_mp_explode(ppp, skb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) #endif /* CONFIG_PPP_MULTILINK */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) ppp->xmit_pending = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) #ifdef CONFIG_PPP_MULTILINK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) static bool mp_protocol_compress __read_mostly = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) module_param(mp_protocol_compress, bool, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) MODULE_PARM_DESC(mp_protocol_compress,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) "compress protocol id in multilink fragments");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) * Divide a packet to be transmitted into fragments and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) * send them out the individual links.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) static int ppp_mp_explode(struct ppp *ppp, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) int len, totlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) int i, bits, hdrlen, mtu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) int flen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) int navail, nfree, nzero;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) int nbigger;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) int totspeed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) int totfree;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) unsigned char *p, *q;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) struct list_head *list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) struct channel *pch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) struct sk_buff *frag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) struct ppp_channel *chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) totspeed = 0; /*total bitrate of the bundle*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) nfree = 0; /* # channels which have no packet already queued */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) navail = 0; /* total # of usable channels (not deregistered) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) nzero = 0; /* number of channels with zero speed associated*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) totfree = 0; /*total # of channels available and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) *having no queued packets before
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) *starting the fragmentation*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) hdrlen = (ppp->flags & SC_MP_XSHORTSEQ)? MPHDRLEN_SSN: MPHDRLEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) list_for_each_entry(pch, &ppp->channels, clist) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) if (pch->chan) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) pch->avail = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) navail++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) pch->speed = pch->chan->speed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) pch->avail = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) if (pch->avail) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) if (skb_queue_empty(&pch->file.xq) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) !pch->had_frag) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) if (pch->speed == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) nzero++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) totspeed += pch->speed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) pch->avail = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) ++nfree;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) ++totfree;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) if (!pch->had_frag && i < ppp->nxchan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) ppp->nxchan = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) ++i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) * Don't start sending this packet unless at least half of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) * the channels are free. This gives much better TCP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) * performance if we have a lot of channels.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) if (nfree == 0 || nfree < navail / 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) return 0; /* can't take now, leave it in xmit_pending */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) /* Do protocol field compression */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) p = skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) len = skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) if (*p == 0 && mp_protocol_compress) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) ++p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) --len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) totlen = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) nbigger = len % nfree;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) /* skip to the channel after the one we last used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) and start at that one */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) list = &ppp->channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) for (i = 0; i < ppp->nxchan; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) list = list->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) if (list == &ppp->channels) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) /* create a fragment for each channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) bits = B;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) while (len > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) list = list->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) if (list == &ppp->channels) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) pch = list_entry(list, struct channel, clist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) ++i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) if (!pch->avail)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) * Skip this channel if it has a fragment pending already and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) * we haven't given a fragment to all of the free channels.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) if (pch->avail == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) if (nfree > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) pch->avail = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) /* check the channel's mtu and whether it is still attached. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) spin_lock(&pch->downl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) if (pch->chan == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) /* can't use this channel, it's being deregistered */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) if (pch->speed == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) nzero--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) totspeed -= pch->speed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) spin_unlock(&pch->downl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) pch->avail = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) totlen = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) totfree--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) nfree--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) if (--navail == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) *if the channel speed is not set divide
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) *the packet evenly among the free channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) *otherwise divide it according to the speed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) *of the channel we are going to transmit on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) flen = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) if (nfree > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) if (pch->speed == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) flen = len/nfree;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) if (nbigger > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) flen++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) nbigger--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) flen = (((totfree - nzero)*(totlen + hdrlen*totfree)) /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) ((totspeed*totfree)/pch->speed)) - hdrlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) if (nbigger > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) flen += ((totfree - nzero)*pch->speed)/totspeed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) nbigger -= ((totfree - nzero)*pch->speed)/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) totspeed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) nfree--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) *check if we are on the last channel or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) *we exceded the length of the data to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) *fragment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) if ((nfree <= 0) || (flen > len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) flen = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) *it is not worth to tx on slow channels:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) *in that case from the resulting flen according to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) *above formula will be equal or less than zero.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) *Skip the channel in this case
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) if (flen <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) pch->avail = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) spin_unlock(&pch->downl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) * hdrlen includes the 2-byte PPP protocol field, but the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) * MTU counts only the payload excluding the protocol field.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) * (RFC1661 Section 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) mtu = pch->chan->mtu - (hdrlen - 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) if (mtu < 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) mtu = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) if (flen > mtu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) flen = mtu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) if (flen == len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) bits |= E;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) frag = alloc_skb(flen + hdrlen + (flen == 0), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) if (!frag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) goto noskb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) q = skb_put(frag, flen + hdrlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) /* make the MP header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) put_unaligned_be16(PPP_MP, q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) if (ppp->flags & SC_MP_XSHORTSEQ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) q[2] = bits + ((ppp->nxseq >> 8) & 0xf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) q[3] = ppp->nxseq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) q[2] = bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) q[3] = ppp->nxseq >> 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) q[4] = ppp->nxseq >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) q[5] = ppp->nxseq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) memcpy(q + hdrlen, p, flen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) /* try to send it down the channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) chan = pch->chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) if (!skb_queue_empty(&pch->file.xq) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) !chan->ops->start_xmit(chan, frag))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) skb_queue_tail(&pch->file.xq, frag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) pch->had_frag = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) p += flen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) len -= flen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) ++ppp->nxseq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) bits = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) spin_unlock(&pch->downl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) ppp->nxchan = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) noskb:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) spin_unlock(&pch->downl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) if (ppp->debug & 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) netdev_err(ppp->dev, "PPP: no memory (fragment)\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) ++ppp->dev->stats.tx_errors;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) ++ppp->nxseq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) return 1; /* abandon the frame */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) #endif /* CONFIG_PPP_MULTILINK */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) /* Try to send data out on a channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) static void __ppp_channel_push(struct channel *pch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) struct ppp *ppp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) spin_lock(&pch->downl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) if (pch->chan) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) while (!skb_queue_empty(&pch->file.xq)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) skb = skb_dequeue(&pch->file.xq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) if (!pch->chan->ops->start_xmit(pch->chan, skb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) /* put the packet back and try again later */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) skb_queue_head(&pch->file.xq, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) /* channel got deregistered */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) skb_queue_purge(&pch->file.xq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) spin_unlock(&pch->downl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) /* see if there is anything from the attached unit to be sent */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) if (skb_queue_empty(&pch->file.xq)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) ppp = pch->ppp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) if (ppp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) __ppp_xmit_process(ppp, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) static void ppp_channel_push(struct channel *pch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) read_lock_bh(&pch->upl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) if (pch->ppp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) (*this_cpu_ptr(pch->ppp->xmit_recursion))++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) __ppp_channel_push(pch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) (*this_cpu_ptr(pch->ppp->xmit_recursion))--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) __ppp_channel_push(pch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) read_unlock_bh(&pch->upl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) * Receive-side routines.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) struct ppp_mp_skb_parm {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) u32 sequence;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) u8 BEbits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) #define PPP_MP_CB(skb) ((struct ppp_mp_skb_parm *)((skb)->cb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) ppp_do_recv(struct ppp *ppp, struct sk_buff *skb, struct channel *pch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) ppp_recv_lock(ppp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) if (!ppp->closing)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) ppp_receive_frame(ppp, skb, pch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) ppp_recv_unlock(ppp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) * __ppp_decompress_proto - Decompress protocol field, slim version.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) * @skb: Socket buffer where protocol field should be decompressed. It must have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) * at least 1 byte of head room and 1 byte of linear data. First byte of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) * data must be a protocol field byte.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) * Decompress protocol field in PPP header if it's compressed, e.g. when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) * Protocol-Field-Compression (PFC) was negotiated. No checks w.r.t. skb data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) * length are done in this function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) static void __ppp_decompress_proto(struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) if (skb->data[0] & 0x01)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) *(u8 *)skb_push(skb, 1) = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) * ppp_decompress_proto - Check skb data room and decompress protocol field.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) * @skb: Socket buffer where protocol field should be decompressed. First byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) * of data must be a protocol field byte.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) * Decompress protocol field in PPP header if it's compressed, e.g. when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) * Protocol-Field-Compression (PFC) was negotiated. This function also makes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) * sure that skb data room is sufficient for Protocol field, before and after
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) * decompression.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) * Return: true - decompressed successfully, false - not enough room in skb.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) static bool ppp_decompress_proto(struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) /* At least one byte should be present (if protocol is compressed) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) if (!pskb_may_pull(skb, 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) __ppp_decompress_proto(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) /* Protocol field should occupy 2 bytes when not compressed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) return pskb_may_pull(skb, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) ppp_input(struct ppp_channel *chan, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) struct channel *pch = chan->ppp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) int proto;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) if (!pch) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) read_lock_bh(&pch->upl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) if (!ppp_decompress_proto(skb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) if (pch->ppp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) ++pch->ppp->dev->stats.rx_length_errors;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) ppp_receive_error(pch->ppp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) proto = PPP_PROTO(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) if (!pch->ppp || proto >= 0xc000 || proto == PPP_CCPFRAG) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) /* put it on the channel queue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) skb_queue_tail(&pch->file.rq, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) /* drop old frames if queue too long */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) while (pch->file.rq.qlen > PPP_MAX_RQLEN &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) (skb = skb_dequeue(&pch->file.rq)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) wake_up_interruptible(&pch->file.rwait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) ppp_do_recv(pch->ppp, skb, pch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) read_unlock_bh(&pch->upl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) /* Put a 0-length skb in the receive queue as an error indication */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) ppp_input_error(struct ppp_channel *chan, int code)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) struct channel *pch = chan->ppp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) if (!pch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) read_lock_bh(&pch->upl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) if (pch->ppp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) skb = alloc_skb(0, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) if (skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) skb->len = 0; /* probably unnecessary */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) skb->cb[0] = code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) ppp_do_recv(pch->ppp, skb, pch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) read_unlock_bh(&pch->upl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) * We come in here to process a received frame.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) * The receive side of the ppp unit is locked.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) ppp_receive_frame(struct ppp *ppp, struct sk_buff *skb, struct channel *pch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) /* note: a 0-length skb is used as an error indication */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) if (skb->len > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) skb_checksum_complete_unset(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) #ifdef CONFIG_PPP_MULTILINK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) /* XXX do channel-level decompression here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) if (PPP_PROTO(skb) == PPP_MP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) ppp_receive_mp_frame(ppp, skb, pch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) #endif /* CONFIG_PPP_MULTILINK */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) ppp_receive_nonmp_frame(ppp, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) ppp_receive_error(ppp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) ppp_receive_error(struct ppp *ppp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) ++ppp->dev->stats.rx_errors;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) if (ppp->vj)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) slhc_toss(ppp->vj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) ppp_receive_nonmp_frame(struct ppp *ppp, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) struct sk_buff *ns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) int proto, len, npi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) * Decompress the frame, if compressed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) * Note that some decompressors need to see uncompressed frames
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) * that come in as well as compressed frames.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) if (ppp->rc_state && (ppp->rstate & SC_DECOMP_RUN) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) (ppp->rstate & (SC_DC_FERROR | SC_DC_ERROR)) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) skb = ppp_decompress_frame(ppp, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) if (ppp->flags & SC_MUST_COMP && ppp->rstate & SC_DC_FERROR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) /* At this point the "Protocol" field MUST be decompressed, either in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) * ppp_input(), ppp_decompress_frame() or in ppp_receive_mp_frame().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) proto = PPP_PROTO(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) switch (proto) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) case PPP_VJC_COMP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) /* decompress VJ compressed packets */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) if (!ppp->vj || (ppp->flags & SC_REJ_COMP_TCP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) if (skb_tailroom(skb) < 124 || skb_cloned(skb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) /* copy to a new sk_buff with more tailroom */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) ns = dev_alloc_skb(skb->len + 128);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) if (!ns) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) netdev_err(ppp->dev, "PPP: no memory "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) "(VJ decomp)\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) skb_reserve(ns, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) skb_copy_bits(skb, 0, skb_put(ns, skb->len), skb->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) consume_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) skb = ns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) skb->ip_summed = CHECKSUM_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) len = slhc_uncompress(ppp->vj, skb->data + 2, skb->len - 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) if (len <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) netdev_printk(KERN_DEBUG, ppp->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) "PPP: VJ decompression error\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) len += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) if (len > skb->len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) skb_put(skb, len - skb->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) else if (len < skb->len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) skb_trim(skb, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) proto = PPP_IP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) case PPP_VJC_UNCOMP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) if (!ppp->vj || (ppp->flags & SC_REJ_COMP_TCP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) /* Until we fix the decompressor need to make sure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) * data portion is linear.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) if (!pskb_may_pull(skb, skb->len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) if (slhc_remember(ppp->vj, skb->data + 2, skb->len - 2) <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) netdev_err(ppp->dev, "PPP: VJ uncompressed error\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) proto = PPP_IP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) case PPP_CCP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) ppp_ccp_peek(ppp, skb, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) ++ppp->stats64.rx_packets;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) ppp->stats64.rx_bytes += skb->len - 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) npi = proto_to_npindex(proto);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) if (npi < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) /* control or unknown frame - pass it to pppd */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) skb_queue_tail(&ppp->file.rq, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) /* limit queue length by dropping old frames */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) while (ppp->file.rq.qlen > PPP_MAX_RQLEN &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) (skb = skb_dequeue(&ppp->file.rq)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) /* wake up any process polling or blocking on read */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) wake_up_interruptible(&ppp->file.rwait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) /* network protocol frame - give it to the kernel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) #ifdef CONFIG_PPP_FILTER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) /* check if the packet passes the pass and active filters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) /* the filter instructions are constructed assuming
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) a four-byte PPP header on each packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) if (ppp->pass_filter || ppp->active_filter) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) if (skb_unclone(skb, GFP_ATOMIC))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) *(u8 *)skb_push(skb, 2) = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) if (ppp->pass_filter &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) BPF_PROG_RUN(ppp->pass_filter, skb) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) if (ppp->debug & 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308) netdev_printk(KERN_DEBUG, ppp->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) "PPP: inbound frame "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) "not passed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) if (!(ppp->active_filter &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) BPF_PROG_RUN(ppp->active_filter, skb) == 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) ppp->last_recv = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) __skb_pull(skb, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) #endif /* CONFIG_PPP_FILTER */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) ppp->last_recv = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) if ((ppp->dev->flags & IFF_UP) == 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) ppp->npmode[npi] != NPMODE_PASS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) /* chop off protocol */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) skb_pull_rcsum(skb, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) skb->dev = ppp->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) skb->protocol = htons(npindex_to_ethertype[npi]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) skb_reset_mac_header(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) skb_scrub_packet(skb, !net_eq(ppp->ppp_net,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) dev_net(ppp->dev)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) netif_rx(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) ppp_receive_error(ppp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) static struct sk_buff *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) ppp_decompress_frame(struct ppp *ppp, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) int proto = PPP_PROTO(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) struct sk_buff *ns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) /* Until we fix all the decompressor's need to make sure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) * data portion is linear.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) if (!pskb_may_pull(skb, skb->len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) if (proto == PPP_COMP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) int obuff_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) switch(ppp->rcomp->compress_proto) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) case CI_MPPE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361) obuff_size = ppp->mru + PPP_HDRLEN + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) obuff_size = ppp->mru + PPP_HDRLEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) ns = dev_alloc_skb(obuff_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) if (!ns) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) netdev_err(ppp->dev, "ppp_decompress_frame: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) "no memory\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) /* the decompressor still expects the A/C bytes in the hdr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375) len = ppp->rcomp->decompress(ppp->rc_state, skb->data - 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) skb->len + 2, ns->data, obuff_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) if (len < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) /* Pass the compressed frame to pppd as an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) error indication. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) if (len == DECOMP_FATALERROR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) ppp->rstate |= SC_DC_FERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) kfree_skb(ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) consume_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) skb = ns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) skb_put(skb, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) skb_pull(skb, 2); /* pull off the A/C bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) /* Don't call __ppp_decompress_proto() here, but instead rely on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392) * corresponding algo (mppe/bsd/deflate) to decompress it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395) /* Uncompressed frame - pass to decompressor so it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) can update its dictionary if necessary. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) if (ppp->rcomp->incomp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) ppp->rcomp->incomp(ppp->rc_state, skb->data - 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399) skb->len + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) return skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) ppp->rstate |= SC_DC_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) ppp_receive_error(ppp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) return skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) #ifdef CONFIG_PPP_MULTILINK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412) * Receive a multilink frame.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) * We put it on the reconstruction queue and then pull off
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414) * as many completed frames as we can.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) ppp_receive_mp_frame(struct ppp *ppp, struct sk_buff *skb, struct channel *pch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) u32 mask, seq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) struct channel *ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421) int mphdrlen = (ppp->flags & SC_MP_SHORTSEQ)? MPHDRLEN_SSN: MPHDRLEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) if (!pskb_may_pull(skb, mphdrlen + 1) || ppp->mrru == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) goto err; /* no good, throw it away */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) /* Decode sequence number and begin/end bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) if (ppp->flags & SC_MP_SHORTSEQ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) seq = ((skb->data[2] & 0x0f) << 8) | skb->data[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) mask = 0xfff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) seq = (skb->data[3] << 16) | (skb->data[4] << 8)| skb->data[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432) mask = 0xffffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) PPP_MP_CB(skb)->BEbits = skb->data[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) skb_pull(skb, mphdrlen); /* pull off PPP and MP headers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) * Do protocol ID decompression on the first fragment of each packet.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) * We have to do that here, because ppp_receive_nonmp_frame() expects
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) * decompressed protocol field.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442) if (PPP_MP_CB(skb)->BEbits & B)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443) __ppp_decompress_proto(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446) * Expand sequence number to 32 bits, making it as close
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) * as possible to ppp->minseq.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449) seq |= ppp->minseq & ~mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450) if ((int)(ppp->minseq - seq) > (int)(mask >> 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451) seq += mask + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) else if ((int)(seq - ppp->minseq) > (int)(mask >> 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453) seq -= mask + 1; /* should never happen */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454) PPP_MP_CB(skb)->sequence = seq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) pch->lastseq = seq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) * If this packet comes before the next one we were expecting,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459) * drop it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) if (seq_before(seq, ppp->nextseq)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) ++ppp->dev->stats.rx_dropped;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464) ppp_receive_error(ppp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469) * Reevaluate minseq, the minimum over all channels of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) * last sequence number received on each channel. Because of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471) * the increasing sequence number rule, we know that any fragment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472) * before `minseq' which hasn't arrived is never going to arrive.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473) * The list of channels can't change because we have the receive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) * side of the ppp unit locked.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) list_for_each_entry(ch, &ppp->channels, clist) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) if (seq_before(ch->lastseq, seq))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478) seq = ch->lastseq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) if (seq_before(ppp->minseq, seq))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481) ppp->minseq = seq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) /* Put the fragment on the reconstruction queue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484) ppp_mp_insert(ppp, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) /* If the queue is getting long, don't wait any longer for packets
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487) before the start of the queue. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488) if (skb_queue_len(&ppp->mrq) >= PPP_MP_MAX_QLEN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) struct sk_buff *mskb = skb_peek(&ppp->mrq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490) if (seq_before(ppp->minseq, PPP_MP_CB(mskb)->sequence))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491) ppp->minseq = PPP_MP_CB(mskb)->sequence;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) /* Pull completed packets off the queue and receive them. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495) while ((skb = ppp_mp_reconstruct(ppp))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496) if (pskb_may_pull(skb, 2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497) ppp_receive_nonmp_frame(ppp, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499) ++ppp->dev->stats.rx_length_errors;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) ppp_receive_error(ppp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509) ppp_receive_error(ppp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513) * Insert a fragment on the MP reconstruction queue.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514) * The queue is ordered by increasing sequence number.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517) ppp_mp_insert(struct ppp *ppp, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519) struct sk_buff *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520) struct sk_buff_head *list = &ppp->mrq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521) u32 seq = PPP_MP_CB(skb)->sequence;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523) /* N.B. we don't need to lock the list lock because we have the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524) ppp unit receive-side lock. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) skb_queue_walk(list, p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) if (seq_before(seq, PPP_MP_CB(p)->sequence))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529) __skb_queue_before(list, p, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533) * Reconstruct a packet from the MP fragment queue.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) * We go through increasing sequence numbers until we find a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535) * complete packet, or we get to the sequence number for a fragment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536) * which hasn't arrived but might still do so.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) static struct sk_buff *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539) ppp_mp_reconstruct(struct ppp *ppp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541) u32 seq = ppp->nextseq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542) u32 minseq = ppp->minseq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543) struct sk_buff_head *list = &ppp->mrq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544) struct sk_buff *p, *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545) struct sk_buff *head, *tail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546) struct sk_buff *skb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547) int lost = 0, len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549) if (ppp->mrru == 0) /* do nothing until mrru is set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551) head = __skb_peek(list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552) tail = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553) skb_queue_walk_safe(list, p, tmp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554) again:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555) if (seq_before(PPP_MP_CB(p)->sequence, seq)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556) /* this can't happen, anyway ignore the skb */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557) netdev_err(ppp->dev, "ppp_mp_reconstruct bad "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558) "seq %u < %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559) PPP_MP_CB(p)->sequence, seq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560) __skb_unlink(p, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561) kfree_skb(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564) if (PPP_MP_CB(p)->sequence != seq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) u32 oldseq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566) /* Fragment `seq' is missing. If it is after
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567) minseq, it might arrive later, so stop here. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568) if (seq_after(seq, minseq))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570) /* Fragment `seq' is lost, keep going. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571) lost = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572) oldseq = seq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573) seq = seq_before(minseq, PPP_MP_CB(p)->sequence)?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) minseq + 1: PPP_MP_CB(p)->sequence;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576) if (ppp->debug & 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577) netdev_printk(KERN_DEBUG, ppp->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578) "lost frag %u..%u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579) oldseq, seq-1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581) goto again;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585) * At this point we know that all the fragments from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586) * ppp->nextseq to seq are either present or lost.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587) * Also, there are no complete packets in the queue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588) * that have no missing fragments and end before this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589) * fragment.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592) /* B bit set indicates this fragment starts a packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593) if (PPP_MP_CB(p)->BEbits & B) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594) head = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595) lost = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596) len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599) len += p->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601) /* Got a complete packet yet? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602) if (lost == 0 && (PPP_MP_CB(p)->BEbits & E) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603) (PPP_MP_CB(head)->BEbits & B)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604) if (len > ppp->mrru + 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605) ++ppp->dev->stats.rx_length_errors;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606) netdev_printk(KERN_DEBUG, ppp->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607) "PPP: reconstructed packet"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608) " is too long (%d)\n", len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610) tail = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613) ppp->nextseq = seq + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617) * If this is the ending fragment of a packet,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618) * and we haven't found a complete valid packet yet,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619) * we can discard up to and including this fragment.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621) if (PPP_MP_CB(p)->BEbits & E) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622) struct sk_buff *tmp2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624) skb_queue_reverse_walk_from_safe(list, p, tmp2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625) if (ppp->debug & 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626) netdev_printk(KERN_DEBUG, ppp->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627) "discarding frag %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628) PPP_MP_CB(p)->sequence);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629) __skb_unlink(p, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630) kfree_skb(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632) head = skb_peek(list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633) if (!head)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636) ++seq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639) /* If we have a complete packet, copy it all into one skb. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640) if (tail != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641) /* If we have discarded any fragments,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642) signal a receive error. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643) if (PPP_MP_CB(head)->sequence != ppp->nextseq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644) skb_queue_walk_safe(list, p, tmp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645) if (p == head)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2646) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2647) if (ppp->debug & 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2648) netdev_printk(KERN_DEBUG, ppp->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2649) "discarding frag %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2650) PPP_MP_CB(p)->sequence);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2651) __skb_unlink(p, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2652) kfree_skb(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2653) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2655) if (ppp->debug & 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2656) netdev_printk(KERN_DEBUG, ppp->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2657) " missed pkts %u..%u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2658) ppp->nextseq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2659) PPP_MP_CB(head)->sequence-1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2660) ++ppp->dev->stats.rx_dropped;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2661) ppp_receive_error(ppp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2662) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2664) skb = head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2665) if (head != tail) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2666) struct sk_buff **fragpp = &skb_shinfo(skb)->frag_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2667) p = skb_queue_next(list, head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2668) __skb_unlink(skb, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2669) skb_queue_walk_from_safe(list, p, tmp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2670) __skb_unlink(p, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2671) *fragpp = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2672) p->next = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2673) fragpp = &p->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2675) skb->len += p->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2676) skb->data_len += p->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2677) skb->truesize += p->truesize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2679) if (p == tail)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2680) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2681) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2682) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2683) __skb_unlink(skb, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2684) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2686) ppp->nextseq = PPP_MP_CB(tail)->sequence + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2687) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2689) return skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2690) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2691) #endif /* CONFIG_PPP_MULTILINK */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2693) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2694) * Channel interface.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2695) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2697) /* Create a new, unattached ppp channel. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2698) int ppp_register_channel(struct ppp_channel *chan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2699) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2700) return ppp_register_net_channel(current->nsproxy->net_ns, chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2701) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2703) /* Create a new, unattached ppp channel for specified net. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2704) int ppp_register_net_channel(struct net *net, struct ppp_channel *chan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2705) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2706) struct channel *pch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2707) struct ppp_net *pn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2709) pch = kzalloc(sizeof(struct channel), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2710) if (!pch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2711) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2713) pn = ppp_pernet(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2715) pch->ppp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2716) pch->chan = chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2717) pch->chan_net = get_net(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2718) chan->ppp = pch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2719) init_ppp_file(&pch->file, CHANNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2720) pch->file.hdrlen = chan->hdrlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2721) #ifdef CONFIG_PPP_MULTILINK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2722) pch->lastseq = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2723) #endif /* CONFIG_PPP_MULTILINK */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2724) init_rwsem(&pch->chan_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2725) spin_lock_init(&pch->downl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2726) rwlock_init(&pch->upl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2728) spin_lock_bh(&pn->all_channels_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2729) pch->file.index = ++pn->last_channel_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2730) list_add(&pch->list, &pn->new_channels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2731) atomic_inc(&channel_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2732) spin_unlock_bh(&pn->all_channels_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2734) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2735) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2737) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2738) * Return the index of a channel.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2739) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2740) int ppp_channel_index(struct ppp_channel *chan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2741) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2742) struct channel *pch = chan->ppp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2744) if (pch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2745) return pch->file.index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2746) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2747) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2748)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2749) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2750) * Return the PPP unit number to which a channel is connected.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2751) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2752) int ppp_unit_number(struct ppp_channel *chan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2753) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2754) struct channel *pch = chan->ppp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2755) int unit = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2756)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2757) if (pch) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2758) read_lock_bh(&pch->upl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2759) if (pch->ppp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2760) unit = pch->ppp->file.index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2761) read_unlock_bh(&pch->upl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2762) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2763) return unit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2764) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2766) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2767) * Return the PPP device interface name of a channel.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2768) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2769) char *ppp_dev_name(struct ppp_channel *chan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2770) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2771) struct channel *pch = chan->ppp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2772) char *name = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2774) if (pch) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2775) read_lock_bh(&pch->upl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2776) if (pch->ppp && pch->ppp->dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2777) name = pch->ppp->dev->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2778) read_unlock_bh(&pch->upl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2779) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2780) return name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2781) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2784) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2785) * Disconnect a channel from the generic layer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2786) * This must be called in process context.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2787) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2788) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2789) ppp_unregister_channel(struct ppp_channel *chan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2790) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2791) struct channel *pch = chan->ppp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2792) struct ppp_net *pn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2793)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2794) if (!pch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2795) return; /* should never happen */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2797) chan->ppp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2799) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2800) * This ensures that we have returned from any calls into the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2801) * the channel's start_xmit or ioctl routine before we proceed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2802) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2803) down_write(&pch->chan_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2804) spin_lock_bh(&pch->downl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2805) pch->chan = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2806) spin_unlock_bh(&pch->downl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2807) up_write(&pch->chan_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2808) ppp_disconnect_channel(pch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2810) pn = ppp_pernet(pch->chan_net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2811) spin_lock_bh(&pn->all_channels_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2812) list_del(&pch->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2813) spin_unlock_bh(&pn->all_channels_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2815) pch->file.dead = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2816) wake_up_interruptible(&pch->file.rwait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2817) if (refcount_dec_and_test(&pch->file.refcnt))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2818) ppp_destroy_channel(pch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2819) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2821) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2822) * Callback from a channel when it can accept more to transmit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2823) * This should be called at BH/softirq level, not interrupt level.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2824) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2825) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2826) ppp_output_wakeup(struct ppp_channel *chan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2827) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2828) struct channel *pch = chan->ppp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2830) if (!pch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2831) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2832) ppp_channel_push(pch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2833) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2834)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2835) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2836) * Compression control.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2837) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2838)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2839) /* Process the PPPIOCSCOMPRESS ioctl. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2840) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2841) ppp_set_compress(struct ppp *ppp, struct ppp_option_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2842) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2843) int err = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2844) struct compressor *cp, *ocomp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2845) void *state, *ostate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2846) unsigned char ccp_option[CCP_MAX_OPTION_LENGTH];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2848) if (data->length > CCP_MAX_OPTION_LENGTH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2849) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2850) if (copy_from_user(ccp_option, data->ptr, data->length))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2851) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2853) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2854) if (data->length < 2 || ccp_option[1] < 2 || ccp_option[1] > data->length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2855) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2857) cp = try_then_request_module(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2858) find_compressor(ccp_option[0]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2859) "ppp-compress-%d", ccp_option[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2860) if (!cp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2861) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2862)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2863) err = -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2864) if (data->transmit) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2865) state = cp->comp_alloc(ccp_option, data->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2866) if (state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2867) ppp_xmit_lock(ppp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2868) ppp->xstate &= ~SC_COMP_RUN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2869) ocomp = ppp->xcomp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2870) ostate = ppp->xc_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2871) ppp->xcomp = cp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2872) ppp->xc_state = state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2873) ppp_xmit_unlock(ppp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2874) if (ostate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2875) ocomp->comp_free(ostate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2876) module_put(ocomp->owner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2877) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2878) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2879) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2880) module_put(cp->owner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2882) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2883) state = cp->decomp_alloc(ccp_option, data->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2884) if (state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2885) ppp_recv_lock(ppp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2886) ppp->rstate &= ~SC_DECOMP_RUN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2887) ocomp = ppp->rcomp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2888) ostate = ppp->rc_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2889) ppp->rcomp = cp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2890) ppp->rc_state = state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2891) ppp_recv_unlock(ppp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2892) if (ostate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2893) ocomp->decomp_free(ostate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2894) module_put(ocomp->owner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2895) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2896) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2897) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2898) module_put(cp->owner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2899) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2900)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2901) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2902) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2903) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2904)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2905) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2906) * Look at a CCP packet and update our state accordingly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2907) * We assume the caller has the xmit or recv path locked.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2908) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2909) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2910) ppp_ccp_peek(struct ppp *ppp, struct sk_buff *skb, int inbound)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2911) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2912) unsigned char *dp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2913) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2914)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2915) if (!pskb_may_pull(skb, CCP_HDRLEN + 2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2916) return; /* no header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2917) dp = skb->data + 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2918)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2919) switch (CCP_CODE(dp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2920) case CCP_CONFREQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2921)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2922) /* A ConfReq starts negotiation of compression
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2923) * in one direction of transmission,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2924) * and hence brings it down...but which way?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2925) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2926) * Remember:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2927) * A ConfReq indicates what the sender would like to receive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2928) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2929) if(inbound)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2930) /* He is proposing what I should send */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2931) ppp->xstate &= ~SC_COMP_RUN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2932) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2933) /* I am proposing to what he should send */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2934) ppp->rstate &= ~SC_DECOMP_RUN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2935)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2936) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2937)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2938) case CCP_TERMREQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2939) case CCP_TERMACK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2940) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2941) * CCP is going down, both directions of transmission
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2942) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2943) ppp->rstate &= ~SC_DECOMP_RUN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2944) ppp->xstate &= ~SC_COMP_RUN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2945) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2946)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2947) case CCP_CONFACK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2948) if ((ppp->flags & (SC_CCP_OPEN | SC_CCP_UP)) != SC_CCP_OPEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2949) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2950) len = CCP_LENGTH(dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2951) if (!pskb_may_pull(skb, len + 2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2952) return; /* too short */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2953) dp += CCP_HDRLEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2954) len -= CCP_HDRLEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2955) if (len < CCP_OPT_MINLEN || len < CCP_OPT_LENGTH(dp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2956) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2957) if (inbound) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2958) /* we will start receiving compressed packets */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2959) if (!ppp->rc_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2960) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2961) if (ppp->rcomp->decomp_init(ppp->rc_state, dp, len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2962) ppp->file.index, 0, ppp->mru, ppp->debug)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2963) ppp->rstate |= SC_DECOMP_RUN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2964) ppp->rstate &= ~(SC_DC_ERROR | SC_DC_FERROR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2965) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2966) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2967) /* we will soon start sending compressed packets */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2968) if (!ppp->xc_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2969) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2970) if (ppp->xcomp->comp_init(ppp->xc_state, dp, len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2971) ppp->file.index, 0, ppp->debug))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2972) ppp->xstate |= SC_COMP_RUN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2973) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2974) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2975)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2976) case CCP_RESETACK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2977) /* reset the [de]compressor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2978) if ((ppp->flags & SC_CCP_UP) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2979) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2980) if (inbound) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2981) if (ppp->rc_state && (ppp->rstate & SC_DECOMP_RUN)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2982) ppp->rcomp->decomp_reset(ppp->rc_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2983) ppp->rstate &= ~SC_DC_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2984) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2985) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2986) if (ppp->xc_state && (ppp->xstate & SC_COMP_RUN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2987) ppp->xcomp->comp_reset(ppp->xc_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2988) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2989) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2990) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2991) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2992)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2993) /* Free up compression resources. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2994) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2995) ppp_ccp_closed(struct ppp *ppp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2996) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2997) void *xstate, *rstate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2998) struct compressor *xcomp, *rcomp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3000) ppp_lock(ppp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3001) ppp->flags &= ~(SC_CCP_OPEN | SC_CCP_UP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3002) ppp->xstate = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3003) xcomp = ppp->xcomp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3004) xstate = ppp->xc_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3005) ppp->xc_state = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3006) ppp->rstate = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3007) rcomp = ppp->rcomp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3008) rstate = ppp->rc_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3009) ppp->rc_state = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3010) ppp_unlock(ppp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3011)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3012) if (xstate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3013) xcomp->comp_free(xstate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3014) module_put(xcomp->owner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3015) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3016) if (rstate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3017) rcomp->decomp_free(rstate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3018) module_put(rcomp->owner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3019) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3020) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3022) /* List of compressors. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3023) static LIST_HEAD(compressor_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3024) static DEFINE_SPINLOCK(compressor_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3025)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3026) struct compressor_entry {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3027) struct list_head list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3028) struct compressor *comp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3029) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3030)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3031) static struct compressor_entry *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3032) find_comp_entry(int proto)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3033) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3034) struct compressor_entry *ce;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3035)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3036) list_for_each_entry(ce, &compressor_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3037) if (ce->comp->compress_proto == proto)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3038) return ce;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3039) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3040) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3041) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3042)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3043) /* Register a compressor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3044) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3045) ppp_register_compressor(struct compressor *cp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3046) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3047) struct compressor_entry *ce;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3048) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3049) spin_lock(&compressor_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3050) ret = -EEXIST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3051) if (find_comp_entry(cp->compress_proto))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3052) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3053) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3054) ce = kmalloc(sizeof(struct compressor_entry), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3055) if (!ce)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3056) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3057) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3058) ce->comp = cp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3059) list_add(&ce->list, &compressor_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3060) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3061) spin_unlock(&compressor_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3062) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3063) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3064)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3065) /* Unregister a compressor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3066) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3067) ppp_unregister_compressor(struct compressor *cp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3068) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3069) struct compressor_entry *ce;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3070)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3071) spin_lock(&compressor_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3072) ce = find_comp_entry(cp->compress_proto);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3073) if (ce && ce->comp == cp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3074) list_del(&ce->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3075) kfree(ce);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3076) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3077) spin_unlock(&compressor_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3078) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3079)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3080) /* Find a compressor. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3081) static struct compressor *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3082) find_compressor(int type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3083) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3084) struct compressor_entry *ce;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3085) struct compressor *cp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3086)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3087) spin_lock(&compressor_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3088) ce = find_comp_entry(type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3089) if (ce) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3090) cp = ce->comp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3091) if (!try_module_get(cp->owner))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3092) cp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3093) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3094) spin_unlock(&compressor_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3095) return cp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3096) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3097)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3098) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3099) * Miscelleneous stuff.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3100) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3102) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3103) ppp_get_stats(struct ppp *ppp, struct ppp_stats *st)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3104) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3105) struct slcompress *vj = ppp->vj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3107) memset(st, 0, sizeof(*st));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3108) st->p.ppp_ipackets = ppp->stats64.rx_packets;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3109) st->p.ppp_ierrors = ppp->dev->stats.rx_errors;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3110) st->p.ppp_ibytes = ppp->stats64.rx_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3111) st->p.ppp_opackets = ppp->stats64.tx_packets;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3112) st->p.ppp_oerrors = ppp->dev->stats.tx_errors;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3113) st->p.ppp_obytes = ppp->stats64.tx_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3114) if (!vj)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3115) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3116) st->vj.vjs_packets = vj->sls_o_compressed + vj->sls_o_uncompressed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3117) st->vj.vjs_compressed = vj->sls_o_compressed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3118) st->vj.vjs_searches = vj->sls_o_searches;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3119) st->vj.vjs_misses = vj->sls_o_misses;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3120) st->vj.vjs_errorin = vj->sls_i_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3121) st->vj.vjs_tossed = vj->sls_i_tossed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3122) st->vj.vjs_uncompressedin = vj->sls_i_uncompressed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3123) st->vj.vjs_compressedin = vj->sls_i_compressed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3126) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3127) * Stuff for handling the lists of ppp units and channels
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3128) * and for initialization.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3129) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3131) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3132) * Create a new ppp interface unit. Fails if it can't allocate memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3133) * or if there is already a unit with the requested number.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3134) * unit == -1 means allocate a new number.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3135) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3136) static int ppp_create_interface(struct net *net, struct file *file, int *unit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3137) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3138) struct ppp_config conf = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3139) .file = file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3140) .unit = *unit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3141) .ifname_is_set = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3142) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3143) struct net_device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3144) struct ppp *ppp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3145) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3147) dev = alloc_netdev(sizeof(struct ppp), "", NET_NAME_ENUM, ppp_setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3148) if (!dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3149) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3150) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3152) dev_net_set(dev, net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3153) dev->rtnl_link_ops = &ppp_link_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3155) rtnl_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3157) err = ppp_dev_configure(net, dev, &conf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3158) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3159) goto err_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3160) ppp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3161) *unit = ppp->file.index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3163) rtnl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3165) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3167) err_dev:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3168) rtnl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3169) free_netdev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3170) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3171) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3174) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3175) * Initialize a ppp_file structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3176) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3177) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3178) init_ppp_file(struct ppp_file *pf, int kind)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3179) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3180) pf->kind = kind;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3181) skb_queue_head_init(&pf->xq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3182) skb_queue_head_init(&pf->rq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3183) refcount_set(&pf->refcnt, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3184) init_waitqueue_head(&pf->rwait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3185) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3187) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3188) * Free the memory used by a ppp unit. This is only called once
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3189) * there are no channels connected to the unit and no file structs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3190) * that reference the unit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3191) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3192) static void ppp_destroy_interface(struct ppp *ppp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3193) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3194) atomic_dec(&ppp_unit_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3196) if (!ppp->file.dead || ppp->n_channels) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3197) /* "can't happen" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3198) netdev_err(ppp->dev, "ppp: destroying ppp struct %p "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3199) "but dead=%d n_channels=%d !\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3200) ppp, ppp->file.dead, ppp->n_channels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3201) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3202) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3204) ppp_ccp_closed(ppp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3205) if (ppp->vj) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3206) slhc_free(ppp->vj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3207) ppp->vj = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3209) skb_queue_purge(&ppp->file.xq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3210) skb_queue_purge(&ppp->file.rq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3211) #ifdef CONFIG_PPP_MULTILINK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3212) skb_queue_purge(&ppp->mrq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3213) #endif /* CONFIG_PPP_MULTILINK */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3214) #ifdef CONFIG_PPP_FILTER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3215) if (ppp->pass_filter) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3216) bpf_prog_destroy(ppp->pass_filter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3217) ppp->pass_filter = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3218) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3220) if (ppp->active_filter) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3221) bpf_prog_destroy(ppp->active_filter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3222) ppp->active_filter = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3224) #endif /* CONFIG_PPP_FILTER */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3226) kfree_skb(ppp->xmit_pending);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3227) free_percpu(ppp->xmit_recursion);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3229) free_netdev(ppp->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3230) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3232) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3233) * Locate an existing ppp unit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3234) * The caller should have locked the all_ppp_mutex.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3235) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3236) static struct ppp *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3237) ppp_find_unit(struct ppp_net *pn, int unit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3238) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3239) return unit_find(&pn->units_idr, unit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3240) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3242) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3243) * Locate an existing ppp channel.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3244) * The caller should have locked the all_channels_lock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3245) * First we look in the new_channels list, then in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3246) * all_channels list. If found in the new_channels list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3247) * we move it to the all_channels list. This is for speed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3248) * when we have a lot of channels in use.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3249) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3250) static struct channel *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3251) ppp_find_channel(struct ppp_net *pn, int unit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3252) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3253) struct channel *pch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3255) list_for_each_entry(pch, &pn->new_channels, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3256) if (pch->file.index == unit) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3257) list_move(&pch->list, &pn->all_channels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3258) return pch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3259) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3262) list_for_each_entry(pch, &pn->all_channels, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3263) if (pch->file.index == unit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3264) return pch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3265) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3267) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3270) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3271) * Connect a PPP channel to a PPP interface unit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3272) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3273) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3274) ppp_connect_channel(struct channel *pch, int unit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3275) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3276) struct ppp *ppp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3277) struct ppp_net *pn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3278) int ret = -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3279) int hdrlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3281) pn = ppp_pernet(pch->chan_net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3283) mutex_lock(&pn->all_ppp_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3284) ppp = ppp_find_unit(pn, unit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3285) if (!ppp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3286) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3287) write_lock_bh(&pch->upl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3288) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3289) if (pch->ppp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3290) goto outl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3292) ppp_lock(ppp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3293) spin_lock_bh(&pch->downl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3294) if (!pch->chan) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3295) /* Don't connect unregistered channels */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3296) spin_unlock_bh(&pch->downl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3297) ppp_unlock(ppp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3298) ret = -ENOTCONN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3299) goto outl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3300) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3301) spin_unlock_bh(&pch->downl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3302) if (pch->file.hdrlen > ppp->file.hdrlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3303) ppp->file.hdrlen = pch->file.hdrlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3304) hdrlen = pch->file.hdrlen + 2; /* for protocol bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3305) if (hdrlen > ppp->dev->hard_header_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3306) ppp->dev->hard_header_len = hdrlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3307) list_add_tail(&pch->clist, &ppp->channels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3308) ++ppp->n_channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3309) pch->ppp = ppp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3310) refcount_inc(&ppp->file.refcnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3311) ppp_unlock(ppp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3312) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3314) outl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3315) write_unlock_bh(&pch->upl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3316) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3317) mutex_unlock(&pn->all_ppp_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3318) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3321) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3322) * Disconnect a channel from its ppp unit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3323) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3324) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3325) ppp_disconnect_channel(struct channel *pch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3326) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3327) struct ppp *ppp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3328) int err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3330) write_lock_bh(&pch->upl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3331) ppp = pch->ppp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3332) pch->ppp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3333) write_unlock_bh(&pch->upl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3334) if (ppp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3335) /* remove it from the ppp unit's list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3336) ppp_lock(ppp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3337) list_del(&pch->clist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3338) if (--ppp->n_channels == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3339) wake_up_interruptible(&ppp->file.rwait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3340) ppp_unlock(ppp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3341) if (refcount_dec_and_test(&ppp->file.refcnt))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3342) ppp_destroy_interface(ppp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3343) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3344) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3345) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3346) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3348) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3349) * Free up the resources used by a ppp channel.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3350) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3351) static void ppp_destroy_channel(struct channel *pch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3352) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3353) put_net(pch->chan_net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3354) pch->chan_net = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3356) atomic_dec(&channel_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3358) if (!pch->file.dead) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3359) /* "can't happen" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3360) pr_err("ppp: destroying undead channel %p !\n", pch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3361) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3362) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3363) skb_queue_purge(&pch->file.xq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3364) skb_queue_purge(&pch->file.rq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3365) kfree(pch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3366) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3368) static void __exit ppp_cleanup(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3369) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3370) /* should never happen */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3371) if (atomic_read(&ppp_unit_count) || atomic_read(&channel_count))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3372) pr_err("PPP: removing module but units remain!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3373) rtnl_link_unregister(&ppp_link_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3374) unregister_chrdev(PPP_MAJOR, "ppp");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3375) device_destroy(ppp_class, MKDEV(PPP_MAJOR, 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3376) class_destroy(ppp_class);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3377) unregister_pernet_device(&ppp_net_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3378) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3380) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3381) * Units handling. Caller must protect concurrent access
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3382) * by holding all_ppp_mutex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3383) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3385) /* associate pointer with specified number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3386) static int unit_set(struct idr *p, void *ptr, int n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3387) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3388) int unit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3390) unit = idr_alloc(p, ptr, n, n + 1, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3391) if (unit == -ENOSPC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3392) unit = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3393) return unit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3394) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3396) /* get new free unit number and associate pointer with it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3397) static int unit_get(struct idr *p, void *ptr, int min)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3398) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3399) return idr_alloc(p, ptr, min, 0, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3400) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3402) /* put unit number back to a pool */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3403) static void unit_put(struct idr *p, int n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3404) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3405) idr_remove(p, n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3406) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3408) /* get pointer associated with the number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3409) static void *unit_find(struct idr *p, int n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3410) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3411) return idr_find(p, n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3412) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3414) /* Module/initialization stuff */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3416) module_init(ppp_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3417) module_exit(ppp_cleanup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3419) EXPORT_SYMBOL(ppp_register_net_channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3420) EXPORT_SYMBOL(ppp_register_channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3421) EXPORT_SYMBOL(ppp_unregister_channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3422) EXPORT_SYMBOL(ppp_channel_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3423) EXPORT_SYMBOL(ppp_unit_number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3424) EXPORT_SYMBOL(ppp_dev_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3425) EXPORT_SYMBOL(ppp_input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3426) EXPORT_SYMBOL(ppp_input_error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3427) EXPORT_SYMBOL(ppp_output_wakeup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3428) EXPORT_SYMBOL(ppp_register_compressor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3429) EXPORT_SYMBOL(ppp_unregister_compressor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3430) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3431) MODULE_ALIAS_CHARDEV(PPP_MAJOR, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3432) MODULE_ALIAS_RTNL_LINK("ppp");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3433) MODULE_ALIAS("devname:ppp");