// SPDX-License-Identifier: GPL-2.0-or-later
/*
 *
 * Copyright (C) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
 */
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/socket.h>
#include <linux/slab.h>
#include <linux/in.h>
#include <linux/kernel.h>
#include <linux/timer.h>
#include <linux/string.h>
#include <linux/sockios.h>
#include <linux/net.h>
#include <linux/spinlock.h>
#include <net/ax25.h>
#include <linux/inet.h>
#include <linux/netdevice.h>
#include <linux/if_arp.h>
#include <linux/skbuff.h>
#include <net/sock.h>
#include <linux/uaccess.h>
#include <linux/fcntl.h>
#include <linux/list.h>
#include <linux/mm.h>
#include <linux/interrupt.h>
#include <linux/init.h>

static LIST_HEAD(ax25_dev_list);
DEFINE_SPINLOCK(ax25_dev_lock);

ax25_dev *ax25_addr_ax25dev(ax25_address *addr)
{
	ax25_dev *ax25_dev, *res = NULL;

	spin_lock_bh(&ax25_dev_lock);
	list_for_each_entry(ax25_dev, &ax25_dev_list, list)
		if (ax25cmp(addr, (const ax25_address *)ax25_dev->dev->dev_addr) == 0) {
			res = ax25_dev;
			ax25_dev_hold(ax25_dev);
			break;
		}
	spin_unlock_bh(&ax25_dev_lock);

	return res;
}

/*
 *	This is called when an interface is brought up. These are
 *	reasonable defaults.
 */
void ax25_dev_device_up(struct net_device *dev)
{
	ax25_dev *ax25_dev;

	ax25_dev = kzalloc(sizeof(*ax25_dev), GFP_KERNEL);
	if (!ax25_dev) {
		printk(KERN_ERR "AX.25: ax25_dev_device_up - out of memory\n");
		return;
	}

	refcount_set(&ax25_dev->refcount, 1);
	ax25_dev->dev     = dev;
	netdev_hold(dev, &ax25_dev->dev_tracker, GFP_KERNEL);
	ax25_dev->forward = NULL;
	ax25_dev->device_up = true;

	ax25_dev->values[AX25_VALUES_IPDEFMODE] = AX25_DEF_IPDEFMODE;
	ax25_dev->values[AX25_VALUES_AXDEFMODE] = AX25_DEF_AXDEFMODE;
	ax25_dev->values[AX25_VALUES_BACKOFF]   = AX25_DEF_BACKOFF;
	ax25_dev->values[AX25_VALUES_CONMODE]   = AX25_DEF_CONMODE;
	ax25_dev->values[AX25_VALUES_WINDOW]    = AX25_DEF_WINDOW;
	ax25_dev->values[AX25_VALUES_EWINDOW]   = AX25_DEF_EWINDOW;
	ax25_dev->values[AX25_VALUES_T1]        = AX25_DEF_T1;
	ax25_dev->values[AX25_VALUES_T2]        = AX25_DEF_T2;
	ax25_dev->values[AX25_VALUES_T3]        = AX25_DEF_T3;
	ax25_dev->values[AX25_VALUES_IDLE]	= AX25_DEF_IDLE;
	ax25_dev->values[AX25_VALUES_N2]        = AX25_DEF_N2;
	ax25_dev->values[AX25_VALUES_PACLEN]	= AX25_DEF_PACLEN;
	ax25_dev->values[AX25_VALUES_PROTOCOL]  = AX25_DEF_PROTOCOL;

#ifdef CONFIG_AX25_DAMA_SLAVE
	ax25_dev->values[AX25_VALUES_DS_TIMEOUT]= AX25_DEF_DS_TIMEOUT;
#endif

#if defined(CONFIG_AX25_DAMA_SLAVE) || defined(CONFIG_AX25_DAMA_MASTER)
	ax25_ds_setup_timer(ax25_dev);
#endif

	spin_lock_bh(&ax25_dev_lock);
	list_add(&ax25_dev->list, &ax25_dev_list);
	rcu_assign_pointer(dev->ax25_ptr, ax25_dev);
	spin_unlock_bh(&ax25_dev_lock);

	ax25_register_dev_sysctl(ax25_dev);
}

void ax25_dev_device_down(struct net_device *dev)
{
	ax25_dev *s, *ax25_dev;

	if ((ax25_dev = ax25_dev_ax25dev(dev)) == NULL)
		return;

	ax25_unregister_dev_sysctl(ax25_dev);

	spin_lock_bh(&ax25_dev_lock);

#ifdef CONFIG_AX25_DAMA_SLAVE
	timer_shutdown_sync(&ax25_dev->dama.slave_timer);
#endif

	/*
	 *	Remove any packet forwarding that points to this device.
	 */
	list_for_each_entry(s, &ax25_dev_list, list)
		if (s->forward == dev)
			s->forward = NULL;

	list_for_each_entry(s, &ax25_dev_list, list) {
		if (s == ax25_dev) {
			list_del(&s->list);
			break;
		}
	}

	RCU_INIT_POINTER(dev->ax25_ptr, NULL);
	spin_unlock_bh(&ax25_dev_lock);
	netdev_put(dev, &ax25_dev->dev_tracker);
	ax25_dev_put(ax25_dev);
}

int ax25_fwd_ioctl(unsigned int cmd, struct ax25_fwd_struct *fwd)
{
	ax25_dev *ax25_dev, *fwd_dev;

	if ((ax25_dev = ax25_addr_ax25dev(&fwd->port_from)) == NULL)
		return -EINVAL;

	switch (cmd) {
	case SIOCAX25ADDFWD:
		fwd_dev = ax25_addr_ax25dev(&fwd->port_to);
		if (!fwd_dev) {
			ax25_dev_put(ax25_dev);
			return -EINVAL;
		}
		if (ax25_dev->forward) {
			ax25_dev_put(fwd_dev);
			ax25_dev_put(ax25_dev);
			return -EINVAL;
		}
		ax25_dev->forward = fwd_dev->dev;
		ax25_dev_put(fwd_dev);
		ax25_dev_put(ax25_dev);
		break;

	case SIOCAX25DELFWD:
		if (!ax25_dev->forward) {
			ax25_dev_put(ax25_dev);
			return -EINVAL;
		}
		ax25_dev->forward = NULL;
		ax25_dev_put(ax25_dev);
		break;

	default:
		ax25_dev_put(ax25_dev);
		return -EINVAL;
	}

	return 0;
}

struct net_device *ax25_fwd_dev(struct net_device *dev)
{
	ax25_dev *ax25_dev;

	if ((ax25_dev = ax25_dev_ax25dev(dev)) == NULL)
		return dev;

	if (ax25_dev->forward == NULL)
		return dev;

	return ax25_dev->forward;
}

/*
 *	Free all memory associated with device structures.
 */
void __exit ax25_dev_free(void)
{
	ax25_dev *s, *n;

	spin_lock_bh(&ax25_dev_lock);
	list_for_each_entry_safe(s, n, &ax25_dev_list, list) {
		netdev_put(s->dev, &s->dev_tracker);
		list_del(&s->list);
		ax25_dev_put(s);
	}
	spin_unlock_bh(&ax25_dev_lock);
}
