static netdev_tx_t vlan_dev_hwaccel_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) { int i = skb_get_queue_mapping(skb); struct netdev_queue *txq = netdev_get_tx_queue(dev, i); u16 vlan_tci; unsigned int len; int ret; vlan_tci = vlan_dev_info(dev)->vlan_id; vlan_tci |= vlan_dev_get_egress_qos_mask(dev, skb); skb = __vlan_hwaccel_put_tag(skb, vlan_tci); skb->dev = vlan_dev_info(dev)->real_dev; len = skb->len; ret = dev_queue_xmit(skb); if (likely(ret == NET_XMIT_SUCCESS || ret == NET_XMIT_CN)) { txq->tx_packets++; txq->tx_bytes += len; } else txq->tx_dropped++; return ret; }
int vlan_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct net_device_stats *stats = vlan_dev_get_stats(dev); struct vlan_ethhdr *veth = (struct vlan_ethhdr *)(skb->data); /* Handle non-VLAN frames if they are sent to us, for example by DHCP. * * NOTE: THIS ASSUMES DIX ETHERNET, SPECIFICALLY NOT SUPPORTING * OTHER THINGS LIKE FDDI/TokenRing/802.3 SNAPs... */ if (veth->h_vlan_proto != htons(ETH_P_8021Q) || VLAN_DEV_INFO(dev)->flags & VLAN_FLAG_REORDER_HDR) { int orig_headroom = skb_headroom(skb); unsigned short veth_TCI; /* This is not a VLAN frame...but we can fix that! */ VLAN_DEV_INFO(dev)->cnt_encap_on_xmit++; #ifdef VLAN_DEBUG printk(VLAN_DBG "%s: proto to encap: 0x%hx (hbo)\n", __FUNCTION__, htons(veth->h_vlan_proto)); #endif /* 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_put_tag(skb, veth_TCI); if (!skb) { stats->tx_dropped++; return 0; } 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", __FUNCTION__, skb, skb->dev->name); printk(VLAN_DBG " %2hx.%2hx.%2hx.%2xh.%2hx.%2hx %2hx.%2hx.%2hx.%2hx.%2hx.%2hx %4hx %4hx %4hx\n", veth->h_dest[0], veth->h_dest[1], veth->h_dest[2], veth->h_dest[3], veth->h_dest[4], veth->h_dest[5], veth->h_source[0], veth->h_source[1], veth->h_source[2], veth->h_source[3], veth->h_source[4], veth->h_source[5], 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; }
int vlan_dev_fastbridge_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) { int i = skb_get_queue_mapping(skb); struct netdev_queue *txq = netdev_get_tx_queue(dev, i); 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_put_tag(skb, veth_TCI); if (!skb) { txq->tx_dropped++; return 0; } txq->tx_packets++; txq->tx_bytes += skb->len; skb->dev = vlan_dev_info(dev)->real_dev; return skb->dev->netdev_ops->ndo_start_xmit(skb, skb->dev); }
static netdev_tx_t vlan_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct ve_struct *env; int i = skb_get_queue_mapping(skb); struct netdev_queue *txq = netdev_get_tx_queue(dev, i); struct vlan_ethhdr *veth = (struct vlan_ethhdr *)(skb->data); unsigned int len; int ret; /* Handle non-VLAN frames if they are sent to us, for example by DHCP. * * NOTE: THIS ASSUMES DIX ETHERNET, SPECIFICALLY NOT SUPPORTING * OTHER THINGS LIKE FDDI/TokenRing/802.3 SNAPs... */ if (veth->h_vlan_proto != htons(ETH_P_8021Q) || vlan_dev_info(dev)->flags & VLAN_FLAG_REORDER_HDR) { unsigned int orig_headroom = skb_headroom(skb); u16 vlan_tci; vlan_dev_info(dev)->cnt_encap_on_xmit++; vlan_tci = vlan_dev_info(dev)->vlan_id; vlan_tci |= vlan_dev_get_egress_qos_mask(dev, skb); skb = __vlan_put_tag(skb, vlan_tci); if (!skb) { txq->tx_dropped++; return NETDEV_TX_OK; } if (orig_headroom < VLAN_HLEN) vlan_dev_info(dev)->cnt_inc_headroom_on_tx++; } skb->dev = vlan_dev_info(dev)->real_dev; len = skb->len; skb->owner_env = skb->dev->owner_env; env = set_exec_env(skb->owner_env); ret = dev_queue_xmit(skb); set_exec_env(env); if (likely(ret == NET_XMIT_SUCCESS)) { txq->tx_packets++; txq->tx_bytes += len; } else txq->tx_dropped++; return NETDEV_TX_OK; }
/* * Create the VLAN header for an arbitrary protocol layer * * saddr=NULL means use device source address * daddr=NULL means leave destination address (eg unresolved arp) * * This is called when the SKB is moving down the stack towards the * physical devices. */ static int vlan_dev_hard_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, const void *daddr, const void *saddr, unsigned int len) { struct vlan_hdr *vhdr; unsigned int vhdrlen = 0; u16 vlan_tci = 0; int rc; if (WARN_ON(skb_headroom(skb) < dev->hard_header_len)) return -ENOSPC; if (!(vlan_dev_info(dev)->flags & VLAN_FLAG_REORDER_HDR)) { vhdr = (struct vlan_hdr *) skb_push(skb, VLAN_HLEN); vlan_tci = vlan_dev_info(dev)->vlan_id; vlan_tci |= vlan_dev_get_egress_qos_mask(dev, skb); vhdr->h_vlan_TCI = htons(vlan_tci); /* * Set the protocol type. For a packet of type ETH_P_802_3 we * put the length in here instead. It is up to the 802.2 * layer to carry protocol information. */ if (type != ETH_P_802_3) vhdr->h_vlan_encapsulated_proto = htons(type); else vhdr->h_vlan_encapsulated_proto = htons(len); skb->protocol = htons(ETH_P_8021Q); type = ETH_P_8021Q; vhdrlen = VLAN_HLEN; } /* Before delegating work to the lower layer, enter our MAC-address */ if (saddr == NULL) saddr = dev->dev_addr; /* Now make the underlying real hard header */ dev = vlan_dev_info(dev)->real_dev; rc = dev_hard_header(skb, dev, type, daddr, saddr, len + vhdrlen); if (rc > 0) rc += vhdrlen; return rc; }
static netdev_tx_t vlan_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct vlan_ethhdr *veth = (struct vlan_ethhdr *)(skb->data); unsigned int len; int ret; /* Handle non-VLAN frames if they are sent to us, for example by DHCP. * * NOTE: THIS ASSUMES DIX ETHERNET, SPECIFICALLY NOT SUPPORTING * OTHER THINGS LIKE FDDI/TokenRing/802.3 SNAPs... */ if ( #ifdef CONFIG_VLAN_8021Q_DOUBLE_TAG vlan_double_tag || #endif veth->h_vlan_proto != __constant_htons(ETH_P_8021Q) || (vlan_dev_priv(dev)->flags & VLAN_FLAG_REORDER_HDR)) { u16 vlan_tci; vlan_tci = vlan_dev_priv(dev)->vlan_id; vlan_tci |= vlan_dev_get_egress_qos_mask(dev, skb); skb = __vlan_hwaccel_put_tag(skb, vlan_tci); } skb->dev = vlan_dev_priv(dev)->real_dev; len = skb->len; #ifdef CONFIG_NETPOLL if (netpoll_tx_running(dev)) return skb->dev->netdev_ops->ndo_start_xmit(skb, skb->dev); #endif ret = dev_queue_xmit(skb); if (likely(ret == NET_XMIT_SUCCESS || ret == NET_XMIT_CN)) { struct vlan_pcpu_stats *stats; stats = this_cpu_ptr(vlan_dev_priv(dev)->vlan_pcpu_stats); u64_stats_update_begin(&stats->syncp); stats->tx_packets++; stats->tx_bytes += len; u64_stats_update_end(&stats->syncp); } else { this_cpu_inc(vlan_dev_priv(dev)->vlan_pcpu_stats->tx_dropped); } return ret; }
static int vlan_dev_hwaccel_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct net_device_stats *stats = &dev->stats; u16 vlan_tci; vlan_tci = vlan_dev_info(dev)->vlan_id; vlan_tci |= vlan_dev_get_egress_qos_mask(dev, skb); skb = __vlan_hwaccel_put_tag(skb, vlan_tci); stats->tx_packets++; stats->tx_bytes += skb->len; skb->dev = vlan_dev_info(dev)->real_dev; dev_queue_xmit(skb); return NETDEV_TX_OK; }
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; 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; }
/* * Create the VLAN header for an arbitrary protocol layer * * saddr=NULL means use device source address * daddr=NULL means leave destination address (eg unresolved arp) * * This is called when the SKB is moving down the stack towards the * physical devices. */ static int vlan_dev_hard_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, const void *daddr, const void *saddr, unsigned int len) { struct vlan_dev_priv *vlan = vlan_dev_priv(dev); struct vlan_hdr *vhdr; unsigned int vhdrlen = 0; u16 vlan_tci = 0; int rc; if (!(vlan->flags & VLAN_FLAG_REORDER_HDR)) { vhdr = (struct vlan_hdr *) skb_push(skb, VLAN_HLEN); vlan_tci = vlan->vlan_id; vlan_tci |= vlan_dev_get_egress_qos_mask(dev, skb->priority); vhdr->h_vlan_TCI = htons(vlan_tci); /* * Set the protocol type. For a packet of type ETH_P_802_3/2 we * put the length in here instead. */ if (type != ETH_P_802_3 && type != ETH_P_802_2) vhdr->h_vlan_encapsulated_proto = htons(type); else vhdr->h_vlan_encapsulated_proto = htons(len); skb->protocol = vlan->vlan_proto; type = ntohs(vlan->vlan_proto); vhdrlen = VLAN_HLEN; } /* Before delegating work to the lower layer, enter our MAC-address */ if (saddr == NULL) saddr = dev->dev_addr; /* Now make the underlying real hard header */ dev = vlan->real_dev; rc = dev_hard_header(skb, dev, type, daddr, saddr, len + vhdrlen); if (rc > 0) rc += vhdrlen; return rc; }
static netdev_tx_t vlan_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct vlan_dev_priv *vlan = vlan_dev_priv(dev); struct vlan_ethhdr *veth = (struct vlan_ethhdr *)(skb->data); unsigned int len; int ret; /* Handle non-VLAN frames if they are sent to us, for example by DHCP. * * NOTE: THIS ASSUMES DIX ETHERNET, SPECIFICALLY NOT SUPPORTING * OTHER THINGS LIKE FDDI/TokenRing/802.3 SNAPs... */ if (veth->h_vlan_proto != vlan->vlan_proto || vlan->flags & VLAN_FLAG_REORDER_HDR) { u16 vlan_tci; vlan_tci = vlan->vlan_id; vlan_tci |= vlan_dev_get_egress_qos_mask(dev, skb->priority); __vlan_hwaccel_put_tag(skb, vlan->vlan_proto, vlan_tci); } skb->dev = vlan->real_dev; len = skb->len; if (unlikely(netpoll_tx_running(dev))) return vlan_netpoll_send_skb(vlan, skb); ret = dev_queue_xmit(skb); if (likely(ret == NET_XMIT_SUCCESS || ret == NET_XMIT_CN)) { struct vlan_pcpu_stats *stats; stats = this_cpu_ptr(vlan->vlan_pcpu_stats); u64_stats_update_begin(&stats->syncp); stats->tx_packets++; stats->tx_bytes += len; u64_stats_update_end(&stats->syncp); } else { this_cpu_inc(vlan->vlan_pcpu_stats->tx_dropped); } return ret; }
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); 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; dev_queue_xmit(skb); return 0; }
static int vlan_dev_hwaccel_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct net_device_stats *stats = &dev->stats; u16 vlan_tci; vlan_tci = vlan_dev_info(dev)->vlan_id; vlan_tci |= vlan_dev_get_egress_qos_mask(dev, skb); /* Start of modified by f00120964 for qos function 2012-4-2*/ #ifdef CONFIG_DT_QOS vlan_tci |= (s_dtQosMarkto8021P[(skb->mark & 0x7)] << 13); #endif /* End of modified by f00120964 for qos function 2012-4-2*/ skb = __vlan_hwaccel_put_tag(skb, vlan_tci); stats->tx_packets++; stats->tx_bytes += skb->len; skb->dev = vlan_dev_info(dev)->real_dev; dev_queue_xmit(skb); return NETDEV_TX_OK; }
static int vlan_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct net_device_stats *stats = &dev->stats; struct vlan_ethhdr *veth = (struct vlan_ethhdr *)(skb->data); /* Handle non-VLAN frames if they are sent to us, for example by DHCP. * * NOTE: THIS ASSUMES DIX ETHERNET, SPECIFICALLY NOT SUPPORTING * OTHER THINGS LIKE FDDI/TokenRing/802.3 SNAPs... */ if (veth->h_vlan_proto != htons(ETH_P_8021Q) || vlan_dev_info(dev)->flags & VLAN_FLAG_REORDER_HDR) { unsigned int orig_headroom = skb_headroom(skb); u16 vlan_tci; vlan_dev_info(dev)->cnt_encap_on_xmit++; vlan_tci = vlan_dev_info(dev)->vlan_id; vlan_tci |= vlan_dev_get_egress_qos_mask(dev, skb); skb = __vlan_put_tag(skb, vlan_tci); if (!skb) { stats->tx_dropped++; return NETDEV_TX_OK; } if (orig_headroom < VLAN_HLEN) vlan_dev_info(dev)->cnt_inc_headroom_on_tx++; } stats->tx_packets++; stats->tx_bytes += skb->len; skb->dev = vlan_dev_info(dev)->real_dev; dev_queue_xmit(skb); return NETDEV_TX_OK; }
/* * Create the VLAN header for an arbitrary protocol layer * * saddr=NULL means use device source address * daddr=NULL means leave destination address (eg unresolved arp) * * This is called when the SKB is moving down the stack towards the * physical devices. */ int vlan_dev_hard_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, void *daddr, void *saddr, unsigned len) { struct vlan_hdr *vhdr; unsigned short veth_TCI = 0; int rc = 0; int build_vlan_header = 0; struct net_device *vdev = dev; /* save this for the bottom of the method */ #ifdef VLAN_DEBUG printk(VLAN_DBG "%s: skb: %p type: %hx len: %x vlan_id: %hx, daddr: %p\n", __FUNCTION__, skb, type, len, VLAN_DEV_INFO(dev)->vlan_id, daddr); #endif /* build vlan header only if re_order_header flag is NOT set. This * fixes some programs that get confused when they see a VLAN device * sending a frame that is VLAN encoded (the consensus is that the VLAN * device should look completely like an Ethernet device when the * REORDER_HEADER flag is set) The drawback to this is some extra * header shuffling in the hard_start_xmit. Users can turn off this * REORDER behaviour with the vconfig tool. */ build_vlan_header = ((VLAN_DEV_INFO(dev)->flags & 1) == 0); if (build_vlan_header) { vhdr = (struct vlan_hdr *) skb_push(skb, VLAN_HLEN); /* build the four bytes that make this a VLAN header. */ /* Now, 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); vhdr->h_vlan_TCI = htons(veth_TCI); /* * Set the protocol type. * For a packet of type ETH_P_802_3 we put the length in here instead. * It is up to the 802.2 layer to carry protocol information. */ if (type != ETH_P_802_3) { vhdr->h_vlan_encapsulated_proto = htons(type); } else { vhdr->h_vlan_encapsulated_proto = htons(len); } } /* Before delegating work to the lower layer, enter our MAC-address */ if (saddr == NULL) saddr = dev->dev_addr; dev = VLAN_DEV_INFO(dev)->real_dev; /* MPLS can send us skbuffs w/out enough space. This check will grow the * skb if it doesn't have enough headroom. Not a beautiful solution, so * I'll tick a counter so that users can know it's happening... If they * care... */ /* NOTE: This may still break if the underlying device is not the final * device (and thus there are more headers to add...) It should work for * good-ole-ethernet though. */ if (skb_headroom(skb) < dev->hard_header_len) { struct sk_buff *sk_tmp = skb; skb = skb_realloc_headroom(sk_tmp, dev->hard_header_len); kfree_skb(sk_tmp); if (skb == NULL) { struct net_device_stats *stats = vlan_dev_get_stats(vdev); stats->tx_dropped++; return -ENOMEM; } VLAN_DEV_INFO(vdev)->cnt_inc_headroom_on_tx++; #ifdef VLAN_DEBUG printk(VLAN_DBG "%s: %s: had to grow skb.\n", __FUNCTION__, vdev->name); #endif } if (build_vlan_header) { /* Now make the underlying real hard header */ rc = dev->hard_header(skb, dev, ETH_P_8021Q, daddr, saddr, len + VLAN_HLEN); if (rc > 0) { rc += VLAN_HLEN; } else if (rc < 0) { rc -= VLAN_HLEN; } } else { /* If here, then we'll just make a normal looking ethernet frame, * but, the hard_start_xmit method will insert the tag (it has to * be able to do this for bridged and other skbs that don't come * down the protocol stack in an orderly manner. */ rc = dev->hard_header(skb, dev, type, daddr, saddr, len); } return rc; }
static int vlan_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct net_device_stats *stats = &dev->stats; struct vlan_ethhdr *veth = (struct vlan_ethhdr *)(skb->data); /* Handle non-VLAN frames if they are sent to us, for example by DHCP. * * NOTE: THIS ASSUMES DIX ETHERNET, SPECIFICALLY NOT SUPPORTING * OTHER THINGS LIKE FDDI/TokenRing/802.3 SNAPs... */ if (veth->h_vlan_proto != htons(ETH_P_8021Q) || vlan_dev_info(dev)->flags & VLAN_FLAG_REORDER_HDR) { unsigned int orig_headroom = skb_headroom(skb); u16 vlan_tci; vlan_dev_info(dev)->cnt_encap_on_xmit++; vlan_tci = vlan_dev_info(dev)->vlan_id; vlan_tci |= vlan_dev_get_egress_qos_mask(dev, skb); /* 802.1p remark */ /*Start of modified by f00120964 for qos function 2012-1-6*/ #if defined(CONFIG_IMQ) && !defined(CONFIG_DT_QOS) /* mark -----|-----|-------|------|-------|-----|------|------ */ /* START OF Add: t00163975 2011-05-21 FOR 移植BCM Eth上行的QoS */ /* START Modify by l00184769 20110708 把原来的为hhb3写的else分支去掉,使得与通用代码一致 */ /* BCM Eth qos lan |dscp |default| wmm | |802.1p|policer|queue */ /* IMQ QOS |802.1p|queue|policer */ if (skb->mark & 0x10) { vlan_tci = ((vlan_tci & 0x1fff) | ((skb->mark & 0xe0) << 8)); } /* END Modify by l00184769 20110708 把原来的为hhb3写的else分支去掉,使得与通用代码一致 */ /* END OF Add: t00163975 2011-05-21 */ if (__constant_htons(ETH_P_PPP_SES) == skb->protocol) { /* PPP_LCP = 0xc021 802.1p mark 7 */ if ((0xc0 == skb->data[20]) && (0x21 == skb->data[21])) { vlan_tci = ((vlan_tci & 0x1fff) | (0xe000)); } } #endif #ifdef CONFIG_DT_QOS vlan_tci |= (s_dtQosMarkto8021P[(skb->mark & 0x7)] << 13); #endif /*End of modified by f00120964 for qos function 2012-1-6*/ #ifdef CONFIG_BCM96362 /* |lan |dscp |default|wmm | |802.1p|policer|queue| */ if (skb->mark & 0x100) { vlan_tci = ((vlan_tci & 0x1fff) | ((skb->mark & 0xe00) << 4)); } #endif skb = __vlan_put_tag(skb, vlan_tci); if (!skb) { stats->tx_dropped++; return NETDEV_TX_OK; } if (orig_headroom < VLAN_HLEN) vlan_dev_info(dev)->cnt_inc_headroom_on_tx++; } /* Start of add by z00202017 2011/12/28 for Internet LED */ #if defined(CONFIG_BCM963268) && defined(CONFIG_BLOG) blog_link(IF_DEVICE, blog_ptr(skb), (void*)dev, DIR_TX, skb->len ); #endif /* End of add by z00202017 2011/12/28 for Internet LED */ stats->tx_packets++; stats->tx_bytes += skb->len; skb->dev = vlan_dev_info(dev)->real_dev; dev_queue_xmit(skb); return NETDEV_TX_OK; }
int vlan_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct net_device_stats *stats = vlan_dev_get_stats(dev); struct vlan_ethhdr *veth = (struct vlan_ethhdr *)(skb->data); /* Handle non-VLAN frames if they are sent to us, for example by DHCP. * * NOTE: THIS ASSUMES DIX ETHERNET, SPECIFICALLY NOT SUPPORTING * OTHER THINGS LIKE FDDI/TokenRing/802.3 SNAPs... */ if (veth->h_vlan_proto != __constant_htons(ETH_P_8021Q)) { unsigned short veth_TCI; /* This is not a VLAN frame...but we can fix that! */ VLAN_DEV_INFO(dev)->cnt_encap_on_xmit++; #ifdef VLAN_DEBUG 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 * 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); veth->h_vlan_TCI = htons(veth_TCI); } skb->dev = VLAN_DEV_INFO(dev)->real_dev; #ifdef VLAN_DEBUG printk(VLAN_DBG "%s: about to send skb: %p to dev: %s\n", __FUNCTION__, skb, skb->dev->name); printk(VLAN_DBG " %2hx.%2hx.%2hx.%2xh.%2hx.%2hx %2hx.%2hx.%2hx.%2hx.%2hx.%2hx %4hx %4hx %4hx\n", veth->h_dest[0], veth->h_dest[1], veth->h_dest[2], veth->h_dest[3], veth->h_dest[4], veth->h_dest[5], veth->h_source[0], veth->h_source[1], veth->h_source[2], veth->h_source[3], veth->h_source[4], veth->h_source[5], 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; dev_queue_xmit(skb); return 0; }