This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "".
The branch, master has been updated via 6ad530311e9cbd5fd77b958e78921e80fbbfa943 (commit) via aa3bbe4da1639ac4649c7d34ae75b0230ade70b2 (commit) from 022cf4a7136c7369ee5f29f5d245ac8d052135e6 (commit)
Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below.
- Log ----------------------------------------------------------------- commit 6ad530311e9cbd5fd77b958e78921e80fbbfa943 Author: Balasubramanian Manoharan bala.manoharan@linaro.org Date: Fri Feb 3 18:15:45 2017 +0530
validation: classification: add test case for ipv6 src and dst addr
Adds test case for ipv6 source and destination address matching
Signed-off-by: Balasubramanian Manoharan bala.manoharan@linaro.org Reviewed-and-tested-by: Bill Fischofer bill.fischofer@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/test/common_plat/validation/api/classification/classification.h b/test/common_plat/validation/api/classification/classification.h index d73c821..0192e24 100644 --- a/test/common_plat/validation/api/classification/classification.h +++ b/test/common_plat/validation/api/classification/classification.h @@ -55,6 +55,27 @@ #define DATA_MAGIC 0x01020304 #define TEST_SEQ_INVALID ((uint32_t)~0)
+/* Test packet Time-to-live */ +#define DEFAULT_TTL 128 + +/* Test packet default DSCP value */ +#define LOW_DROP_PRECEDENCE 0x02 +#define MEDIUM_DROP_PRECEDENCE 0x04 +#define HIGH_DROP_PRECEDENCE 0x06 +#define DROP_PRECEDENCE_MASK 0x06 +#define DSCP_CLASS1 0x08 +#define DSCP_CLASS2 0x10 +#define DSCP_CLASS3 0x18 +#define DSCP_CLASS4 0x20 +#define DEFAULT_DSCP (DSCP_CLASS2 | LOW_DROP_PRECEDENCE) + +/* Test packet default ECN */ +#define DEFAULT_ECN ODPH_IP_ECN_ECT0 + +/* Test packet default TOS */ +#define DEFAULT_TOS ((DEFAULT_DSCP << ODPH_IP_TOS_DSCP_SHIFT) | \ + DEFAULT_ECN) + /* test functions: */ void classification_test_create_cos(void); void classification_test_destroy_cos(void); diff --git a/test/common_plat/validation/api/classification/odp_classification_common.c b/test/common_plat/validation/api/classification/odp_classification_common.c index f7ec6e5..0ca9083 100644 --- a/test/common_plat/validation/api/classification/odp_classification_common.c +++ b/test/common_plat/validation/api/classification/odp_classification_common.c @@ -14,6 +14,16 @@ typedef struct cls_test_packet { odp_u32be_t seq; } cls_test_packet_t;
+static uint8_t IPV6_SRC_ADDR[ODPH_IPV6ADDR_LEN] = { + /* I.e. ::ffff:10.0.0.1 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 10, 0, 0, 1 +}; + +static uint8_t IPV6_DST_ADDR[ODPH_IPV6ADDR_LEN] = { + /* I.e. ::ffff:10.0.0.100 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 10, 0, 0, 100 +}; + odp_pktio_t create_pktio(odp_queue_type_t q_type, odp_pool_t pool) { odp_pktio_t pktio; @@ -211,30 +221,30 @@ odp_pool_t pool_create(const char *poolname) return odp_pool_create(poolname, ¶m); }
-odp_packet_t create_packet(odp_pool_t pool, bool vlan, - odp_atomic_u32_t *seq, bool flag_udp) -{ - return create_packet_len(pool, vlan, seq, flag_udp, 0); -} - -odp_packet_t create_packet_len(odp_pool_t pool, bool vlan, - odp_atomic_u32_t *seq, bool flag_udp, - uint16_t len) +odp_packet_t create_packet(cls_packet_info_t pkt_info) { uint32_t seqno; odph_ethhdr_t *ethhdr; odph_udphdr_t *udp; odph_tcphdr_t *tcp; odph_ipv4hdr_t *ip; + odph_ipv6hdr_t *ipv6; uint16_t payload_len; uint64_t src_mac = CLS_DEFAULT_SMAC; uint64_t dst_mac = CLS_DEFAULT_DMAC; uint64_t dst_mac_be; uint32_t addr = 0; uint32_t mask; - int offset; odp_packet_t pkt; int packet_len = 0; + uint32_t version, tc, flow, ver_tc_flow; + uint8_t *buf, next_hdr; + uint32_t l4_len, l3_len, l2_len, l3_offset, l4_offset; + uint16_t vlan_hdr_len = 0; + uint16_t l2_hdr_len = 0; + uint16_t l3_hdr_len = 0; + uint16_t l4_hdr_len = 0; + uint16_t eth_type;
/* 48 bit ethernet address needs to be left shifted for proper value after changing to be*/ @@ -242,77 +252,85 @@ odp_packet_t create_packet_len(odp_pool_t pool, bool vlan, if (dst_mac != dst_mac_be) dst_mac_be = dst_mac_be >> (64 - 8 * ODPH_ETHADDR_LEN);
- payload_len = sizeof(cls_test_packet_t) + len; - packet_len += ODPH_ETHHDR_LEN; - packet_len += ODPH_IPV4HDR_LEN; - if (flag_udp) - packet_len += ODPH_UDPHDR_LEN; - else - packet_len += ODPH_TCPHDR_LEN; - packet_len += payload_len; - - if (vlan) - packet_len += ODPH_VLANHDR_LEN; - - pkt = odp_packet_alloc(pool, packet_len); + payload_len = sizeof(cls_test_packet_t) + pkt_info.len; + seqno = odp_atomic_fetch_inc_u32(pkt_info.seq); + + vlan_hdr_len = pkt_info.vlan ? ODPH_VLANHDR_LEN : 0; + l3_hdr_len = pkt_info.ipv6 ? ODPH_IPV6HDR_LEN : ODPH_IPV4HDR_LEN; + l4_hdr_len = pkt_info.udp ? ODPH_UDPHDR_LEN : ODPH_TCPHDR_LEN; + eth_type = pkt_info.ipv6 ? ODPH_ETHTYPE_IPV6 : ODPH_ETHTYPE_IPV4; + next_hdr = pkt_info.udp ? ODPH_IPPROTO_UDP : ODPH_IPPROTO_TCP; + l2_hdr_len = ODPH_ETHHDR_LEN + vlan_hdr_len; + l4_len = l4_hdr_len + payload_len; + l3_len = l3_hdr_len + l4_len; + l2_len = l2_hdr_len + l3_len; + packet_len = l2_len; + + pkt = odp_packet_alloc(pkt_info.pool, packet_len); CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
/* Ethernet Header */ - offset = 0; - odp_packet_l2_offset_set(pkt, offset); + buf = odp_packet_data(pkt); + odp_packet_l2_offset_set(pkt, 0); ethhdr = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, NULL); memcpy(ethhdr->src.addr, &src_mac, ODPH_ETHADDR_LEN); memcpy(ethhdr->dst.addr, &dst_mac_be, ODPH_ETHADDR_LEN); - offset += sizeof(odph_ethhdr_t); - if (vlan) { + if (pkt_info.vlan) { /* Default vlan header */ odph_vlanhdr_t *vlan_hdr; - + odp_packet_has_vlan_set(pkt, 1); ethhdr->type = odp_cpu_to_be_16(ODPH_ETHTYPE_VLAN); vlan_hdr = (odph_vlanhdr_t *)(ethhdr + 1); vlan_hdr->tci = odp_cpu_to_be_16(0); - vlan_hdr->type = odp_cpu_to_be_16(ODPH_ETHTYPE_IPV4); - offset += sizeof(odph_vlanhdr_t); + vlan_hdr->type = odp_cpu_to_be_16(eth_type); } else { - ethhdr->type = odp_cpu_to_be_16(ODPH_ETHTYPE_IPV4); + ethhdr->type = odp_cpu_to_be_16(eth_type); }
- odp_packet_l3_offset_set(pkt, offset); - - /* ipv4 */ - ip = (odph_ipv4hdr_t *)odp_packet_l3_ptr(pkt, NULL); - - parse_ipv4_string(CLS_DEFAULT_DADDR, &addr, &mask); - ip->dst_addr = odp_cpu_to_be_32(addr); - - parse_ipv4_string(CLS_DEFAULT_SADDR, &addr, &mask); - ip->src_addr = odp_cpu_to_be_32(addr); - ip->ver_ihl = ODPH_IPV4 << 4 | ODPH_IPV4HDR_IHL_MIN; - odp_packet_has_ipv4_set(pkt, 1); - - if (flag_udp) - ip->tot_len = odp_cpu_to_be_16(ODPH_UDPHDR_LEN + payload_len + - ODPH_IPV4HDR_LEN); - else - ip->tot_len = odp_cpu_to_be_16(ODPH_TCPHDR_LEN + payload_len + - ODPH_IPV4HDR_LEN); - - ip->ttl = 128; - if (flag_udp) - ip->proto = ODPH_IPPROTO_UDP; - else - ip->proto = ODPH_IPPROTO_TCP; + l3_offset = l2_hdr_len; + odp_packet_l3_offset_set(pkt, l3_offset); + + if (!pkt_info.ipv6) { + /* ipv4 */ + ip = (odph_ipv4hdr_t *)(buf + l3_offset); + + parse_ipv4_string(CLS_DEFAULT_DADDR, &addr, &mask); + ip->dst_addr = odp_cpu_to_be_32(addr); + + parse_ipv4_string(CLS_DEFAULT_SADDR, &addr, &mask); + ip->src_addr = odp_cpu_to_be_32(addr); + ip->ver_ihl = ODPH_IPV4 << 4 | ODPH_IPV4HDR_IHL_MIN; + ip->id = odp_cpu_to_be_16(seqno); + ip->chksum = 0; + ip->chksum = odph_ipv4_csum_update(pkt); + ip->proto = next_hdr; + ip->tot_len = odp_cpu_to_be_16(l3_len); + ip->ttl = DEFAULT_TTL; + odp_packet_has_ipv4_set(pkt, 1); + } else { + /* ipv6 */ + odp_packet_has_ipv6_set(pkt, 1); + ipv6 = (odph_ipv6hdr_t *)odp_packet_l3_ptr(pkt, NULL); + version = ODPH_IPV6 << ODPH_IPV6HDR_VERSION_SHIFT; + tc = DEFAULT_TOS << ODPH_IPV6HDR_TC_SHIFT; + flow = seqno << ODPH_IPV6HDR_FLOW_LABEL_SHIFT; + ver_tc_flow = version | tc | flow; + + ipv6->ver_tc_flow = odp_cpu_to_be_32(ver_tc_flow); + ipv6->payload_len = odp_cpu_to_be_16(l4_len); + ipv6->next_hdr = next_hdr; + ipv6->hop_limit = DEFAULT_TTL; + memcpy(ipv6->src_addr, IPV6_SRC_ADDR, ODPH_IPV6ADDR_LEN); + memcpy(ipv6->dst_addr, IPV6_DST_ADDR, ODPH_IPV6ADDR_LEN); + }
- seqno = odp_atomic_fetch_inc_u32(seq); - ip->id = odp_cpu_to_be_16(seqno); - ip->chksum = 0; - ip->chksum = odph_ipv4_csum_update(pkt); - offset += ODPH_IPV4HDR_LEN; + l4_offset = l3_offset + l3_hdr_len; + odp_packet_l4_offset_set(pkt, l4_offset); + tcp = (odph_tcphdr_t *)(buf + l4_offset); + udp = (odph_udphdr_t *)(buf + l4_offset);
/* udp */ - if (flag_udp) { - odp_packet_l4_offset_set(pkt, offset); - udp = (odph_udphdr_t *)odp_packet_l4_ptr(pkt, NULL); + if (pkt_info.udp) { udp->src_port = odp_cpu_to_be_16(CLS_DEFAULT_SPORT); udp->dst_port = odp_cpu_to_be_16(CLS_DEFAULT_DPORT); udp->length = odp_cpu_to_be_16(payload_len + ODPH_UDPHDR_LEN); @@ -323,8 +341,6 @@ odp_packet_t create_packet_len(odp_pool_t pool, bool vlan, return ODP_PACKET_INVALID; } } else { - odp_packet_l4_offset_set(pkt, offset); - tcp = (odph_tcphdr_t *)odp_packet_l4_ptr(pkt, NULL); tcp->src_port = odp_cpu_to_be_16(CLS_DEFAULT_SPORT); tcp->dst_port = odp_cpu_to_be_16(CLS_DEFAULT_DPORT); tcp->hl = ODPH_TCPHDR_LEN / 4; @@ -334,6 +350,7 @@ odp_packet_t create_packet_len(odp_pool_t pool, bool vlan, LOG_ERR("odph_udp_tcp_chksum failed\n"); return ODP_PACKET_INVALID; } + }
/* set pkt sequence number */ diff --git a/test/common_plat/validation/api/classification/odp_classification_test_pmr.c b/test/common_plat/validation/api/classification/odp_classification_test_pmr.c index a54954e..c714549 100644 --- a/test/common_plat/validation/api/classification/odp_classification_test_pmr.c +++ b/test/common_plat/validation/api/classification/odp_classification_test_pmr.c @@ -9,10 +9,11 @@ #include <odp_cunit_common.h>
static odp_pool_t pkt_pool; - /** sequence number of IP packets */ odp_atomic_u32_t seq;
+static cls_packet_info_t default_pkt_info; + int classification_suite_pmr_init(void) { pkt_pool = pool_create("classification_pmr_pool"); @@ -21,7 +22,12 @@ int classification_suite_pmr_init(void) return -1; }
+ memset(&default_pkt_info, 0, sizeof(cls_packet_info_t)); + default_pkt_info.pool = pkt_pool; + default_pkt_info.seq = &seq; + odp_atomic_init_u32(&seq, 0); + return 0; }
@@ -103,7 +109,6 @@ void classification_test_pmr_term_tcp_dport(void) odp_pool_t pool_recv; odp_pmr_param_t pmr_param; odph_ethhdr_t *eth; - val = CLS_DEFAULT_DPORT; mask = 0xffff; seqno = 0; @@ -140,7 +145,7 @@ void classification_test_pmr_term_tcp_dport(void) pmr = odp_cls_pmr_create(&pmr_param, 1, default_cos, cos); CU_ASSERT(pmr != ODP_PMR_INVAL);
- pkt = create_packet(pkt_pool, false, &seq, false); + pkt = create_packet(default_pkt_info); CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); seqno = cls_pkt_get_seq(pkt); CU_ASSERT(seqno != TEST_SEQ_INVALID); @@ -163,7 +168,7 @@ void classification_test_pmr_term_tcp_dport(void) odp_packet_free(pkt);
/* Other packets are delivered to default queue */ - pkt = create_packet(pkt_pool, false, &seq, false); + pkt = create_packet(default_pkt_info); CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); seqno = cls_pkt_get_seq(pkt); CU_ASSERT(seqno != TEST_SEQ_INVALID); @@ -254,7 +259,7 @@ void classification_test_pmr_term_tcp_sport(void) pmr = odp_cls_pmr_create(&pmr_param, 1, default_cos, cos); CU_ASSERT(pmr != ODP_PMR_INVAL);
- pkt = create_packet(pkt_pool, false, &seq, false); + pkt = create_packet(default_pkt_info); CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); seqno = cls_pkt_get_seq(pkt); CU_ASSERT(seqno != TEST_SEQ_INVALID); @@ -275,7 +280,7 @@ void classification_test_pmr_term_tcp_sport(void) CU_ASSERT(recvpool == pool); odp_packet_free(pkt);
- pkt = create_packet(pkt_pool, false, &seq, false); + pkt = create_packet(default_pkt_info); CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); seqno = cls_pkt_get_seq(pkt); CU_ASSERT(seqno != TEST_SEQ_INVALID); @@ -329,6 +334,7 @@ void classification_test_pmr_term_udp_dport(void) odp_pmr_param_t pmr_param; odp_cls_cos_param_t cls_param; odph_ethhdr_t *eth; + cls_packet_info_t pkt_info;
val = CLS_DEFAULT_DPORT; mask = 0xffff; @@ -366,7 +372,9 @@ void classification_test_pmr_term_udp_dport(void) pmr = odp_cls_pmr_create(&pmr_param, 1, default_cos, cos); CU_ASSERT(pmr != ODP_PMR_INVAL);
- pkt = create_packet(pkt_pool, false, &seq, true); + pkt_info = default_pkt_info; + pkt_info.udp = true; + pkt = create_packet(pkt_info); CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); seqno = cls_pkt_get_seq(pkt); CU_ASSERT(seqno != TEST_SEQ_INVALID); @@ -388,7 +396,7 @@ void classification_test_pmr_term_udp_dport(void) odp_packet_free(pkt);
/* Other packets received in default queue */ - pkt = create_packet(pkt_pool, false, &seq, true); + pkt = create_packet(pkt_info); CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); seqno = cls_pkt_get_seq(pkt); CU_ASSERT(seqno != TEST_SEQ_INVALID); @@ -442,6 +450,7 @@ void classification_test_pmr_term_udp_sport(void) odp_pmr_param_t pmr_param; odp_cls_cos_param_t cls_param; odph_ethhdr_t *eth; + cls_packet_info_t pkt_info;
val = CLS_DEFAULT_SPORT; mask = 0xffff; @@ -479,7 +488,9 @@ void classification_test_pmr_term_udp_sport(void) pmr = odp_cls_pmr_create(&pmr_param, 1, default_cos, cos); CU_ASSERT(pmr != ODP_PMR_INVAL);
- pkt = create_packet(pkt_pool, false, &seq, true); + pkt_info = default_pkt_info; + pkt_info.udp = true; + pkt = create_packet(pkt_info); CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); seqno = cls_pkt_get_seq(pkt); CU_ASSERT(seqno != TEST_SEQ_INVALID); @@ -500,7 +511,7 @@ void classification_test_pmr_term_udp_sport(void) CU_ASSERT(recvpool == pool); odp_packet_free(pkt);
- pkt = create_packet(pkt_pool, false, &seq, true); + pkt = create_packet(pkt_info); CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); seqno = cls_pkt_get_seq(pkt); CU_ASSERT(seqno != TEST_SEQ_INVALID); @@ -553,6 +564,7 @@ void classification_test_pmr_term_ipproto(void) odp_cls_cos_param_t cls_param; odp_pmr_param_t pmr_param; odph_ethhdr_t *eth; + cls_packet_info_t pkt_info;
val = ODPH_IPPROTO_UDP; mask = 0xff; @@ -590,7 +602,9 @@ void classification_test_pmr_term_ipproto(void) pmr = odp_cls_pmr_create(&pmr_param, 1, default_cos, cos); CU_ASSERT(pmr != ODP_PMR_INVAL);
- pkt = create_packet(pkt_pool, false, &seq, true); + pkt_info = default_pkt_info; + pkt_info.udp = true; + pkt = create_packet(pkt_info); CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); seqno = cls_pkt_get_seq(pkt); CU_ASSERT(seqno != TEST_SEQ_INVALID); @@ -609,7 +623,7 @@ void classification_test_pmr_term_ipproto(void) odp_packet_free(pkt);
/* Other packets delivered to default queue */ - pkt = create_packet(pkt_pool, false, &seq, false); + pkt = create_packet(default_pkt_info); CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); seqno = cls_pkt_get_seq(pkt); CU_ASSERT(seqno != TEST_SEQ_INVALID); @@ -659,6 +673,7 @@ void classification_test_pmr_term_dmac(void) odp_cls_cos_param_t cls_param; odp_pmr_param_t pmr_param; odph_ethhdr_t *eth; + cls_packet_info_t pkt_info;
val = CLS_DEFAULT_DMAC; /* 48 bit Ethernet Mac address */ mask = 0xffffffffffff; @@ -696,7 +711,9 @@ void classification_test_pmr_term_dmac(void) pmr = odp_cls_pmr_create(&pmr_param, 1, default_cos, cos); CU_ASSERT(pmr != ODP_PMR_INVAL);
- pkt = create_packet(pkt_pool, false, &seq, true); + pkt_info = default_pkt_info; + pkt_info.udp = true; + pkt = create_packet(pkt_info); CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); seqno = cls_pkt_get_seq(pkt); CU_ASSERT(seqno != TEST_SEQ_INVALID); @@ -712,7 +729,7 @@ void classification_test_pmr_term_dmac(void) odp_packet_free(pkt);
/* Other packets delivered to default queue */ - pkt = create_packet(pkt_pool, false, &seq, false); + pkt = create_packet(default_pkt_info); CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); eth = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, NULL); memset(eth->dst.addr, 0, ODPH_ETHADDR_LEN); @@ -762,6 +779,7 @@ void classification_test_pmr_term_packet_len(void) odp_cls_cos_param_t cls_param; odp_pmr_param_t pmr_param; odph_ethhdr_t *eth; + cls_packet_info_t pkt_info;
val = 1024; /*Mask value will match any packet of length 1000 - 1099*/ @@ -801,7 +819,10 @@ void classification_test_pmr_term_packet_len(void) CU_ASSERT(pmr != ODP_PMR_INVAL);
/* create packet of payload length 1024 */ - pkt = create_packet_len(pkt_pool, false, &seq, true, 1024); + pkt_info = default_pkt_info; + pkt_info.udp = true; + pkt_info.len = 1024; + pkt = create_packet(pkt_info); CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); seqno = cls_pkt_get_seq(pkt); CU_ASSERT(seqno != TEST_SEQ_INVALID); @@ -820,7 +841,7 @@ void classification_test_pmr_term_packet_len(void) odp_packet_free(pkt);
/* Other packets delivered to default queue */ - pkt = create_packet(pkt_pool, false, &seq, false); + pkt = create_packet(default_pkt_info); CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); seqno = cls_pkt_get_seq(pkt); CU_ASSERT(seqno != TEST_SEQ_INVALID); @@ -871,6 +892,7 @@ static void classification_test_pmr_pool_set(void) odp_cls_cos_param_t cls_param; odp_pmr_param_t pmr_param; odph_ethhdr_t *eth; + cls_packet_info_t pkt_info;
val = ODPH_IPPROTO_UDP; mask = 0xff; @@ -915,7 +937,9 @@ static void classification_test_pmr_pool_set(void) pmr = odp_cls_pmr_create(&pmr_param, 1, default_cos, cos); CU_ASSERT(pmr != ODP_PMR_INVAL);
- pkt = create_packet(pkt_pool, false, &seq, true); + pkt_info = default_pkt_info; + pkt_info.udp = true; + pkt = create_packet(pkt_info); CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); seqno = cls_pkt_get_seq(pkt); CU_ASSERT(seqno != TEST_SEQ_INVALID); @@ -967,6 +991,7 @@ static void classification_test_pmr_queue_set(void) odp_cls_cos_param_t cls_param; odp_pmr_param_t pmr_param; odph_ethhdr_t *eth; + cls_packet_info_t pkt_info;
val = ODPH_IPPROTO_UDP; mask = 0xff; @@ -1010,8 +1035,9 @@ static void classification_test_pmr_queue_set(void)
pmr = odp_cls_pmr_create(&pmr_param, 1, default_cos, cos); CU_ASSERT(pmr != ODP_PMR_INVAL); - - pkt = create_packet(pkt_pool, false, &seq, true); + pkt_info = default_pkt_info; + pkt_info.udp = true; + pkt = create_packet(pkt_info); CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); seqno = cls_pkt_get_seq(pkt); CU_ASSERT(seqno != TEST_SEQ_INVALID); @@ -1098,7 +1124,7 @@ static void classification_test_pmr_term_daddr(void)
/* packet with dst ip address matching PMR rule to be received in the CoS queue*/ - pkt = create_packet(pkt_pool, false, &seq, false); + pkt = create_packet(default_pkt_info); CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); eth = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, NULL); odp_pktio_mac_addr(pktio, eth->src.addr, ODPH_ETHADDR_LEN); @@ -1119,7 +1145,229 @@ static void classification_test_pmr_term_daddr(void) odp_packet_free(pkt);
/* Other packets delivered to default queue */ - pkt = create_packet(pkt_pool, false, &seq, false); + pkt = create_packet(default_pkt_info); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); + seqno = cls_pkt_get_seq(pkt); + CU_ASSERT(seqno != TEST_SEQ_INVALID); + eth = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, NULL); + odp_pktio_mac_addr(pktio, eth->src.addr, ODPH_ETHADDR_LEN); + odp_pktio_mac_addr(pktio, eth->dst.addr, ODPH_ETHADDR_LEN); + + enqueue_pktio_interface(pkt, pktio); + + pkt = receive_packet(&retqueue, ODP_TIME_SEC_IN_NS); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); + CU_ASSERT(seqno == cls_pkt_get_seq(pkt)); + CU_ASSERT(retqueue == default_queue); + + odp_cos_destroy(cos); + odp_cos_destroy(default_cos); + odp_cls_pmr_destroy(pmr); + odp_packet_free(pkt); + stop_pktio(pktio); + odp_pool_destroy(default_pool); + odp_pool_destroy(pool); + odp_queue_destroy(queue); + odp_queue_destroy(default_queue); + odp_pktio_close(pktio); +} + +static void classification_test_pmr_term_ipv6daddr(void) +{ + odp_packet_t pkt; + uint32_t seqno; + int retval; + odp_pktio_t pktio; + odp_queue_t queue; + odp_queue_t retqueue; + odp_queue_t default_queue; + odp_pool_t pool; + odp_pool_t default_pool; + odp_pmr_t pmr; + odp_cos_t cos; + odp_cos_t default_cos; + char cosname[ODP_QUEUE_NAME_LEN]; + odp_pmr_param_t pmr_param; + odp_cls_cos_param_t cls_param; + odph_ipv6hdr_t *ip; + odph_ethhdr_t *eth; + cls_packet_info_t pkt_info; + + uint8_t IPV6_DST_ADDR[ODPH_IPV6ADDR_LEN] = { + /* I.e. ::ffff:10.1.1.100 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 10, 1, 1, 100 + }; + uint8_t ipv6_mask[ODPH_IPV6ADDR_LEN] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF + }; + + pktio = create_pktio(ODP_QUEUE_TYPE_SCHED, pkt_pool); + retval = start_pktio(pktio); + CU_ASSERT(retval == 0); + + configure_default_cos(pktio, &default_cos, + &default_queue, &default_pool); + + queue = queue_create("daddr", true); + CU_ASSERT_FATAL(queue != ODP_QUEUE_INVALID); + + pool = pool_create("daddr"); + CU_ASSERT_FATAL(pool != ODP_POOL_INVALID); + + sprintf(cosname, "daddr"); + odp_cls_cos_param_init(&cls_param); + cls_param.pool = pool; + cls_param.queue = queue; + cls_param.drop_policy = ODP_COS_DROP_POOL; + + cos = odp_cls_cos_create(cosname, &cls_param); + CU_ASSERT_FATAL(cos != ODP_COS_INVALID); + + odp_cls_pmr_param_init(&pmr_param); + pmr_param.term = ODP_PMR_DIP6_ADDR; + pmr_param.match.value = IPV6_DST_ADDR; + pmr_param.match.mask = ipv6_mask; + pmr_param.val_sz = ODPH_IPV6ADDR_LEN; + + pmr = odp_cls_pmr_create(&pmr_param, 1, default_cos, cos); + CU_ASSERT_FATAL(pmr != ODP_PMR_INVAL); + + /* packet with dst ip address matching PMR rule to be + received in the CoS queue*/ + pkt_info = default_pkt_info; + pkt_info.ipv6 = true; + pkt = create_packet(pkt_info); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); + eth = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, NULL); + odp_pktio_mac_addr(pktio, eth->src.addr, ODPH_ETHADDR_LEN); + odp_pktio_mac_addr(pktio, eth->dst.addr, ODPH_ETHADDR_LEN); + ip = (odph_ipv6hdr_t *)odp_packet_l3_ptr(pkt, NULL); + memcpy(ip->dst_addr, IPV6_DST_ADDR, ODPH_IPV6ADDR_LEN); + + seqno = cls_pkt_get_seq(pkt); + CU_ASSERT(seqno != TEST_SEQ_INVALID); + + enqueue_pktio_interface(pkt, pktio); + + pkt = receive_packet(&retqueue, ODP_TIME_SEC_IN_NS); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); + CU_ASSERT(seqno == cls_pkt_get_seq(pkt)); + CU_ASSERT(retqueue == queue); + odp_packet_free(pkt); + + /* Other packets delivered to default queue */ + pkt = create_packet(pkt_info); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); + seqno = cls_pkt_get_seq(pkt); + CU_ASSERT(seqno != TEST_SEQ_INVALID); + eth = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, NULL); + odp_pktio_mac_addr(pktio, eth->src.addr, ODPH_ETHADDR_LEN); + odp_pktio_mac_addr(pktio, eth->dst.addr, ODPH_ETHADDR_LEN); + + enqueue_pktio_interface(pkt, pktio); + + pkt = receive_packet(&retqueue, ODP_TIME_SEC_IN_NS); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); + CU_ASSERT(seqno == cls_pkt_get_seq(pkt)); + CU_ASSERT(retqueue == default_queue); + + odp_cos_destroy(cos); + odp_cos_destroy(default_cos); + odp_cls_pmr_destroy(pmr); + odp_packet_free(pkt); + stop_pktio(pktio); + odp_pool_destroy(default_pool); + odp_pool_destroy(pool); + odp_queue_destroy(queue); + odp_queue_destroy(default_queue); + odp_pktio_close(pktio); +} + +static void classification_test_pmr_term_ipv6saddr(void) +{ + odp_packet_t pkt; + uint32_t seqno; + int retval; + odp_pktio_t pktio; + odp_queue_t queue; + odp_queue_t retqueue; + odp_queue_t default_queue; + odp_pool_t pool; + odp_pool_t default_pool; + odp_pmr_t pmr; + odp_cos_t cos; + odp_cos_t default_cos; + char cosname[ODP_QUEUE_NAME_LEN]; + odp_pmr_param_t pmr_param; + odp_cls_cos_param_t cls_param; + odph_ipv6hdr_t *ip; + odph_ethhdr_t *eth; + cls_packet_info_t pkt_info; + uint8_t IPV6_SRC_ADDR[ODPH_IPV6ADDR_LEN] = { + /* I.e. ::ffff:10.0.0.100 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 10, 1, 1, 1 + }; + uint8_t ipv6_mask[ODPH_IPV6ADDR_LEN] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF + }; + + pktio = create_pktio(ODP_QUEUE_TYPE_SCHED, pkt_pool); + retval = start_pktio(pktio); + CU_ASSERT(retval == 0); + + configure_default_cos(pktio, &default_cos, + &default_queue, &default_pool); + + queue = queue_create("saddr", true); + CU_ASSERT_FATAL(queue != ODP_QUEUE_INVALID); + + pool = pool_create("saddr"); + CU_ASSERT_FATAL(pool != ODP_POOL_INVALID); + + sprintf(cosname, "saddr"); + odp_cls_cos_param_init(&cls_param); + cls_param.pool = pool; + cls_param.queue = queue; + cls_param.drop_policy = ODP_COS_DROP_POOL; + + cos = odp_cls_cos_create(cosname, &cls_param); + CU_ASSERT_FATAL(cos != ODP_COS_INVALID); + + odp_cls_pmr_param_init(&pmr_param); + pmr_param.term = ODP_PMR_SIP6_ADDR; + pmr_param.match.value = IPV6_SRC_ADDR; + pmr_param.match.mask = ipv6_mask; + pmr_param.val_sz = ODPH_IPV6ADDR_LEN; + + pmr = odp_cls_pmr_create(&pmr_param, 1, default_cos, cos); + CU_ASSERT_FATAL(pmr != ODP_PMR_INVAL); + + /* packet with dst ip address matching PMR rule to be + received in the CoS queue*/ + pkt_info = default_pkt_info; + pkt_info.ipv6 = true; + + pkt = create_packet(pkt_info); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); + eth = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, NULL); + odp_pktio_mac_addr(pktio, eth->src.addr, ODPH_ETHADDR_LEN); + odp_pktio_mac_addr(pktio, eth->dst.addr, ODPH_ETHADDR_LEN); + ip = (odph_ipv6hdr_t *)odp_packet_l3_ptr(pkt, NULL); + memcpy(ip->src_addr, IPV6_SRC_ADDR, ODPH_IPV6ADDR_LEN); + + seqno = cls_pkt_get_seq(pkt); + CU_ASSERT(seqno != TEST_SEQ_INVALID); + + enqueue_pktio_interface(pkt, pktio); + + pkt = receive_packet(&retqueue, ODP_TIME_SEC_IN_NS); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); + CU_ASSERT(seqno == cls_pkt_get_seq(pkt)); + CU_ASSERT(retqueue == queue); + odp_packet_free(pkt); + + /* Other packets delivered to default queue */ + pkt = create_packet(pkt_info); CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); seqno = cls_pkt_get_seq(pkt); CU_ASSERT(seqno != TEST_SEQ_INVALID); @@ -1156,6 +1404,8 @@ odp_testinfo_t classification_suite_pmr[] = { ODP_TEST_INFO(classification_test_pmr_pool_set), ODP_TEST_INFO(classification_test_pmr_queue_set), ODP_TEST_INFO(classification_test_pmr_term_daddr), + ODP_TEST_INFO(classification_test_pmr_term_ipv6saddr), + ODP_TEST_INFO(classification_test_pmr_term_ipv6daddr), ODP_TEST_INFO(classification_test_pmr_term_packet_len), ODP_TEST_INFO_NULL, }; diff --git a/test/common_plat/validation/api/classification/odp_classification_tests.c b/test/common_plat/validation/api/classification/odp_classification_tests.c index 4f1aecd..4f43082 100644 --- a/test/common_plat/validation/api/classification/odp_classification_tests.c +++ b/test/common_plat/validation/api/classification/odp_classification_tests.c @@ -19,6 +19,9 @@ static odp_pktio_t pktio_loop; /** sequence number of IP packets */ odp_atomic_u32_t seq;
+/* default packet info */ +static cls_packet_info_t default_pkt_info; + int classification_suite_init(void) { int i; @@ -43,6 +46,10 @@ int classification_suite_init(void) return -1; }
+ memset(&default_pkt_info, 0, sizeof(cls_packet_info_t)); + default_pkt_info.pool = pool_default; + default_pkt_info.seq = &seq; + odp_pktin_queue_param_init(&pktin_param); pktin_param.queue_param.sched.sync = ODP_SCHED_SYNC_ATOMIC;
@@ -216,8 +223,11 @@ void test_cls_pmr_chain(void) uint32_t addr = 0; uint32_t mask; uint32_t seqno = 0; + cls_packet_info_t pkt_info;
- pkt = create_packet(pool_default, false, &seq, true); + pkt_info = default_pkt_info; + pkt_info.udp = true; + pkt = create_packet(pkt_info); CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); seqno = cls_pkt_get_seq(pkt); CU_ASSERT(seqno != TEST_SEQ_INVALID); @@ -240,7 +250,7 @@ void test_cls_pmr_chain(void) CU_ASSERT(pool == pool_list[CLS_PMR_CHAIN_DST]); odp_packet_free(pkt);
- pkt = create_packet(pool_default, false, &seq, true); + pkt = create_packet(pkt_info); CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); seqno = cls_pkt_get_seq(pkt); CU_ASSERT(seqno != TEST_SEQ_INVALID); @@ -301,8 +311,12 @@ void test_pktio_default_cos(void) odp_queue_t queue; uint32_t seqno = 0; odp_pool_t pool; + cls_packet_info_t pkt_info; + /* create a default packet */ - pkt = create_packet(pool_default, false, &seq, true); + pkt_info = default_pkt_info; + pkt_info.udp = true; + pkt = create_packet(pkt_info); CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); seqno = cls_pkt_get_seq(pkt); CU_ASSERT(seqno != TEST_SEQ_INVALID); @@ -360,9 +374,12 @@ void test_pktio_error_cos(void) odp_queue_t queue; odp_packet_t pkt; odp_pool_t pool; + cls_packet_info_t pkt_info;
/*Create an error packet */ - pkt = create_packet(pool_default, false, &seq, true); + pkt_info = default_pkt_info; + pkt_info.udp = true; + pkt = create_packet(pkt_info); CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); odph_ipv4hdr_t *ip = (odph_ipv4hdr_t *)odp_packet_l3_ptr(pkt, NULL);
@@ -472,10 +489,15 @@ void test_cos_with_l2_priority(void) odp_queue_t queue; odp_pool_t pool; uint32_t seqno = 0; + cls_packet_info_t pkt_info; uint8_t i;
+ pkt_info = default_pkt_info; + pkt_info.udp = true; + pkt_info.vlan = true; + for (i = 0; i < CLS_L2_QOS_MAX; i++) { - pkt = create_packet(pool_default, true, &seq, true); + pkt = create_packet(pkt_info); CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); seqno = cls_pkt_get_seq(pkt); CU_ASSERT(seqno != TEST_SEQ_INVALID); @@ -546,8 +568,11 @@ void test_pmr_cos(void) odp_queue_t queue; odp_pool_t pool; uint32_t seqno = 0; + cls_packet_info_t pkt_info;
- pkt = create_packet(pool_default, false, &seq, true); + pkt_info = default_pkt_info; + pkt_info.udp = true; + pkt = create_packet(pkt_info); CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); seqno = cls_pkt_get_seq(pkt); CU_ASSERT(seqno != TEST_SEQ_INVALID); @@ -629,8 +654,11 @@ void test_pktio_pmr_composite_cos(void) odp_pool_t pool; odp_queue_t queue; uint32_t seqno = 0; + cls_packet_info_t pkt_info;
- pkt = create_packet(pool_default, false, &seq, true); + pkt_info = default_pkt_info; + pkt_info.udp = true; + pkt = create_packet(pkt_info); CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); seqno = cls_pkt_get_seq(pkt); CU_ASSERT(seqno != TEST_SEQ_INVALID); diff --git a/test/common_plat/validation/api/classification/odp_classification_testsuites.h b/test/common_plat/validation/api/classification/odp_classification_testsuites.h index f9fd908..d5ffef7 100644 --- a/test/common_plat/validation/api/classification/odp_classification_testsuites.h +++ b/test/common_plat/validation/api/classification/odp_classification_testsuites.h @@ -12,6 +12,15 @@ #include <odp_cunit_common.h> #include <stdbool.h>
+typedef struct cls_packet_info { + odp_pool_t pool; + bool vlan; + odp_atomic_u32_t *seq; + bool udp; + bool ipv6; + uint32_t len; +} cls_packet_info_t; + extern odp_testinfo_t classification_suite[]; extern odp_testinfo_t classification_suite_basic[]; extern odp_testinfo_t classification_suite_pmr[]; @@ -22,11 +31,10 @@ int classification_suite_term(void); int classification_suite_pmr_term(void); int classification_suite_pmr_init(void);
-odp_packet_t create_packet(odp_pool_t pool, bool vlan, - odp_atomic_u32_t *seq, bool udp); +odp_packet_t create_packet(cls_packet_info_t pkt_info); odp_packet_t create_packet_len(odp_pool_t pool, bool vlan, odp_atomic_u32_t *seq, bool flag_udp, - uint16_t len); + bool ipv4, uint16_t len); int cls_pkt_set_seq(odp_packet_t pkt); uint32_t cls_pkt_get_seq(odp_packet_t pkt); odp_pktio_t create_pktio(odp_queue_type_t q_type, odp_pool_t pool);
commit aa3bbe4da1639ac4649c7d34ae75b0230ade70b2 Author: Balasubramanian Manoharan bala.manoharan@linaro.org Date: Fri Feb 3 18:15:44 2017 +0530
linux-generic: classification: implement ipv6 packet matching rule
Adds test case for ipv6 source and destination address matching
Signed-off-by: Balasubramanian Manoharan bala.manoharan@linaro.org Reviewed-and-tested-by: Bill Fischofer bill.fischofer@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/platform/linux-generic/include/odp_classification_datamodel.h b/platform/linux-generic/include/odp_classification_datamodel.h index 37aff9f..9df756b 100644 --- a/platform/linux-generic/include/odp_classification_datamodel.h +++ b/platform/linux-generic/include/odp_classification_datamodel.h @@ -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 { + _odp_ipv6_addr_t addr; + _odp_ipv6_addr_t mask; + } match_ipv6; + struct { + _odp_ipv6_addr_t addr_start; + _odp_ipv6_addr_t addr_end; + } range_ipv6; }; uint32_t offset; /**< Offset if term == ODP_PMR_CUSTOM_FRAME */ uint32_t val_sz; /**< Size of the value to be matched */ diff --git a/platform/linux-generic/include/odp_classification_inlines.h b/platform/linux-generic/include/odp_classification_inlines.h index b839197..e6f9be9 100644 --- a/platform/linux-generic/include/odp_classification_inlines.h +++ b/platform/linux-generic/include/odp_classification_inlines.h @@ -25,6 +25,8 @@ extern "C" { #include <protocols/udp.h> #include <protocols/tcp.h> #include <odp_packet_internal.h> +#include <stdio.h> +#include <inttypes.h>
/* PMR term value verification function These functions verify the given PMR term value with the value in the packet @@ -179,19 +181,53 @@ 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; + uint64_t addr[2]; + + if (!packet_hdr_has_ipv6(pkt_hdr)) + return 0; + + ipv6 = (const _odp_ipv6hdr_t *)(pkt_addr + pkt_hdr->p.l3_offset); + + addr[0] = ipv6->src_addr.u64[0]; + addr[1] = ipv6->src_addr.u64[1]; + + /* 128 bit address is processed as two 64 bit value + * for bitwise AND operation */ + addr[0] = addr[0] & term_value->match_ipv6.mask.u64[0]; + addr[1] = addr[1] & term_value->match_ipv6.mask.u64[1]; + + if (!memcmp(addr, term_value->match_ipv6.addr.u8, _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; + uint64_t addr[2]; + + if (!packet_hdr_has_ipv6(pkt_hdr)) + return 0; + ipv6 = (const _odp_ipv6hdr_t *)(pkt_addr + pkt_hdr->p.l3_offset); + addr[0] = ipv6->dst_addr.u64[0]; + addr[1] = ipv6->dst_addr.u64[1]; + + /* 128 bit address is processed as two 64 bit value + * for bitwise AND operation */ + addr[0] = addr[0] & term_value->match_ipv6.mask.u64[0]; + addr[1] = addr[1] & term_value->match_ipv6.mask.u64[1]; + + if (!memcmp(addr, term_value->match_ipv6.addr.u8, _ODP_IPV6ADDR_LEN)) + return 1; + return 0; }
diff --git a/platform/linux-generic/include/odp_packet_internal.h b/platform/linux-generic/include/odp_packet_internal.h index e6e9d74..e3ada5c 100644 --- a/platform/linux-generic/include/odp_packet_internal.h +++ b/platform/linux-generic/include/odp_packet_internal.h @@ -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) { diff --git a/platform/linux-generic/include/protocols/ip.h b/platform/linux-generic/include/protocols/ip.h index 6c089e3..20041f1 100644 --- a/platform/linux-generic/include/protocols/ip.h +++ b/platform/linux-generic/include/protocols/ip.h @@ -117,6 +117,16 @@ ODP_STATIC_ASSERT(sizeof(_odp_ipv4hdr_t) == _ODP_IPV4HDR_LEN, (uint8_t)((((ver_tc_flow) & 0x0fc00000) >> 22) & 0xff)
/** + * Ipv6 address + */ +typedef union ODP_PACKED { + uint8_t u8[16]; + odp_u16be_t u16[8]; + odp_u32be_t u32[4]; + odp_u64be_t u64[2]; +} _odp_ipv6_addr_t; + +/** * IPv6 header */ typedef struct ODP_PACKED { @@ -124,8 +134,8 @@ typedef struct ODP_PACKED { odp_u16be_t payload_len; /**< Payload length */ uint8_t next_hdr; /**< Next header */ uint8_t hop_limit; /**< Hop limit */ - uint8_t src_addr[16]; /**< Source address */ - uint8_t dst_addr[16]; /**< Destination address */ + _odp_ipv6_addr_t src_addr; /**< Source address */ + _odp_ipv6_addr_t dst_addr; /**< Destination address */ } _odp_ipv6hdr_t;
/** @internal Compile time assert */ diff --git a/platform/linux-generic/odp_classification.c b/platform/linux-generic/odp_classification.c index e3e3574..5d96b00 100644 --- a/platform/linux-generic/odp_classification.c +++ b/platform/linux-generic/odp_classification.c @@ -446,6 +446,32 @@ 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.addr.u8, 0, 16); + memset(value->match_ipv6.mask.u8, 0, 16); + memcpy(&value->match_ipv6.addr.u8, param->match.value, + param->val_sz); + memcpy(&value->match_ipv6.mask.u8, param->match.mask, + param->val_sz); + for (i = 0; i < 2; i++) + value->match_ipv6.addr.u64[i] &= + value->match_ipv6.mask.u64[i]; + } else { + memset(value->range_ipv6.addr_start.u8, 0, 16); + memset(value->range_ipv6.addr_end.u8, 0, 16); + memcpy(&value->range_ipv6.addr_start.u8, param->range.val_start, + param->val_sz); + memcpy(&value->range_ipv6.addr_end.u8, param->range.val_end, + param->val_sz); + } + + break; + default: if (!value->range_term) { value->match.value = 0; value->match.mask = 0; @@ -460,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; diff --git a/platform/linux-generic/odp_packet.c b/platform/linux-generic/odp_packet.c index 8833822..024f694 100644 --- a/platform/linux-generic/odp_packet.c +++ b/platform/linux-generic/odp_packet.c @@ -1888,7 +1888,7 @@ static inline uint8_t parse_ipv6(packet_parser_t *prs, const uint8_t **parseptr, { const _odp_ipv6hdr_t *ipv6 = (const _odp_ipv6hdr_t *)*parseptr; const _odp_ipv6hdr_ext_t *ipv6ext; - uint32_t dstaddr0 = odp_be_to_cpu_32(ipv6->dst_addr[0]); + uint32_t dstaddr0 = odp_be_to_cpu_32(ipv6->dst_addr.u8[0]);
prs->l3_len = odp_be_to_cpu_16(ipv6->payload_len) + _ODP_IPV6HDR_LEN;
-----------------------------------------------------------------------
Summary of changes: .../include/odp_classification_datamodel.h | 11 +- .../include/odp_classification_inlines.h | 52 +++- .../linux-generic/include/odp_packet_internal.h | 5 + platform/linux-generic/include/protocols/ip.h | 14 +- platform/linux-generic/odp_classification.c | 27 ++ platform/linux-generic/odp_packet.c | 2 +- .../validation/api/classification/classification.h | 21 ++ .../api/classification/odp_classification_common.c | 149 ++++++----- .../classification/odp_classification_test_pmr.c | 292 +++++++++++++++++++-- .../api/classification/odp_classification_tests.c | 42 ++- .../classification/odp_classification_testsuites.h | 14 +- 11 files changed, 520 insertions(+), 109 deletions(-)
hooks/post-receive