Merge tag 'bug-for-3.4' of git://git.kernel.org/pub/scm/linux/kernel/git/paulg/linux
[linux-2.6.git] / include / linux / if_vlan.h
index bc03e40..a810987 100644 (file)
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/rtnetlink.h>
+#include <linux/bug.h>
 
-#define VLAN_HLEN      4               /* The additional bytes (on top of the Ethernet header)
-                                        * that VLAN requires.
+#define VLAN_HLEN      4               /* The additional bytes required by VLAN
+                                        * (in addition to the Ethernet header)
                                         */
-#define VLAN_ETH_ALEN  6               /* Octets in one ethernet addr   */
 #define VLAN_ETH_HLEN  18              /* Total octets in header.       */
 #define VLAN_ETH_ZLEN  64              /* Min. octets in frame sans FCS */
 
@@ -74,41 +74,7 @@ static inline struct vlan_ethhdr *vlan_eth_hdr(const struct sk_buff *skb)
 /* found in socket.c */
 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_SPLIT_PARTS  8
-#define VLAN_GROUP_ARRAY_PART_LEN     (VLAN_N_VID/VLAN_GROUP_ARRAY_SPLIT_PARTS)
-
-struct vlan_group {
-       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_arrays[VLAN_GROUP_ARRAY_SPLIT_PARTS];
-       struct rcu_head         rcu;
-};
-
-static inline struct net_device *vlan_group_get_device(struct vlan_group *vg,
-                                                      u16 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,
-                                        u16 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_info;
 
 static inline int is_vlan_dev(struct net_device *dev)
 {
@@ -120,23 +86,24 @@ static inline int is_vlan_dev(struct net_device *dev)
 
 #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
 
+extern struct net_device *__vlan_find_dev_deep(struct net_device *real_dev,
+                                              u16 vlan_id);
 extern struct net_device *vlan_dev_real_dev(const struct net_device *dev);
 extern u16 vlan_dev_vlan_id(const struct net_device *dev);
 
-extern int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp,
-                            u16 vlan_tci, int polling);
-extern bool vlan_do_receive(struct sk_buff **skb);
+extern bool vlan_do_receive(struct sk_buff **skb, bool last_handler);
 extern struct sk_buff *vlan_untag(struct sk_buff *skb);
-extern gro_result_t
-vlan_gro_receive(struct napi_struct *napi, struct vlan_group *grp,
-                unsigned int vlan_tci, struct sk_buff *skb);
-extern gro_result_t
-vlan_gro_frags(struct napi_struct *napi, struct vlan_group *grp,
-              unsigned int vlan_tci);
 
+extern int vlan_vid_add(struct net_device *dev, unsigned short vid);
+extern void vlan_vid_del(struct net_device *dev, unsigned short vid);
+
+extern int vlan_vids_add_by_dev(struct net_device *dev,
+                               const struct net_device *by_dev);
+extern void vlan_vids_del_by_dev(struct net_device *dev,
+                                const struct net_device *by_dev);
 #else
-static inline struct net_device *vlan_find_dev(struct net_device *real_dev,
-                                              u16 vlan_id)
+static inline struct net_device *
+__vlan_find_dev_deep(struct net_device *real_dev, u16 vlan_id)
 {
        return NULL;
 }
@@ -153,16 +120,9 @@ static inline u16 vlan_dev_vlan_id(const struct net_device *dev)
        return 0;
 }
 
-static inline int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp,
-                                   u16 vlan_tci, int polling)
+static inline bool vlan_do_receive(struct sk_buff **skb, bool last_handler)
 {
-       BUG();
-       return NET_XMIT_SUCCESS;
-}
-
-static inline bool vlan_do_receive(struct sk_buff **skb)
-{
-       if ((*skb)->vlan_tci & VLAN_VID_MASK)
+       if (((*skb)->vlan_tci & VLAN_VID_MASK) && last_handler)
                (*skb)->pkt_type = PACKET_OTHERHOST;
        return false;
 }
@@ -172,46 +132,26 @@ static inline struct sk_buff *vlan_untag(struct sk_buff *skb)
        return skb;
 }
 
-static inline gro_result_t
-vlan_gro_receive(struct napi_struct *napi, struct vlan_group *grp,
-                unsigned int vlan_tci, struct sk_buff *skb)
+static inline int vlan_vid_add(struct net_device *dev, unsigned short vid)
 {
-       return GRO_DROP;
+       return 0;
 }
 
-static inline gro_result_t
-vlan_gro_frags(struct napi_struct *napi, struct vlan_group *grp,
-              unsigned int vlan_tci)
+static inline void vlan_vid_del(struct net_device *dev, unsigned short vid)
 {
-       return GRO_DROP;
 }
-#endif
 
-/**
- * vlan_hwaccel_rx - netif_rx wrapper for VLAN RX acceleration
- * @skb: buffer
- * @grp: vlan group
- * @vlan_tci: VLAN TCI as received from the card
- */
-static inline int vlan_hwaccel_rx(struct sk_buff *skb,
-                                 struct vlan_group *grp,
-                                 u16 vlan_tci)
+static inline int vlan_vids_add_by_dev(struct net_device *dev,
+                                      const struct net_device *by_dev)
 {
-       return __vlan_hwaccel_rx(skb, grp, vlan_tci, 0);
+       return 0;
 }
 
-/**
- * vlan_hwaccel_receive_skb - netif_receive_skb wrapper for VLAN RX acceleration
- * @skb: buffer
- * @grp: vlan group
- * @vlan_tci: VLAN TCI as received from the card
- */
-static inline int vlan_hwaccel_receive_skb(struct sk_buff *skb,
-                                          struct vlan_group *grp,
-                                          u16 vlan_tci)
+static inline void vlan_vids_del_by_dev(struct net_device *dev,
+                                       const struct net_device *by_dev)
 {
-       return __vlan_hwaccel_rx(skb, grp, vlan_tci, 1);
 }
+#endif
 
 /**
  * vlan_insert_tag - regular VLAN tag inserting
@@ -237,7 +177,7 @@ static inline struct sk_buff *vlan_insert_tag(struct sk_buff *skb, u16 vlan_tci)
        veth = (struct vlan_ethhdr *)skb_push(skb, VLAN_HLEN);
 
        /* Move the mac addresses to the beginning of the new header. */
-       memmove(skb->data, skb->data + VLAN_HLEN, 2 * VLAN_ETH_ALEN);
+       memmove(skb->data, skb->data + VLAN_HLEN, 2 * ETH_ALEN);
        skb->mac_header -= VLAN_HLEN;
 
        /* first, the ethernet type */
@@ -382,6 +322,40 @@ static inline __be16 vlan_get_protocol(const struct sk_buff *skb)
 
        return protocol;
 }
+
+static inline void vlan_set_encap_proto(struct sk_buff *skb,
+                                       struct vlan_hdr *vhdr)
+{
+       __be16 proto;
+       unsigned char *rawp;
+
+       /*
+        * Was a VLAN packet, grab the encapsulated protocol, which the layer
+        * three protocols care about.
+        */
+
+       proto = vhdr->h_vlan_encapsulated_proto;
+       if (ntohs(proto) >= 1536) {
+               skb->protocol = proto;
+               return;
+       }
+
+       rawp = skb->data;
+       if (*(unsigned short *) rawp == 0xFFFF)
+               /*
+                * This is a magic hack to spot IPX packets. Older Novell
+                * breaks the protocol design and runs IPX over 802.3 without
+                * an 802.2 LLC layer. We look for FFFF which isn't a used
+                * 802.2 SSAP/DSAP. This won't work for fault tolerant netware
+                * but does for the rest.
+                */
+               skb->protocol = htons(ETH_P_802_3);
+       else
+               /*
+                * Real 802.2 LLC
+                */
+               skb->protocol = htons(ETH_P_802_2);
+}
 #endif /* __KERNEL__ */
 
 /* VLAN IOCTLs are found in sockios.h */
@@ -424,7 +398,7 @@ struct vlan_ioctl_args {
                unsigned int skb_priority;
                unsigned int name_type;
                unsigned int bind_type;
-               unsigned int flag; /* Matches vlan_dev_info flags */
+               unsigned int flag; /* Matches vlan_dev_priv flags */
         } u;
 
        short vlan_qos;