]> git.neil.brown.name Git - history.git/commitdiff
[VLAN]: Use VLAN tag set functionality in 8021q module.
authorShmulik Hen <shmulik.hen@intel.com>
Fri, 6 Feb 2004 08:21:32 +0000 (00:21 -0800)
committerHideaki Yoshifuji <yoshfuji@linux-ipv6.org>
Fri, 6 Feb 2004 08:21:32 +0000 (00:21 -0800)
Make the regular/HW accelerated xmit functions in the 8021q module
use the new set VLAN tag functionality to reduce code duplication.

net/8021q/vlan_dev.c

index 47131d2b27a3b5e2b66289529d3e4b74edf4de4e..b91d251f3fed2a142cbc91d931fac2b8e017bf8a 100644 (file)
@@ -445,6 +445,7 @@ int vlan_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
         */
 
        if (veth->h_vlan_proto != __constant_htons(ETH_P_8021Q)) {
+               int orig_headroom = skb_headroom(skb);
                unsigned short veth_TCI;
 
                /* This is not a VLAN frame...but we can fix that! */
@@ -454,33 +455,7 @@ int vlan_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
                printk(VLAN_DBG "%s: proto to encap: 0x%hx (hbo)\n",
                        __FUNCTION__, htons(veth->h_vlan_proto));
 #endif
-
-               if (skb_headroom(skb) < VLAN_HLEN) {
-                       struct sk_buff *sk_tmp = skb;
-                       skb = skb_realloc_headroom(sk_tmp, VLAN_HLEN);
-                       kfree_skb(sk_tmp);
-                       if (skb == NULL) {
-                               stats->tx_dropped++;
-                               return 0;
-                       }
-                       VLAN_DEV_INFO(dev)->cnt_inc_headroom_on_tx++;
-               } else {
-                       if (!(skb = skb_unshare(skb, GFP_ATOMIC))) {
-                               printk(KERN_ERR "vlan: failed to unshare skbuff\n");
-                               stats->tx_dropped++;
-                               return 0;
-                       }
-               }
-               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, 12);
-
-               /* first, the ethernet type */
-               /* put_unaligned(__constant_htons(ETH_P_8021Q), &veth->h_vlan_proto); */
-               veth->h_vlan_proto = __constant_htons(ETH_P_8021Q);
-
-               /* Now, construct the second two bytes. This field looks something
+               /* Construct the second two bytes. This field looks something
                 * like:
                 * usr_priority: 3 bits  (high bits)
                 * CFI           1 bit
@@ -489,10 +464,16 @@ int vlan_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
                veth_TCI = VLAN_DEV_INFO(dev)->vlan_id;
                veth_TCI |= vlan_dev_get_egress_qos_mask(dev, skb);
 
-               veth->h_vlan_TCI = htons(veth_TCI);
-       }
+               skb = __vlan_put_tag(skb, veth_TCI);
+               if (!skb) {
+                       stats->tx_dropped++;
+                       return 0;
+               }
 
-       skb->dev = VLAN_DEV_INFO(dev)->real_dev;
+               if (orig_headroom < VLAN_HLEN) {
+                       VLAN_DEV_INFO(dev)->cnt_inc_headroom_on_tx++;
+               }
+       }
 
 #ifdef VLAN_DEBUG
        printk(VLAN_DBG "%s: about to send skb: %p to dev: %s\n",
@@ -506,10 +487,7 @@ int vlan_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
        stats->tx_packets++; /* for statics only */
        stats->tx_bytes += skb->len;
 
-       skb->protocol = __constant_htons(ETH_P_8021Q);
-       skb->mac.raw -= VLAN_HLEN;
-       skb->nh.raw -= VLAN_HLEN;
-
+       skb->dev = VLAN_DEV_INFO(dev)->real_dev;
        dev_queue_xmit(skb);
 
        return 0;
@@ -518,17 +496,22 @@ int vlan_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
 int vlan_dev_hwaccel_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
        struct net_device_stats *stats = vlan_dev_get_stats(dev);
-       struct vlan_skb_tx_cookie *cookie;
+       unsigned short veth_TCI;
+
+       /* Construct the second two bytes. This field looks something
+        * like:
+        * usr_priority: 3 bits  (high bits)
+        * CFI           1 bit
+        * VLAN ID       12 bits (low bits)
+        */
+       veth_TCI = VLAN_DEV_INFO(dev)->vlan_id;
+       veth_TCI |= vlan_dev_get_egress_qos_mask(dev, skb);
+       skb = __vlan_hwaccel_put_tag(skb, veth_TCI);
 
        stats->tx_packets++;
        stats->tx_bytes += skb->len;
 
        skb->dev = VLAN_DEV_INFO(dev)->real_dev;
-       cookie = VLAN_TX_SKB_CB(skb);
-       cookie->magic = VLAN_TX_COOKIE_MAGIC;
-       cookie->vlan_tag = (VLAN_DEV_INFO(dev)->vlan_id |
-                           vlan_dev_get_egress_qos_mask(dev, skb));
-
        dev_queue_xmit(skb);
 
        return 0;