当前位置:首页 > Linux VLAN知识总结
{
return __vlan_hwaccel_rx(skb, grp, vlan_tci, 1); } /**
* __vlan_put_tag - regular VLAN tag inserting * @skb: skbuff to tag
* @vlan_tci: VLAN TCI to insert *
* Inserts the VLAN tag into @skb as part of the payload
* Returns a VLAN tagged skb. If a new skb is created, @skb is freed. *
* Following the skb_unshare() example, in case of error, the calling function * doesn't have to worry about freeing the original skb. */
static inline struct sk_buff *__vlan_put_tag(struct sk_buff *skb, u16 vlan_tci) {
struct vlan_ethhdr *veth;
if (skb_cow_head(skb, VLAN_HLEN) < 0) { kfree_skb(skb); return NULL; }
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); skb->mac_header -= VLAN_HLEN;
/* first, the ethernet type */
veth->h_vlan_proto = htons(ETH_P_8021Q);
/* now, the TCI */
veth->h_vlan_TCI = htons(vlan_tci);
skb->protocol = htons(ETH_P_8021Q);
return skb; } /**
* __vlan_hwaccel_put_tag - hardware accelerated VLAN inserting * @skb: skbuff to tag
* @vlan_tci: VLAN TCI to insert *
* Puts the VLAN TCI in @skb->vlan_tci and lets the device do the rest */
static inline struct sk_buff *__vlan_hwaccel_put_tag(struct sk_buff *skb, u16 vlan_tci) {
skb->vlan_tci = VLAN_TAG_PRESENT | vlan_tci; return skb; }
#define HAVE_VLAN_PUT_TAG /**
* vlan_put_tag - inserts VLAN tag according to device features * @skb: skbuff to tag
* @vlan_tci: VLAN TCI to insert *
* Assumes skb->dev is the target that will xmit this frame.
* Returns a VLAN tagged skb. */
static inline struct sk_buff *vlan_put_tag(struct sk_buff *skb, u16 vlan_tci) {
if (skb->dev->features & NETIF_F_HW_VLAN_TX) { return __vlan_hwaccel_put_tag(skb, vlan_tci); } else {
return __vlan_put_tag(skb, vlan_tci); } } /**
* __vlan_get_tag - get the VLAN ID that is part of the payload * @skb: skbuff to query * @vlan_tci: buffer to store vlaue *
* Returns error if the skb is not of VLAN type */
static inline int __vlan_get_tag(const struct sk_buff *skb, u16 *vlan_tci) {
struct vlan_ethhdr *veth = (struct vlan_ethhdr *)skb->data;
if (veth->h_vlan_proto != htons(ETH_P_8021Q)) { return -EINVAL; }
*vlan_tci = ntohs(veth->h_vlan_TCI); return 0; } /**
* __vlan_hwaccel_get_tag - get the VLAN ID that is in @skb->cb[] * @skb: skbuff to query * @vlan_tci: buffer to store vlaue *
* Returns error if @skb->vlan_tci is not set correctly */
static inline int __vlan_hwaccel_get_tag(const struct sk_buff *skb, u16 *vlan_tci) {
if (vlan_tx_tag_present(skb)) { *vlan_tci = vlan_tx_tag_get(skb); return 0; } else {
*vlan_tci = 0; return -EINVAL; } }
#define HAVE_VLAN_GET_TAG /**
* vlan_get_tag - get the VLAN ID from the skb * @skb: skbuff to query * @vlan_tci: buffer to store vlaue *
* Returns error if the skb is not VLAN tagged */
static inline int vlan_get_tag(const struct sk_buff *skb, u16 *vlan_tci) {
if (skb->dev->features & NETIF_F_HW_VLAN_TX) { return __vlan_hwaccel_get_tag(skb, vlan_tci);
共分享92篇相关文档