Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  *
0004  * Copyright (C) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
0005  */
0006 #include <linux/errno.h>
0007 #include <linux/types.h>
0008 #include <linux/socket.h>
0009 #include <linux/slab.h>
0010 #include <linux/in.h>
0011 #include <linux/kernel.h>
0012 #include <linux/timer.h>
0013 #include <linux/string.h>
0014 #include <linux/sockios.h>
0015 #include <linux/net.h>
0016 #include <linux/spinlock.h>
0017 #include <net/ax25.h>
0018 #include <linux/inet.h>
0019 #include <linux/netdevice.h>
0020 #include <linux/if_arp.h>
0021 #include <linux/skbuff.h>
0022 #include <net/sock.h>
0023 #include <linux/uaccess.h>
0024 #include <linux/fcntl.h>
0025 #include <linux/mm.h>
0026 #include <linux/interrupt.h>
0027 #include <linux/init.h>
0028 
0029 ax25_dev *ax25_dev_list;
0030 DEFINE_SPINLOCK(ax25_dev_lock);
0031 
0032 ax25_dev *ax25_addr_ax25dev(ax25_address *addr)
0033 {
0034     ax25_dev *ax25_dev, *res = NULL;
0035 
0036     spin_lock_bh(&ax25_dev_lock);
0037     for (ax25_dev = ax25_dev_list; ax25_dev != NULL; ax25_dev = ax25_dev->next)
0038         if (ax25cmp(addr, (const ax25_address *)ax25_dev->dev->dev_addr) == 0) {
0039             res = ax25_dev;
0040             ax25_dev_hold(ax25_dev);
0041         }
0042     spin_unlock_bh(&ax25_dev_lock);
0043 
0044     return res;
0045 }
0046 
0047 /*
0048  *  This is called when an interface is brought up. These are
0049  *  reasonable defaults.
0050  */
0051 void ax25_dev_device_up(struct net_device *dev)
0052 {
0053     ax25_dev *ax25_dev;
0054 
0055     ax25_dev = kzalloc(sizeof(*ax25_dev), GFP_KERNEL);
0056     if (!ax25_dev) {
0057         printk(KERN_ERR "AX.25: ax25_dev_device_up - out of memory\n");
0058         return;
0059     }
0060 
0061     refcount_set(&ax25_dev->refcount, 1);
0062     dev->ax25_ptr     = ax25_dev;
0063     ax25_dev->dev     = dev;
0064     netdev_hold(dev, &ax25_dev->dev_tracker, GFP_KERNEL);
0065     ax25_dev->forward = NULL;
0066     ax25_dev->device_up = true;
0067 
0068     ax25_dev->values[AX25_VALUES_IPDEFMODE] = AX25_DEF_IPDEFMODE;
0069     ax25_dev->values[AX25_VALUES_AXDEFMODE] = AX25_DEF_AXDEFMODE;
0070     ax25_dev->values[AX25_VALUES_BACKOFF]   = AX25_DEF_BACKOFF;
0071     ax25_dev->values[AX25_VALUES_CONMODE]   = AX25_DEF_CONMODE;
0072     ax25_dev->values[AX25_VALUES_WINDOW]    = AX25_DEF_WINDOW;
0073     ax25_dev->values[AX25_VALUES_EWINDOW]   = AX25_DEF_EWINDOW;
0074     ax25_dev->values[AX25_VALUES_T1]        = AX25_DEF_T1;
0075     ax25_dev->values[AX25_VALUES_T2]        = AX25_DEF_T2;
0076     ax25_dev->values[AX25_VALUES_T3]        = AX25_DEF_T3;
0077     ax25_dev->values[AX25_VALUES_IDLE]  = AX25_DEF_IDLE;
0078     ax25_dev->values[AX25_VALUES_N2]        = AX25_DEF_N2;
0079     ax25_dev->values[AX25_VALUES_PACLEN]    = AX25_DEF_PACLEN;
0080     ax25_dev->values[AX25_VALUES_PROTOCOL]  = AX25_DEF_PROTOCOL;
0081     ax25_dev->values[AX25_VALUES_DS_TIMEOUT]= AX25_DEF_DS_TIMEOUT;
0082 
0083 #if defined(CONFIG_AX25_DAMA_SLAVE) || defined(CONFIG_AX25_DAMA_MASTER)
0084     ax25_ds_setup_timer(ax25_dev);
0085 #endif
0086 
0087     spin_lock_bh(&ax25_dev_lock);
0088     ax25_dev->next = ax25_dev_list;
0089     ax25_dev_list  = ax25_dev;
0090     spin_unlock_bh(&ax25_dev_lock);
0091     ax25_dev_hold(ax25_dev);
0092 
0093     ax25_register_dev_sysctl(ax25_dev);
0094 }
0095 
0096 void ax25_dev_device_down(struct net_device *dev)
0097 {
0098     ax25_dev *s, *ax25_dev;
0099 
0100     if ((ax25_dev = ax25_dev_ax25dev(dev)) == NULL)
0101         return;
0102 
0103     ax25_unregister_dev_sysctl(ax25_dev);
0104 
0105     spin_lock_bh(&ax25_dev_lock);
0106 
0107 #ifdef CONFIG_AX25_DAMA_SLAVE
0108     ax25_ds_del_timer(ax25_dev);
0109 #endif
0110 
0111     /*
0112      *  Remove any packet forwarding that points to this device.
0113      */
0114     for (s = ax25_dev_list; s != NULL; s = s->next)
0115         if (s->forward == dev)
0116             s->forward = NULL;
0117 
0118     if ((s = ax25_dev_list) == ax25_dev) {
0119         ax25_dev_list = s->next;
0120         goto unlock_put;
0121     }
0122 
0123     while (s != NULL && s->next != NULL) {
0124         if (s->next == ax25_dev) {
0125             s->next = ax25_dev->next;
0126             goto unlock_put;
0127         }
0128 
0129         s = s->next;
0130     }
0131     spin_unlock_bh(&ax25_dev_lock);
0132     dev->ax25_ptr = NULL;
0133     ax25_dev_put(ax25_dev);
0134     return;
0135 
0136 unlock_put:
0137     spin_unlock_bh(&ax25_dev_lock);
0138     ax25_dev_put(ax25_dev);
0139     dev->ax25_ptr = NULL;
0140     netdev_put(dev, &ax25_dev->dev_tracker);
0141     ax25_dev_put(ax25_dev);
0142 }
0143 
0144 int ax25_fwd_ioctl(unsigned int cmd, struct ax25_fwd_struct *fwd)
0145 {
0146     ax25_dev *ax25_dev, *fwd_dev;
0147 
0148     if ((ax25_dev = ax25_addr_ax25dev(&fwd->port_from)) == NULL)
0149         return -EINVAL;
0150 
0151     switch (cmd) {
0152     case SIOCAX25ADDFWD:
0153         fwd_dev = ax25_addr_ax25dev(&fwd->port_to);
0154         if (!fwd_dev) {
0155             ax25_dev_put(ax25_dev);
0156             return -EINVAL;
0157         }
0158         if (ax25_dev->forward) {
0159             ax25_dev_put(fwd_dev);
0160             ax25_dev_put(ax25_dev);
0161             return -EINVAL;
0162         }
0163         ax25_dev->forward = fwd_dev->dev;
0164         ax25_dev_put(fwd_dev);
0165         ax25_dev_put(ax25_dev);
0166         break;
0167 
0168     case SIOCAX25DELFWD:
0169         if (!ax25_dev->forward) {
0170             ax25_dev_put(ax25_dev);
0171             return -EINVAL;
0172         }
0173         ax25_dev->forward = NULL;
0174         ax25_dev_put(ax25_dev);
0175         break;
0176 
0177     default:
0178         ax25_dev_put(ax25_dev);
0179         return -EINVAL;
0180     }
0181 
0182     return 0;
0183 }
0184 
0185 struct net_device *ax25_fwd_dev(struct net_device *dev)
0186 {
0187     ax25_dev *ax25_dev;
0188 
0189     if ((ax25_dev = ax25_dev_ax25dev(dev)) == NULL)
0190         return dev;
0191 
0192     if (ax25_dev->forward == NULL)
0193         return dev;
0194 
0195     return ax25_dev->forward;
0196 }
0197 
0198 /*
0199  *  Free all memory associated with device structures.
0200  */
0201 void __exit ax25_dev_free(void)
0202 {
0203     ax25_dev *s, *ax25_dev;
0204 
0205     spin_lock_bh(&ax25_dev_lock);
0206     ax25_dev = ax25_dev_list;
0207     while (ax25_dev != NULL) {
0208         s        = ax25_dev;
0209         netdev_put(ax25_dev->dev, &ax25_dev->dev_tracker);
0210         ax25_dev = ax25_dev->next;
0211         kfree(s);
0212     }
0213     ax25_dev_list = NULL;
0214     spin_unlock_bh(&ax25_dev_lock);
0215 }