All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH 1/6] invisible network devices
@ 2007-01-29 17:48 Jiri Benc
  2007-01-29 17:48 ` [PATCH 2/6] d80211: use invisible network device for wmaster Jiri Benc
                   ` (6 more replies)
  0 siblings, 7 replies; 22+ messages in thread
From: Jiri Benc @ 2007-01-29 17:48 UTC (permalink / raw)
  To: netdev; +Cc: John W. Linville, Stephen Hemminger, David Miller

The d80211 stack needs a network interface (called 'wmaster') used for
communication with the hardware (it has 802.11 qdisc attached which perform
MAC level QoS). This interface is not intended for users and it confuses
them.

As a short time solution, this patch allows net_device to be registered as
"invisible". This means it is not in the dev name hash list, its ifindex is
-1 and protocols are not notified about its registration/unregistration.

Signed-off-by: Jiri Benc <jbenc@suse.cz>

---
 include/linux/netdevice.h |    2 
 net/core/dev.c            |  223 ++++++++++++++++++++++++++++++----------------
 2 files changed, 151 insertions(+), 74 deletions(-)

--- dscape.orig/include/linux/netdevice.h
+++ dscape/include/linux/netdevice.h
@@ -975,6 +975,8 @@ extern struct net_device *alloc_netdev(i
 				       void (*setup)(struct net_device *));
 extern int		register_netdev(struct net_device *dev);
 extern void		unregister_netdev(struct net_device *dev);
+extern int		register_invisible_netdevice(struct net_device *dev);
+extern void		unregister_invisible_netdevice(struct net_device *dev);
 /* Functions used for multicast support */
 extern void		dev_mc_upload(struct net_device *dev);
 extern int 		dev_mc_delete(struct net_device *dev, void *addr, int alen, int all);
--- dscape.orig/net/core/dev.c
+++ dscape/net/core/dev.c
@@ -2891,37 +2891,10 @@ static inline void net_set_todo(struct n
 	spin_unlock(&net_todo_list_lock);
 }
 
-/**
- *	register_netdevice	- register a network device
- *	@dev: device to register
- *
- *	Take a completed network device structure and add it to the kernel
- *	interfaces. A %NETDEV_REGISTER message is sent to the netdev notifier
- *	chain. 0 is returned on success. A negative errno code is returned
- *	on a failure to set up the device, or if the name is a duplicate.
- *
- *	Callers must hold the rtnl semaphore. You may want
- *	register_netdev() instead of this.
- *
- *	BUGS:
- *	The locking appears insufficient to guarantee two parallel registers
- *	will not get the same name.
- */
-
-int register_netdevice(struct net_device *dev)
+static int init_netdevice(struct net_device *dev)
 {
-	struct hlist_head *head;
-	struct hlist_node *p;
 	int ret;
 
-	BUG_ON(dev_boot_phase);
-	ASSERT_RTNL();
-
-	might_sleep();
-
-	/* When net_device's are persistent, this will be fatal. */
-	BUG_ON(dev->reg_state != NETREG_UNINITIALIZED);
-
 	spin_lock_init(&dev->queue_lock);
 	spin_lock_init(&dev->_xmit_lock);
 	dev->xmit_lock_owner = -1;
@@ -2929,7 +2902,7 @@ int register_netdevice(struct net_device
 	spin_lock_init(&dev->ingress_lock);
 #endif
 
-	dev->iflink = -1;
+	dev->iflink = dev->ifindex = -1;
 
 	/* Init, if this function is available */
 	if (dev->init) {
@@ -2940,27 +2913,13 @@ int register_netdevice(struct net_device
 			goto out;
 		}
 	}
- 
-	if (!dev_valid_name(dev->name)) {
-		ret = -EINVAL;
-		goto out;
-	}
-
-	dev->ifindex = dev_new_index();
-	if (dev->iflink == -1)
-		dev->iflink = dev->ifindex;
-
-	/* Check for existence of name */
-	head = dev_name_hash(dev->name);
-	hlist_for_each(p, head) {
-		struct net_device *d
-			= hlist_entry(p, struct net_device, name_hlist);
-		if (!strncmp(d->name, dev->name, IFNAMSIZ)) {
-			ret = -EEXIST;
- 			goto out;
-		}
- 	}
+	ret = 0;
+out:
+	return ret;
+}
 
+static void setup_netdevice(struct net_device *dev)
+{
 	/* Fix illegal SG+CSUM combinations. */
 	if ((dev->features & NETIF_F_SG) &&
 	    !(dev->features & NETIF_F_ALL_CSUM)) {
@@ -2999,17 +2958,75 @@ int register_netdevice(struct net_device
 	if (!dev->rebuild_header)
 		dev->rebuild_header = default_rebuild_header;
 
-	ret = netdev_register_sysfs(dev);
-	if (ret)
-		goto out;
-	dev->reg_state = NETREG_REGISTERED;
-
 	/*
 	 *	Default initial state at registry is that the
 	 *	device is present.
 	 */
 
 	set_bit(__LINK_STATE_PRESENT, &dev->state);
+}
+
+/**
+ *	register_netdevice	- register a network device
+ *	@dev: device to register
+ *
+ *	Take a completed network device structure and add it to the kernel
+ *	interfaces. A %NETDEV_REGISTER message is sent to the netdev notifier
+ *	chain. 0 is returned on success. A negative errno code is returned
+ *	on a failure to set up the device, or if the name is a duplicate.
+ *
+ *	Callers must hold the rtnl semaphore. You may want
+ *	register_netdev() instead of this.
+ *
+ *	BUGS:
+ *	The locking appears insufficient to guarantee two parallel registers
+ *	will not get the same name.
+ */
+
+int register_netdevice(struct net_device *dev)
+{
+	struct hlist_head *head;
+	struct hlist_node *p;
+	int ret;
+
+	BUG_ON(dev_boot_phase);
+	ASSERT_RTNL();
+
+	might_sleep();
+
+	/* When net_device's are persistent, this will be fatal. */
+	BUG_ON(dev->reg_state != NETREG_UNINITIALIZED);
+
+	ret = init_netdevice(dev);
+	if (ret)
+		goto out;
+
+	if (!dev_valid_name(dev->name)) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	dev->ifindex = dev_new_index();
+	if (dev->iflink == -1)
+		dev->iflink = dev->ifindex;
+
+	/* Check for existence of name */
+	head = dev_name_hash(dev->name);
+	hlist_for_each(p, head) {
+		struct net_device *d
+			= hlist_entry(p, struct net_device, name_hlist);
+		if (!strncmp(d->name, dev->name, IFNAMSIZ)) {
+			ret = -EEXIST;
+ 			goto out;
+		}
+ 	}
+
+	ret = netdev_register_sysfs(dev);
+	if (ret)
+		goto out;
+
+	setup_netdevice(dev);
+	dev->reg_state = NETREG_REGISTERED;
 
 	dev->next = NULL;
 	dev_init_scheduler(dev);
@@ -3030,6 +3047,31 @@ out:
 	return ret;
 }
 
+int register_invisible_netdevice(struct net_device *dev)
+{
+	int ret;
+
+	BUG_ON(dev_boot_phase);
+	might_sleep();
+	BUG_ON(dev->reg_state != NETREG_UNINITIALIZED);
+
+	ret = init_netdevice(dev);
+	if (ret)
+		goto out;
+
+	setup_netdevice(dev);
+	dev->reg_state = NETREG_REGISTERED;
+
+	dev->next = NULL;
+	dev_init_scheduler(dev);
+	dev_hold(dev);
+
+	ret = 0;
+out:
+	return ret;
+}
+EXPORT_SYMBOL(register_invisible_netdevice);
+
 /**
  *	register_netdev	- register a network device
  *	@dev: device to register
@@ -3118,6 +3160,23 @@ static void netdev_wait_allrefs(struct n
 	}
 }
 
+static void destruct_netdevice(struct net_device *dev)
+{
+	netdev_wait_allrefs(dev);
+
+	/* paranoia */
+	BUG_ON(atomic_read(&dev->refcnt));
+	BUG_TRAP(!dev->ip_ptr);
+	BUG_TRAP(!dev->ip6_ptr);
+	BUG_TRAP(!dev->dn_ptr);
+
+	/* It must be the very last action,
+	 * after this 'dev' may point to freed up memory.
+	 */
+	if (dev->destructor)
+		dev->destructor(dev);
+}
+
 /* The sequence is:
  *
  *	rtnl_lock();
@@ -3175,19 +3234,7 @@ void netdev_run_todo(void)
 		netdev_unregister_sysfs(dev);
 		dev->reg_state = NETREG_UNREGISTERED;
 
-		netdev_wait_allrefs(dev);
-
-		/* paranoia */
-		BUG_ON(atomic_read(&dev->refcnt));
-		BUG_TRAP(!dev->ip_ptr);
-		BUG_TRAP(!dev->ip6_ptr);
-		BUG_TRAP(!dev->dn_ptr);
-
-		/* It must be the very last action,
-		 * after this 'dev' may point to freed up memory.
-		 */
-		if (dev->destructor)
-			dev->destructor(dev);
+		destruct_netdevice(dev);
 	}
 
 out:
@@ -3269,6 +3316,17 @@ void synchronize_net(void) 
 	synchronize_rcu();
 }
 
+static void uninit_netdevice(struct net_device *dev)
+{
+	/*
+	 *	Flush the multicast chain
+	 */
+	dev_mc_discard(dev);
+
+	if (dev->uninit)
+		dev->uninit(dev);
+}
+
 /**
  *	unregister_netdevice - remove device from the kernel
  *	@dev: device
@@ -3332,14 +3390,8 @@ int unregister_netdevice(struct net_devi
 	   this device. They should clean all the things.
 	*/
 	raw_notifier_call_chain(&netdev_chain, NETDEV_UNREGISTER, dev);
-	
-	/*
-	 *	Flush the multicast chain
-	 */
-	dev_mc_discard(dev);
 
-	if (dev->uninit)
-		dev->uninit(dev);
+	uninit_netdevice(dev);
 
 	/* Notifier chain MUST detach us from master device. */
 	BUG_TRAP(!dev->master);
@@ -3353,6 +3405,29 @@ int unregister_netdevice(struct net_devi
 	return 0;
 }
 
+void unregister_invisible_netdevice(struct net_device *dev)
+{
+	BUG_ON(dev_boot_phase);
+	BUG_ON(dev->reg_state != NETREG_REGISTERED);
+	might_sleep();
+
+	dev_close(dev);
+	dev->reg_state = NETREG_UNREGISTERING;
+	synchronize_net();
+	dev_shutdown(dev);
+
+	uninit_netdevice(dev);
+
+	BUG_TRAP(!dev->master);
+
+	synchronize_net();
+	dev_put(dev);
+
+	dev->reg_state = NETREG_UNREGISTERED;
+	destruct_netdevice(dev);
+}
+EXPORT_SYMBOL(unregister_invisible_netdevice);
+
 /**
  *	unregister_netdev - remove device from the kernel
  *	@dev: device

-- 
Jiri Benc
SUSE Labs

^ permalink raw reply	[flat|nested] 22+ messages in thread

end of thread, other threads:[~2007-02-21  8:05 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-01-29 17:48 [RFC PATCH 1/6] invisible network devices Jiri Benc
2007-01-29 17:48 ` [PATCH 2/6] d80211: use invisible network device for wmaster Jiri Benc
2007-01-29 17:48 ` [PATCH 3/6] d80211: drop packets from nonexisting interfaces in PS mode Jiri Benc
2007-01-29 17:48 ` [PATCH 4/6] d80211: don't display name of invisible network device Jiri Benc
2007-01-30 13:47   ` Johannes Berg
2007-01-30 14:00     ` Jan Kiszka
2007-01-31 18:58       ` Johannes Berg
2007-02-01 15:17         ` Jiri Benc
2007-02-01 15:19           ` Johannes Berg
2007-01-29 17:48 ` [PATCH 5/6] d80211: remove useless callbacks from wmaster Jiri Benc
2007-01-29 17:48 ` [PATCH 6/6] d80211: fix rtnl locking in ieee80211_register_hw Jiri Benc
2007-01-29 17:48 ` d80211: a patch for standalone d80211 tarball Jiri Benc
2007-01-29 18:34   ` Ivo Van Doorn
2007-01-29 20:23   ` Pavel Roskin
2007-01-31 18:06     ` Jiri Benc
2007-01-29 18:28 ` [RFC PATCH 1/6] invisible network devices Stephen Hemminger
2007-01-29 22:09   ` [RFC] Alternative hidden netwirk device interface Stephen Hemminger
2007-01-30 10:09     ` Christoph Hellwig
2007-01-31 18:26     ` Jiri Benc
2007-01-31 18:40       ` Stephen Hemminger
2007-02-21  8:04     ` David Miller
2007-01-30 10:08   ` [RFC PATCH 1/6] invisible network devices Christoph Hellwig

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.