X-Git-Url: http://pilppa.org/gitweb/?a=blobdiff_plain;f=include%2Flinux%2Fif_vlan.h;h=15ace02b7b24b0f3cd0ccfa62bd092fd9b45ead1;hb=595f403c1af37b1339e64b89040528b8cd48c5a3;hp=35cb385735837a2e5b0eca166770bcc647c41fd9;hpb=12cbbd95e12e911b43afae7f6f4850f616223642;p=linux-2.6-omap-h63xx.git diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h index 35cb3857358..15ace02b7b2 100644 --- a/include/linux/if_vlan.h +++ b/include/linux/if_vlan.h @@ -16,11 +16,6 @@ #ifdef __KERNEL__ /* externally defined structs */ -struct vlan_group; -struct net_device; -struct packet_type; -struct vlan_collection; -struct vlan_dev_info; struct hlist_node; #include @@ -39,48 +34,83 @@ struct hlist_node; #define VLAN_ETH_DATA_LEN 1500 /* Max. octets in payload */ #define VLAN_ETH_FRAME_LEN 1518 /* Max. octets in frame sans FCS */ +/* + * struct vlan_hdr - vlan header + * @h_vlan_TCI: priority and VLAN ID + * @h_vlan_encapsulated_proto: packet type ID or len + */ +struct vlan_hdr { + __be16 h_vlan_TCI; + __be16 h_vlan_encapsulated_proto; +}; + +/** + * struct vlan_ethhdr - vlan ethernet header (ethhdr + vlan_hdr) + * @h_dest: destination ethernet address + * @h_source: source ethernet address + * @h_vlan_proto: ethernet protocol (always 0x8100) + * @h_vlan_TCI: priority and VLAN ID + * @h_vlan_encapsulated_proto: packet type ID or len + */ struct vlan_ethhdr { - unsigned char h_dest[ETH_ALEN]; /* destination eth addr */ - unsigned char h_source[ETH_ALEN]; /* source ether addr */ - __be16 h_vlan_proto; /* Should always be 0x8100 */ - __be16 h_vlan_TCI; /* Encapsulates priority and VLAN ID */ - __be16 h_vlan_encapsulated_proto; /* packet type ID field (or len) */ + unsigned char h_dest[ETH_ALEN]; + unsigned char h_source[ETH_ALEN]; + __be16 h_vlan_proto; + __be16 h_vlan_TCI; + __be16 h_vlan_encapsulated_proto; }; #include static inline struct vlan_ethhdr *vlan_eth_hdr(const struct sk_buff *skb) { - return (struct vlan_ethhdr *)skb->mac.raw; + return (struct vlan_ethhdr *)skb_mac_header(skb); } -struct vlan_hdr { - __be16 h_vlan_TCI; /* Encapsulates priority and VLAN ID */ - __be16 h_vlan_encapsulated_proto; /* packet type ID field (or len) */ -}; - #define VLAN_VID_MASK 0xfff /* found in socket.c */ -extern void vlan_ioctl_set(int (*hook)(void __user *)); - -#define VLAN_NAME "vlan" +extern void vlan_ioctl_set(int (*hook)(struct net *, void __user *)); /* if this changes, algorithm will have to be reworked because this * depends on completely exhausting the VLAN identifier space. Thus * it gives constant time look-up, but in many cases it wastes memory. */ -#define VLAN_GROUP_ARRAY_LEN 4096 +#define VLAN_GROUP_ARRAY_LEN 4096 +#define VLAN_GROUP_ARRAY_SPLIT_PARTS 8 +#define VLAN_GROUP_ARRAY_PART_LEN (VLAN_GROUP_ARRAY_LEN/VLAN_GROUP_ARRAY_SPLIT_PARTS) struct vlan_group { - int real_dev_ifindex; /* The ifindex of the ethernet(like) device the vlan is attached to. */ + struct net_device *real_dev; /* The ethernet(like) device + * the vlan is attached to. + */ + unsigned int nr_vlans; struct hlist_node hlist; /* linked list */ - struct net_device *vlan_devices[VLAN_GROUP_ARRAY_LEN]; + struct net_device **vlan_devices_arrays[VLAN_GROUP_ARRAY_SPLIT_PARTS]; struct rcu_head rcu; }; +static inline struct net_device *vlan_group_get_device(struct vlan_group *vg, + unsigned int vlan_id) +{ + struct net_device **array; + array = vg->vlan_devices_arrays[vlan_id / VLAN_GROUP_ARRAY_PART_LEN]; + return array ? array[vlan_id % VLAN_GROUP_ARRAY_PART_LEN] : NULL; +} + +static inline void vlan_group_set_device(struct vlan_group *vg, + unsigned int vlan_id, + struct net_device *dev) +{ + struct net_device **array; + if (!vg) + return; + array = vg->vlan_devices_arrays[vlan_id / VLAN_GROUP_ARRAY_PART_LEN]; + array[vlan_id % VLAN_GROUP_ARRAY_PART_LEN] = dev; +} + struct vlan_priority_tci_mapping { - unsigned long priority; + u32 priority; unsigned short vlan_qos; /* This should be shifted when first set, so we only do it * at provisioning time. * ((skb->priority << 13) & 0xE000) @@ -93,7 +123,10 @@ struct vlan_dev_info { /** This will be the mapping that correlates skb->priority to * 3 bits of VLAN QOS tags... */ - unsigned long ingress_priority_map[8]; + unsigned int nr_ingress_mappings; + u32 ingress_priority_map[8]; + + unsigned int nr_egress_mappings; struct vlan_priority_tci_mapping *egress_priority_map[16]; /* hash table */ unsigned short vlan_id; /* The VLAN Identifier for this interface. */ @@ -105,33 +138,23 @@ struct vlan_dev_info { * like DHCP that use packet-filtering and don't understand * 802.1Q */ - 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 - * to the real hardware... - */ - int old_allmulti; /* similar to above. */ - int old_promiscuity; /* similar to above. */ struct net_device *real_dev; /* the underlying device/interface */ + unsigned char real_dev_addr[ETH_ALEN]; struct proc_dir_entry *dent; /* Holds the proc data */ unsigned long cnt_inc_headroom_on_tx; /* How many times did we have to grow the skb on TX. */ unsigned long cnt_encap_on_xmit; /* How many times did we have to encapsulate the skb on TX. */ - struct net_device_stats dev_stats; /* Device stats (rx-bytes, tx-pkts, etc...) */ }; -#define VLAN_DEV_INFO(x) ((struct vlan_dev_info *)(x->priv)) - -/* inline functions */ - -static inline struct net_device_stats *vlan_dev_get_stats(struct net_device *dev) +static inline struct vlan_dev_info *vlan_dev_info(const struct net_device *dev) { - return &(VLAN_DEV_INFO(dev)->dev_stats); + return netdev_priv(dev); } +/* inline functions */ static inline __u32 vlan_get_ingress_priority(struct net_device *dev, unsigned short vlan_tag) { - struct vlan_dev_info *vip = VLAN_DEV_INFO(dev); + struct vlan_dev_info *vip = vlan_dev_info(dev); return vip->ingress_priority_map[(vlan_tag >> 13) & 0x7]; } @@ -160,7 +183,7 @@ static inline int __vlan_hwaccel_rx(struct sk_buff *skb, return NET_RX_DROP; } - skb->dev = grp->vlan_devices[vlan_tag & VLAN_VID_MASK]; + skb->dev = vlan_group_get_device(grp, vlan_tag & VLAN_VID_MASK); if (skb->dev == NULL) { dev_kfree_skb_any(skb); @@ -172,7 +195,7 @@ static inline int __vlan_hwaccel_rx(struct sk_buff *skb, skb->dev->last_rx = jiffies; - stats = vlan_dev_get_stats(skb->dev); + stats = &skb->dev->stats; stats->rx_packets++; stats->rx_bytes += skb->len; @@ -250,14 +273,14 @@ static inline struct sk_buff *__vlan_put_tag(struct sk_buff *skb, unsigned short memmove(skb->data, skb->data + VLAN_HLEN, 2 * VLAN_ETH_ALEN); /* first, the ethernet type */ - veth->h_vlan_proto = __constant_htons(ETH_P_8021Q); + veth->h_vlan_proto = htons(ETH_P_8021Q); /* now, the tag */ veth->h_vlan_TCI = htons(tag); - skb->protocol = __constant_htons(ETH_P_8021Q); - skb->mac.raw -= VLAN_HLEN; - skb->nh.raw -= VLAN_HLEN; + skb->protocol = htons(ETH_P_8021Q); + skb->mac_header -= VLAN_HLEN; + skb->network_header -= VLAN_HLEN; return skb; } @@ -306,11 +329,11 @@ static inline struct sk_buff *vlan_put_tag(struct sk_buff *skb, unsigned short t * * Returns error if the skb is not of VLAN type */ -static inline int __vlan_get_tag(struct sk_buff *skb, unsigned short *tag) +static inline int __vlan_get_tag(const struct sk_buff *skb, unsigned short *tag) { struct vlan_ethhdr *veth = (struct vlan_ethhdr *)skb->data; - if (veth->h_vlan_proto != __constant_htons(ETH_P_8021Q)) { + if (veth->h_vlan_proto != htons(ETH_P_8021Q)) { return -EINVAL; } @@ -326,7 +349,8 @@ static inline int __vlan_get_tag(struct sk_buff *skb, unsigned short *tag) * * Returns error if @skb->cb[] is not set correctly */ -static inline int __vlan_hwaccel_get_tag(struct sk_buff *skb, unsigned short *tag) +static inline int __vlan_hwaccel_get_tag(const struct sk_buff *skb, + unsigned short *tag) { struct vlan_skb_tx_cookie *cookie; @@ -349,7 +373,7 @@ static inline int __vlan_hwaccel_get_tag(struct sk_buff *skb, unsigned short *ta * * Returns error if the skb is not VLAN tagged */ -static inline int vlan_get_tag(struct sk_buff *skb, unsigned short *tag) +static inline int vlan_get_tag(const struct sk_buff *skb, unsigned short *tag) { if (skb->dev->features & NETIF_F_HW_VLAN_TX) { return __vlan_hwaccel_get_tag(skb, tag); @@ -376,6 +400,10 @@ enum vlan_ioctl_cmds { GET_VLAN_VID_CMD /* Get the VID of this VLAN (specified by name) */ }; +enum vlan_flags { + VLAN_FLAG_REORDER_HDR = 0x1, +}; + enum vlan_name_types { VLAN_NAME_TYPE_PLUS_VID, /* Name will look like: vlan0005 */ VLAN_NAME_TYPE_RAW_PLUS_VID, /* name will look like: eth1.0005 */