cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

lapb_iface.c (11671B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 *	LAPB release 002
      4 *
      5 *	This code REQUIRES 2.1.15 or higher/ NET3.038
      6 *
      7 *	History
      8 *	LAPB 001	Jonathan Naylor	Started Coding
      9 *	LAPB 002	Jonathan Naylor	New timer architecture.
     10 *	2000-10-29	Henner Eisen	lapb_data_indication() return status.
     11 */
     12
     13#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
     14
     15#include <linux/module.h>
     16#include <linux/errno.h>
     17#include <linux/types.h>
     18#include <linux/socket.h>
     19#include <linux/in.h>
     20#include <linux/kernel.h>
     21#include <linux/jiffies.h>
     22#include <linux/timer.h>
     23#include <linux/string.h>
     24#include <linux/sockios.h>
     25#include <linux/net.h>
     26#include <linux/inet.h>
     27#include <linux/if_arp.h>
     28#include <linux/skbuff.h>
     29#include <linux/slab.h>
     30#include <net/sock.h>
     31#include <linux/uaccess.h>
     32#include <linux/fcntl.h>
     33#include <linux/mm.h>
     34#include <linux/interrupt.h>
     35#include <linux/stat.h>
     36#include <linux/init.h>
     37#include <net/lapb.h>
     38
     39static LIST_HEAD(lapb_list);
     40static DEFINE_RWLOCK(lapb_list_lock);
     41
     42/*
     43 *	Free an allocated lapb control block.
     44 */
     45static void lapb_free_cb(struct lapb_cb *lapb)
     46{
     47	kfree(lapb);
     48}
     49
     50static __inline__ void lapb_hold(struct lapb_cb *lapb)
     51{
     52	refcount_inc(&lapb->refcnt);
     53}
     54
     55static __inline__ void lapb_put(struct lapb_cb *lapb)
     56{
     57	if (refcount_dec_and_test(&lapb->refcnt))
     58		lapb_free_cb(lapb);
     59}
     60
     61/*
     62 *	Socket removal during an interrupt is now safe.
     63 */
     64static void __lapb_remove_cb(struct lapb_cb *lapb)
     65{
     66	if (lapb->node.next) {
     67		list_del(&lapb->node);
     68		lapb_put(lapb);
     69	}
     70}
     71
     72/*
     73 *	Add a socket to the bound sockets list.
     74 */
     75static void __lapb_insert_cb(struct lapb_cb *lapb)
     76{
     77	list_add(&lapb->node, &lapb_list);
     78	lapb_hold(lapb);
     79}
     80
     81static struct lapb_cb *__lapb_devtostruct(struct net_device *dev)
     82{
     83	struct lapb_cb *lapb, *use = NULL;
     84
     85	list_for_each_entry(lapb, &lapb_list, node) {
     86		if (lapb->dev == dev) {
     87			use = lapb;
     88			break;
     89		}
     90	}
     91
     92	if (use)
     93		lapb_hold(use);
     94
     95	return use;
     96}
     97
     98static struct lapb_cb *lapb_devtostruct(struct net_device *dev)
     99{
    100	struct lapb_cb *rc;
    101
    102	read_lock_bh(&lapb_list_lock);
    103	rc = __lapb_devtostruct(dev);
    104	read_unlock_bh(&lapb_list_lock);
    105
    106	return rc;
    107}
    108/*
    109 *	Create an empty LAPB control block.
    110 */
    111static struct lapb_cb *lapb_create_cb(void)
    112{
    113	struct lapb_cb *lapb = kzalloc(sizeof(*lapb), GFP_ATOMIC);
    114
    115	if (!lapb)
    116		goto out;
    117
    118	skb_queue_head_init(&lapb->write_queue);
    119	skb_queue_head_init(&lapb->ack_queue);
    120
    121	timer_setup(&lapb->t1timer, NULL, 0);
    122	timer_setup(&lapb->t2timer, NULL, 0);
    123	lapb->t1timer_running = false;
    124	lapb->t2timer_running = false;
    125
    126	lapb->t1      = LAPB_DEFAULT_T1;
    127	lapb->t2      = LAPB_DEFAULT_T2;
    128	lapb->n2      = LAPB_DEFAULT_N2;
    129	lapb->mode    = LAPB_DEFAULT_MODE;
    130	lapb->window  = LAPB_DEFAULT_WINDOW;
    131	lapb->state   = LAPB_STATE_0;
    132
    133	spin_lock_init(&lapb->lock);
    134	refcount_set(&lapb->refcnt, 1);
    135out:
    136	return lapb;
    137}
    138
    139int lapb_register(struct net_device *dev,
    140		  const struct lapb_register_struct *callbacks)
    141{
    142	struct lapb_cb *lapb;
    143	int rc = LAPB_BADTOKEN;
    144
    145	write_lock_bh(&lapb_list_lock);
    146
    147	lapb = __lapb_devtostruct(dev);
    148	if (lapb) {
    149		lapb_put(lapb);
    150		goto out;
    151	}
    152
    153	lapb = lapb_create_cb();
    154	rc = LAPB_NOMEM;
    155	if (!lapb)
    156		goto out;
    157
    158	lapb->dev       = dev;
    159	lapb->callbacks = callbacks;
    160
    161	__lapb_insert_cb(lapb);
    162
    163	lapb_start_t1timer(lapb);
    164
    165	rc = LAPB_OK;
    166out:
    167	write_unlock_bh(&lapb_list_lock);
    168	return rc;
    169}
    170EXPORT_SYMBOL(lapb_register);
    171
    172int lapb_unregister(struct net_device *dev)
    173{
    174	struct lapb_cb *lapb;
    175	int rc = LAPB_BADTOKEN;
    176
    177	write_lock_bh(&lapb_list_lock);
    178	lapb = __lapb_devtostruct(dev);
    179	if (!lapb)
    180		goto out;
    181	lapb_put(lapb);
    182
    183	/* Wait for other refs to "lapb" to drop */
    184	while (refcount_read(&lapb->refcnt) > 2)
    185		usleep_range(1, 10);
    186
    187	spin_lock_bh(&lapb->lock);
    188
    189	lapb_stop_t1timer(lapb);
    190	lapb_stop_t2timer(lapb);
    191
    192	lapb_clear_queues(lapb);
    193
    194	spin_unlock_bh(&lapb->lock);
    195
    196	/* Wait for running timers to stop */
    197	del_timer_sync(&lapb->t1timer);
    198	del_timer_sync(&lapb->t2timer);
    199
    200	__lapb_remove_cb(lapb);
    201
    202	lapb_put(lapb);
    203	rc = LAPB_OK;
    204out:
    205	write_unlock_bh(&lapb_list_lock);
    206	return rc;
    207}
    208EXPORT_SYMBOL(lapb_unregister);
    209
    210int lapb_getparms(struct net_device *dev, struct lapb_parms_struct *parms)
    211{
    212	int rc = LAPB_BADTOKEN;
    213	struct lapb_cb *lapb = lapb_devtostruct(dev);
    214
    215	if (!lapb)
    216		goto out;
    217
    218	spin_lock_bh(&lapb->lock);
    219
    220	parms->t1      = lapb->t1 / HZ;
    221	parms->t2      = lapb->t2 / HZ;
    222	parms->n2      = lapb->n2;
    223	parms->n2count = lapb->n2count;
    224	parms->state   = lapb->state;
    225	parms->window  = lapb->window;
    226	parms->mode    = lapb->mode;
    227
    228	if (!timer_pending(&lapb->t1timer))
    229		parms->t1timer = 0;
    230	else
    231		parms->t1timer = (lapb->t1timer.expires - jiffies) / HZ;
    232
    233	if (!timer_pending(&lapb->t2timer))
    234		parms->t2timer = 0;
    235	else
    236		parms->t2timer = (lapb->t2timer.expires - jiffies) / HZ;
    237
    238	spin_unlock_bh(&lapb->lock);
    239	lapb_put(lapb);
    240	rc = LAPB_OK;
    241out:
    242	return rc;
    243}
    244EXPORT_SYMBOL(lapb_getparms);
    245
    246int lapb_setparms(struct net_device *dev, struct lapb_parms_struct *parms)
    247{
    248	int rc = LAPB_BADTOKEN;
    249	struct lapb_cb *lapb = lapb_devtostruct(dev);
    250
    251	if (!lapb)
    252		goto out;
    253
    254	spin_lock_bh(&lapb->lock);
    255
    256	rc = LAPB_INVALUE;
    257	if (parms->t1 < 1 || parms->t2 < 1 || parms->n2 < 1)
    258		goto out_put;
    259
    260	if (lapb->state == LAPB_STATE_0) {
    261		if (parms->mode & LAPB_EXTENDED) {
    262			if (parms->window < 1 || parms->window > 127)
    263				goto out_put;
    264		} else {
    265			if (parms->window < 1 || parms->window > 7)
    266				goto out_put;
    267		}
    268		lapb->mode    = parms->mode;
    269		lapb->window  = parms->window;
    270	}
    271
    272	lapb->t1    = parms->t1 * HZ;
    273	lapb->t2    = parms->t2 * HZ;
    274	lapb->n2    = parms->n2;
    275
    276	rc = LAPB_OK;
    277out_put:
    278	spin_unlock_bh(&lapb->lock);
    279	lapb_put(lapb);
    280out:
    281	return rc;
    282}
    283EXPORT_SYMBOL(lapb_setparms);
    284
    285int lapb_connect_request(struct net_device *dev)
    286{
    287	struct lapb_cb *lapb = lapb_devtostruct(dev);
    288	int rc = LAPB_BADTOKEN;
    289
    290	if (!lapb)
    291		goto out;
    292
    293	spin_lock_bh(&lapb->lock);
    294
    295	rc = LAPB_OK;
    296	if (lapb->state == LAPB_STATE_1)
    297		goto out_put;
    298
    299	rc = LAPB_CONNECTED;
    300	if (lapb->state == LAPB_STATE_3 || lapb->state == LAPB_STATE_4)
    301		goto out_put;
    302
    303	lapb_establish_data_link(lapb);
    304
    305	lapb_dbg(0, "(%p) S0 -> S1\n", lapb->dev);
    306	lapb->state = LAPB_STATE_1;
    307
    308	rc = LAPB_OK;
    309out_put:
    310	spin_unlock_bh(&lapb->lock);
    311	lapb_put(lapb);
    312out:
    313	return rc;
    314}
    315EXPORT_SYMBOL(lapb_connect_request);
    316
    317static int __lapb_disconnect_request(struct lapb_cb *lapb)
    318{
    319	switch (lapb->state) {
    320	case LAPB_STATE_0:
    321		return LAPB_NOTCONNECTED;
    322
    323	case LAPB_STATE_1:
    324		lapb_dbg(1, "(%p) S1 TX DISC(1)\n", lapb->dev);
    325		lapb_dbg(0, "(%p) S1 -> S0\n", lapb->dev);
    326		lapb_send_control(lapb, LAPB_DISC, LAPB_POLLON, LAPB_COMMAND);
    327		lapb->state = LAPB_STATE_0;
    328		lapb_start_t1timer(lapb);
    329		return LAPB_NOTCONNECTED;
    330
    331	case LAPB_STATE_2:
    332		return LAPB_OK;
    333	}
    334
    335	lapb_clear_queues(lapb);
    336	lapb->n2count = 0;
    337	lapb_send_control(lapb, LAPB_DISC, LAPB_POLLON, LAPB_COMMAND);
    338	lapb_start_t1timer(lapb);
    339	lapb_stop_t2timer(lapb);
    340	lapb->state = LAPB_STATE_2;
    341
    342	lapb_dbg(1, "(%p) S3 DISC(1)\n", lapb->dev);
    343	lapb_dbg(0, "(%p) S3 -> S2\n", lapb->dev);
    344
    345	return LAPB_OK;
    346}
    347
    348int lapb_disconnect_request(struct net_device *dev)
    349{
    350	struct lapb_cb *lapb = lapb_devtostruct(dev);
    351	int rc = LAPB_BADTOKEN;
    352
    353	if (!lapb)
    354		goto out;
    355
    356	spin_lock_bh(&lapb->lock);
    357
    358	rc = __lapb_disconnect_request(lapb);
    359
    360	spin_unlock_bh(&lapb->lock);
    361	lapb_put(lapb);
    362out:
    363	return rc;
    364}
    365EXPORT_SYMBOL(lapb_disconnect_request);
    366
    367int lapb_data_request(struct net_device *dev, struct sk_buff *skb)
    368{
    369	struct lapb_cb *lapb = lapb_devtostruct(dev);
    370	int rc = LAPB_BADTOKEN;
    371
    372	if (!lapb)
    373		goto out;
    374
    375	spin_lock_bh(&lapb->lock);
    376
    377	rc = LAPB_NOTCONNECTED;
    378	if (lapb->state != LAPB_STATE_3 && lapb->state != LAPB_STATE_4)
    379		goto out_put;
    380
    381	skb_queue_tail(&lapb->write_queue, skb);
    382	lapb_kick(lapb);
    383	rc = LAPB_OK;
    384out_put:
    385	spin_unlock_bh(&lapb->lock);
    386	lapb_put(lapb);
    387out:
    388	return rc;
    389}
    390EXPORT_SYMBOL(lapb_data_request);
    391
    392int lapb_data_received(struct net_device *dev, struct sk_buff *skb)
    393{
    394	struct lapb_cb *lapb = lapb_devtostruct(dev);
    395	int rc = LAPB_BADTOKEN;
    396
    397	if (lapb) {
    398		spin_lock_bh(&lapb->lock);
    399		lapb_data_input(lapb, skb);
    400		spin_unlock_bh(&lapb->lock);
    401		lapb_put(lapb);
    402		rc = LAPB_OK;
    403	}
    404
    405	return rc;
    406}
    407EXPORT_SYMBOL(lapb_data_received);
    408
    409void lapb_connect_confirmation(struct lapb_cb *lapb, int reason)
    410{
    411	if (lapb->callbacks->connect_confirmation)
    412		lapb->callbacks->connect_confirmation(lapb->dev, reason);
    413}
    414
    415void lapb_connect_indication(struct lapb_cb *lapb, int reason)
    416{
    417	if (lapb->callbacks->connect_indication)
    418		lapb->callbacks->connect_indication(lapb->dev, reason);
    419}
    420
    421void lapb_disconnect_confirmation(struct lapb_cb *lapb, int reason)
    422{
    423	if (lapb->callbacks->disconnect_confirmation)
    424		lapb->callbacks->disconnect_confirmation(lapb->dev, reason);
    425}
    426
    427void lapb_disconnect_indication(struct lapb_cb *lapb, int reason)
    428{
    429	if (lapb->callbacks->disconnect_indication)
    430		lapb->callbacks->disconnect_indication(lapb->dev, reason);
    431}
    432
    433int lapb_data_indication(struct lapb_cb *lapb, struct sk_buff *skb)
    434{
    435	if (lapb->callbacks->data_indication)
    436		return lapb->callbacks->data_indication(lapb->dev, skb);
    437
    438	kfree_skb(skb);
    439	return NET_RX_SUCCESS; /* For now; must be != NET_RX_DROP */
    440}
    441
    442int lapb_data_transmit(struct lapb_cb *lapb, struct sk_buff *skb)
    443{
    444	int used = 0;
    445
    446	if (lapb->callbacks->data_transmit) {
    447		lapb->callbacks->data_transmit(lapb->dev, skb);
    448		used = 1;
    449	}
    450
    451	return used;
    452}
    453
    454/* Handle device status changes. */
    455static int lapb_device_event(struct notifier_block *this, unsigned long event,
    456			     void *ptr)
    457{
    458	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
    459	struct lapb_cb *lapb;
    460
    461	if (!net_eq(dev_net(dev), &init_net))
    462		return NOTIFY_DONE;
    463
    464	if (dev->type != ARPHRD_X25)
    465		return NOTIFY_DONE;
    466
    467	lapb = lapb_devtostruct(dev);
    468	if (!lapb)
    469		return NOTIFY_DONE;
    470
    471	spin_lock_bh(&lapb->lock);
    472
    473	switch (event) {
    474	case NETDEV_UP:
    475		lapb_dbg(0, "(%p) Interface up: %s\n", dev, dev->name);
    476
    477		if (netif_carrier_ok(dev)) {
    478			lapb_dbg(0, "(%p): Carrier is already up: %s\n", dev,
    479				 dev->name);
    480			if (lapb->mode & LAPB_DCE) {
    481				lapb_start_t1timer(lapb);
    482			} else {
    483				if (lapb->state == LAPB_STATE_0) {
    484					lapb->state = LAPB_STATE_1;
    485					lapb_establish_data_link(lapb);
    486				}
    487			}
    488		}
    489		break;
    490	case NETDEV_GOING_DOWN:
    491		if (netif_carrier_ok(dev))
    492			__lapb_disconnect_request(lapb);
    493		break;
    494	case NETDEV_DOWN:
    495		lapb_dbg(0, "(%p) Interface down: %s\n", dev, dev->name);
    496		lapb_dbg(0, "(%p) S%d -> S0\n", dev, lapb->state);
    497		lapb_clear_queues(lapb);
    498		lapb->state = LAPB_STATE_0;
    499		lapb->n2count   = 0;
    500		lapb_stop_t1timer(lapb);
    501		lapb_stop_t2timer(lapb);
    502		break;
    503	case NETDEV_CHANGE:
    504		if (netif_carrier_ok(dev)) {
    505			lapb_dbg(0, "(%p): Carrier detected: %s\n", dev,
    506				 dev->name);
    507			if (lapb->mode & LAPB_DCE) {
    508				lapb_start_t1timer(lapb);
    509			} else {
    510				if (lapb->state == LAPB_STATE_0) {
    511					lapb->state = LAPB_STATE_1;
    512					lapb_establish_data_link(lapb);
    513				}
    514			}
    515		} else {
    516			lapb_dbg(0, "(%p) Carrier lost: %s\n", dev, dev->name);
    517			lapb_dbg(0, "(%p) S%d -> S0\n", dev, lapb->state);
    518			lapb_clear_queues(lapb);
    519			lapb->state = LAPB_STATE_0;
    520			lapb->n2count   = 0;
    521			lapb_stop_t1timer(lapb);
    522			lapb_stop_t2timer(lapb);
    523		}
    524		break;
    525	}
    526
    527	spin_unlock_bh(&lapb->lock);
    528	lapb_put(lapb);
    529	return NOTIFY_DONE;
    530}
    531
    532static struct notifier_block lapb_dev_notifier = {
    533	.notifier_call = lapb_device_event,
    534};
    535
    536static int __init lapb_init(void)
    537{
    538	return register_netdevice_notifier(&lapb_dev_notifier);
    539}
    540
    541static void __exit lapb_exit(void)
    542{
    543	WARN_ON(!list_empty(&lapb_list));
    544
    545	unregister_netdevice_notifier(&lapb_dev_notifier);
    546}
    547
    548MODULE_AUTHOR("Jonathan Naylor <g4klx@g4klx.demon.co.uk>");
    549MODULE_DESCRIPTION("The X.25 Link Access Procedure B link layer protocol");
    550MODULE_LICENSE("GPL");
    551
    552module_init(lapb_init);
    553module_exit(lapb_exit);