Signed-off-by: Benoît Ganne <[email protected]>
---
 .../include/odp_classification_datamodel.h         |  2 ++
 .../include/odp_classification_inlines.h           | 21 +++++++++++
 platform/linux-generic/odp_classification.c        | 42 ++++++++++++----------
 3 files changed, 46 insertions(+), 19 deletions(-)

diff --git a/platform/linux-generic/include/odp_classification_datamodel.h 
b/platform/linux-generic/include/odp_classification_datamodel.h
index cb970f1..4358fca 100644
--- a/platform/linux-generic/include/odp_classification_datamodel.h
+++ b/platform/linux-generic/include/odp_classification_datamodel.h
@@ -57,6 +57,8 @@ typedef struct pmr_term_value {
        odp_pmr_term_e  term;   /* PMR Term */
        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 */
 } 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 a093211..7f13530 100644
--- a/platform/linux-generic/include/odp_classification_inlines.h
+++ b/platform/linux-generic/include/odp_classification_inlines.h
@@ -223,6 +223,27 @@ static inline int verify_pmr_ld_vni(uint8_t *pkt_addr 
ODP_UNUSED,
        ODP_UNIMPLEMENTED();
        return 0;
 }
+
+static inline int verify_pmr_custom_frame(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 (pkt_hdr->frame_len <= offset + val_sz)
+               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_eth_type_0(uint8_t *pkt_addr ODP_UNUSED,
                                        odp_packet_hdr_t *pkt_hdr ODP_UNUSED,
                                        pmr_term_value_t *term_value ODP_UNUSED)
diff --git a/platform/linux-generic/odp_classification.c 
b/platform/linux-generic/odp_classification.c
index b1ec4c5..2faa244 100644
--- a/platform/linux-generic/odp_classification.c
+++ b/platform/linux-generic/odp_classification.c
@@ -441,12 +441,24 @@ int odp_cos_with_l3_qos(odp_pktio_t pktio_in,
        return 0;
 }
 
-odp_pmr_t odp_pmr_create(odp_pmr_term_e term, const void *val,
-                        const void *mask, uint32_t val_sz)
+static void odp_pmr_create_term(pmr_term_value_t *value,
+                               const odp_pmr_match_t *match)
+{
+       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;
+}
+
+odp_pmr_t odp_pmr_create(const odp_pmr_match_t *match)
 {
        pmr_t *pmr;
        odp_pmr_t id;
-       if (val_sz > ODP_PMR_TERM_BYTES_MAX) {
+       if (match->val_sz > ODP_PMR_TERM_BYTES_MAX) {
                ODP_ERR("val_sz greater than max supported limit");
                return ODP_PMR_INVAL;
        }
@@ -457,12 +469,7 @@ odp_pmr_t odp_pmr_create(odp_pmr_term_e term, const void 
*val,
                return ODP_PMR_INVAL;
 
        pmr->s.num_pmr = 1;
-       pmr->s.pmr_term_value[0].term = term;
-       pmr->s.pmr_term_value[0].val =  0;
-       pmr->s.pmr_term_value[0].mask =  0;
-       memcpy(&pmr->s.pmr_term_value[0].val, val, val_sz);
-       memcpy(&pmr->s.pmr_term_value[0].mask, mask, val_sz);
-       pmr->s.pmr_term_value[0].val &= pmr->s.pmr_term_value[0].mask;
+       odp_pmr_create_term(&pmr->s.pmr_term_value[0], match);
        UNLOCK(&pmr->s.lock);
        return id;
 }
@@ -563,7 +570,7 @@ unsigned odp_pmr_terms_avail(void)
        return count;
 }
 
-int odp_pmr_match_set_create(int num_terms, odp_pmr_match_t *terms,
+int odp_pmr_match_set_create(int num_terms, const odp_pmr_match_t *terms,
                             odp_pmr_set_t *pmr_set_id)
 {
        pmr_t *pmr;
@@ -589,15 +596,7 @@ int odp_pmr_match_set_create(int num_terms, 
odp_pmr_match_t *terms,
                val_sz = terms[i].val_sz;
                if (val_sz > ODP_PMR_TERM_BYTES_MAX)
                        continue;
-               pmr->s.pmr_term_value[i].term = terms[i].term;
-               pmr->s.pmr_term_value[i].val = 0;
-               pmr->s.pmr_term_value[i].mask = 0;
-               memcpy(&pmr->s.pmr_term_value[i].val,
-                      terms[i].val, val_sz);
-               memcpy(&pmr->s.pmr_term_value[i].mask,
-                      terms[i].mask, val_sz);
-               pmr->s.pmr_term_value[i].val &= pmr->s
-                       .pmr_term_value[i].mask;
+               odp_pmr_create_term(&pmr->s.pmr_term_value[i], &terms[i]);
                count++;
        }
        *pmr_set_id = id;
@@ -759,6 +758,11 @@ int verify_pmr(pmr_t *pmr, uint8_t *pkt_addr, 
odp_packet_hdr_t *pkt_hdr)
                                               term_value))
                                pmr_failure = 1;
                        break;
+               case ODP_PMR_CUSTOM_FRAME:
+                       if (!verify_pmr_custom_frame(pkt_addr, pkt_hdr,
+                                                    term_value))
+                               pmr_failure = 1;
+                       break;
                case ODP_PMR_INNER_HDR_OFF:
                        break;
                }
-- 
2.5.1


_______________________________________________
lng-odp mailing list
[email protected]
https://lists.linaro.org/mailman/listinfo/lng-odp

Reply via email to