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