@@ -25,6 +25,7 @@ extern "C" {
#include <odp_packet_internal.h>
#include <odp_packet_io_internal.h>
#include <odp_queue_internal.h>
+#include <protocols/ip.h>
/* Maximum Class Of Service Entry */
#define ODP_COS_MAX_ENTRY 64
@@ -43,7 +44,7 @@ extern "C" {
/* Max L3 QoS Value */
#define ODP_COS_MAX_L3_QOS (1 << ODP_COS_L3_QOS_BITS)
/* Max PMR Term bits */
-#define ODP_PMR_TERM_BYTES_MAX 8
+#define ODP_PMR_TERM_BYTES_MAX 16
/**
Packet Matching Rule Term Value
@@ -67,6 +68,14 @@ typedef struct pmr_term_value {
/** End value of the range */
uint64_t val_end;
} range;
+ struct {
+ uint8_t value[_ODP_IPV6ADDR_LEN];
+ uint8_t mask[_ODP_IPV6ADDR_LEN];
+ } match_ipv6;
+ struct {
+ uint8_t val_start[_ODP_IPV6ADDR_LEN];
+ uint8_t val_end[_ODP_IPV6ADDR_LEN];
+ } range_ipv6;
};
uint32_t offset; /**< Offset if term == ODP_PMR_CUSTOM_FRAME */
uint32_t val_sz; /**< Size of the value to be matched */
@@ -179,19 +179,47 @@ static inline int verify_pmr_dmac(const uint8_t *pkt_addr,
return 0;
}
-static inline int verify_pmr_ipv6_saddr(const uint8_t *pkt_addr ODP_UNUSED,
- odp_packet_hdr_t *pkt_hdr ODP_UNUSED,
- pmr_term_value_t *term_value ODP_UNUSED)
+static inline int verify_pmr_ipv6_saddr(const uint8_t *pkt_addr,
+ odp_packet_hdr_t *pkt_hdr,
+ pmr_term_value_t *term_value)
{
- ODP_UNIMPLEMENTED();
+ const _odp_ipv6hdr_t *ipv6;
+ uint8_t src_addr[_ODP_IPV6ADDR_LEN];
+ uint8_t i;
+
+ if (!packet_hdr_has_ipv6(pkt_hdr))
+ return 0;
+
+ ipv6 = (const _odp_ipv6hdr_t *)(pkt_addr + pkt_hdr->p.l3_offset);
+ memcpy(src_addr, ipv6->src_addr, _ODP_IPV6ADDR_LEN);
+ for (i = 0; i < _ODP_IPV6ADDR_LEN; i++)
+ src_addr[i] = src_addr[i] & term_value->match_ipv6.mask[i];
+
+ if (!memcmp(term_value->match_ipv6.value, src_addr, _ODP_IPV6ADDR_LEN))
+ return 1;
+
return 0;
}
-static inline int verify_pmr_ipv6_daddr(const uint8_t *pkt_addr ODP_UNUSED,
- odp_packet_hdr_t *pkt_hdr ODP_UNUSED,
- pmr_term_value_t *term_value ODP_UNUSED)
+static inline int verify_pmr_ipv6_daddr(const uint8_t *pkt_addr,
+ odp_packet_hdr_t *pkt_hdr,
+ pmr_term_value_t *term_value)
{
- ODP_UNIMPLEMENTED();
+ const _odp_ipv6hdr_t *ipv6;
+ uint8_t dst_addr[_ODP_IPV6ADDR_LEN];
+ uint8_t i;
+
+ if (!packet_hdr_has_ipv6(pkt_hdr))
+ return 0;
+
+ ipv6 = (const _odp_ipv6hdr_t *)(pkt_addr + pkt_hdr->p.l3_offset);
+ memcpy(dst_addr, ipv6->dst_addr, _ODP_IPV6ADDR_LEN);
+ for (i = 0; i < _ODP_IPV6ADDR_LEN; i++)
+ dst_addr[i] = dst_addr[i] & term_value->match_ipv6.mask[i];
+
+ if (!memcmp(term_value->match_ipv6.value, dst_addr, _ODP_IPV6ADDR_LEN))
+ return 1;
+
return 0;
}
@@ -294,6 +294,11 @@ static inline int packet_hdr_has_eth(odp_packet_hdr_t *pkt_hdr)
return pkt_hdr->p.input_flags.eth;
}
+static inline int packet_hdr_has_ipv6(odp_packet_hdr_t *pkt_hdr)
+{
+ return pkt_hdr->p.input_flags.ipv6;
+}
+
static inline void packet_set_ts(odp_packet_hdr_t *pkt_hdr, odp_time_t *ts)
{
if (ts != NULL) {
@@ -447,6 +447,31 @@ static int odp_pmr_create_term(pmr_term_value_t *value,
{
value->term = param->term;
value->range_term = param->range_term;
+ uint8_t i;
+
+ switch (value->term) {
+ case ODP_PMR_SIP6_ADDR:
+ case ODP_PMR_DIP6_ADDR:
+ if (!value->range_term) {
+ memset(value->match_ipv6.value, 0, 16);
+ memset(value->match_ipv6.mask, 0, 16);
+ memcpy(&value->match_ipv6.value, param->match.value,
+ param->val_sz);
+ memcpy(&value->match_ipv6.mask, param->match.mask,
+ param->val_sz);
+ for (i = 0; i < 16; i++)
+ value->match_ipv6.value[i] &= value->match_ipv6.mask[i];
+ } else {
+ memset(value->range_ipv6.val_start, 0, 16);
+ memset(value->range_ipv6.val_end, 0, 16);
+ memcpy(&value->range_ipv6.val_start, param->range.val_start,
+ param->val_sz);
+ memcpy(&value->range_ipv6.val_end, param->range.val_end,
+ param->val_sz);
+ }
+
+ break;
+ default:
if (!value->range_term) {
value->match.value = 0;
value->match.mask = 0;
@@ -461,6 +486,7 @@ static int odp_pmr_create_term(pmr_term_value_t *value,
memcpy(&value->range.val_end, param->range.val_end,
param->val_sz);
}
+ }
value->offset = param->offset;
value->val_sz = param->val_sz;
return 0;
Implements IPV6 src and dst address packet matching rule Signed-off-by: Balasubramanian Manoharan <bala.manoharan@linaro.org> --- .../include/odp_classification_datamodel.h | 11 +++++- .../include/odp_classification_inlines.h | 44 ++++++++++++++++++---- .../linux-generic/include/odp_packet_internal.h | 5 +++ platform/linux-generic/odp_classification.c | 26 +++++++++++++ 4 files changed, 77 insertions(+), 9 deletions(-) -- 1.9.1