From patchwork Tue Aug 26 02:07:51 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stephen Hemminger X-Patchwork-Id: 213 Return-Path: Received: from mail-pd0-f178.google.com (mail-pd0-f178.google.com [209.85.192.178]) by dpdk.org (Postfix) with ESMTP id 347A86A98 for ; Tue, 26 Aug 2014 04:04:51 +0200 (CEST) Received: by mail-pd0-f178.google.com with SMTP id w10so21589528pde.37 for ; Mon, 25 Aug 2014 19:08:48 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:message-id:user-agent:date:from:to:cc:subject :references:mime-version:content-type:content-disposition; bh=3Vx5fvsdzhkeWuP7mj33zltxn6wcvC1nZJsHjWmmGQI=; b=e6AaBDX95Pn21DH0wp3BigSOLVjK3QWzd1yvOqwVXJPC4VA3AR3P0o1ZqX7ZoABlf9 qNeBYUQ0UL2fq7nvy3VGTMkdVa7j+NDIPwZGmIijaVbUag6Qj9PeEorOnnwCWvMtYnVR E7hVd0JYS7fb4+hqYO+C/KrGbY417/7QarKMVouAKzPA6u2GbuBS+0h0d9gs0q+fSrML H3eEmAztqu4hTxyoBrVhTCdWiD0o7z5xKTuu23oVSTS9g90a5atsd9czzvyqfHE+XsfC PeO+xOA8PZmmpaMAAKLMYVBNuHVfKzw8BuYtZKdjowrgaZaRjC1hSejv3pKT4/jeHR/m f5tQ== X-Gm-Message-State: ALoCoQlgXBAI7d1fBxsgW5qEng+UrHeOTN5bLYoyY1ZFrfFq4kNK/UD666fPUaZ5BJFQ6OujfOEX X-Received: by 10.66.182.130 with SMTP id ee2mr32416852pac.48.1409018928338; Mon, 25 Aug 2014 19:08:48 -0700 (PDT) Received: from localhost (static-50-53-65-80.bvtn.or.frontiernet.net. [50.53.65.80]) by mx.google.com with ESMTPSA id gz1sm1136963pbd.74.2014.08.25.19.08.46 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 25 Aug 2014 19:08:47 -0700 (PDT) Message-Id: <20140826020845.804064642@networkplumber.org> User-Agent: quilt/0.63-1 Date: Mon, 25 Aug 2014 19:07:51 -0700 From: Stephen Hemminger To: Ouyang Changchun References: <20140826020746.062748014@networkplumber.org> MIME-Version: 1.0 Content-Disposition: inline; filename=vlan-encap-decap.patch Cc: dev@dpdk.org Subject: [dpdk-dev] [RFC 05/10] ether: add soft vlan encap/decap functions X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 26 Aug 2014 02:04:52 -0000 It is helpful to allow device drivers that don't support hardware VLAN stripping to emulate this in software. Signed-off-by: Stephen Hemminger --- lib/librte_ether/rte_ether.h | 69 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) --- a/lib/librte_ether/rte_ether.h 2014-08-25 19:00:06.978533976 -0700 +++ b/lib/librte_ether/rte_ether.h 2014-08-25 19:00:06.978533976 -0700 @@ -48,6 +48,8 @@ extern "C" { #include #include +#include +#include #define ETHER_ADDR_LEN 6 /**< Length of Ethernet address. */ #define ETHER_TYPE_LEN 2 /**< Length of Ethernet type field. */ @@ -294,6 +296,73 @@ struct vlan_hdr { #define ETHER_TYPE_VLAN 0x8100 /**< IEEE 802.1Q VLAN tagging. */ #define ETHER_TYPE_1588 0x88F7 /**< IEEE 802.1AS 1588 Precise Time Protocol. */ +/** + * Extract VLAN tag information into mbuf + * + * Software version of VLAN stripping + * + * @param m + * The packet mbuf. + * @return + * - 0: Success + * - 1: not a vlan packet + */ +static inline int rte_vlan_strip(struct rte_mbuf *m) +{ + struct ether_hdr *eh + = rte_pktmbuf_mtod(m, struct ether_hdr *); + + if (eh->ether_type != ETHER_TYPE_VLAN) + return -1; + + struct vlan_hdr *vh = (struct vlan_hdr *)(eh + 1); + m->ol_flags |= PKT_RX_VLAN_PKT; + m->pkt.vlan_macip.f.vlan_tci = rte_be_to_cpu_16(vh->vlan_tci); + + /* Copy ether header over rather than moving whole packet */ + memmove(rte_pktmbuf_adj(m, sizeof(struct vlan_hdr)), + eh, 2 * ETHER_ADDR_LEN); + + return 0; +} + +/** + * Insert VLAN tag into mbuf. + * + * Software version of VLAN unstripping + * + * @param m + * The packet mbuf. + * @return + * - 0: On success + * -EPERM: mbuf is is shared overwriting would be unsafe + * -ENOSPC: not enough headroom in mbuf + */ +static inline int rte_vlan_insert(struct rte_mbuf *m) +{ + struct ether_hdr *oh, *nh; + struct vlan_hdr *vh; + +#ifdef RTE_MBUF_SCATTER_GATHER + /* Can't insert header if mbuf is shared */ + if (rte_mbuf_refcnt_read(m) > 1) + return -EINVAL; +#endif + oh = rte_pktmbuf_mtod(m, struct ether_hdr *); + nh = (struct ether_hdr *) + rte_pktmbuf_prepend(m, sizeof(struct vlan_hdr)); + if (nh == NULL) + return -ENOSPC; + + memmove(nh, oh, 2 * ETHER_ADDR_LEN); + nh->ether_type = ETHER_TYPE_VLAN; + + vh = (struct vlan_hdr *) (nh + 1); + vh->vlan_tci = rte_cpu_to_be_16(m->pkt.vlan_macip.f.vlan_tci); + + return 0; +} + #ifdef __cplusplus } #endif