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

ax25_dev.c (5069B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 *
      4 * Copyright (C) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
      5 */
      6#include <linux/errno.h>
      7#include <linux/types.h>
      8#include <linux/socket.h>
      9#include <linux/slab.h>
     10#include <linux/in.h>
     11#include <linux/kernel.h>
     12#include <linux/timer.h>
     13#include <linux/string.h>
     14#include <linux/sockios.h>
     15#include <linux/net.h>
     16#include <linux/spinlock.h>
     17#include <net/ax25.h>
     18#include <linux/inet.h>
     19#include <linux/netdevice.h>
     20#include <linux/if_arp.h>
     21#include <linux/skbuff.h>
     22#include <net/sock.h>
     23#include <linux/uaccess.h>
     24#include <linux/fcntl.h>
     25#include <linux/mm.h>
     26#include <linux/interrupt.h>
     27#include <linux/init.h>
     28
     29ax25_dev *ax25_dev_list;
     30DEFINE_SPINLOCK(ax25_dev_lock);
     31
     32ax25_dev *ax25_addr_ax25dev(ax25_address *addr)
     33{
     34	ax25_dev *ax25_dev, *res = NULL;
     35
     36	spin_lock_bh(&ax25_dev_lock);
     37	for (ax25_dev = ax25_dev_list; ax25_dev != NULL; ax25_dev = ax25_dev->next)
     38		if (ax25cmp(addr, (const ax25_address *)ax25_dev->dev->dev_addr) == 0) {
     39			res = ax25_dev;
     40			ax25_dev_hold(ax25_dev);
     41		}
     42	spin_unlock_bh(&ax25_dev_lock);
     43
     44	return res;
     45}
     46
     47/*
     48 *	This is called when an interface is brought up. These are
     49 *	reasonable defaults.
     50 */
     51void ax25_dev_device_up(struct net_device *dev)
     52{
     53	ax25_dev *ax25_dev;
     54
     55	if ((ax25_dev = kzalloc(sizeof(*ax25_dev), GFP_ATOMIC)) == NULL) {
     56		printk(KERN_ERR "AX.25: ax25_dev_device_up - out of memory\n");
     57		return;
     58	}
     59
     60	refcount_set(&ax25_dev->refcount, 1);
     61	dev->ax25_ptr     = ax25_dev;
     62	ax25_dev->dev     = dev;
     63	dev_hold_track(dev, &ax25_dev->dev_tracker, GFP_ATOMIC);
     64	ax25_dev->forward = NULL;
     65	ax25_dev->device_up = true;
     66
     67	ax25_dev->values[AX25_VALUES_IPDEFMODE] = AX25_DEF_IPDEFMODE;
     68	ax25_dev->values[AX25_VALUES_AXDEFMODE] = AX25_DEF_AXDEFMODE;
     69	ax25_dev->values[AX25_VALUES_BACKOFF]   = AX25_DEF_BACKOFF;
     70	ax25_dev->values[AX25_VALUES_CONMODE]   = AX25_DEF_CONMODE;
     71	ax25_dev->values[AX25_VALUES_WINDOW]    = AX25_DEF_WINDOW;
     72	ax25_dev->values[AX25_VALUES_EWINDOW]   = AX25_DEF_EWINDOW;
     73	ax25_dev->values[AX25_VALUES_T1]        = AX25_DEF_T1;
     74	ax25_dev->values[AX25_VALUES_T2]        = AX25_DEF_T2;
     75	ax25_dev->values[AX25_VALUES_T3]        = AX25_DEF_T3;
     76	ax25_dev->values[AX25_VALUES_IDLE]	= AX25_DEF_IDLE;
     77	ax25_dev->values[AX25_VALUES_N2]        = AX25_DEF_N2;
     78	ax25_dev->values[AX25_VALUES_PACLEN]	= AX25_DEF_PACLEN;
     79	ax25_dev->values[AX25_VALUES_PROTOCOL]  = AX25_DEF_PROTOCOL;
     80	ax25_dev->values[AX25_VALUES_DS_TIMEOUT]= AX25_DEF_DS_TIMEOUT;
     81
     82#if defined(CONFIG_AX25_DAMA_SLAVE) || defined(CONFIG_AX25_DAMA_MASTER)
     83	ax25_ds_setup_timer(ax25_dev);
     84#endif
     85
     86	spin_lock_bh(&ax25_dev_lock);
     87	ax25_dev->next = ax25_dev_list;
     88	ax25_dev_list  = ax25_dev;
     89	spin_unlock_bh(&ax25_dev_lock);
     90	ax25_dev_hold(ax25_dev);
     91
     92	ax25_register_dev_sysctl(ax25_dev);
     93}
     94
     95void ax25_dev_device_down(struct net_device *dev)
     96{
     97	ax25_dev *s, *ax25_dev;
     98
     99	if ((ax25_dev = ax25_dev_ax25dev(dev)) == NULL)
    100		return;
    101
    102	ax25_unregister_dev_sysctl(ax25_dev);
    103
    104	spin_lock_bh(&ax25_dev_lock);
    105
    106#ifdef CONFIG_AX25_DAMA_SLAVE
    107	ax25_ds_del_timer(ax25_dev);
    108#endif
    109
    110	/*
    111	 *	Remove any packet forwarding that points to this device.
    112	 */
    113	for (s = ax25_dev_list; s != NULL; s = s->next)
    114		if (s->forward == dev)
    115			s->forward = NULL;
    116
    117	if ((s = ax25_dev_list) == ax25_dev) {
    118		ax25_dev_list = s->next;
    119		goto unlock_put;
    120	}
    121
    122	while (s != NULL && s->next != NULL) {
    123		if (s->next == ax25_dev) {
    124			s->next = ax25_dev->next;
    125			goto unlock_put;
    126		}
    127
    128		s = s->next;
    129	}
    130	spin_unlock_bh(&ax25_dev_lock);
    131	dev->ax25_ptr = NULL;
    132	ax25_dev_put(ax25_dev);
    133	return;
    134
    135unlock_put:
    136	spin_unlock_bh(&ax25_dev_lock);
    137	ax25_dev_put(ax25_dev);
    138	dev->ax25_ptr = NULL;
    139	dev_put_track(dev, &ax25_dev->dev_tracker);
    140	ax25_dev_put(ax25_dev);
    141}
    142
    143int ax25_fwd_ioctl(unsigned int cmd, struct ax25_fwd_struct *fwd)
    144{
    145	ax25_dev *ax25_dev, *fwd_dev;
    146
    147	if ((ax25_dev = ax25_addr_ax25dev(&fwd->port_from)) == NULL)
    148		return -EINVAL;
    149
    150	switch (cmd) {
    151	case SIOCAX25ADDFWD:
    152		fwd_dev = ax25_addr_ax25dev(&fwd->port_to);
    153		if (!fwd_dev) {
    154			ax25_dev_put(ax25_dev);
    155			return -EINVAL;
    156		}
    157		if (ax25_dev->forward) {
    158			ax25_dev_put(fwd_dev);
    159			ax25_dev_put(ax25_dev);
    160			return -EINVAL;
    161		}
    162		ax25_dev->forward = fwd_dev->dev;
    163		ax25_dev_put(fwd_dev);
    164		ax25_dev_put(ax25_dev);
    165		break;
    166
    167	case SIOCAX25DELFWD:
    168		if (!ax25_dev->forward) {
    169			ax25_dev_put(ax25_dev);
    170			return -EINVAL;
    171		}
    172		ax25_dev->forward = NULL;
    173		ax25_dev_put(ax25_dev);
    174		break;
    175
    176	default:
    177		ax25_dev_put(ax25_dev);
    178		return -EINVAL;
    179	}
    180
    181	return 0;
    182}
    183
    184struct net_device *ax25_fwd_dev(struct net_device *dev)
    185{
    186	ax25_dev *ax25_dev;
    187
    188	if ((ax25_dev = ax25_dev_ax25dev(dev)) == NULL)
    189		return dev;
    190
    191	if (ax25_dev->forward == NULL)
    192		return dev;
    193
    194	return ax25_dev->forward;
    195}
    196
    197/*
    198 *	Free all memory associated with device structures.
    199 */
    200void __exit ax25_dev_free(void)
    201{
    202	ax25_dev *s, *ax25_dev;
    203
    204	spin_lock_bh(&ax25_dev_lock);
    205	ax25_dev = ax25_dev_list;
    206	while (ax25_dev != NULL) {
    207		s        = ax25_dev;
    208		dev_put_track(ax25_dev->dev, &ax25_dev->dev_tracker);
    209		ax25_dev = ax25_dev->next;
    210		kfree(s);
    211	}
    212	ax25_dev_list = NULL;
    213	spin_unlock_bh(&ax25_dev_lock);
    214}