Hi, On Mon, Oct 21, 2019 at 02:46:17PM +0530, kirankum...@marvell.com wrote: > From: Kiran Kumar K <kirankum...@marvell.com> > > Add new rte_flow_item_higig2_hdr in order to match higig2 header. > It is a layer 2.5 protocol and used in Broadcom switches. > Header format is based on the following document. > http://read.pudn.com/downloads558/doc/comm/2301468/HiGig_protocol.pdf > > Signed-off-by: Kiran Kumar K <kirankum...@marvell.com> > Acked-by: Andrew Rybchenko <arybche...@solarflare.com> > --- > V9 Changes: > * Fix gcc 4.8 compile issue > > V8 Changes: > * Fixed gcc 4.8 compile issue > > V7 changes: > * Added doxygen comments > * Moved rte_flow specific code to rte_flow.h > > V6 changes: > * Updated doxy-api > > V5 changes: > * Changed broadcom to Broadcom > * Changed RTE_HIGIG2_H to RTE_HIGIG_H > * Fixed meson build > > V4 Changes: > * Removed packed attribute > > V3 Changes: > * Fixed Copyright header > * Fixed version info in the subject > > V2 Changes: > * Added support in testpmd to parse the higig2 item > * Moved the higig2 header to new file > * Added indentation in doc > > app/test-pmd/cmdline_flow.c | 33 +++++++ > doc/api/doxy-api-index.md | 3 +- > doc/guides/prog_guide/rte_flow.rst | 8 ++ > lib/librte_ethdev/rte_flow.c | 1 + > lib/librte_ethdev/rte_flow.h | 29 ++++++ > lib/librte_net/Makefile | 2 +- > lib/librte_net/meson.build | 3 +- > lib/librte_net/rte_higig.h | 144 +++++++++++++++++++++++++++++ > 8 files changed, 220 insertions(+), 3 deletions(-) > create mode 100644 lib/librte_net/rte_higig.h > > diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c > index b26b8bfe2..970bdef1d 100644 > --- a/app/test-pmd/cmdline_flow.c > +++ b/app/test-pmd/cmdline_flow.c > @@ -203,6 +203,9 @@ enum index { > ITEM_PPPOED, > ITEM_PPPOE_SEID, > ITEM_PPPOE_PROTO_ID, > + ITEM_HIGIG2, > + ITEM_HIGIG2_CLASSIFICATION, > + ITEM_HIGIG2_VID, > > /* Validate/create actions. */ > ACTIONS, > @@ -675,6 +678,7 @@ static const enum index next_item[] = { > ITEM_PPPOES, > ITEM_PPPOED, > ITEM_PPPOE_PROTO_ID, > + ITEM_HIGIG2, > END_SET, > ZERO, > }; > @@ -939,6 +943,13 @@ static const enum index item_pppoe_proto_id[] = { > ZERO, > }; > > +static const enum index item_higig2[] = { > + ITEM_HIGIG2_CLASSIFICATION, > + ITEM_HIGIG2_VID, > + ITEM_NEXT, > + ZERO, > +}; > + > static const enum index next_action[] = { > ACTION_END, > ACTION_VOID, > @@ -2419,6 +2430,28 @@ static const struct token token_list[] = { > .next = NEXT(item_pppoe_proto_id), > .call = parse_vc, > }, > + [ITEM_HIGIG2] = { > + .name = "higig2", > + .help = "matches higig2 header", > + .priv = PRIV_ITEM(HIGIG2, > + sizeof(struct rte_flow_item_higig2_hdr)), > + .next = NEXT(item_higig2), > + .call = parse_vc, > + }, > + [ITEM_HIGIG2_CLASSIFICATION] = { > + .name = "classification", > + .help = "matches classification of higig2 header", > + .next = NEXT(item_higig2, NEXT_ENTRY(UNSIGNED), item_param), > + .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_higig2_hdr, > + hdr.ppt1.classification)), > + }, > + [ITEM_HIGIG2_VID] = { > + .name = "vid", > + .help = "matches vid of higig2 header", > + .next = NEXT(item_higig2, NEXT_ENTRY(UNSIGNED), item_param), > + .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_higig2_hdr, > + hdr.ppt1.vid)), > + }, > /* Validate/create actions. */ > [ACTIONS] = { > .name = "actions", > diff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md > index 6c2d888ee..c52b54e55 100644 > --- a/doc/api/doxy-api-index.md > +++ b/doc/api/doxy-api-index.md > @@ -101,7 +101,8 @@ The public API headers are grouped by topics: > [GSO] (@ref rte_gso.h), > [frag/reass] (@ref rte_ip_frag.h), > [LPM IPv4 route] (@ref rte_lpm.h), > - [LPM IPv6 route] (@ref rte_lpm6.h) > + [LPM IPv6 route] (@ref rte_lpm6.h), > + [HIGIG] (@ref rte_higig.h) > > - **QoS**: > [metering] (@ref rte_meter.h), > diff --git a/doc/guides/prog_guide/rte_flow.rst > b/doc/guides/prog_guide/rte_flow.rst > index 1c837ff13..6e6d44df2 100644 > --- a/doc/guides/prog_guide/rte_flow.rst > +++ b/doc/guides/prog_guide/rte_flow.rst > @@ -1289,6 +1289,14 @@ Matches a IP Authentication Header (RFC 4302). > - ``seq_num``: counter value increased by 1 on each packet sent. > - Default ``mask`` matches spi. > > +Item: ``HIGIG2`` > +^^^^^^^^^^^^^^^^^ > + > +Matches a HIGIG2 header field. It is layer 2.5 protocol and used in > +Broadcom switches. > + > +- Default ``mask`` matches classification and vlan. > + > > Actions > ~~~~~~~ > diff --git a/lib/librte_ethdev/rte_flow.c b/lib/librte_ethdev/rte_flow.c > index 81a85b995..ca0f68016 100644 > --- a/lib/librte_ethdev/rte_flow.c > +++ b/lib/librte_ethdev/rte_flow.c > @@ -83,6 +83,7 @@ static const struct rte_flow_desc_data rte_flow_desc_item[] > = { > MK_FLOW_ITEM(NSH, sizeof(struct rte_flow_item_nsh)), > MK_FLOW_ITEM(IGMP, sizeof(struct rte_flow_item_igmp)), > MK_FLOW_ITEM(AH, sizeof(struct rte_flow_item_ah)), > + MK_FLOW_ITEM(HIGIG2, sizeof(struct rte_flow_item_higig2_hdr)), > }; > > /** Generate flow_action[] entry. */ > diff --git a/lib/librte_ethdev/rte_flow.h b/lib/librte_ethdev/rte_flow.h > index bcfc06cdc..4fee10559 100644 > --- a/lib/librte_ethdev/rte_flow.h > +++ b/lib/librte_ethdev/rte_flow.h > @@ -27,6 +27,7 @@ > #include <rte_udp.h> > #include <rte_byteorder.h> > #include <rte_esp.h> > +#include <rte_higig.h> > > #ifdef __cplusplus > extern "C" { > @@ -491,8 +492,36 @@ enum rte_flow_item_type { > * > */ > RTE_FLOW_ITEM_TYPE_AH, > + > + /** > + * Matches a HIGIG header. > + * see struct rte_flow_item_higig2_hdr. > + */ > + RTE_FLOW_ITEM_TYPE_HIGIG2, > }; > > +/** > + * > + * RTE_FLOW_ITEM_TYPE_HIGIG2 > + * Matches higig2 header > + */ > +RTE_STD_C11 > +struct rte_flow_item_higig2_hdr { > + struct rte_higig2_hdr hdr; > +}; > + > +/** Default mask for RTE_FLOW_ITEM_TYPE_HIGIG2. */ > +#ifndef __cplusplus > +static const struct rte_flow_item_higig2_hdr rte_flow_item_higig2_hdr_mask = > { > + .hdr = { > + .ppt1 = { > + .classification = 0xffff, > + .vid = 0xfff, > + }, > + }, > +}; > +#endif > + > /** > * RTE_FLOW_ITEM_TYPE_ANY > * > diff --git a/lib/librte_net/Makefile b/lib/librte_net/Makefile > index 1244c9fd5..62735a5f9 100644 > --- a/lib/librte_net/Makefile > +++ b/lib/librte_net/Makefile > @@ -21,6 +21,6 @@ SRCS-$(CONFIG_RTE_LIBRTE_NET) += rte_arp.c > SYMLINK-$(CONFIG_RTE_LIBRTE_NET)-include := rte_ip.h rte_tcp.h rte_udp.h > rte_esp.h > SYMLINK-$(CONFIG_RTE_LIBRTE_NET)-include += rte_sctp.h rte_icmp.h rte_arp.h > SYMLINK-$(CONFIG_RTE_LIBRTE_NET)-include += rte_ether.h rte_gre.h rte_net.h > -SYMLINK-$(CONFIG_RTE_LIBRTE_NET)-include += rte_net_crc.h rte_mpls.h > +SYMLINK-$(CONFIG_RTE_LIBRTE_NET)-include += rte_net_crc.h rte_mpls.h > rte_higig.h > > include $(RTE_SDK)/mk/rte.lib.mk > diff --git a/lib/librte_net/meson.build b/lib/librte_net/meson.build > index 868a93fd6..c52c34592 100644 > --- a/lib/librte_net/meson.build > +++ b/lib/librte_net/meson.build > @@ -14,7 +14,8 @@ headers = files('rte_ip.h', > 'rte_gre.h', > 'rte_net.h', > 'rte_net_crc.h', > - 'rte_mpls.h') > + 'rte_mpls.h', > + 'rte_higig.h') > > sources = files('rte_arp.c', 'rte_ether.c', 'rte_net.c', 'rte_net_crc.c') > deps += ['mbuf'] > diff --git a/lib/librte_net/rte_higig.h b/lib/librte_net/rte_higig.h > new file mode 100644 > index 000000000..4847448df > --- /dev/null > +++ b/lib/librte_net/rte_higig.h > @@ -0,0 +1,144 @@ > + > +/* SPDX-License-Identifier: BSD-3-Clause > + * Copyright(C) 2019 Marvell International Ltd. > + */ > + > +#ifndef _RTE_HIGIG_H_ > +#define _RTE_HIGIG_H_ > + > +#include <stdint.h> > +#include <rte_byteorder.h> > + > +#ifdef __cplusplus > +extern "C" { > +#endif > + > +/** > + * > + * higig2 frc header. > + */ > +struct rte_higig2_frc { > +#if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN > + uint32_t ksop:8; > + uint32_t tc:4; > + uint32_t mcst:1; > + uint32_t resv:3; > + uint32_t dst_modid:8; > + uint32_t dst_pid:8; > + uint32_t src_modid:8; > + uint32_t src_pid:8; > + uint32_t lbid:8; > + uint32_t ppd_type:3; > + uint32_t resv1:3; > + uint32_t dp:2; > +#elif RTE_BYTE_ORDER == RTE_BIG_ENDIAN > + uint32_t ksop:8; > + uint32_t resv:3; > + uint32_t mcst:1; > + uint32_t tc:4; > + uint32_t dst_modid:8; > + uint32_t dst_pid:8; > + uint32_t src_modid:8; > + uint32_t src_pid:8; > + uint32_t lbid:8; > + uint32_t dp:2; > + uint32_t resv1:3; > + uint32_t ppd_type:3; > +#endif > +}; > + > + > +/** > + * > + * higig2 ppt type0 header > + */ > +struct rte_higig2_ppt_type0 { > +#if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN > + uint32_t mirror:1; > + uint32_t mirror_done:1; > + uint32_t mirror_only:1; > + uint32_t ingress_tagged:1; > + uint32_t dst_tgid:3; > + uint32_t dst_t:1; > + uint32_t vc_label2:4; > + uint32_t label_present:1; > + uint32_t l3:1; > + uint32_t res:2; > + uint32_t vc_label1:8; > + uint32_t vc_label0:8; > + uint32_t vid_high:8; > + uint32_t vid_low:8; > + uint32_t opc:3; > + uint32_t res1:2; > + uint32_t srce_t:1; > + uint32_t pf:2; > + uint32_t res2:5; > + uint32_t hdr_ext_length:3; > +#elif RTE_BYTE_ORDER == RTE_BIG_ENDIAN > + uint32_t dst_t:1; > + uint32_t dst_tgid:3; > + uint32_t ingress_tagged:1; > + uint32_t mirror_only:1; > + uint32_t mirror_done:1; > + uint32_t mirror:1; > + uint32_t res:2; > + uint32_t l3:1; > + uint32_t label_present:1; > + uint32_t vc_label2:4; > + uint32_t vc_label1:8; > + uint32_t vc_label0:8; > + uint32_t vid_high:8; > + uint32_t vid_low:8; > + uint32_t pf:2; > + uint32_t srce_t:1; > + uint32_t res1:2; > + uint32_t opc:3; > + uint32_t hdr_ext_length:3; > + uint32_t res2:5; > +#endif > +}; > + > + > +/** > + * > + * higig2 ppt type1 header. > + */ > +struct rte_higig2_ppt_type1 { > + uint16_t classification; > + uint16_t resv; > + uint16_t vid; > +#if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN > + uint32_t opcode:3; > + uint32_t resv1:2; > + uint32_t src_t:1; > + uint32_t pfm:2; > + uint32_t resv2:5; > + uint32_t hdr_ext_len:3; > +#elif RTE_BYTE_ORDER == RTE_BIG_ENDIAN > + uint32_t pfm:2; > + uint32_t src_t:1; > + uint32_t resv1:2; > + uint32_t opcode:3; > + uint32_t hdr_ext_len:3; > + uint32_t resv2:5; > +#endif > +};
I don't know this protocol, but the output of pahole for this struct (little endian version) is: struct rte_higig2_ppt_type1 { uint16_t classification; /* 0 2 */ uint16_t resv; /* 2 2 */ uint16_t vid; /* 4 2 */ /* Bitfield combined with previous fields */ uint32_t opcode:3; /* 4:13 4 */ uint32_t resv1:2; /* 4:11 4 */ uint32_t src_t:1; /* 4:10 4 */ uint32_t pfm:2; /* 4: 8 4 */ uint32_t resv2:5; /* 4: 3 4 */ uint32_t hdr_ext_len:3; /* 4: 0 4 */ /* size: 8, cachelines: 1, members: 9 */ /* bit_padding: 16 bits */ /* last cacheline: 8 bytes */ }; There is a 16 bits padding at the end, is it expected? Apart from this comment: Acked-by: Olivier Matz <olivier.m...@6wind.com>