mirror of
https://github.com/Fishwaldo/linux-bl808.git
synced 2025-04-01 11:54:10 +00:00
[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: Eric W. Biederman <ebiederm@xmission.com> Signed-off-by: Daniel Lezcano <dlezcano@fr.ibm.com> Acked-By: Kirill Korotaev <dev@sw.ru> Acked-by: Benjamin Thery <benjamin.thery@bull.net>
This commit is contained in:
parent
de3cb747ff
commit
854d8363f3
1 changed files with 44 additions and 28 deletions
|
@ -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)
|
||||||
|
goto out_free_netdev;
|
||||||
|
|
||||||
|
err = 0;
|
||||||
|
loopback_dev = dev;
|
||||||
|
|
||||||
|
out:
|
||||||
if (err)
|
if (err)
|
||||||
panic("loopback: Failed to register netdevice: %d\n", 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);
|
||||||
|
|
Loading…
Add table
Reference in a new issue