Signed-off-by: huanggaoyang <[email protected]>
---
include/odp/api/classification.h | 16 ++++++----
.../include/odp_classification_datamodel.h | 16 ++++++++--
.../include/odp_classification_inlines.h | 37 +++++++++++++++++++++-
platform/linux-generic/odp_classification.c | 23 ++++++++++++--
4 files changed, 80 insertions(+), 12 deletions(-)
diff --git a/include/odp/api/classification.h b/include/odp/api/classification.h
index c9493c2..80c1412 100644
--- a/include/odp/api/classification.h
+++ b/include/odp/api/classification.h
@@ -4,7 +4,6 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
-
/**
* @file
*
@@ -18,13 +17,11 @@
extern "C" {
#endif
-
/** @defgroup odp_classification ODP CLASSIFICATION
* Classification operations.
* @{
*/
-
/**
* @typedef odp_cos_t
* ODP Class of service handle
@@ -222,7 +219,6 @@ int odp_cos_with_l3_qos(odp_pktio_t pktio_in,
odp_cos_t cos_table[],
odp_bool_t l3_preference);
-
/**
* @typedef odp_cos_flow_set_t
* Set of header fields that take part in flow signature hash calculation:
@@ -267,7 +263,11 @@ typedef enum odp_pmr_term {
expected value, and its size. They must be
applied before any other PMR.
(*val=uint8_t[val_sz])*/
-
+ ODP_PMR_CUSTOM_RANGE, /**< Custom rang match rule. The match means:
+ value_min <= custom_value <= value_max.
+ The custom_value is defined by the offset,
+ the value size and mask.
+ */
/** Inner header may repeat above values with this offset */
ODP_PMR_INNER_HDR_OFF = 32
} odp_pmr_term_e;
@@ -277,7 +277,11 @@ typedef enum odp_pmr_term {
*/
typedef struct odp_pmr_match_t {
odp_pmr_term_e term; /**< PMR term value to be matched */
- const void *val; /**< Value to be matched */
+ const void *val; /**< Value to be matched
+ or value_min in ODP_PMR_CUSTOM_RANGE */
+ const void *val_max; /**< value_max in Range Match rule,
+ will be ignored if not
+ ODP_PMR_CUSTOM_RANGE */
const void *mask; /**< Masked set of bits to be matched */
uint32_t val_sz; /**< Size of the term value */
uint32_t offset; /**< User-defined offset in packet
diff --git a/platform/linux-generic/include/odp_classification_datamodel.h
b/platform/linux-generic/include/odp_classification_datamodel.h
index 5b65202..635f2ea 100644
--- a/platform/linux-generic/include/odp_classification_datamodel.h
+++ b/platform/linux-generic/include/odp_classification_datamodel.h
@@ -4,7 +4,6 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
-
/**
* @file
*
@@ -48,6 +47,14 @@ extern "C" {
#define ODP_PMR_TERM_BYTES_MAX 8
/**
+Range Match Value
+**/
+struct pmr_value_range {
+ uint64_t val_min;
+ uint64_t val_max;
+};
+
+/**
Packet Matching Rule Term Value
Stores the Term and Value mapping for a PMR.
@@ -55,7 +62,11 @@ The maximum size of value currently supported in 64 bits
**/
typedef struct pmr_term_value {
odp_pmr_term_e term; /* PMR Term */
- uint64_t val; /**< Value to be matched */
+ union {
+ /**< value range to be matched */
+ struct pmr_value_range val_rg;
+ uint64_t val; /**< Value to be matched */
+ };
uint64_t mask; /**< Masked set of bits to be matched */
uint32_t offset; /**< Offset if term == ODP_PMR_CUSTOM_FRAME */
uint32_t val_sz; /**< Size of the value to be matched */
@@ -83,7 +94,6 @@ typedef union cos_u {
uint8_t pad[ODP_CACHE_LINE_SIZE_ROUNDUP(sizeof(struct cos_s))];
} cos_t;
-
/**
Packet Matching Rule
diff --git a/platform/linux-generic/include/odp_classification_inlines.h
b/platform/linux-generic/include/odp_classification_inlines.h
index 5f0b564..c353e17 100644
--- a/platform/linux-generic/include/odp_classification_inlines.h
+++ b/platform/linux-generic/include/odp_classification_inlines.h
@@ -4,7 +4,6 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
-
/**
* @file
*
@@ -47,6 +46,7 @@ static inline int verify_pmr_ip_proto(const uint8_t *pkt_addr,
{
const odph_ipv4hdr_t *ip;
uint8_t proto;
+
if (!pkt_hdr->input_flags.ipv4)
return 0;
ip = (const odph_ipv4hdr_t *)(pkt_addr + pkt_hdr->l3_offset);
@@ -63,6 +63,7 @@ static inline int verify_pmr_ipv4_saddr(const uint8_t
*pkt_addr,
{
const odph_ipv4hdr_t *ip;
uint32_t ipaddr;
+
if (!pkt_hdr->input_flags.ipv4)
return 0;
ip = (const odph_ipv4hdr_t *)(pkt_addr + pkt_hdr->l3_offset);
@@ -79,6 +80,7 @@ static inline int verify_pmr_ipv4_daddr(const uint8_t
*pkt_addr,
{
const odph_ipv4hdr_t *ip;
uint32_t ipaddr;
+
if (!pkt_hdr->input_flags.ipv4)
return 0;
ip = (const odph_ipv4hdr_t *)(pkt_addr + pkt_hdr->l3_offset);
@@ -95,6 +97,7 @@ static inline int verify_pmr_tcp_sport(const uint8_t
*pkt_addr,
{
uint16_t sport;
const odph_tcphdr_t *tcp;
+
if (!pkt_hdr->input_flags.tcp)
return 0;
tcp = (const odph_tcphdr_t *)(pkt_addr + pkt_hdr->l4_offset);
@@ -111,6 +114,7 @@ static inline int verify_pmr_tcp_dport(const uint8_t
*pkt_addr,
{
uint16_t dport;
const odph_tcphdr_t *tcp;
+
if (!pkt_hdr->input_flags.tcp)
return 0;
tcp = (const odph_tcphdr_t *)(pkt_addr + pkt_hdr->l4_offset);
@@ -127,6 +131,7 @@ static inline int verify_pmr_udp_dport(const uint8_t
*pkt_addr,
{
uint16_t dport;
const odph_udphdr_t *udp;
+
if (!pkt_hdr->input_flags.udp)
return 0;
udp = (const odph_udphdr_t *)(pkt_addr + pkt_hdr->l4_offset);
@@ -245,12 +250,41 @@ static inline int verify_pmr_custom_frame(const uint8_t
*pkt_addr,
return 0;
memcpy(&val, pkt_addr + offset, val_sz);
+
if (term_value->val == (val & term_value->mask))
return 1;
return 0;
}
+static inline int verify_pmr_custom_range(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 <= ODP_PMR_TERM_BYTES_MAX);
+
+ if (packet_len(pkt_hdr) <= offset + val_sz)
+ return 0;
+
+ memcpy(&val, pkt_addr + offset, val_sz);
+#if ODP_BYTE_ORDER == ODP_LITTLE_ENDIAN
+ val = odp_be_to_cpu_64(val);
+ val = val >> (sizeof(uint64_t) * 8 - val_sz * 8);
+#endif
+
+ val &= term_value->mask;
+ if (term_value->val_rg.val_min <= val &&
+ val <= term_value->val_rg.val_max)
+ return 1;
+
+ return 0;
+}
+
static inline int verify_pmr_eth_type_0(const uint8_t *pkt_addr ODP_UNUSED,
odp_packet_hdr_t *pkt_hdr ODP_UNUSED,
pmr_term_value_t *term_value ODP_UNUSED)
@@ -266,6 +300,7 @@ static inline int verify_pmr_eth_type_x(const uint8_t
*pkt_addr ODP_UNUSED,
ODP_UNIMPLEMENTED();
return 0;
}
+
#ifdef __cplusplus
}
#endif
diff --git a/platform/linux-generic/odp_classification.c
b/platform/linux-generic/odp_classification.c
index da195ad..533fbec 100644
--- a/platform/linux-generic/odp_classification.c
+++ b/platform/linux-generic/odp_classification.c
@@ -482,9 +482,18 @@ static void odp_pmr_create_term(pmr_term_value_t *value,
value->val_sz = match->val_sz;
value->val = 0;
value->mask = 0;
- memcpy(&value->val, match->val, match->val_sz);
+
memcpy(&value->mask, match->mask, match->val_sz);
- value->val &= value->mask;
+
+ if (match->term == ODP_PMR_CUSTOM_RANGE) {
+ memcpy(&value->val_rg.val_min, match->val, match->val_sz);
+ memcpy(&value->val_rg.val_max, match->val_max, match->val_sz);
+ value->val_rg.val_min &= value->mask;
+ value->val_rg.val_max &= value->mask;
+ } else {
+ memcpy(&value->val, match->val, match->val_sz);
+ value->val &= value->mask;
+ }
}
odp_pmr_t odp_pmr_create(const odp_pmr_match_t *match)
@@ -495,6 +504,11 @@ odp_pmr_t odp_pmr_create(const odp_pmr_match_t *match)
ODP_ERR("val_sz greater than max supported limit");
return ODP_PMR_INVAL;
}
+ if ((ODP_PMR_CUSTOM_RANGE == match->term && NULL == match->val_max) ||
+ NULL == match->val) {
+ ODP_ERR("NULL pointer");
+ return ODP_PMR_INVAL;
+ }
id = alloc_pmr(&pmr);
/*if alloc_pmr() is successful it returns with lock acquired*/
@@ -832,6 +846,11 @@ int verify_pmr(pmr_t *pmr, const uint8_t *pkt_addr,
odp_packet_hdr_t *pkt_hdr)
term_value))
pmr_failure = 1;
break;
+ case ODP_PMR_CUSTOM_RANGE:
+ if (!verify_pmr_custom_range(pkt_addr, pkt_hdr,
+ term_value))
+ pmr_failure = 1;
+ break;
case ODP_PMR_INNER_HDR_OFF:
break;
}
--
1.9.1
_______________________________________________
lng-odp mailing list
[email protected]
https://lists.linaro.org/mailman/listinfo/lng-odp