This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "".
The branch, master has been updated via f0f83828a483f90edcf320ec2cf0107cb1e9362e (commit) via 446476b61b1b747cd1e78bcbc2ce8a8a1949a41b (commit) via e47683d428084f9cacf72f1691d30b96c53804c1 (commit) via ce35815639996bb2832c298c7d5d40eff6c175d0 (commit) via 66e459c9f841932818acd423ddeda65f2ad1c2de (commit) via 0b63c8154a779ba20010bcd9ae7ee6bf610d755b (commit) via e7117fb0ecc8440dd1b8ef5845b14c82cd2f2ace (commit) via 95eb732efd42e889e280120f504c4c3e50348cab (commit) from e30d10a42db4083b53c5a85ee91d3bcda1bb80db (commit)
Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below.
- Log ----------------------------------------------------------------- commit f0f83828a483f90edcf320ec2cf0107cb1e9362e Author: Petri Savolainen petri.savolainen@nokia.com Date: Mon Oct 21 16:55:28 2019 +0300
linux-gen: cls: fix vlan match bugs and tests
Vlan_id_0, vlan_id_x and ethtype_x implementation required packets to be VLAN qinq, while those could be also single VLAN packets. Vlan_id_x matched always against outter VLAN, while it should match against the inner most VLAN.
PMR test code generated always VLAN qinq packets, also when not needed. Ethtype_x test did set wrong inner most ethernet type. Corrected mask sizes in VLAN and ethtype_x tests (0xfff for VLAN ID, 0xffff for ethernet type). Removed erroneous comments about packet length.
Signed-off-by: Petri Savolainen petri.savolainen@nokia.com Reviewed-by: Matias Elo matias.elo@nokia.com
diff --git a/platform/linux-generic/odp_classification.c b/platform/linux-generic/odp_classification.c index 93e086e84..907d68481 100644 --- a/platform/linux-generic/odp_classification.c +++ b/platform/linux-generic/odp_classification.c @@ -942,7 +942,7 @@ static inline int verify_pmr_vlan_id_0(const uint8_t *pkt_addr, uint16_t tci; uint16_t vlan_id;
- if (!pkt_hdr->p.input_flags.vlan_qinq) + if (!packet_hdr_has_eth(pkt_hdr) || !pkt_hdr->p.input_flags.vlan) return 0;
eth = (const _odp_ethhdr_t *)(pkt_addr + pkt_hdr->p.l2_offset); @@ -956,21 +956,24 @@ static inline int verify_pmr_vlan_id_0(const uint8_t *pkt_addr, return 0; }
-static inline int verify_pmr_vlan_id_x(const uint8_t *pkt_addr ODP_UNUSED, - odp_packet_hdr_t *pkt_hdr ODP_UNUSED, - pmr_term_value_t *term_value ODP_UNUSED) +static inline int verify_pmr_vlan_id_x(const uint8_t *pkt_addr, + odp_packet_hdr_t *pkt_hdr, + pmr_term_value_t *term_value) { const _odp_ethhdr_t *eth; const _odp_vlanhdr_t *vlan; uint16_t tci; uint16_t vlan_id;
- if (!pkt_hdr->p.input_flags.vlan_qinq) + if (!pkt_hdr->p.input_flags.vlan && !pkt_hdr->p.input_flags.vlan_qinq) return 0;
eth = (const _odp_ethhdr_t *)(pkt_addr + pkt_hdr->p.l2_offset); vlan = (const _odp_vlanhdr_t *)(eth + 1); - vlan++; + + if (pkt_hdr->p.input_flags.vlan_qinq) + vlan++; + tci = odp_be_to_cpu_16(vlan->tci); vlan_id = tci & 0x0fff;
@@ -1061,11 +1064,15 @@ static inline int verify_pmr_eth_type_x(const uint8_t *pkt_addr, uint16_t ethtype; const _odp_vlanhdr_t *vlan;
- if (!pkt_hdr->p.input_flags.vlan_qinq) + if (!pkt_hdr->p.input_flags.vlan && !pkt_hdr->p.input_flags.vlan_qinq) return 0;
eth = (const _odp_ethhdr_t *)(pkt_addr + pkt_hdr->p.l2_offset); vlan = (const _odp_vlanhdr_t *)(eth + 1); + + if (pkt_hdr->p.input_flags.vlan_qinq) + vlan++; + ethtype = odp_be_to_cpu_16(vlan->type);
if (term_value->match.value == (ethtype & term_value->match.mask)) diff --git a/test/validation/api/classification/odp_classification_test_pmr.c b/test/validation/api/classification/odp_classification_test_pmr.c index c8cf0077d..a01c0a403 100644 --- a/test/validation/api/classification/odp_classification_test_pmr.c +++ b/test/validation/api/classification/odp_classification_test_pmr.c @@ -1059,8 +1059,8 @@ static void classification_test_pmr_term_vlan_id_0(void) odph_vlanhdr_t *vlan_0; cls_packet_info_t pkt_info;
- val = 1024; - mask = 0xff00; + val = 0x123; + mask = 0xfff; seqno = 0;
pktio = create_pktio(ODP_QUEUE_TYPE_SCHED, pkt_pool, true); @@ -1095,10 +1095,8 @@ static void classification_test_pmr_term_vlan_id_0(void) pmr = odp_cls_pmr_create(&pmr_param, 1, default_cos, cos); CU_ASSERT(pmr != ODP_PMR_INVALID);
- /* create packet of payload length 1024 */ pkt_info = default_pkt_info; pkt_info.vlan = true; - pkt_info.vlan_qinq = true; pkt = create_packet(pkt_info); CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); seqno = cls_pkt_get_seq(pkt); @@ -1107,7 +1105,7 @@ static void classification_test_pmr_term_vlan_id_0(void) odp_pktio_mac_addr(pktio, eth->src.addr, ODPH_ETHADDR_LEN); odp_pktio_mac_addr(pktio, eth->dst.addr, ODPH_ETHADDR_LEN); vlan_0 = (odph_vlanhdr_t *)(eth + 1); - vlan_0->tci = odp_cpu_to_be_16(1024); + vlan_0->tci = odp_cpu_to_be_16(val); enqueue_pktio_interface(pkt, pktio);
pkt = receive_packet(&retqueue, ODP_TIME_SEC_IN_NS); @@ -1172,8 +1170,8 @@ static void classification_test_pmr_term_vlan_id_x(void) odph_vlanhdr_t *vlan_x; cls_packet_info_t pkt_info;
- val = 1024; - mask = 0xff00; + val = 0x345; + mask = 0xfff; seqno = 0;
pktio = create_pktio(ODP_QUEUE_TYPE_SCHED, pkt_pool, true); @@ -1208,7 +1206,6 @@ static void classification_test_pmr_term_vlan_id_x(void) pmr = odp_cls_pmr_create(&pmr_param, 1, default_cos, cos); CU_ASSERT(pmr != ODP_PMR_INVALID);
- /* create packet of payload length 1024 */ pkt_info = default_pkt_info; pkt_info.vlan = true; pkt_info.vlan_qinq = true; @@ -1221,7 +1218,7 @@ static void classification_test_pmr_term_vlan_id_x(void) odp_pktio_mac_addr(pktio, eth->dst.addr, ODPH_ETHADDR_LEN); vlan_x = (odph_vlanhdr_t *)(eth + 1); vlan_x++; - vlan_x->tci = odp_cpu_to_be_16(1024); + vlan_x->tci = odp_cpu_to_be_16(val); enqueue_pktio_interface(pkt, pktio);
pkt = receive_packet(&retqueue, ODP_TIME_SEC_IN_NS); @@ -1394,8 +1391,8 @@ static void classification_test_pmr_term_eth_type_x(void) odph_vlanhdr_t *vlan_x; cls_packet_info_t pkt_info;
- val = 0x8100; - mask = 0xff00; + val = 0x0800; + mask = 0xffff; seqno = 0;
pktio = create_pktio(ODP_QUEUE_TYPE_SCHED, pkt_pool, true); @@ -1430,7 +1427,6 @@ static void classification_test_pmr_term_eth_type_x(void) pmr = odp_cls_pmr_create(&pmr_param, 1, default_cos, cos); CU_ASSERT(pmr != ODP_PMR_INVALID);
- /* create packet of payload length 1024 */ pkt_info = default_pkt_info; pkt_info.vlan = true; pkt_info.vlan_qinq = true; @@ -1442,7 +1438,10 @@ static void classification_test_pmr_term_eth_type_x(void) odp_pktio_mac_addr(pktio, eth->src.addr, ODPH_ETHADDR_LEN); odp_pktio_mac_addr(pktio, eth->dst.addr, ODPH_ETHADDR_LEN); vlan_x = (odph_vlanhdr_t *)(eth + 1); - vlan_x->tci = odp_cpu_to_be_16(1024); + vlan_x++; + vlan_x->tci = odp_cpu_to_be_16(0x123); + vlan_x->type = odp_cpu_to_be_16(val); + enqueue_pktio_interface(pkt, pktio);
pkt = receive_packet(&retqueue, ODP_TIME_SEC_IN_NS);
commit 446476b61b1b747cd1e78bcbc2ce8a8a1949a41b Author: Petri Savolainen petri.savolainen@nokia.com Date: Mon Oct 21 14:32:51 2019 +0300
linux-gen: dpdk: check supported ptypes in L2 parse
DPDK ethernet devices do not support all ptype flags, but usually only a subset (e.g. i40e does not support RTE_PTYPE_L2_ETHER_VLAN by default). Save supported ptypes of L2 and trust only those types that are supported.
Signed-off-by: Petri Savolainen petri.savolainen@nokia.com Reviewed-by: Matias Elo matias.elo@nokia.com
diff --git a/platform/linux-generic/include/odp_packet_dpdk.h b/platform/linux-generic/include/odp_packet_dpdk.h index 1b660babf..2b6b859c4 100644 --- a/platform/linux-generic/include/odp_packet_dpdk.h +++ b/platform/linux-generic/include/odp_packet_dpdk.h @@ -16,6 +16,15 @@
struct rte_mbuf;
+/* Flags for pkt_dpdk_t.supported_ptypes */ +#define PTYPE_VLAN 0x01 +#define PTYPE_VLAN_QINQ 0x02 +#define PTYPE_ARP 0x04 +#define PTYPE_IPV4 0x08 +#define PTYPE_IPV6 0x10 +#define PTYPE_UDP 0x20 +#define PTYPE_TCP 0x40 + /** * Calculate size of zero-copy DPDK packet pool object */ @@ -33,11 +42,13 @@ int _odp_dpdk_packet_parse_common(packet_parser_t *pkt_hdr, uint32_t seg_len, struct rte_mbuf *mbuf, int layer, + uint32_t supported_ptypes, odp_pktin_config_opt_t pktin_cfg);
static inline int _odp_dpdk_packet_parse_layer(odp_packet_hdr_t *pkt_hdr, struct rte_mbuf *mbuf, odp_pktio_parser_layer_t layer, + uint32_t supported_ptypes, odp_pktin_config_opt_t pktin_cfg) { uint32_t seg_len = pkt_hdr->buf_hdr.seg[0].len; @@ -45,6 +56,7 @@ static inline int _odp_dpdk_packet_parse_layer(odp_packet_hdr_t *pkt_hdr,
return _odp_dpdk_packet_parse_common(&pkt_hdr->p, base, pkt_hdr->frame_len, seg_len, mbuf, - layer, pktin_cfg); + layer, supported_ptypes, + pktin_cfg); } #endif diff --git a/platform/linux-generic/pktio/dpdk.c b/platform/linux-generic/pktio/dpdk.c index 593f02813..c38747d3c 100644 --- a/platform/linux-generic/pktio/dpdk.c +++ b/platform/linux-generic/pktio/dpdk.c @@ -113,6 +113,8 @@ typedef struct ODP_ALIGNED_CACHE { uint32_t data_room; /**< maximum packet length */ unsigned int min_rx_burst; /**< minimum RX burst size */ odp_pktin_hash_proto_t hash; /**< Packet input hash protocol */ + /* Supported RTE_PTYPE_XXX flags in a mask */ + uint32_t supported_ptypes; uint16_t mtu; /**< maximum transmission unit */ uint16_t port_id; /**< DPDK port identifier */ /** Use system call to get/set vdev promisc mode */ @@ -533,15 +535,16 @@ static inline int mbuf_to_pkt(pktio_entry_t *pktio_entry, struct rte_mbuf *mbuf; void *data; int i, j; - int nb_pkts = 0; int alloc_len, num; - odp_pool_t pool = pkt_priv(pktio_entry)->pool; + int nb_pkts = 0; + pkt_dpdk_t *pkt_dpdk = pkt_priv(pktio_entry); + odp_pool_t pool = pkt_dpdk->pool; odp_pktin_config_opt_t pktin_cfg = pktio_entry->s.config.pktin; odp_proto_layer_t parse_layer = pktio_entry->s.config.parser.layer; odp_pktio_t input = pktio_entry->s.handle;
/* Allocate maximum sized packets */ - alloc_len = pkt_priv(pktio_entry)->data_room; + alloc_len = pkt_dpdk->data_room;
num = packet_alloc_multi(pool, alloc_len, pkt_table, mbuf_num); if (num != mbuf_num) { @@ -566,12 +569,15 @@ static inline int mbuf_to_pkt(pktio_entry_t *pktio_entry, pkt_len = rte_pktmbuf_pkt_len(mbuf);
if (pktio_cls_enabled(pktio_entry)) { + uint32_t supported_ptypes = pkt_dpdk->supported_ptypes; + packet_parse_reset(&parsed_hdr); packet_set_len(&parsed_hdr, pkt_len); if (_odp_dpdk_packet_parse_common(&parsed_hdr.p, data, pkt_len, pkt_len, mbuf, ODP_PROTO_LAYER_ALL, + supported_ptypes, pktin_cfg)) { odp_packet_free(pkt_table[i]); rte_pktmbuf_free(mbuf); @@ -593,16 +599,20 @@ static inline int mbuf_to_pkt(pktio_entry_t *pktio_entry,
pkt_hdr->input = input;
- if (pktio_cls_enabled(pktio_entry)) + if (pktio_cls_enabled(pktio_entry)) { copy_packet_cls_metadata(&parsed_hdr, pkt_hdr); - else if (parse_layer != ODP_PROTO_LAYER_NONE) + } else if (parse_layer != ODP_PROTO_LAYER_NONE) { + uint32_t supported_ptypes = pkt_dpdk->supported_ptypes; + if (_odp_dpdk_packet_parse_layer(pkt_hdr, mbuf, parse_layer, + supported_ptypes, pktin_cfg)) { odp_packet_free(pkt); rte_pktmbuf_free(mbuf); continue; } + }
if (mbuf->ol_flags & PKT_RX_RSS_HASH) packet_set_flow_hash(pkt_hdr, mbuf->hash.rss); @@ -808,11 +818,13 @@ static inline int mbuf_to_pkt_zero(pktio_entry_t *pktio_entry, odp_pktin_config_opt_t pktin_cfg; odp_proto_layer_t parse_layer; odp_pktio_t input; + pkt_dpdk_t *pkt_dpdk;
prefetch_pkt(mbuf_table[0]);
+ pkt_dpdk = pkt_priv(pktio_entry); nb_pkts = 0; - pool = pkt_priv(pktio_entry)->pool; + pool = pkt_dpdk->pool; pktin_cfg = pktio_entry->s.config.pktin; parse_layer = pktio_entry->s.config.parser.layer; input = pktio_entry->s.handle; @@ -839,12 +851,15 @@ static inline int mbuf_to_pkt_zero(pktio_entry_t *pktio_entry, pkt_hdr = pkt_hdr_from_mbuf(mbuf);
if (pktio_cls_enabled(pktio_entry)) { + uint32_t supported_ptypes = pkt_dpdk->supported_ptypes; + packet_parse_reset(&parsed_hdr); packet_set_len(&parsed_hdr, pkt_len); if (_odp_dpdk_packet_parse_common(&parsed_hdr.p, data, pkt_len, pkt_len, mbuf, ODP_PROTO_LAYER_ALL, + supported_ptypes, pktin_cfg)) { rte_pktmbuf_free(mbuf); continue; @@ -866,15 +881,19 @@ static inline int mbuf_to_pkt_zero(pktio_entry_t *pktio_entry, packet_init(pkt_hdr, pkt_len); pkt_hdr->input = input;
- if (pktio_cls_enabled(pktio_entry)) + if (pktio_cls_enabled(pktio_entry)) { copy_packet_cls_metadata(&parsed_hdr, pkt_hdr); - else if (parse_layer != ODP_PROTO_LAYER_NONE) + } else if (parse_layer != ODP_PROTO_LAYER_NONE) { + uint32_t supported_ptypes = pkt_dpdk->supported_ptypes; + if (_odp_dpdk_packet_parse_layer(pkt_hdr, mbuf, parse_layer, + supported_ptypes, pktin_cfg)) { rte_pktmbuf_free(mbuf); continue; } + }
if (mbuf->ol_flags & PKT_RX_RSS_HASH) packet_set_flow_hash(pkt_hdr, mbuf->hash.rss); @@ -1696,6 +1715,49 @@ static int dpdk_setup_eth_rx(const pktio_entry_t *pktio_entry, return 0; }
+static void dpdk_ptype_support_set(pktio_entry_t *pktio_entry, uint16_t port_id) +{ + int max_num, num, i; + pkt_dpdk_t *pkt_dpdk = pkt_priv(pktio_entry); + uint32_t mask = RTE_PTYPE_L2_MASK | RTE_PTYPE_L3_MASK | + RTE_PTYPE_L4_MASK; + + pkt_dpdk->supported_ptypes = 0; + + max_num = rte_eth_dev_get_supported_ptypes(port_id, mask, NULL, 0); + if (max_num <= 0) { + ODP_ERR("Device does not support any ptype flags\n"); + return; + } + + uint32_t ptype[max_num]; + + num = rte_eth_dev_get_supported_ptypes(port_id, mask, ptype, max_num); + if (num <= 0) { + ODP_ERR("Device does not support any ptype flags\n"); + return; + } + + for (i = 0; i < num; i++) { + ODP_DBG(" supported ptype: 0x%x\n", ptype[i]); + + if (ptype[i] == RTE_PTYPE_L2_ETHER_VLAN) + pkt_dpdk->supported_ptypes |= PTYPE_VLAN; + else if (ptype[i] == RTE_PTYPE_L2_ETHER_QINQ) + pkt_dpdk->supported_ptypes |= PTYPE_VLAN_QINQ; + else if (ptype[i] == RTE_PTYPE_L2_ETHER_ARP) + pkt_dpdk->supported_ptypes |= PTYPE_ARP; + else if (RTE_ETH_IS_IPV4_HDR(ptype[i])) + pkt_dpdk->supported_ptypes |= PTYPE_IPV4; + else if (RTE_ETH_IS_IPV6_HDR(ptype[i])) + pkt_dpdk->supported_ptypes |= PTYPE_IPV6; + else if (ptype[i] == RTE_PTYPE_L4_UDP) + pkt_dpdk->supported_ptypes |= PTYPE_UDP; + else if (ptype[i] == RTE_PTYPE_L4_TCP) + pkt_dpdk->supported_ptypes |= PTYPE_TCP; + } +} + static int dpdk_start(pktio_entry_t *pktio_entry) { struct rte_eth_dev_info dev_info; @@ -1733,6 +1795,9 @@ static int dpdk_start(pktio_entry_t *pktio_entry) return -1; }
+ /* Record supported parser ptype flags */ + dpdk_ptype_support_set(pktio_entry, port_id); + return 0; }
diff --git a/platform/linux-generic/pktio/dpdk_parse.c b/platform/linux-generic/pktio/dpdk_parse.c index ef3065df7..9dad1a7ae 100644 --- a/platform/linux-generic/pktio/dpdk_parse.c +++ b/platform/linux-generic/pktio/dpdk_parse.c @@ -27,14 +27,18 @@ static inline uint16_t dpdk_parse_eth(packet_parser_t *prs, const uint8_t **parseptr, uint32_t *offset, uint32_t frame_len, - uint32_t mbuf_packet_type) + uint32_t mbuf_packet_type, + uint32_t supported_ptypes) { uint16_t ethtype; const _odp_ethhdr_t *eth; uint16_t macaddr0, macaddr2, macaddr4; const _odp_vlanhdr_t *vlan; _odp_packet_input_flags_t input_flags; - uint32_t l2_packet_type; + uint32_t l2_ptype; + int vlan_supported = supported_ptypes & PTYPE_VLAN; + int qinq_supported = supported_ptypes & PTYPE_VLAN_QINQ; + int arp_supported = supported_ptypes & PTYPE_ARP;
input_flags.all = 0; input_flags.l2 = 1; @@ -64,22 +68,19 @@ static inline uint16_t dpdk_parse_eth(packet_parser_t *prs, }
/* Get Ethertype */ - l2_packet_type = mbuf_packet_type & RTE_PTYPE_L2_MASK; - switch (l2_packet_type) { - case RTE_PTYPE_L2_ETHER: - if (RTE_ETH_IS_IPV4_HDR(mbuf_packet_type)) - ethtype = _ODP_ETHTYPE_IPV4; - else if (RTE_ETH_IS_IPV6_HDR(mbuf_packet_type)) - ethtype = _ODP_ETHTYPE_IPV6; - else - ethtype = odp_be_to_cpu_16(eth->type); - break; - case RTE_PTYPE_L2_ETHER_VLAN: + l2_ptype = mbuf_packet_type & RTE_PTYPE_L2_MASK; + + /* RTE_PTYPE_L2_ETHER type cannot be trusted when some L2 types are + * not supported. E.g. if VLAN is not supported, both VLAN and non-VLAN + * packets are marked as RTE_PTYPE_L2_ETHER. */ + ethtype = odp_be_to_cpu_16(eth->type); + + if (vlan_supported && l2_ptype == RTE_PTYPE_L2_ETHER_VLAN) ethtype = _ODP_ETHTYPE_VLAN; - break; - default: - ethtype = odp_be_to_cpu_16(eth->type); - } + else if (qinq_supported && l2_ptype == RTE_PTYPE_L2_ETHER_QINQ) + ethtype = _ODP_ETHTYPE_VLAN_OUTER; + else if (arp_supported && l2_ptype == RTE_PTYPE_L2_ETHER_ARP) + ethtype = _ODP_ETHTYPE_ARP;
*offset += sizeof(*eth); *parseptr += sizeof(*eth); @@ -460,6 +461,7 @@ int dpdk_packet_parse_common_l3_l4(packet_parser_t *prs, int _odp_dpdk_packet_parse_common(packet_parser_t *prs, const uint8_t *ptr, uint32_t frame_len, uint32_t seg_len, struct rte_mbuf *mbuf, int layer, + uint32_t supported_ptype, odp_pktin_config_opt_t pktin_cfg) { uint32_t offset; @@ -481,7 +483,7 @@ int _odp_dpdk_packet_parse_common(packet_parser_t *prs, const uint8_t *ptr, prs->l2_offset = offset;
ethtype = dpdk_parse_eth(prs, &parseptr, &offset, frame_len, - mbuf_packet_type); + mbuf_packet_type, supported_ptype);
return dpdk_packet_parse_common_l3_l4(prs, parseptr, offset, frame_len, seg_len, layer, ethtype,
commit e47683d428084f9cacf72f1691d30b96c53804c1 Author: Petri Savolainen petri.savolainen@nokia.com Date: Fri Oct 18 15:14:26 2019 +0300
example: cls: add support for ODP_PMR_VLAN_ID_0
Added support for ODP_PMR_VLAN_ID_0 term.
Signed-off-by: Petri Savolainen petri.savolainen@nokia.com Reviewed-by: Matias Elo matias.elo@nokia.com
diff --git a/example/classifier/odp_classifier.c b/example/classifier/odp_classifier.c index 8cbc5a289..691fec297 100644 --- a/example/classifier/odp_classifier.c +++ b/example/classifier/odp_classifier.c @@ -771,6 +771,9 @@ static int convert_str_to_pmr_enum(char *token, odp_cls_pmr_term_t *term) if (strcasecmp(token, "ODP_PMR_ETHTYPE_0") == 0) { *term = ODP_PMR_ETHTYPE_0; return 0; + } else if (strcasecmp(token, "ODP_PMR_VLAN_ID_0") == 0) { + *term = ODP_PMR_VLAN_ID_0; + return 0; } else if (strcasecmp(token, "ODP_PMR_SIP_ADDR") == 0) { *term = ODP_PMR_SIP_ADDR; return 0; @@ -822,6 +825,9 @@ static int parse_pmr_policy(appl_args_t *appl_args, char *argv[], char *optarg) switch (term) { case ODP_PMR_ETHTYPE_0: /* :<type>:<mask> */ + /* Fall through */ + case ODP_PMR_VLAN_ID_0: + /* :<vlan_id>:<mask> */ token = strtok(NULL, ":"); strncpy(stats[policy_count].value, token, DISPLAY_STRING_LEN - 1);
commit ce35815639996bb2832c298c7d5d40eff6c175d0 Author: Petri Savolainen petri.savolainen@nokia.com Date: Thu Oct 17 09:26:36 2019 +0300
example: cls: add support for ODP_PMR_ETHTYPE_0
Added support for ODP_PMR_ETHTYPE_0 term.
Signed-off-by: Petri Savolainen petri.savolainen@nokia.com Reviewed-by: Matias Elo matias.elo@nokia.com
diff --git a/example/classifier/odp_classifier.c b/example/classifier/odp_classifier.c index 578109e6c..8cbc5a289 100644 --- a/example/classifier/odp_classifier.c +++ b/example/classifier/odp_classifier.c @@ -768,7 +768,10 @@ static int convert_str_to_pmr_enum(char *token, odp_cls_pmr_term_t *term) if (NULL == token) return -1;
- if (strcasecmp(token, "ODP_PMR_SIP_ADDR") == 0) { + if (strcasecmp(token, "ODP_PMR_ETHTYPE_0") == 0) { + *term = ODP_PMR_ETHTYPE_0; + return 0; + } else if (strcasecmp(token, "ODP_PMR_SIP_ADDR") == 0) { *term = ODP_PMR_SIP_ADDR; return 0; } else if (strcasecmp(token, "ODP_PMR_CUSTOM_FRAME") == 0) { @@ -789,6 +792,7 @@ static int parse_pmr_policy(appl_args_t *appl_args, char *argv[], char *optarg) char *pmr_str; uint32_t offset; uint32_t ip_addr; + unsigned long int value;
policy_count = appl_args->policy_count; stats = appl_args->stats; @@ -812,9 +816,24 @@ static int parse_pmr_policy(appl_args_t *appl_args, char *argv[], char *optarg) exit(EXIT_FAILURE); } stats[policy_count].rule.term = term; + stats[policy_count].rule.offset = 0;
/* PMR value */ - switch (term) { + switch (term) { + case ODP_PMR_ETHTYPE_0: + /* :<type>:<mask> */ + token = strtok(NULL, ":"); + strncpy(stats[policy_count].value, token, + DISPLAY_STRING_LEN - 1); + value = strtoul(token, NULL, 0); + stats[policy_count].rule.val = value; + + token = strtok(NULL, ":"); + strncpy(stats[policy_count].mask, token, + DISPLAY_STRING_LEN - 1); + parse_mask(token, &stats[policy_count].rule.mask); + stats[policy_count].rule.val_sz = 2; + break; case ODP_PMR_SIP_ADDR: /* :<IP addr>:<mask> */ token = strtok(NULL, ":"); @@ -833,7 +852,6 @@ static int parse_pmr_policy(appl_args_t *appl_args, char *argv[], char *optarg) DISPLAY_STRING_LEN - 1); parse_mask(token, &stats[policy_count].rule.mask); stats[policy_count].rule.val_sz = 4; - stats[policy_count].rule.offset = 0; break; case ODP_PMR_CUSTOM_FRAME: /* :<offset>:<value>:<mask> */
commit 66e459c9f841932818acd423ddeda65f2ad1c2de Author: Petri Savolainen petri.savolainen@nokia.com Date: Wed Oct 16 15:58:42 2019 +0300
example: cls: add source cos parameter
Add source CoS name into the parameter list of -p option. This enables linking classification rules together. When a source CoS is not defined, the default CoS is used as the source CoS.
Option -p parameter list format is now: <term>:<xxx>:<yyy>:<src_cos>:<dst_cos>
Where <src_cos> is optional and number of "xxx", "yyy", etc parameters is term depend.
Signed-off-by: Petri Savolainen petri.savolainen@nokia.com Reviewed-by: Matias Elo matias.elo@nokia.com
diff --git a/example/classifier/odp_classifier.c b/example/classifier/odp_classifier.c index 3ee1cde76..578109e6c 100644 --- a/example/classifier/odp_classifier.c +++ b/example/classifier/odp_classifier.c @@ -56,6 +56,7 @@ typedef struct { odp_atomic_u64_t queue_pkt_count; /**< count of received packets */ odp_atomic_u64_t pool_pkt_count; /**< count of received packets */ char cos_name[ODP_COS_NAME_LEN]; /**< cos name */ + char src_cos_name[ODP_COS_NAME_LEN]; /**< source cos name */ struct { odp_cls_pmr_term_t term; /**< odp pmr term value */ uint64_t val; /**< pmr term value */ @@ -65,6 +66,8 @@ typedef struct { } rule; char value[DISPLAY_STRING_LEN]; /**< Display string for value */ char mask[DISPLAY_STRING_LEN]; /**< Display string for mask */ + int has_src_cos; + } global_statistics;
typedef struct { @@ -87,17 +90,11 @@ enum packet_mode {
static appl_args_t *appl_args_gbl;
-/* helper funcs */ static int drop_err_pkts(odp_packet_t pkt_tbl[], unsigned len); static void swap_pkt_addrs(odp_packet_t pkt_tbl[], unsigned len); static void parse_args(int argc, char *argv[], appl_args_t *appl_args); static void print_info(char *progname, appl_args_t *appl_args); static void usage(char *progname); -static void configure_cos(odp_cos_t default_cos, appl_args_t *args); -static odp_cos_t configure_default_cos(odp_pktio_t pktio, appl_args_t *args); -static int convert_str_to_pmr_enum(char *token, odp_cls_pmr_term_t *term, - uint32_t *offset); -static int parse_pmr_policy(appl_args_t *appl_args, char *argv[], char *optarg);
static inline void print_cls_statistics(appl_args_t *args) { @@ -410,6 +407,23 @@ static odp_cos_t configure_default_cos(odp_pktio_t pktio, appl_args_t *args) return cos_default; }
+static int find_cos(appl_args_t *args, const char *name, odp_cos_t *cos) +{ + global_statistics *stats; + int i; + + for (i = 0; i < args->policy_count - 1; i++) { + stats = &args->stats[i]; + + if (strcmp(stats->cos_name, name) == 0) { + *cos = stats->cos; + return 0; + } + } + + return -1; +} + static void configure_cos(odp_cos_t default_cos, appl_args_t *args) { char cos_name[ODP_COS_NAME_LEN]; @@ -417,7 +431,6 @@ static void configure_cos(odp_cos_t default_cos, appl_args_t *args) const char *queue_name; odp_pool_param_t pool_params; odp_cls_cos_param_t cls_param; - odp_pmr_param_t pmr_param; int i; global_statistics *stats; odp_queue_param_t qparam; @@ -462,6 +475,23 @@ static void configure_cos(odp_cos_t default_cos, appl_args_t *args) cls_param.drop_policy = ODP_COS_DROP_POOL; stats->cos = odp_cls_cos_create(cos_name, &cls_param);
+ odp_atomic_init_u64(&stats->queue_pkt_count, 0); + odp_atomic_init_u64(&stats->pool_pkt_count, 0); + } + + for (i = 0; i < args->policy_count - 1; i++) { + odp_pmr_param_t pmr_param; + odp_cos_t src_cos = default_cos; + + stats = &args->stats[i]; + + if (stats->has_src_cos) { + if (find_cos(args, stats->src_cos_name, &src_cos)) { + ODPH_ERR("find_cos failed\n"); + exit(EXIT_FAILURE); + } + } + odp_cls_pmr_param_init(&pmr_param); pmr_param.term = stats->rule.term; pmr_param.match.value = &stats->rule.val; @@ -469,16 +499,14 @@ static void configure_cos(odp_cos_t default_cos, appl_args_t *args) pmr_param.val_sz = stats->rule.val_sz; pmr_param.offset = stats->rule.offset;
- stats->pmr = odp_cls_pmr_create(&pmr_param, 1, default_cos, + stats->pmr = odp_cls_pmr_create(&pmr_param, 1, src_cos, stats->cos); if (stats->pmr == ODP_PMR_INVALID) { ODPH_ERR("odp_pktio_pmr_cos failed\n"); exit(EXIT_FAILURE); } - - odp_atomic_init_u64(&stats->queue_pkt_count, 0); - odp_atomic_init_u64(&stats->pool_pkt_count, 0); } + }
static void sig_handler(int signo) @@ -735,30 +763,26 @@ static void swap_pkt_addrs(odp_packet_t pkt_tbl[], unsigned len) } }
-static int convert_str_to_pmr_enum(char *token, odp_cls_pmr_term_t *term, - uint32_t *offset) +static int convert_str_to_pmr_enum(char *token, odp_cls_pmr_term_t *term) { if (NULL == token) return -1;
- if (0 == strcasecmp(token, "ODP_PMR_SIP_ADDR")) { + if (strcasecmp(token, "ODP_PMR_SIP_ADDR") == 0) { *term = ODP_PMR_SIP_ADDR; return 0; - } else { - errno = 0; - *offset = strtoul(token, NULL, 0); - if (errno) - return -1; + } else if (strcasecmp(token, "ODP_PMR_CUSTOM_FRAME") == 0) { *term = ODP_PMR_CUSTOM_FRAME; return 0; } + return -1; }
static int parse_pmr_policy(appl_args_t *appl_args, char *argv[], char *optarg) { int policy_count; - char *token; + char *token, *cos0, *cos1; size_t len; odp_cls_pmr_term_t term; global_statistics *stats; @@ -781,8 +805,9 @@ static int parse_pmr_policy(appl_args_t *appl_args, char *argv[], char *optarg) strcpy(pmr_str, optarg);
/* PMR TERM */ + /* <term>:<xxx>:<yyy>:<src_cos>:<dst_cos> */ token = strtok(pmr_str, ":"); - if (convert_str_to_pmr_enum(token, &term, &offset)) { + if (convert_str_to_pmr_enum(token, &term)) { ODPH_ERR("Invalid ODP_PMR_TERM string\n"); exit(EXIT_FAILURE); } @@ -791,6 +816,7 @@ static int parse_pmr_policy(appl_args_t *appl_args, char *argv[], char *optarg) /* PMR value */ switch (term) { case ODP_PMR_SIP_ADDR: + /* :<IP addr>:<mask> */ token = strtok(NULL, ":"); strncpy(stats[policy_count].value, token, DISPLAY_STRING_LEN - 1); @@ -810,6 +836,13 @@ static int parse_pmr_policy(appl_args_t *appl_args, char *argv[], char *optarg) stats[policy_count].rule.offset = 0; break; case ODP_PMR_CUSTOM_FRAME: + /* :<offset>:<value>:<mask> */ + token = strtok(NULL, ":"); + errno = 0; + offset = strtoul(token, NULL, 0); + if (errno) + return -1; + token = strtok(NULL, ":"); strncpy(stats[policy_count].value, token, DISPLAY_STRING_LEN - 1); @@ -826,10 +859,24 @@ static int parse_pmr_policy(appl_args_t *appl_args, char *argv[], char *optarg) exit(EXIT_FAILURE); }
- /* Queue Name */ - token = strtok(NULL, ":"); + /* Optional source CoS name and name of this CoS + * :<src_cos>:<cos> */ + cos0 = strtok(NULL, ":"); + cos1 = strtok(NULL, ":"); + if (cos0 == NULL) + return -1; + + if (cos1) { + stats[policy_count].has_src_cos = 1; + strncpy(stats[policy_count].src_cos_name, cos0, + ODP_COS_NAME_LEN - 1); + strncpy(stats[policy_count].cos_name, cos1, + ODP_COS_NAME_LEN - 1); + } else { + strncpy(stats[policy_count].cos_name, cos0, + ODP_COS_NAME_LEN - 1); + }
- strncpy(stats[policy_count].cos_name, token, ODP_QUEUE_NAME_LEN - 1); appl_args->policy_count++; free(pmr_str); return 0;
commit 0b63c8154a779ba20010bcd9ae7ee6bf610d755b Author: Petri Savolainen petri.savolainen@nokia.com Date: Wed Oct 16 11:16:50 2019 +0300
example: cls: add verbose option
Added -v option which prints received packet with CoS queue name. This can be used for debugging classification rules.
Signed-off-by: Petri Savolainen petri.savolainen@nokia.com Reviewed-by: Matias Elo matias.elo@nokia.com
diff --git a/example/classifier/odp_classifier.c b/example/classifier/odp_classifier.c index c38c6dfd8..3ee1cde76 100644 --- a/example/classifier/odp_classifier.c +++ b/example/classifier/odp_classifier.c @@ -1,4 +1,5 @@ /* Copyright (c) 2015-2018, Linaro Limited + * Copyright (c) 2019, Nokia * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause @@ -9,6 +10,7 @@ #include <getopt.h> #include <unistd.h> #include <inttypes.h> +#include <signal.h>
#include <odp_api.h> #include <odp/helper/odph_api.h> @@ -74,6 +76,8 @@ typedef struct { uint32_t time; /**< Number of seconds to run */ char *if_name; /**< pointer to interface names */ int shutdown; /**< Shutdown threads if !0 */ + int shutdown_sig; + int verbose; } appl_args_t;
enum packet_mode { @@ -81,6 +85,8 @@ enum packet_mode { APPL_MODE_REPLY /**< Packet is sent back */ };
+static appl_args_t *appl_args_gbl; + /* helper funcs */ static int drop_err_pkts(odp_packet_t pkt_tbl[], unsigned len); static void swap_pkt_addrs(odp_packet_t pkt_tbl[], unsigned len); @@ -93,8 +99,7 @@ static int convert_str_to_pmr_enum(char *token, odp_cls_pmr_term_t *term, uint32_t *offset); static int parse_pmr_policy(appl_args_t *appl_args, char *argv[], char *optarg);
-static inline -void print_cls_statistics(appl_args_t *args) +static inline void print_cls_statistics(appl_args_t *args) { int i; uint32_t timeout; @@ -153,6 +158,9 @@ void print_cls_statistics(appl_args_t *args) printf("%-" PRIu64, odp_atomic_load_u64(&args-> total_packets));
+ if (args->shutdown_sig) + break; + sleep(1); printf("\r"); fflush(stdout); @@ -161,8 +169,7 @@ void print_cls_statistics(appl_args_t *args) printf("\n"); }
-static inline -int parse_mask(const char *str, uint64_t *mask) +static inline int parse_mask(const char *str, uint64_t *mask) { uint64_t b; int ret; @@ -172,8 +179,7 @@ int parse_mask(const char *str, uint64_t *mask) return ret != 1; }
-static -int parse_value(const char *str, uint64_t *val, uint32_t *val_sz) +static int parse_value(const char *str, uint64_t *val, uint32_t *val_sz) { size_t len; size_t i; @@ -260,12 +266,13 @@ static int pktio_receive_thread(void *arg) odp_packet_t pkt; odp_pool_t pool; odp_event_t ev; - unsigned long err_cnt = 0; odp_queue_t queue; int i; + global_statistics *stats; + unsigned long err_cnt = 0; thr = odp_thread_id(); appl_args_t *appl = (appl_args_t *)arg; - global_statistics *stats; + uint64_t wait_time = odp_schedule_wait_time(100 * ODP_TIME_MSEC_IN_NS);
/* Loop packets */ for (;;) { @@ -275,8 +282,7 @@ static int pktio_receive_thread(void *arg) break;
/* Use schedule to get buf from any input queue */ - ev = odp_schedule(&queue, - odp_schedule_wait_time(ODP_TIME_SEC_IN_NS)); + ev = odp_schedule(&queue, wait_time);
/* Loop back to receive packets incase of invalid event */ if (odp_unlikely(ev == ODP_EVENT_INVALID)) @@ -284,6 +290,19 @@ static int pktio_receive_thread(void *arg)
pkt = odp_packet_from_event(ev);
+ if (appl->verbose) { + odp_queue_info_t info; + uint32_t len = odp_packet_len(pkt); + + if (odp_queue_info(queue, &info) == 0) + printf("Queue: %s\n", info.name); + + if (len > 96) + len = 96; + + odp_packet_print_data(pkt, 0, len); + } + /* Total packets received */ odp_atomic_inc_u64(&appl->total_packets);
@@ -394,8 +413,8 @@ static odp_cos_t configure_default_cos(odp_pktio_t pktio, appl_args_t *args) static void configure_cos(odp_cos_t default_cos, appl_args_t *args) { char cos_name[ODP_COS_NAME_LEN]; - char queue_name[ODP_QUEUE_NAME_LEN]; char pool_name[ODP_POOL_NAME_LEN]; + const char *queue_name; odp_pool_param_t pool_params; odp_cls_cos_param_t cls_param; odp_pmr_param_t pmr_param; @@ -412,8 +431,7 @@ static void configure_cos(odp_cos_t default_cos, appl_args_t *args) qparam.sched.sync = ODP_SCHED_SYNC_PARALLEL; qparam.sched.group = ODP_SCHED_GROUP_ALL;
- snprintf(queue_name, sizeof(queue_name), "%sQueue%d", - args->stats[i].cos_name, i); + queue_name = args->stats[i].cos_name; stats->queue = odp_queue_create(queue_name, &qparam); if (ODP_QUEUE_INVALID == stats->queue) { ODPH_ERR("odp_queue_create failed\n"); @@ -463,6 +481,15 @@ static void configure_cos(odp_cos_t default_cos, appl_args_t *args) } }
+static void sig_handler(int signo) +{ + (void)signo; + + if (appl_args_gbl == NULL) + return; + appl_args_gbl->shutdown_sig = 1; +} + /** * ODP Classifier example main function */ @@ -486,6 +513,8 @@ int main(int argc, char *argv[]) odph_thread_common_param_t thr_common; odph_thread_param_t thr_param;
+ signal(SIGINT, sig_handler); + /* Let helper collect its own arguments (e.g. --odph_proc) */ argc = odph_parse_options(argc, argv); if (odph_options(&helper_options)) { @@ -524,6 +553,7 @@ int main(int argc, char *argv[]) exit(EXIT_FAILURE); }
+ appl_args_gbl = args; memset(args, 0, sizeof(*args)); /* Parse and store the application arguments */ parse_args(argc, argv, args); @@ -591,7 +621,18 @@ int main(int argc, char *argv[])
odph_thread_create(thread_tbl, &thr_common, &thr_param, num_workers);
- print_cls_statistics(args); + if (args->verbose == 0) { + print_cls_statistics(args); + } else { + int timeout = args->time; + + for (i = 0; timeout == 0 || i < timeout; i++) { + if (args->shutdown_sig) + break; + + sleep(1); + } + }
odp_pktio_stop(pktio); args->shutdown = 1; @@ -714,7 +755,6 @@ static int convert_str_to_pmr_enum(char *token, odp_cls_pmr_term_t *term, return -1; }
- static int parse_pmr_policy(appl_args_t *appl_args, char *argv[], char *optarg) { int policy_count; @@ -813,17 +853,19 @@ static void parse_args(int argc, char *argv[], appl_args_t *appl_args)
static const struct option longopts[] = { {"count", required_argument, NULL, 'c'}, - {"interface", required_argument, NULL, 'i'}, /* return 'i' */ - {"policy", required_argument, NULL, 'p'}, /* return 'p' */ - {"mode", required_argument, NULL, 'm'}, /* return 'm' */ - {"time", required_argument, NULL, 't'}, /* return 't' */ - {"help", no_argument, NULL, 'h'}, /* return 'h' */ + {"interface", required_argument, NULL, 'i'}, + {"policy", required_argument, NULL, 'p'}, + {"mode", required_argument, NULL, 'm'}, + {"time", required_argument, NULL, 't'}, + {"verbose", no_argument, NULL, 'v'}, + {"help", no_argument, NULL, 'h'}, {NULL, 0, NULL, 0} };
- static const char *shortopts = "+c:t:i:p:m:t:h"; + static const char *shortopts = "+c:t:i:p:m:t:vh";
appl_args->cpu_count = 1; /* Use one worker by default */ + appl_args->verbose = 0;
while (1) { opt = getopt_long(argc, argv, shortopts, @@ -861,11 +903,6 @@ static void parse_args(int argc, char *argv[], appl_args_t *appl_args) strcpy(appl_args->if_name, optarg); interface = 1; break; - - case 'h': - usage(argv[0]); - exit(EXIT_SUCCESS); - break; case 'm': i = atoi(optarg); if (i == 0) @@ -873,7 +910,13 @@ static void parse_args(int argc, char *argv[], appl_args_t *appl_args) else appl_args->appl_mode = APPL_MODE_REPLY; break; - + case 'v': + appl_args->verbose = 1; + break; + case 'h': + usage(argv[0]); + exit(EXIT_SUCCESS); + break; default: break; }
commit e7117fb0ecc8440dd1b8ef5845b14c82cd2f2ace Author: Petri Savolainen petri.savolainen@nokia.com Date: Fri Oct 11 17:28:39 2019 +0300
linux-gen: cls: fix eth_type_0 match bug
Eth_type_0 match required packet to be a VLAN qinq frame, when packet needs to be just ethernet.
Also, eth_type_0 test case produced a VLAN qinq frame. Use an IPv6 packet instead.
Signed-off-by: Petri Savolainen petri.savolainen@nokia.com Reviewed-by: Matias Elo matias.elo@nokia.com
diff --git a/platform/linux-generic/odp_classification.c b/platform/linux-generic/odp_classification.c index 6f4b02c2f..93e086e84 100644 --- a/platform/linux-generic/odp_classification.c +++ b/platform/linux-generic/odp_classification.c @@ -1041,7 +1041,7 @@ static inline int verify_pmr_eth_type_0(const uint8_t *pkt_addr, const _odp_ethhdr_t *eth; uint16_t ethtype;
- if (!pkt_hdr->p.input_flags.vlan_qinq) + if (!packet_hdr_has_eth(pkt_hdr)) return 0;
eth = (const _odp_ethhdr_t *)(pkt_addr + pkt_hdr->p.l2_offset); diff --git a/test/validation/api/classification/odp_classification_test_pmr.c b/test/validation/api/classification/odp_classification_test_pmr.c index 47cdeaa76..c8cf0077d 100644 --- a/test/validation/api/classification/odp_classification_test_pmr.c +++ b/test/validation/api/classification/odp_classification_test_pmr.c @@ -1285,7 +1285,7 @@ static void classification_test_pmr_term_eth_type_0(void) odph_ethhdr_t *eth; cls_packet_info_t pkt_info;
- val = 0x88A8; + val = ODPH_ETHTYPE_IPV6; mask = 0xffff; seqno = 0;
@@ -1322,8 +1322,7 @@ static void classification_test_pmr_term_eth_type_0(void) CU_ASSERT(pmr != ODP_PMR_INVALID);
pkt_info = default_pkt_info; - pkt_info.vlan = true; - pkt_info.vlan_qinq = true; + pkt_info.ipv6 = true; pkt = create_packet(pkt_info); CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); seqno = cls_pkt_get_seq(pkt);
commit 95eb732efd42e889e280120f504c4c3e50348cab Author: Petri Savolainen petri.savolainen@nokia.com Date: Fri Oct 11 17:02:58 2019 +0300
linux-gen: cls: remove odp_classification_inlines.h
Content of this header is needed only in odp_classification.c file. Copy content there and remove the header file.
Signed-off-by: Petri Savolainen petri.savolainen@nokia.com Reviewed-by: Matias Elo matias.elo@nokia.com
diff --git a/platform/linux-generic/Makefile.am b/platform/linux-generic/Makefile.am index 9f24bc829..0d4d905f9 100644 --- a/platform/linux-generic/Makefile.am +++ b/platform/linux-generic/Makefile.am @@ -90,7 +90,6 @@ noinst_HEADERS = \ include/odp_bitset.h \ include/odp_buffer_internal.h \ include/odp_classification_datamodel.h \ - include/odp_classification_inlines.h \ include/odp_classification_internal.h \ include/odp_config_internal.h \ include/odp_debug_internal.h \ diff --git a/platform/linux-generic/include/odp_classification_inlines.h b/platform/linux-generic/include/odp_classification_inlines.h deleted file mode 100644 index 36fffc1dc..000000000 --- a/platform/linux-generic/include/odp_classification_inlines.h +++ /dev/null @@ -1,385 +0,0 @@ -/* Copyright (c) 2014-2018, Linaro Limited - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/** - * @file - * - * ODP Classification Inlines - * Classification Inlines Functions - */ -#ifndef __ODP_CLASSIFICATION_INLINES_H_ -#define __ODP_CLASSIFICATION_INLINES_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include <odp/api/debug.h> -#include <odp/api/byteorder.h> -#include <odp/api/plat/byteorder_inlines.h> -#include <protocols/eth.h> -#include <protocols/ip.h> -#include <protocols/ipsec.h> -#include <protocols/udp.h> -#include <protocols/tcp.h> -#include <odp_packet_internal.h> -#include <stdio.h> -#include <inttypes.h> - -/* PMR term value verification function -These functions verify the given PMR term value with the value in the packet -These following functions return 1 on success and 0 on failure -*/ - -static inline int verify_pmr_packet_len(odp_packet_hdr_t *pkt_hdr, - pmr_term_value_t *term_value) -{ - if (term_value->match.value == (packet_len(pkt_hdr) & - term_value->match.mask)) - return 1; - - return 0; -} - -static inline int verify_pmr_ip_proto(const uint8_t *pkt_addr, - odp_packet_hdr_t *pkt_hdr, - pmr_term_value_t *term_value) -{ - const _odp_ipv4hdr_t *ip; - uint8_t proto; - - if (!pkt_hdr->p.input_flags.ipv4) - return 0; - ip = (const _odp_ipv4hdr_t *)(pkt_addr + pkt_hdr->p.l3_offset); - proto = ip->proto; - if (term_value->match.value == (proto & term_value->match.mask)) - return 1; - - return 0; -} - -static inline int verify_pmr_ipv4_saddr(const uint8_t *pkt_addr, - odp_packet_hdr_t *pkt_hdr, - pmr_term_value_t *term_value) -{ - const _odp_ipv4hdr_t *ip; - uint32_t ipaddr; - - if (!pkt_hdr->p.input_flags.ipv4) - return 0; - ip = (const _odp_ipv4hdr_t *)(pkt_addr + pkt_hdr->p.l3_offset); - ipaddr = odp_be_to_cpu_32(ip->src_addr); - if (term_value->match.value == (ipaddr & term_value->match.mask)) - return 1; - - return 0; -} - -static inline int verify_pmr_ipv4_daddr(const uint8_t *pkt_addr, - odp_packet_hdr_t *pkt_hdr, - pmr_term_value_t *term_value) -{ - const _odp_ipv4hdr_t *ip; - uint32_t ipaddr; - - if (!pkt_hdr->p.input_flags.ipv4) - return 0; - ip = (const _odp_ipv4hdr_t *)(pkt_addr + pkt_hdr->p.l3_offset); - ipaddr = odp_be_to_cpu_32(ip->dst_addr); - if (term_value->match.value == (ipaddr & term_value->match.mask)) - return 1; - - return 0; -} - -static inline int verify_pmr_tcp_sport(const uint8_t *pkt_addr, - odp_packet_hdr_t *pkt_hdr, - pmr_term_value_t *term_value) -{ - uint16_t sport; - const _odp_tcphdr_t *tcp; - - if (!pkt_hdr->p.input_flags.tcp) - return 0; - tcp = (const _odp_tcphdr_t *)(pkt_addr + pkt_hdr->p.l4_offset); - sport = odp_be_to_cpu_16(tcp->src_port); - if (term_value->match.value == (sport & term_value->match.mask)) - return 1; - - return 0; -} - -static inline int verify_pmr_tcp_dport(const uint8_t *pkt_addr, - odp_packet_hdr_t *pkt_hdr, - pmr_term_value_t *term_value) -{ - uint16_t dport; - const _odp_tcphdr_t *tcp; - - if (!pkt_hdr->p.input_flags.tcp) - return 0; - tcp = (const _odp_tcphdr_t *)(pkt_addr + pkt_hdr->p.l4_offset); - dport = odp_be_to_cpu_16(tcp->dst_port); - if (term_value->match.value == (dport & term_value->match.mask)) - return 1; - - return 0; -} - -static inline int verify_pmr_udp_dport(const uint8_t *pkt_addr, - odp_packet_hdr_t *pkt_hdr, - pmr_term_value_t *term_value) -{ - uint16_t dport; - const _odp_udphdr_t *udp; - - if (!pkt_hdr->p.input_flags.udp) - return 0; - udp = (const _odp_udphdr_t *)(pkt_addr + pkt_hdr->p.l4_offset); - dport = odp_be_to_cpu_16(udp->dst_port); - if (term_value->match.value == (dport & term_value->match.mask)) - return 1; - - return 0; -} - -static inline int verify_pmr_udp_sport(const uint8_t *pkt_addr, - odp_packet_hdr_t *pkt_hdr, - pmr_term_value_t *term_value) -{ - uint16_t sport; - const _odp_udphdr_t *udp; - - if (!pkt_hdr->p.input_flags.udp) - return 0; - udp = (const _odp_udphdr_t *)(pkt_addr + pkt_hdr->p.l4_offset); - sport = odp_be_to_cpu_16(udp->src_port); - if (term_value->match.value == (sport & term_value->match.mask)) - return 1; - - return 0; -} - -static inline int verify_pmr_dmac(const uint8_t *pkt_addr, - odp_packet_hdr_t *pkt_hdr, - pmr_term_value_t *term_value) -{ - uint64_t dmac = 0; - uint64_t dmac_be = 0; - const _odp_ethhdr_t *eth; - - if (!packet_hdr_has_eth(pkt_hdr)) - return 0; - - eth = (const _odp_ethhdr_t *)(pkt_addr + pkt_hdr->p.l2_offset); - memcpy(&dmac_be, eth->dst.addr, _ODP_ETHADDR_LEN); - dmac = odp_be_to_cpu_64(dmac_be); - /* since we are converting a 48 bit ethernet address from BE to cpu - format using odp_be_to_cpu_64() the last 16 bits needs to be right - shifted */ - if (dmac_be != dmac) - dmac = dmac >> (64 - (_ODP_ETHADDR_LEN * 8)); - - if (term_value->match.value == (dmac & term_value->match.mask)) - return 1; - return 0; -} - -static inline int verify_pmr_ipv6_saddr(const uint8_t *pkt_addr, - odp_packet_hdr_t *pkt_hdr, - pmr_term_value_t *term_value) -{ - const _odp_ipv6hdr_t *ipv6; - uint64_t addr[2]; - - if (!packet_hdr_has_ipv6(pkt_hdr)) - return 0; - - ipv6 = (const _odp_ipv6hdr_t *)(pkt_addr + pkt_hdr->p.l3_offset); - - addr[0] = ipv6->src_addr.u64[0]; - addr[1] = ipv6->src_addr.u64[1]; - - /* 128 bit address is processed as two 64 bit value - * for bitwise AND operation */ - addr[0] = addr[0] & term_value->match_ipv6.mask.u64[0]; - addr[1] = addr[1] & term_value->match_ipv6.mask.u64[1]; - - if (!memcmp(addr, term_value->match_ipv6.addr.u8, _ODP_IPV6ADDR_LEN)) - return 1; - - return 0; -} - -static inline int verify_pmr_ipv6_daddr(const uint8_t *pkt_addr, - odp_packet_hdr_t *pkt_hdr, - pmr_term_value_t *term_value) -{ - const _odp_ipv6hdr_t *ipv6; - uint64_t addr[2]; - - if (!packet_hdr_has_ipv6(pkt_hdr)) - return 0; - ipv6 = (const _odp_ipv6hdr_t *)(pkt_addr + pkt_hdr->p.l3_offset); - addr[0] = ipv6->dst_addr.u64[0]; - addr[1] = ipv6->dst_addr.u64[1]; - - /* 128 bit address is processed as two 64 bit value - * for bitwise AND operation */ - addr[0] = addr[0] & term_value->match_ipv6.mask.u64[0]; - addr[1] = addr[1] & term_value->match_ipv6.mask.u64[1]; - - if (!memcmp(addr, term_value->match_ipv6.addr.u8, _ODP_IPV6ADDR_LEN)) - return 1; - - return 0; -} - -static inline int verify_pmr_vlan_id_0(const uint8_t *pkt_addr, - odp_packet_hdr_t *pkt_hdr, - pmr_term_value_t *term_value) -{ - const _odp_ethhdr_t *eth; - const _odp_vlanhdr_t *vlan; - uint16_t tci; - uint16_t vlan_id; - - if (!pkt_hdr->p.input_flags.vlan_qinq) - return 0; - - eth = (const _odp_ethhdr_t *)(pkt_addr + pkt_hdr->p.l2_offset); - vlan = (const _odp_vlanhdr_t *)(eth + 1); - tci = odp_be_to_cpu_16(vlan->tci); - vlan_id = tci & 0x0fff; - - if (term_value->match.value == (vlan_id & term_value->match.mask)) - return 1; - - return 0; -} - -static inline int verify_pmr_vlan_id_x(const uint8_t *pkt_addr ODP_UNUSED, - odp_packet_hdr_t *pkt_hdr ODP_UNUSED, - pmr_term_value_t *term_value ODP_UNUSED) -{ - const _odp_ethhdr_t *eth; - const _odp_vlanhdr_t *vlan; - uint16_t tci; - uint16_t vlan_id; - - if (!pkt_hdr->p.input_flags.vlan_qinq) - return 0; - - eth = (const _odp_ethhdr_t *)(pkt_addr + pkt_hdr->p.l2_offset); - vlan = (const _odp_vlanhdr_t *)(eth + 1); - vlan++; - tci = odp_be_to_cpu_16(vlan->tci); - vlan_id = tci & 0x0fff; - - if (term_value->match.value == (vlan_id & term_value->match.mask)) - return 1; - - return 0; -} - -static inline int verify_pmr_ipsec_spi(const uint8_t *pkt_addr, - odp_packet_hdr_t *pkt_hdr, - pmr_term_value_t *term_value) -{ - uint32_t spi; - - pkt_addr += pkt_hdr->p.l4_offset; - - if (pkt_hdr->p.input_flags.ipsec_ah) { - const _odp_ahhdr_t *ahhdr = (const _odp_ahhdr_t *)pkt_addr; - - spi = odp_be_to_cpu_32(ahhdr->spi); - } else if (pkt_hdr->p.input_flags.ipsec_esp) { - const _odp_esphdr_t *esphdr = (const _odp_esphdr_t *)pkt_addr; - - spi = odp_be_to_cpu_32(esphdr->spi); - } else { - return 0; - } - - if (term_value->match.value == (spi & term_value->match.mask)) - return 1; - - return 0; -} - -static inline int verify_pmr_ld_vni(const uint8_t *pkt_addr ODP_UNUSED, - odp_packet_hdr_t *pkt_hdr ODP_UNUSED, - pmr_term_value_t *term_value ODP_UNUSED) -{ - ODP_UNIMPLEMENTED(); - return 0; -} - -static inline int verify_pmr_custom_frame(const uint8_t *pkt_addr, - odp_packet_hdr_t *pkt_hdr, - pmr_term_value_t *term_value) -{ - uint64_t val = 0; - uint32_t offset = term_value->offset; - uint32_t val_sz = term_value->val_sz; - - ODP_ASSERT(val_sz <= CLS_PMR_TERM_BYTES_MAX); - - if (packet_len(pkt_hdr) <= offset + val_sz) - return 0; - - memcpy(&val, pkt_addr + offset, val_sz); - if (term_value->match.value == (val & term_value->match.mask)) - return 1; - - return 0; -} - -static inline int verify_pmr_eth_type_0(const uint8_t *pkt_addr, - odp_packet_hdr_t *pkt_hdr, - pmr_term_value_t *term_value) -{ - const _odp_ethhdr_t *eth; - uint16_t ethtype; - - if (!pkt_hdr->p.input_flags.vlan_qinq) - return 0; - - eth = (const _odp_ethhdr_t *)(pkt_addr + pkt_hdr->p.l2_offset); - ethtype = odp_be_to_cpu_16(eth->type); - - if (term_value->match.value == (ethtype & term_value->match.mask)) - return 1; - - return 0; -} - -static inline int verify_pmr_eth_type_x(const uint8_t *pkt_addr, - odp_packet_hdr_t *pkt_hdr, - pmr_term_value_t *term_value) -{ - const _odp_ethhdr_t *eth; - uint16_t ethtype; - const _odp_vlanhdr_t *vlan; - - if (!pkt_hdr->p.input_flags.vlan_qinq) - return 0; - - eth = (const _odp_ethhdr_t *)(pkt_addr + pkt_hdr->p.l2_offset); - vlan = (const _odp_vlanhdr_t *)(eth + 1); - ethtype = odp_be_to_cpu_16(vlan->type); - - if (term_value->match.value == (ethtype & term_value->match.mask)) - return 1; - - return 0; -} - -#ifdef __cplusplus -} -#endif -#endif diff --git a/platform/linux-generic/odp_classification.c b/platform/linux-generic/odp_classification.c index b3d91b3fe..6f4b02c2f 100644 --- a/platform/linux-generic/odp_classification.c +++ b/platform/linux-generic/odp_classification.c @@ -15,12 +15,14 @@ #include <odp/api/packet_io.h> #include <odp_packet_io_internal.h> #include <odp_classification_datamodel.h> -#include <odp_classification_inlines.h> #include <odp_classification_internal.h> #include <odp/api/shared_memory.h> -#include <protocols/thash.h> #include <protocols/eth.h> #include <protocols/ip.h> +#include <protocols/ipsec.h> +#include <protocols/udp.h> +#include <protocols/tcp.h> +#include <protocols/thash.h> #include <string.h> #include <errno.h> #include <stdbool.h> @@ -727,12 +729,357 @@ odp_pool_t odp_cls_cos_pool(odp_cos_t cos_id) return cos->s.pool; }
+static inline int verify_pmr_packet_len(odp_packet_hdr_t *pkt_hdr, + pmr_term_value_t *term_value) +{ + if (term_value->match.value == (packet_len(pkt_hdr) & + term_value->match.mask)) + return 1; + + return 0; +} + +static inline int verify_pmr_ip_proto(const uint8_t *pkt_addr, + odp_packet_hdr_t *pkt_hdr, + pmr_term_value_t *term_value) +{ + const _odp_ipv4hdr_t *ip; + uint8_t proto; + + if (!pkt_hdr->p.input_flags.ipv4) + return 0; + ip = (const _odp_ipv4hdr_t *)(pkt_addr + pkt_hdr->p.l3_offset); + proto = ip->proto; + if (term_value->match.value == (proto & term_value->match.mask)) + return 1; + + return 0; +} + +static inline int verify_pmr_ipv4_saddr(const uint8_t *pkt_addr, + odp_packet_hdr_t *pkt_hdr, + pmr_term_value_t *term_value) +{ + const _odp_ipv4hdr_t *ip; + uint32_t ipaddr; + + if (!pkt_hdr->p.input_flags.ipv4) + return 0; + ip = (const _odp_ipv4hdr_t *)(pkt_addr + pkt_hdr->p.l3_offset); + ipaddr = odp_be_to_cpu_32(ip->src_addr); + if (term_value->match.value == (ipaddr & term_value->match.mask)) + return 1; + + return 0; +} + +static inline int verify_pmr_ipv4_daddr(const uint8_t *pkt_addr, + odp_packet_hdr_t *pkt_hdr, + pmr_term_value_t *term_value) +{ + const _odp_ipv4hdr_t *ip; + uint32_t ipaddr; + + if (!pkt_hdr->p.input_flags.ipv4) + return 0; + ip = (const _odp_ipv4hdr_t *)(pkt_addr + pkt_hdr->p.l3_offset); + ipaddr = odp_be_to_cpu_32(ip->dst_addr); + if (term_value->match.value == (ipaddr & term_value->match.mask)) + return 1; + + return 0; +} + +static inline int verify_pmr_tcp_sport(const uint8_t *pkt_addr, + odp_packet_hdr_t *pkt_hdr, + pmr_term_value_t *term_value) +{ + uint16_t sport; + const _odp_tcphdr_t *tcp; + + if (!pkt_hdr->p.input_flags.tcp) + return 0; + tcp = (const _odp_tcphdr_t *)(pkt_addr + pkt_hdr->p.l4_offset); + sport = odp_be_to_cpu_16(tcp->src_port); + if (term_value->match.value == (sport & term_value->match.mask)) + return 1; + + return 0; +} + +static inline int verify_pmr_tcp_dport(const uint8_t *pkt_addr, + odp_packet_hdr_t *pkt_hdr, + pmr_term_value_t *term_value) +{ + uint16_t dport; + const _odp_tcphdr_t *tcp; + + if (!pkt_hdr->p.input_flags.tcp) + return 0; + tcp = (const _odp_tcphdr_t *)(pkt_addr + pkt_hdr->p.l4_offset); + dport = odp_be_to_cpu_16(tcp->dst_port); + if (term_value->match.value == (dport & term_value->match.mask)) + return 1; + + return 0; +} + +static inline int verify_pmr_udp_dport(const uint8_t *pkt_addr, + odp_packet_hdr_t *pkt_hdr, + pmr_term_value_t *term_value) +{ + uint16_t dport; + const _odp_udphdr_t *udp; + + if (!pkt_hdr->p.input_flags.udp) + return 0; + udp = (const _odp_udphdr_t *)(pkt_addr + pkt_hdr->p.l4_offset); + dport = odp_be_to_cpu_16(udp->dst_port); + if (term_value->match.value == (dport & term_value->match.mask)) + return 1; + + return 0; +} + +static inline int verify_pmr_udp_sport(const uint8_t *pkt_addr, + odp_packet_hdr_t *pkt_hdr, + pmr_term_value_t *term_value) +{ + uint16_t sport; + const _odp_udphdr_t *udp; + + if (!pkt_hdr->p.input_flags.udp) + return 0; + udp = (const _odp_udphdr_t *)(pkt_addr + pkt_hdr->p.l4_offset); + sport = odp_be_to_cpu_16(udp->src_port); + if (term_value->match.value == (sport & term_value->match.mask)) + return 1; + + return 0; +} + +static inline int verify_pmr_dmac(const uint8_t *pkt_addr, + odp_packet_hdr_t *pkt_hdr, + pmr_term_value_t *term_value) +{ + uint64_t dmac = 0; + uint64_t dmac_be = 0; + const _odp_ethhdr_t *eth; + + if (!packet_hdr_has_eth(pkt_hdr)) + return 0; + + eth = (const _odp_ethhdr_t *)(pkt_addr + pkt_hdr->p.l2_offset); + memcpy(&dmac_be, eth->dst.addr, _ODP_ETHADDR_LEN); + dmac = odp_be_to_cpu_64(dmac_be); + /* since we are converting a 48 bit ethernet address from BE to cpu + format using odp_be_to_cpu_64() the last 16 bits needs to be right + shifted */ + if (dmac_be != dmac) + dmac = dmac >> (64 - (_ODP_ETHADDR_LEN * 8)); + + if (term_value->match.value == (dmac & term_value->match.mask)) + return 1; + return 0; +} + +static inline int verify_pmr_ipv6_saddr(const uint8_t *pkt_addr, + odp_packet_hdr_t *pkt_hdr, + pmr_term_value_t *term_value) +{ + const _odp_ipv6hdr_t *ipv6; + uint64_t addr[2]; + + if (!packet_hdr_has_ipv6(pkt_hdr)) + return 0; + + ipv6 = (const _odp_ipv6hdr_t *)(pkt_addr + pkt_hdr->p.l3_offset); + + addr[0] = ipv6->src_addr.u64[0]; + addr[1] = ipv6->src_addr.u64[1]; + + /* 128 bit address is processed as two 64 bit value + * for bitwise AND operation */ + addr[0] = addr[0] & term_value->match_ipv6.mask.u64[0]; + addr[1] = addr[1] & term_value->match_ipv6.mask.u64[1]; + + if (!memcmp(addr, term_value->match_ipv6.addr.u8, _ODP_IPV6ADDR_LEN)) + return 1; + + return 0; +} + +static inline int verify_pmr_ipv6_daddr(const uint8_t *pkt_addr, + odp_packet_hdr_t *pkt_hdr, + pmr_term_value_t *term_value) +{ + const _odp_ipv6hdr_t *ipv6; + uint64_t addr[2]; + + if (!packet_hdr_has_ipv6(pkt_hdr)) + return 0; + ipv6 = (const _odp_ipv6hdr_t *)(pkt_addr + pkt_hdr->p.l3_offset); + addr[0] = ipv6->dst_addr.u64[0]; + addr[1] = ipv6->dst_addr.u64[1]; + + /* 128 bit address is processed as two 64 bit value + * for bitwise AND operation */ + addr[0] = addr[0] & term_value->match_ipv6.mask.u64[0]; + addr[1] = addr[1] & term_value->match_ipv6.mask.u64[1]; + + if (!memcmp(addr, term_value->match_ipv6.addr.u8, _ODP_IPV6ADDR_LEN)) + return 1; + + return 0; +} + +static inline int verify_pmr_vlan_id_0(const uint8_t *pkt_addr, + odp_packet_hdr_t *pkt_hdr, + pmr_term_value_t *term_value) +{ + const _odp_ethhdr_t *eth; + const _odp_vlanhdr_t *vlan; + uint16_t tci; + uint16_t vlan_id; + + if (!pkt_hdr->p.input_flags.vlan_qinq) + return 0; + + eth = (const _odp_ethhdr_t *)(pkt_addr + pkt_hdr->p.l2_offset); + vlan = (const _odp_vlanhdr_t *)(eth + 1); + tci = odp_be_to_cpu_16(vlan->tci); + vlan_id = tci & 0x0fff; + + if (term_value->match.value == (vlan_id & term_value->match.mask)) + return 1; + + return 0; +} + +static inline int verify_pmr_vlan_id_x(const uint8_t *pkt_addr ODP_UNUSED, + odp_packet_hdr_t *pkt_hdr ODP_UNUSED, + pmr_term_value_t *term_value ODP_UNUSED) +{ + const _odp_ethhdr_t *eth; + const _odp_vlanhdr_t *vlan; + uint16_t tci; + uint16_t vlan_id; + + if (!pkt_hdr->p.input_flags.vlan_qinq) + return 0; + + eth = (const _odp_ethhdr_t *)(pkt_addr + pkt_hdr->p.l2_offset); + vlan = (const _odp_vlanhdr_t *)(eth + 1); + vlan++; + tci = odp_be_to_cpu_16(vlan->tci); + vlan_id = tci & 0x0fff; + + if (term_value->match.value == (vlan_id & term_value->match.mask)) + return 1; + + return 0; +} + +static inline int verify_pmr_ipsec_spi(const uint8_t *pkt_addr, + odp_packet_hdr_t *pkt_hdr, + pmr_term_value_t *term_value) +{ + uint32_t spi; + + pkt_addr += pkt_hdr->p.l4_offset; + + if (pkt_hdr->p.input_flags.ipsec_ah) { + const _odp_ahhdr_t *ahhdr = (const _odp_ahhdr_t *)pkt_addr; + + spi = odp_be_to_cpu_32(ahhdr->spi); + } else if (pkt_hdr->p.input_flags.ipsec_esp) { + const _odp_esphdr_t *esphdr = (const _odp_esphdr_t *)pkt_addr; + + spi = odp_be_to_cpu_32(esphdr->spi); + } else { + return 0; + } + + if (term_value->match.value == (spi & term_value->match.mask)) + return 1; + + return 0; +} + +static inline int verify_pmr_ld_vni(const uint8_t *pkt_addr ODP_UNUSED, + odp_packet_hdr_t *pkt_hdr ODP_UNUSED, + pmr_term_value_t *term_value ODP_UNUSED) +{ + ODP_UNIMPLEMENTED(); + return 0; +} + +static inline int verify_pmr_custom_frame(const uint8_t *pkt_addr, + odp_packet_hdr_t *pkt_hdr, + pmr_term_value_t *term_value) +{ + uint64_t val = 0; + uint32_t offset = term_value->offset; + uint32_t val_sz = term_value->val_sz; + + ODP_ASSERT(val_sz <= CLS_PMR_TERM_BYTES_MAX); + + if (packet_len(pkt_hdr) <= offset + val_sz) + return 0; + + memcpy(&val, pkt_addr + offset, val_sz); + if (term_value->match.value == (val & term_value->match.mask)) + return 1; + + return 0; +} + +static inline int verify_pmr_eth_type_0(const uint8_t *pkt_addr, + odp_packet_hdr_t *pkt_hdr, + pmr_term_value_t *term_value) +{ + const _odp_ethhdr_t *eth; + uint16_t ethtype; + + if (!pkt_hdr->p.input_flags.vlan_qinq) + return 0; + + eth = (const _odp_ethhdr_t *)(pkt_addr + pkt_hdr->p.l2_offset); + ethtype = odp_be_to_cpu_16(eth->type); + + if (term_value->match.value == (ethtype & term_value->match.mask)) + return 1; + + return 0; +} + +static inline int verify_pmr_eth_type_x(const uint8_t *pkt_addr, + odp_packet_hdr_t *pkt_hdr, + pmr_term_value_t *term_value) +{ + const _odp_ethhdr_t *eth; + uint16_t ethtype; + const _odp_vlanhdr_t *vlan; + + if (!pkt_hdr->p.input_flags.vlan_qinq) + return 0; + + eth = (const _odp_ethhdr_t *)(pkt_addr + pkt_hdr->p.l2_offset); + vlan = (const _odp_vlanhdr_t *)(eth + 1); + ethtype = odp_be_to_cpu_16(vlan->type); + + if (term_value->match.value == (ethtype & term_value->match.mask)) + return 1; + + return 0; +} + /* * This function goes through each PMR_TERM value in pmr_t structure and calls * verification function for each term.Returns 1 if PMR matches or 0 otherwise. */ -static -int verify_pmr(pmr_t *pmr, const uint8_t *pkt_addr, odp_packet_hdr_t *pkt_hdr) +static int verify_pmr(pmr_t *pmr, const uint8_t *pkt_addr, + odp_packet_hdr_t *pkt_hdr) { int pmr_failure = 0; int num_pmr; diff --git a/platform/linux-generic/pktio/netmap.c b/platform/linux-generic/pktio/netmap.c index 230a9a76b..313ebd5ec 100644 --- a/platform/linux-generic/pktio/netmap.c +++ b/platform/linux-generic/pktio/netmap.c @@ -31,7 +31,6 @@ #include <linux/ethtool.h> #include <linux/sockios.h> #include <odp_classification_datamodel.h> -#include <odp_classification_inlines.h> #include <odp_classification_internal.h> #include <odp_libconfig_internal.h>
diff --git a/platform/linux-generic/pktio/socket_mmap.c b/platform/linux-generic/pktio/socket_mmap.c index 17bebe9a0..6ae0e295f 100644 --- a/platform/linux-generic/pktio/socket_mmap.c +++ b/platform/linux-generic/pktio/socket_mmap.c @@ -34,7 +34,6 @@ #include <odp_debug_internal.h> #include <odp_errno_define.h> #include <odp_classification_datamodel.h> -#include <odp_classification_inlines.h> #include <odp_classification_internal.h> #include <odp/api/hints.h> #include <odp_global_data.h>
-----------------------------------------------------------------------
Summary of changes: example/classifier/odp_classifier.c | 222 +++++++++--- platform/linux-generic/Makefile.am | 1 - .../include/odp_classification_inlines.h | 385 --------------------- platform/linux-generic/include/odp_packet_dpdk.h | 14 +- platform/linux-generic/odp_classification.c | 362 ++++++++++++++++++- platform/linux-generic/pktio/dpdk.c | 81 ++++- platform/linux-generic/pktio/dpdk_parse.c | 38 +- platform/linux-generic/pktio/netmap.c | 1 - platform/linux-generic/pktio/socket_mmap.c | 1 - .../classification/odp_classification_test_pmr.c | 30 +- 10 files changed, 646 insertions(+), 489 deletions(-) delete mode 100644 platform/linux-generic/include/odp_classification_inlines.h
hooks/post-receive