Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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) /* net/atm/pppoatm.c - RFC2364 PPP over ATM/AAL5 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4) /* Copyright 1999-2000 by Mitchell Blank Jr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) /* Based on clip.c; 1995-1999 by Werner Almesberger, EPFL LRC/ICA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) /* And on ppp_async.c; Copyright 1999 Paul Mackerras */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) /* And help from Jens Axboe */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  * This driver provides the encapsulation and framing for sending
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  * and receiving PPP frames in ATM AAL5 PDUs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16)  * One shortcoming of this driver is that it does not comply with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17)  * section 8 of RFC2364 - we are supposed to detect a change
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18)  * in encapsulation and immediately abort the connection (in order
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19)  * to avoid a black-hole being created if our peer loses state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20)  * and changes encapsulation unilaterally.  However, since the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21)  * ppp_generic layer actually does the decapsulation, we need
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22)  * a way of notifying it when we _think_ there might be a problem)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23)  * There's two cases:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24)  *   1.	LLC-encapsulation was missing when it was enabled.  In
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25)  *	this case, we should tell the upper layer "tear down
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26)  *	this session if this skb looks ok to you"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27)  *   2.	LLC-encapsulation was present when it was disabled.  Then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28)  *	we need to tell the upper layer "this packet may be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29)  *	ok, but if its in error tear down the session"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30)  * These hooks are not yet available in ppp_generic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) #define pr_fmt(fmt) KBUILD_MODNAME ":%s: " fmt, __func__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) #include <linux/skbuff.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) #include <linux/atm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) #include <linux/atmdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) #include <linux/capability.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) #include <linux/ppp_defs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) #include <linux/ppp-ioctl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) #include <linux/ppp_channel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) #include <linux/atmppp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) #include "common.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) enum pppoatm_encaps {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	e_autodetect = PPPOATM_ENCAPS_AUTODETECT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	e_vc = PPPOATM_ENCAPS_VC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	e_llc = PPPOATM_ENCAPS_LLC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) struct pppoatm_vcc {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	struct atm_vcc	*atmvcc;	/* VCC descriptor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	void (*old_push)(struct atm_vcc *, struct sk_buff *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	void (*old_pop)(struct atm_vcc *, struct sk_buff *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	void (*old_release_cb)(struct atm_vcc *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	struct module *old_owner;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 					/* keep old push/pop for detaching */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	enum pppoatm_encaps encaps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	atomic_t inflight;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	unsigned long blocked;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	int flags;			/* SC_COMP_PROT - compress protocol */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	struct ppp_channel chan;	/* interface to generic ppp layer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	struct tasklet_struct wakeup_tasklet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72)  * We want to allow two packets in the queue. The one that's currently in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73)  * flight, and *one* queued up ready for the ATM device to send immediately
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74)  * from its TX done IRQ. We want to be able to use atomic_inc_not_zero(), so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75)  * inflight == -2 represents an empty queue, -1 one packet, and zero means
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76)  * there are two packets in the queue.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) #define NONE_INFLIGHT -2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) #define BLOCKED 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83)  * Header used for LLC Encapsulated PPP (4 bytes) followed by the LCP protocol
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84)  * ID (0xC021) used in autodetection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) static const unsigned char pppllc[6] = { 0xFE, 0xFE, 0x03, 0xCF, 0xC0, 0x21 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) #define LLC_LEN		(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) static inline struct pppoatm_vcc *atmvcc_to_pvcc(const struct atm_vcc *atmvcc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	return (struct pppoatm_vcc *) (atmvcc->user_back);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) static inline struct pppoatm_vcc *chan_to_pvcc(const struct ppp_channel *chan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	return (struct pppoatm_vcc *) (chan->private);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)  * We can't do this directly from our _pop handler, since the ppp code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)  * doesn't want to be called in interrupt context, so we do it from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)  * a tasklet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) static void pppoatm_wakeup_sender(unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	ppp_output_wakeup((struct ppp_channel *) arg);
^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) static void pppoatm_release_cb(struct atm_vcc *atmvcc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	struct pppoatm_vcc *pvcc = atmvcc_to_pvcc(atmvcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	 * As in pppoatm_pop(), it's safe to clear the BLOCKED bit here because
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	 * the wakeup *can't* race with pppoatm_send(). They both hold the PPP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	 * channel's ->downl lock. And the potential race with *setting* it,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	 * which leads to the double-check dance in pppoatm_may_send(), doesn't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	 * exist here. In the sock_owned_by_user() case in pppoatm_send(), we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	 * set the BLOCKED bit while the socket is still locked. We know that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	 * ->release_cb() can't be called until that's done.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	if (test_and_clear_bit(BLOCKED, &pvcc->blocked))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 		tasklet_schedule(&pvcc->wakeup_tasklet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	if (pvcc->old_release_cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 		pvcc->old_release_cb(atmvcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)  * This gets called every time the ATM card has finished sending our
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)  * skb.  The ->old_pop will take care up normal atm flow control,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)  * but we also need to wake up the device if we blocked it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) static void pppoatm_pop(struct atm_vcc *atmvcc, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	struct pppoatm_vcc *pvcc = atmvcc_to_pvcc(atmvcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	pvcc->old_pop(atmvcc, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	atomic_dec(&pvcc->inflight);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	 * We always used to run the wakeup tasklet unconditionally here, for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	 * fear of race conditions where we clear the BLOCKED flag just as we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	 * refuse another packet in pppoatm_send(). This was quite inefficient.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	 * In fact it's OK. The PPP core will only ever call pppoatm_send()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	 * while holding the channel->downl lock. And ppp_output_wakeup() as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	 * called by the tasklet will *also* grab that lock. So even if another
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	 * CPU is in pppoatm_send() right now, the tasklet isn't going to race
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	 * with it. The wakeup *will* happen after the other CPU is safely out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	 * of pppoatm_send() again.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	 * So if the CPU in pppoatm_send() has already set the BLOCKED bit and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	 * it about to return, that's fine. We trigger a wakeup which will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	 * happen later. And if the CPU in pppoatm_send() *hasn't* set the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	 * BLOCKED bit yet, that's fine too because of the double check in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	 * pppoatm_may_send() which is commented there.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	if (test_and_clear_bit(BLOCKED, &pvcc->blocked))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 		tasklet_schedule(&pvcc->wakeup_tasklet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)  * Unbind from PPP - currently we only do this when closing the socket,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)  * but we could put this into an ioctl if need be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) static void pppoatm_unassign_vcc(struct atm_vcc *atmvcc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	struct pppoatm_vcc *pvcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	pvcc = atmvcc_to_pvcc(atmvcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	atmvcc->push = pvcc->old_push;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	atmvcc->pop = pvcc->old_pop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	atmvcc->release_cb = pvcc->old_release_cb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	tasklet_kill(&pvcc->wakeup_tasklet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	ppp_unregister_channel(&pvcc->chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	atmvcc->user_back = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	kfree(pvcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) /* Called when an AAL5 PDU comes in */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) static void pppoatm_push(struct atm_vcc *atmvcc, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	struct pppoatm_vcc *pvcc = atmvcc_to_pvcc(atmvcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	pr_debug("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	if (skb == NULL) {			/* VCC was closed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 		struct module *module;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 		pr_debug("removing ATMPPP VCC %p\n", pvcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 		module = pvcc->old_owner;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 		pppoatm_unassign_vcc(atmvcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 		atmvcc->push(atmvcc, NULL);	/* Pass along bad news */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 		module_put(module);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	atm_return(atmvcc, skb->truesize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	switch (pvcc->encaps) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	case e_llc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 		if (skb->len < LLC_LEN ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 		    memcmp(skb->data, pppllc, LLC_LEN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 			goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 		skb_pull(skb, LLC_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	case e_autodetect:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 		if (pvcc->chan.ppp == NULL) {	/* Not bound yet! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 			kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 		if (skb->len >= sizeof(pppllc) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 		    !memcmp(skb->data, pppllc, sizeof(pppllc))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 			pvcc->encaps = e_llc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 			skb_pull(skb, LLC_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 		if (skb->len >= (sizeof(pppllc) - LLC_LEN) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 		    !memcmp(skb->data, &pppllc[LLC_LEN],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 		    sizeof(pppllc) - LLC_LEN)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 			pvcc->encaps = e_vc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 			pvcc->chan.mtu += LLC_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 		pr_debug("Couldn't autodetect yet (skb: %6ph)\n", skb->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 	case e_vc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 	ppp_input(&pvcc->chan, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 	kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 	ppp_input_error(&pvcc->chan, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) static int pppoatm_may_send(struct pppoatm_vcc *pvcc, int size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 	 * It's not clear that we need to bother with using atm_may_send()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 	 * to check we don't exceed sk->sk_sndbuf. If userspace sets a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 	 * value of sk_sndbuf which is lower than the MTU, we're going to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 	 * block for ever. But the code always did that before we introduced
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 	 * the packet count limit, so...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 	if (atm_may_send(pvcc->atmvcc, size) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 	    atomic_inc_not_zero(&pvcc->inflight))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 	 * We use test_and_set_bit() rather than set_bit() here because
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 	 * we need to ensure there's a memory barrier after it. The bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 	 * *must* be set before we do the atomic_inc() on pvcc->inflight.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 	 * There's no smp_mb__after_set_bit(), so it's this or abuse
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	 * smp_mb__after_atomic().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	test_and_set_bit(BLOCKED, &pvcc->blocked);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	 * We may have raced with pppoatm_pop(). If it ran for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	 * last packet in the queue, *just* before we set the BLOCKED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 	 * bit, then it might never run again and the channel could
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 	 * remain permanently blocked. Cope with that race by checking
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 	 * *again*. If it did run in that window, we'll have space on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	 * the queue now and can return success. It's harmless to leave
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 	 * the BLOCKED flag set, since it's only used as a trigger to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 	 * run the wakeup tasklet. Another wakeup will never hurt.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 	 * If pppoatm_pop() is running but hasn't got as far as making
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 	 * space on the queue yet, then it hasn't checked the BLOCKED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 	 * flag yet either, so we're safe in that case too. It'll issue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 	 * an "immediate" wakeup... where "immediate" actually involves
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 	 * taking the PPP channel's ->downl lock, which is held by the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 	 * code path that calls pppoatm_send(), and is thus going to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 	 * wait for us to finish.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 	if (atm_may_send(pvcc->atmvcc, size) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 	    atomic_inc_not_zero(&pvcc->inflight))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)  * Called by the ppp_generic.c to send a packet - returns true if packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)  * was accepted.  If we return false, then it's our job to call
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)  * ppp_output_wakeup(chan) when we're feeling more up to it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)  * Note that in the ENOMEM case (as opposed to the !atm_may_send case)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)  * we should really drop the packet, but the generic layer doesn't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)  * support this yet.  We just return 'DROP_PACKET' which we actually define
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)  * as success, just to be clear what we're really doing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) #define DROP_PACKET 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) static int pppoatm_send(struct ppp_channel *chan, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 	struct pppoatm_vcc *pvcc = chan_to_pvcc(chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 	struct atm_vcc *vcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 	ATM_SKB(skb)->vcc = pvcc->atmvcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 	pr_debug("(skb=0x%p, vcc=0x%p)\n", skb, pvcc->atmvcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 	if (skb->data[0] == '\0' && (pvcc->flags & SC_COMP_PROT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 		(void) skb_pull(skb, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 	vcc = ATM_SKB(skb)->vcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 	bh_lock_sock(sk_atm(vcc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 	if (sock_owned_by_user(sk_atm(vcc))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 		 * Needs to happen (and be flushed, hence test_and_) before we unlock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 		 * the socket. It needs to be seen by the time our ->release_cb gets
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 		 * called.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 		test_and_set_bit(BLOCKED, &pvcc->blocked);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 		goto nospace;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 	if (test_bit(ATM_VF_RELEASED, &vcc->flags) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 	    test_bit(ATM_VF_CLOSE, &vcc->flags) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 	    !test_bit(ATM_VF_READY, &vcc->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 		bh_unlock_sock(sk_atm(vcc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 		kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 		return DROP_PACKET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 	switch (pvcc->encaps) {		/* LLC encapsulation needed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	case e_llc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 		if (skb_headroom(skb) < LLC_LEN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 			struct sk_buff *n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 			n = skb_realloc_headroom(skb, LLC_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 			if (n != NULL &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 			    !pppoatm_may_send(pvcc, n->truesize)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 				kfree_skb(n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 				goto nospace;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 			consume_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 			skb = n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 			if (skb == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 				bh_unlock_sock(sk_atm(vcc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 				return DROP_PACKET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 		} else if (!pppoatm_may_send(pvcc, skb->truesize))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 			goto nospace;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 		memcpy(skb_push(skb, LLC_LEN), pppllc, LLC_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 	case e_vc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 		if (!pppoatm_may_send(pvcc, skb->truesize))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 			goto nospace;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 	case e_autodetect:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 		bh_unlock_sock(sk_atm(vcc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 		pr_debug("Trying to send without setting encaps!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 		kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 	atm_account_tx(vcc, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 	pr_debug("atm_skb(%p)->vcc(%p)->dev(%p)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 		 skb, ATM_SKB(skb)->vcc, ATM_SKB(skb)->vcc->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 	ret = ATM_SKB(skb)->vcc->send(ATM_SKB(skb)->vcc, skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 	    ? DROP_PACKET : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 	bh_unlock_sock(sk_atm(vcc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) nospace:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 	bh_unlock_sock(sk_atm(vcc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 	 * We don't have space to send this SKB now, but we might have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 	 * already applied SC_COMP_PROT compression, so may need to undo
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 	if ((pvcc->flags & SC_COMP_PROT) && skb_headroom(skb) > 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 	    skb->data[-1] == '\0')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 		(void) skb_push(skb, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) /* This handles ioctls sent to the /dev/ppp interface */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) static int pppoatm_devppp_ioctl(struct ppp_channel *chan, unsigned int cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 	unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 	switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 	case PPPIOCGFLAGS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 		return put_user(chan_to_pvcc(chan)->flags, (int __user *) arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 		    ? -EFAULT : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 	case PPPIOCSFLAGS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 		return get_user(chan_to_pvcc(chan)->flags, (int __user *) arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 		    ? -EFAULT : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 	return -ENOTTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) static const struct ppp_channel_ops pppoatm_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 	.start_xmit = pppoatm_send,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 	.ioctl = pppoatm_devppp_ioctl,
^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) static int pppoatm_assign_vcc(struct atm_vcc *atmvcc, void __user *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 	struct atm_backend_ppp be;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 	struct pppoatm_vcc *pvcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 	 * Each PPPoATM instance has its own tasklet - this is just a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 	 * prototypical one used to initialize them
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 	static const DECLARE_TASKLET_OLD(tasklet_proto, pppoatm_wakeup_sender);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 	if (copy_from_user(&be, arg, sizeof be))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 		return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 	if (be.encaps != PPPOATM_ENCAPS_AUTODETECT &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 	    be.encaps != PPPOATM_ENCAPS_VC && be.encaps != PPPOATM_ENCAPS_LLC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 	pvcc = kzalloc(sizeof(*pvcc), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 	if (pvcc == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 	pvcc->atmvcc = atmvcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 	/* Maximum is zero, so that we can use atomic_inc_not_zero() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 	atomic_set(&pvcc->inflight, NONE_INFLIGHT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 	pvcc->old_push = atmvcc->push;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 	pvcc->old_pop = atmvcc->pop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 	pvcc->old_owner = atmvcc->owner;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 	pvcc->old_release_cb = atmvcc->release_cb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 	pvcc->encaps = (enum pppoatm_encaps) be.encaps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 	pvcc->chan.private = pvcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 	pvcc->chan.ops = &pppoatm_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 	pvcc->chan.mtu = atmvcc->qos.txtp.max_sdu - PPP_HDRLEN -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 	    (be.encaps == e_vc ? 0 : LLC_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 	pvcc->wakeup_tasklet = tasklet_proto;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 	pvcc->wakeup_tasklet.data = (unsigned long) &pvcc->chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 	err = ppp_register_channel(&pvcc->chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 	if (err != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 		kfree(pvcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 	atmvcc->user_back = pvcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 	atmvcc->push = pppoatm_push;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 	atmvcc->pop = pppoatm_pop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 	atmvcc->release_cb = pppoatm_release_cb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 	__module_get(THIS_MODULE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 	atmvcc->owner = THIS_MODULE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 	/* re-process everything received between connection setup and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 	   backend setup */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 	vcc_process_recv_queue(atmvcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)  * This handles ioctls actually performed on our vcc - we must return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)  * -ENOIOCTLCMD for any unrecognized ioctl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) static int pppoatm_ioctl(struct socket *sock, unsigned int cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 	unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 	struct atm_vcc *atmvcc = ATM_SD(sock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 	void __user *argp = (void __user *)arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 	if (cmd != ATM_SETBACKEND && atmvcc->push != pppoatm_push)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 		return -ENOIOCTLCMD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 	switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 	case ATM_SETBACKEND: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 		atm_backend_t b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 		if (get_user(b, (atm_backend_t __user *) argp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 			return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 		if (b != ATM_BACKEND_PPP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 			return -ENOIOCTLCMD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 		if (!capable(CAP_NET_ADMIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 			return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 		if (sock->state != SS_CONNECTED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 		return pppoatm_assign_vcc(atmvcc, argp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 	case PPPIOCGCHAN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 		return put_user(ppp_channel_index(&atmvcc_to_pvcc(atmvcc)->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 		    chan), (int __user *) argp) ? -EFAULT : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 	case PPPIOCGUNIT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 		return put_user(ppp_unit_number(&atmvcc_to_pvcc(atmvcc)->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 		    chan), (int __user *) argp) ? -EFAULT : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 	return -ENOIOCTLCMD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) static struct atm_ioctl pppoatm_ioctl_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 	.owner	= THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 	.ioctl	= pppoatm_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) static int __init pppoatm_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 	register_atm_ioctl(&pppoatm_ioctl_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) static void __exit pppoatm_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 	deregister_atm_ioctl(&pppoatm_ioctl_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) module_init(pppoatm_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) module_exit(pppoatm_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) MODULE_AUTHOR("Mitchell Blank Jr <mitch@sfgoth.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) MODULE_DESCRIPTION("RFC2364 PPP over ATM/AAL5");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) MODULE_LICENSE("GPL");