Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 58899
b: refs/heads/master
c: c17d887
h: refs/heads/master
i:
  58897: 334dae7
  58895: d2b93c4
v: v3
  • Loading branch information
Patrick McHardy authored and David S. Miller committed Jul 11, 2007
1 parent 1f05cc7 commit f964935
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 200 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 9ba2cd656021e7f70038ba9d551224e04d0bfcef
refs/heads/master: c17d8874f9959070552fddf1b4e1d73c0c144c0f
153 changes: 64 additions & 89 deletions trunk/net/8021q/vlan.c
Original file line number Diff line number Diff line change
Expand Up @@ -278,43 +278,16 @@ static int unregister_vlan_dev(struct net_device *real_dev,
return ret;
}

static int unregister_vlan_device(const char *vlan_IF_name)
static int unregister_vlan_device(struct net_device *dev)
{
struct net_device *dev = NULL;
int ret;

ret = unregister_vlan_dev(VLAN_DEV_INFO(dev)->real_dev,
VLAN_DEV_INFO(dev)->vlan_id);
unregister_netdevice(dev);

dev = dev_get_by_name(vlan_IF_name);
ret = -EINVAL;
if (dev) {
if (dev->priv_flags & IFF_802_1Q_VLAN) {
rtnl_lock();

ret = unregister_vlan_dev(VLAN_DEV_INFO(dev)->real_dev,
VLAN_DEV_INFO(dev)->vlan_id);

dev_put(dev);
unregister_netdevice(dev);

rtnl_unlock();

if (ret == 1)
ret = 0;
} else {
printk(VLAN_ERR
"%s: ERROR: Tried to remove a non-vlan device "
"with VLAN code, name: %s priv_flags: %hX\n",
__FUNCTION__, dev->name, dev->priv_flags);
dev_put(dev);
ret = -EPERM;
}
} else {
#ifdef VLAN_DEBUG
printk(VLAN_DBG "%s: WARNING: Could not find dev.\n", __FUNCTION__);
#endif
ret = -EINVAL;
}

if (ret == 1)
ret = 0;
return ret;
}

Expand Down Expand Up @@ -378,12 +351,11 @@ static struct lock_class_key vlan_netdev_xmit_lock_key;
* Returns the device that was created, or NULL if there was
* an error of some kind.
*/
static struct net_device *register_vlan_device(const char *eth_IF_name,
static struct net_device *register_vlan_device(struct net_device *real_dev,
unsigned short VLAN_ID)
{
struct vlan_group *grp;
struct net_device *new_dev;
struct net_device *real_dev; /* the ethernet device */
char name[IFNAMSIZ];
int i;

Expand All @@ -395,46 +367,36 @@ static struct net_device *register_vlan_device(const char *eth_IF_name,
if (VLAN_ID >= VLAN_VID_MASK)
goto out_ret_null;

/* find the device relating to eth_IF_name. */
real_dev = dev_get_by_name(eth_IF_name);
if (!real_dev)
goto out_ret_null;

if (real_dev->features & NETIF_F_VLAN_CHALLENGED) {
printk(VLAN_DBG "%s: VLANs not supported on %s.\n",
__FUNCTION__, real_dev->name);
goto out_put_dev;
goto out_ret_null;
}

if ((real_dev->features & NETIF_F_HW_VLAN_RX) &&
!real_dev->vlan_rx_register) {
printk(VLAN_DBG "%s: Device %s has buggy VLAN hw accel.\n",
__FUNCTION__, real_dev->name);
goto out_put_dev;
goto out_ret_null;
}

if ((real_dev->features & NETIF_F_HW_VLAN_FILTER) &&
(!real_dev->vlan_rx_add_vid || !real_dev->vlan_rx_kill_vid)) {
printk(VLAN_DBG "%s: Device %s has buggy VLAN hw accel.\n",
__FUNCTION__, real_dev->name);
goto out_put_dev;
goto out_ret_null;
}

/* From this point on, all the data structures must remain
* consistent.
*/
rtnl_lock();

/* The real device must be up and operating in order to
* assosciate a VLAN device with it.
*/
if (!(real_dev->flags & IFF_UP))
goto out_unlock;
goto out_ret_null;

if (__find_vlan_dev(real_dev, VLAN_ID) != NULL) {
/* was already registered. */
printk(VLAN_DBG "%s: ALREADY had VLAN registered\n", __FUNCTION__);
goto out_unlock;
goto out_ret_null;
}

/* Gotta set up the fields for the device. */
Expand Down Expand Up @@ -471,7 +433,7 @@ static struct net_device *register_vlan_device(const char *eth_IF_name,
vlan_setup);

if (new_dev == NULL)
goto out_unlock;
goto out_ret_null;

#ifdef VLAN_DEBUG
printk(VLAN_DBG "Allocated new name -:%s:-\n", new_dev->name);
Expand Down Expand Up @@ -577,9 +539,8 @@ static struct net_device *register_vlan_device(const char *eth_IF_name,
if (real_dev->features & NETIF_F_HW_VLAN_FILTER)
real_dev->vlan_rx_add_vid(real_dev, VLAN_ID);

rtnl_unlock();


/* 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
Expand All @@ -590,17 +551,11 @@ static struct net_device *register_vlan_device(const char *eth_IF_name,

out_free_unregister:
unregister_netdev(new_dev);
goto out_unlock;
goto out_ret_null;

out_free_newdev:
free_netdev(new_dev);

out_unlock:
rtnl_unlock();

out_put_dev:
dev_put(real_dev);

out_ret_null:
return NULL;
}
Expand Down Expand Up @@ -693,9 +648,10 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
*/
static int vlan_ioctl_handler(void __user *arg)
{
int err = 0;
int err;
unsigned short vid = 0;
struct vlan_ioctl_args args;
struct net_device *dev = NULL;

if (copy_from_user(&args, arg, sizeof(struct vlan_ioctl_args)))
return -EFAULT;
Expand All @@ -708,35 +664,61 @@ static int vlan_ioctl_handler(void __user *arg)
printk(VLAN_DBG "%s: args.cmd: %x\n", __FUNCTION__, args.cmd);
#endif

rtnl_lock();

switch (args.cmd) {
case SET_VLAN_INGRESS_PRIORITY_CMD:
case SET_VLAN_EGRESS_PRIORITY_CMD:
case SET_VLAN_FLAG_CMD:
case ADD_VLAN_CMD:
case DEL_VLAN_CMD:
case GET_VLAN_REALDEV_NAME_CMD:
case GET_VLAN_VID_CMD:
err = -ENODEV;
dev = __dev_get_by_name(args.device1);
if (!dev)
goto out;

err = -EINVAL;
if (args.cmd != ADD_VLAN_CMD &&
!(dev->priv_flags & IFF_802_1Q_VLAN))
goto out;
}

switch (args.cmd) {
case SET_VLAN_INGRESS_PRIORITY_CMD:
err = -EPERM;
if (!capable(CAP_NET_ADMIN))
return -EPERM;
err = vlan_dev_set_ingress_priority(args.device1,
args.u.skb_priority,
args.vlan_qos);
break;
vlan_dev_set_ingress_priority(dev,
args.u.skb_priority,
args.vlan_qos);
break;

case SET_VLAN_EGRESS_PRIORITY_CMD:
err = -EPERM;
if (!capable(CAP_NET_ADMIN))
return -EPERM;
err = vlan_dev_set_egress_priority(args.device1,
break;
err = vlan_dev_set_egress_priority(dev,
args.u.skb_priority,
args.vlan_qos);
break;

case SET_VLAN_FLAG_CMD:
err = -EPERM;
if (!capable(CAP_NET_ADMIN))
return -EPERM;
err = vlan_dev_set_vlan_flag(args.device1,
break;
err = vlan_dev_set_vlan_flag(dev,
args.u.flag,
args.vlan_qos);
break;

case SET_VLAN_NAME_TYPE_CMD:
err = -EPERM;
if (!capable(CAP_NET_ADMIN))
return -EPERM;
if (args.u.name_type < VLAN_NAME_TYPE_HIGHEST) {
if ((args.u.name_type >= 0) &&
(args.u.name_type < VLAN_NAME_TYPE_HIGHEST)) {
vlan_name_type = args.u.name_type;
err = 0;
} else {
Expand All @@ -745,26 +727,21 @@ static int vlan_ioctl_handler(void __user *arg)
break;

case ADD_VLAN_CMD:
err = -EPERM;
if (!capable(CAP_NET_ADMIN))
return -EPERM;
/* we have been given the name of the Ethernet Device we want to
* talk to: args.dev1 We also have the
* VLAN ID: args.u.VID
*/
if (register_vlan_device(args.device1, args.u.VID)) {
break;
if (register_vlan_device(dev, args.u.VID)) {
err = 0;
} else {
err = -EINVAL;
}
break;

case DEL_VLAN_CMD:
err = -EPERM;
if (!capable(CAP_NET_ADMIN))
return -EPERM;
/* Here, the args.dev1 is the actual VLAN we want
* to get rid of.
*/
err = unregister_vlan_device(args.device1);
break;
err = unregister_vlan_device(dev);
break;

case GET_VLAN_INGRESS_PRIORITY_CMD:
Expand All @@ -788,19 +765,15 @@ static int vlan_ioctl_handler(void __user *arg)
err = -EINVAL;
break;
case GET_VLAN_REALDEV_NAME_CMD:
err = vlan_dev_get_realdev_name(args.device1, args.u.device2);
if (err)
goto out;
vlan_dev_get_realdev_name(dev, args.u.device2);
if (copy_to_user(arg, &args,
sizeof(struct vlan_ioctl_args))) {
err = -EFAULT;
}
break;

case GET_VLAN_VID_CMD:
err = vlan_dev_get_vid(args.device1, &vid);
if (err)
goto out;
vlan_dev_get_vid(dev, &vid);
args.u.VID = vid;
if (copy_to_user(arg, &args,
sizeof(struct vlan_ioctl_args))) {
Expand All @@ -812,9 +785,11 @@ static int vlan_ioctl_handler(void __user *arg)
/* pass on to underlying device instead?? */
printk(VLAN_DBG "%s: Unknown VLAN CMD: %x \n",
__FUNCTION__, args.cmd);
return -EINVAL;
err = -EINVAL;
break;
}
out:
rtnl_unlock();
return err;
}

Expand Down
13 changes: 8 additions & 5 deletions trunk/net/8021q/vlan.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,14 @@ int vlan_dev_set_mac_address(struct net_device *dev, void* addr);
int vlan_dev_open(struct net_device* dev);
int vlan_dev_stop(struct net_device* dev);
int vlan_dev_ioctl(struct net_device* dev, struct ifreq *ifr, int cmd);
int vlan_dev_set_ingress_priority(char* dev_name, __u32 skb_prio, short vlan_prio);
int vlan_dev_set_egress_priority(char* dev_name, __u32 skb_prio, short vlan_prio);
int vlan_dev_set_vlan_flag(char* dev_name, __u32 flag, short flag_val);
int vlan_dev_get_realdev_name(const char* dev_name, char* result);
int vlan_dev_get_vid(const char* dev_name, unsigned short* result);
void vlan_dev_set_ingress_priority(const struct net_device *dev,
u32 skb_prio, short vlan_prio);
int vlan_dev_set_egress_priority(const struct net_device *dev,
u32 skb_prio, short vlan_prio);
int vlan_dev_set_vlan_flag(const struct net_device *dev,
u32 flag, short flag_val);
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);

#endif /* !(__BEN_VLAN_802_1Q_INC__) */
Loading

0 comments on commit f964935

Please sign in to comment.