All of lore.kernel.org
 help / color / mirror / Atom feed
From: Patrick McHardy <kaber@trash.net>
To: netdev@vger.kernel.org
Cc: Patrick McHardy <kaber@trash.net>
Subject: [RFC VLAN 05/08]: Split up device creation
Date: Tue,  5 Jun 2007 16:23:37 +0200 (MEST)	[thread overview]
Message-ID: <20070605142336.20372.3681.sendpatchset@localhost.localdomain> (raw)
In-Reply-To: <20070605142327.20372.18108.sendpatchset@localhost.localdomain>

[VLAN]: Split up device creation

Split up device creation in allocation/registration functions taking
struct net_device * and a small wrapper for the ioctl handling. This is
needed by the netlink interface to properly set up the device before
registration.

Signed-off-by: Patrick McHardy <kaber@trash.net>

---
commit c59e99d32d8085f8ed1aa794106c28e546220581
tree dca7eeb9815666e863e5739a8c0a4698333026bc
parent 1057887432918a89e5b374c29ac36224716cb0e4
author Patrick McHardy <kaber@trash.net> Tue, 29 May 2007 17:52:41 +0200
committer Patrick McHardy <kaber@trash.net> Tue, 29 May 2007 17:52:41 +0200

 net/8021q/vlan.c |  196 ++++++++++++++++++++++++++----------------------------
 net/8021q/vlan.h |    4 +
 2 files changed, 100 insertions(+), 100 deletions(-)

diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c
index d470913..e5405cf 100644
--- a/net/8021q/vlan.c
+++ b/net/8021q/vlan.c
@@ -380,64 +380,110 @@ static void vlan_transfer_operstate(const struct net_device *dev, struct net_dev
 	}
 }
 
-/*  Attach a VLAN device to a mac address (ie Ethernet Card).
- *  Returns the device that was created, or NULL if there was
- *  an error of some kind.
- */
-static struct net_device *register_vlan_device(struct net_device *real_dev,
-					       unsigned short VLAN_ID)
+int vlan_check_device(struct net_device *dev, unsigned short vlan_id)
 {
-	struct vlan_group *grp, *reg = NULL;
-	struct net_device *new_dev;
-	char name[IFNAMSIZ];
-
-#ifdef VLAN_DEBUG
-	printk(VLAN_DBG "%s: if_name -:%s:-	vid: %i\n",
-		__FUNCTION__, eth_IF_name, VLAN_ID);
-#endif
-
-	if (VLAN_ID >= VLAN_VID_MASK)
-		goto out_ret_null;
-
-	if (real_dev->features & NETIF_F_VLAN_CHALLENGED) {
+	if (dev->features & NETIF_F_VLAN_CHALLENGED) {
 		printk(VLAN_DBG "%s: VLANs not supported on %s.\n",
-			__FUNCTION__, real_dev->name);
-		goto out_ret_null;
+			__FUNCTION__, dev->name);
+		return -EOPNOTSUPP;
 	}
 
-	if ((real_dev->features & NETIF_F_HW_VLAN_RX) &&
-	    (real_dev->vlan_rx_register == NULL ||
-	     real_dev->vlan_rx_kill_vid == NULL)) {
+	if ((dev->features & NETIF_F_HW_VLAN_RX) &&
+	    (dev->vlan_rx_register == NULL || dev->vlan_rx_kill_vid == NULL)) {
 		printk(VLAN_DBG "%s: Device %s has buggy VLAN hw accel.\n",
-			__FUNCTION__, real_dev->name);
-		goto out_ret_null;
+			__FUNCTION__, dev->name);
+		return -EOPNOTSUPP;
 	}
 
-	if ((real_dev->features & NETIF_F_HW_VLAN_FILTER) &&
-	    (real_dev->vlan_rx_add_vid == NULL ||
-	     real_dev->vlan_rx_kill_vid == NULL)) {
+	if ((dev->features & NETIF_F_HW_VLAN_FILTER) &&
+	    (dev->vlan_rx_add_vid == NULL || dev->vlan_rx_kill_vid == NULL)) {
 		printk(VLAN_DBG "%s: Device %s has buggy VLAN hw accel.\n",
-			__FUNCTION__, real_dev->name);
-		goto out_ret_null;
+			__FUNCTION__, dev->name);
+		return -EOPNOTSUPP;
 	}
 
 	/* The real device must be up and operating in order to
-	 * assosciate a VLAN device with it.
+	 * associate a VLAN device with it.
 	 */
-	if (!(real_dev->flags & IFF_UP))
-		goto out_ret_null;
+	if (!(dev->flags & IFF_UP))
+		return -ENETDOWN;
 
-	if (__find_vlan_dev(real_dev, VLAN_ID) != NULL) {
-		/* was already registered. */
-		printk(VLAN_DBG "%s: ALREADY had VLAN registered\n", __FUNCTION__);
-		goto out_ret_null;
+	if (__find_vlan_dev(dev, vlan_id) != NULL)
+		return -EEXIST;
+
+	return 0;
+}
+
+int vlan_register_dev(struct net_device *dev)
+{
+	struct vlan_dev_info *vlan = VLAN_DEV_INFO(dev);
+	struct net_device *real_dev = vlan->real_dev;
+	struct vlan_group *group, *reg = NULL;
+	int err;
+
+	group = __vlan_find_group(real_dev->ifindex);
+	if (!group) {
+		err = -ENOMEM;
+		group = reg = vlan_group_alloc(real_dev->ifindex);
+		if (!group)
+			goto err1;
 	}
 
-	/* Gotta set up the fields for the device. */
+	err = register_netdevice(dev);
+	if (err < 0)
+		goto err2;
+
+	/* Account for reference in struct vlan_dev_info */
+	dev_hold(real_dev);
+
+	vlan_transfer_operstate(real_dev, dev);
+	linkwatch_fire_event(dev); /* _MUST_ call rfc2863_policy() */
+
+	/* So, got the sucker initialized, now lets place
+	 * it into our local structure.
+	 */
+	vlan_group_set_device(group, vlan->vlan_id, dev);
+
+	if (reg && real_dev->features & NETIF_F_HW_VLAN_RX)
+		real_dev->vlan_rx_register(real_dev, reg);
+	if (real_dev->features & NETIF_F_HW_VLAN_FILTER)
+		real_dev->vlan_rx_add_vid(real_dev, vlan->vlan_id);
+
+	if (vlan_proc_add_dev(dev) < 0)
+		printk(KERN_WARNING "VLAN: failed to add proc entry for %s\n",
+		       dev->name);
+	return 0;
+
+err2:
+	if (reg)
+		vlan_group_free(reg);
+err1:
+	return err;
+}
+
+/*  Attach a VLAN device to a mac address (ie Ethernet Card).
+ *  Returns 0 if the device was created or a negative error code otherwise.
+ */
+static int register_vlan_device(struct net_device *real_dev,
+				unsigned short VLAN_ID)
+{
+	struct net_device *new_dev;
+	char name[IFNAMSIZ];
+	int err;
+
 #ifdef VLAN_DEBUG
-	printk(VLAN_DBG "About to allocate name, vlan_name_type: %i\n",
-	       vlan_name_type);
+	printk(VLAN_DBG "%s: if_name -:%s:-	vid: %i\n",
+		__FUNCTION__, eth_IF_name, VLAN_ID);
 #endif
+
+	if (VLAN_ID >= VLAN_VID_MASK)
+		return -ERANGE;
+
+	err = vlan_check_device(real_dev, VLAN_ID);
+	if (err < 0)
+		return err;
+
+	/* Gotta set up the fields for the device. */
 	switch (vlan_name_type) {
 	case VLAN_NAME_TYPE_RAW_PLUS_VID:
 		/* name will look like:	 eth1.0005 */
@@ -465,71 +511,25 @@ static struct net_device *register_vlan_device(struct net_device *real_dev,
 
 	new_dev = alloc_netdev(sizeof(struct vlan_dev_info), name,
 			       vlan_setup);
-
 	if (new_dev == NULL)
-		goto out_ret_null;
+		return -ENOMEM;
 
 #ifdef VLAN_DEBUG
 	printk(VLAN_DBG "Allocated new name -:%s:-\n", new_dev->name);
-#endif
-
-	VLAN_DEV_INFO(new_dev)->vlan_id = VLAN_ID; /* 1 through VLAN_VID_MASK */
-	VLAN_DEV_INFO(new_dev)->real_dev = real_dev;
-	VLAN_DEV_INFO(new_dev)->dent = NULL;
-	VLAN_DEV_INFO(new_dev)->flags = 1;
-
 	VLAN_MEM_DBG("new_dev->priv malloc, addr: %p  size: %i\n",
 		     new_dev->priv,
 		     sizeof(struct vlan_dev_info));
-
-#ifdef VLAN_DEBUG
-	printk(VLAN_DBG "About to go find the group for idx: %i\n",
-	       real_dev->ifindex);
-#endif
-	grp = __vlan_find_group(real_dev->ifindex);
-	if (!grp) {
-		reg = grp = vlan_group_alloc(real_dev->ifindex);
-		if (!grp)
-			goto out_free_newdev;
-	}
-
-	if (register_netdevice(new_dev))
-		goto out_free_group;
-
-	vlan_transfer_operstate(real_dev, new_dev);
-	linkwatch_fire_event(new_dev); /* _MUST_ call rfc2863_policy() */
-
-	/* So, got the sucker initialized, now lets place
-	 * it into our local structure.
-	 */
-	if (reg && real_dev->features & NETIF_F_HW_VLAN_RX)
-		real_dev->vlan_rx_register(real_dev, reg);
-
-	vlan_group_set_device(grp, VLAN_ID, new_dev);
-
-	if (vlan_proc_add_dev(new_dev)<0)/* create it's proc entry */
-		printk(KERN_WARNING "VLAN: failed to add proc entry for %s\n",
-							 new_dev->name);
-
-	if (real_dev->features & NETIF_F_HW_VLAN_FILTER)
-		real_dev->vlan_rx_add_vid(real_dev, VLAN_ID);
-
-	/* Account for reference in struct vlan_dev_info */
-	dev_hold(real_dev);
-#ifdef VLAN_DEBUG
-	printk(VLAN_DBG "Allocated new device successfully, returning.\n");
 #endif
-	return new_dev;
 
-out_free_group:
-	if (reg)
-		vlan_group_free(reg);
+	VLAN_DEV_INFO(new_dev)->vlan_id = VLAN_ID; /* 1 through VLAN_VID_MASK */
+	VLAN_DEV_INFO(new_dev)->real_dev = real_dev;
+	VLAN_DEV_INFO(new_dev)->flags = 1;
 
-out_free_newdev:
-	free_netdev(new_dev);
+	err = vlan_register_dev(new_dev);
+	if (err < 0)
+		free_netdev(new_dev);
 
-out_ret_null:
-	return NULL;
+	return 0;
 }
 
 static int vlan_device_event(struct notifier_block *unused, unsigned long event, void *ptr)
@@ -699,11 +699,7 @@ static int vlan_ioctl_handler(void __user *arg)
 		 * talk to:  args.dev1	 We also have the
 		 * VLAN ID:  args.u.VID
 		 */
-		if (register_vlan_device(dev, args.u.VID)) {
-			err = 0;
-		} else {
-			err = -EINVAL;
-		}
+		err = register_vlan_device(dev, args.u.VID);
 		break;
 
 	case DEL_VLAN_CMD:
diff --git a/net/8021q/vlan.h b/net/8021q/vlan.h
index b837390..47f0c53 100644
--- a/net/8021q/vlan.h
+++ b/net/8021q/vlan.h
@@ -72,4 +72,8 @@ void vlan_dev_get_realdev_name(const struct net_device *dev, char *result);
 void vlan_dev_get_vid(const struct net_device *dev, unsigned short *result);
 void vlan_dev_set_multicast_list(struct net_device *vlan_dev);
 
+int vlan_check_device(struct net_device *dev, unsigned short vlan_id);
+int vlan_register_dev(struct net_device *dev);
+int vlan_unregister_dev(struct net_device *dev);
+
 #endif /* !(__BEN_VLAN_802_1Q_INC__) */

  parent reply	other threads:[~2007-06-05 14:23 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-06-05 14:23 [RFC VLAN 00/08]: VLAN netlink support Patrick McHardy
2007-06-05 14:23 ` [RFC VLAN 01/08]: Move device lookup to ioctl handler Patrick McHardy
2007-06-05 14:23 ` [RFC VLAN 02/08]: Remove unregister_vlan_dev wrapper Patrick McHardy
2007-06-05 14:23 ` [RFC VLAN 03/08]: Add device init callback Patrick McHardy
2007-06-05 14:23 ` [RFC VLAN 04/08]: Move vlan_group allocation to seperate function Patrick McHardy
2007-06-05 14:23 ` Patrick McHardy [this message]
2007-06-05 14:23 ` [RFC VLAN 06/08]: Use 32 bit value for skb->priority mapping Patrick McHardy
2007-06-05 14:23 ` [RFC VLAN 07/08]: Keep track of number of QoS mappings Patrick McHardy
2007-06-05 14:23 ` [RFC VLAN 08/08]: Use rtnl_link API Patrick McHardy
2007-06-05 14:26 ` [RFC IPROUTE]: VLAN support Patrick McHardy
2007-06-05 14:33 ` [RFC VLAN 00/08]: VLAN netlink support Patrick McHardy

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20070605142336.20372.3681.sendpatchset@localhost.localdomain \
    --to=kaber@trash.net \
    --cc=netdev@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.