DPDK patches and discussions
 help / color / mirror / Atom feed
From: "Liang, Cunming" <cunming.liang@intel.com>
To: Olivier MATZ <olivier.matz@6wind.com>, "dev@dpdk.org" <dev@dpdk.org>
Subject: Re: [dpdk-dev] [PATCH 05/18] mbuf: add function to get packet type from data
Date: Thu, 7 Jul 2016 08:19:59 +0000	[thread overview]
Message-ID: <D0158A423229094DA7ABF71CF2FA0DA31554517C@shsmsx102.ccr.corp.intel.com> (raw)
In-Reply-To: <12989717-cc42-9ce6-f520-0ffbd3db7a8a@6wind.com>

Hi Olivier,

> -----Original Message-----
> From: Olivier MATZ [mailto:olivier.matz@6wind.com]
> Sent: Wednesday, July 06, 2016 3:43 PM
> To: Liang, Cunming <cunming.liang@intel.com>; dev@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH 05/18] mbuf: add function to get packet type
> from data
> 
> Hi Cunming,
> 
> On 07/06/2016 08:44 AM, Liang, Cunming wrote:
> > Hi Olivier,
> >
> > On 7/5/2016 11:41 PM, Olivier Matz wrote:
> >> Introduce the function rte_pktmbuf_get_ptype() that parses a
> >> mbuf and returns its packet type. For now, the following packet
> >> types are parsed:
> >>     L2: Ether
> >>     L3: IPv4, IPv6
> >>     L4: TCP, UDP, SCTP
> >>
> >> The goal here is to provide a reference implementation for packet type
> >> parsing. This function will be used by testpmd in next commits, allowing
> >> to compare its result with the value given by the hardware.
> >>
> >> This function will also be useful when implementing Rx offload support
> >> in virtio pmd. Indeed, the virtio protocol gives the csum start and
> >> offset, but it does not give the L4 protocol nor it tells if the
> >> checksum is relevant for inner or outer. This information has to be
> >> known to properly set the ol_flags in mbuf.
> >>
> >> Signed-off-by: Didier Pallard <didier.pallard@6wind.com>
> >> Signed-off-by: Jean Dao <jean.dao@6wind.com>
> >> Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
> >> ---
> >>   doc/guides/rel_notes/release_16_11.rst |   5 +
> >>   lib/librte_mbuf/Makefile               |   5 +-
> >>   lib/librte_mbuf/rte_mbuf_ptype.c       | 234
> >> +++++++++++++++++++++++++++++++++
> >>   lib/librte_mbuf/rte_mbuf_ptype.h       |  43 ++++++
> >>   lib/librte_mbuf/rte_mbuf_version.map   |   1 +
> >>   5 files changed, 286 insertions(+), 2 deletions(-)
> >>   create mode 100644 lib/librte_mbuf/rte_mbuf_ptype.c
> >>
> >> [...]
> >> +
> >> +/* parse mbuf data to get packet type */
> >> +uint32_t rte_pktmbuf_get_ptype(const struct rte_mbuf *m,
> >> +    struct rte_mbuf_hdr_lens *hdr_lens)
> >> +{
> >> +    struct rte_mbuf_hdr_lens local_hdr_lens;
> >> +    const struct ether_hdr *eh;
> >> +    struct ether_hdr eh_copy;
> >> +    uint32_t pkt_type = RTE_PTYPE_L2_ETHER;
> >> +    uint32_t off = 0;
> >> +    uint16_t proto;
> >> +
> >> +    if (hdr_lens == NULL)
> >> +        hdr_lens = &local_hdr_lens;
> >> +
> >> +    eh = rte_pktmbuf_read(m, off, sizeof(*eh), &eh_copy);
> >> +    if (unlikely(eh == NULL))
> >> +        return 0;
> >> +    proto = eh->ether_type;
> >> +    off = sizeof(*eh);
> >> +    hdr_lens->l2_len = off;
> >> +
> >> +    if (proto == rte_cpu_to_be_16(ETHER_TYPE_IPv4)) {
> >> +        const struct ipv4_hdr *ip4h;
> >> +        struct ipv4_hdr ip4h_copy;
> >> +
> >> +        ip4h = rte_pktmbuf_read(m, off, sizeof(*ip4h), &ip4h_copy);
> >> +        if (unlikely(ip4h == NULL))
> >> +            return pkt_type;
> >> +
> >> +        pkt_type |= ptype_l3_ip(ip4h->version_ihl);
> >> +        hdr_lens->l3_len = ip4_hlen(ip4h);
> >> +        off += hdr_lens->l3_len;
> >> +        if (ip4h->fragment_offset &
> >> +                rte_cpu_to_be_16(IPV4_HDR_OFFSET_MASK |
> >> +                    IPV4_HDR_MF_FLAG)) {
> >> +            pkt_type |= RTE_PTYPE_L4_FRAG;
> >> +            hdr_lens->l4_len = 0;
> >> +            return pkt_type;
> >> +        }
> >> +        proto = ip4h->next_proto_id;
> >> +        pkt_type |= ptype_l4(proto);
> >> +    } else if (proto == rte_cpu_to_be_16(ETHER_TYPE_IPv6)) {
> >> +        const struct ipv6_hdr *ip6h;
> >> +        struct ipv6_hdr ip6h_copy;
> >> +        int frag = 0;
> >> +
> >> +        ip6h = rte_pktmbuf_read(m, off, sizeof(*ip6h), &ip6h_copy);
> >> +        if (unlikely(ip6h == NULL))
> >> +            return pkt_type;
> >> +
> >> +        proto = ip6h->proto;
> >> +        hdr_lens->l3_len = sizeof(*ip6h);
> >> +        off += hdr_lens->l3_len;
> >> +        pkt_type |= ptype_l3_ip6(proto);
> >> +        if ((pkt_type & RTE_PTYPE_L3_MASK) == RTE_PTYPE_L3_IPV6_EXT) {
> >> +            proto = skip_ip6_ext(proto, m, &off, &frag);
> >> +            hdr_lens->l3_len = off - hdr_lens->l2_len;
> >> +        }
> >> +        if (proto == 0)
> >> +            return pkt_type;
> >> +        if (frag) {
> >> +            pkt_type |= RTE_PTYPE_L4_FRAG;
> >> +            hdr_lens->l4_len = 0;
> >> +            return pkt_type;
> >> +        }
> >> +        pkt_type |= ptype_l4(proto);
> >> +    }
> >> +
> >> +    if ((pkt_type & RTE_PTYPE_L4_MASK) == RTE_PTYPE_L4_UDP) {
> >> +        hdr_lens->l4_len = sizeof(struct udp_hdr);
> >> +    } else if ((pkt_type & RTE_PTYPE_L4_MASK) == RTE_PTYPE_L4_TCP) {
> >> +        const struct tcp_hdr *th;
> >> +        struct tcp_hdr th_copy;
> >> +
> >> +        th = rte_pktmbuf_read(m, off, sizeof(*th), &th_copy);
> >> +        if (unlikely(th == NULL))
> >> +            return pkt_type & (RTE_PTYPE_L2_MASK |
> >> +                RTE_PTYPE_L3_MASK);
> >> +        hdr_lens->l4_len = (th->data_off & 0xf0) >> 2;
> >> +    } else if ((pkt_type & RTE_PTYPE_L4_MASK) == RTE_PTYPE_L4_SCTP) {
> >> +        hdr_lens->l4_len = sizeof(struct sctp_hdr);
> >> +    } else {
> >> +        hdr_lens->l4_len = 0;
> >> +    }
> >> +
> >> +    return pkt_type;
> >> +}
> >> diff --git a/lib/librte_mbuf/rte_mbuf_ptype.h
> >> b/lib/librte_mbuf/rte_mbuf_ptype.h
> >> index 4a34678..f468520 100644
> >> --- a/lib/librte_mbuf/rte_mbuf_ptype.h
> >> +++ b/lib/librte_mbuf/rte_mbuf_ptype.h
> >> @@ -545,6 +545,49 @@ extern "C" {
> >>           RTE_PTYPE_INNER_L3_MASK |                \
> >>           RTE_PTYPE_INNER_L4_MASK))
> >>   +struct rte_mbuf;
> >> +
> >> +/**
> >> + * Structure containing header lengths associated to a packet.
> >> + */
> >> +struct rte_mbuf_hdr_lens {
> >> +    uint8_t l2_len;
> >> +    uint8_t l3_len;
> >> +    uint8_t l4_len;
> >> +    uint8_t tunnel_len;
> >> +    uint8_t inner_l2_len;
> >> +    uint8_t inner_l3_len;
> >> +    uint8_t inner_l4_len;
> >> +};
> > [LC] The header parsing graph usually is not unique. The definition
> > maybe nice for the basic IP and L4 tunnel.
> > However it can't scale out to other cases, e.g. qinq, mac-in-mac, mpls
> > l2/l3 tunnel.
> > The parsing logic of "rte_pktmbuf_get_ptype()" and the definition of
> > "struct rte_mbuf_hdr_lens" consist a pair for one specific parser scheme.
> > In this case, the fixed function is to support below.
> >
> > + * Supported packet types are:
> > + *   L2: Ether
> > + *   L3: IPv4, IPv6
> > + *   L4: TCP, UDP, SCTP
> >
> > Of course, it can add more packet type detection logic in future. But
> > the more support, the higher the cost.
> >
> > One of the alternative way is to allow registering parser pair. APP
> > decides to choose the predefined scheme(by DPDK LIB), or to self-define
> > the parsing logic.
> > In this way, the scheme can do some assumption for the specific case and
> > ignore some useless graph detection.
> > In addition, besides the SW parser, the HW parser(identified by
> > packet_type in mbuf) can be turn on/off by leveraging the same manner.
> 
> 
> Sorry, I'm not sure I'm fully getting what you are saying. If I
> understand well, you would like to have something more flexible that
> supports the registration of protocol to be recognized?
[LC] Not on that granularity, but on the entire parsing routine.
rte_pktmbuf_get_ptype() as the common API, and can present in different behavior.
Usually in different scenario, the interested packet set is different.
For the specific case, can do some speculation pre-checking on the optimization perspective.

> 
> I'm not sure having a function with a dynamic registration method would
> really increase the performance compared to a static complete function.
[LC] No, it won't. But the overhead is not much, refer to rx_pkt_burst(is a callback either).
If someone only interest for IPv4-NoFrag-TCP stream, the easiest way maybe not layer by layer detection.
The straight forward way maybe, 1) load n bytes 2) compare mask 3) update ptype.
We require a normal way to do SW detection, current version is perfect.
My point is, we can provide a simple mechanism to allow other way, and under the same unified API.

> Actually, we will never support a tons of protocols since each layer
> packet type is 4 bits, and since it requires that at least one hw
> supports it.
[LC] Agree, it is today. But maybe dynamic in future, packet type definition as a template.
> 
> As described in the cover letter, the 2 main goals of this patchset are
> to provide a reference implementation for packet type recognition, and
> enable the support of virtio offloads (I'll send the patchset soon).
> This function is adapted to these 2 usages. Are you thinking of another
> use-case that would not be covered?
[LC] That's excellent work.  Furthermore I believe it can cover all ethdev actually.
When HW can't report some demand packet type, then fallback to your SW parser version.
If the auto-switch can be transparent, that's perfect. Maybe rx callback and update ptype in mbuf?

Thanks
> 
> Regards,
> Olivier

  parent reply	other threads:[~2016-07-07  8:20 UTC|newest]

Thread overview: 71+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-07-05 15:41 [dpdk-dev] [PATCH 00/18] software parser for packet type Olivier Matz
2016-07-05 15:41 ` [dpdk-dev] [PATCH 01/18] doc: add template for release notes 16.11 Olivier Matz
2016-07-06 11:48   ` Mcnamara, John
2016-07-06 12:00     ` Olivier MATZ
2016-07-05 15:41 ` [dpdk-dev] [PATCH 02/18] mbuf: add function to read packet data Olivier Matz
2016-07-05 15:41 ` [dpdk-dev] [PATCH 03/18] net: move Ethernet header definitions to the net library Olivier Matz
2016-07-05 15:41 ` [dpdk-dev] [PATCH 04/18] mbuf: move packet type definitions in a new file Olivier Matz
2016-07-05 15:41 ` [dpdk-dev] [PATCH 05/18] mbuf: add function to get packet type from data Olivier Matz
2016-07-06  6:44   ` Liang, Cunming
2016-07-06  7:42     ` Olivier MATZ
2016-07-06 11:59       ` Chilikin, Andrey
2016-07-06 12:08         ` Olivier MATZ
2016-07-06 12:21           ` Chilikin, Andrey
2016-07-07  8:19       ` Liang, Cunming [this message]
2016-07-07 15:48         ` Olivier Matz
2016-07-08 10:08           ` Liang, Cunming
2016-07-05 15:41 ` [dpdk-dev] [PATCH 06/18] mbuf: support Vlan in software packet type parser Olivier Matz
2016-07-05 15:41 ` [dpdk-dev] [PATCH 07/18] mbuf: support QinQ " Olivier Matz
2016-07-05 15:41 ` [dpdk-dev] [PATCH 08/18] net: add Mpls header structure Olivier Matz
2016-07-05 15:41 ` [dpdk-dev] [PATCH 09/18] mbuf: support Mpls in software packet type parser Olivier Matz
2016-07-06  7:08   ` Liang, Cunming
2016-07-06  8:00     ` Olivier MATZ
2016-07-07  8:48       ` Liang, Cunming
2016-07-07 16:01         ` Olivier Matz
2016-07-05 15:41 ` [dpdk-dev] [PATCH 10/18] mbuf: support Ip tunnels " Olivier Matz
2016-07-05 15:41 ` [dpdk-dev] [PATCH 11/18] net: add Gre header structure Olivier Matz
2016-07-05 15:41 ` [dpdk-dev] [PATCH 12/18] mbuf: support Gre in software packet type parser Olivier Matz
2016-07-05 15:41 ` [dpdk-dev] [PATCH 13/18] mbuf: support Nvgre " Olivier Matz
2016-07-05 15:41 ` [dpdk-dev] [PATCH 14/18] mbuf: get ptype for the first layers only Olivier Matz
2016-07-05 15:41 ` [dpdk-dev] [PATCH 15/18] mbuf: add functions to dump packet type Olivier Matz
2016-07-05 15:41 ` [dpdk-dev] [PATCH 16/18] mbuf: clarify definition of fragment packet types Olivier Matz
2016-07-05 15:41 ` [dpdk-dev] [PATCH 17/18] app/testpmd: dump ptype using the new function Olivier Matz
2016-07-05 15:41 ` [dpdk-dev] [PATCH 18/18] app/testpmd: display sw packet type Olivier Matz
2016-08-29 14:35 ` [dpdk-dev] [PATCH v2 00/16] software parser for " Olivier Matz
2016-08-29 14:35   ` [dpdk-dev] [PATCH v2 01/16] mbuf: add function to read packet data Olivier Matz
2016-08-29 14:35   ` [dpdk-dev] [PATCH v2 02/16] net: move Ethernet header definitions to the net library Olivier Matz
2016-08-29 14:35   ` [dpdk-dev] [PATCH v2 03/16] mbuf: move packet type definitions in a new file Olivier Matz
2016-08-29 14:35   ` [dpdk-dev] [PATCH v2 04/16] net: introduce net library Olivier Matz
2016-08-29 14:35   ` [dpdk-dev] [PATCH v2 05/16] net: add function to get packet type from data Olivier Matz
2016-08-29 14:35   ` [dpdk-dev] [PATCH v2 06/16] net: support Vlan in software packet type parser Olivier Matz
2016-08-29 14:35   ` [dpdk-dev] [PATCH v2 07/16] net: support QinQ " Olivier Matz
2016-08-29 14:35   ` [dpdk-dev] [PATCH v2 08/16] net: support Ip tunnels " Olivier Matz
2016-08-29 14:35   ` [dpdk-dev] [PATCH v2 09/16] net: add Gre header structure Olivier Matz
2016-08-29 14:35   ` [dpdk-dev] [PATCH v2 10/16] net: support Gre in software packet type parser Olivier Matz
2016-08-29 14:35   ` [dpdk-dev] [PATCH v2 11/16] net: support Nvgre " Olivier Matz
2016-08-29 14:35   ` [dpdk-dev] [PATCH v2 12/16] net: get ptype for the first layers only Olivier Matz
2016-08-29 14:35   ` [dpdk-dev] [PATCH v2 13/16] mbuf: add functions to dump packet type Olivier Matz
2016-08-29 14:35   ` [dpdk-dev] [PATCH v2 14/16] mbuf: clarify definition of fragment packet types Olivier Matz
2016-08-29 14:35   ` [dpdk-dev] [PATCH v2 15/16] app/testpmd: dump ptype using the new function Olivier Matz
2016-08-29 14:35   ` [dpdk-dev] [PATCH v2 16/16] app/testpmd: display software packet type Olivier Matz
2016-10-03  8:38   ` [dpdk-dev] [PATCH v3 00/16] software parser for " Olivier Matz
2016-10-03  8:38     ` [dpdk-dev] [PATCH v3 01/16] mbuf: add function to read packet data Olivier Matz
2016-10-03  8:38     ` [dpdk-dev] [PATCH v3 02/16] net: move Ethernet header definitions to the net library Olivier Matz
2016-10-03  8:38     ` [dpdk-dev] [PATCH v3 03/16] mbuf: move packet type definitions in a new file Olivier Matz
2016-10-10 14:52       ` Thomas Monjalon
2016-10-11  9:01         ` Olivier MATZ
2016-10-11 15:51           ` Thomas Monjalon
2016-10-03  8:38     ` [dpdk-dev] [PATCH v3 04/16] net: introduce net library Olivier Matz
2016-10-03  8:38     ` [dpdk-dev] [PATCH v3 05/16] net: add function to get packet type from data Olivier Matz
2016-10-03  8:38     ` [dpdk-dev] [PATCH v3 06/16] net: support Vlan in software packet type parser Olivier Matz
2016-10-03  8:38     ` [dpdk-dev] [PATCH v3 07/16] net: support QinQ " Olivier Matz
2016-10-03  8:38     ` [dpdk-dev] [PATCH v3 08/16] net: support Ip tunnels " Olivier Matz
2016-10-03  8:38     ` [dpdk-dev] [PATCH v3 09/16] net: add Gre header structure Olivier Matz
2016-10-03  8:38     ` [dpdk-dev] [PATCH v3 10/16] net: support Gre in software packet type parser Olivier Matz
2016-10-03  8:38     ` [dpdk-dev] [PATCH v3 11/16] net: support Nvgre " Olivier Matz
2016-10-03  8:38     ` [dpdk-dev] [PATCH v3 12/16] net: get ptype for the first layers only Olivier Matz
2016-10-03  8:38     ` [dpdk-dev] [PATCH v3 13/16] mbuf: add functions to dump packet type Olivier Matz
2016-10-03  8:38     ` [dpdk-dev] [PATCH v3 14/16] mbuf: clarify definition of fragment packet types Olivier Matz
2016-10-03  8:38     ` [dpdk-dev] [PATCH v3 15/16] app/testpmd: dump ptype using the new function Olivier Matz
2016-10-03  8:38     ` [dpdk-dev] [PATCH v3 16/16] app/testpmd: display software packet type Olivier Matz
2016-10-11 16:24     ` [dpdk-dev] [PATCH v3 00/16] software parser for " Thomas Monjalon

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=D0158A423229094DA7ABF71CF2FA0DA31554517C@shsmsx102.ccr.corp.intel.com \
    --to=cunming.liang@intel.com \
    --cc=dev@dpdk.org \
    --cc=olivier.matz@6wind.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).