Implements classification capability and PMR range functionality feature.

Signed-off-by: Balasubramanian Manoharan <bala.manoha...@linaro.org>
---
 .../include/odp_classification_datamodel.h         | 17 +++-
 .../include/odp_classification_inlines.h           | 24 +++---
 platform/linux-generic/odp_classification.c        | 92 +++++++++++++---------
 3 files changed, 81 insertions(+), 52 deletions(-)

diff --git a/platform/linux-generic/include/odp_classification_datamodel.h 
b/platform/linux-generic/include/odp_classification_datamodel.h
index 63f3ec6..7a1dd5c 100644
--- a/platform/linux-generic/include/odp_classification_datamodel.h
+++ b/platform/linux-generic/include/odp_classification_datamodel.h
@@ -53,8 +53,21 @@ The maximum size of value currently supported in 64 bits
 **/
 typedef struct pmr_term_value {
        odp_pmr_term_t  term;   /* PMR Term */
-       uint64_t        val;    /**< Value to be matched */
-       uint64_t        mask;   /**< Masked set of bits to be matched */
+       odp_bool_t      range_term;
+       union {
+               struct {
+                       /** Value to be matched */
+                       uint64_t        value;
+                       /** Masked set of bits to be matched */
+                       uint64_t        mask;
+               } match;
+               struct {
+                       /** Start value of the range */
+                       uint64_t        val_start;
+                       /** End value of the range */
+                       uint64_t        val_end;
+               } range;
+       };
        uint32_t        offset; /**< Offset if term == ODP_PMR_CUSTOM_FRAME */
        uint32_t        val_sz; /**< Size of the value to be matched */
 } pmr_term_value_t;
diff --git a/platform/linux-generic/include/odp_classification_inlines.h 
b/platform/linux-generic/include/odp_classification_inlines.h
index bac5b48..b8b04ce 100644
--- a/platform/linux-generic/include/odp_classification_inlines.h
+++ b/platform/linux-generic/include/odp_classification_inlines.h
@@ -34,8 +34,8 @@ 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->val == (packet_len(pkt_hdr) &
-                                    term_value->mask))
+       if (term_value->match.value == (packet_len(pkt_hdr) &
+                                    term_value->match.mask))
                return 1;
 
        return 0;
@@ -51,7 +51,7 @@ static inline int verify_pmr_ip_proto(const uint8_t *pkt_addr,
                return 0;
        ip = (const odph_ipv4hdr_t *)(pkt_addr + pkt_hdr->l3_offset);
        proto = ip->proto;
-       if (term_value->val == (proto & term_value->mask))
+       if (term_value->match.value == (proto & term_value->match.mask))
                return 1;
 
        return 0;
@@ -67,7 +67,7 @@ static inline int verify_pmr_ipv4_saddr(const uint8_t 
*pkt_addr,
                return 0;
        ip = (const odph_ipv4hdr_t *)(pkt_addr + pkt_hdr->l3_offset);
        ipaddr = odp_be_to_cpu_32(ip->src_addr);
-       if (term_value->val == (ipaddr & term_value->mask))
+       if (term_value->match.value == (ipaddr & term_value->match.mask))
                return 1;
 
        return 0;
@@ -83,7 +83,7 @@ static inline int verify_pmr_ipv4_daddr(const uint8_t 
*pkt_addr,
                return 0;
        ip = (const odph_ipv4hdr_t *)(pkt_addr + pkt_hdr->l3_offset);
        ipaddr = odp_be_to_cpu_32(ip->dst_addr);
-       if (term_value->val == (ipaddr & term_value->mask))
+       if (term_value->match.value == (ipaddr & term_value->match.mask))
                return 1;
 
        return 0;
@@ -99,7 +99,7 @@ static inline int verify_pmr_tcp_sport(const uint8_t 
*pkt_addr,
                return 0;
        tcp = (const odph_tcphdr_t *)(pkt_addr + pkt_hdr->l4_offset);
        sport = odp_be_to_cpu_16(tcp->src_port);
-       if (term_value->val == (sport & term_value->mask))
+       if (term_value->match.value == (sport & term_value->match.mask))
                return 1;
 
        return 0;
@@ -115,7 +115,7 @@ static inline int verify_pmr_tcp_dport(const uint8_t 
*pkt_addr,
                return 0;
        tcp = (const odph_tcphdr_t *)(pkt_addr + pkt_hdr->l4_offset);
        dport = odp_be_to_cpu_16(tcp->dst_port);
-       if (term_value->val == (dport & term_value->mask))
+       if (term_value->match.value == (dport & term_value->match.mask))
                return 1;
 
        return 0;
@@ -131,7 +131,7 @@ static inline int verify_pmr_udp_dport(const uint8_t 
*pkt_addr,
                return 0;
        udp = (const odph_udphdr_t *)(pkt_addr + pkt_hdr->l4_offset);
        dport = odp_be_to_cpu_16(udp->dst_port);
-       if (term_value->val == (dport & term_value->mask))
+       if (term_value->match.value == (dport & term_value->match.mask))
                        return 1;
 
        return 0;
@@ -148,7 +148,7 @@ static inline int verify_pmr_udp_sport(const uint8_t 
*pkt_addr,
                return 0;
        udp = (const odph_udphdr_t *)(pkt_addr + pkt_hdr->l4_offset);
        sport = odp_be_to_cpu_16(udp->src_port);
-       if (term_value->val == (sport & term_value->mask))
+       if (term_value->match.value == (sport & term_value->match.mask))
                return 1;
 
        return 0;
@@ -174,7 +174,7 @@ static inline int verify_pmr_dmac(const uint8_t *pkt_addr,
        if (dmac_be != dmac)
                dmac = dmac >> (64 - (ODPH_ETHADDR_LEN * 8));
 
-       if (term_value->val == (dmac & term_value->mask))
+       if (term_value->match.value == (dmac & term_value->match.mask))
                return 1;
        return 0;
 }
@@ -234,7 +234,7 @@ static inline int verify_pmr_ipsec_spi(const uint8_t 
*pkt_addr,
                return 0;
        }
 
-       if (term_value->val == (spi & term_value->mask))
+       if (term_value->match.value == (spi & term_value->match.mask))
                return 1;
 
        return 0;
@@ -262,7 +262,7 @@ 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))
+       if (term_value->match.value == (val & term_value->match.mask))
                return 1;
 
        return 0;
diff --git a/platform/linux-generic/odp_classification.c 
b/platform/linux-generic/odp_classification.c
index f5e4673..c991fd9 100644
--- a/platform/linux-generic/odp_classification.c
+++ b/platform/linux-generic/odp_classification.c
@@ -124,6 +124,34 @@ void odp_cls_cos_param_init(odp_cls_cos_param_t *param)
        param->drop_policy = ODP_COS_DROP_NEVER;
 }
 
+void odp_cls_pmr_param_init(odp_pmr_param_t *param)
+{
+       memset(param, 0, sizeof(odp_pmr_param_t));
+}
+
+int odp_cls_capability(odp_cls_capability_t *capability)
+{
+       unsigned count = 0;
+
+       for (int i = 0; i < ODP_PMR_MAX_ENTRY; i++)
+               if (!pmr_tbl->pmr[i].s.valid)
+                       count++;
+
+       capability->max_pmr_terms = ODP_PMR_MAX_ENTRY;
+       capability->available_pmr_terms = count;
+       capability->max_cos = ODP_COS_MAX_ENTRY;
+       capability->pmr_range_supported = false;
+       capability->pmr_terms.all_bits = 0;
+       capability->pmr_terms.proto.ip_proto = 1;
+       capability->pmr_terms.proto.udp_dport = 1;
+       capability->pmr_terms.proto.udp_sport = 1;
+       capability->pmr_terms.proto.tcp_dport = 1;
+       capability->pmr_terms.proto.tcp_sport = 1;
+       capability->pmr_terms.proto.sip_addr = 1;
+       capability->pmr_terms.proto.dip_addr = 1;
+       return 0;
+}
+
 odp_cos_t odp_cls_cos_create(const char *name, odp_cls_cos_param_t *param)
 {
        int i, j;
@@ -409,17 +437,28 @@ int odp_cos_with_l3_qos(odp_pktio_t pktio_in,
        return 0;
 }
 
-static void odp_pmr_create_term(pmr_term_value_t *value,
-                               const odp_pmr_match_t *match)
+static int odp_pmr_create_term(pmr_term_value_t *value,
+                              const odp_pmr_param_t *param)
 {
-       value->term = match->term;
-       value->offset = match->offset;
-       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;
+       value->term = param->term;
+       value->range_term = param->range_term;
+       if (!value->range_term) {
+               value->match.value = 0;
+               value->match.mask = 0;
+               memcpy(&value->match.value, param->match.value, param->val_sz);
+               memcpy(&value->match.mask, param->match.mask, param->val_sz);
+               value->match.value &= value->match.mask;
+       } else {
+               value->range.val_start = 0;
+               value->range.val_end = 0;
+               memcpy(&value->range.val_start, param->range.val_start,
+                      param->val_sz);
+               memcpy(&value->range.val_end, param->range.val_end,
+                      param->val_sz);
+       }
+       value->offset = param->offset;
+       value->val_sz = param->val_sz;
+       return 0;
 }
 
 int odp_cls_pmr_destroy(odp_pmr_t pmr_id)
@@ -452,33 +491,7 @@ no_rule:
        return 0;
 }
 
-unsigned long long odp_pmr_terms_cap(void)
-{
-       unsigned long long term_cap = 0;
-
-       term_cap |= (1 << ODP_PMR_LEN);
-       term_cap |= (1 << ODP_PMR_IPPROTO);
-       term_cap |= (1 << ODP_PMR_UDP_DPORT);
-       term_cap |= (1 << ODP_PMR_TCP_DPORT);
-       term_cap |= (1 << ODP_PMR_UDP_SPORT);
-       term_cap |= (1 << ODP_PMR_TCP_SPORT);
-       term_cap |= (1 << ODP_PMR_SIP_ADDR);
-       term_cap |= (1 << ODP_PMR_DIP_ADDR);
-       return term_cap;
-}
-
-unsigned odp_pmr_terms_avail(void)
-{
-       unsigned count = 0;
-       int i;
-
-       for (i = 0; i < ODP_PMR_MAX_ENTRY; i++)
-               if (!pmr_tbl->pmr[i].s.valid)
-                       count++;
-       return count;
-}
-
-odp_pmr_t odp_cls_pmr_create(const odp_pmr_match_t *terms, int num_terms,
+odp_pmr_t odp_cls_pmr_create(const odp_pmr_param_t *terms, int num_terms,
                             odp_cos_t src_cos, odp_cos_t dst_cos)
 {
        pmr_t *pmr;
@@ -512,10 +525,13 @@ odp_pmr_t odp_cls_pmr_create(const odp_pmr_match_t 
*terms, int num_terms,
                val_sz = terms[i].val_sz;
                if (val_sz > ODP_PMR_TERM_BYTES_MAX) {
                        pmr->s.valid = 0;
+                       return ODP_PMR_INVAL;
+               }
+               if (0 > odp_pmr_create_term(&pmr->s.pmr_term_value[i],
+                                           &terms[i])) {
                        UNLOCK(&pmr->s.lock);
                        return ODP_PMR_INVAL;
                }
-               odp_pmr_create_term(&pmr->s.pmr_term_value[i], &terms[i]);
        }
 
        loc = odp_atomic_fetch_inc_u32(&cos_src->s.num_rule);
-- 
1.9.1

_______________________________________________
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp

Reply via email to