Home » Mailing lists » Devel » Dynamically allocate the loopback device
Dynamically allocate the loopback device [message #19762] |
Fri, 24 August 2007 12:50 |
Daniel Lezcano
Messages: 417 Registered: June 2006
|
Senior Member |
|
|
From: Daniel Lezcano <dlezcano@fr.ibm.com>
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>
---
drivers/net/loopback.c | 63 +++++++++++++++++++++++---------------
include/linux/netdevice.h | 2 +-
net/core/dst.c | 8 ++--
net/decnet/dn_dev.c | 4 +-
net/decnet/dn_route.c | 14 ++++----
net/ipv4/devinet.c | 6 ++--
net/ipv4/ipconfig.c | 6 ++--
net/ipv4/ipvs/ip_vs_core.c | 2 +-
net/ipv4/route.c | 18 +++++-----
net/ipv4/xfrm4_policy.c | 2 +-
net/ipv6/addrconf.c | 15 +++++---
net/ipv6/ip6_input.c | 2 +-
net/ipv6/netfilter/ip6t_REJECT.c | 2 +-
net/ipv6/route.c | 15 +++-----
net/ipv6/xfrm6_policy.c | 2 +-
net/xfrm/xfrm_policy.c | 4 +-
16 files changed, 89 insertions(+), 76 deletions(-)
diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c
index 5106c23..3642aff 100644
--- a/drivers/net/loopback.c
+++ b/drivers/net/loopback.c
@@ -199,44 +199,57 @@ static const struct ethtool_ops loopback_ethtool_ops = {
.get_rx_csum = always_on,
};
-/*
- * The loopback device is special. There is only one instance and
- * it is statically allocated. Don't do this for other devices.
- */
-struct net_device loopback_dev = {
- .name = "lo",
- .get_stats = &get_stats,
- .mtu = (16 * 1024) + 20 + 20 + 12,
- .hard_start_xmit = loopback_xmit,
- .hard_header = eth_header,
- .hard_header_cache = eth_header_cache,
- .header_cache_update = eth_header_cache_update,
- .hard_header_len = ETH_HLEN, /* 14 */
- .addr_len = ETH_ALEN, /* 6 */
- .tx_queue_len = 0,
- .type = ARPHRD_LOOPBACK, /* 0x0001*/
- .rebuild_header = eth_rebuild_header,
- .flags = IFF_LOOPBACK,
- .features = NETIF_F_SG | NETIF_F_FRAGLIST
+static void loopback_setup(struct net_device *dev)
+{
+ dev->get_stats = &get_stats;
+ dev->mtu = (16 * 1024) + 20 + 20 + 12;
+ dev->hard_start_xmit = loopback_xmit;
+ dev->hard_header = eth_header;
+ dev->hard_header_cache = eth_header_cache;
+ dev->header_cache_update = eth_header_cache_update;
+ dev->hard_header_len = ETH_HLEN; /* 14 */
+ dev->addr_len = ETH_ALEN; /* 6 */
+ dev->tx_queue_len = 0;
+ dev->type = ARPHRD_LOOPBACK; /* 0x0001*/
+ dev->rebuild_header = eth_rebuild_header;
+ dev->flags = IFF_LOOPBACK;
+ dev->features = NETIF_F_SG | NETIF_F_FRAGLIST
#ifdef LOOPBACK_TSO
| NETIF_F_TSO
#endif
| NETIF_F_NO_CSUM | NETIF_F_HIGHDMA
- | NETIF_F_LLTX,
- .ethtool_ops = &loopback_ethtool_ops,
-};
+ | NETIF_F_LLTX;
+ dev->ethtool_ops = &loopback_ethtool_ops;
+}
/* Setup and register the loopback device. */
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)
panic("loopback: Failed to register netdevice: %d\n", err);
-
return err;
+out_free_netdev:
+ free_netdev(dev);
+ goto out;
};
-module_init(loopback_init);
+fs_initcall(loopback_init);
+struct net_device *loopback_dev;
EXPORT_SYMBOL(loopback_dev);
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 8d12f02..7cd0641 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -680,7 +680,7 @@ struct packet_type {
#include <linux/interrupt.h>
#include <linux/notifier.h>
-extern struct net_device loopback_dev; /* The loopback */
+extern struct net_device *loopback_dev; /* The loopback */
extern struct list_head dev_base_head; /* All devices */
extern rwlock_t dev_base_lock; /* Device list lock */
diff --git a/net/core/dst.c b/net/core/dst.c
index c6a0587..ad8549e 100644
--- a/net/core/dst.c
+++ b/net/core/dst.c
@@ -236,13 +236,13 @@ static inline void dst_ifdown(struct dst_entry *dst, struct net_device *dev,
if (!unregister) {
dst->input = dst->output = dst_discard;
} else {
- dst->dev = &loopback_dev;
- dev_hold(&loopback_dev);
+ dst->dev = loopback_dev;
+ dev_hold(dst->dev);
dev_put(dev);
if (dst->neighbour && dst->neighbour->dev == dev) {
- dst->neighbour->dev = &loopback_dev;
+ dst->neighbour->dev = loopback_dev;
dev_put(dev);
- dev_hold(&loopback_dev);
+ dev_hold(dst->neighbour->dev);
}
}
}
diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c
index fa6604f..9fea83e 100644
--- a/net/decnet/dn_dev.c
+++ b/net/decnet/dn_dev.c
@@ -868,10 +868,10 @@ last_chance:
rv = dn_dev_get_first(dev, addr);
read_unlock(&dev_base_lock);
dev_put(dev);
- if (rv == 0 || dev == &loopback_dev)
+ if (rv == 0 || dev == loopback_dev)
return rv;
}
- dev = &loopback_dev;
+ dev = loopback_dev;
dev_hold(dev);
goto last_chance;
}
diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c
index a4a6209..8c04ebc 100644
--- a/net/decnet/dn_route.c
+++ b/net/decnet/dn_route.c
@@ -883,7 +883,7 @@ static int dn_route_output_slow(struct dst_entry **pprt, const struct flowi *old
.scope = RT_SCOPE_UNIVERSE,
} },
.mark = oldflp->mark,
- .iif = loopback_dev.ifindex,
+ .iif = loopback_dev->ifindex,
.oif = oldflp->oif };
struct dn_route *rt = NULL;
struct net_device *dev_out = NULL, *dev;
@@ -900,7 +900,7 @@ static int dn_route_output_slow(struct dst_entry **pprt, const struct flowi *old
"dn_route_output_slow: dst=%04x src=%04x mark=%d"
" iif=%d oif=%d\n", dn_ntohs(oldflp->fld_dst),
dn_ntohs(oldflp->fld_src),
- oldflp->mark, loopback_dev.ifindex, oldflp->oif);
+ oldflp->mark, loopback_dev->ifindex, oldflp->oif);
/* If we have an output interface, verify its a DECnet device */
if (oldflp->oif) {
@@ -953,7 +953,7 @@ source_ok:
err = -EADDRNOTAVAIL;
if (dev_out)
dev_put(dev_out);
- dev_out = &loopback_dev;
+ dev_out = loopback_dev;
dev_hold(dev_out);
if (!fl.fld_dst) {
fl.fld_dst =
@@ -962,7 +962,7 @@ source_ok:
if (!fl.fld_dst)
goto out;
}
- fl.oif = loopback_dev.ifindex;
+ fl.oif = loopback_dev->ifindex;
res.type = RTN_LOCAL;
goto make_route;
}
@@ -1008,7 +1008,7 @@ source_ok:
if (dev_out)
dev_put(dev_out);
if (dn_dev_islocal(neigh->dev, fl.fld_dst)) {
- dev_out = &loopback_dev;
+ dev_out = loopback_dev;
res.type = RTN_LOCAL;
} else {
dev_out = neigh->dev;
@@ -1029,7 +1029,7 @@ source_ok:
/* Possible improvement - check all devices for local addr */
if (dn_dev_islocal(dev_out, fl.fld_dst)) {
dev_put(dev_out);
- dev_out = &loopback_dev;
+ dev_out = loopback_dev;
dev_hold(dev_out);
res.type = RTN_LOCAL;
goto select_source;
@@ -1065,7 +1065,7 @@ select_source:
fl.fld_src = fl.fld_dst;
if (dev_out)
dev_put(dev_out);
- dev_out = &loopback_dev;
+ dev_out = loopback_dev;
dev_hold(dev_out);
fl.oif = dev_out->ifindex;
if (res.fi)
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index 5b77bda..808f529 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -203,7 +203,7 @@ static void inetdev_destroy(struct in_device *in_dev)
ASSERT_RTNL();
dev = in_dev->dev;
- if (dev == &loopback_dev)
+ if (dev == loopback_dev)
return;
in_dev->dead = 1;
@@ -1058,7 +1058,7 @@ static int inetdev_event(struct notifier_block *this, unsigned long event,
in_dev = inetdev_init(dev);
if (!in_dev)
return notifier_from_errno(-ENOMEM);
- if (dev == &loopback_dev) {
+ if (dev == loopback_dev) {
IN_DEV_CONF_SET(in_dev, NOXFRM, 1);
IN_DEV_CONF_SET(in_dev, NOPOLICY, 1);
}
@@ -1074,7 +1074,7 @@ static int inetdev_event(struct notifier_block *this, unsigned long event,
case NETDEV_UP:
if (dev->mtu < 68)
break;
- if (dev == &loopback_dev) {
+ if (dev == loopback_dev) {
struct in_ifaddr *ifa;
if ((ifa = inet_alloc_ifa()) != NULL) {
ifa->ifa_local =
diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c
index c5b2470..3ec7690 100644
--- a/net/ipv4/ipconfig.c
+++ b/net/ipv4/ipconfig.c
@@ -189,11 +189,11 @@ static int __init ic_open_devs(void)
rtnl_lock();
/* bring loopback device up first */
- if (dev_change_flags(&loopback_dev, loopback_dev.flags | IFF_UP) < 0)
- printk(KERN_ERR "IP-Config: Failed to open %s\n", loopback_dev.name);
+ if (dev_change_flags(loopback_dev, loopback_dev->flags | IFF_UP) < 0)
+ printk(KERN_ERR "IP-Config: Failed to open %s\n", loopback_dev->name);
for_each_netdev(dev) {
- if (dev == &loopback_dev)
+ if (dev == loopback_dev)
continue;
if (user_dev_name[0] ? !strcmp(dev->name, user_dev_name) :
(!(dev->flags & IFF_LOOPBACK) &&
diff --git a/net/ipv4/ipvs/ip_vs_core.c b/net/ipv4/ipvs/ip_vs_core.c
index f005a2f..7450326 100644
--- a/net/ipv4/ipvs/ip_vs_core.c
+++ b/net/ipv4/ipvs/ip_vs_core.c
@@ -961,7 +961,7 @@ ip_vs_in(unsigned int hooknum, struct sk_buff **pskb,
* ... don't know why 1st test DOES NOT include 2nd (?)
*/
if (unlikely(skb->pkt_type != PACKET_HOST
- || skb->dev == &loopback_dev || skb->sk)) {
+ || skb->dev == loopback_dev || skb->sk)) {
IP_VS_DBG(12, "packet type=%d proto=%d daddr=%d.%d.%d.%d ignored\n",
skb->pkt_type,
ip_hdr(skb)-
...
|
|
|
Re: Dynamically allocate the loopback device [message #19763 is a reply to message #19762] |
Fri, 24 August 2007 13:22 |
Benjamin Thery
Messages: 79 Registered: March 2007
|
Member |
|
|
Kirill Korotaev wrote:
> Acked-By: Kirill Korotaev <dev@sw.ru>
Acked-by: Benjamin Thery <benjamin.thery@bull.net>
Looks good to me.
Compiled and tested on i386.
>
> dlezcano@fr.ibm.com wrote:
>> From: Daniel Lezcano <dlezcano@fr.ibm.com>
>>
>> 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>
>> ---
>> drivers/net/loopback.c | 63 +++++++++++++++++++++++---------------
>> include/linux/netdevice.h | 2 +-
>> net/core/dst.c | 8 ++--
>> net/decnet/dn_dev.c | 4 +-
>> net/decnet/dn_route.c | 14 ++++----
>> net/ipv4/devinet.c | 6 ++--
>> net/ipv4/ipconfig.c | 6 ++--
>> net/ipv4/ipvs/ip_vs_core.c | 2 +-
>> net/ipv4/route.c | 18 +++++-----
>> net/ipv4/xfrm4_policy.c | 2 +-
>> net/ipv6/addrconf.c | 15 +++++---
>> net/ipv6/ip6_input.c | 2 +-
>> net/ipv6/netfilter/ip6t_REJECT.c | 2 +-
>> net/ipv6/route.c | 15 +++-----
>> net/ipv6/xfrm6_policy.c | 2 +-
>> net/xfrm/xfrm_policy.c | 4 +-
>> 16 files changed, 89 insertions(+), 76 deletions(-)
>>
>> diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c
>> index 5106c23..3642aff 100644
>> --- a/drivers/net/loopback.c
>> +++ b/drivers/net/loopback.c
>> @@ -199,44 +199,57 @@ static const struct ethtool_ops loopback_ethtool_ops = {
>> .get_rx_csum = always_on,
>> };
>>
>> -/*
>> - * The loopback device is special. There is only one instance and
>> - * it is statically allocated. Don't do this for other devices.
>> - */
>> -struct net_device loopback_dev = {
>> - .name = "lo",
>> - .get_stats = &get_stats,
>> - .mtu = (16 * 1024) + 20 + 20 + 12,
>> - .hard_start_xmit = loopback_xmit,
>> - .hard_header = eth_header,
>> - .hard_header_cache = eth_header_cache,
>> - .header_cache_update = eth_header_cache_update,
>> - .hard_header_len = ETH_HLEN, /* 14 */
>> - .addr_len = ETH_ALEN, /* 6 */
>> - .tx_queue_len = 0,
>> - .type = ARPHRD_LOOPBACK, /* 0x0001*/
>> - .rebuild_header = eth_rebuild_header,
>> - .flags = IFF_LOOPBACK,
>> - .features = NETIF_F_SG | NETIF_F_FRAGLIST
>> +static void loopback_setup(struct net_device *dev)
>> +{
>> + dev->get_stats = &get_stats;
>> + dev->mtu = (16 * 1024) + 20 + 20 + 12;
>> + dev->hard_start_xmit = loopback_xmit;
>> + dev->hard_header = eth_header;
>> + dev->hard_header_cache = eth_header_cache;
>> + dev->header_cache_update = eth_header_cache_update;
>> + dev->hard_header_len = ETH_HLEN; /* 14 */
>> + dev->addr_len = ETH_ALEN; /* 6 */
>> + dev->tx_queue_len = 0;
>> + dev->type = ARPHRD_LOOPBACK; /* 0x0001*/
>> + dev->rebuild_header = eth_rebuild_header;
>> + dev->flags = IFF_LOOPBACK;
>> + dev->features = NETIF_F_SG | NETIF_F_FRAGLIST
>> #ifdef LOOPBACK_TSO
>> | NETIF_F_TSO
>> #endif
>> | NETIF_F_NO_CSUM | NETIF_F_HIGHDMA
>> - | NETIF_F_LLTX,
>> - .ethtool_ops = &loopback_ethtool_ops,
>> -};
>> + | NETIF_F_LLTX;
>> + dev->ethtool_ops = &loopback_ethtool_ops;
>> +}
>>
>> /* Setup and register the loopback device. */
>> 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)
>> panic("loopback: Failed to register netdevice: %d\n", err);
>> -
>> return err;
>> +out_free_netdev:
>> + free_netdev(dev);
>> + goto out;
>> };
>>
>> -module_init(loopback_init);
>> +fs_initcall(loopback_init);
>>
>> +struct net_device *loopback_dev;
>> EXPORT_SYMBOL(loopback_dev);
>> diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
>> index 8d12f02..7cd0641 100644
>> --- a/include/linux/netdevice.h
>> +++ b/include/linux/netdevice.h
>> @@ -680,7 +680,7 @@ struct packet_type {
>> #include <linux/interrupt.h>
>> #include <linux/notifier.h>
>>
>> -extern struct net_device loopback_dev; /* The loopback */
>> +extern struct net_device *loopback_dev; /* The loopback */
>> extern struct list_head dev_base_head; /* All devices */
>> extern rwlock_t dev_base_lock; /* Device list lock */
>>
>> diff --git a/net/core/dst.c b/net/core/dst.c
>> index c6a0587..ad8549e 100644
>> --- a/net/core/dst.c
>> +++ b/net/core/dst.c
>> @@ -236,13 +236,13 @@ static inline void dst_ifdown(struct dst_entry *dst, struct net_device *dev,
>> if (!unregister) {
>> dst->input = dst->output = dst_discard;
>> } else {
>> - dst->dev = &loopback_dev;
>> - dev_hold(&loopback_dev);
>> + dst->dev = loopback_dev;
>> + dev_hold(dst->dev);
>> dev_put(dev);
>> if (dst->neighbour && dst->neighbour->dev == dev) {
>> - dst->neighbour->dev = &loopback_dev;
>> + dst->neighbour->dev = loopback_dev;
>> dev_put(dev);
>> - dev_hold(&loopback_dev);
>> + dev_hold(dst->neighbour->dev);
>> }
>> }
>> }
>> diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c
>> index fa6604f..9fea83e 100644
>> --- a/net/decnet/dn_dev.c
>> +++ b/net/decnet/dn_dev.c
>> @@ -868,10 +868,10 @@ last_chance:
>> rv = dn_dev_get_first(dev, addr);
>> read_unlock(&dev_base_lock);
>> dev_put(dev);
>> - if (rv == 0 || dev == &loopback_dev)
>> + if (rv == 0 || dev == loopback_dev)
>> return rv;
>> }
>> - dev = &loopback_dev;
>> + dev = loopback_dev;
>> dev_hold(dev);
>> goto last_chance;
>> }
>> diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c
>> index a4a6209..8c04ebc 100644
>> --- a/net/decnet/dn_route.c
>> +++ b/net/decnet/dn_route.c
>> @@ -883,7 +883,7 @@ static int dn_route_output_slow(struct dst_entry **pprt, const struct flowi *old
>> .scope = RT_SCOPE_UNIVERSE,
>> } },
>> .mark = oldflp->mark,
>> - .iif = loopback_dev.ifindex,
>> + .iif = loopback_dev->ifindex,
>> .oif = oldflp->oif };
>> struct dn_route *rt = NULL;
>> struct net_device *dev_out = NULL, *dev;
>> @@ -900,7 +900,7 @@ static int dn_route_output_slow(struct dst_entry **pprt, const struct flowi *old
>> "dn_route_output_slow: dst=%04x src=%04x mark=%d"
>> " iif=%d oif=%d\n", dn_ntohs(oldflp->fld_dst),
>> dn_ntohs(oldflp->fld_src),
>> - oldflp->mark, loopback_dev.ifindex, oldflp->oif);
>> + oldflp->mark, loopback_dev->ifindex, oldflp->oif);
>>
>> /* If we have an output interface, verify its a DECnet device */
>> if (oldflp->oif) {
>> @@ -953,7 +953,7 @@ source_ok:
>> err = -EADDRNOTAVAIL;
>> if (dev_out)
>> dev_put(dev_out);
>> - dev_out = &loopback_dev;
>> + dev_out = loopback_dev;
>> dev_hold(dev_out);
>> if (!fl.fld_dst) {
>> fl.fld_dst =
>> @@ -962,7 +962,7 @@ source_ok:
>> if (!fl.fld_dst)
>> goto out;
>> }
>> - fl.oif = loopback_dev.ifindex;
>> + fl.oif = loopback_dev->ifindex;
>> res.type = RTN_LOCAL;
>> goto make_route;
>> }
>> @@ -1008,7 +1008,7 @@ source_ok:
>> if (dev_out)
>> dev_put(dev_out);
>> if (dn_dev_islocal(neigh->dev, fl.fld_dst)) {
>> - dev_out = &loopback_dev;
>> + dev_out = loopback_dev;
>> res.type = RTN_LOCAL;
>> } else {
>> dev_out = neigh->dev;
>> @@ -1029,7 +1029,7 @@ source_ok:
>> /* Possible improvement - check all devices for local addr */
>> if (dn_dev_islocal(dev_out, fl.fld_dst)) {
>> dev_put(dev_out);
>> - dev_out = &loopback_dev;
>> + dev_out = loopback_dev;
>> dev_hold(dev_out);
>> res.type = RTN_LOCAL;
>> goto select_source;
>> @@ -1065,7 +1065,7 @@ select_source:
>> fl.fld_src = fl.fld_dst;
>> if (dev_out)
>> dev_put(dev_out);
>> - dev_out = &loopback_dev;
>> + dev_out = loopback_dev;
>> dev_hold(dev_out);
>> fl.oif = dev_out->ifindex;
>> if (res.fi)
>> diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
>> index 5b
...
|
|
|
Re: Dynamically allocate the loopback device [message #19765 is a reply to message #19762] |
Fri, 24 August 2007 13:06 |
dev
Messages: 1693 Registered: September 2005 Location: Moscow
|
Senior Member |
|
|
Acked-By: Kirill Korotaev <dev@sw.ru>
dlezcano@fr.ibm.com wrote:
> From: Daniel Lezcano <dlezcano@fr.ibm.com>
>
> 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>
> ---
> drivers/net/loopback.c | 63 +++++++++++++++++++++++---------------
> include/linux/netdevice.h | 2 +-
> net/core/dst.c | 8 ++--
> net/decnet/dn_dev.c | 4 +-
> net/decnet/dn_route.c | 14 ++++----
> net/ipv4/devinet.c | 6 ++--
> net/ipv4/ipconfig.c | 6 ++--
> net/ipv4/ipvs/ip_vs_core.c | 2 +-
> net/ipv4/route.c | 18 +++++-----
> net/ipv4/xfrm4_policy.c | 2 +-
> net/ipv6/addrconf.c | 15 +++++---
> net/ipv6/ip6_input.c | 2 +-
> net/ipv6/netfilter/ip6t_REJECT.c | 2 +-
> net/ipv6/route.c | 15 +++-----
> net/ipv6/xfrm6_policy.c | 2 +-
> net/xfrm/xfrm_policy.c | 4 +-
> 16 files changed, 89 insertions(+), 76 deletions(-)
>
> diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c
> index 5106c23..3642aff 100644
> --- a/drivers/net/loopback.c
> +++ b/drivers/net/loopback.c
> @@ -199,44 +199,57 @@ static const struct ethtool_ops loopback_ethtool_ops = {
> .get_rx_csum = always_on,
> };
>
> -/*
> - * The loopback device is special. There is only one instance and
> - * it is statically allocated. Don't do this for other devices.
> - */
> -struct net_device loopback_dev = {
> - .name = "lo",
> - .get_stats = &get_stats,
> - .mtu = (16 * 1024) + 20 + 20 + 12,
> - .hard_start_xmit = loopback_xmit,
> - .hard_header = eth_header,
> - .hard_header_cache = eth_header_cache,
> - .header_cache_update = eth_header_cache_update,
> - .hard_header_len = ETH_HLEN, /* 14 */
> - .addr_len = ETH_ALEN, /* 6 */
> - .tx_queue_len = 0,
> - .type = ARPHRD_LOOPBACK, /* 0x0001*/
> - .rebuild_header = eth_rebuild_header,
> - .flags = IFF_LOOPBACK,
> - .features = NETIF_F_SG | NETIF_F_FRAGLIST
> +static void loopback_setup(struct net_device *dev)
> +{
> + dev->get_stats = &get_stats;
> + dev->mtu = (16 * 1024) + 20 + 20 + 12;
> + dev->hard_start_xmit = loopback_xmit;
> + dev->hard_header = eth_header;
> + dev->hard_header_cache = eth_header_cache;
> + dev->header_cache_update = eth_header_cache_update;
> + dev->hard_header_len = ETH_HLEN; /* 14 */
> + dev->addr_len = ETH_ALEN; /* 6 */
> + dev->tx_queue_len = 0;
> + dev->type = ARPHRD_LOOPBACK; /* 0x0001*/
> + dev->rebuild_header = eth_rebuild_header;
> + dev->flags = IFF_LOOPBACK;
> + dev->features = NETIF_F_SG | NETIF_F_FRAGLIST
> #ifdef LOOPBACK_TSO
> | NETIF_F_TSO
> #endif
> | NETIF_F_NO_CSUM | NETIF_F_HIGHDMA
> - | NETIF_F_LLTX,
> - .ethtool_ops = &loopback_ethtool_ops,
> -};
> + | NETIF_F_LLTX;
> + dev->ethtool_ops = &loopback_ethtool_ops;
> +}
>
> /* Setup and register the loopback device. */
> 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)
> panic("loopback: Failed to register netdevice: %d\n", err);
> -
> return err;
> +out_free_netdev:
> + free_netdev(dev);
> + goto out;
> };
>
> -module_init(loopback_init);
> +fs_initcall(loopback_init);
>
> +struct net_device *loopback_dev;
> EXPORT_SYMBOL(loopback_dev);
> diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
> index 8d12f02..7cd0641 100644
> --- a/include/linux/netdevice.h
> +++ b/include/linux/netdevice.h
> @@ -680,7 +680,7 @@ struct packet_type {
> #include <linux/interrupt.h>
> #include <linux/notifier.h>
>
> -extern struct net_device loopback_dev; /* The loopback */
> +extern struct net_device *loopback_dev; /* The loopback */
> extern struct list_head dev_base_head; /* All devices */
> extern rwlock_t dev_base_lock; /* Device list lock */
>
> diff --git a/net/core/dst.c b/net/core/dst.c
> index c6a0587..ad8549e 100644
> --- a/net/core/dst.c
> +++ b/net/core/dst.c
> @@ -236,13 +236,13 @@ static inline void dst_ifdown(struct dst_entry *dst, struct net_device *dev,
> if (!unregister) {
> dst->input = dst->output = dst_discard;
> } else {
> - dst->dev = &loopback_dev;
> - dev_hold(&loopback_dev);
> + dst->dev = loopback_dev;
> + dev_hold(dst->dev);
> dev_put(dev);
> if (dst->neighbour && dst->neighbour->dev == dev) {
> - dst->neighbour->dev = &loopback_dev;
> + dst->neighbour->dev = loopback_dev;
> dev_put(dev);
> - dev_hold(&loopback_dev);
> + dev_hold(dst->neighbour->dev);
> }
> }
> }
> diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c
> index fa6604f..9fea83e 100644
> --- a/net/decnet/dn_dev.c
> +++ b/net/decnet/dn_dev.c
> @@ -868,10 +868,10 @@ last_chance:
> rv = dn_dev_get_first(dev, addr);
> read_unlock(&dev_base_lock);
> dev_put(dev);
> - if (rv == 0 || dev == &loopback_dev)
> + if (rv == 0 || dev == loopback_dev)
> return rv;
> }
> - dev = &loopback_dev;
> + dev = loopback_dev;
> dev_hold(dev);
> goto last_chance;
> }
> diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c
> index a4a6209..8c04ebc 100644
> --- a/net/decnet/dn_route.c
> +++ b/net/decnet/dn_route.c
> @@ -883,7 +883,7 @@ static int dn_route_output_slow(struct dst_entry **pprt, const struct flowi *old
> .scope = RT_SCOPE_UNIVERSE,
> } },
> .mark = oldflp->mark,
> - .iif = loopback_dev.ifindex,
> + .iif = loopback_dev->ifindex,
> .oif = oldflp->oif };
> struct dn_route *rt = NULL;
> struct net_device *dev_out = NULL, *dev;
> @@ -900,7 +900,7 @@ static int dn_route_output_slow(struct dst_entry **pprt, const struct flowi *old
> "dn_route_output_slow: dst=%04x src=%04x mark=%d"
> " iif=%d oif=%d\n", dn_ntohs(oldflp->fld_dst),
> dn_ntohs(oldflp->fld_src),
> - oldflp->mark, loopback_dev.ifindex, oldflp->oif);
> + oldflp->mark, loopback_dev->ifindex, oldflp->oif);
>
> /* If we have an output interface, verify its a DECnet device */
> if (oldflp->oif) {
> @@ -953,7 +953,7 @@ source_ok:
> err = -EADDRNOTAVAIL;
> if (dev_out)
> dev_put(dev_out);
> - dev_out = &loopback_dev;
> + dev_out = loopback_dev;
> dev_hold(dev_out);
> if (!fl.fld_dst) {
> fl.fld_dst =
> @@ -962,7 +962,7 @@ source_ok:
> if (!fl.fld_dst)
> goto out;
> }
> - fl.oif = loopback_dev.ifindex;
> + fl.oif = loopback_dev->ifindex;
> res.type = RTN_LOCAL;
> goto make_route;
> }
> @@ -1008,7 +1008,7 @@ source_ok:
> if (dev_out)
> dev_put(dev_out);
> if (dn_dev_islocal(neigh->dev, fl.fld_dst)) {
> - dev_out = &loopback_dev;
> + dev_out = loopback_dev;
> res.type = RTN_LOCAL;
> } else {
> dev_out = neigh->dev;
> @@ -1029,7 +1029,7 @@ source_ok:
> /* Possible improvement - check all devices for local addr */
> if (dn_dev_islocal(dev_out, fl.fld_dst)) {
> dev_put(dev_out);
> - dev_out = &loopback_dev;
> + dev_out = loopback_dev;
> dev_hold(dev_out);
> res.type = RTN_LOCAL;
> goto select_source;
> @@ -1065,7 +1065,7 @@ select_source:
> fl.fld_src = fl.fld_dst;
> if (dev_out)
> dev_put(dev_out);
> - dev_out = &loopback_dev;
> + dev_out = loopback_dev;
> dev_hold(dev_out);
> fl.oif = dev_out->ifindex;
> if (res.fi)
> diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
> index 5b77bda..808f529 100644
> --- a/net/ipv4/devinet.c
> +++ b/net/ipv4/devinet.c
> @@ -203,7 +203,7 @@ static void inetdev_destroy(struct in_device *in_dev)
> ASSERT_RTNL();
>
> dev = in_dev->dev;
> - if (dev == &loopback_dev)
> + if (dev == loopback_dev)
> return;
>
> in_dev->dead = 1;
> @@ -1058,7 +1058,7 @@ static int inetdev_event(struct notifier_block *this, unsigned long event,
> in_dev = inetdev_init(dev);
> if (!in_dev)
> return notifier_from_errno(-ENOMEM);
> - if (dev == &loopback_dev) {
> + if (dev == loopback_dev) {
> IN_DEV_CONF_SET(in_dev, NOXFRM, 1);
> IN_DEV_CONF_SET(in_dev, NOPOLICY, 1);
> }
> @@ -1074,7 +1074,7 @@ static int inetdev_event(struct notifier_block *this, unsigned long event,
> case NETDEV_UP:
> if (dev->mtu < 68)
> break;
> - if (dev == &loopback_dev) {
> + if (dev == loopback_dev) {
> struct in_ifaddr *ifa;
> if ((ifa = inet_alloc_ifa()) != NULL) {
> ifa->ifa_local
...
|
|
|
Goto Forum:
Current Time: Thu Jan 02 19:45:25 GMT 2025
Total time taken to generate the page: 0.10500 seconds
|