summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2017-01-16 22:37:41 +0100
committerRalf Baechle <ralf@linux-mips.org>2017-03-08 21:54:12 +0100
commit1bea128318b914484a4be019cecdec4738df81d4 (patch)
tree358d9368c7bdf39efaaaabd613a2c18a47da2210
parent1b3294fb4a0b5ceb31a8e11579742e73b0a4f144 (diff)
NET: NETROM: Convert NETROM device creation to netlink.ax25-bpqether-rework-4.10
Until now, NETROM did create a number of NETROM devices on initialization. The number could be set by the module parameter nr_ndevs and did default to 4 while typically only a single one would be used. With this applied a new version of ip from the iproute2 is required for NETROM device creation: # ip link add type netrom This will create a NETROM device which will be named netrom0 for the first device thus consistent with the old naming practice. Explicit naming is possible with # ip link add name red23 type netrom which will create a NETROM device named red23. Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
-rw-r--r--include/net/netrom.h1
-rw-r--r--net/netrom/af_netrom.c103
-rw-r--r--net/netrom/nr_dev.c83
3 files changed, 102 insertions, 85 deletions
diff --git a/include/net/netrom.h b/include/net/netrom.h
index 110350aca3df..b66b2970b04a 100644
--- a/include/net/netrom.h
+++ b/include/net/netrom.h
@@ -189,6 +189,7 @@ void nr_destroy_socket(struct sock *);
/* nr_dev.c */
int nr_rx_ip(struct sk_buff *, struct net_device *);
void nr_setup(struct net_device *);
+extern struct rtnl_link_ops nr_link_ops;
/* nr_in.c */
int nr_process_rx_frame(struct sock *, struct sk_buff *);
diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c
index eb27d3e5ef5c..762b6511cba0 100644
--- a/net/netrom/af_netrom.c
+++ b/net/netrom/af_netrom.c
@@ -44,8 +44,6 @@
#include <net/arp.h>
#include <linux/init.h>
-static int nr_ndevs = 4;
-
int sysctl_netrom_default_path_quality = NR_DEFAULT_QUAL;
int sysctl_netrom_obsolescence_count_initialiser = NR_DEFAULT_OBS;
int sysctl_netrom_network_ttl_initialiser = NR_DEFAULT_TTL;
@@ -67,28 +65,6 @@ static DEFINE_SPINLOCK(nr_list_lock);
static const struct proto_ops nr_proto_ops;
/*
- * NETROM network devices are virtual network devices encapsulating NETROM
- * frames into AX.25 which will be sent through an AX.25 device, so form a
- * special "super class" of normal net devices; split their locks off into a
- * separate class since they always nest.
- */
-static struct lock_class_key nr_netdev_xmit_lock_key;
-static struct lock_class_key nr_netdev_addr_lock_key;
-
-static void nr_set_lockdep_one(struct net_device *dev,
- struct netdev_queue *txq,
- void *_unused)
-{
- lockdep_set_class(&txq->_xmit_lock, &nr_netdev_xmit_lock_key);
-}
-
-static void nr_set_lockdep_key(struct net_device *dev)
-{
- lockdep_set_class(&dev->addr_list_lock, &nr_netdev_addr_lock_key);
- netdev_for_each_tx_queue(dev, nr_set_lockdep_one, NULL);
-}
-
-/*
* Socket removal during an interrupt is now safe.
*/
static void nr_remove_socket(struct sock *sk)
@@ -1382,8 +1358,6 @@ static struct notifier_block nr_dev_notifier = {
.notifier_call = nr_device_event,
};
-static struct net_device **dev_nr;
-
static struct ax25_protocol nr_pid = {
.pid = AX25_P_NETROM,
.func = nr_route_frame
@@ -1395,47 +1369,19 @@ static struct ax25_linkfail nr_linkfail_notifier = {
static int __init nr_proto_init(void)
{
- int i;
- int rc = proto_register(&nr_proto, 0);
+ int err;
- if (rc != 0)
+ err = proto_register(&nr_proto, 0);
+ if (err)
goto out;
- if (nr_ndevs > 0x7fffffff/sizeof(struct net_device *)) {
- printk(KERN_ERR "NET/ROM: nr_proto_init - nr_ndevs parameter to large\n");
- return -1;
- }
-
- dev_nr = kzalloc(nr_ndevs * sizeof(struct net_device *), GFP_KERNEL);
- if (dev_nr == NULL) {
- printk(KERN_ERR "NET/ROM: nr_proto_init - unable to allocate device array\n");
- return -1;
- }
-
- for (i = 0; i < nr_ndevs; i++) {
- char name[IFNAMSIZ];
- struct net_device *dev;
-
- sprintf(name, "nr%d", i);
- dev = alloc_netdev(0, name, NET_NAME_UNKNOWN, nr_setup);
- if (!dev) {
- printk(KERN_ERR "NET/ROM: nr_proto_init - unable to allocate device structure\n");
- goto fail;
- }
-
- dev->base_addr = i;
- if (register_netdev(dev)) {
- printk(KERN_ERR "NET/ROM: nr_proto_init - unable to register network device\n");
- free_netdev(dev);
- goto fail;
- }
- nr_set_lockdep_key(dev);
- dev_nr[i] = dev;
- }
+ err = rtnl_link_register(&nr_link_ops);
+ if (err)
+ goto out_unregister_proto;
if (sock_register(&nr_family_ops)) {
printk(KERN_ERR "NET/ROM: nr_proto_init - unable to register socket family\n");
- goto fail;
+ goto out_rtnl_link_unregister;
}
register_netdevice_notifier(&nr_dev_notifier);
@@ -1452,23 +1398,21 @@ static int __init nr_proto_init(void)
proc_create("nr", S_IRUGO, init_net.proc_net, &nr_info_fops);
proc_create("nr_neigh", S_IRUGO, init_net.proc_net, &nr_neigh_fops);
proc_create("nr_nodes", S_IRUGO, init_net.proc_net, &nr_nodes_fops);
-out:
- return rc;
-fail:
- while (--i >= 0) {
- unregister_netdev(dev_nr[i]);
- free_netdev(dev_nr[i]);
- }
- kfree(dev_nr);
+
+ return 0;
+
+out_rtnl_link_unregister:
+ rtnl_link_unregister(&nr_link_ops);
+
+out_unregister_proto:
proto_unregister(&nr_proto);
- rc = -1;
- goto out;
+
+out:
+ return err;
}
static void __exit nr_exit(void)
{
- int i;
-
remove_proc_entry("nr", init_net.proc_net);
remove_proc_entry("nr_neigh", init_net.proc_net);
remove_proc_entry("nr_nodes", init_net.proc_net);
@@ -1487,24 +1431,13 @@ static void __exit nr_exit(void)
sock_unregister(PF_NETROM);
- for (i = 0; i < nr_ndevs; i++) {
- struct net_device *dev = dev_nr[i];
- if (dev) {
- unregister_netdev(dev);
- free_netdev(dev);
- }
- }
-
- kfree(dev_nr);
+ rtnl_link_unregister(&nr_link_ops);
proto_unregister(&nr_proto);
}
module_init(nr_proto_init);
module_exit(nr_exit);
-module_param(nr_ndevs, int, 0);
-MODULE_PARM_DESC(nr_ndevs, "number of NET/ROM devices");
-
MODULE_AUTHOR("Jonathan Naylor G4KLX <g4klx@g4klx.demon.co.uk>");
MODULE_DESCRIPTION("The amateur radio NET/ROM network and transport layer protocol");
MODULE_LICENSE("GPL");
diff --git a/net/netrom/nr_dev.c b/net/netrom/nr_dev.c
index 988f542481a8..44f24f78792e 100644
--- a/net/netrom/nr_dev.c
+++ b/net/netrom/nr_dev.c
@@ -37,6 +37,28 @@
#include <net/netrom.h>
/*
+ * NETROM network devices are virtual network devices encapsulating NETROM
+ * frames into AX.25 which will be sent through an AX.25 device, so form a
+ * special "super class" of normal net devices; split their locks off into a
+ * separate class since they always nest.
+ */
+static struct lock_class_key nr_netdev_xmit_lock_key;
+static struct lock_class_key nr_netdev_addr_lock_key;
+
+static void nr_set_lockdep_one(struct net_device *dev,
+ struct netdev_queue *txq,
+ void *_unused)
+{
+ lockdep_set_class(&txq->_xmit_lock, &nr_netdev_xmit_lock_key);
+}
+
+static void nr_set_lockdep_key(struct net_device *dev)
+{
+ lockdep_set_class(&dev->addr_list_lock, &nr_netdev_addr_lock_key);
+ netdev_for_each_tx_queue(dev, nr_set_lockdep_one, NULL);
+}
+
+/*
* Only allow IP over NET/ROM frames through if the netrom device is up.
*/
@@ -171,6 +193,8 @@ void nr_setup(struct net_device *dev)
{
dev->mtu = NR_MAX_PACKET_SIZE;
dev->netdev_ops = &nr_netdev_ops;
+ //dev->destructor = free_netdev;
+
dev->header_ops = &nr_header_ops;
dev->hard_header_len = NR_NETWORK_LEN + NR_TRANSPORT_LEN;
dev->addr_len = AX25_ADDR_LEN;
@@ -179,3 +203,62 @@ void nr_setup(struct net_device *dev)
/* New-style flags. */
dev->flags = IFF_NOARP;
}
+
+static struct device_type nr_type = {
+ .name = "netrom",
+};
+
+static int nr_validate(struct nlattr *tb[], struct nlattr *data[])
+{
+ if (tb[IFLA_ADDRESS]) {
+ if (nla_len(tb[IFLA_ADDRESS]) != AX25_ADDR_LEN)
+ return -EINVAL;
+
+ if (!ax25_address_is_valid((void *)nla_data(tb[IFLA_ADDRESS])))
+ return -EADDRNOTAVAIL;
+ }
+
+ return 0;
+}
+
+static int nr_newlink(struct net *src_net, struct net_device *dev,
+ struct nlattr *tb[], struct nlattr *data[])
+{
+ int err;
+
+ SET_NETDEV_DEVTYPE(dev, &nr_type);
+
+ err = register_netdevice(dev);
+ if (err)
+ return err;
+
+ nr_set_lockdep_key(dev);
+
+ return 0;
+}
+
+static void nr_dellink(struct net_device *dev, struct list_head *head)
+{
+ unregister_netdevice(dev);
+}
+
+static size_t nr_get_size(const struct net_device *dev)
+{
+ return nla_total_size(AX25_ADDR_LEN) + /* IFLA_ADDRESS */
+ 0;
+}
+
+struct rtnl_link_ops nr_link_ops __read_mostly = {
+ .kind = "netrom",
+ .priv_size = sizeof(struct net_device),
+ .setup = nr_setup,
+ .maxtype = 0,
+ .policy = NULL,
+ .validate = nr_validate,
+ .newlink = nr_newlink,
+ .changelink = NULL,
+ .dellink = nr_dellink,
+ .get_size = nr_get_size,
+ .fill_info = NULL,
+ .get_link_net = NULL,
+};