Add support to the VLAN subsystem for enabling/disabling hardware VLAN filtering at runtime. This is useful for debugging purposes.
The existing vconfig utility can be used without modification. Signed-off-by: Mitch Williams <[EMAIL PROTECTED]> diff -urpN -X dontdiff linux-2.6.22.1-clean/include/linux/if_vlan.h linux-2.6.22.1/include/linux/if_vlan.h --- linux-2.6.22.1-clean/include/linux/if_vlan.h 2007-07-10 11:56:30.000000000 -0700 +++ linux-2.6.22.1/include/linux/if_vlan.h 2007-07-26 16:29:00.000000000 -0700 @@ -106,7 +106,20 @@ struct vlan_priority_tci_mapping { */ struct vlan_priority_tci_mapping *next; }; - +#define VLAN_FLAG_REORDER 1 /* (1 << 0) re_order_header This option will cause the + * VLAN code to move around the ethernet header on + * ingress to make the skb look **exactly** like it + * came in from an ethernet port. This destroys some of + * the VLAN information in the skb, but it fixes programs + * like DHCP that use packet-filtering and don't understand + * 802.1Q + */ + +#define VLAN_FLAG_DISABLE_FILTER 2 /* (1 << 1) disable HW filtering. This flag allows + * devices that perform hardware filtering to + * turn off filtering. This may be useful for + * debugging or for sniffer applications. + */ /* Holds information that makes sense if this device is a VLAN device. */ struct vlan_dev_info { /** This will be the mapping that correlates skb->priority to @@ -116,14 +129,7 @@ struct vlan_dev_info { struct vlan_priority_tci_mapping *egress_priority_map[16]; /* hash table */ unsigned short vlan_id; /* The VLAN Identifier for this interface. */ - unsigned short flags; /* (1 << 0) re_order_header This option will cause the - * VLAN code to move around the ethernet header on - * ingress to make the skb look **exactly** like it - * came in from an ethernet port. This destroys some of - * the VLAN information in the skb, but it fixes programs - * like DHCP that use packet-filtering and don't understand - * 802.1Q - */ + unsigned short flags; struct dev_mc_list *old_mc_list; /* old multi-cast list for the VLAN interface.. * we save this so we can tell what changes were * made, in order to feed the right changes down diff -urpN -X dontdiff linux-2.6.22.1-clean/include/linux/netdevice.h linux-2.6.22.1/include/linux/netdevice.h --- linux-2.6.22.1-clean/include/linux/netdevice.h 2007-07-10 11:56:30.000000000 -0700 +++ linux-2.6.22.1/include/linux/netdevice.h 2007-07-26 16:29:00.000000000 -0700 @@ -522,7 +522,9 @@ struct net_device unsigned short vid); void (*vlan_rx_kill_vid)(struct net_device *dev, unsigned short vid); - +#define HAVE_VLAN_FLAGS + int (*vlan_set_flag)(struct net_device *dev, + unsigned int flag, int value); int (*hard_header_parse)(struct sk_buff *skb, unsigned char *haddr); int (*neigh_setup)(struct net_device *dev, struct neigh_parms *); diff -urpN -X dontdiff linux-2.6.22.1-clean/net/8021q/vlan_dev.c linux-2.6.22.1/net/8021q/vlan_dev.c --- linux-2.6.22.1-clean/net/8021q/vlan_dev.c 2007-07-10 11:56:30.000000000 -0700 +++ linux-2.6.22.1/net/8021q/vlan_dev.c 2007-07-27 11:40:22.000000000 -0700 @@ -593,37 +593,58 @@ int vlan_dev_set_egress_priority(char *d /* Flags are defined in the vlan_dev_info class in include/linux/if_vlan.h file. */ int vlan_dev_set_vlan_flag(char *dev_name, __u32 flag, short flag_val) { + struct net_device *real_dev; struct net_device *dev = dev_get_by_name(dev_name); + int ret = 0; - if (dev) { - if (dev->priv_flags & IFF_802_1Q_VLAN) { - /* verify flag is supported */ - if (flag == 1) { - if (flag_val) { - VLAN_DEV_INFO(dev)->flags |= 1; - } else { - VLAN_DEV_INFO(dev)->flags &= ~1; - } - dev_put(dev); - return 0; - } else { - printk(KERN_ERR "%s: flag %i is not valid.\n", - __FUNCTION__, (int)(flag)); - dev_put(dev); - return -EINVAL; - } - } else { - printk(KERN_ERR - "%s: %s is not a vlan device, priv_flags: %hX.\n", - __FUNCTION__, dev->name, dev->priv_flags); - dev_put(dev); - } - } else { + if (!dev) { printk(KERN_ERR "%s: Could not find device: %s\n", __FUNCTION__, dev_name); + ret = -EINVAL; + goto out_no_dev; + } + + if (!(dev->priv_flags & IFF_802_1Q_VLAN)) { + printk(KERN_ERR + "%s: %s is not a vlan device, priv_flags: %hX.\n", + __FUNCTION__, dev->name, dev->priv_flags); + dev_put(dev); + ret = -EINVAL; + goto out; + } + + real_dev = VLAN_DEV_INFO(dev)->real_dev; + switch (flag) { + case VLAN_FLAG_REORDER: + if (flag_val) + VLAN_DEV_INFO(dev)->flags |= 1; + else + VLAN_DEV_INFO(dev)->flags &= ~1; + break; + + case VLAN_FLAG_DISABLE_FILTER: + if (real_dev->vlan_set_flag) + ret = real_dev->vlan_set_flag(real_dev, + flag, flag_val); + else { + printk(KERN_ERR + "%s: VLAN flags not supported on base device %s.\n", + __FUNCTION__, real_dev->name); + ret = -EINVAL; + } + break; + + default: + printk(KERN_ERR "%s: VLAN flag %d is invalid.\n", + __FUNCTION__, flag); + ret = -EINVAL; + break; } - return -EINVAL; +out: + dev_put(dev); +out_no_dev: + return ret; } - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html