From: Ben Greear <greearb@candelatech.com>
To: "'netdev@oss.sgi.com'" <netdev@oss.sgi.com>,
"Linux 802.1Q VLAN" <vlan@candelatech.com>
Subject: [PATCH] 802.1Q VLAN
Date: Fri, 22 Oct 2004 14:07:34 -0700 [thread overview]
Message-ID: <41797696.9070905@candelatech.com> (raw)
Signed off by: Ben Greear <greearb@candelatech.com>
This patch brings the 2.6.9 802.1Q VLAN code up to date with 2.4.27. It also
includes better return logic from the hard_start_xmit hook to allow
back pressure up the networking stack.
Comments welcome.
Thanks,
Ben
--- linux-2.6.9/net/8021q/vlan_dev.c 2004-10-18 14:55:07.000000000 -0700
+++ linux-2.6.9.p4s/net/8021q/vlan_dev.c 2004-10-22 12:14:24.000000000 -0700
@@ -1,4 +1,4 @@
-/*
+/* -*- linux-c -*-
* INET 802.1Q VLAN
* Ethernet-type device handling.
*
@@ -484,13 +484,32 @@
veth->h_vlan_proto, veth->h_vlan_TCI, veth->h_vlan_encapsulated_proto);
#endif
- stats->tx_packets++; /* for statics only */
- stats->tx_bytes += skb->len;
-
skb->dev = VLAN_DEV_INFO(dev)->real_dev;
- dev_queue_xmit(skb);
- return 0;
+ {
+ /* Please note, dev_queue_xmit consumes the pkt regardless of the
+ * error value. So, will copy the skb first and free if successful.
+ */
+ struct sk_buff* skb2 = skb_get(skb);
+ int rv = dev_queue_xmit(skb2);
+ if (rv != 0) {
+ /* The skb memory should still be valid since we made a copy,
+ * so can return error code here.
+ */
+ return rv;
+ }
+ else {
+ /* Was success, need to free the skb reference since we bumped up the
+ * user count above.
+ */
+
+ stats->tx_packets++; /* for statics only */
+ stats->tx_bytes += skb->len;
+
+ kfree_skb(skb);
+ return 0;
+ }
+ }
}
int vlan_dev_hwaccel_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
@@ -622,7 +641,57 @@
return -EINVAL;
}
+
+int vlan_dev_get_realdev_name(const char *dev_name, char* result)
+{
+ struct net_device *dev = dev_get_by_name(dev_name);
+ int rv = 0;
+ if (dev) {
+ if (dev->priv_flags & IFF_802_1Q_VLAN) {
+ strncpy(result, VLAN_DEV_INFO(dev)->real_dev->name, 23);
+ dev_put(dev);
+ rv = 0;
+ } else {
+ /*printk(KERN_ERR
+ "%s: %s is not a vlan device, priv_flags: %hX.\n",
+ __FUNCTION__, dev->name, dev->priv_flags);*/
+ dev_put(dev);
+ rv = -EINVAL;
+ }
+ } else {
+ /* printk(KERN_ERR "%s: Could not find device: %s\n",
+ __FUNCTION__, dev_name); */
+ rv = -ENODEV;
+ }
+ return rv;
+}
+
+int vlan_dev_get_vid(const char *dev_name, unsigned short* result)
+{
+ struct net_device *dev = dev_get_by_name(dev_name);
+ int rv = 0;
+ if (dev) {
+ if (dev->priv_flags & IFF_802_1Q_VLAN) {
+ *result = VLAN_DEV_INFO(dev)->vlan_id;
+ dev_put(dev);
+ rv = 0;
+ } else {
+ /*printk(KERN_ERR
+ "%s: %s is not a vlan device, priv_flags: %hX.\n",
+ __FUNCTION__, dev->name, dev->priv_flags);*/
+ dev_put(dev);
+ rv = -EINVAL;
+ }
+ } else {
+ /* printk(KERN_ERR "%s: Could not find device: %s\n",
+ __FUNCTION__, dev_name);*/
+ rv = -ENODEV;
+ }
+ return rv;
+}
+
+
int vlan_dev_set_mac_address(struct net_device *dev, void *addr_struct_p)
{
struct sockaddr *addr = (struct sockaddr *)(addr_struct_p);
--- linux-2.6.9/net/8021q/vlan.c 2004-10-18 14:54:55.000000000 -0700
+++ linux-2.6.9.p4s/net/8021q/vlan.c 2004-10-22 12:14:24.000000000 -0700
@@ -1,4 +1,4 @@
-/*
+/* -*- linux-c -*-
* INET 802.1Q VLAN
* Ethernet-type device handling.
*
@@ -646,15 +646,9 @@
static int vlan_ioctl_handler(void __user *arg)
{
int err = 0;
+ unsigned short vid = 0;
struct vlan_ioctl_args args;
- /* everything here needs root permissions, except aguably the
- * hack ioctls for sending packets. However, I know _I_ don't
- * want users running that on my network! --BLG
- */
- if (!capable(CAP_NET_ADMIN))
- return -EPERM;
-
if (copy_from_user(&args, arg, sizeof(struct vlan_ioctl_args)))
return -EFAULT;
@@ -668,24 +662,32 @@
switch (args.cmd) {
case SET_VLAN_INGRESS_PRIORITY_CMD:
+ if (!capable(CAP_NET_ADMIN))
+ return -EPERM;
err = vlan_dev_set_ingress_priority(args.device1,
args.u.skb_priority,
args.vlan_qos);
break;
case SET_VLAN_EGRESS_PRIORITY_CMD:
+ if (!capable(CAP_NET_ADMIN))
+ return -EPERM;
err = vlan_dev_set_egress_priority(args.device1,
args.u.skb_priority,
args.vlan_qos);
break;
case SET_VLAN_FLAG_CMD:
+ if (!capable(CAP_NET_ADMIN))
+ return -EPERM;
err = vlan_dev_set_vlan_flag(args.device1,
args.u.flag,
args.vlan_qos);
break;
case SET_VLAN_NAME_TYPE_CMD:
+ if (!capable(CAP_NET_ADMIN))
+ return -EPERM;
if ((args.u.name_type >= 0) &&
(args.u.name_type < VLAN_NAME_TYPE_HIGHEST)) {
vlan_name_type = args.u.name_type;
@@ -695,17 +697,9 @@
}
break;
- /* TODO: Figure out how to pass info back...
- case GET_VLAN_INGRESS_PRIORITY_IOCTL:
- err = vlan_dev_get_ingress_priority(args);
- break;
-
- case GET_VLAN_EGRESS_PRIORITY_IOCTL:
- err = vlan_dev_get_egress_priority(args);
- break;
- */
-
case ADD_VLAN_CMD:
+ 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
@@ -718,13 +712,52 @@
break;
case DEL_VLAN_CMD:
+ 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;
+ case GET_VLAN_INGRESS_PRIORITY_CMD:
+ /* TODO: Implement
+ err = vlan_dev_get_ingress_priority(args);
+ if (copy_to_user((void*)arg, &args,
+ sizeof(struct vlan_ioctl_args))) {
+ err = -EFAULT;
+ }
+ */
+ err = -EINVAL;
+ break;
+ case GET_VLAN_EGRESS_PRIORITY_CMD:
+ /* TODO: Implement
+ err = vlan_dev_get_egress_priority(args.device1, &(args.args);
+ if (copy_to_user((void*)arg, &args,
+ sizeof(struct vlan_ioctl_args))) {
+ err = -EFAULT;
+ }
+ */
+ err = -EINVAL;
+ break;
+ case GET_VLAN_REALDEV_NAME_CMD:
+ err = vlan_dev_get_realdev_name(args.device1, args.u.device2);
+ if (copy_to_user((void*)arg, &args,
+ sizeof(struct vlan_ioctl_args))) {
+ err = -EFAULT;
+ }
+ break;
+
+ case GET_VLAN_VID_CMD:
+ err = vlan_dev_get_vid(args.device1, &vid);
+ args.u.VID = vid;
+ if (copy_to_user((void*)arg, &args,
+ sizeof(struct vlan_ioctl_args))) {
+ err = -EFAULT;
+ }
+ break;
+
default:
/* pass on to underlying device instead?? */
printk(VLAN_DBG "%s: Unknown VLAN CMD: %x \n",
--- linux-2.6.9/net/8021q/vlan.h 2004-10-18 14:54:37.000000000 -0700
+++ linux-2.6.9.p4s/net/8021q/vlan.h 2004-10-22 12:14:24.000000000 -0700
@@ -66,7 +66,9 @@
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_multicast_list(struct net_device *vlan_dev);
#endif /* !(__BEN_VLAN_802_1Q_INC__) */
--- linux-2.6.9/include/linux/if_vlan.h 2004-10-18 14:53:43.000000000 -0700
+++ linux-2.6.9.p4s/include/linux/if_vlan.h 2004-10-22 12:14:24.000000000 -0700
@@ -366,7 +366,9 @@
GET_VLAN_INGRESS_PRIORITY_CMD,
GET_VLAN_EGRESS_PRIORITY_CMD,
SET_VLAN_NAME_TYPE_CMD,
- SET_VLAN_FLAG_CMD
+ SET_VLAN_FLAG_CMD,
+ GET_VLAN_REALDEV_NAME_CMD, /* If this works, you know it's a VLAN device, btw */
+ GET_VLAN_VID_CMD /* Get the VID of this VLAN (specified by name) */
};
enum vlan_name_types {
--
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc http://www.candelatech.com
next reply other threads:[~2004-10-22 21:07 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2004-10-22 21:07 Ben Greear [this message]
2004-10-22 21:46 ` [PATCH] 802.1Q VLAN Francois Romieu
2004-10-22 22:09 ` Ben Greear
2004-10-23 0:24 ` Francois Romieu
2004-10-25 20:51 ` Ben Greear
2004-10-25 23:56 ` Ben Greear
2004-10-27 1:02 ` David S. Miller
2004-10-27 23:49 ` David S. Miller
2004-10-28 1:28 ` Ben Greear
2004-10-28 4:42 ` David S. Miller
2004-10-28 23:40 ` Tommy Christensen
2004-10-28 23:35 ` David S. Miller
2004-10-29 0:23 ` Ben Greear
2004-10-29 0:38 ` Krzysztof Halasa
2004-10-29 8:29 ` Tommy Christensen
2004-10-29 17:45 ` Ben Greear
2004-10-29 23:37 ` Tommy Christensen
2004-10-29 23:56 ` Ben Greear
2004-10-30 0:05 ` Ben Greear
2004-10-30 0:31 ` Tommy Christensen
2004-11-01 18:58 ` Ben Greear
2004-11-01 23:08 ` Tommy Christensen
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=41797696.9070905@candelatech.com \
--to=greearb@candelatech.com \
--cc=netdev@oss.sgi.com \
--cc=vlan@candelatech.com \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).