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

Reply via email to