@@ -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;
@@ -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;
@@ -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);
Implements classification capability and PMR range functionality feature. Signed-off-by: Balasubramanian Manoharan <bala.manoharan@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(-)