Commit 854d8363 authored by Daniel Lezcano's avatar Daniel Lezcano Committed by David S. Miller

[NET]: Dynamically allocate the loopback device, part 2.

Doing this makes loopback.c a better example of how to do a
simple network device, and it removes the special case
single static allocation of a struct net_device, hopefully
making maintenance easier.
Signed-off-by: default avatarEric W. Biederman <ebiederm@xmission.com>
Signed-off-by: default avatarDaniel Lezcano <dlezcano@fr.ibm.com>
Acked-By: default avatarKirill Korotaev <dev@sw.ru>
Acked-by: default avatarBenjamin Thery <benjamin.thery@bull.net>
parent de3cb747
...@@ -202,44 +202,60 @@ static const struct ethtool_ops loopback_ethtool_ops = { ...@@ -202,44 +202,60 @@ static const struct ethtool_ops loopback_ethtool_ops = {
* The loopback device is special. There is only one instance and * The loopback device is special. There is only one instance and
* it is statically allocated. Don't do this for other devices. * it is statically allocated. Don't do this for other devices.
*/ */
struct net_device __loopback_dev = { static void loopback_setup(struct net_device *dev)
.name = "lo", {
.get_stats = &get_stats, dev->get_stats = &get_stats;
.mtu = (16 * 1024) + 20 + 20 + 12, dev->mtu = (16 * 1024) + 20 + 20 + 12;
.hard_start_xmit = loopback_xmit, dev->hard_start_xmit = loopback_xmit;
.hard_header = eth_header, dev->hard_header = eth_header;
.hard_header_cache = eth_header_cache, dev->hard_header_cache = eth_header_cache;
.header_cache_update = eth_header_cache_update, dev->header_cache_update = eth_header_cache_update;
.hard_header_len = ETH_HLEN, /* 14 */ dev->hard_header_len = ETH_HLEN; /* 14 */
.addr_len = ETH_ALEN, /* 6 */ dev->addr_len = ETH_ALEN; /* 6 */
.tx_queue_len = 0, dev->tx_queue_len = 0;
.type = ARPHRD_LOOPBACK, /* 0x0001*/ dev->type = ARPHRD_LOOPBACK; /* 0x0001*/
.rebuild_header = eth_rebuild_header, dev->rebuild_header = eth_rebuild_header;
.flags = IFF_LOOPBACK, dev->flags = IFF_LOOPBACK;
.features = NETIF_F_SG | NETIF_F_FRAGLIST dev->features = NETIF_F_SG | NETIF_F_FRAGLIST
#ifdef LOOPBACK_TSO #ifdef LOOPBACK_TSO
| NETIF_F_TSO | NETIF_F_TSO
#endif #endif
| NETIF_F_NO_CSUM | NETIF_F_HIGHDMA | NETIF_F_NO_CSUM
| NETIF_F_LLTX | NETIF_F_HIGHDMA
| NETIF_F_NETNS_LOCAL, | NETIF_F_LLTX
.ethtool_ops = &loopback_ethtool_ops, | NETIF_F_NETNS_LOCAL,
.nd_net = &init_net, dev->ethtool_ops = &loopback_ethtool_ops;
}; }
struct net_device *loopback_dev = &__loopback_dev;
/* Setup and register the loopback device. */ /* Setup and register the loopback device. */
static int __init loopback_init(void) static int __init loopback_init(void)
{ {
int err = register_netdev(loopback_dev); struct net_device *dev;
int err;
err = -ENOMEM;
dev = alloc_netdev(0, "lo", loopback_setup);
if (!dev)
goto out;
err = register_netdev(dev);
if (err) if (err)
panic("loopback: Failed to register netdevice: %d\n", err); goto out_free_netdev;
err = 0;
loopback_dev = dev;
out:
if (err)
panic("loopback: Failed to register netdevice: %d\n", err);
return err; return err;
};
module_init(loopback_init); out_free_netdev:
free_netdev(dev);
goto out;
}
fs_initcall(loopback_init);
struct net_device *loopback_dev;
EXPORT_SYMBOL(loopback_dev); EXPORT_SYMBOL(loopback_dev);
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment