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, next has been updated discards c1201795da7e0b21e63c496ff632af02b10dc7d1 (commit) discards d39b01ce075fa73386096d5960762741fb2805f6 (commit) discards 253681892e97ee0f4f7a5c1c1a27b4b336833bcb (commit) discards ffce96cbcdef44fe089746e9fc06f982ecdb1932 (commit) discards af4a068fa640f50dd72ebcb5ac02ca1510d4119e (commit) discards cd14a67e875c4edb809c5e9c4f1f3e9a018b3c91 (commit) discards 4d619768d75e4e1c15bb1be7fe282dff532f166b (commit) discards c951ba0386581a87675477456e3df0010f2eac66 (commit) via dbec145ddcf4a7362785cd15462ac561d8fe7a5b (commit) via a38cda50644887b62091e35df82501d08afeddfb (commit) via fe338dbae8bcc7ef4494d687aa75daaa037229f4 (commit) via 12c027befdddae5c94d3965e80678a28fe6643d2 (commit) via 37a6847e26c1ad9a20e29ff528a5a56bd460ce34 (commit) via 6821be78596aee4ef8c5484a6ea67790a667f5de (commit) via 5ceb481e02ec84af4537eee51b28ebbc7037d115 (commit) via 6865706a3ddf84793a17385f23097de74be66388 (commit) via dc0fb9e2e6d6e0ecdd7d131a9f2f491ff3d3f8f2 (commit) via 275b837ca639d52745004c66c497f85a1fe4fc12 (commit) via 473789f52ec383ee2caf1124af0866e7c8b81968 (commit) via abfda4861d5dbcfcd636f82ddbdc140f46d22c58 (commit) via cc162128ebcda9068c80016d2979780db7c46f0d (commit) via bd31f839f8d64ca475c88ef075ccc3be4d142027 (commit) via edccba8e41c67909f2485ec483252dc9193618a6 (commit) via 10f655cbef0dd7237f2ae49d8b2cd35a963ca1ec (commit) via 60e950dbd1a26ff18db663b6b9fb5f4fc17c6785 (commit) via 1973794053d956b90e4fd0cddcb922f2ac29c2e4 (commit) via 31eac29b5767df7eeb72ce0e099567f05a8093fe (commit) via 329ad2cc86f87ce96ab8eeabbf113500bce64b50 (commit) via fce41954cef8512050b829fd726a41584f3216f5 (commit) via 99733f4463b297fc7913be83cfb2cc7fea372137 (commit) via b57ea8ad55a879b6ef5ec1a2ae4e4c25fb90a5d3 (commit) via 5132040a52da2d7d7b4f16648d04d379f2a990ba (commit) via 1fd68e4cb742c241177d49f8c0ee9d60afba7297 (commit) via 86bee4260c6d6e8cdb2fb652dfafa9fbc27bd4f1 (commit) via 6110797199e7e253659352d31011450b9b13410d (commit) via e78e597cd45d9e6fd5b36b8efa5e046dde5f3190 (commit) via 656272a80373740140d983213c6336b982633f22 (commit) via f7e7ba1373522283c313c7ceebce5e8454f43e09 (commit) via f1bc34659c87405f1b9bf29695aa75d00be0e140 (commit) via 42117d5a3400b9f0e364eb6bc4670d145afc4dbe (commit) via d9efed317ef9900ef5a89f5ecf7a71344dbc3e04 (commit) via 9959f0d04d83eebd9bb0a4520e1cce1626343772 (commit) via cf495ab4fea270115aaf0f9c6be8e3c6f2ec4524 (commit) via e89884f30208ad5751c687713e6cad38d573b4f5 (commit) via cfcd4b990d1825fbedca00fd38cac981dbaa5951 (commit) via 413813b897c15e430699f9f06b78633cd9f9536f (commit) via aad1266fd6517118e7f115f7e97d638313c8903b (commit) via 3214a1a34e3639903c18e4a99346261d9d5d39a0 (commit) via f97abebd29b5c4c90d24bda7bcfec48f7abcf28a (commit) via 0c1675e93796897a5d358635697068dc81c1e763 (commit) via bc2f82e41e517d8c379eb753fd8379479a5e8b7c (commit) via 6d3ff54693d7e62ac1163a78c8df9cb66496eaf0 (commit) via 320d1f3195e7aa75e899506392632a7dab72bdac (commit) via d8f38f6d14ef0e966d06dd8630b75eb4db3f01d6 (commit) via 77a9d1e16d8a6d35d71aa0f8450c00c98295fb0f (commit) via a1afe8ff10bcb000ac69fc61eeae1acd14f8e4bd (commit) via ed17c2117dd80b100182d60f29c74735fd65e85c (commit) via 605b00a21e1d979a124980ad25bc32539bd00139 (commit) via 7c8cbb741d3c2b9e4e05ce1296ba9d2690f643f4 (commit) via 73d26f022e59c6e93f09545470d6e2e67eda6e86 (commit) via 9f38efb09731b5f03b2eaf787a066620e778127e (commit) via 6fb137874e77f2dfdae42d30308dd74bc06118f0 (commit) via d41e230e73243cbd63902dce005889581b23085b (commit) via db72c685127c33e3f34c6b49ef053335849990cf (commit) via 40c3619a6ce16b0e7521b649a9625e98aee85160 (commit) via 7ec1d26bf7307f300b1aad331535f601b63522b1 (commit) via b1f25eafa5b29ed21a87eecbc125a71ca38ed40b (commit) via 36c39aa5a8bcbeb9bf153f6ba91fc1f569c78e72 (commit) via a3dce4d2b259ce80f7cdaf0115b13f315353d358 (commit) via db181a6eca25a99aa07128a0e4d984eaee1372a9 (commit) via f4504d7c1e3ce5f92b7c68c0b93b288bcd018e04 (commit) via c0aaad8e02f277b40bd8deaaadae8bf122ea6657 (commit) via 033cd2a5c7c7dbc325d792c8e91389af7aa2eef0 (commit) via c7f11e9d3c5339c9805598f1046024e7165eb3e3 (commit) via 87bba414b4444d8247adf3411e8bbefd35899f1b (commit) via 0f47f4c4b48fb08326d6be9c0b1019f738d57911 (commit) via fc815dec86d080ca7d1b8fadddcab1e7c8e4b11b (commit) via 472d34cc0fd2b5f96277b1799583ab6c45375d40 (commit) via 148a700fb9af847a64d732bf7ed9975aa03fefa9 (commit) via ba6cad6319b917c078dd0c20cd6b011637195898 (commit) via c5eb1703fe9e7529ae12ecf1799b757e1a992afd (commit)
This update added new revisions after undoing existing revisions. That is to say, the old revision is not a strict subset of the new revision. This situation occurs when you --force push a change and generate a repository containing something like this:
* -- * -- B -- O -- O -- O (c1201795da7e0b21e63c496ff632af02b10dc7d1) \ N -- N -- N (dbec145ddcf4a7362785cd15462ac561d8fe7a5b)
When this happens we assume that you've already had alert emails for all of the O revisions, and so we here report only the revisions in the N branch from the common base, B.
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 dbec145ddcf4a7362785cd15462ac561d8fe7a5b Author: Matias Elo matias.elo@nokia.com Date: Tue Apr 4 09:28:19 2017 +0300
linux-gen: packet: remove lazy parsing
Replace old lazy parsing code with a new packet parsing implementation which follows the latest API (parsing level is selected using odp_pktio_config()).
Signed-off-by: Matias Elo matias.elo@nokia.com 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/api/plat/packet_types.h b/platform/linux-generic/include/odp/api/plat/packet_types.h index 95cba5eb..a209c759 100644 --- a/platform/linux-generic/include/odp/api/plat/packet_types.h +++ b/platform/linux-generic/include/odp/api/plat/packet_types.h @@ -107,7 +107,6 @@ typedef union {
/** Individual input flags */ struct { - uint64_t parsed_l2:1; /**< L2 parsed */ uint64_t dst_queue:1; /**< Dst queue present */
uint64_t flow_hash:1; /**< Flow hash present */ diff --git a/platform/linux-generic/include/odp_packet_internal.h b/platform/linux-generic/include/odp_packet_internal.h index 4c8d7515..a480a748 100644 --- a/platform/linux-generic/include/odp_packet_internal.h +++ b/platform/linux-generic/include/odp_packet_internal.h @@ -80,18 +80,6 @@ ODP_STATIC_ASSERT(sizeof(output_flags_t) == sizeof(uint32_t), "OUTPUT_FLAGS_SIZE_ERROR");
/** - * Protocol stack layers - */ -typedef enum { - LAYER_NONE = 0, - LAYER_L1, - LAYER_L2, - LAYER_L3, - LAYER_L4, - LAYER_ALL -} layer_t; - -/** * Packet parser metadata */ typedef struct { @@ -102,14 +90,6 @@ typedef struct { uint32_t l2_offset; /**< offset to L2 hdr, e.g. Eth */ uint32_t l3_offset; /**< offset to L3 hdr, e.g. IPv4, IPv6 */ uint32_t l4_offset; /**< offset to L4 hdr (TCP, UDP, SCTP, also ICMP) */ - - uint32_t l3_len; /**< Layer 3 length */ - uint32_t l4_len; /**< Layer 4 length */ - - uint16_t ethtype; /**< EtherType */ - uint8_t ip_proto; /**< IP protocol */ - uint8_t parsed_layers; /**< Highest parsed protocol stack layer */ - } packet_parser_t;
/** @@ -203,16 +183,6 @@ static inline void packet_set_len(odp_packet_hdr_t *pkt_hdr, uint32_t len) pkt_hdr->frame_len = len; }
-static inline int packet_parse_l2_not_done(packet_parser_t *prs) -{ - return !prs->input_flags.parsed_l2; -} - -static inline int packet_parse_not_complete(odp_packet_hdr_t *pkt_hdr) -{ - return pkt_hdr->p.parsed_layers != LAYER_ALL; -} - /* Forward declarations */ int _odp_packet_copy_md_to_packet(odp_packet_t srcpkt, odp_packet_t dstpkt);
@@ -220,11 +190,9 @@ int _odp_packet_copy_md_to_packet(odp_packet_t srcpkt, odp_packet_t dstpkt); int packet_alloc_multi(odp_pool_t pool_hdl, uint32_t len, odp_packet_t pkt[], int max_num);
-/* Fill in parser metadata for L2 */ -void packet_parse_l2(packet_parser_t *prs, uint32_t frame_len); - /* Perform packet parse up to a given protocol layer */ -int packet_parse_layer(odp_packet_hdr_t *pkt_hdr, layer_t layer); +int packet_parse_layer(odp_packet_hdr_t *pkt_hdr, + odp_pktio_parser_layer_t layer);
/* Reset parser metadata for a new parse */ void packet_parse_reset(odp_packet_hdr_t *pkt_hdr); @@ -264,7 +232,8 @@ static inline void packet_set_ts(odp_packet_hdr_t *pkt_hdr, odp_time_t *ts) }
int packet_parse_common(packet_parser_t *pkt_hdr, const uint8_t *ptr, - uint32_t pkt_len, uint32_t seg_len, layer_t layer); + uint32_t pkt_len, uint32_t seg_len, + odp_pktio_parser_layer_t layer);
int _odp_cls_parse(odp_packet_hdr_t *pkt_hdr, const uint8_t *parseptr);
diff --git a/platform/linux-generic/odp_classification.c b/platform/linux-generic/odp_classification.c index 5d96b00b..7ebc47d7 100644 --- a/platform/linux-generic/odp_classification.c +++ b/platform/linux-generic/odp_classification.c @@ -790,10 +790,6 @@ static inline cos_t *cls_select_cos(pktio_entry_t *entry, cls = &entry->s.cls; default_cos = cls->default_cos;
- /* Check for lazy parse needed */ - if (packet_parse_not_complete(pkt_hdr)) - packet_parse_layer(pkt_hdr, LAYER_ALL); - /* Return error cos for error packet */ if (pkt_hdr->p.error_flags.all) return cls->error_cos; @@ -838,7 +834,8 @@ int cls_classify_packet(pktio_entry_t *entry, const uint8_t *base, packet_parse_reset(pkt_hdr); packet_set_len(pkt_hdr, pkt_len);
- packet_parse_common(&pkt_hdr->p, base, pkt_len, seg_len, LAYER_ALL); + packet_parse_common(&pkt_hdr->p, base, pkt_len, seg_len, + ODP_PKTIO_PARSER_LAYER_ALL); cos = cls_select_cos(entry, base, pkt_hdr);
if (cos == NULL) diff --git a/platform/linux-generic/odp_packet.c b/platform/linux-generic/odp_packet.c index 69098624..eb66af2d 100644 --- a/platform/linux-generic/odp_packet.c +++ b/platform/linux-generic/odp_packet.c @@ -220,16 +220,9 @@ static inline void *packet_map(odp_packet_hdr_t *pkt_hdr, return addr; }
-static inline void packet_parse_disable(odp_packet_hdr_t *pkt_hdr) -{ - pkt_hdr->p.input_flags.parsed_l2 = 1; - pkt_hdr->p.parsed_layers = LAYER_ALL; -} - void packet_parse_reset(odp_packet_hdr_t *pkt_hdr) { /* Reset parser metadata before new parse */ - pkt_hdr->p.parsed_layers = LAYER_NONE; pkt_hdr->p.error_flags.all = 0; pkt_hdr->p.input_flags.all = 0; pkt_hdr->p.output_flags.all = 0; @@ -241,8 +234,7 @@ void packet_parse_reset(odp_packet_hdr_t *pkt_hdr) /** * Initialize packet */ -static inline void packet_init(odp_packet_hdr_t *pkt_hdr, uint32_t len, - int parse) +static inline void packet_init(odp_packet_hdr_t *pkt_hdr, uint32_t len) { uint32_t seg_len; int num = pkt_hdr->buf_hdr.segcount; @@ -257,7 +249,6 @@ static inline void packet_init(odp_packet_hdr_t *pkt_hdr, uint32_t len, pkt_hdr->buf_hdr.seg[num - 1].len = seg_len; }
- pkt_hdr->p.parsed_layers = LAYER_NONE; pkt_hdr->p.input_flags.all = 0; pkt_hdr->p.output_flags.all = 0; pkt_hdr->p.error_flags.all = 0; @@ -266,10 +257,6 @@ static inline void packet_init(odp_packet_hdr_t *pkt_hdr, uint32_t len, pkt_hdr->p.l3_offset = ODP_PACKET_OFFSET_INVALID; pkt_hdr->p.l4_offset = ODP_PACKET_OFFSET_INVALID;
- /* Disable lazy parsing on user allocated packets */ - if (!parse) - packet_parse_disable(pkt_hdr); - /* * Packet headroom is set from the pool's headroom * Packet tailroom is rounded up to fill the last @@ -485,7 +472,7 @@ static inline odp_packet_hdr_t *free_segments(odp_packet_hdr_t *pkt_hdr, }
static inline int packet_alloc(pool_t *pool, uint32_t len, int max_pkt, - int num_seg, odp_packet_t *pkt, int parse) + int num_seg, odp_packet_t *pkt) { int num_buf, i; int num = max_pkt; @@ -518,7 +505,7 @@ static inline int packet_alloc(pool_t *pool, uint32_t len, int max_pkt, pkt[i] = packet_handle(hdr); init_segments(&pkt_hdr[i * num_seg], num_seg);
- packet_init(hdr, len, parse); + packet_init(hdr, len); }
return num; @@ -531,7 +518,7 @@ int packet_alloc_multi(odp_pool_t pool_hdl, uint32_t len, int num, num_seg;
num_seg = num_segments(len); - num = packet_alloc(pool, len, max_num, num_seg, pkt, 1); + num = packet_alloc(pool, len, max_num, num_seg, pkt);
return num; } @@ -551,7 +538,7 @@ odp_packet_t odp_packet_alloc(odp_pool_t pool_hdl, uint32_t len) return ODP_PACKET_INVALID;
num_seg = num_segments(len); - num = packet_alloc(pool, len, 1, num_seg, &pkt, 0); + num = packet_alloc(pool, len, 1, num_seg, &pkt);
if (odp_unlikely(num == 0)) return ODP_PACKET_INVALID; @@ -574,7 +561,7 @@ int odp_packet_alloc_multi(odp_pool_t pool_hdl, uint32_t len, return -1;
num_seg = num_segments(len); - num = packet_alloc(pool, len, max_num, num_seg, pkt, 0); + num = packet_alloc(pool, len, max_num, num_seg, pkt);
return num; } @@ -635,7 +622,7 @@ int odp_packet_reset(odp_packet_t pkt, uint32_t len) if (len > pool->headroom + pool->data_size + pool->tailroom) return -1;
- packet_init(pkt_hdr, len, 0); + packet_init(pkt_hdr, len);
return 0; } @@ -1247,8 +1234,6 @@ void *odp_packet_l3_ptr(odp_packet_t pkt, uint32_t *len) { odp_packet_hdr_t *pkt_hdr = packet_hdr(pkt);
- if (pkt_hdr->p.parsed_layers < LAYER_L3) - packet_parse_layer(pkt_hdr, LAYER_L3); return packet_map(pkt_hdr, pkt_hdr->p.l3_offset, len, NULL); }
@@ -1256,8 +1241,6 @@ uint32_t odp_packet_l3_offset(odp_packet_t pkt) { odp_packet_hdr_t *pkt_hdr = packet_hdr(pkt);
- if (pkt_hdr->p.parsed_layers < LAYER_L3) - packet_parse_layer(pkt_hdr, LAYER_L3); return pkt_hdr->p.l3_offset; }
@@ -1268,8 +1251,6 @@ int odp_packet_l3_offset_set(odp_packet_t pkt, uint32_t offset) if (offset >= pkt_hdr->frame_len) return -1;
- if (pkt_hdr->p.parsed_layers < LAYER_L3) - packet_parse_layer(pkt_hdr, LAYER_L3); pkt_hdr->p.l3_offset = offset; return 0; } @@ -1278,8 +1259,6 @@ void *odp_packet_l4_ptr(odp_packet_t pkt, uint32_t *len) { odp_packet_hdr_t *pkt_hdr = packet_hdr(pkt);
- if (pkt_hdr->p.parsed_layers < LAYER_L4) - packet_parse_layer(pkt_hdr, LAYER_L4); return packet_map(pkt_hdr, pkt_hdr->p.l4_offset, len, NULL); }
@@ -1287,8 +1266,6 @@ uint32_t odp_packet_l4_offset(odp_packet_t pkt) { odp_packet_hdr_t *pkt_hdr = packet_hdr(pkt);
- if (pkt_hdr->p.parsed_layers < LAYER_L4) - packet_parse_layer(pkt_hdr, LAYER_L4); return pkt_hdr->p.l4_offset; }
@@ -1299,8 +1276,6 @@ int odp_packet_l4_offset_set(odp_packet_t pkt, uint32_t offset) if (offset >= pkt_hdr->frame_len) return -1;
- if (pkt_hdr->p.parsed_layers < LAYER_L4) - packet_parse_layer(pkt_hdr, LAYER_L4); pkt_hdr->p.l4_offset = offset; return 0; } @@ -1829,12 +1804,11 @@ static inline uint8_t parse_ipv4(packet_parser_t *prs, const uint8_t **parseptr, uint8_t ihl = _ODP_IPV4HDR_IHL(ipv4->ver_ihl); uint16_t frag_offset; uint32_t dstaddr = odp_be_to_cpu_32(ipv4->dst_addr); - - prs->l3_len = odp_be_to_cpu_16(ipv4->tot_len); + uint32_t l3_len = odp_be_to_cpu_16(ipv4->tot_len);
if (odp_unlikely(ihl < _ODP_IPV4HDR_IHL_MIN) || odp_unlikely(ver != 4) || - (prs->l3_len > frame_len - *offset)) { + (l3_len > frame_len - *offset)) { prs->error_flags.ip_err = 1; return 0; } @@ -1871,13 +1845,12 @@ 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.u8[0]); - - prs->l3_len = odp_be_to_cpu_16(ipv6->payload_len) + - _ODP_IPV6HDR_LEN; + uint32_t l3_len = odp_be_to_cpu_16(ipv6->payload_len) + + _ODP_IPV6HDR_LEN;
/* Basic sanity checks on IPv6 header */ if ((odp_be_to_cpu_32(ipv6->ver_tc_flow) >> 28) != 6 || - prs->l3_len > frame_len - *offset) { + l3_len > frame_len - *offset) { prs->error_flags.ip_err = 1; return 0; } @@ -1938,9 +1911,6 @@ static inline void parse_tcp(packet_parser_t *prs, else if ((uint32_t)tcp->hl * 4 > sizeof(_odp_tcphdr_t)) prs->input_flags.tcpopt = 1;
- prs->l4_len = prs->l3_len + - prs->l3_offset - prs->l4_offset; - if (offset) *offset += (uint32_t)tcp->hl * 4; *parseptr += (uint32_t)tcp->hl * 4; @@ -1955,13 +1925,8 @@ static inline void parse_udp(packet_parser_t *prs, const _odp_udphdr_t *udp = (const _odp_udphdr_t *)*parseptr; uint32_t udplen = odp_be_to_cpu_16(udp->length);
- if (udplen < sizeof(_odp_udphdr_t) || - udplen > (prs->l3_len + - prs->l4_offset - prs->l3_offset)) { + if (odp_unlikely(udplen < sizeof(_odp_udphdr_t))) prs->error_flags.udp_err = 1; - } - - prs->l4_len = udplen;
if (offset) *offset += sizeof(_odp_udphdr_t); @@ -1969,218 +1934,170 @@ static inline void parse_udp(packet_parser_t *prs, }
/** - * Initialize L2 related parser flags and metadata - */ -void packet_parse_l2(packet_parser_t *prs, uint32_t frame_len) -{ - /* Packet alloc or reset have already init other offsets and flags */ - - /* We only support Ethernet for now */ - prs->input_flags.eth = 1; - - /* Detect jumbo frames */ - if (frame_len > _ODP_ETH_LEN_MAX) - prs->input_flags.jumbo = 1; - - /* Assume valid L2 header, no CRC/FCS check in SW */ - prs->input_flags.l2 = 1; - - prs->input_flags.parsed_l2 = 1; -} - -/** * Parse common packet headers up to given layer * * The function expects at least PACKET_PARSE_SEG_LEN bytes of data to be * available from the ptr. */ int packet_parse_common(packet_parser_t *prs, const uint8_t *ptr, - uint32_t frame_len, uint32_t seg_len, layer_t layer) + uint32_t frame_len, uint32_t seg_len, + odp_pktio_parser_layer_t layer) { uint32_t offset; + uint16_t ethtype; const uint8_t *parseptr; + uint8_t ip_proto; + const _odp_ethhdr_t *eth; + uint16_t macaddr0, macaddr2, macaddr4; + const _odp_vlanhdr_t *vlan;
- switch (prs->parsed_layers) { - case LAYER_NONE: - /* Fall through */ - - case LAYER_L2: - { - const _odp_ethhdr_t *eth; - uint16_t macaddr0, macaddr2, macaddr4; - const _odp_vlanhdr_t *vlan; - - offset = sizeof(_odp_ethhdr_t); - if (packet_parse_l2_not_done(prs)) - packet_parse_l2(prs, frame_len); - - eth = (const _odp_ethhdr_t *)ptr; - - /* Handle Ethernet broadcast/multicast addresses */ - macaddr0 = odp_be_to_cpu_16(*((const uint16_t *) - (const void *)eth)); - prs->input_flags.eth_mcast = (macaddr0 & 0x0100) == 0x0100; - - if (macaddr0 == 0xffff) { - macaddr2 = - odp_be_to_cpu_16(*((const uint16_t *) - (const void *)eth + 1)); - macaddr4 = - odp_be_to_cpu_16(*((const uint16_t *) - (const void *)eth + 2)); - prs->input_flags.eth_bcast = - (macaddr2 == 0xffff) && (macaddr4 == 0xffff); - } else { - prs->input_flags.eth_bcast = 0; - } + if (layer == ODP_PKTIO_PARSER_LAYER_NONE) + return 0;
- /* Get Ethertype */ - prs->ethtype = odp_be_to_cpu_16(eth->type); - parseptr = (const uint8_t *)(eth + 1); + /* We only support Ethernet for now */ + prs->input_flags.eth = 1; + /* Assume valid L2 header, no CRC/FCS check in SW */ + prs->input_flags.l2 = 1; + /* Detect jumbo frames */ + if (frame_len > _ODP_ETH_LEN_MAX) + prs->input_flags.jumbo = 1;
- /* Check for SNAP vs. DIX */ - if (prs->ethtype < _ODP_ETH_LEN_MAX) { - prs->input_flags.snap = 1; - if (prs->ethtype > frame_len - offset) { - prs->error_flags.snap_len = 1; - goto parse_exit; - } - prs->ethtype = odp_be_to_cpu_16(*((const uint16_t *) - (uintptr_t) - (parseptr + 6))); - offset += 8; - parseptr += 8; - } + offset = sizeof(_odp_ethhdr_t); + eth = (const _odp_ethhdr_t *)ptr; + + /* Handle Ethernet broadcast/multicast addresses */ + macaddr0 = odp_be_to_cpu_16(*((const uint16_t *)(const void *)eth)); + prs->input_flags.eth_mcast = (macaddr0 & 0x0100) == 0x0100; + + if (macaddr0 == 0xffff) { + macaddr2 = + odp_be_to_cpu_16(*((const uint16_t *) + (const void *)eth + 1)); + macaddr4 = + odp_be_to_cpu_16(*((const uint16_t *) + (const void *)eth + 2)); + prs->input_flags.eth_bcast = + (macaddr2 == 0xffff) && (macaddr4 == 0xffff); + } else { + prs->input_flags.eth_bcast = 0; + }
- /* Parse the VLAN header(s), if present */ - if (prs->ethtype == _ODP_ETHTYPE_VLAN_OUTER) { - prs->input_flags.vlan_qinq = 1; - prs->input_flags.vlan = 1; + /* Get Ethertype */ + ethtype = odp_be_to_cpu_16(eth->type); + parseptr = (const uint8_t *)(eth + 1);
- vlan = (const _odp_vlanhdr_t *)parseptr; - prs->ethtype = odp_be_to_cpu_16(vlan->type); - offset += sizeof(_odp_vlanhdr_t); - parseptr += sizeof(_odp_vlanhdr_t); + /* Check for SNAP vs. DIX */ + if (ethtype < _ODP_ETH_LEN_MAX) { + prs->input_flags.snap = 1; + if (ethtype > frame_len - offset) { + prs->error_flags.snap_len = 1; + goto parse_exit; } + ethtype = odp_be_to_cpu_16(*((const uint16_t *)(uintptr_t) + (parseptr + 6))); + offset += 8; + parseptr += 8; + }
- if (prs->ethtype == _ODP_ETHTYPE_VLAN) { - prs->input_flags.vlan = 1; - vlan = (const _odp_vlanhdr_t *)parseptr; - prs->ethtype = odp_be_to_cpu_16(vlan->type); - offset += sizeof(_odp_vlanhdr_t); - parseptr += sizeof(_odp_vlanhdr_t); - } + /* Parse the VLAN header(s), if present */ + if (ethtype == _ODP_ETHTYPE_VLAN_OUTER) { + prs->input_flags.vlan_qinq = 1; + prs->input_flags.vlan = 1;
- prs->l3_offset = offset; - prs->parsed_layers = LAYER_L2; - if (layer == LAYER_L2) - return prs->error_flags.all != 0; + vlan = (const _odp_vlanhdr_t *)parseptr; + ethtype = odp_be_to_cpu_16(vlan->type); + offset += sizeof(_odp_vlanhdr_t); + parseptr += sizeof(_odp_vlanhdr_t); } - /* Fall through */
- case LAYER_L3: - { - offset = prs->l3_offset; - parseptr = (const uint8_t *)(ptr + offset); - /* Set l3_offset+flag only for known ethtypes */ - prs->input_flags.l3 = 1; - - /* Parse Layer 3 headers */ - switch (prs->ethtype) { - case _ODP_ETHTYPE_IPV4: - prs->input_flags.ipv4 = 1; - prs->ip_proto = parse_ipv4(prs, &parseptr, &offset, - frame_len); - break; + if (ethtype == _ODP_ETHTYPE_VLAN) { + prs->input_flags.vlan = 1; + vlan = (const _odp_vlanhdr_t *)parseptr; + ethtype = odp_be_to_cpu_16(vlan->type); + offset += sizeof(_odp_vlanhdr_t); + parseptr += sizeof(_odp_vlanhdr_t); + }
- case _ODP_ETHTYPE_IPV6: - prs->input_flags.ipv6 = 1; - prs->ip_proto = parse_ipv6(prs, &parseptr, &offset, - frame_len, seg_len); - break; + if (layer == ODP_PKTIO_PARSER_LAYER_L2) + return prs->error_flags.all != 0;
- case _ODP_ETHTYPE_ARP: - prs->input_flags.arp = 1; - prs->ip_proto = 255; /* Reserved invalid by IANA */ - break; + /* Set l3_offset+flag only for known ethtypes */ + prs->l3_offset = offset; + prs->input_flags.l3 = 1;
- default: - prs->input_flags.l3 = 0; - prs->l3_offset = ODP_PACKET_OFFSET_INVALID; - prs->ip_proto = 255; /* Reserved invalid by IANA */ - } + /* Parse Layer 3 headers */ + switch (ethtype) { + case _ODP_ETHTYPE_IPV4: + prs->input_flags.ipv4 = 1; + ip_proto = parse_ipv4(prs, &parseptr, &offset, frame_len); + break;
- /* Set l4_offset+flag only for known ip_proto */ - prs->l4_offset = offset; - prs->parsed_layers = LAYER_L3; - if (layer == LAYER_L3) - return prs->error_flags.all != 0; - } - /* Fall through */ + case _ODP_ETHTYPE_IPV6: + prs->input_flags.ipv6 = 1; + ip_proto = parse_ipv6(prs, &parseptr, &offset, frame_len, + seg_len); + break;
- case LAYER_L4: - { - offset = prs->l4_offset; - parseptr = (const uint8_t *)(ptr + offset); - prs->input_flags.l4 = 1; + case _ODP_ETHTYPE_ARP: + prs->input_flags.arp = 1; + ip_proto = 255; /* Reserved invalid by IANA */ + break;
- /* Parse Layer 4 headers */ - switch (prs->ip_proto) { - case _ODP_IPPROTO_ICMPv4: - /* Fall through */ + default: + prs->input_flags.l3 = 0; + prs->l3_offset = ODP_PACKET_OFFSET_INVALID; + ip_proto = 255; /* Reserved invalid by IANA */ + }
- case _ODP_IPPROTO_ICMPv6: - prs->input_flags.icmp = 1; - break; + if (layer == ODP_PKTIO_PARSER_LAYER_L3) + return prs->error_flags.all != 0;
- case _ODP_IPPROTO_TCP: - if (odp_unlikely(offset + _ODP_TCPHDR_LEN > seg_len)) - return -1; - prs->input_flags.tcp = 1; - parse_tcp(prs, &parseptr, NULL); - break; + /* Set l4_offset+flag only for known ip_proto */ + prs->l4_offset = offset; + prs->input_flags.l4 = 1;
- case _ODP_IPPROTO_UDP: - if (odp_unlikely(offset + _ODP_UDPHDR_LEN > seg_len)) - return -1; - prs->input_flags.udp = 1; - parse_udp(prs, &parseptr, NULL); - break; + /* Parse Layer 4 headers */ + switch (ip_proto) { + case _ODP_IPPROTO_ICMPv4: + /* Fall through */
- case _ODP_IPPROTO_AH: - prs->input_flags.ipsec = 1; - prs->input_flags.ipsec_ah = 1; - break; + case _ODP_IPPROTO_ICMPv6: + prs->input_flags.icmp = 1; + break;
- case _ODP_IPPROTO_ESP: - prs->input_flags.ipsec = 1; - prs->input_flags.ipsec_esp = 1; - break; + case _ODP_IPPROTO_TCP: + if (odp_unlikely(offset + _ODP_TCPHDR_LEN > seg_len)) + return -1; + prs->input_flags.tcp = 1; + parse_tcp(prs, &parseptr, NULL); + break;
- case _ODP_IPPROTO_SCTP: - prs->input_flags.sctp = 1; - break; + case _ODP_IPPROTO_UDP: + if (odp_unlikely(offset + _ODP_UDPHDR_LEN > seg_len)) + return -1; + prs->input_flags.udp = 1; + parse_udp(prs, &parseptr, NULL); + break;
- default: - prs->input_flags.l4 = 0; - prs->l4_offset = ODP_PACKET_OFFSET_INVALID; - break; - } + case _ODP_IPPROTO_AH: + prs->input_flags.ipsec = 1; + prs->input_flags.ipsec_ah = 1; + break;
- prs->parsed_layers = LAYER_L4; + case _ODP_IPPROTO_ESP: + prs->input_flags.ipsec = 1; + prs->input_flags.ipsec_esp = 1; break; - }
- case LAYER_ALL: + case _ODP_IPPROTO_SCTP: + prs->input_flags.sctp = 1; break;
default: - ODP_ERR("Invalid parse layer: %d\n", (int)layer); - return -1; + prs->input_flags.l4 = 0; + prs->l4_offset = ODP_PACKET_OFFSET_INVALID; + break; } - - prs->parsed_layers = LAYER_ALL; - parse_exit: return prs->error_flags.all != 0; } @@ -2188,7 +2105,8 @@ parse_exit: /** * Simple packet parser */ -int packet_parse_layer(odp_packet_hdr_t *pkt_hdr, layer_t layer) +int packet_parse_layer(odp_packet_hdr_t *pkt_hdr, + odp_pktio_parser_layer_t layer) { uint32_t seg_len = packet_first_seg_len(pkt_hdr); void *base = packet_data(pkt_hdr); diff --git a/platform/linux-generic/odp_packet_flags.c b/platform/linux-generic/odp_packet_flags.c index c2e8b9cf..72df1ecf 100644 --- a/platform/linux-generic/odp_packet_flags.c +++ b/platform/linux-generic/odp_packet_flags.c @@ -8,17 +8,13 @@ #include <odp/api/packet_flags.h> #include <odp_packet_internal.h>
-#define retflag(pkt, x, layer) do { \ +#define retflag(pkt, x) do { \ odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt); \ - if (pkt_hdr->p.parsed_layers < layer) \ - packet_parse_layer(pkt_hdr, layer); \ return pkt_hdr->p.x; \ } while (0)
-#define setflag(pkt, x, v, layer) do { \ +#define setflag(pkt, x, v) do { \ odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt); \ - if (pkt_hdr->p.parsed_layers < layer) \ - packet_parse_layer(pkt_hdr, layer); \ pkt_hdr->p.x = (v) & 1; \ } while (0)
@@ -26,9 +22,7 @@ int odp_packet_has_error(odp_packet_t pkt) { odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
- if (packet_parse_not_complete(pkt_hdr)) - packet_parse_layer(pkt_hdr, LAYER_ALL); - return odp_packet_hdr(pkt)->p.error_flags.all != 0; + return pkt_hdr->p.error_flags.all != 0; }
/* Get Input Flags */ @@ -45,126 +39,117 @@ int odp_packet_has_l2_error(odp_packet_t pkt)
int odp_packet_has_l3(odp_packet_t pkt) { - retflag(pkt, input_flags.l3, LAYER_L3); + retflag(pkt, input_flags.l3); }
int odp_packet_has_l3_error(odp_packet_t pkt) { odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
- if (pkt_hdr->p.parsed_layers < LAYER_L3) - packet_parse_layer(pkt_hdr, LAYER_L3); - return pkt_hdr->p.error_flags.ip_err; }
int odp_packet_has_l4(odp_packet_t pkt) { - retflag(pkt, input_flags.l4, LAYER_L4); + retflag(pkt, input_flags.l4); }
int odp_packet_has_l4_error(odp_packet_t pkt) { odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
- if (pkt_hdr->p.parsed_layers < LAYER_L4) - packet_parse_layer(pkt_hdr, LAYER_L4); - return pkt_hdr->p.error_flags.tcp_err | pkt_hdr->p.error_flags.udp_err; }
int odp_packet_has_eth_bcast(odp_packet_t pkt) { - retflag(pkt, input_flags.eth_bcast, LAYER_L2); + retflag(pkt, input_flags.eth_bcast); }
int odp_packet_has_eth_mcast(odp_packet_t pkt) { - retflag(pkt, input_flags.eth_mcast, LAYER_L2); + retflag(pkt, input_flags.eth_mcast); }
int odp_packet_has_vlan(odp_packet_t pkt) { - retflag(pkt, input_flags.vlan, LAYER_L2); + retflag(pkt, input_flags.vlan); }
int odp_packet_has_vlan_qinq(odp_packet_t pkt) { - retflag(pkt, input_flags.vlan_qinq, LAYER_L2); + retflag(pkt, input_flags.vlan_qinq); }
int odp_packet_has_arp(odp_packet_t pkt) { - retflag(pkt, input_flags.arp, LAYER_L3); + retflag(pkt, input_flags.arp); }
int odp_packet_has_ipv4(odp_packet_t pkt) { - retflag(pkt, input_flags.ipv4, LAYER_L3); + retflag(pkt, input_flags.ipv4); }
int odp_packet_has_ipv6(odp_packet_t pkt) { - retflag(pkt, input_flags.ipv6, LAYER_L3); + retflag(pkt, input_flags.ipv6); }
int odp_packet_has_ip_bcast(odp_packet_t pkt) { - retflag(pkt, input_flags.ip_bcast, LAYER_L3); + retflag(pkt, input_flags.ip_bcast); }
int odp_packet_has_ip_mcast(odp_packet_t pkt) { - retflag(pkt, input_flags.ip_mcast, LAYER_L3); + retflag(pkt, input_flags.ip_mcast); }
int odp_packet_has_ipfrag(odp_packet_t pkt) { - retflag(pkt, input_flags.ipfrag, LAYER_L3); + retflag(pkt, input_flags.ipfrag); }
int odp_packet_has_ipopt(odp_packet_t pkt) { - retflag(pkt, input_flags.ipopt, LAYER_L3); + retflag(pkt, input_flags.ipopt); }
int odp_packet_has_ipsec(odp_packet_t pkt) { - retflag(pkt, input_flags.ipsec, LAYER_L4); + retflag(pkt, input_flags.ipsec); }
int odp_packet_has_udp(odp_packet_t pkt) { - retflag(pkt, input_flags.udp, LAYER_L4); + retflag(pkt, input_flags.udp); }
int odp_packet_has_tcp(odp_packet_t pkt) { - retflag(pkt, input_flags.tcp, LAYER_L4); + retflag(pkt, input_flags.tcp); }
int odp_packet_has_sctp(odp_packet_t pkt) { - retflag(pkt, input_flags.sctp, LAYER_L4); + retflag(pkt, input_flags.sctp); }
int odp_packet_has_icmp(odp_packet_t pkt) { - retflag(pkt, input_flags.icmp, LAYER_L4); + retflag(pkt, input_flags.icmp); }
odp_packet_color_t odp_packet_color(odp_packet_t pkt) { - retflag(pkt, input_flags.color, LAYER_ALL); + retflag(pkt, input_flags.color); }
void odp_packet_color_set(odp_packet_t pkt, odp_packet_color_t color) { odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
- if (packet_parse_not_complete(pkt_hdr)) - packet_parse_layer(pkt_hdr, LAYER_ALL); - pkt_hdr->p.input_flags.color = color; }
@@ -172,29 +157,23 @@ odp_bool_t odp_packet_drop_eligible(odp_packet_t pkt) { odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
- if (packet_parse_not_complete(pkt_hdr)) - packet_parse_layer(pkt_hdr, LAYER_ALL); - return !pkt_hdr->p.input_flags.nodrop; }
void odp_packet_drop_eligible_set(odp_packet_t pkt, odp_bool_t drop) { - setflag(pkt, input_flags.nodrop, !drop, LAYER_ALL); + setflag(pkt, input_flags.nodrop, !drop); }
int8_t odp_packet_shaper_len_adjust(odp_packet_t pkt) { - retflag(pkt, output_flags.shaper_len_adj, LAYER_ALL); + retflag(pkt, output_flags.shaper_len_adj); }
void odp_packet_shaper_len_adjust_set(odp_packet_t pkt, int8_t adj) { odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
- if (packet_parse_not_complete(pkt_hdr)) - packet_parse_layer(pkt_hdr, LAYER_ALL); - pkt_hdr->p.output_flags.shaper_len_adj = adj; }
@@ -202,107 +181,107 @@ void odp_packet_shaper_len_adjust_set(odp_packet_t pkt, int8_t adj)
void odp_packet_has_l2_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.l2, val, LAYER_L2); + setflag(pkt, input_flags.l2, val); }
void odp_packet_has_l3_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.l3, val, LAYER_L3); + setflag(pkt, input_flags.l3, val); }
void odp_packet_has_l4_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.l4, val, LAYER_L4); + setflag(pkt, input_flags.l4, val); }
void odp_packet_has_eth_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.eth, val, LAYER_L2); + setflag(pkt, input_flags.eth, val); }
void odp_packet_has_eth_bcast_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.eth_bcast, val, LAYER_L2); + setflag(pkt, input_flags.eth_bcast, val); }
void odp_packet_has_eth_mcast_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.eth_mcast, val, LAYER_L2); + setflag(pkt, input_flags.eth_mcast, val); }
void odp_packet_has_jumbo_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.jumbo, val, LAYER_L2); + setflag(pkt, input_flags.jumbo, val); }
void odp_packet_has_vlan_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.vlan, val, LAYER_L2); + setflag(pkt, input_flags.vlan, val); }
void odp_packet_has_vlan_qinq_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.vlan_qinq, val, LAYER_L2); + setflag(pkt, input_flags.vlan_qinq, val); }
void odp_packet_has_arp_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.arp, val, LAYER_L3); + setflag(pkt, input_flags.arp, val); }
void odp_packet_has_ipv4_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.ipv4, val, LAYER_L3); + setflag(pkt, input_flags.ipv4, val); }
void odp_packet_has_ipv6_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.ipv6, val, LAYER_L3); + setflag(pkt, input_flags.ipv6, val); }
void odp_packet_has_ip_bcast_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.ip_bcast, val, LAYER_L3); + setflag(pkt, input_flags.ip_bcast, val); }
void odp_packet_has_ip_mcast_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.ip_mcast, val, LAYER_L3); + setflag(pkt, input_flags.ip_mcast, val); }
void odp_packet_has_ipfrag_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.ipfrag, val, LAYER_L3); + setflag(pkt, input_flags.ipfrag, val); }
void odp_packet_has_ipopt_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.ipopt, val, LAYER_L3); + setflag(pkt, input_flags.ipopt, val); }
void odp_packet_has_ipsec_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.ipsec, val, LAYER_L4); + setflag(pkt, input_flags.ipsec, val); }
void odp_packet_has_udp_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.udp, val, LAYER_L4); + setflag(pkt, input_flags.udp, val); }
void odp_packet_has_tcp_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.tcp, val, LAYER_L4); + setflag(pkt, input_flags.tcp, val); }
void odp_packet_has_sctp_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.sctp, val, LAYER_L4); + setflag(pkt, input_flags.sctp, val); }
void odp_packet_has_icmp_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.icmp, val, LAYER_L4); + setflag(pkt, input_flags.icmp, val); }
void odp_packet_has_flow_hash_clr(odp_packet_t pkt) diff --git a/platform/linux-generic/odp_packet_io.c b/platform/linux-generic/odp_packet_io.c index ea9f2a75..877978ba 100644 --- a/platform/linux-generic/odp_packet_io.c +++ b/platform/linux-generic/odp_packet_io.c @@ -206,6 +206,8 @@ static odp_pktio_t setup_pktio_entry(const char *name, odp_pool_t pool, memcpy(&pktio_entry->s.param, param, sizeof(odp_pktio_param_t)); pktio_entry->s.handle = hdl;
+ odp_pktio_config_init(&pktio_entry->s.config); + for (pktio_if = 0; pktio_if_ops[pktio_if]; ++pktio_if) { ret = pktio_if_ops[pktio_if]->open(hdl, pktio_entry, name, pool); diff --git a/platform/linux-generic/pktio/dpdk.c b/platform/linux-generic/pktio/dpdk.c index 6ac89bd5..c52cd09d 100644 --- a/platform/linux-generic/pktio/dpdk.c +++ b/platform/linux-generic/pktio/dpdk.c @@ -653,7 +653,8 @@ static inline int mbuf_to_pkt(pktio_entry_t *pktio_entry, if (pktio_cls_enabled(pktio_entry)) copy_packet_cls_metadata(&parsed_hdr, pkt_hdr); else - packet_parse_l2(&pkt_hdr->p, pkt_len); + packet_parse_layer(pkt_hdr, + pktio_entry->s.config.parser.layer);
if (mbuf->ol_flags & PKT_RX_RSS_HASH) odp_packet_flow_hash_set(pkt, mbuf->hash.rss); diff --git a/platform/linux-generic/pktio/loop.c b/platform/linux-generic/pktio/loop.c index 61e98ad8..e9ad22ba 100644 --- a/platform/linux-generic/pktio/loop.c +++ b/platform/linux-generic/pktio/loop.c @@ -132,7 +132,8 @@ static int loopback_recv(pktio_entry_t *pktio_entry, int index ODP_UNUSED, if (pktio_cls_enabled(pktio_entry)) copy_packet_cls_metadata(&parsed_hdr, pkt_hdr); else - packet_parse_l2(&pkt_hdr->p, pkt_len); + packet_parse_layer(pkt_hdr, + pktio_entry->s.config.parser.layer);
packet_set_ts(pkt_hdr, ts);
diff --git a/platform/linux-generic/pktio/netmap.c b/platform/linux-generic/pktio/netmap.c index ae3db34d..928bb00a 100644 --- a/platform/linux-generic/pktio/netmap.c +++ b/platform/linux-generic/pktio/netmap.c @@ -663,7 +663,8 @@ static inline int netmap_pkt_to_odp(pktio_entry_t *pktio_entry, if (pktio_cls_enabled(pktio_entry)) copy_packet_cls_metadata(&parsed_hdr, pkt_hdr); else - packet_parse_l2(&pkt_hdr->p, len); + packet_parse_layer(pkt_hdr, + pktio_entry->s.config.parser.layer);
packet_set_ts(pkt_hdr, ts); } diff --git a/platform/linux-generic/pktio/pcap.c b/platform/linux-generic/pktio/pcap.c index e54a56f5..a467b640 100644 --- a/platform/linux-generic/pktio/pcap.c +++ b/platform/linux-generic/pktio/pcap.c @@ -252,7 +252,8 @@ static int pcapif_recv_pkt(pktio_entry_t *pktio_entry, int index ODP_UNUSED, break; }
- packet_parse_l2(&pkt_hdr->p, pkt_len); + packet_parse_layer(pkt_hdr, + pktio_entry->s.config.parser.layer); pktio_entry->s.stats.in_octets += pkt_hdr->frame_len;
packet_set_ts(pkt_hdr, ts); diff --git a/platform/linux-generic/pktio/socket.c b/platform/linux-generic/pktio/socket.c index a08b0104..6f8a352e 100644 --- a/platform/linux-generic/pktio/socket.c +++ b/platform/linux-generic/pktio/socket.c @@ -750,7 +750,8 @@ static int sock_mmsg_recv(pktio_entry_t *pktio_entry, int index ODP_UNUSED, }
pkt_hdr = odp_packet_hdr(pkt); - packet_parse_l2(&pkt_hdr->p, pkt_hdr->frame_len); + packet_parse_layer(pkt_hdr, + pktio_entry->s.config.parser.layer); packet_set_ts(pkt_hdr, ts); pkt_hdr->input = pktio_entry->s.handle;
diff --git a/platform/linux-generic/pktio/socket_mmap.c b/platform/linux-generic/pktio/socket_mmap.c index fdf8cca5..2dba7b08 100644 --- a/platform/linux-generic/pktio/socket_mmap.c +++ b/platform/linux-generic/pktio/socket_mmap.c @@ -231,7 +231,8 @@ static inline unsigned pkt_mmap_v2_rx(pktio_entry_t *pktio_entry, if (pktio_cls_enabled(pktio_entry)) copy_packet_cls_metadata(&parsed_hdr, hdr); else - packet_parse_l2(&hdr->p, pkt_len); + packet_parse_layer(hdr, + pktio_entry->s.config.parser.layer);
packet_set_ts(hdr, ts);
diff --git a/platform/linux-generic/pktio/tap.c b/platform/linux-generic/pktio/tap.c index ac204560..650c12a7 100644 --- a/platform/linux-generic/pktio/tap.c +++ b/platform/linux-generic/pktio/tap.c @@ -213,7 +213,8 @@ static odp_packet_t pack_odp_pkt(pktio_entry_t *pktio_entry, const void *data, if (pktio_cls_enabled(pktio_entry)) copy_packet_cls_metadata(&parsed_hdr, pkt_hdr); else - packet_parse_l2(&pkt_hdr->p, len); + packet_parse_layer(pkt_hdr, + pktio_entry->s.config.parser.layer);
packet_set_ts(pkt_hdr, ts); pkt_hdr->input = pktio_entry->s.handle;
commit a38cda50644887b62091e35df82501d08afeddfb Author: Dmitry Eremin-Solenikov dmitry.ereminsolenikov@linaro.org Date: Tue May 23 09:00:10 2017 +0300
api: ipsec: factor out IP protocol version parameter
Instead of using 'magic' numbers for ip version in SA params, define new enum to distinguish between IPv4 and IPv6.
Signed-off-by: Dmitry Eremin-Solenikov dmitry.ereminsolenikov@linaro.org Reviewed-by: Petri Savolainen petri.savolainen@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/include/odp/api/spec/ipsec.h b/include/odp/api/spec/ipsec.h index 9a7404c9..15f5e8be 100644 --- a/include/odp/api/spec/ipsec.h +++ b/include/odp/api/spec/ipsec.h @@ -581,6 +581,18 @@ typedef enum odp_ipsec_pipeline_t { } odp_ipsec_pipeline_t;
/** + * IPSEC header type + */ +typedef enum odp_ipsec_ip_version_t { + /** Header is IPv4 */ + ODP_IPSEC_IPV4 = 4, + + /** Header is IPv6 */ + ODP_IPSEC_IPV6 = 6 + +} odp_ipsec_ip_version_t; + +/** * IPSEC Security Association (SA) parameters */ typedef struct odp_ipsec_sa_param_t { @@ -625,11 +637,8 @@ typedef struct odp_ipsec_sa_param_t { * only in ODP_IPSEC_LOOKUP_DSTADDR_SPI lookup mode. */ struct { /** Select IP version - * - * 4: IPv4 - * 6: IPv6 */ - uint8_t ip_version; + odp_ipsec_ip_version_t ip_version;
/** IP destination address (NETWORK ENDIAN) */ void *dst_addr;
commit fe338dbae8bcc7ef4494d687aa75daaa037229f4 Author: Dmitry Eremin-Solenikov dmitry.ereminsolenikov@linaro.org Date: Thu May 11 00:00:05 2017 +0300
api: ipsec: split INLINE capability into in and out pair
Unlike SYNC/ASYNC operation modes, it well might be that the implementation provides only INLINE support only for inbound or outbound packets. Let's split the capability into two new caps.
Signed-off-by: Dmitry Eremin-Solenikov dmitry.ereminsolenikov@linaro.org Reviewed-by: Petri Savolainen petri.savolainen@linaro.org Reviewed-by: Balasubramanian Manoharan bala.manoharan@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/include/odp/api/spec/ipsec.h b/include/odp/api/spec/ipsec.h index f55afe93..9a7404c9 100644 --- a/include/odp/api/spec/ipsec.h +++ b/include/odp/api/spec/ipsec.h @@ -241,8 +241,17 @@ typedef struct odp_ipsec_capability_t { */ odp_support_t op_mode_async;
- /** Inline IPSEC operation mode (ODP_IPSEC_OP_MODE_INLINE) support */ - odp_support_t op_mode_inline; + /** + * Inline inbound IPSEC operation mode (ODP_IPSEC_OP_MODE_INLINE) + * support + */ + odp_support_t op_mode_inline_in; + + /** + * Inline outgoing IPSEC operation mode (ODP_IPSEC_OP_MODE_INLINE) + * support + */ + odp_support_t op_mode_inline_out;
/** IP Authenticated Header (ODP_IPSEC_AH) support */ odp_support_t proto_ah;
commit 12c027befdddae5c94d3965e80678a28fe6643d2 Author: Dmitry Eremin-Solenikov dmitry.ereminsolenikov@linaro.org Date: Thu May 11 00:00:04 2017 +0300
api: ipsec: add AH capability
RFC4301 marks AH support as MAY instead of MUST. Some platforms might skip implementing AH. Thus we should provide capability to allow applications to check if AH is actually implemented or not.
Signed-off-by: Dmitry Eremin-Solenikov dmitry.ereminsolenikov@linaro.org Reviewed-by: Petri Savolainen petri.savolainen@linaro.org Reviewed-by: Balasubramanian Manoharan bala.manoharan@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/include/odp/api/spec/ipsec.h b/include/odp/api/spec/ipsec.h index 59737e63..f55afe93 100644 --- a/include/odp/api/spec/ipsec.h +++ b/include/odp/api/spec/ipsec.h @@ -244,6 +244,9 @@ typedef struct odp_ipsec_capability_t { /** Inline IPSEC operation mode (ODP_IPSEC_OP_MODE_INLINE) support */ odp_support_t op_mode_inline;
+ /** IP Authenticated Header (ODP_IPSEC_AH) support */ + odp_support_t proto_ah; + /** * Support of pipelined classification (ODP_IPSEC_PIPELINE_CLS) of * resulting inbound packets
commit 37a6847e26c1ad9a20e29ff528a5a56bd460ce34 Author: Dmitry Eremin-Solenikov dmitry.ereminsolenikov@linaro.org Date: Thu May 11 01:00:10 2017 +0300
api: ipsec: mark odp_ipsec_sa_create argument as constant
odp_ipsec_sa_create() should not change its argument. Thus mark it as a constant.
Signed-off-by: Dmitry Eremin-Solenikov dmitry.ereminsolenikov@linaro.org Reviewed-by: Petri Savolainen petri.savolainen@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/include/odp/api/spec/ipsec.h b/include/odp/api/spec/ipsec.h index e83494d3..59737e63 100644 --- a/include/odp/api/spec/ipsec.h +++ b/include/odp/api/spec/ipsec.h @@ -773,7 +773,7 @@ void odp_ipsec_sa_param_init(odp_ipsec_sa_param_t *param); * * @see odp_ipsec_sa_param_init() */ -odp_ipsec_sa_t odp_ipsec_sa_create(odp_ipsec_sa_param_t *param); +odp_ipsec_sa_t odp_ipsec_sa_create(const odp_ipsec_sa_param_t *param);
/** * Disable IPSEC SA diff --git a/platform/linux-generic/odp_ipsec.c b/platform/linux-generic/odp_ipsec.c index 5eb1be30..10918dfb 100644 --- a/platform/linux-generic/odp_ipsec.c +++ b/platform/linux-generic/odp_ipsec.c @@ -52,7 +52,7 @@ void odp_ipsec_sa_param_init(odp_ipsec_sa_param_t *param) memset(param, 0, sizeof(odp_ipsec_sa_param_t)); }
-odp_ipsec_sa_t odp_ipsec_sa_create(odp_ipsec_sa_param_t *param) +odp_ipsec_sa_t odp_ipsec_sa_create(const odp_ipsec_sa_param_t *param) { (void)param;
commit 6821be78596aee4ef8c5484a6ea67790a667f5de Author: Bill Fischofer bill.fischofer@linaro.org Date: Fri Apr 21 09:25:21 2017 -0500
api: ipsec: add additional doxygen documentation
Resolve Bug https://bugs.linaro.org/show_bug.cgi?id=2952 by adding additional field documentation to avoid problems with doxygen 1.8.13 and higher.
Signed-off-by: Bill Fischofer bill.fischofer@linaro.org Reviewed-by: Petri Savolainen petri.savolainen@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/include/odp/api/spec/ipsec.h b/include/odp/api/spec/ipsec.h index ecbf38c6..e83494d3 100644 --- a/include/odp/api/spec/ipsec.h +++ b/include/odp/api/spec/ipsec.h @@ -158,6 +158,7 @@ typedef struct odp_ipsec_inbound_config_t { /** Flags to control IPSEC payload data checks up to the selected parse * level. */ union { + /** Mapping for individual bits */ struct { /** Check IPv4 header checksum in IPSEC payload. * Default value is 0. */ @@ -196,6 +197,7 @@ typedef struct odp_ipsec_outbound_config_t { * metadata flag to disable checksum insertion per packet bases. */ union { + /** Mapping for individual bits */ struct { /** Insert IPv4 header checksum on the payload packet * before IPSEC transformation. Default value is 0. */ @@ -378,6 +380,7 @@ typedef struct odp_ipsec_tunnel_param_t { /** Tunnel type: IPv4 or IPv6 */ odp_ipsec_tunnel_type_t type;
+ /** Variant mappings for tunnel parameters */ union { /** IPv4 header parameters */ struct { @@ -835,6 +838,7 @@ typedef struct odp_ipsec_op_opt_t {
/** IPSEC operation status */ typedef struct odp_ipsec_op_status_t { + /** Variant mappings for op status */ union { /** Error flags */ struct { @@ -886,6 +890,7 @@ typedef struct odp_ipsec_op_status_t { uint32_t all_error; };
+ /** Variant mappings for status flags */ union { /** Status flags */ struct {
commit 5ceb481e02ec84af4537eee51b28ebbc7037d115 Author: Dmitry Eremin-Solenikov dmitry.ereminsolenikov@linaro.org Date: Wed Apr 19 16:41:27 2017 +0300
api: ipsec: factor out definitions for feature support levels
Instead of having magic 0-1-2 numbers, let's have the special enum for feature support levels (unsupported/supported/preferred).
Signed-off-by: Dmitry Eremin-Solenikov dmitry.ereminsolenikov@linaro.org Reviewed-by: Petri Savolainen petri.savolainen@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/include/odp/api/spec/ipsec.h b/include/odp/api/spec/ipsec.h index a0ceb11a..ecbf38c6 100644 --- a/include/odp/api/spec/ipsec.h +++ b/include/odp/api/spec/ipsec.h @@ -19,6 +19,7 @@ extern "C" { #endif
#include <odp/api/crypto.h> +#include <odp/api/support.h> #include <odp/api/packet_io.h> #include <odp/api/classification.h>
@@ -230,38 +231,22 @@ typedef struct odp_ipsec_capability_t { /** Maximum number of IPSEC SAs */ uint32_t max_num_sa;
- /** Synchronous IPSEC operation mode (ODP_IPSEC_OP_MODE_SYNC) support - * - * 0: Synchronous mode is not supported - * 1: Synchronous mode is supported - * 2: Synchronous mode is supported and preferred - */ - uint8_t op_mode_sync; + /** Synchronous IPSEC operation mode (ODP_IPSEC_OP_MODE_SYNC) support */ + odp_support_t op_mode_sync;
- /** Asynchronous IPSEC operation mode (ODP_IPSEC_OP_MODE_ASYNC) support - * - * 0: Asynchronous mode is not supported - * 1: Asynchronous mode is supported - * 2: Asynchronous mode is supported and preferred + /** + * Asynchronous IPSEC operation mode (ODP_IPSEC_OP_MODE_ASYNC) support */ - uint8_t op_mode_async; + odp_support_t op_mode_async;
- /** Inline IPSEC operation mode (ODP_IPSEC_OP_MODE_INLINE) support - * - * 0: Inline IPSEC operation is not supported - * 1: Inline IPSEC operation is supported - * 2: Inline IPSEC operation is supported and preferred - */ - uint8_t op_mode_inline; + /** Inline IPSEC operation mode (ODP_IPSEC_OP_MODE_INLINE) support */ + odp_support_t op_mode_inline;
- /** Support of pipelined classification (ODP_IPSEC_PIPELINE_CLS) of - * resulting inbound packets. - * - * 0: Classification of resulting packets is not supported - * 1: Classification of resulting packets is supported - * 2: Classification of resulting packets is supported and preferred + /** + * Support of pipelined classification (ODP_IPSEC_PIPELINE_CLS) of + * resulting inbound packets */ - uint8_t pipeline_cls; + odp_support_t pipeline_cls;
/** Soft expiry limit in seconds support * diff --git a/include/odp/api/spec/support.h b/include/odp/api/spec/support.h new file mode 100644 index 00000000..cc43b6f0 --- /dev/null +++ b/include/odp/api/spec/support.h @@ -0,0 +1,57 @@ +/* Copyright (c) 2017, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @file + * + * ODP support API + */ + +#ifndef ODP_API_SUPPORT_H_ +#define ODP_API_SUPPORT_H_ +#include <odp/visibility_begin.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup odp_support ODP support + * Common API + * @{ + */ + +/** + * ODP support support + * + * Support levels are specified in the relative order, where ODP_SUPPORT_NO is + * the lowest level. E.g. if the examined support level is greater than + * ODP_SUPPORT_NO, the feature is supported in some form. + */ +typedef enum odp_support_t { + /** + * Feature is not supported + */ + ODP_SUPPORT_NO = 0, + /** + * Feature is supported + */ + ODP_SUPPORT_YES, + /** + * Feature is supported and preferred + */ + ODP_SUPPORT_PREFERRED +} odp_support_t; + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#include <odp/visibility_end.h> +#endif diff --git a/include/odp_api.h b/include/odp_api.h index 962415fa..8146e024 100644 --- a/include/odp_api.h +++ b/include/odp_api.h @@ -58,6 +58,7 @@ extern "C" { #include <odp/api/spinlock_recursive.h> #include <odp/api/rwlock_recursive.h> #include <odp/api/std_clib.h> +#include <odp/api/support.h> #include <odp/api/ipsec.h>
#ifdef __cplusplus diff --git a/platform/Makefile.inc b/platform/Makefile.inc index 8fcb91ad..2a0ecc0e 100644 --- a/platform/Makefile.inc +++ b/platform/Makefile.inc @@ -32,6 +32,7 @@ odpapispecinclude_HEADERS = \ $(top_srcdir)/include/odp/api/spec/deprecated.h \ $(top_srcdir)/include/odp/api/spec/errno.h \ $(top_srcdir)/include/odp/api/spec/event.h \ + $(top_srcdir)/include/odp/api/spec/support.h \ $(top_srcdir)/include/odp/api/spec/hash.h \ $(top_srcdir)/include/odp/api/spec/hints.h \ $(top_srcdir)/include/odp/api/spec/init.h \ diff --git a/platform/linux-generic/Makefile.am b/platform/linux-generic/Makefile.am index 50218762..6717d1fe 100644 --- a/platform/linux-generic/Makefile.am +++ b/platform/linux-generic/Makefile.am @@ -36,6 +36,7 @@ odpapiinclude_HEADERS = \ $(srcdir)/include/odp/api/deprecated.h \ $(srcdir)/include/odp/api/errno.h \ $(srcdir)/include/odp/api/event.h \ + $(srcdir)/include/odp/api/support.h \ $(srcdir)/include/odp/api/hash.h \ $(srcdir)/include/odp/api/hints.h \ $(srcdir)/include/odp/api/init.h \ diff --git a/platform/linux-generic/include/odp/api/support.h b/platform/linux-generic/include/odp/api/support.h new file mode 100644 index 00000000..dd6abab2 --- /dev/null +++ b/platform/linux-generic/include/odp/api/support.h @@ -0,0 +1,34 @@ +/* Copyright (c) 2017, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @file + * + * ODP support API - platform specific header + */ + +#ifndef ODP_PLAT_SUPPORT_H_ +#define ODP_PLAT_SUPPORT_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @ingroup odp_support + * @{ + */ + +/** + * @} + */ + +#include <odp/api/spec/support.h> + +#ifdef __cplusplus +} +#endif + +#endif
commit 6865706a3ddf84793a17385f23097de74be66388 Author: Maxim Uvarov maxim.uvarov@linaro.org Date: Wed Apr 19 10:56:21 2017 +0300
Revert "api: ipsec: factor out definitions for feature support levels"
This reverts commit d025907602c5 ("api: ipsec: factor out definitions for feature support levels") Petri rejected this patch and plan write some common solution
Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/include/odp/api/spec/feature.h b/include/odp/api/spec/feature.h deleted file mode 100644 index 7ee2ae04..00000000 --- a/include/odp/api/spec/feature.h +++ /dev/null @@ -1,53 +0,0 @@ -/* Copyright (c) 2017, Linaro Limited - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/** - * @file - * - * ODP feature API - */ - -#ifndef ODP_API_FEATURE_H_ -#define ODP_API_FEATURE_H_ -#include <odp/visibility_begin.h> - -#ifdef __cplusplus -extern "C" { -#endif - -/** @defgroup odp_feature ODP feature - * Common API - * @{ - */ - -/** - * ODP feature support - */ -typedef enum odp_feature_t { - /** - * Feature is not supported - */ - ODP_FEATURE_UNSUPPORTED, - /** - * Feature is supported - */ - ODP_FEATURE_SUPPORTED, - /** - * Feature is supported and preferred - */ - ODP_FEATURE_PREFERRED -} odp_feature_t; - -/** - * @} - */ - -#ifdef __cplusplus -} -#endif - -#include <odp/visibility_end.h> -#endif diff --git a/include/odp/api/spec/ipsec.h b/include/odp/api/spec/ipsec.h index e15eb590..a0ceb11a 100644 --- a/include/odp/api/spec/ipsec.h +++ b/include/odp/api/spec/ipsec.h @@ -19,7 +19,6 @@ extern "C" { #endif
#include <odp/api/crypto.h> -#include <odp/api/feature.h> #include <odp/api/packet_io.h> #include <odp/api/classification.h>
@@ -231,22 +230,38 @@ typedef struct odp_ipsec_capability_t { /** Maximum number of IPSEC SAs */ uint32_t max_num_sa;
- /** Synchronous IPSEC operation mode (ODP_IPSEC_OP_MODE_SYNC) support */ - odp_feature_t op_mode_sync; + /** Synchronous IPSEC operation mode (ODP_IPSEC_OP_MODE_SYNC) support + * + * 0: Synchronous mode is not supported + * 1: Synchronous mode is supported + * 2: Synchronous mode is supported and preferred + */ + uint8_t op_mode_sync;
- /** - * Asynchronous IPSEC operation mode (ODP_IPSEC_OP_MODE_ASYNC) support + /** Asynchronous IPSEC operation mode (ODP_IPSEC_OP_MODE_ASYNC) support + * + * 0: Asynchronous mode is not supported + * 1: Asynchronous mode is supported + * 2: Asynchronous mode is supported and preferred */ - odp_feature_t op_mode_async; + uint8_t op_mode_async;
- /** Inline IPSEC operation mode (ODP_IPSEC_OP_MODE_INLINE) support */ - odp_feature_t op_mode_inline; + /** Inline IPSEC operation mode (ODP_IPSEC_OP_MODE_INLINE) support + * + * 0: Inline IPSEC operation is not supported + * 1: Inline IPSEC operation is supported + * 2: Inline IPSEC operation is supported and preferred + */ + uint8_t op_mode_inline;
- /** - * Support of pipelined classification (ODP_IPSEC_PIPELINE_CLS) of - * resulting inbound packets + /** Support of pipelined classification (ODP_IPSEC_PIPELINE_CLS) of + * resulting inbound packets. + * + * 0: Classification of resulting packets is not supported + * 1: Classification of resulting packets is supported + * 2: Classification of resulting packets is supported and preferred */ - odp_feature_t pipeline_cls; + uint8_t pipeline_cls;
/** Soft expiry limit in seconds support * diff --git a/include/odp_api.h b/include/odp_api.h index 7e3c0669..962415fa 100644 --- a/include/odp_api.h +++ b/include/odp_api.h @@ -58,7 +58,6 @@ extern "C" { #include <odp/api/spinlock_recursive.h> #include <odp/api/rwlock_recursive.h> #include <odp/api/std_clib.h> -#include <odp/api/feature.h> #include <odp/api/ipsec.h>
#ifdef __cplusplus diff --git a/platform/Makefile.inc b/platform/Makefile.inc index e0f57f38..8fcb91ad 100644 --- a/platform/Makefile.inc +++ b/platform/Makefile.inc @@ -32,7 +32,6 @@ odpapispecinclude_HEADERS = \ $(top_srcdir)/include/odp/api/spec/deprecated.h \ $(top_srcdir)/include/odp/api/spec/errno.h \ $(top_srcdir)/include/odp/api/spec/event.h \ - $(top_srcdir)/include/odp/api/spec/feature.h \ $(top_srcdir)/include/odp/api/spec/hash.h \ $(top_srcdir)/include/odp/api/spec/hints.h \ $(top_srcdir)/include/odp/api/spec/init.h \ diff --git a/platform/linux-generic/Makefile.am b/platform/linux-generic/Makefile.am index 9121fa3d..50218762 100644 --- a/platform/linux-generic/Makefile.am +++ b/platform/linux-generic/Makefile.am @@ -36,7 +36,6 @@ odpapiinclude_HEADERS = \ $(srcdir)/include/odp/api/deprecated.h \ $(srcdir)/include/odp/api/errno.h \ $(srcdir)/include/odp/api/event.h \ - $(srcdir)/include/odp/api/feature.h \ $(srcdir)/include/odp/api/hash.h \ $(srcdir)/include/odp/api/hints.h \ $(srcdir)/include/odp/api/init.h \ diff --git a/platform/linux-generic/include/odp/api/feature.h b/platform/linux-generic/include/odp/api/feature.h deleted file mode 100644 index d0aa8179..00000000 --- a/platform/linux-generic/include/odp/api/feature.h +++ /dev/null @@ -1,34 +0,0 @@ -/* Copyright (c) 2017, Linaro Limited - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/** - * @file - * - * ODP feature API - platform specific header - */ - -#ifndef ODP_PLAT_FEATURE_H_ -#define ODP_PLAT_FEATURE_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -/** @ingroup odp_feature - * @{ - */ - -/** - * @} - */ - -#include <odp/api/spec/feature.h> - -#ifdef __cplusplus -} -#endif - -#endif
commit dc0fb9e2e6d6e0ecdd7d131a9f2f491ff3d3f8f2 Author: Dmitry Eremin-Solenikov dmitry.ereminsolenikov@linaro.org Date: Tue Apr 18 00:02:58 2017 +0300
api: ipsec: factor out definitions for feature support levels
Instead of having magic 0-1-2 numbers, let's have the special enum for feature support levels (unsupported/supported/preferred).
Signed-off-by: Dmitry Eremin-Solenikov dmitry.ereminsolenikov@linaro.org Reviewed-by: Balasubramanian Manoharan bala.manoharan@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/include/odp/api/spec/feature.h b/include/odp/api/spec/feature.h new file mode 100644 index 00000000..7ee2ae04 --- /dev/null +++ b/include/odp/api/spec/feature.h @@ -0,0 +1,53 @@ +/* Copyright (c) 2017, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @file + * + * ODP feature API + */ + +#ifndef ODP_API_FEATURE_H_ +#define ODP_API_FEATURE_H_ +#include <odp/visibility_begin.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup odp_feature ODP feature + * Common API + * @{ + */ + +/** + * ODP feature support + */ +typedef enum odp_feature_t { + /** + * Feature is not supported + */ + ODP_FEATURE_UNSUPPORTED, + /** + * Feature is supported + */ + ODP_FEATURE_SUPPORTED, + /** + * Feature is supported and preferred + */ + ODP_FEATURE_PREFERRED +} odp_feature_t; + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#include <odp/visibility_end.h> +#endif diff --git a/include/odp/api/spec/ipsec.h b/include/odp/api/spec/ipsec.h index a0ceb11a..e15eb590 100644 --- a/include/odp/api/spec/ipsec.h +++ b/include/odp/api/spec/ipsec.h @@ -19,6 +19,7 @@ extern "C" { #endif
#include <odp/api/crypto.h> +#include <odp/api/feature.h> #include <odp/api/packet_io.h> #include <odp/api/classification.h>
@@ -230,38 +231,22 @@ typedef struct odp_ipsec_capability_t { /** Maximum number of IPSEC SAs */ uint32_t max_num_sa;
- /** Synchronous IPSEC operation mode (ODP_IPSEC_OP_MODE_SYNC) support - * - * 0: Synchronous mode is not supported - * 1: Synchronous mode is supported - * 2: Synchronous mode is supported and preferred - */ - uint8_t op_mode_sync; + /** Synchronous IPSEC operation mode (ODP_IPSEC_OP_MODE_SYNC) support */ + odp_feature_t op_mode_sync;
- /** Asynchronous IPSEC operation mode (ODP_IPSEC_OP_MODE_ASYNC) support - * - * 0: Asynchronous mode is not supported - * 1: Asynchronous mode is supported - * 2: Asynchronous mode is supported and preferred + /** + * Asynchronous IPSEC operation mode (ODP_IPSEC_OP_MODE_ASYNC) support */ - uint8_t op_mode_async; + odp_feature_t op_mode_async;
- /** Inline IPSEC operation mode (ODP_IPSEC_OP_MODE_INLINE) support - * - * 0: Inline IPSEC operation is not supported - * 1: Inline IPSEC operation is supported - * 2: Inline IPSEC operation is supported and preferred - */ - uint8_t op_mode_inline; + /** Inline IPSEC operation mode (ODP_IPSEC_OP_MODE_INLINE) support */ + odp_feature_t op_mode_inline;
- /** Support of pipelined classification (ODP_IPSEC_PIPELINE_CLS) of - * resulting inbound packets. - * - * 0: Classification of resulting packets is not supported - * 1: Classification of resulting packets is supported - * 2: Classification of resulting packets is supported and preferred + /** + * Support of pipelined classification (ODP_IPSEC_PIPELINE_CLS) of + * resulting inbound packets */ - uint8_t pipeline_cls; + odp_feature_t pipeline_cls;
/** Soft expiry limit in seconds support * diff --git a/include/odp_api.h b/include/odp_api.h index 962415fa..7e3c0669 100644 --- a/include/odp_api.h +++ b/include/odp_api.h @@ -58,6 +58,7 @@ extern "C" { #include <odp/api/spinlock_recursive.h> #include <odp/api/rwlock_recursive.h> #include <odp/api/std_clib.h> +#include <odp/api/feature.h> #include <odp/api/ipsec.h>
#ifdef __cplusplus diff --git a/platform/Makefile.inc b/platform/Makefile.inc index 8fcb91ad..e0f57f38 100644 --- a/platform/Makefile.inc +++ b/platform/Makefile.inc @@ -32,6 +32,7 @@ odpapispecinclude_HEADERS = \ $(top_srcdir)/include/odp/api/spec/deprecated.h \ $(top_srcdir)/include/odp/api/spec/errno.h \ $(top_srcdir)/include/odp/api/spec/event.h \ + $(top_srcdir)/include/odp/api/spec/feature.h \ $(top_srcdir)/include/odp/api/spec/hash.h \ $(top_srcdir)/include/odp/api/spec/hints.h \ $(top_srcdir)/include/odp/api/spec/init.h \ diff --git a/platform/linux-generic/Makefile.am b/platform/linux-generic/Makefile.am index 50218762..9121fa3d 100644 --- a/platform/linux-generic/Makefile.am +++ b/platform/linux-generic/Makefile.am @@ -36,6 +36,7 @@ odpapiinclude_HEADERS = \ $(srcdir)/include/odp/api/deprecated.h \ $(srcdir)/include/odp/api/errno.h \ $(srcdir)/include/odp/api/event.h \ + $(srcdir)/include/odp/api/feature.h \ $(srcdir)/include/odp/api/hash.h \ $(srcdir)/include/odp/api/hints.h \ $(srcdir)/include/odp/api/init.h \ diff --git a/platform/linux-generic/include/odp/api/feature.h b/platform/linux-generic/include/odp/api/feature.h new file mode 100644 index 00000000..d0aa8179 --- /dev/null +++ b/platform/linux-generic/include/odp/api/feature.h @@ -0,0 +1,34 @@ +/* Copyright (c) 2017, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @file + * + * ODP feature API - platform specific header + */ + +#ifndef ODP_PLAT_FEATURE_H_ +#define ODP_PLAT_FEATURE_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @ingroup odp_feature + * @{ + */ + +/** + * @} + */ + +#include <odp/api/spec/feature.h> + +#ifdef __cplusplus +} +#endif + +#endif
commit 275b837ca639d52745004c66c497f85a1fe4fc12 Author: Petri Savolainen petri.savolainen@linaro.org Date: Fri Apr 7 15:35:20 2017 +0300
api: ipsec: spi_overlap and lookup modes
Lookup modes are per SA and thus may be used in a mix. Spi_overlap parameter is global. So, removed comment about ignoring it in LOOKUP_SPI mode.
Signed-off-by: Petri Savolainen petri.savolainen@linaro.org Reviewed-by: Bill Fischofer bill.fischofer@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/include/odp/api/spec/ipsec.h b/include/odp/api/spec/ipsec.h index b3dc0cab..a0ceb11a 100644 --- a/include/odp/api/spec/ipsec.h +++ b/include/odp/api/spec/ipsec.h @@ -111,9 +111,7 @@ typedef struct odp_ipsec_inbound_config_t { uint32_t max_spi;
/** Select if SPI values for SA lookup are unique or may contain - * the same value multiple times. This configuration is not - * relevant in ODP_IPSEC_LOOKUP_SPI mode. The default value - * is 0. + * the same SPI value multiple times. The default value is 0. * * 0: All SAs in SA lookup have unique SPI value * 1: The same SPI value may be used for multiple SAs
commit 473789f52ec383ee2caf1124af0866e7c8b81968 Author: Petri Savolainen petri.savolainen@linaro.org Date: Thu Mar 30 13:29:44 2017 +0300
api: ipsec: add inline IPSEC support
Added support for inline IPSEC processing on packet input and output. Inline mode IPSEC and traffic manager cannot be enabled (currently) on the same pktio interface.
Signed-off-by: Petri Savolainen petri.savolainen@linaro.org Reviewed-by: Bill Fischofer bill.fischofer@linaro.org Reviewed-by: Balasubramanian Manoharan bala.manoharan@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/include/odp/api/spec/ipsec.h b/include/odp/api/spec/ipsec.h index 118363e6..b3dc0cab 100644 --- a/include/odp/api/spec/ipsec.h +++ b/include/odp/api/spec/ipsec.h @@ -19,6 +19,8 @@ extern "C" { #endif
#include <odp/api/crypto.h> +#include <odp/api/packet_io.h> +#include <odp/api/classification.h>
/** @defgroup odp_ipsec ODP IPSEC * Operations of IPSEC API. @@ -51,11 +53,43 @@ typedef enum odp_ipsec_op_mode_t { * Application uses asynchronous IPSEC operations, * which return results via events. */ - ODP_IPSEC_OP_MODE_ASYNC + ODP_IPSEC_OP_MODE_ASYNC, + + /** Inline IPSEC operation + * + * Packet input/output is connected directly to IPSEC inbound/outbound + * processing. Application uses asynchronous or inline IPSEC + * operations. + */ + ODP_IPSEC_OP_MODE_INLINE, + + /** IPSEC is disabled in inbound / outbound direction */ + ODP_IPSEC_OP_MODE_DISABLED
} odp_ipsec_op_mode_t;
/** + * Protocol layers in IPSEC configuration + */ +typedef enum odp_ipsec_proto_layer_t { + /** No layers */ + ODP_IPSEC_LAYER_NONE = 0, + + /** Layer L2 protocols (Ethernet, VLAN, etc) */ + ODP_IPSEC_LAYER_L2, + + /** Layer L3 protocols (IPv4, IPv6, ICMP, IPSEC, etc) */ + ODP_IPSEC_LAYER_L3, + + /** Layer L4 protocols (UDP, TCP, SCTP) */ + ODP_IPSEC_LAYER_L4, + + /** All layers */ + ODP_IPSEC_LAYER_ALL + +} odp_ipsec_proto_layer_t; + +/** * Configuration options for IPSEC inbound processing */ typedef struct odp_ipsec_inbound_config_t { @@ -88,9 +122,110 @@ typedef struct odp_ipsec_inbound_config_t {
} lookup;
+ /** Retain outer headers + * + * Select up to which protocol layer (at least) outer headers are + * retained in inbound inline processing. Default value is + * ODP_IPSEC_LAYER_NONE. + * + * ODP_IPSEC_LAYER_NONE: Application does not require any outer + * headers to be retained. + * + * ODP_IPSEC_LAYER_L2: Retain headers up to layer 2. + * + * ODP_IPSEC_LAYER_L3: Retain headers up to layer 3, otherwise the + * same as ODP_IPSEC_LAYER_ALL. + * + * ODP_IPSEC_LAYER_L4: Retain headers up to layer 4, otherwise the + * same as ODP_IPSEC_LAYER_ALL. + * + * ODP_IPSEC_LAYER_ALL: In tunnel mode, all headers before IPSEC are + * retained. In transport mode, all headers + * before IP (carrying IPSEC) are retained. + * + */ + odp_ipsec_proto_layer_t retain_outer; + + /** Parse packet headers after IPSEC transformation + * + * Select header parsing level after inbound processing. Headers of the + * resulting packet must be parsed (at least) up to this level. Parsing + * starts from IP (layer 3). Each successfully transformed packet has + * a valid value for L3 offset regardless of the parse configuration. + * Default value is ODP_IPSEC_LAYER_NONE. + */ + odp_ipsec_proto_layer_t parse; + + /** Flags to control IPSEC payload data checks up to the selected parse + * level. */ + union { + struct { + /** Check IPv4 header checksum in IPSEC payload. + * Default value is 0. */ + uint32_t ipv4_chksum : 1; + + /** Check UDP checksum in IPSEC payload. + * Default value is 0. */ + uint32_t udp_chksum : 1; + + /** Check TCP checksum in IPSEC payload. + * Default value is 0. */ + uint32_t tcp_chksum : 1; + + /** Check SCTP checksum in IPSEC payload. + * Default value is 0. */ + uint32_t sctp_chksum : 1; + } check; + + /** All bits of the bit field structure + * + * This field can be used to set/clear all flags, or bitwise + * operations over the entire structure. */ + uint32_t all_check; + }; + } odp_ipsec_inbound_config_t;
/** + * Configuration options for IPSEC outbound processing + */ +typedef struct odp_ipsec_outbound_config_t { + /** Flags to control L3/L4 checksum insertion as part of outbound + * packet processing. Packet must have set with valid L3/L4 offsets. + * Checksum configuration is ignored for packets that checksum cannot + * be computed for (e.g. IPv4 fragments). Application may use a packet + * metadata flag to disable checksum insertion per packet bases. + */ + union { + struct { + /** Insert IPv4 header checksum on the payload packet + * before IPSEC transformation. Default value is 0. */ + uint32_t inner_ipv4 : 1; + + /** Insert UDP header checksum on the payload packet + * before IPSEC transformation. Default value is 0. */ + uint32_t inner_udp : 1; + + /** Insert TCP header checksum on the payload packet + * before IPSEC transformation. Default value is 0. */ + uint32_t inner_tcp : 1; + + /** Insert SCTP header checksum on the payload packet + * before IPSEC transformation. Default value is 0. */ + uint32_t inner_sctp : 1; + + } chksum; + + /** All bits of the bit field structure + * + * This field can be used to set/clear all flags, or bitwise + * operations over the entire structure. */ + uint32_t all_chksum; + }; + +} odp_ipsec_outbound_config_t; + +/** * IPSEC capability */ typedef struct odp_ipsec_capability_t { @@ -113,6 +248,23 @@ typedef struct odp_ipsec_capability_t { */ uint8_t op_mode_async;
+ /** Inline IPSEC operation mode (ODP_IPSEC_OP_MODE_INLINE) support + * + * 0: Inline IPSEC operation is not supported + * 1: Inline IPSEC operation is supported + * 2: Inline IPSEC operation is supported and preferred + */ + uint8_t op_mode_inline; + + /** Support of pipelined classification (ODP_IPSEC_PIPELINE_CLS) of + * resulting inbound packets. + * + * 0: Classification of resulting packets is not supported + * 1: Classification of resulting packets is supported + * 2: Classification of resulting packets is supported and preferred + */ + uint8_t pipeline_cls; + /** Soft expiry limit in seconds support * * 0: Limit is not supported @@ -139,12 +291,19 @@ typedef struct odp_ipsec_capability_t { * IPSEC configuration options */ typedef struct odp_ipsec_config_t { - /** IPSEC operation mode. Application selects which mode (sync or async) - * will be used for IPSEC operations. + /** Inbound IPSEC operation mode. Application selects which mode + * will be used for inbound IPSEC operations. * * @see odp_ipsec_in(), odp_ipsec_in_enq() */ - odp_ipsec_op_mode_t op_mode; + odp_ipsec_op_mode_t inbound_mode; + + /** Outbound IPSEC operation mode. Application selects which mode + * will be used for outbound IPSEC operations. + * + * @see odp_ipsec_out(), odp_ipsec_out_enq(), odp_ipsec_out_inline() + */ + odp_ipsec_op_mode_t outbound_mode;
/** Maximum number of IPSEC SAs that application will use * simultaneously */ @@ -153,6 +312,9 @@ typedef struct odp_ipsec_config_t { /** IPSEC inbound processing configuration */ odp_ipsec_inbound_config_t inbound;
+ /** IPSEC outbound processing configuration */ + odp_ipsec_outbound_config_t outbound; + } odp_ipsec_config_t;
/** @@ -392,13 +554,35 @@ typedef enum odp_ipsec_lookup_mode_t { ODP_IPSEC_LOOKUP_DISABLED = 0,
/** Inbound SA lookup is enabled. Lookup matches only SPI value. - * SA lookup failure status (error.sa_lookup) is reported through + * In inline mode, a lookup miss directs the packet back to normal + * packet input interface processing. In other modes, the SA lookup + * failure status (error.sa_lookup) is reported through * odp_ipsec_packet_result_t. */ - ODP_IPSEC_LOOKUP_SPI + ODP_IPSEC_LOOKUP_SPI, + + /** Inbound SA lookup is enabled. Lookup matches both SPI value and + * destination IP address. Functionality is otherwise identical to + * ODP_IPSEC_LOOKUP_SPI. */ + ODP_IPSEC_LOOKUP_DSTADDR_SPI
} odp_ipsec_lookup_mode_t;
/** + * Result event pipeline configuration + */ +typedef enum odp_ipsec_pipeline_t { + /** Do not pipeline */ + ODP_IPSEC_PIPELINE_NONE = 0, + + /** Send IPSEC result events to the classifier. + * + * IPSEC capability 'pipeline_cls' determines if pipelined + * classification is supported. */ + ODP_IPSEC_PIPELINE_CLS + +} odp_ipsec_pipeline_t; + +/** * IPSEC Security Association (SA) parameters */ typedef struct odp_ipsec_sa_param_t { @@ -439,6 +623,21 @@ typedef struct odp_ipsec_sa_param_t { /** SPI value */ uint32_t spi;
+ /** Additional inbound SA lookup parameters. Values are considered + * only in ODP_IPSEC_LOOKUP_DSTADDR_SPI lookup mode. */ + struct { + /** Select IP version + * + * 4: IPv4 + * 6: IPv6 + */ + uint8_t ip_version; + + /** IP destination address (NETWORK ENDIAN) */ + void *dst_addr; + + } lookup_param; + /** MTU for outbound IP fragmentation offload * * This is the maximum length of IP packets that outbound IPSEC @@ -447,13 +646,31 @@ typedef struct odp_ipsec_sa_param_t { */ uint32_t mtu;
+ /** Select pipelined destination for IPSEC result events + * + * Asynchronous and inline modes generate result events. Select where + * those events are sent. Inbound SAs may choose to use pipelined + * classification. The default value is ODP_IPSEC_PIPELINE_NONE. + */ + odp_ipsec_pipeline_t pipeline; + /** Destination queue for IPSEC events * - * Operations in asynchronous mode enqueue resulting events into - * this queue. + * Operations in asynchronous or inline mode enqueue resulting events + * into this queue. */ odp_queue_t dest_queue;
+ /** Classifier destination CoS for IPSEC result events + * + * Result events for successfully decapsulated packets are sent to + * classification through this CoS. Other result events are sent to + * 'dest_queue'. This field is considered only when 'pipeline' is + * ODP_IPSEC_PIPELINE_CLS. The CoS must not be shared between any pktio + * interface default CoS. + */ + odp_cos_t dest_cos; + /** User defined SA context pointer * * User defined context pointer associated with the SA. @@ -686,6 +903,18 @@ typedef struct odp_ipsec_op_status_t { uint32_t all_error; };
+ union { + /** Status flags */ + struct { + /** Packet was processed in inline mode */ + uint32_t inline_mode : 1; + + } flag; + + /** All flag bits */ + uint32_t all_flag; + }; + } odp_ipsec_op_status_t;
/** @@ -715,7 +944,7 @@ typedef struct odp_ipsec_op_param_t {
/** Pointer to an array of packets * - * Each packet must have a valid value for these meta-data: + * Each packet must have a valid value for these metadata: * * L3 offset: Offset to the first byte of the (outmost) IP header * * L4 offset: For inbound direction, when udp_encap is enabled - * offset to the first byte of the encapsulating UDP @@ -740,6 +969,35 @@ typedef struct odp_ipsec_op_param_t { } odp_ipsec_op_param_t;
/** + * Outbound inline IPSEC operation parameters + */ +typedef struct odp_ipsec_inline_op_param_t { + /** Packet output interface for inline output operation + * + * Outbound inline IPSEC operation uses this packet IO interface to + * output the packet after a successful IPSEC transformation. The pktio + * must have been configured to operate in inline IPSEC mode. + */ + odp_pktio_t pktio; + + /** Outer headers for inline output operation + * + * Outbound inline IPSEC operation uses this information to prepend + * outer headers to the IPSEC packet before sending it out. + */ + struct { + /** Points to first byte of outer headers to be copied in + * front of the outgoing IPSEC packet. Implementation copies + * the headers during odp_ipsec_out_inline() call. */ + uint8_t *ptr; + + /** Outer header length in bytes */ + uint32_t len; + } outer_hdr; + +} odp_ipsec_inline_op_param_t; + +/** * IPSEC operation result for a packet */ typedef struct odp_ipsec_packet_result_t { @@ -765,6 +1023,23 @@ typedef struct odp_ipsec_packet_result_t { */ odp_ipsec_sa_t sa;
+ /** Packet outer header status before inbound inline processing. + * This is valid only when status.flag.inline_mode is set. + */ + struct { + /** Points to the first byte of retained outer headers. These + * headers are stored in a contiquous, per packet, + * implementation specific memory space. Since the memory space + * may overlap with e.g. packet head/tailroom, the content + * becomes invalid if packet data storage is modified in + * anyway. The memory space may not be sharable to other + * threads. */ + uint8_t *ptr; + + /** Outer header length in bytes */ + uint32_t len; + } outer_hdr; + } odp_ipsec_packet_result_t;
/** @@ -786,18 +1061,14 @@ typedef struct odp_ipsec_op_result_t { * at least 'num_pkt' elements. * * Each successfully transformed packet has a valid value for these - * meta-data: + * metadata regardless of the inner packet parse configuration. + * (odp_ipsec_inbound_config_t): * * L3 offset: Offset to the first byte of the (outmost) IP header - * * L4 offset: Offset to the first byte of the valid and known L4 - * header (immediately following the IP header). - * * Various flags about L3 and L4 layers: - * has_l3, has_l4, has_ipv4, has_ipv6, has_ipfrag, - * has_ipsec, has_udp, has_tcp, etc depending on - * the resulted packet format + * * pktio: For inbound inline IPSEC processed packets, original + * packet input interface * - * @see odp_packet_l3_offset(), odp_packet_l4_offset(), - * odp_packet_has_ipv4(), odp_packet_has_ipv6(), - * odp_packet_has_ipfrag(), odp_packet_has_ipsec() + * Other metadata for parse results and error checks depend on + * configuration (selected parse and error check levels). */ odp_packet_t *pkt;
@@ -928,10 +1199,10 @@ int odp_ipsec_out(const odp_ipsec_op_param_t *input, /** * Inbound asynchronous IPSEC operation * - * This operation does inbound IPSEC processing in asynchronous mode - * (ODP_IPSEC_OP_MODE_ASYNC). It processes packets otherwise identically to - * odp_ipsec_in(), but outputs all results through one or more - * ODP_EVENT_IPSEC_RESULT events with the following ordering considerations. + * This operation does inbound IPSEC processing in asynchronous mode. It + * processes packets otherwise identically to odp_ipsec_in(), but outputs all + * results through one or more ODP_EVENT_IPSEC_RESULT events with the following + * ordering considerations. * * Asynchronous mode maintains (operation input) packet order per SA when * application calls the operation within an ordered or atomic scheduler context @@ -941,6 +1212,11 @@ int odp_ipsec_out(const odp_ipsec_op_param_t *input, * events for the same SA are enqueued in order, and packet handles (for the * same SA) are stored in order within an event. * + * The function may be used also in inline processing mode, e.g. for IPSEC + * packets for which inline processing is not possible. Packets for the same SA + * may be processed simultaneously in both modes (initiated by this function + * and inline operation). + * * @param input Operation input parameters * * @return Number of input packets consumed (0 ... input.num_pkt) @@ -953,10 +1229,10 @@ int odp_ipsec_in_enq(const odp_ipsec_op_param_t *input); /** * Outbound asynchronous IPSEC operation * - * This operation does outbound IPSEC processing in asynchronous mode - * (ODP_IPSEC_OP_MODE_ASYNC). It processes packets otherwise identically to - * odp_ipsec_out(), but outputs all results through one or more - * ODP_EVENT_IPSEC_RESULT events with the following ordering considerations. + * This operation does outbound IPSEC processing in asynchronous mode. It + * processes packets otherwise identically to odp_ipsec_out(), but outputs all + * results through one or more ODP_EVENT_IPSEC_RESULT events with the following + * ordering considerations. * * Asynchronous mode maintains (operation input) packet order per SA when * application calls the operation within an ordered or atomic scheduler context @@ -966,6 +1242,9 @@ int odp_ipsec_in_enq(const odp_ipsec_op_param_t *input); * events for the same SA are enqueued in order, and packet handles (for the * same SA) are stored in order within an event. * + * The function may be used also in inline processing mode, e.g. for IPSEC + * packets for which inline processing is not possible. + * * @param input Operation input parameters * * @return Number of input packets consumed (0 ... input.num_pkt) @@ -976,6 +1255,28 @@ int odp_ipsec_in_enq(const odp_ipsec_op_param_t *input); int odp_ipsec_out_enq(const odp_ipsec_op_param_t *input);
/** + * Outbound inline IPSEC operation + * + * This operation does outbound inline IPSEC processing for the packets. It's + * otherwise identical to odp_ipsec_out_enq(), but outputs all successfully + * transformed packets to the specified output interface, instead of generating + * result events for those. + * + * Inline operation parameters are defined per packet. The array of parameters + * must have 'op_param.num_pkt' elements and is pointed to by 'inline_param'. + * + * @param op_param Operation parameters + * @param inline_param Outbound inline operation specific parameters + * + * @return Number of packets consumed (0 ... op_param.num_pkt) + * @retval <0 On failure + * + * @see odp_ipsec_out_enq() + */ +int odp_ipsec_out_inline(const odp_ipsec_op_param_t *op_param, + const odp_ipsec_inline_op_param_t *inline_param); + +/** * Get IPSEC results from an ODP_EVENT_IPSEC_RESULT event * * Copies IPSEC operation results from an event. The event must be of diff --git a/include/odp/api/spec/packet_io.h b/include/odp/api/spec/packet_io.h index cec1f22a..88020892 100644 --- a/include/odp/api/spec/packet_io.h +++ b/include/odp/api/spec/packet_io.h @@ -407,6 +407,38 @@ typedef struct odp_pktio_config_t { * interface capability before enabling the same. */ odp_bool_t enable_loop;
+ /** Inbound IPSEC inlined with packet input + * + * Enable/disable inline inbound IPSEC operation. When enabled packet + * input directs all IPSEC packets automatically to IPSEC inbound + * processing. IPSEC configuration is done through the IPSEC API. + * Packets that are not (recognized as) IPSEC are processed + * according to the packet input configuration. + * + * 0: Disable inbound IPSEC inline operation (default) + * 1: Enable inbound IPSEC inline operation + * + * @see odp_ipsec_config(), odp_ipsec_sa_create() + */ + odp_bool_t inbound_ipsec; + + /** Outbound IPSEC inlined with packet output + * + * Enable/disable inline outbound IPSEC operation. When enabled IPSEC + * outbound processing can send outgoing IPSEC packets directly + * to the pktio interface for output. IPSEC configuration is done + * through the IPSEC API. + * + * Outbound IPSEC inline operation cannot be combined with traffic + * manager (ODP_PKTOUT_MODE_TM). + * + * 0: Disable outbound IPSEC inline operation (default) + * 1: Enable outbound IPSEC inline operation + * + * @see odp_ipsec_config(), odp_ipsec_sa_create() + */ + odp_bool_t outbound_ipsec; + } odp_pktio_config_t;
/**
commit abfda4861d5dbcfcd636f82ddbdc140f46d22c58 Author: Petri Savolainen petri.savolainen@linaro.org Date: Thu Mar 30 13:29:43 2017 +0300
api: ipsec: extend lookaside API
Added configuration option for inbound SPI range (for lookups). Removed unique SPI requirement and added config option for overlap. Added default queue for lookup misses. Added SA disable function and status event for the response from it. The same event may be used for e.g. IPSEC statistics, etc queries. Improved outbound fragmentation documentation.
Signed-off-by: Petri Savolainen petri.savolainen@linaro.org Reviewed-by: Bill Fischofer bill.fischofer@linaro.org Reviewed-by: Balasubramanian Manoharan bala.manoharan@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/include/odp/api/spec/event.h b/include/odp/api/spec/event.h index 75c0bbc2..f22efce5 100644 --- a/include/odp/api/spec/event.h +++ b/include/odp/api/spec/event.h @@ -39,7 +39,7 @@ extern "C" { * @typedef odp_event_type_t * ODP event types: * ODP_EVENT_BUFFER, ODP_EVENT_PACKET, ODP_EVENT_TIMEOUT, - * ODP_EVENT_CRYPTO_COMPL, ODP_EVENT_IPSEC_RESULT + * ODP_EVENT_CRYPTO_COMPL, ODP_EVENT_IPSEC_RESULT, ODP_EVENT_IPSEC_STATUS */
/** diff --git a/include/odp/api/spec/ipsec.h b/include/odp/api/spec/ipsec.h index 66222d86..118363e6 100644 --- a/include/odp/api/spec/ipsec.h +++ b/include/odp/api/spec/ipsec.h @@ -56,6 +56,41 @@ typedef enum odp_ipsec_op_mode_t { } odp_ipsec_op_mode_t;
/** + * Configuration options for IPSEC inbound processing + */ +typedef struct odp_ipsec_inbound_config_t { + /** Default destination queue for IPSEC events + * + * When inbound SA lookup fails in the asynchronous mode, + * resulting IPSEC events are enqueued into this queue. + */ + odp_queue_t default_queue; + + /** Constraints for SPI values used with inbound SA lookup. Minimal + * SPI range and unique values may improve performance. */ + struct { + /** Minimum SPI value for SA lookup. Default value is 0. */ + uint32_t min_spi; + + /** Maximum SPI value for SA lookup. Default value is + * UINT32_MAX. */ + uint32_t max_spi; + + /** Select if SPI values for SA lookup are unique or may contain + * the same value multiple times. This configuration is not + * relevant in ODP_IPSEC_LOOKUP_SPI mode. The default value + * is 0. + * + * 0: All SAs in SA lookup have unique SPI value + * 1: The same SPI value may be used for multiple SAs + */ + odp_bool_t spi_overlap; + + } lookup; + +} odp_ipsec_inbound_config_t; + +/** * IPSEC capability */ typedef struct odp_ipsec_capability_t { @@ -111,6 +146,13 @@ typedef struct odp_ipsec_config_t { */ odp_ipsec_op_mode_t op_mode;
+ /** Maximum number of IPSEC SAs that application will use + * simultaneously */ + uint32_t max_num_sa; + + /** IPSEC inbound processing configuration */ + odp_ipsec_inbound_config_t inbound; + } odp_ipsec_config_t;
/** @@ -349,8 +391,10 @@ typedef enum odp_ipsec_lookup_mode_t { /** Inbound SA lookup is disabled. */ ODP_IPSEC_LOOKUP_DISABLED = 0,
- /** Inbound SA lookup is enabled. Used SPI values must be unique. */ - ODP_IPSEC_LOOKUP_IN_UNIQUE_SA + /** Inbound SA lookup is enabled. Lookup matches only SPI value. + * SA lookup failure status (error.sa_lookup) is reported through + * odp_ipsec_packet_result_t. */ + ODP_IPSEC_LOOKUP_SPI
} odp_ipsec_lookup_mode_t;
@@ -529,6 +573,29 @@ void odp_ipsec_sa_param_init(odp_ipsec_sa_param_t *param); odp_ipsec_sa_t odp_ipsec_sa_create(odp_ipsec_sa_param_t *param);
/** + * Disable IPSEC SA + * + * Application must use this call to disable a SA before destroying it. The call + * marks the SA disabled, so that IPSEC implementation stops using it. For + * example, inbound SPI lookups will not match any more. Application must + * stop providing the SA as parameter to new IPSEC input/output operations + * before calling disable. Packets in progress during the call may still match + * the SA and be processed successfully. + * + * When in synchronous operation mode, the call will return when it's possible + * to destroy the SA. In asynchronous mode, the same is indicated by an + * ODP_EVENT_IPSEC_STATUS event sent to the queue specified for the SA. + * + * @param sa IPSEC SA to be disabled + * + * @retval 0 On success + * @retval <0 On failure + * + * @see odp_ipsec_sa_destroy() + */ +int odp_ipsec_sa_disable(odp_ipsec_sa_t sa); + +/** * Destroy IPSEC SA * * Destroy an unused IPSEC SA. Result is undefined if the SA is being used @@ -567,55 +634,59 @@ typedef struct odp_ipsec_op_opt_t { #define ODP_IPSEC_OK 0
/** IPSEC operation status */ -typedef union odp_ipsec_status_t { - /** Error flags */ - struct { - /** Protocol error. Not a valid ESP or AH packet. */ - uint32_t proto : 1; +typedef struct odp_ipsec_op_status_t { + union { + /** Error flags */ + struct { + /** Protocol error. Not a valid ESP or AH packet. */ + uint32_t proto : 1;
- /** SA lookup failed */ - uint32_t sa_lookup : 1; + /** SA lookup failed */ + uint32_t sa_lookup : 1;
- /** Authentication failed */ - uint32_t auth : 1; + /** Authentication failed */ + uint32_t auth : 1;
- /** Anti-replay check failed */ - uint32_t antireplay : 1; + /** Anti-replay check failed */ + uint32_t antireplay : 1;
- /** Other algorithm error */ - uint32_t alg : 1; + /** Other algorithm error */ + uint32_t alg : 1;
- /** Packet does not fit into the given MTU size */ - uint32_t mtu : 1; + /** Packet does not fit into the given MTU size */ + uint32_t mtu : 1;
- /** Soft lifetime expired: seconds */ - uint32_t soft_exp_sec : 1; + /** Soft lifetime expired: seconds */ + uint32_t soft_exp_sec : 1;
- /** Soft lifetime expired: bytes */ - uint32_t soft_exp_bytes : 1; + /** Soft lifetime expired: bytes */ + uint32_t soft_exp_bytes : 1;
- /** Soft lifetime expired: packets */ - uint32_t soft_exp_packets : 1; + /** Soft lifetime expired: packets */ + uint32_t soft_exp_packets : 1;
- /** Hard lifetime expired: seconds */ - uint32_t hard_exp_sec : 1; + /** Hard lifetime expired: seconds */ + uint32_t hard_exp_sec : 1;
- /** Hard lifetime expired: bytes */ - uint32_t hard_exp_bytes : 1; + /** Hard lifetime expired: bytes */ + uint32_t hard_exp_bytes : 1;
- /** Hard lifetime expired: packets */ - uint32_t hard_exp_packets : 1; - } error; + /** Hard lifetime expired: packets */ + uint32_t hard_exp_packets : 1;
- /** All bits of the bit field structure - * - * This field can be used to set, clear or compare multiple flags. - * For example, 'status.all != ODP_IPSEC_OK' checks if there are any - * errors. - */ - uint32_t all; + } error;
-} odp_ipsec_status_t; + /** All error bits + * + * This field can be used to set, clear or compare multiple + * flags. For example, 'status.all_error != ODP_IPSEC_OK' + * checks if there are + * any errors. + */ + uint32_t all_error; + }; + +} odp_ipsec_op_status_t;
/** * IPSEC operation input parameters @@ -673,14 +744,15 @@ typedef struct odp_ipsec_op_param_t { */ typedef struct odp_ipsec_packet_result_t { /** IPSEC operation status */ - odp_ipsec_status_t status; + odp_ipsec_op_status_t status;
/** Number of output packets created from the corresponding input packet * * Without fragmentation offload this is always one. However, if the * input packet was fragmented during the operation this is larger than - * one for the first fragment and zero for the rest of the fragments - * (following the first one in the 'pkt' array). + * one for the first returned fragment and zero for the rest of the + * fragments. All the fragments (of the same source packet) are stored + * consecutively in the 'pkt' array. */ int num_out;
@@ -745,6 +817,34 @@ typedef struct odp_ipsec_op_result_t { } odp_ipsec_op_result_t;
/** + * IPSEC status ID + */ +typedef enum odp_ipsec_status_id_t { + /** Response to SA disable command */ + ODP_IPSEC_STATUS_SA_DISABLE = 0 + +} odp_ipsec_status_id_t; + +/** + * IPSEC status content + */ +typedef struct odp_ipsec_status_t { + /** IPSEC status ID */ + odp_ipsec_status_id_t id; + + /** Return value from the operation + * + * 0: Success + * <0: Failure + */ + int ret; + + /** IPSEC SA that was target of the operation */ + odp_ipsec_sa_t sa; + +} odp_ipsec_status_t; + +/** * Inbound synchronous IPSEC operation * * This operation does inbound IPSEC processing in synchronous mode @@ -897,6 +997,22 @@ int odp_ipsec_out_enq(const odp_ipsec_op_param_t *input); int odp_ipsec_result(odp_ipsec_op_result_t *result, odp_event_t event);
/** + * Get IPSEC status information from an ODP_EVENT_IPSEC_STATUS event + * + * Copies IPSEC status information from an event. The event must be of + * type ODP_EVENT_IPSEC_STATUS. + * + * @param[out] status Pointer to status information structure for output. + * @param event An ODP_EVENT_IPSEC_STATUS event + * + * @retval 0 On success + * @retval <0 On failure + * + * @see odp_ipsec_sa_disable() + */ +int odp_ipsec_status(odp_ipsec_status_t *status, odp_event_t event); + +/** * Update MTU for outbound IP fragmentation * * When IP fragmentation offload is enabled, the SA is created with an MTU.
commit cc162128ebcda9068c80016d2979780db7c46f0d Author: Petri Savolainen petri.savolainen@nokia.com Date: Thu Jan 12 16:45:35 2017 +0200
api: ipsec: packet transformation follows RFCs
Add explicit requirement that IPSEC in-/outbound operations transform packet headers according to the standards (RFCs).
Signed-off-by: Petri Savolainen petri.savolainen@nokia.com Reviewed-by: Bill Fischofer bill.fischofer@linaro.org Reviewed-by: Nikhil Agarwal Nikhil.agarwal@linaro.org Reviewed-by: Balasubramanian Manoharan bala.manoharan@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/include/odp/api/spec/ipsec.h b/include/odp/api/spec/ipsec.h index 255bb796..66222d86 100644 --- a/include/odp/api/spec/ipsec.h +++ b/include/odp/api/spec/ipsec.h @@ -726,9 +726,6 @@ typedef struct odp_ipsec_op_result_t { * @see odp_packet_l3_offset(), odp_packet_l4_offset(), * odp_packet_has_ipv4(), odp_packet_has_ipv6(), * odp_packet_has_ipfrag(), odp_packet_has_ipsec() - * - * @note The amount and content of packet data before the IP header is - * implementation specific. */ odp_packet_t *pkt;
@@ -770,6 +767,14 @@ typedef struct odp_ipsec_op_result_t { * input 'pkt' array to output 'pkt' array. Packet order is not guaranteed * between calling threads. * + * Input packets must not be IP fragments. + * + * The operation does packet transformation according to IPSEC standards (see + * e.g. RFC 4302 and 4303). Resulting packets are well formed, reconstructed + * original IP packets, with IPSEC headers removed and valid header field values + * restored. The amount and content of packet data before the IP header is + * undefined. + * * @param input Operation input parameters * @param[out] output Operation results * @@ -804,6 +809,11 @@ int odp_ipsec_in(const odp_ipsec_op_param_t *input, * input 'pkt' array to output 'pkt' array. Packet order is not guaranteed * between calling threads. * + * The operation does packet transformation according to IPSEC standards (see + * e.g. RFC 4302 and 4303). Resulting packets are well formed IP packets + * with IPSEC, etc headers constructed according to the standards. The amount + * and content of packet data before the IP header is undefined. + * * @param input Operation input parameters * @param[out] output Operation results *
commit bd31f839f8d64ca475c88ef075ccc3be4d142027 Author: Petri Savolainen petri.savolainen@nokia.com Date: Fri Dec 23 12:33:36 2016 +0200
api: ipsec: add algorithm capabilities
Added the same algorithm capabilities API that was added to crypto API. IPSEC capabilities may be more limited than bulk crypto, since IPSEC RFCs limit the set of valid key lengths, etc options.
Signed-off-by: Petri Savolainen petri.savolainen@nokia.com Reviewed-by: Bill Fischofer bill.fischofer@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/include/odp/api/spec/ipsec.h b/include/odp/api/spec/ipsec.h index 86f66e63..255bb796 100644 --- a/include/odp/api/spec/ipsec.h +++ b/include/odp/api/spec/ipsec.h @@ -441,6 +441,46 @@ typedef struct odp_ipsec_sa_param_t { int odp_ipsec_capability(odp_ipsec_capability_t *capa);
/** + * Query supported IPSEC cipher algorithm capabilities + * + * Outputs all supported configuration options for the algorithm. Output is + * sorted (from the smallest to the largest) first by key length, then by IV + * length. Use this information to select key lengths, etc cipher algorithm + * options for SA creation (odp_ipsec_crypto_param_t). + * + * @param cipher Cipher algorithm + * @param[out] capa Array of capability structures for output + * @param num Maximum number of capability structures to output + * + * @return Number of capability structures for the algorithm. If this is larger + * than 'num', only 'num' first structures were output and application + * may call the function again with a larger value of 'num'. + * @retval <0 on failure + */ +int odp_ipsec_cipher_capability(odp_cipher_alg_t cipher, + odp_crypto_cipher_capability_t capa[], int num); + +/** + * Query supported IPSEC authentication algorithm capabilities + * + * Outputs all supported configuration options for the algorithm. Output is + * sorted (from the smallest to the largest) first by digest length, then by key + * length. Use this information to select key lengths, etc authentication + * algorithm options for SA creation (odp_ipsec_crypto_param_t). + * + * @param auth Authentication algorithm + * @param[out] capa Array of capability structures for output + * @param num Maximum number of capability structures to output + * + * @return Number of capability structures for the algorithm. If this is larger + * than 'num', only 'num' first structures were output and application + * may call the function again with a larger value of 'num'. + * @retval <0 on failure + */ +int odp_ipsec_auth_capability(odp_auth_alg_t auth, + odp_crypto_auth_capability_t capa[], int num); + +/** * Initialize IPSEC configuration options * * Initialize an odp_ipsec_config_t to its default values.
commit edccba8e41c67909f2485ec483252dc9193618a6 Author: Petri Savolainen petri.savolainen@nokia.com Date: Thu Dec 1 11:17:43 2016 +0200
api: ipsec: added IPSEC API
Added definitions for a look-a-side IPSEC offload API. In addition to IPSEC packet transformations, it also supports: * inbound SA look up * outbound IP fragmentation
Signed-off-by: Petri Savolainen petri.savolainen@nokia.com Reviewed-by: Balasubramanian Manoharan bala.manoharan@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/include/odp/api/spec/event.h b/include/odp/api/spec/event.h index fdfa52d1..75c0bbc2 100644 --- a/include/odp/api/spec/event.h +++ b/include/odp/api/spec/event.h @@ -39,7 +39,7 @@ extern "C" { * @typedef odp_event_type_t * ODP event types: * ODP_EVENT_BUFFER, ODP_EVENT_PACKET, ODP_EVENT_TIMEOUT, - * ODP_EVENT_CRYPTO_COMPL + * ODP_EVENT_CRYPTO_COMPL, ODP_EVENT_IPSEC_RESULT */
/** diff --git a/include/odp/api/spec/ipsec.h b/include/odp/api/spec/ipsec.h new file mode 100644 index 00000000..86f66e63 --- /dev/null +++ b/include/odp/api/spec/ipsec.h @@ -0,0 +1,883 @@ +/* Copyright (c) 2016, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @file + * + * ODP IPSEC API + */ + +#ifndef ODP_API_IPSEC_H_ +#define ODP_API_IPSEC_H_ +#include <odp/visibility_begin.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/crypto.h> + +/** @defgroup odp_ipsec ODP IPSEC + * Operations of IPSEC API. + * @{ + */ + +/** + * @typedef odp_ipsec_sa_t + * IPSEC Security Association (SA) + */ + + /** + * @def ODP_IPSEC_SA_INVALID + * Invalid IPSEC SA + */ + +/** + * IPSEC operation mode + */ +typedef enum odp_ipsec_op_mode_t { + /** Synchronous IPSEC operation + * + * Application uses synchronous IPSEC operations, + * which output all results on function return. + */ + ODP_IPSEC_OP_MODE_SYNC = 0, + + /** Asynchronous IPSEC operation + * + * Application uses asynchronous IPSEC operations, + * which return results via events. + */ + ODP_IPSEC_OP_MODE_ASYNC + +} odp_ipsec_op_mode_t; + +/** + * IPSEC capability + */ +typedef struct odp_ipsec_capability_t { + /** Maximum number of IPSEC SAs */ + uint32_t max_num_sa; + + /** Synchronous IPSEC operation mode (ODP_IPSEC_OP_MODE_SYNC) support + * + * 0: Synchronous mode is not supported + * 1: Synchronous mode is supported + * 2: Synchronous mode is supported and preferred + */ + uint8_t op_mode_sync; + + /** Asynchronous IPSEC operation mode (ODP_IPSEC_OP_MODE_ASYNC) support + * + * 0: Asynchronous mode is not supported + * 1: Asynchronous mode is supported + * 2: Asynchronous mode is supported and preferred + */ + uint8_t op_mode_async; + + /** Soft expiry limit in seconds support + * + * 0: Limit is not supported + * 1: Limit is supported + */ + uint8_t soft_limit_sec; + + /** Hard expiry limit in seconds support + * + * 0: Limit is not supported + * 1: Limit is supported + */ + uint8_t hard_limit_sec; + + /** Supported cipher algorithms */ + odp_crypto_cipher_algos_t ciphers; + + /** Supported authentication algorithms */ + odp_crypto_auth_algos_t auths; + +} odp_ipsec_capability_t; + +/** + * IPSEC configuration options + */ +typedef struct odp_ipsec_config_t { + /** IPSEC operation mode. Application selects which mode (sync or async) + * will be used for IPSEC operations. + * + * @see odp_ipsec_in(), odp_ipsec_in_enq() + */ + odp_ipsec_op_mode_t op_mode; + +} odp_ipsec_config_t; + +/** + * IPSEC SA direction + */ +typedef enum odp_ipsec_dir_t { + /** Inbound IPSEC SA */ + ODP_IPSEC_DIR_INBOUND = 0, + + /** Outbound IPSEC SA */ + ODP_IPSEC_DIR_OUTBOUND + +} odp_ipsec_dir_t; + +/** + * IPSEC protocol mode + */ +typedef enum odp_ipsec_mode_t { + /** IPSEC tunnel mode */ + ODP_IPSEC_MODE_TUNNEL = 0, + + /** IPSEC transport mode */ + ODP_IPSEC_MODE_TRANSPORT + +} odp_ipsec_mode_t; + +/** + * IPSEC protocol + */ +typedef enum odp_ipsec_protocol_t { + /** ESP protocol */ + ODP_IPSEC_ESP = 0, + + /** AH protocol */ + ODP_IPSEC_AH + +} odp_ipsec_protocol_t; + +/** + * IPSEC tunnel type + */ +typedef enum odp_ipsec_tunnel_type_t { + /** Outer header is IPv4 */ + ODP_IPSEC_TUNNEL_IPV4 = 0, + + /** Outer header is IPv6 */ + ODP_IPSEC_TUNNEL_IPV6 + +} odp_ipsec_tunnel_type_t; + +/** + * IPSEC crypto parameters + */ +typedef struct odp_ipsec_crypto_param_t { + /** Cipher algorithm */ + odp_cipher_alg_t cipher_alg; + + /** Cipher key */ + odp_crypto_key_t cipher_key; + + /** Authentication algorithm */ + odp_auth_alg_t auth_alg; + + /** Authentication key */ + odp_crypto_key_t auth_key; + +} odp_ipsec_crypto_param_t; + +/** + * IPSEC tunnel parameters + * + * These parameters are used to build outbound tunnel headers. All values are + * passed in CPU native byte / bit order if not specified otherwise. + * IP addresses must be in NETWORK byte order as those are passed in with + * pointers and copied byte-by-byte from memory to the packet. + */ +typedef struct odp_ipsec_tunnel_param_t { + /** Tunnel type: IPv4 or IPv6 */ + odp_ipsec_tunnel_type_t type; + + union { + /** IPv4 header parameters */ + struct { + /** IPv4 source address (NETWORK ENDIAN) */ + void *src_addr; + + /** IPv4 destination address (NETWORK ENDIAN) */ + void *dst_addr; + + /** IPv4 Differentiated Services Code Point */ + uint8_t dscp; + + /** IPv4 Don't Fragment bit */ + uint8_t df; + + /** IPv4 Time To Live */ + uint8_t ttl; + } ipv4; + + /** IPv6 header parameters */ + struct { + /** IPv6 source address (NETWORK ENDIAN) */ + void *src_addr; + + /** IPv6 destination address (NETWORK ENDIAN) */ + void *dst_addr; + + /** IPv6 Differentiated Services Code Point */ + uint8_t dscp; + + /** IPv6 flow label */ + uint32_t flabel; + + /** IPv6 hop limit */ + uint8_t hlimit; + } ipv6; + }; +} odp_ipsec_tunnel_param_t; + +/** + * IPSEC SA option flags + */ +typedef struct odp_ipsec_sa_opt_t { + /** Extended Sequence Numbers (ESN) + * + * * 1: Use extended (64 bit) sequence numbers + * * 0: Use normal sequence numbers + */ + uint32_t esn : 1; + + /** UDP encapsulation + * + * * 1: Do UDP encapsulation/decapsulation so that IPSEC packets can + * traverse through NAT boxes. + * * 0: No UDP encapsulation + */ + uint32_t udp_encap : 1; + + /** Copy DSCP bits + * + * * 1: Copy IPv4 or IPv6 DSCP bits from inner IP header to + * the outer IP header in encapsulation, and vice versa in + * decapsulation. + * * 0: Use values from odp_ipsec_tunnel_param_t in encapsulation and + * do not change DSCP field in decapsulation. + */ + uint32_t copy_dscp : 1; + + /** Copy IPv6 Flow Label + * + * * 1: Copy IPv6 flow label from inner IPv6 header to the + * outer IPv6 header. + * * 0: Use value from odp_ipsec_tunnel_param_t + */ + uint32_t copy_flabel : 1; + + /** Copy IPv4 Don't Fragment bit + * + * * 1: Copy the DF bit from the inner IPv4 header to the outer + * IPv4 header. + * * 0: Use value from odp_ipsec_tunnel_param_t + */ + uint32_t copy_df : 1; + + /** Decrement inner packet Time To Live (TTL) field + * + * * 1: In tunnel mode, decrement inner packet IPv4 TTL or + * IPv6 Hop Limit after tunnel decapsulation, or before tunnel + * encapsulation. + * * 0: Inner packet is not modified. + */ + uint32_t dec_ttl : 1; + +} odp_ipsec_sa_opt_t; + +/** + * IPSEC SA lifetime limits + * + * These limits are used for setting up SA lifetime. IPSEC operations check + * against the limits and output a status code (e.g. soft_exp_bytes) when + * a limit is crossed. Any number of limits may be used simultaneously. + * Use zero when there is no limit. + */ +typedef struct odp_ipsec_lifetime_t { + /** Soft expiry limits for the session */ + struct { + /** Limit in seconds from the SA creation */ + uint64_t sec; + + /** Limit in bytes */ + uint64_t bytes; + + /** Limit in packet */ + uint64_t packets; + } soft_limit; + + /** Hard expiry limits for the session */ + struct { + /** Limit in seconds from the SA creation */ + uint64_t sec; + + /** Limit in bytes */ + uint64_t bytes; + + /** Limit in packet */ + uint64_t packets; + } hard_limit; +} odp_ipsec_lifetime_t; + +/** + * Fragmentation mode + * + * These options control outbound IP packet fragmentation offload. When offload + * is enabled, IPSEC operation will determine if fragmentation is needed and + * does it according to the mode. + */ +typedef enum odp_ipsec_frag_mode_t { + /** Do not fragment IP packets */ + ODP_IPSEC_FRAG_DISABLED = 0, + + /** Fragment IP packet before IPSEC operation */ + ODP_IPSEC_FRAG_BEFORE, + + /** Fragment IP packet after IPSEC operation */ + ODP_IPSEC_FRAG_AFTER, + + /** Only check if IP fragmentation is needed, + * do not fragment packets. */ + ODP_IPSEC_FRAG_CHECK +} odp_ipsec_frag_mode_t; + +/** + * Packet lookup mode + */ +typedef enum odp_ipsec_lookup_mode_t { + /** Inbound SA lookup is disabled. */ + ODP_IPSEC_LOOKUP_DISABLED = 0, + + /** Inbound SA lookup is enabled. Used SPI values must be unique. */ + ODP_IPSEC_LOOKUP_IN_UNIQUE_SA + +} odp_ipsec_lookup_mode_t; + +/** + * IPSEC Security Association (SA) parameters + */ +typedef struct odp_ipsec_sa_param_t { + /** IPSEC SA direction: inbound or outbound */ + odp_ipsec_dir_t dir; + + /** IPSEC protocol: ESP or AH */ + odp_ipsec_protocol_t proto; + + /** IPSEC protocol mode: transport or tunnel */ + odp_ipsec_mode_t mode; + + /** Parameters for crypto and authentication algorithms */ + odp_ipsec_crypto_param_t crypto; + + /** Parameters for tunnel mode */ + odp_ipsec_tunnel_param_t tunnel; + + /** Fragmentation mode */ + odp_ipsec_frag_mode_t frag_mode; + + /** Various SA option flags */ + odp_ipsec_sa_opt_t opt; + + /** SA lifetime parameters */ + odp_ipsec_lifetime_t lifetime; + + /** SA lookup mode */ + odp_ipsec_lookup_mode_t lookup_mode; + + /** Minimum anti-replay window size. Use 0 to disable anti-replay + * service. */ + uint32_t antireplay_ws; + + /** Initial sequence number */ + uint64_t seq; + + /** SPI value */ + uint32_t spi; + + /** MTU for outbound IP fragmentation offload + * + * This is the maximum length of IP packets that outbound IPSEC + * operations may produce. The value may be updated later with + * odp_ipsec_mtu_update(). + */ + uint32_t mtu; + + /** Destination queue for IPSEC events + * + * Operations in asynchronous mode enqueue resulting events into + * this queue. + */ + odp_queue_t dest_queue; + + /** User defined SA context pointer + * + * User defined context pointer associated with the SA. + * The implementation may prefetch the context data. Default value + * of the pointer is NULL. + */ + void *context; + + /** Context data length + * + * User defined context data length in bytes for prefetching. + * The implementation may use this value as a hint for the number of + * context data bytes to prefetch. Default value is zero (no hint). + */ + uint32_t context_len; + +} odp_ipsec_sa_param_t; + +/** + * Query IPSEC capabilities + * + * Outputs IPSEC capabilities on success. + * + * @param[out] capa Pointer to capability structure for output + * + * @retval 0 on success + * @retval <0 on failure + */ +int odp_ipsec_capability(odp_ipsec_capability_t *capa); + +/** + * Initialize IPSEC configuration options + * + * Initialize an odp_ipsec_config_t to its default values. + * + * @param[out] config Pointer to IPSEC configuration structure + */ +void odp_ipsec_config_init(odp_ipsec_config_t *config); + +/** + * Global IPSEC configuration + * + * Initialize and configure IPSEC offload with global configuration options. + * This must be called before any SAs are created. Use odp_ipsec_capability() + * to examine which features and modes are supported. + * + * @param config Pointer to IPSEC configuration structure + * + * @retval 0 on success + * @retval <0 on failure + * + * @see odp_ipsec_capability(), odp_ipsec_config_init() + */ +int odp_ipsec_config(const odp_ipsec_config_t *config); + +/** + * Initialize IPSEC SA parameters + * + * Initialize an odp_ipsec_sa_param_t to its default values for all fields. + * + * @param param Pointer to the parameter structure + */ +void odp_ipsec_sa_param_init(odp_ipsec_sa_param_t *param); + +/** + * Create IPSEC SA + * + * Create a new IPSEC SA according to the parameters. + * + * @param param IPSEC SA parameters + * + * @return IPSEC SA handle + * @retval ODP_IPSEC_SA_INVALID on failure + * + * @see odp_ipsec_sa_param_init() + */ +odp_ipsec_sa_t odp_ipsec_sa_create(odp_ipsec_sa_param_t *param); + +/** + * Destroy IPSEC SA + * + * Destroy an unused IPSEC SA. Result is undefined if the SA is being used + * (i.e. asynchronous operation is in progress). + * + * @param sa IPSEC SA to be destroyed + * + * @retval 0 On success + * @retval <0 On failure + * + * @see odp_ipsec_sa_create() + */ +int odp_ipsec_sa_destroy(odp_ipsec_sa_t sa); + +/** + * Printable format of odp_ipsec_sa_t + * + * @param sa IPSEC SA handle + * + * @return uint64_t value that can be used to print/display this handle + */ +uint64_t odp_ipsec_sa_to_u64(odp_ipsec_sa_t sa); + +/** + * IPSEC operation level options + * + * These may be used to override some SA level options + */ +typedef struct odp_ipsec_op_opt_t { + /** Fragmentation mode */ + odp_ipsec_frag_mode_t mode; + +} odp_ipsec_op_opt_t; + +/** IPSEC operation status has no errors */ +#define ODP_IPSEC_OK 0 + +/** IPSEC operation status */ +typedef union odp_ipsec_status_t { + /** Error flags */ + struct { + /** Protocol error. Not a valid ESP or AH packet. */ + uint32_t proto : 1; + + /** SA lookup failed */ + uint32_t sa_lookup : 1; + + /** Authentication failed */ + uint32_t auth : 1; + + /** Anti-replay check failed */ + uint32_t antireplay : 1; + + /** Other algorithm error */ + uint32_t alg : 1; + + /** Packet does not fit into the given MTU size */ + uint32_t mtu : 1; + + /** Soft lifetime expired: seconds */ + uint32_t soft_exp_sec : 1; + + /** Soft lifetime expired: bytes */ + uint32_t soft_exp_bytes : 1; + + /** Soft lifetime expired: packets */ + uint32_t soft_exp_packets : 1; + + /** Hard lifetime expired: seconds */ + uint32_t hard_exp_sec : 1; + + /** Hard lifetime expired: bytes */ + uint32_t hard_exp_bytes : 1; + + /** Hard lifetime expired: packets */ + uint32_t hard_exp_packets : 1; + } error; + + /** All bits of the bit field structure + * + * This field can be used to set, clear or compare multiple flags. + * For example, 'status.all != ODP_IPSEC_OK' checks if there are any + * errors. + */ + uint32_t all; + +} odp_ipsec_status_t; + +/** + * IPSEC operation input parameters + */ +typedef struct odp_ipsec_op_param_t { + /** Number of packets to be processed */ + int num_pkt; + + /** Number of SAs + * + * Valid values are: + * * 0: No SAs (default) + * * 1: Single SA for all packets + * * num_pkt: SA per packet + */ + int num_sa; + + /** Number of operation options + * + * Valid values are: + * * 0: No options (default) + * * 1: Single option for all packets + * * num_pkt: An option per packet + */ + int num_opt; + + /** Pointer to an array of packets + * + * Each packet must have a valid value for these meta-data: + * * L3 offset: Offset to the first byte of the (outmost) IP header + * * L4 offset: For inbound direction, when udp_encap is enabled - + * offset to the first byte of the encapsulating UDP + * header + * + * @see odp_packet_l3_offset(), odp_packet_l4_offset() + */ + odp_packet_t *pkt; + + /** Pointer to an array of IPSEC SAs + * + * May be NULL when num_sa is zero. + */ + odp_ipsec_sa_t *sa; + + /** Pointer to an array of operation options + * + * May be NULL when num_opt is zero. + */ + odp_ipsec_op_opt_t *opt; + +} odp_ipsec_op_param_t; + +/** + * IPSEC operation result for a packet + */ +typedef struct odp_ipsec_packet_result_t { + /** IPSEC operation status */ + odp_ipsec_status_t status; + + /** Number of output packets created from the corresponding input packet + * + * Without fragmentation offload this is always one. However, if the + * input packet was fragmented during the operation this is larger than + * one for the first fragment and zero for the rest of the fragments + * (following the first one in the 'pkt' array). + */ + int num_out; + + /** IPSEC SA that was used to create the packet + * + * Operation updates this SA handle value, when SA look up is performed + * as part of the operation and the look up is successful. Operation + * status code indicates if the look up failed. Otherwise, the SA + * provided by the application is copied here. + */ + odp_ipsec_sa_t sa; + +} odp_ipsec_packet_result_t; + +/** + * IPSEC operation results + */ +typedef struct odp_ipsec_op_result_t { + /** Number of packets + * + * Application sets this to the maximum number of packets the operation + * may output (number of elements in 'pkt' and 'res' arrays). + * The operation updates it with the actual number of packets + * outputted. + */ + int num_pkt; + + /** Pointer to an array of packets + * + * Operation outputs packets into this array. The array must have + * at least 'num_pkt' elements. + * + * Each successfully transformed packet has a valid value for these + * meta-data: + * * L3 offset: Offset to the first byte of the (outmost) IP header + * * L4 offset: Offset to the first byte of the valid and known L4 + * header (immediately following the IP header). + * * Various flags about L3 and L4 layers: + * has_l3, has_l4, has_ipv4, has_ipv6, has_ipfrag, + * has_ipsec, has_udp, has_tcp, etc depending on + * the resulted packet format + * + * @see odp_packet_l3_offset(), odp_packet_l4_offset(), + * odp_packet_has_ipv4(), odp_packet_has_ipv6(), + * odp_packet_has_ipfrag(), odp_packet_has_ipsec() + * + * @note The amount and content of packet data before the IP header is + * implementation specific. + */ + odp_packet_t *pkt; + + /** Pointer to an array of per packet operation results + * + * Operation outputs results for each outputted packet into this array. + * The array must have at least 'num_pkt' elements. The results include + * operation status and packet form information for each outputted + * packet. + * + * For example, some packets may not have been transformed due to + * an error, but the original packet is returned with appropriate + * packet result information instead. + */ + odp_ipsec_packet_result_t *res; + +} odp_ipsec_op_result_t; + +/** + * Inbound synchronous IPSEC operation + * + * This operation does inbound IPSEC processing in synchronous mode + * (ODP_IPSEC_OP_MODE_SYNC). A successful operation returns the number of + * packets consumed and outputs a new packet handle as well as an operation + * result for each outputted packet. The operation does not modify packets that + * it does not consume. It cannot consume all input packets if 'output.num_pkt' + * is smaller than 'input.num_pkt'. + * + * Packet context pointer and user area content are copied from input to output + * packets. Output packets are allocated from the same pool(s) as input packets. + * + * When 'input.num_sa' is zero, this operation performs SA look up for each + * packet. Otherwise, application must provide the SA(s) as part of operation + * input parameters (odp_ipsec_op_param_t). The operation outputs used SA(s) as + * part of per packet operation results (odp_ipsec_packet_result_t), or an error + * status if a SA was not found. + * + * Packets are processed in the input order. Packet order is maintained from + * input 'pkt' array to output 'pkt' array. Packet order is not guaranteed + * between calling threads. + * + * @param input Operation input parameters + * @param[out] output Operation results + * + * @return Number of input packets consumed (0 ... input.num_pkt) + * @retval <0 On failure + * + * @see odp_packet_user_ptr(), odp_packet_user_area() + */ +int odp_ipsec_in(const odp_ipsec_op_param_t *input, + odp_ipsec_op_result_t *output); + +/** + * Outbound synchronous IPSEC operation + * + * This operation does outbound IPSEC processing in synchronous mode + * (ODP_IPSEC_OP_MODE_SYNC). A successful operation returns the number of + * packets consumed and outputs a new packet handle as well as an operation + * result for each outputted packet. The operation does not modify packets that + * it does not consume. It cannot consume all input packets if 'output.num_pkt' + * is smaller than 'input.num_pkt'. + * + * Packet context pointer and user area content are copied from input to output + * packets. Output packets are allocated from the same pool(s) as input packets. + * + * When outbound IP fragmentation offload is enabled, the number of outputted + * packets (and corresponding per packet results) may be greater than + * the number of input packets. In that case, application may examine 'num_out' + * of each packet result (odp_ipsec_packet_result_t) to find out which + * fragments are originated from which input packet. + * + * Packets are processed in the input order. Packet order is maintained from + * input 'pkt' array to output 'pkt' array. Packet order is not guaranteed + * between calling threads. + * + * @param input Operation input parameters + * @param[out] output Operation results + * + * @return Number of input packets consumed (0 ... input.num_pkt) + * @retval <0 On failure + * + * @see odp_packet_user_ptr(), odp_packet_user_area() + */ +int odp_ipsec_out(const odp_ipsec_op_param_t *input, + odp_ipsec_op_result_t *output); + +/** + * Inbound asynchronous IPSEC operation + * + * This operation does inbound IPSEC processing in asynchronous mode + * (ODP_IPSEC_OP_MODE_ASYNC). It processes packets otherwise identically to + * odp_ipsec_in(), but outputs all results through one or more + * ODP_EVENT_IPSEC_RESULT events with the following ordering considerations. + * + * Asynchronous mode maintains (operation input) packet order per SA when + * application calls the operation within an ordered or atomic scheduler context + * of the same queue. Packet order is also maintained when application + * otherwise guarantees (e.g. using locks) that the operation is not called + * simultaneously from multiple threads for the same SA(s). Resulting + * events for the same SA are enqueued in order, and packet handles (for the + * same SA) are stored in order within an event. + * + * @param input Operation input parameters + * + * @return Number of input packets consumed (0 ... input.num_pkt) + * @retval <0 On failure + * + * @see odp_ipsec_in(), odp_ipsec_result() + */ +int odp_ipsec_in_enq(const odp_ipsec_op_param_t *input); + +/** + * Outbound asynchronous IPSEC operation + * + * This operation does outbound IPSEC processing in asynchronous mode + * (ODP_IPSEC_OP_MODE_ASYNC). It processes packets otherwise identically to + * odp_ipsec_out(), but outputs all results through one or more + * ODP_EVENT_IPSEC_RESULT events with the following ordering considerations. + * + * Asynchronous mode maintains (operation input) packet order per SA when + * application calls the operation within an ordered or atomic scheduler context + * of the same queue. Packet order is also maintained when application + * otherwise guarantees (e.g. using locks) that the operation is not called + * simultaneously from multiple threads for the same SA(s). Resulting + * events for the same SA are enqueued in order, and packet handles (for the + * same SA) are stored in order within an event. + * + * @param input Operation input parameters + * + * @return Number of input packets consumed (0 ... input.num_pkt) + * @retval <0 On failure + * + * @see odp_ipsec_out(), odp_ipsec_result() + */ +int odp_ipsec_out_enq(const odp_ipsec_op_param_t *input); + +/** + * Get IPSEC results from an ODP_EVENT_IPSEC_RESULT event + * + * Copies IPSEC operation results from an event. The event must be of + * type ODP_EVENT_IPSEC_RESULT. It must be freed before the application passes + * any resulting packet handles to other ODP calls. + * + * @param[out] result Pointer to operation result for output. Maybe NULL, if + * application is interested only on the number of + * packets. + * @param event An ODP_EVENT_IPSEC_RESULT event + * + * @return Number of packets in the event. If this is larger than + * 'result.num_pkt', all packets did not fit into result struct and + * application must call the function again with a larger result struct. + * @retval <0 On failure + * + * @see odp_ipsec_in_enq(), odp_ipsec_out_enq() + */ +int odp_ipsec_result(odp_ipsec_op_result_t *result, odp_event_t event); + +/** + * Update MTU for outbound IP fragmentation + * + * When IP fragmentation offload is enabled, the SA is created with an MTU. + * This call may be used to update MTU at any time. MTU updates are not + * expected to happen very frequently. + * + * @param sa IPSEC SA to be updated + * @param mtu The new MTU value + * + * @retval 0 On success + * @retval <0 On failure + */ +int odp_ipsec_mtu_update(odp_ipsec_sa_t sa, uint32_t mtu); + +/** + * Get user defined SA context pointer + * + * @param sa IPSEC SA handle + * + * @return User defined SA context pointer value + * @retval NULL On failure + */ +void *odp_ipsec_sa_context(odp_ipsec_sa_t sa); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#include <odp/visibility_end.h> +#endif diff --git a/include/odp_api.h b/include/odp_api.h index 060ec888..962415fa 100644 --- a/include/odp_api.h +++ b/include/odp_api.h @@ -58,6 +58,7 @@ extern "C" { #include <odp/api/spinlock_recursive.h> #include <odp/api/rwlock_recursive.h> #include <odp/api/std_clib.h> +#include <odp/api/ipsec.h>
#ifdef __cplusplus } diff --git a/platform/Makefile.inc b/platform/Makefile.inc index 9844a58a..8fcb91ad 100644 --- a/platform/Makefile.inc +++ b/platform/Makefile.inc @@ -35,6 +35,7 @@ odpapispecinclude_HEADERS = \ $(top_srcdir)/include/odp/api/spec/hash.h \ $(top_srcdir)/include/odp/api/spec/hints.h \ $(top_srcdir)/include/odp/api/spec/init.h \ + $(top_srcdir)/include/odp/api/spec/ipsec.h \ $(top_srcdir)/include/odp/api/spec/packet.h \ $(top_srcdir)/include/odp/api/spec/packet_flags.h \ $(top_srcdir)/include/odp/api/spec/packet_io.h \ diff --git a/platform/linux-generic/Makefile.am b/platform/linux-generic/Makefile.am index 0ad0b8e2..50218762 100644 --- a/platform/linux-generic/Makefile.am +++ b/platform/linux-generic/Makefile.am @@ -39,6 +39,7 @@ odpapiinclude_HEADERS = \ $(srcdir)/include/odp/api/hash.h \ $(srcdir)/include/odp/api/hints.h \ $(srcdir)/include/odp/api/init.h \ + $(srcdir)/include/odp/api/ipsec.h \ $(srcdir)/include/odp/api/packet_flags.h \ $(srcdir)/include/odp/api/packet.h \ $(srcdir)/include/odp/api/packet_io.h \ @@ -80,6 +81,7 @@ odpapiplatinclude_HEADERS = \ $(srcdir)/include/odp/api/plat/crypto_types.h \ $(srcdir)/include/odp/api/plat/event_types.h \ $(srcdir)/include/odp/api/plat/init_types.h \ + $(srcdir)/include/odp/api/plat/ipsec_types.h \ $(srcdir)/include/odp/api/plat/packet_flag_inlines.h \ $(srcdir)/include/odp/api/plat/packet_flag_inlines_api.h \ $(srcdir)/include/odp/api/plat/packet_inlines.h \ diff --git a/platform/linux-generic/include/odp/api/ipsec.h b/platform/linux-generic/include/odp/api/ipsec.h new file mode 100644 index 00000000..44c5d025 --- /dev/null +++ b/platform/linux-generic/include/odp/api/ipsec.h @@ -0,0 +1,36 @@ +/* Copyright (c) 2016, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @file + * + * ODP IPSEC API - platform specific header + */ + +#ifndef ODP_PLAT_IPSEC_H_ +#define ODP_PLAT_IPSEC_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/plat/ipsec_types.h> + +/** @ingroup odp_ipsec + * @{ + */ + +/** + * @} + */ + +#include <odp/api/spec/ipsec.h> + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/platform/linux-generic/include/odp/api/plat/event_types.h b/platform/linux-generic/include/odp/api/plat/event_types.h index a1aa0e45..0f517834 100644 --- a/platform/linux-generic/include/odp/api/plat/event_types.h +++ b/platform/linux-generic/include/odp/api/plat/event_types.h @@ -39,6 +39,7 @@ typedef enum odp_event_type_t { ODP_EVENT_PACKET = 2, ODP_EVENT_TIMEOUT = 3, ODP_EVENT_CRYPTO_COMPL = 4, + ODP_EVENT_IPSEC_RESULT = 5 } odp_event_type_t;
/** diff --git a/platform/linux-generic/include/odp/api/plat/ipsec_types.h b/platform/linux-generic/include/odp/api/plat/ipsec_types.h new file mode 100644 index 00000000..a36cdada --- /dev/null +++ b/platform/linux-generic/include/odp/api/plat/ipsec_types.h @@ -0,0 +1,39 @@ +/* Copyright (c) 2016, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @file + * + * ODP IPSEC API - platform specific types + */ + +#ifndef ODP_PLAT_IPSEC_TYPES_H_ +#define ODP_PLAT_IPSEC_TYPES_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/std_types.h> +#include <odp/api/plat/strong_types.h> + +/** @ingroup odp_ipsec + * @{ + */ + +typedef ODP_HANDLE_T(odp_ipsec_sa_t); + +#define ODP_IPSEC_SA_INVALID _odp_cast_scalar(odp_ipsec_sa_t, 0xffffffff) + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif
commit 10f655cbef0dd7237f2ae49d8b2cd35a963ca1ec Author: Maxim Uvarov maxim.uvarov@linaro.org Date: Tue May 30 16:14:57 2017 +0300
mergefix: remove duplicate declaration
Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/platform/linux-generic/odp_crypto.c b/platform/linux-generic/odp_crypto.c index 157a4152..a993542f 100644 --- a/platform/linux-generic/odp_crypto.c +++ b/platform/linux-generic/odp_crypto.c @@ -656,83 +656,6 @@ int odp_crypto_auth_capability(odp_auth_alg_t auth, return num; }
-int odp_crypto_cipher_capability(odp_cipher_alg_t cipher, - odp_crypto_cipher_capability_t dst[], - int num_copy) -{ - const odp_crypto_cipher_capability_t *src; - int num; - int size = sizeof(odp_crypto_cipher_capability_t); - - switch (cipher) { - case ODP_CIPHER_ALG_NULL: - src = NULL; - num = 0; - break; - case ODP_CIPHER_ALG_DES: - src = cipher_capa_des; - num = sizeof(cipher_capa_des) / size; - break; - case ODP_CIPHER_ALG_3DES_CBC: - src = cipher_capa_trides_cbc; - num = sizeof(cipher_capa_trides_cbc) / size; - break; - case ODP_CIPHER_ALG_AES_CBC: - src = cipher_capa_aes_cbc; - num = sizeof(cipher_capa_aes_cbc) / size; - break; - case ODP_CIPHER_ALG_AES_GCM: - src = cipher_capa_aes_gcm; - num = sizeof(cipher_capa_aes_gcm) / size; - break; - default: - return -1; - } - - if (num < num_copy) - num_copy = num; - - memcpy(dst, src, num_copy * size); - - return num; -} - -int odp_crypto_auth_capability(odp_auth_alg_t auth, - odp_crypto_auth_capability_t dst[], int num_copy) -{ - const odp_crypto_auth_capability_t *src; - int num; - int size = sizeof(odp_crypto_auth_capability_t); - - switch (auth) { - case ODP_AUTH_ALG_NULL: - src = NULL; - num = 0; - break; - case ODP_AUTH_ALG_MD5_HMAC: - src = auth_capa_md5_hmac; - num = sizeof(auth_capa_md5_hmac) / size; - break; - case ODP_AUTH_ALG_SHA256_HMAC: - src = auth_capa_sha256_hmac; - num = sizeof(auth_capa_sha256_hmac) / size; - break; - case ODP_AUTH_ALG_AES_GCM: - src = auth_capa_aes_gcm; - num = sizeof(auth_capa_aes_gcm) / size; - break; - default: - return -1; - } - - if (num < num_copy) - num_copy = num; - - memcpy(dst, src, num_copy * size); - - return num; -} - int odp_crypto_session_create(odp_crypto_session_param_t *param, odp_crypto_session_t *session_out,
commit 60e950dbd1a26ff18db663b6b9fb5f4fc17c6785 Author: Dmitry Eremin-Solenikov dmitry.ereminsolenikov@linaro.org Date: Mon May 15 23:24:38 2017 +0300
linux-generic: packet: add functions to optimize memset and memcmp paths
Add function implementing memset and memcmp on packet object.
Signed-off-by: Dmitry Eremin-Solenikov dmitry.ereminsolenikov@linaro.org Reviewed-by: <Bill Fischofer bill.fischofer@linaro.org> Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/platform/linux-generic/include/odp_packet_internal.h b/platform/linux-generic/include/odp_packet_internal.h index 0a9f1779..4c8d7515 100644 --- a/platform/linux-generic/include/odp_packet_internal.h +++ b/platform/linux-generic/include/odp_packet_internal.h @@ -268,6 +268,12 @@ int packet_parse_common(packet_parser_t *pkt_hdr, const uint8_t *ptr,
int _odp_cls_parse(odp_packet_hdr_t *pkt_hdr, const uint8_t *parseptr);
+int _odp_packet_set_data(odp_packet_t pkt, uint32_t offset, + uint8_t c, uint32_t len); + +int _odp_packet_cmp_data(odp_packet_t pkt, uint32_t offset, + const void *s, uint32_t len); + #ifdef __cplusplus } #endif diff --git a/platform/linux-generic/odp_packet.c b/platform/linux-generic/odp_packet.c index c6962ce9..69098624 100644 --- a/platform/linux-generic/odp_packet.c +++ b/platform/linux-generic/odp_packet.c @@ -1665,6 +1665,54 @@ int odp_packet_move_data(odp_packet_t pkt, uint32_t dst_offset, pkt, src_offset, len); }
+int _odp_packet_set_data(odp_packet_t pkt, uint32_t offset, + uint8_t c, uint32_t len) +{ + void *mapaddr; + uint32_t seglen = 0; /* GCC */ + uint32_t setlen; + odp_packet_hdr_t *pkt_hdr = packet_hdr(pkt); + + if (offset + len > pkt_hdr->frame_len) + return -1; + + while (len > 0) { + mapaddr = packet_map(pkt_hdr, offset, &seglen, NULL); + setlen = len > seglen ? seglen : len; + memset(mapaddr, c, setlen); + offset += setlen; + len -= setlen; + } + + return 0; +} + +int _odp_packet_cmp_data(odp_packet_t pkt, uint32_t offset, + const void *s, uint32_t len) +{ + const uint8_t *ptr = s; + void *mapaddr; + uint32_t seglen = 0; /* GCC */ + uint32_t cmplen; + int ret; + odp_packet_hdr_t *pkt_hdr = packet_hdr(pkt); + + ODP_ASSERT(offset + len <= pkt_hdr->frame_len); + + while (len > 0) { + mapaddr = packet_map(pkt_hdr, offset, &seglen, NULL); + cmplen = len > seglen ? seglen : len; + ret = memcmp(mapaddr, ptr, cmplen); + if (ret != 0) + return ret; + offset += cmplen; + len -= cmplen; + ptr += cmplen; + } + + return 0; +} + /* * * Debugging
commit 1973794053d956b90e4fd0cddcb922f2ac29c2e4 Author: Dmitry Eremin-Solenikov dmitry.ereminsolenikov@linaro.org Date: Fri May 5 04:14:34 2017 +0300
linux: crypto: fix checking of GCM tags
Currently odp_crypto code will happily accept wrong tags, because the check for EVP_DecryptFinal_ex return code is incorrect. This function returns 0 if tag is incorrect, not < 0. https://bugs.linaro.org/show_bug.cgi?id=3003
Signed-off-by: Dmitry Eremin-Solenikov dmitry.ereminsolenikov@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/odp_crypto.c b/platform/linux-generic/odp_crypto.c index 6963ee62..157a4152 100644 --- a/platform/linux-generic/odp_crypto.c +++ b/platform/linux-generic/odp_crypto.c @@ -384,7 +384,7 @@ odp_crypto_alg_err_t aes_gcm_decrypt(odp_crypto_op_param_t *param, auth_len - (aad_tail - aad_head)); }
- if (EVP_DecryptFinal_ex(ctx, cipherdata + cipher_len, &plain_len) < 0) + if (EVP_DecryptFinal_ex(ctx, cipherdata + cipher_len, &plain_len) <= 0) return ODP_CRYPTO_ALG_ERR_ICV_CHECK;
return ODP_CRYPTO_ALG_ERR_NONE;
commit 31eac29b5767df7eeb72ce0e099567f05a8093fe Author: Dmitry Eremin-Solenikov dmitry.ereminsolenikov@linaro.org Date: Fri May 5 04:13:15 2017 +0300
test: crypto: add AES-GCM tests with wrong tag value
Signed-off-by: Dmitry Eremin-Solenikov dmitry.ereminsolenikov@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/crypto/odp_crypto_test_inp.c b/test/common_plat/validation/api/crypto/odp_crypto_test_inp.c index 57e7c0e0..9defdbfa 100644 --- a/test/common_plat/validation/api/crypto/odp_crypto_test_inp.c +++ b/test/common_plat/validation/api/crypto/odp_crypto_test_inp.c @@ -689,10 +689,13 @@ void crypto_test_dec_alg_aes128_gcm(void) odp_crypto_key_t cipher_key = { .data = NULL, .length = 0 }, auth_key = { .data = NULL, .length = 0 }; odp_crypto_iv_t iv = { .data = NULL, .length = AES128_GCM_IV_LEN }; + uint8_t wrong_digest[AES128_GCM_DIGEST_LEN]; unsigned int test_vec_num = (sizeof(aes128_gcm_reference_length) / sizeof(aes128_gcm_reference_length[0])); unsigned int i;
+ memset(wrong_digest, 0xa5, sizeof(wrong_digest)); + for (i = 0; i < test_vec_num; i++) { cipher_key.data = aes128_gcm_reference_key[i]; cipher_key.length = sizeof(aes128_gcm_reference_key[i]); @@ -723,6 +726,23 @@ void crypto_test_dec_alg_aes128_gcm(void) aes128_gcm_reference_ciphertext[i] + aes128_gcm_reference_length[i], AES128_GCM_CHECK_LEN); + + alg_test(ODP_CRYPTO_OP_DECODE, + 1, + ODP_CIPHER_ALG_AES_GCM, + iv, + NULL, + cipher_key, + ODP_AUTH_ALG_AES_GCM, + auth_key, + &aes128_gcm_cipher_range[i], + &aes128_gcm_auth_range[i], + aes128_gcm_reference_ciphertext[i], + aes128_gcm_reference_length[i] + AES128_GCM_CHECK_LEN, + aes128_gcm_reference_plaintext[i], + aes128_gcm_reference_length[i], + wrong_digest, + AES128_GCM_CHECK_LEN); } }
@@ -736,10 +756,13 @@ void crypto_test_dec_alg_aes128_gcm_ovr_iv(void) odp_crypto_key_t cipher_key = { .data = NULL, .length = 0 }, auth_key = { .data = NULL, .length = 0 }; odp_crypto_iv_t iv = { .data = NULL, .length = AES128_GCM_IV_LEN }; + uint8_t wrong_digest[AES128_GCM_DIGEST_LEN]; unsigned int test_vec_num = (sizeof(aes128_gcm_reference_length) / sizeof(aes128_gcm_reference_length[0])); unsigned int i;
+ memset(wrong_digest, 0xa5, sizeof(wrong_digest)); + for (i = 0; i < test_vec_num; i++) { cipher_key.data = aes128_gcm_reference_key[i]; cipher_key.length = sizeof(aes128_gcm_reference_key[i]); @@ -768,6 +791,23 @@ void crypto_test_dec_alg_aes128_gcm_ovr_iv(void) aes128_gcm_reference_ciphertext[i] + aes128_gcm_reference_length[i], AES128_GCM_CHECK_LEN); + + alg_test(ODP_CRYPTO_OP_DECODE, + 1, + ODP_CIPHER_ALG_AES_GCM, + iv, + aes128_gcm_reference_iv[i], + cipher_key, + ODP_AUTH_ALG_AES_GCM, + auth_key, + &aes128_gcm_cipher_range[i], + &aes128_gcm_auth_range[i], + aes128_gcm_reference_ciphertext[i], + aes128_gcm_reference_length[i] + AES128_GCM_CHECK_LEN, + aes128_gcm_reference_plaintext[i], + aes128_gcm_reference_length[i], + wrong_digest, + AES128_GCM_CHECK_LEN); } }
commit 329ad2cc86f87ce96ab8eeabbf113500bce64b50 Author: Petri Savolainen petri.savolainen@linaro.org Date: Fri Apr 28 15:09:58 2017 +0300
linux-gen: time: store timespec as nsec
Use single 64 bit nanosecond value to store time when using posix time. Posix time stamp is converted directly from timespec (sec + nsec) to nsec time. Storage space for odp_time_t is halved as both posix and HW time use single u64. Some functions (sum, diff, cmp) are generic for both time sources.
Signed-off-by: Petri Savolainen petri.savolainen@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/api/plat/time_types.h b/platform/linux-generic/include/odp/api/plat/time_types.h index 1cafb1f7..71e354e6 100644 --- a/platform/linux-generic/include/odp/api/plat/time_types.h +++ b/platform/linux-generic/include/odp/api/plat/time_types.h @@ -22,32 +22,24 @@ extern "C" { **/
/** - * @internal Time structure used to isolate odp-linux implementation from - * the linux timespec structure, which is dependent on POSIX extension level. + * @internal Time structure used for both POSIX timespec and HW counter + * implementations. */ typedef struct odp_time_t { union { - /** @internal Posix timespec */ - struct { - /** @internal Seconds */ - int64_t tv_sec; - - /** @internal Nanoseconds */ - int64_t tv_nsec; - } spec; - - /** @internal HW time counter */ - struct { - /** @internal Counter value */ - uint64_t count; - - /** @internal Reserved */ - uint64_t reserved; - } hw; + /** @internal Used with generic 64 bit operations */ + uint64_t u64; + + /** @internal Nanoseconds */ + uint64_t nsec; + + /** @internal HW timer counter value */ + uint64_t count; + }; } odp_time_t;
-#define ODP_TIME_NULL ((odp_time_t){.spec = {0, 0} }) +#define ODP_TIME_NULL ((odp_time_t){.u64 = 0})
/** * @} diff --git a/platform/linux-generic/odp_time.c b/platform/linux-generic/odp_time.c index ac82175d..2bbe5666 100644 --- a/platform/linux-generic/odp_time.c +++ b/platform/linux-generic/odp_time.c @@ -15,10 +15,10 @@ #include <inttypes.h>
typedef struct time_global_t { - odp_time_t start_time; - int use_hw; - uint64_t hw_start; - uint64_t hw_freq_hz; + struct timespec spec_start; + int use_hw; + uint64_t hw_start; + uint64_t hw_freq_hz; } time_global_t;
static time_global_t global; @@ -27,19 +27,23 @@ static time_global_t global; * Posix timespec based functions */
-static inline odp_time_t time_spec_diff(odp_time_t t2, odp_time_t t1) +static inline uint64_t time_spec_diff_nsec(struct timespec *t2, + struct timespec *t1) { - odp_time_t time; + struct timespec diff; + uint64_t nsec;
- time.spec.tv_sec = t2.spec.tv_sec - t1.spec.tv_sec; - time.spec.tv_nsec = t2.spec.tv_nsec - t1.spec.tv_nsec; + diff.tv_sec = t2->tv_sec - t1->tv_sec; + diff.tv_nsec = t2->tv_nsec - t1->tv_nsec;
- if (time.spec.tv_nsec < 0) { - time.spec.tv_nsec += ODP_TIME_SEC_IN_NS; - --time.spec.tv_sec; + if (diff.tv_nsec < 0) { + diff.tv_nsec += ODP_TIME_SEC_IN_NS; + diff.tv_sec -= 1; }
- return time; + nsec = (diff.tv_sec * ODP_TIME_SEC_IN_NS) + diff.tv_nsec; + + return nsec; }
static inline odp_time_t time_spec_cur(void) @@ -52,10 +56,9 @@ static inline odp_time_t time_spec_cur(void) if (odp_unlikely(ret != 0)) ODP_ABORT("clock_gettime failed\n");
- time.spec.tv_sec = sys_time.tv_sec; - time.spec.tv_nsec = sys_time.tv_nsec; + time.nsec = time_spec_diff_nsec(&sys_time, &global.spec_start);
- return time_spec_diff(time, global.start_time); + return time; }
static inline uint64_t time_spec_res(void) @@ -70,48 +73,16 @@ static inline uint64_t time_spec_res(void) return ODP_TIME_SEC_IN_NS / (uint64_t)tres.tv_nsec; }
-static inline int time_spec_cmp(odp_time_t t2, odp_time_t t1) -{ - if (t2.spec.tv_sec < t1.spec.tv_sec) - return -1; - - if (t2.spec.tv_sec > t1.spec.tv_sec) - return 1; - - return t2.spec.tv_nsec - t1.spec.tv_nsec; -} - -static inline odp_time_t time_spec_sum(odp_time_t t1, odp_time_t t2) -{ - odp_time_t time; - - time.spec.tv_sec = t2.spec.tv_sec + t1.spec.tv_sec; - time.spec.tv_nsec = t2.spec.tv_nsec + t1.spec.tv_nsec; - - if (time.spec.tv_nsec >= (long)ODP_TIME_SEC_IN_NS) { - time.spec.tv_nsec -= ODP_TIME_SEC_IN_NS; - ++time.spec.tv_sec; - } - - return time; -} - static inline uint64_t time_spec_to_ns(odp_time_t time) { - uint64_t ns; - - ns = time.spec.tv_sec * ODP_TIME_SEC_IN_NS; - ns += time.spec.tv_nsec; - - return ns; + return time.nsec; }
static inline odp_time_t time_spec_from_ns(uint64_t ns) { odp_time_t time;
- time.spec.tv_sec = ns / ODP_TIME_SEC_IN_NS; - time.spec.tv_nsec = ns - time.spec.tv_sec * ODP_TIME_SEC_IN_NS; + time.nsec = ns;
return time; } @@ -124,7 +95,7 @@ static inline odp_time_t time_hw_cur(void) { odp_time_t time;
- time.hw.count = cpu_global_time() - global.hw_start; + time.count = cpu_global_time() - global.hw_start;
return time; } @@ -136,40 +107,11 @@ static inline uint64_t time_hw_res(void) return global.hw_freq_hz / 10; }
-static inline int time_hw_cmp(odp_time_t t2, odp_time_t t1) -{ - if (odp_likely(t2.hw.count > t1.hw.count)) - return 1; - - if (t2.hw.count < t1.hw.count) - return -1; - - return 0; -} - -static inline odp_time_t time_hw_diff(odp_time_t t2, odp_time_t t1) -{ - odp_time_t time; - - time.hw.count = t2.hw.count - t1.hw.count; - - return time; -} - -static inline odp_time_t time_hw_sum(odp_time_t t1, odp_time_t t2) -{ - odp_time_t time; - - time.hw.count = t1.hw.count + t2.hw.count; - - return time; -} - static inline uint64_t time_hw_to_ns(odp_time_t time) { uint64_t nsec; uint64_t freq_hz = global.hw_freq_hz; - uint64_t count = time.hw.count; + uint64_t count = time.count; uint64_t sec = 0;
if (count >= freq_hz) { @@ -197,8 +139,7 @@ static inline odp_time_t time_hw_from_ns(uint64_t ns) count = sec * freq_hz; count += (ns * freq_hz) / ODP_TIME_SEC_IN_NS;
- time.hw.reserved = 0; - time.hw.count = count; + time.count = count;
return time; } @@ -225,26 +166,22 @@ static inline uint64_t time_res(void)
static inline int time_cmp(odp_time_t t2, odp_time_t t1) { - if (global.use_hw) - return time_hw_cmp(t2, t1); - - return time_spec_cmp(t2, t1); -} + if (odp_likely(t2.u64 > t1.u64)) + return 1;
-static inline odp_time_t time_diff(odp_time_t t2, odp_time_t t1) -{ - if (global.use_hw) - return time_hw_diff(t2, t1); + if (t2.u64 < t1.u64) + return -1;
- return time_spec_diff(t2, t1); + return 0; }
static inline odp_time_t time_sum(odp_time_t t1, odp_time_t t2) { - if (global.use_hw) - return time_hw_sum(t1, t2); + odp_time_t time; + + time.u64 = t1.u64 + t2.u64;
- return time_spec_sum(t1, t2); + return time; }
static inline uint64_t time_to_ns(odp_time_t time) @@ -284,7 +221,11 @@ odp_time_t odp_time_global(void)
odp_time_t odp_time_diff(odp_time_t t2, odp_time_t t1) { - return time_diff(t2, t1); + odp_time_t time; + + time.u64 = t2.u64 - t1.u64; + + return time; }
uint64_t odp_time_to_ns(odp_time_t time) @@ -338,7 +279,6 @@ void odp_time_wait_until(odp_time_t time)
int odp_time_init_global(void) { - struct timespec sys_time; int ret = 0;
memset(&global, 0, sizeof(time_global_t)); @@ -357,13 +297,10 @@ int odp_time_init_global(void) return 0; }
- global.start_time = ODP_TIME_NULL; + global.spec_start.tv_sec = 0; + global.spec_start.tv_nsec = 0;
- ret = clock_gettime(CLOCK_MONOTONIC_RAW, &sys_time); - if (ret == 0) { - global.start_time.spec.tv_sec = sys_time.tv_sec; - global.start_time.spec.tv_nsec = sys_time.tv_nsec; - } + ret = clock_gettime(CLOCK_MONOTONIC_RAW, &global.spec_start);
return ret; }
commit fce41954cef8512050b829fd726a41584f3216f5 Author: Petri Savolainen petri.savolainen@linaro.org Date: Fri Apr 28 15:09:57 2017 +0300
linux-gen: time: improve x86 TSC freq measurement accuracy
Add short warm up round and measure over a longer period of time (250ms vs 100ms).
Signed-off-by: Petri Savolainen petri.savolainen@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/arch/x86/odp_cpu_arch.c b/platform/linux-generic/arch/x86/odp_cpu_arch.c index 9ba601a3..b1da428b 100644 --- a/platform/linux-generic/arch/x86/odp_cpu_arch.c +++ b/platform/linux-generic/arch/x86/odp_cpu_arch.c @@ -54,11 +54,16 @@ uint64_t cpu_global_time_freq(void) uint64_t t1, t2, ts_nsec, cycles, hz; int i; uint64_t avg = 0; - int rounds = 4; + int rounds = 3; + int warm_up = 1;
for (i = 0; i < rounds; i++) { - sleep.tv_sec = 0; - sleep.tv_nsec = SEC_IN_NS / 10; + sleep.tv_sec = 0; + + if (warm_up) + sleep.tv_nsec = SEC_IN_NS / 1000; + else + sleep.tv_nsec = SEC_IN_NS / 4;
if (clock_gettime(CLOCK_MONOTONIC_RAW, &ts1)) { ODP_DBG("clock_gettime failed\n"); @@ -85,8 +90,12 @@ uint64_t cpu_global_time_freq(void) cycles = t2 - t1;
hz = (cycles * SEC_IN_NS) / ts_nsec; - avg += hz; + + if (warm_up) + warm_up = 0; + else + avg += hz; }
- return avg / rounds; + return avg / (rounds - 1); }
commit 99733f4463b297fc7913be83cfb2cc7fea372137 Author: Petri Savolainen petri.savolainen@linaro.org Date: Fri Apr 28 15:09:56 2017 +0300
linux-gen: time: use hw time counter when available
Use 64 bit HW time counter when available. It is used on x86 when invariant TSC CPU flag indicates that TSC frequency is constant. Otherwise, the system time is used as before. Direct HW time counter usage avoids system call, and related latency and performance issues.
Signed-off-by: Petri Savolainen petri.savolainen@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/Makefile.am b/platform/linux-generic/Makefile.am index 6492073d..0ad0b8e2 100644 --- a/platform/linux-generic/Makefile.am +++ b/platform/linux-generic/Makefile.am @@ -147,6 +147,7 @@ noinst_HEADERS = \ ${srcdir}/include/odp_schedule_if.h \ ${srcdir}/include/odp_sorted_list_internal.h \ ${srcdir}/include/odp_shm_internal.h \ + ${srcdir}/include/odp_time_internal.h \ ${srcdir}/include/odp_timer_internal.h \ ${srcdir}/include/odp_timer_wheel_internal.h \ ${srcdir}/include/odp_traffic_mngr_internal.h \ diff --git a/platform/linux-generic/arch/arm/odp_cpu_arch.c b/platform/linux-generic/arch/arm/odp_cpu_arch.c index 2ac223e0..c31f9084 100644 --- a/platform/linux-generic/arch/arm/odp_cpu_arch.c +++ b/platform/linux-generic/arch/arm/odp_cpu_arch.c @@ -13,6 +13,7 @@ #include <odp/api/hints.h> #include <odp/api/system_info.h> #include <odp_debug_internal.h> +#include <odp_time_internal.h>
#define GIGA 1000000000
@@ -46,3 +47,18 @@ uint64_t odp_cpu_cycles_resolution(void) { return 1; } + +int cpu_has_global_time(void) +{ + return 0; +} + +uint64_t cpu_global_time(void) +{ + return 0; +} + +uint64_t cpu_global_time_freq(void) +{ + return 0; +} diff --git a/platform/linux-generic/arch/default/odp_cpu_arch.c b/platform/linux-generic/arch/default/odp_cpu_arch.c index 2ac223e0..c31f9084 100644 --- a/platform/linux-generic/arch/default/odp_cpu_arch.c +++ b/platform/linux-generic/arch/default/odp_cpu_arch.c @@ -13,6 +13,7 @@ #include <odp/api/hints.h> #include <odp/api/system_info.h> #include <odp_debug_internal.h> +#include <odp_time_internal.h>
#define GIGA 1000000000
@@ -46,3 +47,18 @@ uint64_t odp_cpu_cycles_resolution(void) { return 1; } + +int cpu_has_global_time(void) +{ + return 0; +} + +uint64_t cpu_global_time(void) +{ + return 0; +} + +uint64_t cpu_global_time_freq(void) +{ + return 0; +} diff --git a/platform/linux-generic/arch/mips64/odp_cpu_arch.c b/platform/linux-generic/arch/mips64/odp_cpu_arch.c index 646acf9c..f7eafa0f 100644 --- a/platform/linux-generic/arch/mips64/odp_cpu_arch.c +++ b/platform/linux-generic/arch/mips64/odp_cpu_arch.c @@ -7,6 +7,7 @@ #include <odp/api/cpu.h> #include <odp/api/hints.h> #include <odp/api/system_info.h> +#include <odp_time_internal.h>
uint64_t odp_cpu_cycles(void) { @@ -29,3 +30,18 @@ uint64_t odp_cpu_cycles_resolution(void) { return 1; } + +int cpu_has_global_time(void) +{ + return 0; +} + +uint64_t cpu_global_time(void) +{ + return 0; +} + +uint64_t cpu_global_time_freq(void) +{ + return 0; +} diff --git a/platform/linux-generic/arch/powerpc/odp_cpu_arch.c b/platform/linux-generic/arch/powerpc/odp_cpu_arch.c index 2ac223e0..c31f9084 100644 --- a/platform/linux-generic/arch/powerpc/odp_cpu_arch.c +++ b/platform/linux-generic/arch/powerpc/odp_cpu_arch.c @@ -13,6 +13,7 @@ #include <odp/api/hints.h> #include <odp/api/system_info.h> #include <odp_debug_internal.h> +#include <odp_time_internal.h>
#define GIGA 1000000000
@@ -46,3 +47,18 @@ uint64_t odp_cpu_cycles_resolution(void) { return 1; } + +int cpu_has_global_time(void) +{ + return 0; +} + +uint64_t cpu_global_time(void) +{ + return 0; +} + +uint64_t cpu_global_time_freq(void) +{ + return 0; +} diff --git a/platform/linux-generic/arch/x86/cpu_flags.c b/platform/linux-generic/arch/x86/cpu_flags.c index 954dac27..a492a35b 100644 --- a/platform/linux-generic/arch/x86/cpu_flags.c +++ b/platform/linux-generic/arch/x86/cpu_flags.c @@ -39,6 +39,7 @@
#include <arch/x86/cpu_flags.h> #include <odp_debug_internal.h> +#include <odp_time_internal.h> #include <stdio.h> #include <stdint.h>
@@ -357,3 +358,11 @@ void cpu_flags_print_all(void) str[len] = '\0'; ODP_PRINT("%s", str); } + +int cpu_has_global_time(void) +{ + if (cpu_get_flag_enabled(RTE_CPUFLAG_INVTSC) > 0) + return 1; + + return 0; +} diff --git a/platform/linux-generic/arch/x86/odp_cpu_arch.c b/platform/linux-generic/arch/x86/odp_cpu_arch.c index c8cf27b6..9ba601a3 100644 --- a/platform/linux-generic/arch/x86/odp_cpu_arch.c +++ b/platform/linux-generic/arch/x86/odp_cpu_arch.c @@ -3,7 +3,14 @@ * * SPDX-License-Identifier: BSD-3-Clause */ + +#include <odp_posix_extensions.h> + #include <odp/api/cpu.h> +#include <odp_time_internal.h> +#include <odp_debug_internal.h> + +#include <time.h>
uint64_t odp_cpu_cycles(void) { @@ -31,3 +38,55 @@ uint64_t odp_cpu_cycles_resolution(void) { return 1; } + +uint64_t cpu_global_time(void) +{ + return odp_cpu_cycles(); +} + +#define SEC_IN_NS 1000000000ULL + +/* Measure TSC frequency. Frequency information registers are defined for x86, + * but those are often not enumerated. */ +uint64_t cpu_global_time_freq(void) +{ + struct timespec sleep, ts1, ts2; + uint64_t t1, t2, ts_nsec, cycles, hz; + int i; + uint64_t avg = 0; + int rounds = 4; + + for (i = 0; i < rounds; i++) { + sleep.tv_sec = 0; + sleep.tv_nsec = SEC_IN_NS / 10; + + if (clock_gettime(CLOCK_MONOTONIC_RAW, &ts1)) { + ODP_DBG("clock_gettime failed\n"); + return 0; + } + + t1 = cpu_global_time(); + + if (nanosleep(&sleep, NULL) < 0) { + ODP_DBG("nanosleep failed\n"); + return 0; + } + + if (clock_gettime(CLOCK_MONOTONIC_RAW, &ts2)) { + ODP_DBG("clock_gettime failed\n"); + return 0; + } + + t2 = cpu_global_time(); + + ts_nsec = (ts2.tv_sec - ts1.tv_sec) * SEC_IN_NS; + ts_nsec += ts2.tv_nsec - ts1.tv_nsec; + + cycles = t2 - t1; + + hz = (cycles * SEC_IN_NS) / ts_nsec; + avg += hz; + } + + return avg / rounds; +} diff --git a/platform/linux-generic/include/odp/api/plat/time_types.h b/platform/linux-generic/include/odp/api/plat/time_types.h index 4847f3b1..1cafb1f7 100644 --- a/platform/linux-generic/include/odp/api/plat/time_types.h +++ b/platform/linux-generic/include/odp/api/plat/time_types.h @@ -26,11 +26,28 @@ extern "C" { * the linux timespec structure, which is dependent on POSIX extension level. */ typedef struct odp_time_t { - int64_t tv_sec; /**< @internal Seconds */ - int64_t tv_nsec; /**< @internal Nanoseconds */ + union { + /** @internal Posix timespec */ + struct { + /** @internal Seconds */ + int64_t tv_sec; + + /** @internal Nanoseconds */ + int64_t tv_nsec; + } spec; + + /** @internal HW time counter */ + struct { + /** @internal Counter value */ + uint64_t count; + + /** @internal Reserved */ + uint64_t reserved; + } hw; + }; } odp_time_t;
-#define ODP_TIME_NULL ((odp_time_t){0, 0}) +#define ODP_TIME_NULL ((odp_time_t){.spec = {0, 0} })
/** * @} diff --git a/platform/linux-generic/include/odp_time_internal.h b/platform/linux-generic/include/odp_time_internal.h new file mode 100644 index 00000000..99ac7977 --- /dev/null +++ b/platform/linux-generic/include/odp_time_internal.h @@ -0,0 +1,24 @@ +/* Copyright (c) 2017, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef ODP_TIME_INTERNAL_H_ +#define ODP_TIME_INTERNAL_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <stdint.h> + +int cpu_has_global_time(void); +uint64_t cpu_global_time(void); +uint64_t cpu_global_time_freq(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/platform/linux-generic/odp_time.c b/platform/linux-generic/odp_time.c index 0e5966c0..ac82175d 100644 --- a/platform/linux-generic/odp_time.c +++ b/platform/linux-generic/odp_time.c @@ -10,36 +10,39 @@ #include <odp/api/time.h> #include <odp/api/hints.h> #include <odp_debug_internal.h> +#include <odp_time_internal.h> +#include <string.h> +#include <inttypes.h>
-static odp_time_t start_time; +typedef struct time_global_t { + odp_time_t start_time; + int use_hw; + uint64_t hw_start; + uint64_t hw_freq_hz; +} time_global_t;
-static inline -uint64_t time_to_ns(odp_time_t time) -{ - uint64_t ns; - - ns = time.tv_sec * ODP_TIME_SEC_IN_NS; - ns += time.tv_nsec; +static time_global_t global;
- return ns; -} +/* + * Posix timespec based functions + */
-static inline odp_time_t time_diff(odp_time_t t2, odp_time_t t1) +static inline odp_time_t time_spec_diff(odp_time_t t2, odp_time_t t1) { odp_time_t time;
- time.tv_sec = t2.tv_sec - t1.tv_sec; - time.tv_nsec = t2.tv_nsec - t1.tv_nsec; + time.spec.tv_sec = t2.spec.tv_sec - t1.spec.tv_sec; + time.spec.tv_nsec = t2.spec.tv_nsec - t1.spec.tv_nsec;
- if (time.tv_nsec < 0) { - time.tv_nsec += ODP_TIME_SEC_IN_NS; - --time.tv_sec; + if (time.spec.tv_nsec < 0) { + time.spec.tv_nsec += ODP_TIME_SEC_IN_NS; + --time.spec.tv_sec; }
return time; }
-static inline odp_time_t time_local(void) +static inline odp_time_t time_spec_cur(void) { int ret; odp_time_t time; @@ -49,77 +52,234 @@ static inline odp_time_t time_local(void) if (odp_unlikely(ret != 0)) ODP_ABORT("clock_gettime failed\n");
- time.tv_sec = sys_time.tv_sec; - time.tv_nsec = sys_time.tv_nsec; + time.spec.tv_sec = sys_time.tv_sec; + time.spec.tv_nsec = sys_time.tv_nsec;
- return time_diff(time, start_time); + return time_spec_diff(time, global.start_time); }
-static inline int time_cmp(odp_time_t t2, odp_time_t t1) +static inline uint64_t time_spec_res(void) { - if (t2.tv_sec < t1.tv_sec) + int ret; + struct timespec tres; + + ret = clock_getres(CLOCK_MONOTONIC_RAW, &tres); + if (odp_unlikely(ret != 0)) + ODP_ABORT("clock_getres failed\n"); + + return ODP_TIME_SEC_IN_NS / (uint64_t)tres.tv_nsec; +} + +static inline int time_spec_cmp(odp_time_t t2, odp_time_t t1) +{ + if (t2.spec.tv_sec < t1.spec.tv_sec) return -1;
- if (t2.tv_sec > t1.tv_sec) + if (t2.spec.tv_sec > t1.spec.tv_sec) return 1;
- return t2.tv_nsec - t1.tv_nsec; + return t2.spec.tv_nsec - t1.spec.tv_nsec; }
-static inline odp_time_t time_sum(odp_time_t t1, odp_time_t t2) +static inline odp_time_t time_spec_sum(odp_time_t t1, odp_time_t t2) { odp_time_t time;
- time.tv_sec = t2.tv_sec + t1.tv_sec; - time.tv_nsec = t2.tv_nsec + t1.tv_nsec; + time.spec.tv_sec = t2.spec.tv_sec + t1.spec.tv_sec; + time.spec.tv_nsec = t2.spec.tv_nsec + t1.spec.tv_nsec;
- if (time.tv_nsec >= (long)ODP_TIME_SEC_IN_NS) { - time.tv_nsec -= ODP_TIME_SEC_IN_NS; - ++time.tv_sec; + if (time.spec.tv_nsec >= (long)ODP_TIME_SEC_IN_NS) { + time.spec.tv_nsec -= ODP_TIME_SEC_IN_NS; + ++time.spec.tv_sec; }
return time; }
-static inline odp_time_t time_local_from_ns(uint64_t ns) +static inline uint64_t time_spec_to_ns(odp_time_t time) +{ + uint64_t ns; + + ns = time.spec.tv_sec * ODP_TIME_SEC_IN_NS; + ns += time.spec.tv_nsec; + + return ns; +} + +static inline odp_time_t time_spec_from_ns(uint64_t ns) { odp_time_t time;
- time.tv_sec = ns / ODP_TIME_SEC_IN_NS; - time.tv_nsec = ns - time.tv_sec * ODP_TIME_SEC_IN_NS; + time.spec.tv_sec = ns / ODP_TIME_SEC_IN_NS; + time.spec.tv_nsec = ns - time.spec.tv_sec * ODP_TIME_SEC_IN_NS;
return time; }
-static inline void time_wait_until(odp_time_t time) +/* + * HW time counter based functions + */ + +static inline odp_time_t time_hw_cur(void) { - odp_time_t cur; + odp_time_t time;
- do { - cur = time_local(); - } while (time_cmp(time, cur) > 0); + time.hw.count = cpu_global_time() - global.hw_start; + + return time; }
-static inline uint64_t time_local_res(void) +static inline uint64_t time_hw_res(void) { - int ret; - struct timespec tres; + /* Promise a bit lower resolution than average cycle counter + * frequency */ + return global.hw_freq_hz / 10; +}
- ret = clock_getres(CLOCK_MONOTONIC_RAW, &tres); - if (odp_unlikely(ret != 0)) - ODP_ABORT("clock_getres failed\n"); +static inline int time_hw_cmp(odp_time_t t2, odp_time_t t1) +{ + if (odp_likely(t2.hw.count > t1.hw.count)) + return 1;
- return ODP_TIME_SEC_IN_NS / (uint64_t)tres.tv_nsec; + if (t2.hw.count < t1.hw.count) + return -1; + + return 0; +} + +static inline odp_time_t time_hw_diff(odp_time_t t2, odp_time_t t1) +{ + odp_time_t time; + + time.hw.count = t2.hw.count - t1.hw.count; + + return time; +} + +static inline odp_time_t time_hw_sum(odp_time_t t1, odp_time_t t2) +{ + odp_time_t time; + + time.hw.count = t1.hw.count + t2.hw.count; + + return time; +} + +static inline uint64_t time_hw_to_ns(odp_time_t time) +{ + uint64_t nsec; + uint64_t freq_hz = global.hw_freq_hz; + uint64_t count = time.hw.count; + uint64_t sec = 0; + + if (count >= freq_hz) { + sec = count / freq_hz; + count = count - sec * freq_hz; + } + + nsec = (ODP_TIME_SEC_IN_NS * count) / freq_hz; + + return (sec * ODP_TIME_SEC_IN_NS) + nsec; +} + +static inline odp_time_t time_hw_from_ns(uint64_t ns) +{ + odp_time_t time; + uint64_t count; + uint64_t freq_hz = global.hw_freq_hz; + uint64_t sec = 0; + + if (ns >= ODP_TIME_SEC_IN_NS) { + sec = ns / ODP_TIME_SEC_IN_NS; + ns = ns - sec * ODP_TIME_SEC_IN_NS; + } + + count = sec * freq_hz; + count += (ns * freq_hz) / ODP_TIME_SEC_IN_NS; + + time.hw.reserved = 0; + time.hw.count = count; + + return time; +} + +/* + * Common functions + */ + +static inline odp_time_t time_cur(void) +{ + if (global.use_hw) + return time_hw_cur(); + + return time_spec_cur(); +} + +static inline uint64_t time_res(void) +{ + if (global.use_hw) + return time_hw_res(); + + return time_spec_res(); +} + +static inline int time_cmp(odp_time_t t2, odp_time_t t1) +{ + if (global.use_hw) + return time_hw_cmp(t2, t1); + + return time_spec_cmp(t2, t1); +} + +static inline odp_time_t time_diff(odp_time_t t2, odp_time_t t1) +{ + if (global.use_hw) + return time_hw_diff(t2, t1); + + return time_spec_diff(t2, t1); +} + +static inline odp_time_t time_sum(odp_time_t t1, odp_time_t t2) +{ + if (global.use_hw) + return time_hw_sum(t1, t2); + + return time_spec_sum(t1, t2); +} + +static inline uint64_t time_to_ns(odp_time_t time) +{ + if (global.use_hw) + return time_hw_to_ns(time); + + return time_spec_to_ns(time); +} + +static inline odp_time_t time_from_ns(uint64_t ns) +{ + if (global.use_hw) + return time_hw_from_ns(ns); + + return time_spec_from_ns(ns); +} + +static inline void time_wait_until(odp_time_t time) +{ + odp_time_t cur; + + do { + cur = time_cur(); + } while (time_cmp(time, cur) > 0); }
odp_time_t odp_time_local(void) { - return time_local(); + return time_cur(); }
odp_time_t odp_time_global(void) { - return time_local(); + return time_cur(); }
odp_time_t odp_time_diff(odp_time_t t2, odp_time_t t1) @@ -134,12 +294,12 @@ uint64_t odp_time_to_ns(odp_time_t time)
odp_time_t odp_time_local_from_ns(uint64_t ns) { - return time_local_from_ns(ns); + return time_from_ns(ns); }
odp_time_t odp_time_global_from_ns(uint64_t ns) { - return time_local_from_ns(ns); + return time_from_ns(ns); }
int odp_time_cmp(odp_time_t t2, odp_time_t t1) @@ -154,18 +314,18 @@ odp_time_t odp_time_sum(odp_time_t t1, odp_time_t t2)
uint64_t odp_time_local_res(void) { - return time_local_res(); + return time_res(); }
uint64_t odp_time_global_res(void) { - return time_local_res(); + return time_res(); }
void odp_time_wait_ns(uint64_t ns) { - odp_time_t cur = time_local(); - odp_time_t wait = time_local_from_ns(ns); + odp_time_t cur = time_cur(); + odp_time_t wait = time_from_ns(ns); odp_time_t end_time = time_sum(cur, wait);
time_wait_until(end_time); @@ -178,15 +338,31 @@ void odp_time_wait_until(odp_time_t time)
int odp_time_init_global(void) { - int ret; - struct timespec time; - - ret = clock_gettime(CLOCK_MONOTONIC_RAW, &time); - if (ret) { - start_time = ODP_TIME_NULL; - } else { - start_time.tv_sec = time.tv_sec; - start_time.tv_nsec = time.tv_nsec; + struct timespec sys_time; + int ret = 0; + + memset(&global, 0, sizeof(time_global_t)); + + if (cpu_has_global_time()) { + global.use_hw = 1; + global.hw_freq_hz = cpu_global_time_freq(); + + if (global.hw_freq_hz == 0) + return -1; + + printf("HW time counter freq: %" PRIu64 " hz\n\n", + global.hw_freq_hz); + + global.hw_start = cpu_global_time(); + return 0; + } + + global.start_time = ODP_TIME_NULL; + + ret = clock_gettime(CLOCK_MONOTONIC_RAW, &sys_time); + if (ret == 0) { + global.start_time.spec.tv_sec = sys_time.tv_sec; + global.start_time.spec.tv_nsec = sys_time.tv_nsec; }
return ret;
commit b57ea8ad55a879b6ef5ec1a2ae4e4c25fb90a5d3 Author: Petri Savolainen petri.savolainen@linaro.org Date: Fri Apr 28 15:09:55 2017 +0300
test: validation: add time accuracy test
Test ODP time keeping accuracy against system time.
Signed-off-by: Petri Savolainen petri.savolainen@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/time/time.c b/test/common_plat/validation/api/time/time.c index 36c419cb..e2ca2e17 100644 --- a/test/common_plat/validation/api/time/time.c +++ b/test/common_plat/validation/api/time/time.c @@ -7,6 +7,7 @@ #include <odp_api.h> #include "odp_cunit_common.h" #include "time_test.h" +#include <time.h>
#define BUSY_LOOP_CNT 30000000 /* used for t > min resolution */ #define BUSY_LOOP_CNT_LONG 6000000000 /* used for t > 4 sec */ @@ -140,25 +141,25 @@ void time_test_monotony(void) CU_ASSERT(ns3 > ns2); }
-static void time_test_cmp(time_cb time, time_from_ns_cb time_from_ns) +static void time_test_cmp(time_cb time_cur, time_from_ns_cb time_from_ns) { /* volatile to stop optimization of busy loop */ volatile int count = 0; odp_time_t t1, t2, t3;
- t1 = time(); + t1 = time_cur();
while (count < BUSY_LOOP_CNT) { count++; };
- t2 = time(); + t2 = time_cur();
while (count < BUSY_LOOP_CNT * 2) { count++; };
- t3 = time(); + t3 = time_cur();
CU_ASSERT(odp_time_cmp(t2, t1) > 0); CU_ASSERT(odp_time_cmp(t3, t2) > 0); @@ -191,7 +192,7 @@ void time_test_global_cmp(void) }
/* check that a time difference gives a reasonable result */ -static void time_test_diff(time_cb time, +static void time_test_diff(time_cb time_cur, time_from_ns_cb time_from_ns, uint64_t res) { @@ -202,13 +203,13 @@ static void time_test_diff(time_cb time, uint64_t upper_limit, lower_limit;
/* test timestamp diff */ - t1 = time(); + t1 = time_cur();
while (count < BUSY_LOOP_CNT) { count++; };
- t2 = time(); + t2 = time_cur(); CU_ASSERT(odp_time_cmp(t2, t1) > 0);
diff = odp_time_diff(t2, t1); @@ -268,7 +269,7 @@ void time_test_global_diff(void) }
/* check that a time sum gives a reasonable result */ -static void time_test_sum(time_cb time, +static void time_test_sum(time_cb time_cur, time_from_ns_cb time_from_ns, uint64_t res) { @@ -277,7 +278,7 @@ static void time_test_sum(time_cb time, uint64_t upper_limit, lower_limit;
/* sum timestamp and interval */ - t1 = time(); + t1 = time_cur(); ns2 = 103; t2 = time_from_ns(ns2); ns1 = odp_time_to_ns(t1); @@ -319,20 +320,20 @@ void time_test_global_sum(void) time_test_sum(odp_time_global, odp_time_global_from_ns, global_res); }
-static void time_test_wait_until(time_cb time, time_from_ns_cb time_from_ns) +static void time_test_wait_until(time_cb time_cur, time_from_ns_cb time_from_ns) { int i; odp_time_t lower_limit, upper_limit; odp_time_t start_time, end_time, wait; odp_time_t second = time_from_ns(ODP_TIME_SEC_IN_NS);
- start_time = time(); + start_time = time_cur(); wait = start_time; for (i = 0; i < WAIT_SECONDS; i++) { wait = odp_time_sum(wait, second); odp_time_wait_until(wait); } - end_time = time(); + end_time = time_cur();
wait = odp_time_diff(end_time, start_time); lower_limit = time_from_ns(WAIT_SECONDS * ODP_TIME_SEC_IN_NS - @@ -398,6 +399,45 @@ void time_test_wait_ns(void) } }
+static void time_test_accuracy(time_cb time_cur, time_from_ns_cb time_from_ns) +{ + int i; + odp_time_t t1, t2, wait, diff; + clock_t c1, c2; + double sec_t, sec_c; + odp_time_t sec = time_from_ns(ODP_TIME_SEC_IN_NS); + + c1 = clock(); + t1 = time_cur(); + + wait = odp_time_sum(t1, sec); + for (i = 0; i < 5; i++) { + odp_time_wait_until(wait); + wait = odp_time_sum(wait, sec); + } + + t2 = time_cur(); + c2 = clock(); + + diff = odp_time_diff(t2, t1); + sec_t = ((double)odp_time_to_ns(diff)) / ODP_TIME_SEC_IN_NS; + sec_c = ((double)(c2 - c1)) / CLOCKS_PER_SEC; + + /* Check that ODP time is within +-5% of system time */ + CU_ASSERT(sec_t < sec_c * 1.05); + CU_ASSERT(sec_t > sec_c * 0.95); +} + +static void time_test_local_accuracy(void) +{ + time_test_accuracy(odp_time_local, odp_time_local_from_ns); +} + +static void time_test_global_accuracy(void) +{ + time_test_accuracy(odp_time_global, odp_time_global_from_ns); +} + odp_testinfo_t time_suite_time[] = { ODP_TEST_INFO(time_test_constants), ODP_TEST_INFO(time_test_local_res), @@ -408,12 +448,14 @@ odp_testinfo_t time_suite_time[] = { ODP_TEST_INFO(time_test_local_sum), ODP_TEST_INFO(time_test_local_wait_until), ODP_TEST_INFO(time_test_wait_ns), + ODP_TEST_INFO(time_test_local_accuracy), ODP_TEST_INFO(time_test_global_res), ODP_TEST_INFO(time_test_global_conversion), ODP_TEST_INFO(time_test_global_cmp), ODP_TEST_INFO(time_test_global_diff), ODP_TEST_INFO(time_test_global_sum), ODP_TEST_INFO(time_test_global_wait_until), + ODP_TEST_INFO(time_test_global_accuracy), ODP_TEST_INFO_NULL };
commit 5132040a52da2d7d7b4f16648d04d379f2a990ba Author: Petri Savolainen petri.savolainen@linaro.org Date: Fri Apr 28 15:09:54 2017 +0300
test: validation: rename time test header file
Header file name time.h is ambiguos since C has a library header file with the same name.
Signed-off-by: Petri Savolainen petri.savolainen@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/time/Makefile.am b/test/common_plat/validation/api/time/Makefile.am index bf2d0268..999fcf15 100644 --- a/test/common_plat/validation/api/time/Makefile.am +++ b/test/common_plat/validation/api/time/Makefile.am @@ -7,4 +7,4 @@ test_PROGRAMS = time_main$(EXEEXT) dist_time_main_SOURCES = time_main.c time_main_LDADD = libtesttime.la $(LIBCUNIT_COMMON) $(LIBODP)
-EXTRA_DIST = time.h +EXTRA_DIST = time_test.h diff --git a/test/common_plat/validation/api/time/time.c b/test/common_plat/validation/api/time/time.c index df65c719..36c419cb 100644 --- a/test/common_plat/validation/api/time/time.c +++ b/test/common_plat/validation/api/time/time.c @@ -6,7 +6,7 @@
#include <odp_api.h> #include "odp_cunit_common.h" -#include "time.h" +#include "time_test.h"
#define BUSY_LOOP_CNT 30000000 /* used for t > min resolution */ #define BUSY_LOOP_CNT_LONG 6000000000 /* used for t > 4 sec */ diff --git a/test/common_plat/validation/api/time/time_main.c b/test/common_plat/validation/api/time/time_main.c index f86d638a..bf1cfe7b 100644 --- a/test/common_plat/validation/api/time/time_main.c +++ b/test/common_plat/validation/api/time/time_main.c @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-3-Clause */
-#include "time.h" +#include "time_test.h"
int main(int argc, char *argv[]) { diff --git a/test/common_plat/validation/api/time/time.h b/test/common_plat/validation/api/time/time_test.h similarity index 100% rename from test/common_plat/validation/api/time/time.h rename to test/common_plat/validation/api/time/time_test.h
commit 1fd68e4cb742c241177d49f8c0ee9d60afba7297 Author: Petri Savolainen petri.savolainen@linaro.org Date: Fri Apr 28 15:09:53 2017 +0300
test: sched_latency: use sys_info_print
Use the new system info print function.
Signed-off-by: Petri Savolainen petri.savolainen@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/performance/odp_sched_latency.c b/test/common_plat/performance/odp_sched_latency.c index b4018687..026f2f6c 100644 --- a/test/common_plat/performance/odp_sched_latency.c +++ b/test/common_plat/performance/odp_sched_latency.c @@ -667,16 +667,7 @@ int main(int argc, char *argv[]) return -1; }
- printf("\n"); - printf("ODP system info\n"); - printf("---------------\n"); - printf("ODP API version: %s\n", odp_version_api_str()); - printf("ODP impl name: %s\n", odp_version_impl_name()); - printf("ODP impl details: %s\n", odp_version_impl_str()); - printf("CPU model: %s\n", odp_cpu_model_str()); - printf("CPU freq (hz): %" PRIu64 "\n", odp_cpu_hz_max()); - printf("Cache line size: %i\n", odp_sys_cache_line_size()); - printf("Max CPU count: %i\n", odp_cpu_count()); + odp_sys_info_print();
/* Get default worker cpumask */ if (args.cpu_count) @@ -687,9 +678,10 @@ int main(int argc, char *argv[])
(void)odp_cpumask_to_str(&cpumask, cpumaskstr, sizeof(cpumaskstr));
- printf("Worker threads: %i\n", num_workers); - printf("First CPU: %i\n", odp_cpumask_first(&cpumask)); - printf("CPU mask: %s\n\n", cpumaskstr); + printf("CPU mask info:\n"); + printf(" Worker threads: %i\n", num_workers); + printf(" First CPU: %i\n", odp_cpumask_first(&cpumask)); + printf(" CPU mask: %s\n", cpumaskstr);
thread_tbl = calloc(sizeof(odph_odpthread_t), num_workers); if (!thread_tbl) {
commit 86bee4260c6d6e8cdb2fb652dfafa9fbc27bd4f1 Author: Petri Savolainen petri.savolainen@linaro.org Date: Fri Apr 28 15:09:52 2017 +0300
test: validation: add odp_sys_info_print test
Added validation test for the new system info print call.
Signed-off-by: Petri Savolainen petri.savolainen@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/system/system.c b/test/common_plat/validation/api/system/system.c index 57ff34eb..5b7ca01a 100644 --- a/test/common_plat/validation/api/system/system.c +++ b/test/common_plat/validation/api/system/system.c @@ -301,6 +301,13 @@ void system_test_odp_cpu_hz_max_id(void) } }
+void system_test_info_print(void) +{ + printf("\n\nCalling system info print...\n"); + odp_sys_info_print(); + printf("...done. "); +} + odp_testinfo_t system_suite[] = { ODP_TEST_INFO(system_test_odp_version_numbers), ODP_TEST_INFO(system_test_odp_cpu_count), @@ -319,6 +326,7 @@ odp_testinfo_t system_suite[] = { ODP_TEST_INFO(system_test_odp_cpu_cycles_max), ODP_TEST_INFO(system_test_odp_cpu_cycles_resolution), ODP_TEST_INFO(system_test_odp_cpu_cycles_diff), + ODP_TEST_INFO(system_test_info_print), ODP_TEST_INFO_NULL, };
diff --git a/test/common_plat/validation/api/system/system.h b/test/common_plat/validation/api/system/system.h index cbb994eb..c33729b9 100644 --- a/test/common_plat/validation/api/system/system.h +++ b/test/common_plat/validation/api/system/system.h @@ -30,6 +30,7 @@ void system_test_odp_cpu_cycles_max(void); void system_test_odp_cpu_cycles(void); void system_test_odp_cpu_cycles_diff(void); void system_test_odp_cpu_cycles_resolution(void); +void system_test_info_print(void);
/* test arrays: */ extern odp_testinfo_t system_suite[];
commit 6110797199e7e253659352d31011450b9b13410d Author: Petri Savolainen petri.savolainen@linaro.org Date: Fri Apr 28 15:09:51 2017 +0300
linux-gen: system: implement system info print
Print API, impl name, CPU model/freq, cache line size and CPU count by default. Print CPU flags in case of x86.
Signed-off-by: Petri Savolainen petri.savolainen@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/arch/arm/odp_sysinfo_parse.c b/platform/linux-generic/arch/arm/odp_sysinfo_parse.c index 53e2aaea..8ae2022a 100644 --- a/platform/linux-generic/arch/arm/odp_sysinfo_parse.c +++ b/platform/linux-generic/arch/arm/odp_sysinfo_parse.c @@ -25,3 +25,7 @@ uint64_t odp_cpu_hz_current(int id ODP_UNUSED) { return 0; } + +void sys_info_print_arch(void) +{ +} diff --git a/platform/linux-generic/arch/default/odp_sysinfo_parse.c b/platform/linux-generic/arch/default/odp_sysinfo_parse.c index 53e2aaea..8ae2022a 100644 --- a/platform/linux-generic/arch/default/odp_sysinfo_parse.c +++ b/platform/linux-generic/arch/default/odp_sysinfo_parse.c @@ -25,3 +25,7 @@ uint64_t odp_cpu_hz_current(int id ODP_UNUSED) { return 0; } + +void sys_info_print_arch(void) +{ +} diff --git a/platform/linux-generic/arch/mips64/odp_sysinfo_parse.c b/platform/linux-generic/arch/mips64/odp_sysinfo_parse.c index 407264b7..d6f75f28 100644 --- a/platform/linux-generic/arch/mips64/odp_sysinfo_parse.c +++ b/platform/linux-generic/arch/mips64/odp_sysinfo_parse.c @@ -62,3 +62,7 @@ uint64_t odp_cpu_hz_current(int id ODP_UNUSED) { return 0; } + +void sys_info_print_arch(void) +{ +} diff --git a/platform/linux-generic/arch/powerpc/odp_sysinfo_parse.c b/platform/linux-generic/arch/powerpc/odp_sysinfo_parse.c index 3b88d55b..bd4b9b42 100644 --- a/platform/linux-generic/arch/powerpc/odp_sysinfo_parse.c +++ b/platform/linux-generic/arch/powerpc/odp_sysinfo_parse.c @@ -61,3 +61,7 @@ uint64_t odp_cpu_hz_current(int id ODP_UNUSED) { return 0; } + +void sys_info_print_arch(void) +{ +} diff --git a/platform/linux-generic/arch/x86/odp_sysinfo_parse.c b/platform/linux-generic/arch/x86/odp_sysinfo_parse.c index 96127ec6..d77165a4 100644 --- a/platform/linux-generic/arch/x86/odp_sysinfo_parse.c +++ b/platform/linux-generic/arch/x86/odp_sysinfo_parse.c @@ -5,6 +5,7 @@ */
#include <odp_internal.h> +#include <arch/x86/cpu_flags.h> #include <string.h>
int cpuinfo_parser(FILE *file, system_info_t *sysinfo) @@ -73,3 +74,8 @@ uint64_t odp_cpu_hz_current(int id)
return 0; } + +void sys_info_print_arch(void) +{ + cpu_flags_print_all(); +} diff --git a/platform/linux-generic/include/odp_internal.h b/platform/linux-generic/include/odp_internal.h index e1267cff..8bae028d 100644 --- a/platform/linux-generic/include/odp_internal.h +++ b/platform/linux-generic/include/odp_internal.h @@ -128,6 +128,7 @@ int _odp_ishm_term_local(void);
int cpuinfo_parser(FILE *file, system_info_t *sysinfo); uint64_t odp_cpu_hz_current(int id); +void sys_info_print_arch(void);
#ifdef __cplusplus } diff --git a/platform/linux-generic/odp_system_info.c b/platform/linux-generic/odp_system_info.c index 18c61dbe..40ffca07 100644 --- a/platform/linux-generic/odp_system_info.c +++ b/platform/linux-generic/odp_system_info.c @@ -14,6 +14,7 @@ #include <odp_posix_extensions.h>
#include <odp/api/system_info.h> +#include <odp/api/version.h> #include <odp_internal.h> #include <odp_debug_internal.h> #include <odp/api/align.h> @@ -405,3 +406,32 @@ int odp_cpu_count(void) { return odp_global_data.system_info.cpu_count; } + +void odp_sys_info_print(void) +{ + int len; + int max_len = 512; + char str[max_len]; + + len = snprintf(str, max_len, "\n" + "ODP system info\n" + "---------------\n" + "ODP API version: %s\n" + "ODP impl name: %s\n" + "CPU model: %s\n" + "CPU freq (hz): %" PRIu64 "\n" + "Cache line size: %i\n" + "CPU count: %i\n" + "\n", + odp_version_api_str(), + odp_version_impl_name(), + odp_cpu_model_str(), + odp_cpu_hz_max(), + odp_sys_cache_line_size(), + odp_cpu_count()); + + str[len] = '\0'; + ODP_PRINT("%s", str); + + sys_info_print_arch(); +}
commit e78e597cd45d9e6fd5b36b8efa5e046dde5f3190 Author: Petri Savolainen petri.savolainen@linaro.org Date: Fri Apr 28 15:09:50 2017 +0300
linux-gen: cpu_flags: added x86 cpu flag read functions
When building on x86 CPU flags can be used to determine which CPU features are supported. CPU flag definitions and the code to read the flags is from DPDK.
Signed-off-by: Petri Savolainen petri.savolainen@linaro.org Reviewed-and-tested-by: Bill Fischofer bill.fischofer@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/configure.ac b/configure.ac index 0743f761..58682564 100644 --- a/configure.ac +++ b/configure.ac @@ -225,6 +225,7 @@ AM_CONDITIONAL([HAVE_DOXYGEN], [test "x${DOXYGEN}" = "xdoxygen"]) AM_CONDITIONAL([user_guide], [test "x${user_guides}" = "xyes" ]) AM_CONDITIONAL([HAVE_MSCGEN], [test "x${MSCGEN}" = "xmscgen"]) AM_CONDITIONAL([helper_linux], [test x$helper_linux = xyes ]) +AM_CONDITIONAL([ARCH_IS_X86], [test "x${ARCH_DIR}" = "xx86"])
########################################################################## # Setup doxygen documentation diff --git a/platform/Makefile.inc b/platform/Makefile.inc index 59a57724..9844a58a 100644 --- a/platform/Makefile.inc +++ b/platform/Makefile.inc @@ -98,4 +98,6 @@ EXTRA_DIST = \ arch/powerpc/odp_sysinfo_parse.c \ arch/x86/odp/api/cpu_arch.h \ arch/x86/odp_cpu_arch.c \ - arch/x86/odp_sysinfo_parse.c + arch/x86/odp_sysinfo_parse.c \ + arch/x86/cpu_flags.c \ + arch/x86/cpu_flags.h diff --git a/platform/linux-generic/Makefile.am b/platform/linux-generic/Makefile.am index 12de626c..6492073d 100644 --- a/platform/linux-generic/Makefile.am +++ b/platform/linux-generic/Makefile.am @@ -221,6 +221,10 @@ __LIB__libodp_linux_la_SOURCES = \ arch/@ARCH_DIR@/odp_cpu_arch.c \ arch/@ARCH_DIR@/odp_sysinfo_parse.c
+if ARCH_IS_X86 +__LIB__libodp_linux_la_SOURCES += arch/@ARCH_DIR@/cpu_flags.c +endif + if HAVE_PCAP __LIB__libodp_linux_la_SOURCES += pktio/pcap.c endif diff --git a/platform/linux-generic/arch/x86/cpu_flags.c b/platform/linux-generic/arch/x86/cpu_flags.c new file mode 100644 index 00000000..954dac27 --- /dev/null +++ b/platform/linux-generic/arch/x86/cpu_flags.c @@ -0,0 +1,359 @@ +/* Copyright (c) 2017, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/*- + * BSD LICENSE + * + * Copyright(c) 2010-2015 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <arch/x86/cpu_flags.h> +#include <odp_debug_internal.h> +#include <stdio.h> +#include <stdint.h> + +enum rte_cpu_flag_t { + /* (EAX 01h) ECX features*/ + RTE_CPUFLAG_SSE3 = 0, /**< SSE3 */ + RTE_CPUFLAG_PCLMULQDQ, /**< PCLMULQDQ */ + RTE_CPUFLAG_DTES64, /**< DTES64 */ + RTE_CPUFLAG_MONITOR, /**< MONITOR */ + RTE_CPUFLAG_DS_CPL, /**< DS_CPL */ + RTE_CPUFLAG_VMX, /**< VMX */ + RTE_CPUFLAG_SMX, /**< SMX */ + RTE_CPUFLAG_EIST, /**< EIST */ + RTE_CPUFLAG_TM2, /**< TM2 */ + RTE_CPUFLAG_SSSE3, /**< SSSE3 */ + RTE_CPUFLAG_CNXT_ID, /**< CNXT_ID */ + RTE_CPUFLAG_FMA, /**< FMA */ + RTE_CPUFLAG_CMPXCHG16B, /**< CMPXCHG16B */ + RTE_CPUFLAG_XTPR, /**< XTPR */ + RTE_CPUFLAG_PDCM, /**< PDCM */ + RTE_CPUFLAG_PCID, /**< PCID */ + RTE_CPUFLAG_DCA, /**< DCA */ + RTE_CPUFLAG_SSE4_1, /**< SSE4_1 */ + RTE_CPUFLAG_SSE4_2, /**< SSE4_2 */ + RTE_CPUFLAG_X2APIC, /**< X2APIC */ + RTE_CPUFLAG_MOVBE, /**< MOVBE */ + RTE_CPUFLAG_POPCNT, /**< POPCNT */ + RTE_CPUFLAG_TSC_DEADLINE, /**< TSC_DEADLINE */ + RTE_CPUFLAG_AES, /**< AES */ + RTE_CPUFLAG_XSAVE, /**< XSAVE */ + RTE_CPUFLAG_OSXSAVE, /**< OSXSAVE */ + RTE_CPUFLAG_AVX, /**< AVX */ + RTE_CPUFLAG_F16C, /**< F16C */ + RTE_CPUFLAG_RDRAND, /**< RDRAND */ + + /* (EAX 01h) EDX features */ + RTE_CPUFLAG_FPU, /**< FPU */ + RTE_CPUFLAG_VME, /**< VME */ + RTE_CPUFLAG_DE, /**< DE */ + RTE_CPUFLAG_PSE, /**< PSE */ + RTE_CPUFLAG_TSC, /**< TSC */ + RTE_CPUFLAG_MSR, /**< MSR */ + RTE_CPUFLAG_PAE, /**< PAE */ + RTE_CPUFLAG_MCE, /**< MCE */ + RTE_CPUFLAG_CX8, /**< CX8 */ + RTE_CPUFLAG_APIC, /**< APIC */ + RTE_CPUFLAG_SEP, /**< SEP */ + RTE_CPUFLAG_MTRR, /**< MTRR */ + RTE_CPUFLAG_PGE, /**< PGE */ + RTE_CPUFLAG_MCA, /**< MCA */ + RTE_CPUFLAG_CMOV, /**< CMOV */ + RTE_CPUFLAG_PAT, /**< PAT */ + RTE_CPUFLAG_PSE36, /**< PSE36 */ + RTE_CPUFLAG_PSN, /**< PSN */ + RTE_CPUFLAG_CLFSH, /**< CLFSH */ + RTE_CPUFLAG_DS, /**< DS */ + RTE_CPUFLAG_ACPI, /**< ACPI */ + RTE_CPUFLAG_MMX, /**< MMX */ + RTE_CPUFLAG_FXSR, /**< FXSR */ + RTE_CPUFLAG_SSE, /**< SSE */ + RTE_CPUFLAG_SSE2, /**< SSE2 */ + RTE_CPUFLAG_SS, /**< SS */ + RTE_CPUFLAG_HTT, /**< HTT */ + RTE_CPUFLAG_TM, /**< TM */ + RTE_CPUFLAG_PBE, /**< PBE */ + + /* (EAX 06h) EAX features */ + RTE_CPUFLAG_DIGTEMP, /**< DIGTEMP */ + RTE_CPUFLAG_TRBOBST, /**< TRBOBST */ + RTE_CPUFLAG_ARAT, /**< ARAT */ + RTE_CPUFLAG_PLN, /**< PLN */ + RTE_CPUFLAG_ECMD, /**< ECMD */ + RTE_CPUFLAG_PTM, /**< PTM */ + + /* (EAX 06h) ECX features */ + RTE_CPUFLAG_MPERF_APERF_MSR, /**< MPERF_APERF_MSR */ + RTE_CPUFLAG_ACNT2, /**< ACNT2 */ + RTE_CPUFLAG_ENERGY_EFF, /**< ENERGY_EFF */ + + /* (EAX 07h, ECX 0h) EBX features */ + RTE_CPUFLAG_FSGSBASE, /**< FSGSBASE */ + RTE_CPUFLAG_BMI1, /**< BMI1 */ + RTE_CPUFLAG_HLE, /**< Hardware Lock elision */ + RTE_CPUFLAG_AVX2, /**< AVX2 */ + RTE_CPUFLAG_SMEP, /**< SMEP */ + RTE_CPUFLAG_BMI2, /**< BMI2 */ + RTE_CPUFLAG_ERMS, /**< ERMS */ + RTE_CPUFLAG_INVPCID, /**< INVPCID */ + RTE_CPUFLAG_RTM, /**< Transactional memory */ + RTE_CPUFLAG_AVX512F, /**< AVX512F */ + + /* (EAX 80000001h) ECX features */ + RTE_CPUFLAG_LAHF_SAHF, /**< LAHF_SAHF */ + RTE_CPUFLAG_LZCNT, /**< LZCNT */ + + /* (EAX 80000001h) EDX features */ + RTE_CPUFLAG_SYSCALL, /**< SYSCALL */ + RTE_CPUFLAG_XD, /**< XD */ + RTE_CPUFLAG_1GB_PG, /**< 1GB_PG */ + RTE_CPUFLAG_RDTSCP, /**< RDTSCP */ + RTE_CPUFLAG_EM64T, /**< EM64T */ + + /* (EAX 80000007h) EDX features */ + RTE_CPUFLAG_INVTSC, /**< INVTSC */ + + /* The last item */ + RTE_CPUFLAG_NUMFLAGS, /**< This should always be the last! */ +}; + +enum cpu_register_t { + RTE_REG_EAX = 0, + RTE_REG_EBX, + RTE_REG_ECX, + RTE_REG_EDX, +}; + +typedef uint32_t cpuid_registers_t[4]; + +/** + * Struct to hold a processor feature entry + */ +struct feature_entry { + uint32_t leaf; /**< cpuid leaf */ + uint32_t subleaf; /**< cpuid subleaf */ + uint32_t reg; /**< cpuid register */ + uint32_t bit; /**< cpuid register bit */ +#define CPU_FLAG_NAME_MAX_LEN 64 + char name[CPU_FLAG_NAME_MAX_LEN]; /**< String for printing */ +}; + +#define FEAT_DEF(name, leaf, subleaf, reg, bit) \ + [RTE_CPUFLAG_##name] = {leaf, subleaf, reg, bit, #name }, + +static const struct feature_entry cpu_feature_table[] = { + FEAT_DEF(SSE3, 0x00000001, 0, RTE_REG_ECX, 0) + FEAT_DEF(PCLMULQDQ, 0x00000001, 0, RTE_REG_ECX, 1) + FEAT_DEF(DTES64, 0x00000001, 0, RTE_REG_ECX, 2) + FEAT_DEF(MONITOR, 0x00000001, 0, RTE_REG_ECX, 3) + FEAT_DEF(DS_CPL, 0x00000001, 0, RTE_REG_ECX, 4) + FEAT_DEF(VMX, 0x00000001, 0, RTE_REG_ECX, 5) + FEAT_DEF(SMX, 0x00000001, 0, RTE_REG_ECX, 6) + FEAT_DEF(EIST, 0x00000001, 0, RTE_REG_ECX, 7) + FEAT_DEF(TM2, 0x00000001, 0, RTE_REG_ECX, 8) + FEAT_DEF(SSSE3, 0x00000001, 0, RTE_REG_ECX, 9) + FEAT_DEF(CNXT_ID, 0x00000001, 0, RTE_REG_ECX, 10) + FEAT_DEF(FMA, 0x00000001, 0, RTE_REG_ECX, 12) + FEAT_DEF(CMPXCHG16B, 0x00000001, 0, RTE_REG_ECX, 13) + FEAT_DEF(XTPR, 0x00000001, 0, RTE_REG_ECX, 14) + FEAT_DEF(PDCM, 0x00000001, 0, RTE_REG_ECX, 15) + FEAT_DEF(PCID, 0x00000001, 0, RTE_REG_ECX, 17) + FEAT_DEF(DCA, 0x00000001, 0, RTE_REG_ECX, 18) + FEAT_DEF(SSE4_1, 0x00000001, 0, RTE_REG_ECX, 19) + FEAT_DEF(SSE4_2, 0x00000001, 0, RTE_REG_ECX, 20) + FEAT_DEF(X2APIC, 0x00000001, 0, RTE_REG_ECX, 21) + FEAT_DEF(MOVBE, 0x00000001, 0, RTE_REG_ECX, 22) + FEAT_DEF(POPCNT, 0x00000001, 0, RTE_REG_ECX, 23) + FEAT_DEF(TSC_DEADLINE, 0x00000001, 0, RTE_REG_ECX, 24) + FEAT_DEF(AES, 0x00000001, 0, RTE_REG_ECX, 25) + FEAT_DEF(XSAVE, 0x00000001, 0, RTE_REG_ECX, 26) + FEAT_DEF(OSXSAVE, 0x00000001, 0, RTE_REG_ECX, 27) + FEAT_DEF(AVX, 0x00000001, 0, RTE_REG_ECX, 28) + FEAT_DEF(F16C, 0x00000001, 0, RTE_REG_ECX, 29) + FEAT_DEF(RDRAND, 0x00000001, 0, RTE_REG_ECX, 30) + + FEAT_DEF(FPU, 0x00000001, 0, RTE_REG_EDX, 0) + FEAT_DEF(VME, 0x00000001, 0, RTE_REG_EDX, 1) + FEAT_DEF(DE, 0x00000001, 0, RTE_REG_EDX, 2) + FEAT_DEF(PSE, 0x00000001, 0, RTE_REG_EDX, 3) + FEAT_DEF(TSC, 0x00000001, 0, RTE_REG_EDX, 4) + FEAT_DEF(MSR, 0x00000001, 0, RTE_REG_EDX, 5) + FEAT_DEF(PAE, 0x00000001, 0, RTE_REG_EDX, 6) + FEAT_DEF(MCE, 0x00000001, 0, RTE_REG_EDX, 7) + FEAT_DEF(CX8, 0x00000001, 0, RTE_REG_EDX, 8) + FEAT_DEF(APIC, 0x00000001, 0, RTE_REG_EDX, 9) + FEAT_DEF(SEP, 0x00000001, 0, RTE_REG_EDX, 11) + FEAT_DEF(MTRR, 0x00000001, 0, RTE_REG_EDX, 12) + FEAT_DEF(PGE, 0x00000001, 0, RTE_REG_EDX, 13) + FEAT_DEF(MCA, 0x00000001, 0, RTE_REG_EDX, 14) + FEAT_DEF(CMOV, 0x00000001, 0, RTE_REG_EDX, 15) + FEAT_DEF(PAT, 0x00000001, 0, RTE_REG_EDX, 16) + FEAT_DEF(PSE36, 0x00000001, 0, RTE_REG_EDX, 17) + FEAT_DEF(PSN, 0x00000001, 0, RTE_REG_EDX, 18) + FEAT_DEF(CLFSH, 0x00000001, 0, RTE_REG_EDX, 19) + FEAT_DEF(DS, 0x00000001, 0, RTE_REG_EDX, 21) + FEAT_DEF(ACPI, 0x00000001, 0, RTE_REG_EDX, 22) + FEAT_DEF(MMX, 0x00000001, 0, RTE_REG_EDX, 23) + FEAT_DEF(FXSR, 0x00000001, 0, RTE_REG_EDX, 24) + FEAT_DEF(SSE, 0x00000001, 0, RTE_REG_EDX, 25) + FEAT_DEF(SSE2, 0x00000001, 0, RTE_REG_EDX, 26) + FEAT_DEF(SS, 0x00000001, 0, RTE_REG_EDX, 27) + FEAT_DEF(HTT, 0x00000001, 0, RTE_REG_EDX, 28) + FEAT_DEF(TM, 0x00000001, 0, RTE_REG_EDX, 29) + FEAT_DEF(PBE, 0x00000001, 0, RTE_REG_EDX, 31) + + FEAT_DEF(DIGTEMP, 0x00000006, 0, RTE_REG_EAX, 0) + FEAT_DEF(TRBOBST, 0x00000006, 0, RTE_REG_EAX, 1) + FEAT_DEF(ARAT, 0x00000006, 0, RTE_REG_EAX, 2) + FEAT_DEF(PLN, 0x00000006, 0, RTE_REG_EAX, 4) + FEAT_DEF(ECMD, 0x00000006, 0, RTE_REG_EAX, 5) + FEAT_DEF(PTM, 0x00000006, 0, RTE_REG_EAX, 6) + + FEAT_DEF(MPERF_APERF_MSR, 0x00000006, 0, RTE_REG_ECX, 0) + FEAT_DEF(ACNT2, 0x00000006, 0, RTE_REG_ECX, 1) + FEAT_DEF(ENERGY_EFF, 0x00000006, 0, RTE_REG_ECX, 3) + + FEAT_DEF(FSGSBASE, 0x00000007, 0, RTE_REG_EBX, 0) + FEAT_DEF(BMI1, 0x00000007, 0, RTE_REG_EBX, 2) + FEAT_DEF(HLE, 0x00000007, 0, RTE_REG_EBX, 4) + FEAT_DEF(AVX2, 0x00000007, 0, RTE_REG_EBX, 5) + FEAT_DEF(SMEP, 0x00000007, 0, RTE_REG_EBX, 6) + FEAT_DEF(BMI2, 0x00000007, 0, RTE_REG_EBX, 7) + FEAT_DEF(ERMS, 0x00000007, 0, RTE_REG_EBX, 8) + FEAT_DEF(INVPCID, 0x00000007, 0, RTE_REG_EBX, 10) + FEAT_DEF(RTM, 0x00000007, 0, RTE_REG_EBX, 11) + FEAT_DEF(AVX512F, 0x00000007, 0, RTE_REG_EBX, 16) + + FEAT_DEF(LAHF_SAHF, 0x80000001, 0, RTE_REG_ECX, 0) + FEAT_DEF(LZCNT, 0x80000001, 0, RTE_REG_ECX, 4) + + FEAT_DEF(SYSCALL, 0x80000001, 0, RTE_REG_EDX, 11) + FEAT_DEF(XD, 0x80000001, 0, RTE_REG_EDX, 20) + FEAT_DEF(1GB_PG, 0x80000001, 0, RTE_REG_EDX, 26) + FEAT_DEF(RDTSCP, 0x80000001, 0, RTE_REG_EDX, 27) + FEAT_DEF(EM64T, 0x80000001, 0, RTE_REG_EDX, 29) + + FEAT_DEF(INVTSC, 0x80000007, 0, RTE_REG_EDX, 8) +}; + +/* + * Execute CPUID instruction and get contents of a specific register + * + * This function, when compiled with GCC, will generate architecture-neutral + * code, as per GCC manual. + */ +static void cpu_get_features(uint32_t leaf, uint32_t subleaf, + cpuid_registers_t out) +{ +#if defined(__i386__) && defined(__PIC__) + /* %ebx is a forbidden register if we compile with -fPIC or -fPIE */ + __asm__ __volatile__("movl %%ebx,%0 ; cpuid ; xchgl %%ebx,%0" + : "=r" (out[RTE_REG_EBX]), + "=a" (out[RTE_REG_EAX]), + "=c" (out[RTE_REG_ECX]), + "=d" (out[RTE_REG_EDX]) + : "a" (leaf), "c" (subleaf)); +#else + __asm__ __volatile__("cpuid" + : "=a" (out[RTE_REG_EAX]), + "=b" (out[RTE_REG_EBX]), + "=c" (out[RTE_REG_ECX]), + "=d" (out[RTE_REG_EDX]) + : "a" (leaf), "c" (subleaf)); +#endif +} + +static int cpu_get_flag_enabled(enum rte_cpu_flag_t feature) +{ + const struct feature_entry *feat; + cpuid_registers_t regs; + + if (feature >= RTE_CPUFLAG_NUMFLAGS) + /* Flag does not match anything in the feature tables */ + return -1; + + feat = &cpu_feature_table[feature]; + + if (!feat->leaf) + /* This entry in the table wasn't filled out! */ + return -1; + + cpu_get_features(feat->leaf & 0xffff0000, 0, regs); + if (((regs[RTE_REG_EAX] ^ feat->leaf) & 0xffff0000) || + regs[RTE_REG_EAX] < feat->leaf) + return 0; + + /* get the cpuid leaf containing the desired feature */ + cpu_get_features(feat->leaf, feat->subleaf, regs); + + /* check if the feature is enabled */ + return (regs[feat->reg] >> feat->bit) & 1; +} + +static const char *cpu_get_flag_name(enum rte_cpu_flag_t feature) +{ + if (feature >= RTE_CPUFLAG_NUMFLAGS) + return NULL; + return cpu_feature_table[feature].name; +} + +void cpu_flags_print_all(void) +{ + int len, i; + int max_str = 1024; + int max_len = max_str - 1; + char str[max_str]; + + len = snprintf(str, max_len, "\nCPU features supported:\n"); + + for (i = 0; i < RTE_CPUFLAG_NUMFLAGS; i++) { + if (cpu_get_flag_enabled(i) > 0) + len += snprintf(&str[len], max_len - len, "%s ", + cpu_get_flag_name(i)); + } + + len += snprintf(&str[len], max_len - len, + "\n\nCPU features NOT supported:\n"); + + for (i = 0; i < RTE_CPUFLAG_NUMFLAGS; i++) { + if (cpu_get_flag_enabled(i) <= 0) + len += snprintf(&str[len], max_len - len, "%s ", + cpu_get_flag_name(i)); + } + + len += snprintf(&str[len], max_len - len, "\n\n"); + + str[len] = '\0'; + ODP_PRINT("%s", str); +} diff --git a/platform/linux-generic/arch/x86/cpu_flags.h b/platform/linux-generic/arch/x86/cpu_flags.h new file mode 100644 index 00000000..f709ca08 --- /dev/null +++ b/platform/linux-generic/arch/x86/cpu_flags.h @@ -0,0 +1,20 @@ +/* Copyright (c) 2017, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef ODP_PLAT_CPU_FLAGS_H_ +#define ODP_PLAT_CPU_FLAGS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +void cpu_flags_print_all(void); + +#ifdef __cplusplus +} +#endif + +#endif
commit 656272a80373740140d983213c6336b982633f22 Author: Petri Savolainen petri.savolainen@linaro.org Date: Fri Apr 28 15:09:49 2017 +0300
api: system: added system info print
This information specifies the system where ODP application is running for debugging purposes.
Signed-off-by: Petri Savolainen petri.savolainen@linaro.org Reviewed-and-tested-by: Bill Fischofer bill.fischofer@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/include/odp/api/spec/system_info.h b/include/odp/api/spec/system_info.h index 0bb4f1f1..ca4dcdc7 100644 --- a/include/odp/api/spec/system_info.h +++ b/include/odp/api/spec/system_info.h @@ -45,6 +45,15 @@ uint64_t odp_sys_page_size(void); int odp_sys_cache_line_size(void);
/** + * Print system info + * + * Print out implementation defined information about the system. This + * information is intended for debugging purposes and may contain e.g. + * information about CPUs, memory and other HW configuration. + */ +void odp_sys_info_print(void); + +/** * @} */
commit f7e7ba1373522283c313c7ceebce5e8454f43e09 Author: Petri Savolainen petri.savolainen@linaro.org Date: Fri Apr 28 15:09:48 2017 +0300
api: time: remove odp_time_to_u64 from API
Debug function that converts odp_time_t to u64 is unnecessary since odp_time_to_ns() returns time as a u64 (nsec) value. Application can always use that as the 64 bit representation of an odp_time_t value. Also validation tests for odp_time_to_u64() were erroneous since those compared returned u64 values and expected greater/lesser than relation.
Signed-off-by: Petri Savolainen petri.savolainen@linaro.org Reviewed-and-tested-by: Bill Fischofer bill.fischofer@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/include/odp/api/spec/time.h b/include/odp/api/spec/time.h index fcc94c98..29175eb5 100644 --- a/include/odp/api/spec/time.h +++ b/include/odp/api/spec/time.h @@ -158,19 +158,6 @@ void odp_time_wait_until(odp_time_t time); void odp_time_wait_ns(uint64_t ns);
/** - * Get printable value for an odp_time_t - * - * @param time time to be printed - * - * @return uint64_t value that can be used to print/display this time - * - * @note This routine is intended to be used for diagnostic purposes - * to enable applications to generate a printable value that represents - * an odp_time_t time. - */ -uint64_t odp_time_to_u64(odp_time_t time); - -/** * @} */
diff --git a/platform/linux-generic/odp_time.c b/platform/linux-generic/odp_time.c index 81e05224..0e5966c0 100644 --- a/platform/linux-generic/odp_time.c +++ b/platform/linux-generic/odp_time.c @@ -176,21 +176,6 @@ void odp_time_wait_until(odp_time_t time) return time_wait_until(time); }
-uint64_t odp_time_to_u64(odp_time_t time) -{ - int ret; - struct timespec tres; - uint64_t resolution; - - ret = clock_getres(CLOCK_MONOTONIC_RAW, &tres); - if (odp_unlikely(ret != 0)) - ODP_ABORT("clock_getres failed\n"); - - resolution = (uint64_t)tres.tv_nsec; - - return time_to_ns(time) / resolution; -} - int odp_time_init_global(void) { int ret; diff --git a/test/common_plat/validation/api/time/time.c b/test/common_plat/validation/api/time/time.c index 530d5c07..df65c719 100644 --- a/test/common_plat/validation/api/time/time.c +++ b/test/common_plat/validation/api/time/time.c @@ -398,41 +398,6 @@ void time_test_wait_ns(void) } }
-static void time_test_to_u64(time_cb time) -{ - volatile int count = 0; - uint64_t val1, val2; - odp_time_t t1, t2; - - t1 = time(); - - val1 = odp_time_to_u64(t1); - CU_ASSERT(val1 > 0); - - while (count < BUSY_LOOP_CNT) { - count++; - }; - - t2 = time(); - val2 = odp_time_to_u64(t2); - CU_ASSERT(val2 > 0); - - CU_ASSERT(val2 > val1); - - val1 = odp_time_to_u64(ODP_TIME_NULL); - CU_ASSERT(val1 == 0); -} - -void time_test_local_to_u64(void) -{ - time_test_to_u64(odp_time_local); -} - -void time_test_global_to_u64(void) -{ - time_test_to_u64(odp_time_global); -} - odp_testinfo_t time_suite_time[] = { ODP_TEST_INFO(time_test_constants), ODP_TEST_INFO(time_test_local_res), @@ -443,14 +408,12 @@ odp_testinfo_t time_suite_time[] = { ODP_TEST_INFO(time_test_local_sum), ODP_TEST_INFO(time_test_local_wait_until), ODP_TEST_INFO(time_test_wait_ns), - ODP_TEST_INFO(time_test_local_to_u64), ODP_TEST_INFO(time_test_global_res), ODP_TEST_INFO(time_test_global_conversion), ODP_TEST_INFO(time_test_global_cmp), ODP_TEST_INFO(time_test_global_diff), ODP_TEST_INFO(time_test_global_sum), ODP_TEST_INFO(time_test_global_wait_until), - ODP_TEST_INFO(time_test_global_to_u64), ODP_TEST_INFO_NULL };
diff --git a/test/common_plat/validation/api/time/time.h b/test/common_plat/validation/api/time/time.h index e5132a49..10956294 100644 --- a/test/common_plat/validation/api/time/time.h +++ b/test/common_plat/validation/api/time/time.h @@ -24,8 +24,6 @@ void time_test_global_sum(void); void time_test_local_wait_until(void); void time_test_global_wait_until(void); void time_test_wait_ns(void); -void time_test_local_to_u64(void); -void time_test_global_to_u64(void); void time_test_monotony(void);
/* test arrays: */
commit f1bc34659c87405f1b9bf29695aa75d00be0e140 Author: Bill Fischofer bill.fischofer@linaro.org Date: Fri Apr 21 09:25:25 2017 -0500
helper: add additional doxygen documentation
Resolve Bug https://bugs.linaro.org/show_bug.cgi?id=2952 by adding additional field documentation to avoid problems with doxygen 1.8.13 and higher.
Signed-off-by: Bill Fischofer bill.fischofer@linaro.org Reviewed-by: Petri Savolainen petri.savolainen@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/helper/include/odp/helper/icmp.h b/helper/include/odp/helper/icmp.h index e25646ad..bef96784 100644 --- a/helper/include/odp/helper/icmp.h +++ b/helper/include/odp/helper/icmp.h @@ -32,15 +32,18 @@ typedef struct ODP_PACKED { uint8_t type; /**< message type */ uint8_t code; /**< type sub-code */ odp_u16sum_t chksum; /**< checksum of icmp header */ + /** Variant mappings of ICMP fields */ union { + /** Fields used for ICMP echo msgs */ struct { - odp_u16be_t id; - odp_u16be_t sequence; + odp_u16be_t id; /**< id */ + odp_u16be_t sequence; /**< sequence */ } echo; /**< echo datagram */ odp_u32be_t gateway; /**< gateway address */ + /** Fields used for ICMP frag msgs */ struct { - odp_u16be_t __unused; - odp_u16be_t mtu; + odp_u16be_t __unused; /**< @internal */ + odp_u16be_t mtu; /**< mtu */ } frag; /**< path mtu discovery */ } un; /**< icmp sub header */ } odph_icmphdr_t; diff --git a/helper/include/odp/helper/strong_types.h b/helper/include/odp/helper/strong_types.h index 13e35a43..501d0f28 100644 --- a/helper/include/odp/helper/strong_types.h +++ b/helper/include/odp/helper/strong_types.h @@ -20,10 +20,11 @@
/** Use strong typing for ODP types */ #ifdef __cplusplus +/** @internal C++ helper macro for strong typing @param type @return */ #define ODPH_HANDLE_T(type) struct _##type { uint8_t unused_dummy_var; } *type #else #define odph_handle_t struct { uint8_t unused_dummy_var; } * -/** C/C++ helper macro for strong typing */ +/** @internal C helper macro for strong typing @param type @return */ #define ODPH_HANDLE_T(type) odph_handle_t type #endif
diff --git a/helper/include/odp/helper/table.h b/helper/include/odp/helper/table.h index b3440ef5..96c9c5fe 100644 --- a/helper/include/odp/helper/table.h +++ b/helper/include/odp/helper/table.h @@ -94,7 +94,7 @@ extern "C" { #define ODPH_TABLE_NAME_LEN 32
#include <odp/helper/strong_types.h> -/** ODP table handle */ +/** @internal ODPH table handle @return */ typedef ODPH_HANDLE_T(odph_table_t);
/** diff --git a/helper/include/odp/helper/tcp.h b/helper/include/odp/helper/tcp.h index fd234e58..e91b52e2 100644 --- a/helper/include/odp/helper/tcp.h +++ b/helper/include/odp/helper/tcp.h @@ -32,8 +32,9 @@ typedef struct ODP_PACKED { odp_u16be_t dst_port; /**< Destination port */ odp_u32be_t seq_no; /**< Sequence number */ odp_u32be_t ack_no; /**< Acknowledgment number */ + /** Variant maps for TCP header fields */ union { - odp_u16be_t doffset_flags; + odp_u16be_t doffset_flags; /**< TCP Flags aggregate */ #if ODP_BIG_ENDIAN_BITFIELD struct { odp_u16be_t rsvd1:8; @@ -42,14 +43,14 @@ typedef struct ODP_PACKED { struct { odp_u16be_t hl:4; /**< Hdr len, in words */ odp_u16be_t rsvd3:4; /**< Reserved */ - odp_u16be_t cwr:1; - odp_u16be_t ece:1; - odp_u16be_t urg:1; - odp_u16be_t ack:1; - odp_u16be_t psh:1; - odp_u16be_t rst:1; - odp_u16be_t syn:1; - odp_u16be_t fin:1; + odp_u16be_t cwr:1; /**< cwr bit */ + odp_u16be_t ece:1; /**< ece bit */ + odp_u16be_t urg:1; /**< urg bit */ + odp_u16be_t ack:1; /**< ack bit */ + odp_u16be_t psh:1; /**< psh bit */ + odp_u16be_t rst:1; /**< rst bit */ + odp_u16be_t syn:1; /**< syn bit */ + odp_u16be_t fin:1; /**< fin bit */ }; #elif ODP_LITTLE_ENDIAN_BITFIELD struct { @@ -59,14 +60,14 @@ typedef struct ODP_PACKED { struct { odp_u16be_t rsvd3:4; /**< Reserved */ odp_u16be_t hl:4; /**< Hdr len, in words */ - odp_u16be_t fin:1; - odp_u16be_t syn:1; - odp_u16be_t rst:1; - odp_u16be_t psh:1; - odp_u16be_t ack:1; - odp_u16be_t urg:1; - odp_u16be_t ece:1; - odp_u16be_t cwr:1; + odp_u16be_t fin:1; /**< fin bit */ + odp_u16be_t syn:1; /**< syn bit */ + odp_u16be_t rst:1; /**< rst bit */ + odp_u16be_t psh:1; /**< psh bit */ + odp_u16be_t ack:1; /**< ack bit */ + odp_u16be_t urg:1; /**< urg bit */ + odp_u16be_t ece:1; /**< ece bit */ + odp_u16be_t cwr:1; /**< cwr bit */ };
#else diff --git a/helper/include/odp/helper/threads.h b/helper/include/odp/helper/threads.h index 5682bab9..526f0d48 100644 --- a/helper/include/odp/helper/threads.h +++ b/helper/include/odp/helper/threads.h @@ -80,12 +80,15 @@ typedef struct { odph_odpthread_start_args_t start_args; /**< start arguments */ int cpu; /**< CPU ID */ int last; /**< true if last table entry */ + /** Variant field mappings for thread/process modes */ union { - struct { /* for thread implementation */ + /** For thread implementation */ + struct { pthread_t thread_id; /**< Pthread ID */ pthread_attr_t attr; /**< Pthread attributes */ } thread; - struct { /* for process implementation */ + /** For process implementation */ + struct { pid_t pid; /**< Process ID */ int status; /**< Process state chge status*/ } proc;
commit 42117d5a3400b9f0e364eb6bc4670d145afc4dbe Author: Bill Fischofer bill.fischofer@linaro.org Date: Fri Apr 21 09:25:24 2017 -0500
linux-generic: types: add additional doxygen documentation
Resolve Bug https://bugs.linaro.org/show_bug.cgi?id=2952 by adding additional field documentation to avoid problems with doxygen 1.8.13 and higher.
Signed-off-by: Bill Fischofer bill.fischofer@linaro.org Reviewed-by: Petri Savolainen petri.savolainen@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/platform/linux-generic/include/odp/api/debug.h b/platform/linux-generic/include/odp/api/debug.h index b0f91b1c..bef2fd0e 100644 --- a/platform/linux-generic/include/odp/api/debug.h +++ b/platform/linux-generic/include/odp/api/debug.h @@ -25,17 +25,23 @@ extern "C" { * versions. */ #define _odp_merge(a, b) a##b +/** @internal */ #define _odp_label(a) _odp_merge(_ODP_SASSERT_, a) +/** @internal */ #define _ODP_SASSERT _odp_label(__COUNTER__) +/** @internal */ #define _ODP_SASSERT_ENUM(e) { _ODP_SASSERT = 1 / !!(e) } +/** @internal */ #define _odp_static_assert(e, s) enum _ODP_SASSERT_ENUM(e)
#if defined(__clang__) #if defined(__cplusplus) #if !__has_feature(cxx_static_assert) && !defined(static_assert) +/** @internal */ #define static_assert(e, s) _odp_static_assert(e, s) #endif #elif !__has_feature(c_static_assert) && !defined(_Static_assert) +/** @internal */ #define _Static_assert(e, s) _odp_static_assert(e, s) #endif
@@ -44,9 +50,11 @@ extern "C" { (__GNUC__ < 6 && defined(__cplusplus)) #if defined(__cplusplus) #if !defined(static_assert) +/** @intenral */ #define static_assert(e, s) _odp_static_assert(e, s) #endif #elif !defined(_Static_assert) +/** @internal */ #define _Static_assert(e, s) _odp_static_assert(e, s) #endif #endif diff --git a/platform/linux-generic/include/odp/api/plat/packet_types.h b/platform/linux-generic/include/odp/api/plat/packet_types.h index 7e3c51e6..95cba5eb 100644 --- a/platform/linux-generic/include/odp/api/plat/packet_types.h +++ b/platform/linux-generic/include/odp/api/plat/packet_types.h @@ -105,6 +105,7 @@ typedef union { /** All input flags */ uint64_t all;
+ /** Individual input flags */ struct { uint64_t parsed_l2:1; /**< L2 parsed */ uint64_t dst_queue:1; /**< Dst queue present */ diff --git a/platform/linux-generic/include/odp/api/plat/traffic_mngr_types.h b/platform/linux-generic/include/odp/api/plat/traffic_mngr_types.h index b766afec..f47a13f6 100644 --- a/platform/linux-generic/include/odp/api/plat/traffic_mngr_types.h +++ b/platform/linux-generic/include/odp/api/plat/traffic_mngr_types.h @@ -168,7 +168,7 @@ typedef odp_tm_handle_t odp_tm_wred_t; */ #define ODP_TM_ROOT ((odp_tm_handle_t)-1)
-/** Get printable format of odp_queue_t */ +/** @internal Get printable format of odp_tm_handle_t @param hdl @return */ static inline uint64_t odp_tm_handle_to_u64(odp_tm_handle_t hdl) { return hdl;
commit d9efed317ef9900ef5a89f5ecf7a71344dbc3e04 Author: Bill Fischofer bill.fischofer@linaro.org Date: Fri Apr 21 09:25:23 2017 -0500
api: tm: add additional doxygen documentation
Resolve Bug https://bugs.linaro.org/show_bug.cgi?id=2952 by adding additional field documentation to avoid problems with doxygen 1.8.13 and higher.
Signed-off-by: Bill Fischofer bill.fischofer@linaro.org Reviewed-by: Petri Savolainen petri.savolainen@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/include/odp/api/spec/traffic_mngr.h b/include/odp/api/spec/traffic_mngr.h index 71198bbd..3a748cef 100644 --- a/include/odp/api/spec/traffic_mngr.h +++ b/include/odp/api/spec/traffic_mngr.h @@ -471,9 +471,10 @@ typedef enum { typedef struct { odp_tm_egress_kind_t egress_kind; /**< Union discriminator */
+ /** Variant parameters for different TM outputs */ union { - odp_pktio_t pktio; - odp_tm_egress_fcn_t egress_fcn; + odp_pktio_t pktio; /**< Output to PktIO */ + odp_tm_egress_fcn_t egress_fcn; /**< Output to user func */ }; } odp_tm_egress_t;
commit 9959f0d04d83eebd9bb0a4520e1cce1626343772 Author: Bill Fischofer bill.fischofer@linaro.org Date: Fri Apr 21 09:25:22 2017 -0500
api: pool: add additional doxygen documentation
Resolve Bug https://bugs.linaro.org/show_bug.cgi?id=2952 by adding additional field documentation to avoid problems with doxygen 1.8.13 and higher.
Signed-off-by: Bill Fischofer bill.fischofer@linaro.org Reviewed-by: Petri Savolainen petri.savolainen@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/include/odp/api/spec/pool.h b/include/odp/api/spec/pool.h index c0de195a..6fc5b6b4 100644 --- a/include/odp/api/spec/pool.h +++ b/include/odp/api/spec/pool.h @@ -166,7 +166,9 @@ typedef struct odp_pool_param_t { /** Pool type */ int type;
+ /** Variant parameters for different pool types */ union { + /** Parameters for buffer pools */ struct { /** Number of buffers in the pool */ uint32_t num; @@ -180,6 +182,8 @@ typedef struct odp_pool_param_t { Default will always be a multiple of 8. */ uint32_t align; } buf; + + /** Parameters for packet pools */ struct { /** The number of packets that the pool must provide that are packet length 'len' bytes or smaller. @@ -211,6 +215,8 @@ typedef struct odp_pool_param_t { Specify as 0 if no user area is needed. */ uint32_t uarea_size; } pkt; + + /** Parameters for timeout pools */ struct { /** Number of timeouts in the pool */ uint32_t num;
commit cf495ab4fea270115aaf0f9c6be8e3c6f2ec4524 Author: Honnappa Nagarahalli honnappa.nagarahalli@linaro.org Date: Thu Apr 6 23:07:04 2017 -0500
helper: cuckoo: add queue size config to cuckoo table
Some queue implementations in ODP take queue size input. Cuckoo table is modified to provide the queue size input while creating the queue.
Signed-off-by: Honnappa Nagarahalli honnappa.nagarahalli@linaro.org Reviewed-by: Bill Fischofer bill.fischofer@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/helper/cuckootable.c b/helper/cuckootable.c index 80ff4989..0d46300e 100644 --- a/helper/cuckootable.c +++ b/helper/cuckootable.c @@ -256,6 +256,7 @@ odph_cuckoo_table_create( /* initialize free_slots queue */ odp_queue_param_init(&qparam); qparam.type = ODP_QUEUE_TYPE_PLAIN; + qparam.size = capacity;
snprintf(queue_name, sizeof(queue_name), "fs_%s", name); queue = odp_queue_create(queue_name, &qparam);
commit e89884f30208ad5751c687713e6cad38d573b4f5 Author: Kevin Wang kevin.wang@arm.com Date: Fri Apr 14 10:57:21 2017 +0800
validation: scheduler: release context according to scheduler sync type
For different scheduler sync type, need to call different release function.
Signed-off-by: Kevin Wang kevin.wang@arm.com Reviewed-by: Honnappa Nagarahalli honnappa.nagarahalli@arm.com Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/test/common_plat/validation/api/scheduler/scheduler.c b/test/common_plat/validation/api/scheduler/scheduler.c index f46d3910..4f99435c 100644 --- a/test/common_plat/validation/api/scheduler/scheduler.c +++ b/test/common_plat/validation/api/scheduler/scheduler.c @@ -129,6 +129,14 @@ static int exit_schedule_loop(void) return ret; }
+static void release_context(odp_schedule_sync_t sync) +{ + if (sync == ODP_SCHED_SYNC_ATOMIC) + odp_schedule_release_atomic(); + else if (sync == ODP_SCHED_SYNC_ORDERED) + odp_schedule_release_ordered(); +} + void scheduler_test_wait_time(void) { int i; @@ -251,8 +259,7 @@ void scheduler_test_queue_destroy(void) CU_ASSERT_FATAL(u32[0] == MAGIC);
odp_buffer_free(buf); - odp_schedule_release_ordered(); - + release_context(qp.sched.sync); CU_ASSERT_FATAL(odp_queue_destroy(queue) == 0); }
@@ -820,12 +827,7 @@ static int schedule_common_(void *arg) } }
- if (sync == ODP_SCHED_SYNC_ATOMIC) - odp_schedule_release_atomic(); - - if (sync == ODP_SCHED_SYNC_ORDERED) - odp_schedule_release_ordered(); - + release_context(sync); odp_ticketlock_lock(&globals->lock);
globals->buf_count -= num;
commit cfcd4b990d1825fbedca00fd38cac981dbaa5951 Author: Kevin Wang kevin.wang@arm.com Date: Tue Apr 11 10:38:06 2017 +0800
validation: scheduler: modify the queue size for atomic queue
Signed-off-by: Kevin Wang kevin.wang@arm.com Reviewed-by: Honnappa Nagarahalli honnappa.nagarahalli@arm.com Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/test/common_plat/validation/api/scheduler/scheduler.c b/test/common_plat/validation/api/scheduler/scheduler.c index 952561cd..f46d3910 100644 --- a/test/common_plat/validation/api/scheduler/scheduler.c +++ b/test/common_plat/validation/api/scheduler/scheduler.c @@ -1388,6 +1388,7 @@ static int create_queues(void)
snprintf(name, sizeof(name), "sched_%d_%d_a", i, j); p.sched.sync = ODP_SCHED_SYNC_ATOMIC; + p.size = BUFS_PER_QUEUE_EXCL; q = odp_queue_create(name, &p);
if (q == ODP_QUEUE_INVALID) { @@ -1423,6 +1424,7 @@ static int create_queues(void) snprintf(name, sizeof(name), "sched_%d_%d_o", i, j); p.sched.sync = ODP_SCHED_SYNC_ORDERED; p.sched.lock_count = capa.max_ordered_locks; + p.size = 0; q = odp_queue_create(name, &p);
if (q == ODP_QUEUE_INVALID) {
commit 413813b897c15e430699f9f06b78633cd9f9536f Author: Petri Savolainen petri.savolainen@linaro.org Date: Thu Apr 13 17:40:51 2017 +0300
validation: queue: test queue max_num per type
Updated implementation and test with type specific number of queues.
Signed-off-by: Petri Savolainen petri.savolainen@linaro.org Reviewed-by: Bill Fischofer bill.fischofer@linaro.org Reviewed-by: Honnappa Nagarahalli honnappa.nagarahalli@linaro.org Reviewed-by: Balasubramanian Manoharan bala.manoharan@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/platform/linux-generic/odp_queue.c b/platform/linux-generic/odp_queue.c index a96f9225..dd430cd1 100644 --- a/platform/linux-generic/odp_queue.c +++ b/platform/linux-generic/odp_queue.c @@ -176,6 +176,8 @@ int odp_queue_capability(odp_queue_capability_t *capa) capa->max_ordered_locks = sched_fn->max_ordered_locks(); capa->max_sched_groups = sched_fn->num_grps(); capa->sched_prios = odp_schedule_num_prio(); + capa->plain.max_num = capa->max_queues; + capa->sched.max_num = capa->max_queues;
return 0; } diff --git a/test/common_plat/validation/api/queue/queue.c b/test/common_plat/validation/api/queue/queue.c index 1f7913a1..6a13c006 100644 --- a/test/common_plat/validation/api/queue/queue.c +++ b/test/common_plat/validation/api/queue/queue.c @@ -56,7 +56,7 @@ void queue_test_capa(void) odp_queue_param_t qparams; char name[ODP_QUEUE_NAME_LEN]; odp_queue_t queue[MAX_QUEUES]; - uint32_t num_queues, i; + uint32_t num_queues, min, i, j;
memset(&capa, 0, sizeof(odp_queue_capability_t)); CU_ASSERT(odp_queue_capability(&capa) == 0); @@ -65,34 +65,49 @@ void queue_test_capa(void) CU_ASSERT(capa.max_ordered_locks != 0); CU_ASSERT(capa.max_sched_groups != 0); CU_ASSERT(capa.sched_prios != 0); + CU_ASSERT(capa.plain.max_num != 0); + CU_ASSERT(capa.sched.max_num != 0); + + min = capa.plain.max_num; + if (min > capa.sched.max_num) + min = capa.sched.max_num; + + CU_ASSERT(capa.max_queues >= min);
for (i = 0; i < ODP_QUEUE_NAME_LEN; i++) name[i] = 'A' + (i % 26);
name[ODP_QUEUE_NAME_LEN - 1] = 0;
- if (capa.max_queues > MAX_QUEUES) - num_queues = MAX_QUEUES; - else - num_queues = capa.max_queues; - odp_queue_param_init(&qparams);
- for (i = 0; i < num_queues; i++) { - generate_name(name, i); - queue[i] = odp_queue_create(name, &qparams); + for (j = 0; j < 2; j++) { + if (j == 0) { + num_queues = capa.plain.max_num; + } else { + num_queues = capa.sched.max_num; + qparams.type = ODP_QUEUE_TYPE_SCHED; + } + + if (num_queues > MAX_QUEUES) + num_queues = MAX_QUEUES;
- if (queue[i] == ODP_QUEUE_INVALID) { - CU_FAIL("Queue create failed"); - num_queues = i; - break; + for (i = 0; i < num_queues; i++) { + generate_name(name, i); + queue[i] = odp_queue_create(name, &qparams); + + if (queue[i] == ODP_QUEUE_INVALID) { + CU_FAIL("Queue create failed"); + num_queues = i; + break; + } + + CU_ASSERT(odp_queue_lookup(name) != ODP_QUEUE_INVALID); }
- CU_ASSERT(odp_queue_lookup(name) != ODP_QUEUE_INVALID); + for (i = 0; i < num_queues; i++) + CU_ASSERT(odp_queue_destroy(queue[i]) == 0); } - - for (i = 0; i < num_queues; i++) - CU_ASSERT(odp_queue_destroy(queue[i]) == 0); }
void queue_test_mode(void)
commit aad1266fd6517118e7f115f7e97d638313c8903b Author: Petri Savolainen petri.savolainen@linaro.org Date: Thu Apr 13 17:40:50 2017 +0300
api: queue: added queue size param
Added capability information about maximum number of queues and queue sizes. Both are defined per queue type, since plain and scheduled queues may have different implementations (e.g. one uses HW while the other is SW).
Added queue size parameter, which specifies how large storage size application requires in minimum.
Signed-off-by: Petri Savolainen petri.savolainen@linaro.org Reviewed-by: Bill Fischofer bill.fischofer@linaro.org Reviewed-by: Honnappa Nagarahalli honnappa.nagarahalli@linaro.org Reviewed-by: Balasubramanian Manoharan bala.manoharan@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/include/odp/api/spec/queue.h b/include/odp/api/spec/queue.h index 7972feac..9dd0a561 100644 --- a/include/odp/api/spec/queue.h +++ b/include/odp/api/spec/queue.h @@ -100,7 +100,9 @@ typedef enum odp_queue_op_mode_t { * Queue capabilities */ typedef struct odp_queue_capability_t { - /** Maximum number of event queues */ + /** Maximum number of event queues of any type (default size). Use + * this in addition to queue type specific 'max_num', if both queue + * types are used simultaneously. */ uint32_t max_queues;
/** Maximum number of ordered locks per queue */ @@ -112,6 +114,32 @@ typedef struct odp_queue_capability_t { /** Number of scheduling priorities */ unsigned sched_prios;
+ /** Plain queue capabilities */ + struct { + /** Maximum number of plain queues of the default size. */ + uint32_t max_num; + + /** Maximum number of events a plain queue can store + * simultaneously. The value of zero means that plain + * queues do not have a size limit, but a single queue can + * store all available events. */ + uint32_t max_size; + + } plain; + + /** Scheduled queue capabilities */ + struct { + /** Maximum number of scheduled queues of the default size. */ + uint32_t max_num; + + /** Maximum number of events a scheduled queue can store + * simultaneously. The value of zero means that scheduled + * queues do not have a size limit, but a single queue can + * store all available events. */ + uint32_t max_size; + + } sched; + } odp_queue_capability_t;
/** @@ -165,6 +193,15 @@ typedef struct odp_queue_param_t { * The implementation may use this value as a hint for the number of * context data bytes to prefetch. Default value is zero (no hint). */ uint32_t context_len; + + /** Queue size + * + * The queue must be able to store at minimum this many events + * simultaneously. The value must not exceed 'max_size' queue + * capability. The value of zero means implementation specific + * default size. */ + uint32_t size; + } odp_queue_param_t;
/**
commit 3214a1a34e3639903c18e4a99346261d9d5d39a0 Author: Matias Elo matias.elo@nokia.com Date: Thu Apr 6 17:41:17 2017 +0300
validation: pktio: remove CRCs from parser test packets
Remove precalculated CRCs from test packets. Some pktio devices may drop CRCs causing the tests to fail.
Signed-off-by: Matias Elo matias.elo@nokia.com Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/test/common_plat/validation/api/pktio/parser.h b/test/common_plat/validation/api/pktio/parser.h index 57c62388..5cc2b988 100644 --- a/test/common_plat/validation/api/pktio/parser.h +++ b/test/common_plat/validation/api/pktio/parser.h @@ -28,6 +28,8 @@ int parser_suite_init(void); /* test arrays: */ extern odp_testinfo_t parser_suite[];
+/* Test packets without CRC */ + /** * ARP request */ @@ -39,7 +41,7 @@ static const uint8_t test_packet_arp[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xA8, 0x01, 0x02, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, - 0x0E, 0x0F, 0x10, 0x11, 0xA1, 0xA8, 0x27, 0x43, + 0x0E, 0x0F, 0x10, 0x11 };
/** @@ -53,7 +55,7 @@ static const uint8_t test_packet_ipv4_icmp[] = { 0x01, 0x02, 0x00, 0x00, 0xB7, 0xAB, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, - 0x0E, 0x0F, 0x10, 0x11, 0xD9, 0x7F, 0xE8, 0x02, + 0x0E, 0x0F, 0x10, 0x11 };
/** @@ -67,7 +69,7 @@ static const uint8_t test_packet_ipv4_tcp[] = { 0x01, 0x01, 0x04, 0xD2, 0x10, 0xE1, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x50, 0x00, 0x00, 0x00, 0x0C, 0xCC, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x03, 0x04, 0x05, 0x2E, 0xDE, 0x5E, 0x48, + 0x02, 0x03, 0x04, 0x05 };
/** @@ -81,7 +83,7 @@ static const uint8_t test_packet_ipv4_udp[] = { 0x01, 0x01, 0x00, 0x3F, 0x00, 0x3F, 0x00, 0x1A, 0x2F, 0x97, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, - 0x0E, 0x0F, 0x10, 0x11, 0x64, 0xF4, 0xE4, 0xB6, + 0x0E, 0x0F, 0x10, 0x11 };
/** @@ -96,7 +98,7 @@ static const uint8_t test_packet_vlan_ipv4_udp[] = { 0x01, 0x02, 0xC4, 0xA8, 0x01, 0x01, 0x00, 0x3F, 0x00, 0x3F, 0x00, 0x16, 0x4D, 0xBF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, - 0x0A, 0x0B, 0x0C, 0x0D, 0xCB, 0xBF, 0xD0, 0x29, + 0x0A, 0x0B, 0x0C, 0x0D };
/** @@ -112,7 +114,7 @@ static const uint8_t test_packet_vlan_qinq_ipv4_udp[] = { 0xF3, 0x73, 0xC0, 0xA8, 0x01, 0x02, 0xC4, 0xA8, 0x01, 0x01, 0x00, 0x3F, 0x00, 0x3F, 0x00, 0x12, 0x63, 0xDF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, - 0x06, 0x07, 0x08, 0x09, 0x80, 0x98, 0xB8, 0x18, + 0x06, 0x07, 0x08, 0x09 };
/** @@ -126,8 +128,7 @@ static const uint8_t test_packet_ipv6_icmp[] = { 0x09, 0xFF, 0xFE, 0x00, 0x04, 0x00, 0x35, 0x55, 0x55, 0x55, 0x66, 0x66, 0x66, 0x66, 0x77, 0x77, 0x77, 0x77, 0x88, 0x88, 0x88, 0x88, 0x80, 0x00, - 0x1B, 0xC2, 0x00, 0x01, 0x00, 0x02, 0xE0, 0x68, - 0x0E, 0xBA, + 0x1B, 0xC2, 0x00, 0x01, 0x00, 0x02 };
/** @@ -143,7 +144,7 @@ static const uint8_t test_packet_ipv6_tcp[] = { 0x77, 0x77, 0x88, 0x88, 0x88, 0x88, 0x04, 0xD2, 0x10, 0xE1, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x50, 0x00, 0x00, 0x00, 0x36, 0x37, - 0x00, 0x00, 0x28, 0x67, 0xD2, 0xAF, + 0x00, 0x00 };
/** @@ -157,8 +158,7 @@ static const uint8_t test_packet_ipv6_udp[] = { 0x09, 0xFF, 0xFE, 0x00, 0x04, 0x00, 0x35, 0x55, 0x55, 0x55, 0x66, 0x66, 0x66, 0x66, 0x77, 0x77, 0x77, 0x77, 0x88, 0x88, 0x88, 0x88, 0x00, 0x3F, - 0x00, 0x3F, 0x00, 0x08, 0x9B, 0x68, 0x35, 0xD3, - 0x64, 0x49, + 0x00, 0x3F, 0x00, 0x08, 0x9B, 0x68 };
/** @@ -174,7 +174,7 @@ static const uint8_t test_packet_vlan_ipv6_udp[] = { 0x04, 0x00, 0x35, 0x55, 0x55, 0x55, 0x66, 0x66, 0x66, 0x66, 0x77, 0x77, 0x77, 0x77, 0x88, 0x88, 0x88, 0x88, 0x00, 0x3F, 0x00, 0x3F, 0x00, 0x08, - 0x9B, 0x68, 0xC5, 0xD8, 0x2F, 0x5C, + 0x9B, 0x68 };
#endif
commit f97abebd29b5c4c90d24bda7bcfec48f7abcf28a Author: Matias Elo matias.elo@nokia.com Date: Tue Apr 4 09:28:21 2017 +0300
validation: pktio: add tests for packet parsing
Test packet parsing using predefined test packets (byte arrays). Test packets are looped through tested pktio interfaces to force packet parsing.
Signed-off-by: Matias Elo matias.elo@nokia.com 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/pktio/Makefile.am b/test/common_plat/validation/api/pktio/Makefile.am index 466d690d..c6368fba 100644 --- a/test/common_plat/validation/api/pktio/Makefile.am +++ b/test/common_plat/validation/api/pktio/Makefile.am @@ -4,7 +4,7 @@ noinst_LTLIBRARIES = libtestpktio.la libtestpktio_la_SOURCES = pktio.c
test_PROGRAMS = pktio_main$(EXEEXT) -dist_pktio_main_SOURCES = pktio_main.c +dist_pktio_main_SOURCES = pktio_main.c parser.c pktio_main_LDADD = libtestpktio.la $(LIBCUNIT_COMMON) $(LIBODP)
-EXTRA_DIST = pktio.h +EXTRA_DIST = pktio.h parser.h diff --git a/test/common_plat/validation/api/pktio/parser.c b/test/common_plat/validation/api/pktio/parser.c new file mode 100644 index 00000000..ad7101d0 --- /dev/null +++ b/test/common_plat/validation/api/pktio/parser.c @@ -0,0 +1,545 @@ +/* Copyright (c) 2017, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#include <odp_api.h> +#include <odp_cunit_common.h> + +#include <odp/helper/odph_api.h> + +#include <stdlib.h> +#include "parser.h" +#include "pktio.h" + +#define MAX_NUM_IFACES 2 +#define PKT_POOL_NUM 256 +#define PKT_POOL_BUF_LEN (2 * 1024) + +/** + * local container for pktio attributes + */ +typedef struct { + const char *name; + odp_pktio_t hdl; + odp_pktout_queue_t pktout; + odp_pktin_queue_t pktin; +} pktio_info_t; + +/** Interface names used for testing */ +static const char *iface_name[MAX_NUM_IFACES]; + +/** Test interfaces */ +pktio_info_t pktios[MAX_NUM_IFACES]; +pktio_info_t *pktio_a; +pktio_info_t *pktio_b; + +/** Number of interfaces being used (1=loopback, 2=pair) */ +static int num_ifaces; + +/** While testing real-world interfaces additional time may be needed for + * external network to enable link to pktio interface that just become up. + */ +static bool wait_for_network; + +/** Parser packet pool */ +odp_pool_t parser_pool = ODP_POOL_INVALID; + +static inline void wait_linkup(odp_pktio_t pktio) +{ + /* wait 1 second for link up */ + uint64_t wait_ns = (10 * ODP_TIME_MSEC_IN_NS); + int wait_num = 100; + int i; + int ret = -1; + + for (i = 0; i < wait_num; i++) { + ret = odp_pktio_link_status(pktio); + if (ret < 0 || ret == 1) + break; + /* link is down, call status again after delay */ + odp_time_wait_ns(wait_ns); + } +} + +static int pkt_pool_create(void) +{ + odp_pool_capability_t capa; + odp_pool_param_t params; + + if (odp_pool_capability(&capa) != 0) { + printf("Error: unable to query pool capability.\n"); + return -1; + } + + if (capa.pkt.max_num && capa.pkt.max_num < PKT_POOL_NUM) { + printf("Error: packet pool size not supported.\n"); + printf("MAX: %" PRIu32 "\n", capa.pkt.max_num); + return -1; + } else if (capa.pkt.max_len && capa.pkt.max_len < PKT_POOL_BUF_LEN) { + printf("Error: packet length not supported.\n"); + return -1; + } else if (capa.pkt.max_seg_len && + capa.pkt.max_seg_len < PKT_POOL_BUF_LEN) { + printf("Error: segment length not supported.\n"); + return -1; + } + + odp_pool_param_init(¶ms); + params.pkt.seg_len = PKT_POOL_BUF_LEN; + params.pkt.len = PKT_POOL_BUF_LEN; + params.pkt.num = PKT_POOL_NUM; + params.type = ODP_POOL_PACKET; + + parser_pool = odp_pool_create("pkt_pool_default", ¶ms); + if (parser_pool == ODP_POOL_INVALID) { + printf("Error: packet pool create failed.\n"); + return -1; + } + + return 0; +} + +static odp_pktio_t create_pktio(int iface_idx, odp_pool_t pool) +{ + odp_pktio_t pktio; + odp_pktio_config_t config; + odp_pktio_param_t pktio_param; + const char *iface = iface_name[iface_idx]; + + odp_pktio_param_init(&pktio_param); + pktio_param.in_mode = ODP_PKTIN_MODE_DIRECT; + pktio_param.out_mode = ODP_PKTOUT_MODE_DIRECT; + + pktio = odp_pktio_open(iface, pool, &pktio_param); + if (pktio == ODP_PKTIO_INVALID) { + printf("Error: failed to open %s\n", iface); + return ODP_PKTIO_INVALID; + } + + odp_pktio_config_init(&config); + config.parser.layer = ODP_PKTIO_PARSER_LAYER_ALL; + if (odp_pktio_config(pktio, &config)) { + printf("Error: failed to configure %s\n", iface); + return ODP_PKTIO_INVALID; + } + + /* By default, single input and output queue is used */ + if (odp_pktin_queue_config(pktio, NULL)) { + printf("Error: failed to config input queue for %s\n", iface); + return ODP_PKTIO_INVALID; + } + if (odp_pktout_queue_config(pktio, NULL)) { + printf("Error: failed to config output queue for %s\n", iface); + return ODP_PKTIO_INVALID; + } + + if (wait_for_network) + odp_time_wait_ns(ODP_TIME_SEC_IN_NS / 4); + + return pktio; +} + +static odp_packet_t create_packet(const uint8_t *data, uint32_t len) +{ + odp_packet_t pkt; + + pkt = odp_packet_alloc(parser_pool, len); + if (pkt == ODP_PACKET_INVALID) + return ODP_PACKET_INVALID; + + if (odp_packet_copy_from_mem(pkt, 0, len, data)) { + printf("Error: failed to copy test packet data\n"); + odp_packet_free(pkt); + return ODP_PACKET_INVALID; + } + + odp_packet_l2_offset_set(pkt, 0); + + return pkt; +} + +/** + * Receive incoming packets and compare them to the original. Function returns + * a valid packet handle only when the received packet matches to the original + * packet. + */ +static odp_packet_t recv_and_cmp_packet(odp_pktin_queue_t pktin, + odp_packet_t orig_pkt, uint64_t ns) +{ + odp_packet_t pkt = ODP_PACKET_INVALID; + odp_time_t wait_time, end; + uint32_t orig_len; + uint8_t *orig_data; + + orig_len = odp_packet_len(orig_pkt); + orig_data = odp_packet_data(orig_pkt); + wait_time = odp_time_local_from_ns(ns); + end = odp_time_sum(odp_time_local(), wait_time); + + do { + int ret; + odp_packet_t tmp_pkt; + + ret = odp_pktin_recv(pktin, &tmp_pkt, 1); + if (ret < 0) + break; + + if (ret == 1) { + uint32_t len; + uint8_t *data; + + len = odp_packet_len(tmp_pkt); + data = odp_packet_data(tmp_pkt); + + if (len == orig_len && + memcmp(data, orig_data, len) == 0) { + pkt = tmp_pkt; + break; + } + odp_packet_free(tmp_pkt); + } + } while (odp_time_cmp(end, odp_time_local()) > 0); + + return pkt; +} + +/** + * Creates a test packet from data array and loops it through the test pktio + * interfaces forcing packet parsing. + */ +static odp_packet_t loopback_packet(pktio_info_t *pktio_a, + pktio_info_t *pktio_b, const uint8_t *data, + uint32_t len) +{ + odp_packet_t pkt; + odp_packet_t sent_pkt; + + pkt = create_packet(data, len); + if (pkt == ODP_PACKET_INVALID) { + CU_FAIL("failed to generate test packet"); + return ODP_PACKET_INVALID; + } + + pktio_pkt_set_macs(pkt, pktio_a->hdl, pktio_b->hdl); + + sent_pkt = odp_packet_copy(pkt, parser_pool); + if (sent_pkt == ODP_PACKET_INVALID) { + CU_FAIL_FATAL("failed to copy test packet"); + odp_packet_free(pkt); + return ODP_PACKET_INVALID; + } + + while (1) { + int ret = odp_pktout_send(pktio_a->pktout, &pkt, 1); + + if (ret < 0) { + CU_FAIL_FATAL("failed to send test packet"); + odp_packet_free(pkt); + odp_packet_free(sent_pkt); + return ODP_PACKET_INVALID; + } + if (ret == 1) + break; + } + + /* and wait for them to arrive back */ + pkt = recv_and_cmp_packet(pktio_b->pktin, sent_pkt, ODP_TIME_SEC_IN_NS); + odp_packet_free(sent_pkt); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); + CU_ASSERT(odp_packet_input(pkt) == pktio_b->hdl); + CU_ASSERT(odp_packet_has_error(pkt) == 0); + + return pkt; +} + +void parser_test_arp(void) +{ + odp_packet_t pkt; + + pkt = loopback_packet(pktio_a, pktio_b, test_packet_arp, + sizeof(test_packet_arp)); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); + CU_ASSERT(odp_packet_has_eth(pkt)); + CU_ASSERT(odp_packet_has_arp(pkt)); + + CU_ASSERT(!odp_packet_has_ipv4(pkt)); + CU_ASSERT(!odp_packet_has_ipv6(pkt)); + + odp_packet_free(pkt); +} + +void parser_test_ipv4_icmp(void) +{ + odp_packet_t pkt; + + pkt = loopback_packet(pktio_a, pktio_b, test_packet_ipv4_icmp, + sizeof(test_packet_ipv4_icmp)); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); + CU_ASSERT(odp_packet_has_eth(pkt)); + CU_ASSERT(odp_packet_has_ipv4(pkt)); + CU_ASSERT(odp_packet_has_icmp(pkt)); + + CU_ASSERT(!odp_packet_has_ipv6(pkt)); + CU_ASSERT(!odp_packet_has_tcp(pkt)); + CU_ASSERT(!odp_packet_has_udp(pkt)); + + odp_packet_free(pkt); +} + +void parser_test_ipv4_tcp(void) +{ + odp_packet_t pkt; + + pkt = loopback_packet(pktio_a, pktio_b, test_packet_ipv4_tcp, + sizeof(test_packet_ipv4_tcp)); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); + CU_ASSERT(odp_packet_has_eth(pkt)); + CU_ASSERT(odp_packet_has_ipv4(pkt)); + CU_ASSERT(odp_packet_has_tcp(pkt)); + + CU_ASSERT(!odp_packet_has_ipv6(pkt)); + CU_ASSERT(!odp_packet_has_udp(pkt)); + + odp_packet_free(pkt); +} + +void parser_test_ipv4_udp(void) +{ + odp_packet_t pkt; + + pkt = loopback_packet(pktio_a, pktio_b, test_packet_ipv4_udp, + sizeof(test_packet_ipv4_udp)); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); + CU_ASSERT(odp_packet_has_eth(pkt)); + CU_ASSERT(odp_packet_has_ipv4(pkt)); + CU_ASSERT(odp_packet_has_udp(pkt)); + + CU_ASSERT(!odp_packet_has_ipv6(pkt)); + CU_ASSERT(!odp_packet_has_tcp(pkt)); + + odp_packet_free(pkt); +} + +void parser_test_vlan_ipv4_udp(void) +{ + odp_packet_t pkt; + + pkt = loopback_packet(pktio_a, pktio_b, test_packet_vlan_ipv4_udp, + sizeof(test_packet_vlan_ipv4_udp)); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); + CU_ASSERT(odp_packet_has_eth(pkt)); + CU_ASSERT(odp_packet_has_vlan(pkt)); + CU_ASSERT(odp_packet_has_ipv4(pkt)); + CU_ASSERT(odp_packet_has_udp(pkt)); + + CU_ASSERT(!odp_packet_has_ipv6(pkt)); + CU_ASSERT(!odp_packet_has_tcp(pkt)); + + odp_packet_free(pkt); +} + +void parser_test_vlan_qinq_ipv4_udp(void) +{ + odp_packet_t pkt; + + pkt = loopback_packet(pktio_a, pktio_b, test_packet_vlan_qinq_ipv4_udp, + sizeof(test_packet_vlan_qinq_ipv4_udp)); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); + CU_ASSERT(odp_packet_has_eth(pkt)); + CU_ASSERT(odp_packet_has_vlan(pkt)); + CU_ASSERT(odp_packet_has_vlan_qinq(pkt)); + CU_ASSERT(odp_packet_has_ipv4(pkt)); + CU_ASSERT(odp_packet_has_udp(pkt)); + + CU_ASSERT(!odp_packet_has_ipv6(pkt)); + CU_ASSERT(!odp_packet_has_tcp(pkt)); + + odp_packet_free(pkt); +} + +void parser_test_ipv6_icmp(void) +{ + odp_packet_t pkt; + + pkt = loopback_packet(pktio_a, pktio_b, test_packet_ipv6_icmp, + sizeof(test_packet_ipv6_icmp)); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); + CU_ASSERT(odp_packet_has_eth(pkt)); + CU_ASSERT(odp_packet_has_ipv6(pkt)); + CU_ASSERT(odp_packet_has_icmp(pkt)); + + CU_ASSERT(!odp_packet_has_ipv4(pkt)); + CU_ASSERT(!odp_packet_has_tcp(pkt)); + CU_ASSERT(!odp_packet_has_udp(pkt)); + + odp_packet_free(pkt); +} + +void parser_test_ipv6_tcp(void) +{ + odp_packet_t pkt; + + pkt = loopback_packet(pktio_a, pktio_b, test_packet_ipv6_tcp, + sizeof(test_packet_ipv6_tcp)); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); + CU_ASSERT(odp_packet_has_eth(pkt)); + CU_ASSERT(odp_packet_has_ipv6(pkt)); + CU_ASSERT(odp_packet_has_tcp(pkt)); + + CU_ASSERT(!odp_packet_has_ipv4(pkt)); + CU_ASSERT(!odp_packet_has_udp(pkt)); + + odp_packet_free(pkt); +} + +void parser_test_ipv6_udp(void) +{ + odp_packet_t pkt; + + pkt = loopback_packet(pktio_a, pktio_b, test_packet_ipv6_udp, + sizeof(test_packet_ipv6_udp)); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); + CU_ASSERT(odp_packet_has_eth(pkt)); + CU_ASSERT(odp_packet_has_ipv6(pkt)); + CU_ASSERT(odp_packet_has_udp(pkt)); + + CU_ASSERT(!odp_packet_has_ipv4(pkt)); + CU_ASSERT(!odp_packet_has_tcp(pkt)); + + odp_packet_free(pkt); +} + +void parser_test_vlan_ipv6_udp(void) +{ + odp_packet_t pkt; + + pkt = loopback_packet(pktio_a, pktio_b, test_packet_vlan_ipv6_udp, + sizeof(test_packet_vlan_ipv6_udp)); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); + CU_ASSERT(odp_packet_has_eth(pkt)); + CU_ASSERT(odp_packet_has_vlan(pkt)); + CU_ASSERT(odp_packet_has_ipv6(pkt)); + CU_ASSERT(odp_packet_has_udp(pkt)); + + CU_ASSERT(!odp_packet_has_ipv4(pkt)); + CU_ASSERT(!odp_packet_has_tcp(pkt)); + + odp_packet_free(pkt); +} + +int parser_suite_init(void) +{ + int i; + + if (getenv("ODP_WAIT_FOR_NETWORK")) + wait_for_network = true; + + iface_name[0] = getenv("ODP_PKTIO_IF0"); + iface_name[1] = getenv("ODP_PKTIO_IF1"); + num_ifaces = 1; + + if (!iface_name[0]) { + printf("No interfaces specified, using default "loop".\n"); + iface_name[0] = "loop"; + } else if (!iface_name[1]) { + printf("Using loopback interface: %s\n", iface_name[0]); + } else { + num_ifaces = 2; + printf("Using paired interfaces: %s %s\n", + iface_name[0], iface_name[1]); + } + + if (pkt_pool_create() != 0) { + printf("Error: failed to create parser pool\n"); + return -1; + } + + /* Create pktios and associate input/output queues */ + for (i = 0; i < num_ifaces; ++i) { + pktio_info_t *io; + + io = &pktios[i]; + io->name = iface_name[i]; + io->hdl = create_pktio(i, parser_pool); + if (io->hdl == ODP_PKTIO_INVALID) { + printf("Error: failed to open iface"); + return -1; + } + + if (odp_pktout_queue(io->hdl, &io->pktout, 1) != 1) { + printf("Error: failed to start iface: %s\n", io->name); + return -1; + } + + if (odp_pktin_queue(io->hdl, &io->pktin, 1) != 1) { + printf("Error: failed to start iface: %s\n", io->name); + return -1; + } + + if (odp_pktio_start(io->hdl)) { + printf("Error: failed to start iface: %s\n", io->name); + return -1; + } + + wait_linkup(io->hdl); + } + + pktio_a = &pktios[0]; + pktio_b = &pktios[1]; + if (num_ifaces == 1) + pktio_b = pktio_a; + + return 0; +} + +int parser_suite_term(void) +{ + int i; + int ret = 0; + + for (i = 0; i < num_ifaces; ++i) { + if (odp_pktio_stop(pktios[i].hdl)) { + printf("Error: failed to stop pktio: %s\n", + pktios[i].name); + ret = -1; + } + if (odp_pktio_close(pktios[i].hdl)) { + printf("Error: failed to close pktio: %s\n", + pktios[i].name); + ret = -1; + } + } + + if (odp_pool_destroy(parser_pool) != 0) { + printf("Error: failed to destroy packet pool\n"); + ret = -1; + } + + return ret; +} + +/** + * Certain tests can only be run with 'loop' pktio. + */ +static int loop_pktio(void) +{ + if (strcmp(iface_name[0], "loop") == 0) + return ODP_TEST_ACTIVE; + else + return ODP_TEST_INACTIVE; +} + +odp_testinfo_t parser_suite[] = { + ODP_TEST_INFO(parser_test_arp), + ODP_TEST_INFO(parser_test_ipv4_icmp), + ODP_TEST_INFO(parser_test_ipv4_tcp), + ODP_TEST_INFO(parser_test_ipv4_udp), + ODP_TEST_INFO_CONDITIONAL(parser_test_vlan_ipv4_udp, loop_pktio), + ODP_TEST_INFO_CONDITIONAL(parser_test_vlan_qinq_ipv4_udp, loop_pktio), + ODP_TEST_INFO(parser_test_ipv6_icmp), + ODP_TEST_INFO(parser_test_ipv6_tcp), + ODP_TEST_INFO(parser_test_ipv6_udp), + ODP_TEST_INFO_CONDITIONAL(parser_test_vlan_ipv6_udp, loop_pktio), + ODP_TEST_INFO_NULL +}; diff --git a/test/common_plat/validation/api/pktio/parser.h b/test/common_plat/validation/api/pktio/parser.h new file mode 100644 index 00000000..57c62388 --- /dev/null +++ b/test/common_plat/validation/api/pktio/parser.h @@ -0,0 +1,180 @@ +/* Copyright (c) 2017, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _ODP_TEST_PARSER_H_ +#define _ODP_TEST_PARSER_H_ + +#include <odp_cunit_common.h> + +/* test functions: */ +void parser_test_arp(void); +void parser_test_ipv4_icmp(void); +void parser_test_ipv4_tcp(void); +void parser_test_ipv4_udp(void); +void parser_test_vlan_ipv4_udp(void); +void parser_test_vlan_qinq_ipv4_udp(void); +void parser_test_ipv6_icmp(void); +void parser_test_ipv6_tcp(void); +void parser_test_ipv6_udp(void); +void parser_test_vlan_ipv6_udp(void); + +/* test array init/term functions: */ +int parser_suite_term(void); +int parser_suite_init(void); + +/* test arrays: */ +extern odp_testinfo_t parser_suite[]; + +/** + * ARP request + */ +static const uint8_t test_packet_arp[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, + 0x09, 0x00, 0x04, 0x00, 0x08, 0x06, 0x00, 0x01, + 0x08, 0x00, 0x06, 0x04, 0x00, 0x01, 0x00, 0x00, + 0x09, 0x00, 0x04, 0x00, 0xC0, 0xA8, 0x01, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xA8, + 0x01, 0x02, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, + 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, + 0x0E, 0x0F, 0x10, 0x11, 0xA1, 0xA8, 0x27, 0x43, +}; + +/** + * ICMPv4 echo reply + */ +static const uint8_t test_packet_ipv4_icmp[] = { + 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x04, 0x00, 0x08, 0x00, 0x45, 0x00, + 0x00, 0x2E, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, + 0xF3, 0x7B, 0xC0, 0xA8, 0x01, 0x01, 0xC4, 0xA8, + 0x01, 0x02, 0x00, 0x00, 0xB7, 0xAB, 0x00, 0x01, + 0x00, 0x02, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, + 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, + 0x0E, 0x0F, 0x10, 0x11, 0xD9, 0x7F, 0xE8, 0x02, +}; + +/** + * IPv4 TCP + */ +static const uint8_t test_packet_ipv4_tcp[] = { + 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x04, 0x00, 0x08, 0x00, 0x45, 0x00, + 0x00, 0x2E, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, + 0xF3, 0x76, 0xC0, 0xA8, 0x01, 0x02, 0xC4, 0xA8, + 0x01, 0x01, 0x04, 0xD2, 0x10, 0xE1, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x50, 0x00, + 0x00, 0x00, 0x0C, 0xCC, 0x00, 0x00, 0x00, 0x01, + 0x02, 0x03, 0x04, 0x05, 0x2E, 0xDE, 0x5E, 0x48, +}; + +/** + * IPv4 UDP + */ +static const uint8_t test_packet_ipv4_udp[] = { + 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x04, 0x00, 0x08, 0x00, 0x45, 0x00, + 0x00, 0x2E, 0x00, 0x00, 0x00, 0x00, 0x40, 0x11, + 0xF3, 0x6B, 0xC0, 0xA8, 0x01, 0x02, 0xC4, 0xA8, + 0x01, 0x01, 0x00, 0x3F, 0x00, 0x3F, 0x00, 0x1A, + 0x2F, 0x97, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, + 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, + 0x0E, 0x0F, 0x10, 0x11, 0x64, 0xF4, 0xE4, 0xB6, +}; + +/** + * VLAN IPv4 UDP + * - ID: 23 + */ +static const uint8_t test_packet_vlan_ipv4_udp[] = { + 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x04, 0x00, 0x81, 0x00, 0x00, 0x17, + 0x08, 0x00, 0x45, 0x00, 0x00, 0x2A, 0x00, 0x00, + 0x00, 0x00, 0x40, 0x11, 0xF3, 0x6F, 0xC0, 0xA8, + 0x01, 0x02, 0xC4, 0xA8, 0x01, 0x01, 0x00, 0x3F, + 0x00, 0x3F, 0x00, 0x16, 0x4D, 0xBF, 0x00, 0x01, + 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, + 0x0A, 0x0B, 0x0C, 0x0D, 0xCB, 0xBF, 0xD0, 0x29, +}; + +/** + * VLAN Q-in-Q IPv4 UDP + * - Outer: Tag Protocol ID 0x88a8, VLAN ID 1 + * - Inner: Tag Protocol ID 0x8100, VLAN ID 2 + */ +static const uint8_t test_packet_vlan_qinq_ipv4_udp[] = { + 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x04, 0x00, 0x88, 0xA8, 0x00, 0x01, + 0x81, 0x00, 0x00, 0x02, 0x08, 0x00, 0x45, 0x00, + 0x00, 0x26, 0x00, 0x00, 0x00, 0x00, 0x40, 0x11, + 0xF3, 0x73, 0xC0, 0xA8, 0x01, 0x02, 0xC4, 0xA8, + 0x01, 0x01, 0x00, 0x3F, 0x00, 0x3F, 0x00, 0x12, + 0x63, 0xDF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, + 0x06, 0x07, 0x08, 0x09, 0x80, 0x98, 0xB8, 0x18, +}; + +/** + * ICMPv6 echo request + */ +static const uint8_t test_packet_ipv6_icmp[] = { + 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x04, 0x00, 0x86, 0xDD, 0x60, 0x30, + 0x00, 0x00, 0x00, 0x08, 0x3A, 0xFF, 0xFE, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x09, 0xFF, 0xFE, 0x00, 0x04, 0x00, 0x35, 0x55, + 0x55, 0x55, 0x66, 0x66, 0x66, 0x66, 0x77, 0x77, + 0x77, 0x77, 0x88, 0x88, 0x88, 0x88, 0x80, 0x00, + 0x1B, 0xC2, 0x00, 0x01, 0x00, 0x02, 0xE0, 0x68, + 0x0E, 0xBA, +}; + +/** + * IPv6 TCP + */ +static const uint8_t test_packet_ipv6_tcp[] = { + 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x04, 0x00, 0x86, 0xDD, 0x60, 0x30, + 0x00, 0x00, 0x00, 0x14, 0x06, 0xFF, 0xFE, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x09, 0xFF, 0xFE, 0x00, 0x04, 0x00, 0x35, 0x55, + 0x55, 0x55, 0x66, 0x66, 0x66, 0x66, 0x77, 0x77, + 0x77, 0x77, 0x88, 0x88, 0x88, 0x88, 0x04, 0xD2, + 0x10, 0xE1, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x02, 0x50, 0x00, 0x00, 0x00, 0x36, 0x37, + 0x00, 0x00, 0x28, 0x67, 0xD2, 0xAF, +}; + +/** + * IPv6 UDP + */ +static const uint8_t test_packet_ipv6_udp[] = { + 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x04, 0x00, 0x86, 0xDD, 0x60, 0x30, + 0x00, 0x00, 0x00, 0x08, 0x11, 0xFF, 0xFE, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x09, 0xFF, 0xFE, 0x00, 0x04, 0x00, 0x35, 0x55, + 0x55, 0x55, 0x66, 0x66, 0x66, 0x66, 0x77, 0x77, + 0x77, 0x77, 0x88, 0x88, 0x88, 0x88, 0x00, 0x3F, + 0x00, 0x3F, 0x00, 0x08, 0x9B, 0x68, 0x35, 0xD3, + 0x64, 0x49, +}; + +/** + * VLAN IPv6 + * - ID: 23 + */ +static const uint8_t test_packet_vlan_ipv6_udp[] = { + 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x04, 0x00, 0x81, 0x00, 0x00, 0x17, + 0x86, 0xDD, 0x60, 0x30, 0x00, 0x00, 0x00, 0x08, + 0x11, 0xFF, 0xFE, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x00, 0x09, 0xFF, 0xFE, 0x00, + 0x04, 0x00, 0x35, 0x55, 0x55, 0x55, 0x66, 0x66, + 0x66, 0x66, 0x77, 0x77, 0x77, 0x77, 0x88, 0x88, + 0x88, 0x88, 0x00, 0x3F, 0x00, 0x3F, 0x00, 0x08, + 0x9B, 0x68, 0xC5, 0xD8, 0x2F, 0x5C, +}; + +#endif diff --git a/test/common_plat/validation/api/pktio/pktio.c b/test/common_plat/validation/api/pktio/pktio.c index a21959ef..43fe515a 100644 --- a/test/common_plat/validation/api/pktio/pktio.c +++ b/test/common_plat/validation/api/pktio/pktio.c @@ -10,6 +10,7 @@
#include <stdlib.h> #include "pktio.h" +#include "parser.h"
#define PKT_BUF_NUM 32 #define PKT_BUF_SIZE (9 * 1024) @@ -143,8 +144,7 @@ static void set_pool_len(odp_pool_param_t *params, odp_pool_capability_t *capa) } }
-static void pktio_pkt_set_macs(odp_packet_t pkt, - odp_pktio_t src, odp_pktio_t dst) +void pktio_pkt_set_macs(odp_packet_t pkt, odp_pktio_t src, odp_pktio_t dst) { uint32_t len; odph_ethhdr_t *eth = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, &len); @@ -2190,6 +2190,7 @@ odp_suiteinfo_t pktio_suites[] = { pktio_suite_term, pktio_suite_unsegmented}, {"Packet I/O Segmented", pktio_suite_init_segmented, pktio_suite_term, pktio_suite_segmented}, + {"Packet parser", parser_suite_init, parser_suite_term, parser_suite}, ODP_SUITE_INFO_NULL };
diff --git a/test/common_plat/validation/api/pktio/pktio.h b/test/common_plat/validation/api/pktio/pktio.h index 8131d05f..b8799d9e 100644 --- a/test/common_plat/validation/api/pktio/pktio.h +++ b/test/common_plat/validation/api/pktio/pktio.h @@ -61,4 +61,7 @@ extern odp_suiteinfo_t pktio_suites[]; /* main test program: */ int pktio_main(int argc, char *argv[]);
+/* functions shared by parser test suite */ +void pktio_pkt_set_macs(odp_packet_t pkt, odp_pktio_t src, odp_pktio_t dst); + #endif
commit 0c1675e93796897a5d358635697068dc81c1e763 Author: Maxim Uvarov maxim.uvarov@linaro.org Date: Tue Apr 11 16:31:14 2017 +0300
Revert "validation: pktio: add tests for packet parsing"
This reverts commit 5a770508ecf (validation: pktio: add tests for packet parsing) This commit breaks tap pktio test on Travis CI and some over envs. That needs to be fixed before restoring it back. Suite: Packet parser Test: parser_test_arp ...passed Test: parser_test_ipv4_icmp ...received pkt 0x7fec7ea00000, len == 60, orig_len = 64 FAILED 1. parser.c:251 - pkt != ODP_PACKET_INVALID Test: parser_test_ipv4_tcp ...received pkt 0x7fec7ea425c0, len == 60, orig_len = 64 FAILED 1. parser.c:251 - pkt != ODP_PACKET_INVALID Test: parser_test_ipv4_udp ...received pkt 0x7fec7ea00000, len == 60, orig_len = 64 FAILED 1. parser.c:251 - pkt != ODP_PACKET_INVALID Test: parser_test_ipv6_icmp ...received pkt 0x7fec7ea425c0, len == 62, orig_len = 66 FAILED 1. parser.c:251 - pkt != ODP_PACKET_INVALID Test: parser_test_ipv6_tcp ...received pkt 0x7fec7ea00000, len == 74, orig_len = 78 FAILED 1. parser.c:251 - pkt != ODP_PACKET_INVALID Test: parser_test_ipv6_udp ...received pkt 0x7fec7ea425c0, len == 62, orig_len = 66 FAILED 1. parser.c:251 - pkt != ODP_PACKET_INVALID
Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/test/common_plat/validation/api/pktio/Makefile.am b/test/common_plat/validation/api/pktio/Makefile.am index c6368fba..466d690d 100644 --- a/test/common_plat/validation/api/pktio/Makefile.am +++ b/test/common_plat/validation/api/pktio/Makefile.am @@ -4,7 +4,7 @@ noinst_LTLIBRARIES = libtestpktio.la libtestpktio_la_SOURCES = pktio.c
test_PROGRAMS = pktio_main$(EXEEXT) -dist_pktio_main_SOURCES = pktio_main.c parser.c +dist_pktio_main_SOURCES = pktio_main.c pktio_main_LDADD = libtestpktio.la $(LIBCUNIT_COMMON) $(LIBODP)
-EXTRA_DIST = pktio.h parser.h +EXTRA_DIST = pktio.h diff --git a/test/common_plat/validation/api/pktio/parser.c b/test/common_plat/validation/api/pktio/parser.c deleted file mode 100644 index ad7101d0..00000000 --- a/test/common_plat/validation/api/pktio/parser.c +++ /dev/null @@ -1,545 +0,0 @@ -/* Copyright (c) 2017, Linaro Limited - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ -#include <odp_api.h> -#include <odp_cunit_common.h> - -#include <odp/helper/odph_api.h> - -#include <stdlib.h> -#include "parser.h" -#include "pktio.h" - -#define MAX_NUM_IFACES 2 -#define PKT_POOL_NUM 256 -#define PKT_POOL_BUF_LEN (2 * 1024) - -/** - * local container for pktio attributes - */ -typedef struct { - const char *name; - odp_pktio_t hdl; - odp_pktout_queue_t pktout; - odp_pktin_queue_t pktin; -} pktio_info_t; - -/** Interface names used for testing */ -static const char *iface_name[MAX_NUM_IFACES]; - -/** Test interfaces */ -pktio_info_t pktios[MAX_NUM_IFACES]; -pktio_info_t *pktio_a; -pktio_info_t *pktio_b; - -/** Number of interfaces being used (1=loopback, 2=pair) */ -static int num_ifaces; - -/** While testing real-world interfaces additional time may be needed for - * external network to enable link to pktio interface that just become up. - */ -static bool wait_for_network; - -/** Parser packet pool */ -odp_pool_t parser_pool = ODP_POOL_INVALID; - -static inline void wait_linkup(odp_pktio_t pktio) -{ - /* wait 1 second for link up */ - uint64_t wait_ns = (10 * ODP_TIME_MSEC_IN_NS); - int wait_num = 100; - int i; - int ret = -1; - - for (i = 0; i < wait_num; i++) { - ret = odp_pktio_link_status(pktio); - if (ret < 0 || ret == 1) - break; - /* link is down, call status again after delay */ - odp_time_wait_ns(wait_ns); - } -} - -static int pkt_pool_create(void) -{ - odp_pool_capability_t capa; - odp_pool_param_t params; - - if (odp_pool_capability(&capa) != 0) { - printf("Error: unable to query pool capability.\n"); - return -1; - } - - if (capa.pkt.max_num && capa.pkt.max_num < PKT_POOL_NUM) { - printf("Error: packet pool size not supported.\n"); - printf("MAX: %" PRIu32 "\n", capa.pkt.max_num); - return -1; - } else if (capa.pkt.max_len && capa.pkt.max_len < PKT_POOL_BUF_LEN) { - printf("Error: packet length not supported.\n"); - return -1; - } else if (capa.pkt.max_seg_len && - capa.pkt.max_seg_len < PKT_POOL_BUF_LEN) { - printf("Error: segment length not supported.\n"); - return -1; - } - - odp_pool_param_init(¶ms); - params.pkt.seg_len = PKT_POOL_BUF_LEN; - params.pkt.len = PKT_POOL_BUF_LEN; - params.pkt.num = PKT_POOL_NUM; - params.type = ODP_POOL_PACKET; - - parser_pool = odp_pool_create("pkt_pool_default", ¶ms); - if (parser_pool == ODP_POOL_INVALID) { - printf("Error: packet pool create failed.\n"); - return -1; - } - - return 0; -} - -static odp_pktio_t create_pktio(int iface_idx, odp_pool_t pool) -{ - odp_pktio_t pktio; - odp_pktio_config_t config; - odp_pktio_param_t pktio_param; - const char *iface = iface_name[iface_idx]; - - odp_pktio_param_init(&pktio_param); - pktio_param.in_mode = ODP_PKTIN_MODE_DIRECT; - pktio_param.out_mode = ODP_PKTOUT_MODE_DIRECT; - - pktio = odp_pktio_open(iface, pool, &pktio_param); - if (pktio == ODP_PKTIO_INVALID) { - printf("Error: failed to open %s\n", iface); - return ODP_PKTIO_INVALID; - } - - odp_pktio_config_init(&config); - config.parser.layer = ODP_PKTIO_PARSER_LAYER_ALL; - if (odp_pktio_config(pktio, &config)) { - printf("Error: failed to configure %s\n", iface); - return ODP_PKTIO_INVALID; - } - - /* By default, single input and output queue is used */ - if (odp_pktin_queue_config(pktio, NULL)) { - printf("Error: failed to config input queue for %s\n", iface); - return ODP_PKTIO_INVALID; - } - if (odp_pktout_queue_config(pktio, NULL)) { - printf("Error: failed to config output queue for %s\n", iface); - return ODP_PKTIO_INVALID; - } - - if (wait_for_network) - odp_time_wait_ns(ODP_TIME_SEC_IN_NS / 4); - - return pktio; -} - -static odp_packet_t create_packet(const uint8_t *data, uint32_t len) -{ - odp_packet_t pkt; - - pkt = odp_packet_alloc(parser_pool, len); - if (pkt == ODP_PACKET_INVALID) - return ODP_PACKET_INVALID; - - if (odp_packet_copy_from_mem(pkt, 0, len, data)) { - printf("Error: failed to copy test packet data\n"); - odp_packet_free(pkt); - return ODP_PACKET_INVALID; - } - - odp_packet_l2_offset_set(pkt, 0); - - return pkt; -} - -/** - * Receive incoming packets and compare them to the original. Function returns - * a valid packet handle only when the received packet matches to the original - * packet. - */ -static odp_packet_t recv_and_cmp_packet(odp_pktin_queue_t pktin, - odp_packet_t orig_pkt, uint64_t ns) -{ - odp_packet_t pkt = ODP_PACKET_INVALID; - odp_time_t wait_time, end; - uint32_t orig_len; - uint8_t *orig_data; - - orig_len = odp_packet_len(orig_pkt); - orig_data = odp_packet_data(orig_pkt); - wait_time = odp_time_local_from_ns(ns); - end = odp_time_sum(odp_time_local(), wait_time); - - do { - int ret; - odp_packet_t tmp_pkt; - - ret = odp_pktin_recv(pktin, &tmp_pkt, 1); - if (ret < 0) - break; - - if (ret == 1) { - uint32_t len; - uint8_t *data; - - len = odp_packet_len(tmp_pkt); - data = odp_packet_data(tmp_pkt); - - if (len == orig_len && - memcmp(data, orig_data, len) == 0) { - pkt = tmp_pkt; - break; - } - odp_packet_free(tmp_pkt); - } - } while (odp_time_cmp(end, odp_time_local()) > 0); - - return pkt; -} - -/** - * Creates a test packet from data array and loops it through the test pktio - * interfaces forcing packet parsing. - */ -static odp_packet_t loopback_packet(pktio_info_t *pktio_a, - pktio_info_t *pktio_b, const uint8_t *data, - uint32_t len) -{ - odp_packet_t pkt; - odp_packet_t sent_pkt; - - pkt = create_packet(data, len); - if (pkt == ODP_PACKET_INVALID) { - CU_FAIL("failed to generate test packet"); - return ODP_PACKET_INVALID; - } - - pktio_pkt_set_macs(pkt, pktio_a->hdl, pktio_b->hdl); - - sent_pkt = odp_packet_copy(pkt, parser_pool); - if (sent_pkt == ODP_PACKET_INVALID) { - CU_FAIL_FATAL("failed to copy test packet"); - odp_packet_free(pkt); - return ODP_PACKET_INVALID; - } - - while (1) { - int ret = odp_pktout_send(pktio_a->pktout, &pkt, 1); - - if (ret < 0) { - CU_FAIL_FATAL("failed to send test packet"); - odp_packet_free(pkt); - odp_packet_free(sent_pkt); - return ODP_PACKET_INVALID; - } - if (ret == 1) - break; - } - - /* and wait for them to arrive back */ - pkt = recv_and_cmp_packet(pktio_b->pktin, sent_pkt, ODP_TIME_SEC_IN_NS); - odp_packet_free(sent_pkt); - CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); - CU_ASSERT(odp_packet_input(pkt) == pktio_b->hdl); - CU_ASSERT(odp_packet_has_error(pkt) == 0); - - return pkt; -} - -void parser_test_arp(void) -{ - odp_packet_t pkt; - - pkt = loopback_packet(pktio_a, pktio_b, test_packet_arp, - sizeof(test_packet_arp)); - CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); - CU_ASSERT(odp_packet_has_eth(pkt)); - CU_ASSERT(odp_packet_has_arp(pkt)); - - CU_ASSERT(!odp_packet_has_ipv4(pkt)); - CU_ASSERT(!odp_packet_has_ipv6(pkt)); - - odp_packet_free(pkt); -} - -void parser_test_ipv4_icmp(void) -{ - odp_packet_t pkt; - - pkt = loopback_packet(pktio_a, pktio_b, test_packet_ipv4_icmp, - sizeof(test_packet_ipv4_icmp)); - CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); - CU_ASSERT(odp_packet_has_eth(pkt)); - CU_ASSERT(odp_packet_has_ipv4(pkt)); - CU_ASSERT(odp_packet_has_icmp(pkt)); - - CU_ASSERT(!odp_packet_has_ipv6(pkt)); - CU_ASSERT(!odp_packet_has_tcp(pkt)); - CU_ASSERT(!odp_packet_has_udp(pkt)); - - odp_packet_free(pkt); -} - -void parser_test_ipv4_tcp(void) -{ - odp_packet_t pkt; - - pkt = loopback_packet(pktio_a, pktio_b, test_packet_ipv4_tcp, - sizeof(test_packet_ipv4_tcp)); - CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); - CU_ASSERT(odp_packet_has_eth(pkt)); - CU_ASSERT(odp_packet_has_ipv4(pkt)); - CU_ASSERT(odp_packet_has_tcp(pkt)); - - CU_ASSERT(!odp_packet_has_ipv6(pkt)); - CU_ASSERT(!odp_packet_has_udp(pkt)); - - odp_packet_free(pkt); -} - -void parser_test_ipv4_udp(void) -{ - odp_packet_t pkt; - - pkt = loopback_packet(pktio_a, pktio_b, test_packet_ipv4_udp, - sizeof(test_packet_ipv4_udp)); - CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); - CU_ASSERT(odp_packet_has_eth(pkt)); - CU_ASSERT(odp_packet_has_ipv4(pkt)); - CU_ASSERT(odp_packet_has_udp(pkt)); - - CU_ASSERT(!odp_packet_has_ipv6(pkt)); - CU_ASSERT(!odp_packet_has_tcp(pkt)); - - odp_packet_free(pkt); -} - -void parser_test_vlan_ipv4_udp(void) -{ - odp_packet_t pkt; - - pkt = loopback_packet(pktio_a, pktio_b, test_packet_vlan_ipv4_udp, - sizeof(test_packet_vlan_ipv4_udp)); - CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); - CU_ASSERT(odp_packet_has_eth(pkt)); - CU_ASSERT(odp_packet_has_vlan(pkt)); - CU_ASSERT(odp_packet_has_ipv4(pkt)); - CU_ASSERT(odp_packet_has_udp(pkt)); - - CU_ASSERT(!odp_packet_has_ipv6(pkt)); - CU_ASSERT(!odp_packet_has_tcp(pkt)); - - odp_packet_free(pkt); -} - -void parser_test_vlan_qinq_ipv4_udp(void) -{ - odp_packet_t pkt; - - pkt = loopback_packet(pktio_a, pktio_b, test_packet_vlan_qinq_ipv4_udp, - sizeof(test_packet_vlan_qinq_ipv4_udp)); - CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); - CU_ASSERT(odp_packet_has_eth(pkt)); - CU_ASSERT(odp_packet_has_vlan(pkt)); - CU_ASSERT(odp_packet_has_vlan_qinq(pkt)); - CU_ASSERT(odp_packet_has_ipv4(pkt)); - CU_ASSERT(odp_packet_has_udp(pkt)); - - CU_ASSERT(!odp_packet_has_ipv6(pkt)); - CU_ASSERT(!odp_packet_has_tcp(pkt)); - - odp_packet_free(pkt); -} - -void parser_test_ipv6_icmp(void) -{ - odp_packet_t pkt; - - pkt = loopback_packet(pktio_a, pktio_b, test_packet_ipv6_icmp, - sizeof(test_packet_ipv6_icmp)); - CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); - CU_ASSERT(odp_packet_has_eth(pkt)); - CU_ASSERT(odp_packet_has_ipv6(pkt)); - CU_ASSERT(odp_packet_has_icmp(pkt)); - - CU_ASSERT(!odp_packet_has_ipv4(pkt)); - CU_ASSERT(!odp_packet_has_tcp(pkt)); - CU_ASSERT(!odp_packet_has_udp(pkt)); - - odp_packet_free(pkt); -} - -void parser_test_ipv6_tcp(void) -{ - odp_packet_t pkt; - - pkt = loopback_packet(pktio_a, pktio_b, test_packet_ipv6_tcp, - sizeof(test_packet_ipv6_tcp)); - CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); - CU_ASSERT(odp_packet_has_eth(pkt)); - CU_ASSERT(odp_packet_has_ipv6(pkt)); - CU_ASSERT(odp_packet_has_tcp(pkt)); - - CU_ASSERT(!odp_packet_has_ipv4(pkt)); - CU_ASSERT(!odp_packet_has_udp(pkt)); - - odp_packet_free(pkt); -} - -void parser_test_ipv6_udp(void) -{ - odp_packet_t pkt; - - pkt = loopback_packet(pktio_a, pktio_b, test_packet_ipv6_udp, - sizeof(test_packet_ipv6_udp)); - CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); - CU_ASSERT(odp_packet_has_eth(pkt)); - CU_ASSERT(odp_packet_has_ipv6(pkt)); - CU_ASSERT(odp_packet_has_udp(pkt)); - - CU_ASSERT(!odp_packet_has_ipv4(pkt)); - CU_ASSERT(!odp_packet_has_tcp(pkt)); - - odp_packet_free(pkt); -} - -void parser_test_vlan_ipv6_udp(void) -{ - odp_packet_t pkt; - - pkt = loopback_packet(pktio_a, pktio_b, test_packet_vlan_ipv6_udp, - sizeof(test_packet_vlan_ipv6_udp)); - CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); - CU_ASSERT(odp_packet_has_eth(pkt)); - CU_ASSERT(odp_packet_has_vlan(pkt)); - CU_ASSERT(odp_packet_has_ipv6(pkt)); - CU_ASSERT(odp_packet_has_udp(pkt)); - - CU_ASSERT(!odp_packet_has_ipv4(pkt)); - CU_ASSERT(!odp_packet_has_tcp(pkt)); - - odp_packet_free(pkt); -} - -int parser_suite_init(void) -{ - int i; - - if (getenv("ODP_WAIT_FOR_NETWORK")) - wait_for_network = true; - - iface_name[0] = getenv("ODP_PKTIO_IF0"); - iface_name[1] = getenv("ODP_PKTIO_IF1"); - num_ifaces = 1; - - if (!iface_name[0]) { - printf("No interfaces specified, using default "loop".\n"); - iface_name[0] = "loop"; - } else if (!iface_name[1]) { - printf("Using loopback interface: %s\n", iface_name[0]); - } else { - num_ifaces = 2; - printf("Using paired interfaces: %s %s\n", - iface_name[0], iface_name[1]); - } - - if (pkt_pool_create() != 0) { - printf("Error: failed to create parser pool\n"); - return -1; - } - - /* Create pktios and associate input/output queues */ - for (i = 0; i < num_ifaces; ++i) { - pktio_info_t *io; - - io = &pktios[i]; - io->name = iface_name[i]; - io->hdl = create_pktio(i, parser_pool); - if (io->hdl == ODP_PKTIO_INVALID) { - printf("Error: failed to open iface"); - return -1; - } - - if (odp_pktout_queue(io->hdl, &io->pktout, 1) != 1) { - printf("Error: failed to start iface: %s\n", io->name); - return -1; - } - - if (odp_pktin_queue(io->hdl, &io->pktin, 1) != 1) { - printf("Error: failed to start iface: %s\n", io->name); - return -1; - } - - if (odp_pktio_start(io->hdl)) { - printf("Error: failed to start iface: %s\n", io->name); - return -1; - } - - wait_linkup(io->hdl); - } - - pktio_a = &pktios[0]; - pktio_b = &pktios[1]; - if (num_ifaces == 1) - pktio_b = pktio_a; - - return 0; -} - -int parser_suite_term(void) -{ - int i; - int ret = 0; - - for (i = 0; i < num_ifaces; ++i) { - if (odp_pktio_stop(pktios[i].hdl)) { - printf("Error: failed to stop pktio: %s\n", - pktios[i].name); - ret = -1; - } - if (odp_pktio_close(pktios[i].hdl)) { - printf("Error: failed to close pktio: %s\n", - pktios[i].name); - ret = -1; - } - } - - if (odp_pool_destroy(parser_pool) != 0) { - printf("Error: failed to destroy packet pool\n"); - ret = -1; - } - - return ret; -} - -/** - * Certain tests can only be run with 'loop' pktio. - */ -static int loop_pktio(void) -{ - if (strcmp(iface_name[0], "loop") == 0) - return ODP_TEST_ACTIVE; - else - return ODP_TEST_INACTIVE; -} - -odp_testinfo_t parser_suite[] = { - ODP_TEST_INFO(parser_test_arp), - ODP_TEST_INFO(parser_test_ipv4_icmp), - ODP_TEST_INFO(parser_test_ipv4_tcp), - ODP_TEST_INFO(parser_test_ipv4_udp), - ODP_TEST_INFO_CONDITIONAL(parser_test_vlan_ipv4_udp, loop_pktio), - ODP_TEST_INFO_CONDITIONAL(parser_test_vlan_qinq_ipv4_udp, loop_pktio), - ODP_TEST_INFO(parser_test_ipv6_icmp), - ODP_TEST_INFO(parser_test_ipv6_tcp), - ODP_TEST_INFO(parser_test_ipv6_udp), - ODP_TEST_INFO_CONDITIONAL(parser_test_vlan_ipv6_udp, loop_pktio), - ODP_TEST_INFO_NULL -}; diff --git a/test/common_plat/validation/api/pktio/parser.h b/test/common_plat/validation/api/pktio/parser.h deleted file mode 100644 index 57c62388..00000000 --- a/test/common_plat/validation/api/pktio/parser.h +++ /dev/null @@ -1,180 +0,0 @@ -/* Copyright (c) 2017, Linaro Limited - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef _ODP_TEST_PARSER_H_ -#define _ODP_TEST_PARSER_H_ - -#include <odp_cunit_common.h> - -/* test functions: */ -void parser_test_arp(void); -void parser_test_ipv4_icmp(void); -void parser_test_ipv4_tcp(void); -void parser_test_ipv4_udp(void); -void parser_test_vlan_ipv4_udp(void); -void parser_test_vlan_qinq_ipv4_udp(void); -void parser_test_ipv6_icmp(void); -void parser_test_ipv6_tcp(void); -void parser_test_ipv6_udp(void); -void parser_test_vlan_ipv6_udp(void); - -/* test array init/term functions: */ -int parser_suite_term(void); -int parser_suite_init(void); - -/* test arrays: */ -extern odp_testinfo_t parser_suite[]; - -/** - * ARP request - */ -static const uint8_t test_packet_arp[] = { - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, - 0x09, 0x00, 0x04, 0x00, 0x08, 0x06, 0x00, 0x01, - 0x08, 0x00, 0x06, 0x04, 0x00, 0x01, 0x00, 0x00, - 0x09, 0x00, 0x04, 0x00, 0xC0, 0xA8, 0x01, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xA8, - 0x01, 0x02, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, - 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, - 0x0E, 0x0F, 0x10, 0x11, 0xA1, 0xA8, 0x27, 0x43, -}; - -/** - * ICMPv4 echo reply - */ -static const uint8_t test_packet_ipv4_icmp[] = { - 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x09, 0x00, 0x04, 0x00, 0x08, 0x00, 0x45, 0x00, - 0x00, 0x2E, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, - 0xF3, 0x7B, 0xC0, 0xA8, 0x01, 0x01, 0xC4, 0xA8, - 0x01, 0x02, 0x00, 0x00, 0xB7, 0xAB, 0x00, 0x01, - 0x00, 0x02, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, - 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, - 0x0E, 0x0F, 0x10, 0x11, 0xD9, 0x7F, 0xE8, 0x02, -}; - -/** - * IPv4 TCP - */ -static const uint8_t test_packet_ipv4_tcp[] = { - 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x09, 0x00, 0x04, 0x00, 0x08, 0x00, 0x45, 0x00, - 0x00, 0x2E, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, - 0xF3, 0x76, 0xC0, 0xA8, 0x01, 0x02, 0xC4, 0xA8, - 0x01, 0x01, 0x04, 0xD2, 0x10, 0xE1, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x50, 0x00, - 0x00, 0x00, 0x0C, 0xCC, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x03, 0x04, 0x05, 0x2E, 0xDE, 0x5E, 0x48, -}; - -/** - * IPv4 UDP - */ -static const uint8_t test_packet_ipv4_udp[] = { - 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x09, 0x00, 0x04, 0x00, 0x08, 0x00, 0x45, 0x00, - 0x00, 0x2E, 0x00, 0x00, 0x00, 0x00, 0x40, 0x11, - 0xF3, 0x6B, 0xC0, 0xA8, 0x01, 0x02, 0xC4, 0xA8, - 0x01, 0x01, 0x00, 0x3F, 0x00, 0x3F, 0x00, 0x1A, - 0x2F, 0x97, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, - 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, - 0x0E, 0x0F, 0x10, 0x11, 0x64, 0xF4, 0xE4, 0xB6, -}; - -/** - * VLAN IPv4 UDP - * - ID: 23 - */ -static const uint8_t test_packet_vlan_ipv4_udp[] = { - 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x09, 0x00, 0x04, 0x00, 0x81, 0x00, 0x00, 0x17, - 0x08, 0x00, 0x45, 0x00, 0x00, 0x2A, 0x00, 0x00, - 0x00, 0x00, 0x40, 0x11, 0xF3, 0x6F, 0xC0, 0xA8, - 0x01, 0x02, 0xC4, 0xA8, 0x01, 0x01, 0x00, 0x3F, - 0x00, 0x3F, 0x00, 0x16, 0x4D, 0xBF, 0x00, 0x01, - 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, - 0x0A, 0x0B, 0x0C, 0x0D, 0xCB, 0xBF, 0xD0, 0x29, -}; - -/** - * VLAN Q-in-Q IPv4 UDP - * - Outer: Tag Protocol ID 0x88a8, VLAN ID 1 - * - Inner: Tag Protocol ID 0x8100, VLAN ID 2 - */ -static const uint8_t test_packet_vlan_qinq_ipv4_udp[] = { - 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x09, 0x00, 0x04, 0x00, 0x88, 0xA8, 0x00, 0x01, - 0x81, 0x00, 0x00, 0x02, 0x08, 0x00, 0x45, 0x00, - 0x00, 0x26, 0x00, 0x00, 0x00, 0x00, 0x40, 0x11, - 0xF3, 0x73, 0xC0, 0xA8, 0x01, 0x02, 0xC4, 0xA8, - 0x01, 0x01, 0x00, 0x3F, 0x00, 0x3F, 0x00, 0x12, - 0x63, 0xDF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, - 0x06, 0x07, 0x08, 0x09, 0x80, 0x98, 0xB8, 0x18, -}; - -/** - * ICMPv6 echo request - */ -static const uint8_t test_packet_ipv6_icmp[] = { - 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x09, 0x00, 0x04, 0x00, 0x86, 0xDD, 0x60, 0x30, - 0x00, 0x00, 0x00, 0x08, 0x3A, 0xFF, 0xFE, 0x80, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, - 0x09, 0xFF, 0xFE, 0x00, 0x04, 0x00, 0x35, 0x55, - 0x55, 0x55, 0x66, 0x66, 0x66, 0x66, 0x77, 0x77, - 0x77, 0x77, 0x88, 0x88, 0x88, 0x88, 0x80, 0x00, - 0x1B, 0xC2, 0x00, 0x01, 0x00, 0x02, 0xE0, 0x68, - 0x0E, 0xBA, -}; - -/** - * IPv6 TCP - */ -static const uint8_t test_packet_ipv6_tcp[] = { - 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x09, 0x00, 0x04, 0x00, 0x86, 0xDD, 0x60, 0x30, - 0x00, 0x00, 0x00, 0x14, 0x06, 0xFF, 0xFE, 0x80, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, - 0x09, 0xFF, 0xFE, 0x00, 0x04, 0x00, 0x35, 0x55, - 0x55, 0x55, 0x66, 0x66, 0x66, 0x66, 0x77, 0x77, - 0x77, 0x77, 0x88, 0x88, 0x88, 0x88, 0x04, 0xD2, - 0x10, 0xE1, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, - 0x00, 0x02, 0x50, 0x00, 0x00, 0x00, 0x36, 0x37, - 0x00, 0x00, 0x28, 0x67, 0xD2, 0xAF, -}; - -/** - * IPv6 UDP - */ -static const uint8_t test_packet_ipv6_udp[] = { - 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x09, 0x00, 0x04, 0x00, 0x86, 0xDD, 0x60, 0x30, - 0x00, 0x00, 0x00, 0x08, 0x11, 0xFF, 0xFE, 0x80, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, - 0x09, 0xFF, 0xFE, 0x00, 0x04, 0x00, 0x35, 0x55, - 0x55, 0x55, 0x66, 0x66, 0x66, 0x66, 0x77, 0x77, - 0x77, 0x77, 0x88, 0x88, 0x88, 0x88, 0x00, 0x3F, - 0x00, 0x3F, 0x00, 0x08, 0x9B, 0x68, 0x35, 0xD3, - 0x64, 0x49, -}; - -/** - * VLAN IPv6 - * - ID: 23 - */ -static const uint8_t test_packet_vlan_ipv6_udp[] = { - 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x09, 0x00, 0x04, 0x00, 0x81, 0x00, 0x00, 0x17, - 0x86, 0xDD, 0x60, 0x30, 0x00, 0x00, 0x00, 0x08, - 0x11, 0xFF, 0xFE, 0x80, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x02, 0x00, 0x09, 0xFF, 0xFE, 0x00, - 0x04, 0x00, 0x35, 0x55, 0x55, 0x55, 0x66, 0x66, - 0x66, 0x66, 0x77, 0x77, 0x77, 0x77, 0x88, 0x88, - 0x88, 0x88, 0x00, 0x3F, 0x00, 0x3F, 0x00, 0x08, - 0x9B, 0x68, 0xC5, 0xD8, 0x2F, 0x5C, -}; - -#endif diff --git a/test/common_plat/validation/api/pktio/pktio.c b/test/common_plat/validation/api/pktio/pktio.c index 43fe515a..a21959ef 100644 --- a/test/common_plat/validation/api/pktio/pktio.c +++ b/test/common_plat/validation/api/pktio/pktio.c @@ -10,7 +10,6 @@
#include <stdlib.h> #include "pktio.h" -#include "parser.h"
#define PKT_BUF_NUM 32 #define PKT_BUF_SIZE (9 * 1024) @@ -144,7 +143,8 @@ static void set_pool_len(odp_pool_param_t *params, odp_pool_capability_t *capa) } }
-void pktio_pkt_set_macs(odp_packet_t pkt, odp_pktio_t src, odp_pktio_t dst) +static void pktio_pkt_set_macs(odp_packet_t pkt, + odp_pktio_t src, odp_pktio_t dst) { uint32_t len; odph_ethhdr_t *eth = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, &len); @@ -2190,7 +2190,6 @@ odp_suiteinfo_t pktio_suites[] = { pktio_suite_term, pktio_suite_unsegmented}, {"Packet I/O Segmented", pktio_suite_init_segmented, pktio_suite_term, pktio_suite_segmented}, - {"Packet parser", parser_suite_init, parser_suite_term, parser_suite}, ODP_SUITE_INFO_NULL };
diff --git a/test/common_plat/validation/api/pktio/pktio.h b/test/common_plat/validation/api/pktio/pktio.h index b8799d9e..8131d05f 100644 --- a/test/common_plat/validation/api/pktio/pktio.h +++ b/test/common_plat/validation/api/pktio/pktio.h @@ -61,7 +61,4 @@ extern odp_suiteinfo_t pktio_suites[]; /* main test program: */ int pktio_main(int argc, char *argv[]);
-/* functions shared by parser test suite */ -void pktio_pkt_set_macs(odp_packet_t pkt, odp_pktio_t src, odp_pktio_t dst); - #endif
commit bc2f82e41e517d8c379eb753fd8379479a5e8b7c Author: Janne Peltonen janne.peltonen@nokia.com Date: Fri Apr 7 12:54:00 2017 +0300
abi: event: add ODP_EVENT_IPSEC_STATUS
Update ABI spec with the new IPsec event type.
Signed-off-by: Janne Peltonen janne.peltonen@nokia.com Reviewed-by: Bill Fischofer bill.fischofer@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/include/odp/arch/default/api/abi/event.h b/include/odp/arch/default/api/abi/event.h index ab141572..87220d63 100644 --- a/include/odp/arch/default/api/abi/event.h +++ b/include/odp/arch/default/api/abi/event.h @@ -29,7 +29,8 @@ typedef enum odp_event_type_t { ODP_EVENT_PACKET = 2, ODP_EVENT_TIMEOUT = 3, ODP_EVENT_CRYPTO_COMPL = 4, - ODP_EVENT_IPSEC_RESULT = 5 + ODP_EVENT_IPSEC_RESULT = 5, + ODP_EVENT_IPSEC_STATUS = 6 } odp_event_type_t;
/**
commit 6d3ff54693d7e62ac1163a78c8df9cb66496eaf0 Author: Matias Elo matias.elo@nokia.com Date: Tue Apr 4 09:28:21 2017 +0300
validation: pktio: add tests for packet parsing
Test packet parsing using predefined test packets (byte arrays). Test packets are looped through tested pktio interfaces to force packet parsing.
Signed-off-by: Matias Elo matias.elo@nokia.com 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/pktio/Makefile.am b/test/common_plat/validation/api/pktio/Makefile.am index 466d690d..c6368fba 100644 --- a/test/common_plat/validation/api/pktio/Makefile.am +++ b/test/common_plat/validation/api/pktio/Makefile.am @@ -4,7 +4,7 @@ noinst_LTLIBRARIES = libtestpktio.la libtestpktio_la_SOURCES = pktio.c
test_PROGRAMS = pktio_main$(EXEEXT) -dist_pktio_main_SOURCES = pktio_main.c +dist_pktio_main_SOURCES = pktio_main.c parser.c pktio_main_LDADD = libtestpktio.la $(LIBCUNIT_COMMON) $(LIBODP)
-EXTRA_DIST = pktio.h +EXTRA_DIST = pktio.h parser.h diff --git a/test/common_plat/validation/api/pktio/parser.c b/test/common_plat/validation/api/pktio/parser.c new file mode 100644 index 00000000..ad7101d0 --- /dev/null +++ b/test/common_plat/validation/api/pktio/parser.c @@ -0,0 +1,545 @@ +/* Copyright (c) 2017, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#include <odp_api.h> +#include <odp_cunit_common.h> + +#include <odp/helper/odph_api.h> + +#include <stdlib.h> +#include "parser.h" +#include "pktio.h" + +#define MAX_NUM_IFACES 2 +#define PKT_POOL_NUM 256 +#define PKT_POOL_BUF_LEN (2 * 1024) + +/** + * local container for pktio attributes + */ +typedef struct { + const char *name; + odp_pktio_t hdl; + odp_pktout_queue_t pktout; + odp_pktin_queue_t pktin; +} pktio_info_t; + +/** Interface names used for testing */ +static const char *iface_name[MAX_NUM_IFACES]; + +/** Test interfaces */ +pktio_info_t pktios[MAX_NUM_IFACES]; +pktio_info_t *pktio_a; +pktio_info_t *pktio_b; + +/** Number of interfaces being used (1=loopback, 2=pair) */ +static int num_ifaces; + +/** While testing real-world interfaces additional time may be needed for + * external network to enable link to pktio interface that just become up. + */ +static bool wait_for_network; + +/** Parser packet pool */ +odp_pool_t parser_pool = ODP_POOL_INVALID; + +static inline void wait_linkup(odp_pktio_t pktio) +{ + /* wait 1 second for link up */ + uint64_t wait_ns = (10 * ODP_TIME_MSEC_IN_NS); + int wait_num = 100; + int i; + int ret = -1; + + for (i = 0; i < wait_num; i++) { + ret = odp_pktio_link_status(pktio); + if (ret < 0 || ret == 1) + break; + /* link is down, call status again after delay */ + odp_time_wait_ns(wait_ns); + } +} + +static int pkt_pool_create(void) +{ + odp_pool_capability_t capa; + odp_pool_param_t params; + + if (odp_pool_capability(&capa) != 0) { + printf("Error: unable to query pool capability.\n"); + return -1; + } + + if (capa.pkt.max_num && capa.pkt.max_num < PKT_POOL_NUM) { + printf("Error: packet pool size not supported.\n"); + printf("MAX: %" PRIu32 "\n", capa.pkt.max_num); + return -1; + } else if (capa.pkt.max_len && capa.pkt.max_len < PKT_POOL_BUF_LEN) { + printf("Error: packet length not supported.\n"); + return -1; + } else if (capa.pkt.max_seg_len && + capa.pkt.max_seg_len < PKT_POOL_BUF_LEN) { + printf("Error: segment length not supported.\n"); + return -1; + } + + odp_pool_param_init(¶ms); + params.pkt.seg_len = PKT_POOL_BUF_LEN; + params.pkt.len = PKT_POOL_BUF_LEN; + params.pkt.num = PKT_POOL_NUM; + params.type = ODP_POOL_PACKET; + + parser_pool = odp_pool_create("pkt_pool_default", ¶ms); + if (parser_pool == ODP_POOL_INVALID) { + printf("Error: packet pool create failed.\n"); + return -1; + } + + return 0; +} + +static odp_pktio_t create_pktio(int iface_idx, odp_pool_t pool) +{ + odp_pktio_t pktio; + odp_pktio_config_t config; + odp_pktio_param_t pktio_param; + const char *iface = iface_name[iface_idx]; + + odp_pktio_param_init(&pktio_param); + pktio_param.in_mode = ODP_PKTIN_MODE_DIRECT; + pktio_param.out_mode = ODP_PKTOUT_MODE_DIRECT; + + pktio = odp_pktio_open(iface, pool, &pktio_param); + if (pktio == ODP_PKTIO_INVALID) { + printf("Error: failed to open %s\n", iface); + return ODP_PKTIO_INVALID; + } + + odp_pktio_config_init(&config); + config.parser.layer = ODP_PKTIO_PARSER_LAYER_ALL; + if (odp_pktio_config(pktio, &config)) { + printf("Error: failed to configure %s\n", iface); + return ODP_PKTIO_INVALID; + } + + /* By default, single input and output queue is used */ + if (odp_pktin_queue_config(pktio, NULL)) { + printf("Error: failed to config input queue for %s\n", iface); + return ODP_PKTIO_INVALID; + } + if (odp_pktout_queue_config(pktio, NULL)) { + printf("Error: failed to config output queue for %s\n", iface); + return ODP_PKTIO_INVALID; + } + + if (wait_for_network) + odp_time_wait_ns(ODP_TIME_SEC_IN_NS / 4); + + return pktio; +} + +static odp_packet_t create_packet(const uint8_t *data, uint32_t len) +{ + odp_packet_t pkt; + + pkt = odp_packet_alloc(parser_pool, len); + if (pkt == ODP_PACKET_INVALID) + return ODP_PACKET_INVALID; + + if (odp_packet_copy_from_mem(pkt, 0, len, data)) { + printf("Error: failed to copy test packet data\n"); + odp_packet_free(pkt); + return ODP_PACKET_INVALID; + } + + odp_packet_l2_offset_set(pkt, 0); + + return pkt; +} + +/** + * Receive incoming packets and compare them to the original. Function returns + * a valid packet handle only when the received packet matches to the original + * packet. + */ +static odp_packet_t recv_and_cmp_packet(odp_pktin_queue_t pktin, + odp_packet_t orig_pkt, uint64_t ns) +{ + odp_packet_t pkt = ODP_PACKET_INVALID; + odp_time_t wait_time, end; + uint32_t orig_len; + uint8_t *orig_data; + + orig_len = odp_packet_len(orig_pkt); + orig_data = odp_packet_data(orig_pkt); + wait_time = odp_time_local_from_ns(ns); + end = odp_time_sum(odp_time_local(), wait_time); + + do { + int ret; + odp_packet_t tmp_pkt; + + ret = odp_pktin_recv(pktin, &tmp_pkt, 1); + if (ret < 0) + break; + + if (ret == 1) { + uint32_t len; + uint8_t *data; + + len = odp_packet_len(tmp_pkt); + data = odp_packet_data(tmp_pkt); + + if (len == orig_len && + memcmp(data, orig_data, len) == 0) { + pkt = tmp_pkt; + break; + } + odp_packet_free(tmp_pkt); + } + } while (odp_time_cmp(end, odp_time_local()) > 0); + + return pkt; +} + +/** + * Creates a test packet from data array and loops it through the test pktio + * interfaces forcing packet parsing. + */ +static odp_packet_t loopback_packet(pktio_info_t *pktio_a, + pktio_info_t *pktio_b, const uint8_t *data, + uint32_t len) +{ + odp_packet_t pkt; + odp_packet_t sent_pkt; + + pkt = create_packet(data, len); + if (pkt == ODP_PACKET_INVALID) { + CU_FAIL("failed to generate test packet"); + return ODP_PACKET_INVALID; + } + + pktio_pkt_set_macs(pkt, pktio_a->hdl, pktio_b->hdl); + + sent_pkt = odp_packet_copy(pkt, parser_pool); + if (sent_pkt == ODP_PACKET_INVALID) { + CU_FAIL_FATAL("failed to copy test packet"); + odp_packet_free(pkt); + return ODP_PACKET_INVALID; + } + + while (1) { + int ret = odp_pktout_send(pktio_a->pktout, &pkt, 1); + + if (ret < 0) { + CU_FAIL_FATAL("failed to send test packet"); + odp_packet_free(pkt); + odp_packet_free(sent_pkt); + return ODP_PACKET_INVALID; + } + if (ret == 1) + break; + } + + /* and wait for them to arrive back */ + pkt = recv_and_cmp_packet(pktio_b->pktin, sent_pkt, ODP_TIME_SEC_IN_NS); + odp_packet_free(sent_pkt); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); + CU_ASSERT(odp_packet_input(pkt) == pktio_b->hdl); + CU_ASSERT(odp_packet_has_error(pkt) == 0); + + return pkt; +} + +void parser_test_arp(void) +{ + odp_packet_t pkt; + + pkt = loopback_packet(pktio_a, pktio_b, test_packet_arp, + sizeof(test_packet_arp)); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); + CU_ASSERT(odp_packet_has_eth(pkt)); + CU_ASSERT(odp_packet_has_arp(pkt)); + + CU_ASSERT(!odp_packet_has_ipv4(pkt)); + CU_ASSERT(!odp_packet_has_ipv6(pkt)); + + odp_packet_free(pkt); +} + +void parser_test_ipv4_icmp(void) +{ + odp_packet_t pkt; + + pkt = loopback_packet(pktio_a, pktio_b, test_packet_ipv4_icmp, + sizeof(test_packet_ipv4_icmp)); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); + CU_ASSERT(odp_packet_has_eth(pkt)); + CU_ASSERT(odp_packet_has_ipv4(pkt)); + CU_ASSERT(odp_packet_has_icmp(pkt)); + + CU_ASSERT(!odp_packet_has_ipv6(pkt)); + CU_ASSERT(!odp_packet_has_tcp(pkt)); + CU_ASSERT(!odp_packet_has_udp(pkt)); + + odp_packet_free(pkt); +} + +void parser_test_ipv4_tcp(void) +{ + odp_packet_t pkt; + + pkt = loopback_packet(pktio_a, pktio_b, test_packet_ipv4_tcp, + sizeof(test_packet_ipv4_tcp)); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); + CU_ASSERT(odp_packet_has_eth(pkt)); + CU_ASSERT(odp_packet_has_ipv4(pkt)); + CU_ASSERT(odp_packet_has_tcp(pkt)); + + CU_ASSERT(!odp_packet_has_ipv6(pkt)); + CU_ASSERT(!odp_packet_has_udp(pkt)); + + odp_packet_free(pkt); +} + +void parser_test_ipv4_udp(void) +{ + odp_packet_t pkt; + + pkt = loopback_packet(pktio_a, pktio_b, test_packet_ipv4_udp, + sizeof(test_packet_ipv4_udp)); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); + CU_ASSERT(odp_packet_has_eth(pkt)); + CU_ASSERT(odp_packet_has_ipv4(pkt)); + CU_ASSERT(odp_packet_has_udp(pkt)); + + CU_ASSERT(!odp_packet_has_ipv6(pkt)); + CU_ASSERT(!odp_packet_has_tcp(pkt)); + + odp_packet_free(pkt); +} + +void parser_test_vlan_ipv4_udp(void) +{ + odp_packet_t pkt; + + pkt = loopback_packet(pktio_a, pktio_b, test_packet_vlan_ipv4_udp, + sizeof(test_packet_vlan_ipv4_udp)); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); + CU_ASSERT(odp_packet_has_eth(pkt)); + CU_ASSERT(odp_packet_has_vlan(pkt)); + CU_ASSERT(odp_packet_has_ipv4(pkt)); + CU_ASSERT(odp_packet_has_udp(pkt)); + + CU_ASSERT(!odp_packet_has_ipv6(pkt)); + CU_ASSERT(!odp_packet_has_tcp(pkt)); + + odp_packet_free(pkt); +} + +void parser_test_vlan_qinq_ipv4_udp(void) +{ + odp_packet_t pkt; + + pkt = loopback_packet(pktio_a, pktio_b, test_packet_vlan_qinq_ipv4_udp, + sizeof(test_packet_vlan_qinq_ipv4_udp)); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); + CU_ASSERT(odp_packet_has_eth(pkt)); + CU_ASSERT(odp_packet_has_vlan(pkt)); + CU_ASSERT(odp_packet_has_vlan_qinq(pkt)); + CU_ASSERT(odp_packet_has_ipv4(pkt)); + CU_ASSERT(odp_packet_has_udp(pkt)); + + CU_ASSERT(!odp_packet_has_ipv6(pkt)); + CU_ASSERT(!odp_packet_has_tcp(pkt)); + + odp_packet_free(pkt); +} + +void parser_test_ipv6_icmp(void) +{ + odp_packet_t pkt; + + pkt = loopback_packet(pktio_a, pktio_b, test_packet_ipv6_icmp, + sizeof(test_packet_ipv6_icmp)); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); + CU_ASSERT(odp_packet_has_eth(pkt)); + CU_ASSERT(odp_packet_has_ipv6(pkt)); + CU_ASSERT(odp_packet_has_icmp(pkt)); + + CU_ASSERT(!odp_packet_has_ipv4(pkt)); + CU_ASSERT(!odp_packet_has_tcp(pkt)); + CU_ASSERT(!odp_packet_has_udp(pkt)); + + odp_packet_free(pkt); +} + +void parser_test_ipv6_tcp(void) +{ + odp_packet_t pkt; + + pkt = loopback_packet(pktio_a, pktio_b, test_packet_ipv6_tcp, + sizeof(test_packet_ipv6_tcp)); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); + CU_ASSERT(odp_packet_has_eth(pkt)); + CU_ASSERT(odp_packet_has_ipv6(pkt)); + CU_ASSERT(odp_packet_has_tcp(pkt)); + + CU_ASSERT(!odp_packet_has_ipv4(pkt)); + CU_ASSERT(!odp_packet_has_udp(pkt)); + + odp_packet_free(pkt); +} + +void parser_test_ipv6_udp(void) +{ + odp_packet_t pkt; + + pkt = loopback_packet(pktio_a, pktio_b, test_packet_ipv6_udp, + sizeof(test_packet_ipv6_udp)); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); + CU_ASSERT(odp_packet_has_eth(pkt)); + CU_ASSERT(odp_packet_has_ipv6(pkt)); + CU_ASSERT(odp_packet_has_udp(pkt)); + + CU_ASSERT(!odp_packet_has_ipv4(pkt)); + CU_ASSERT(!odp_packet_has_tcp(pkt)); + + odp_packet_free(pkt); +} + +void parser_test_vlan_ipv6_udp(void) +{ + odp_packet_t pkt; + + pkt = loopback_packet(pktio_a, pktio_b, test_packet_vlan_ipv6_udp, + sizeof(test_packet_vlan_ipv6_udp)); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); + CU_ASSERT(odp_packet_has_eth(pkt)); + CU_ASSERT(odp_packet_has_vlan(pkt)); + CU_ASSERT(odp_packet_has_ipv6(pkt)); + CU_ASSERT(odp_packet_has_udp(pkt)); + + CU_ASSERT(!odp_packet_has_ipv4(pkt)); + CU_ASSERT(!odp_packet_has_tcp(pkt)); + + odp_packet_free(pkt); +} + +int parser_suite_init(void) +{ + int i; + + if (getenv("ODP_WAIT_FOR_NETWORK")) + wait_for_network = true; + + iface_name[0] = getenv("ODP_PKTIO_IF0"); + iface_name[1] = getenv("ODP_PKTIO_IF1"); + num_ifaces = 1; + + if (!iface_name[0]) { + printf("No interfaces specified, using default "loop".\n"); + iface_name[0] = "loop"; + } else if (!iface_name[1]) { + printf("Using loopback interface: %s\n", iface_name[0]); + } else { + num_ifaces = 2; + printf("Using paired interfaces: %s %s\n", + iface_name[0], iface_name[1]); + } + + if (pkt_pool_create() != 0) { + printf("Error: failed to create parser pool\n"); + return -1; + } + + /* Create pktios and associate input/output queues */ + for (i = 0; i < num_ifaces; ++i) { + pktio_info_t *io; + + io = &pktios[i]; + io->name = iface_name[i]; + io->hdl = create_pktio(i, parser_pool); + if (io->hdl == ODP_PKTIO_INVALID) { + printf("Error: failed to open iface"); + return -1; + } + + if (odp_pktout_queue(io->hdl, &io->pktout, 1) != 1) { + printf("Error: failed to start iface: %s\n", io->name); + return -1; + } + + if (odp_pktin_queue(io->hdl, &io->pktin, 1) != 1) { + printf("Error: failed to start iface: %s\n", io->name); + return -1; + } + + if (odp_pktio_start(io->hdl)) { + printf("Error: failed to start iface: %s\n", io->name); + return -1; + } + + wait_linkup(io->hdl); + } + + pktio_a = &pktios[0]; + pktio_b = &pktios[1]; + if (num_ifaces == 1) + pktio_b = pktio_a; + + return 0; +} + +int parser_suite_term(void) +{ + int i; + int ret = 0; + + for (i = 0; i < num_ifaces; ++i) { + if (odp_pktio_stop(pktios[i].hdl)) { + printf("Error: failed to stop pktio: %s\n", + pktios[i].name); + ret = -1; + } + if (odp_pktio_close(pktios[i].hdl)) { + printf("Error: failed to close pktio: %s\n", + pktios[i].name); + ret = -1; + } + } + + if (odp_pool_destroy(parser_pool) != 0) { + printf("Error: failed to destroy packet pool\n"); + ret = -1; + } + + return ret; +} + +/** + * Certain tests can only be run with 'loop' pktio. + */ +static int loop_pktio(void) +{ + if (strcmp(iface_name[0], "loop") == 0) + return ODP_TEST_ACTIVE; + else + return ODP_TEST_INACTIVE; +} + +odp_testinfo_t parser_suite[] = { + ODP_TEST_INFO(parser_test_arp), + ODP_TEST_INFO(parser_test_ipv4_icmp), + ODP_TEST_INFO(parser_test_ipv4_tcp), + ODP_TEST_INFO(parser_test_ipv4_udp), + ODP_TEST_INFO_CONDITIONAL(parser_test_vlan_ipv4_udp, loop_pktio), + ODP_TEST_INFO_CONDITIONAL(parser_test_vlan_qinq_ipv4_udp, loop_pktio), + ODP_TEST_INFO(parser_test_ipv6_icmp), + ODP_TEST_INFO(parser_test_ipv6_tcp), + ODP_TEST_INFO(parser_test_ipv6_udp), + ODP_TEST_INFO_CONDITIONAL(parser_test_vlan_ipv6_udp, loop_pktio), + ODP_TEST_INFO_NULL +}; diff --git a/test/common_plat/validation/api/pktio/parser.h b/test/common_plat/validation/api/pktio/parser.h new file mode 100644 index 00000000..57c62388 --- /dev/null +++ b/test/common_plat/validation/api/pktio/parser.h @@ -0,0 +1,180 @@ +/* Copyright (c) 2017, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _ODP_TEST_PARSER_H_ +#define _ODP_TEST_PARSER_H_ + +#include <odp_cunit_common.h> + +/* test functions: */ +void parser_test_arp(void); +void parser_test_ipv4_icmp(void); +void parser_test_ipv4_tcp(void); +void parser_test_ipv4_udp(void); +void parser_test_vlan_ipv4_udp(void); +void parser_test_vlan_qinq_ipv4_udp(void); +void parser_test_ipv6_icmp(void); +void parser_test_ipv6_tcp(void); +void parser_test_ipv6_udp(void); +void parser_test_vlan_ipv6_udp(void); + +/* test array init/term functions: */ +int parser_suite_term(void); +int parser_suite_init(void); + +/* test arrays: */ +extern odp_testinfo_t parser_suite[]; + +/** + * ARP request + */ +static const uint8_t test_packet_arp[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, + 0x09, 0x00, 0x04, 0x00, 0x08, 0x06, 0x00, 0x01, + 0x08, 0x00, 0x06, 0x04, 0x00, 0x01, 0x00, 0x00, + 0x09, 0x00, 0x04, 0x00, 0xC0, 0xA8, 0x01, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xA8, + 0x01, 0x02, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, + 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, + 0x0E, 0x0F, 0x10, 0x11, 0xA1, 0xA8, 0x27, 0x43, +}; + +/** + * ICMPv4 echo reply + */ +static const uint8_t test_packet_ipv4_icmp[] = { + 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x04, 0x00, 0x08, 0x00, 0x45, 0x00, + 0x00, 0x2E, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, + 0xF3, 0x7B, 0xC0, 0xA8, 0x01, 0x01, 0xC4, 0xA8, + 0x01, 0x02, 0x00, 0x00, 0xB7, 0xAB, 0x00, 0x01, + 0x00, 0x02, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, + 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, + 0x0E, 0x0F, 0x10, 0x11, 0xD9, 0x7F, 0xE8, 0x02, +}; + +/** + * IPv4 TCP + */ +static const uint8_t test_packet_ipv4_tcp[] = { + 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x04, 0x00, 0x08, 0x00, 0x45, 0x00, + 0x00, 0x2E, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, + 0xF3, 0x76, 0xC0, 0xA8, 0x01, 0x02, 0xC4, 0xA8, + 0x01, 0x01, 0x04, 0xD2, 0x10, 0xE1, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x50, 0x00, + 0x00, 0x00, 0x0C, 0xCC, 0x00, 0x00, 0x00, 0x01, + 0x02, 0x03, 0x04, 0x05, 0x2E, 0xDE, 0x5E, 0x48, +}; + +/** + * IPv4 UDP + */ +static const uint8_t test_packet_ipv4_udp[] = { + 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x04, 0x00, 0x08, 0x00, 0x45, 0x00, + 0x00, 0x2E, 0x00, 0x00, 0x00, 0x00, 0x40, 0x11, + 0xF3, 0x6B, 0xC0, 0xA8, 0x01, 0x02, 0xC4, 0xA8, + 0x01, 0x01, 0x00, 0x3F, 0x00, 0x3F, 0x00, 0x1A, + 0x2F, 0x97, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, + 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, + 0x0E, 0x0F, 0x10, 0x11, 0x64, 0xF4, 0xE4, 0xB6, +}; + +/** + * VLAN IPv4 UDP + * - ID: 23 + */ +static const uint8_t test_packet_vlan_ipv4_udp[] = { + 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x04, 0x00, 0x81, 0x00, 0x00, 0x17, + 0x08, 0x00, 0x45, 0x00, 0x00, 0x2A, 0x00, 0x00, + 0x00, 0x00, 0x40, 0x11, 0xF3, 0x6F, 0xC0, 0xA8, + 0x01, 0x02, 0xC4, 0xA8, 0x01, 0x01, 0x00, 0x3F, + 0x00, 0x3F, 0x00, 0x16, 0x4D, 0xBF, 0x00, 0x01, + 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, + 0x0A, 0x0B, 0x0C, 0x0D, 0xCB, 0xBF, 0xD0, 0x29, +}; + +/** + * VLAN Q-in-Q IPv4 UDP + * - Outer: Tag Protocol ID 0x88a8, VLAN ID 1 + * - Inner: Tag Protocol ID 0x8100, VLAN ID 2 + */ +static const uint8_t test_packet_vlan_qinq_ipv4_udp[] = { + 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x04, 0x00, 0x88, 0xA8, 0x00, 0x01, + 0x81, 0x00, 0x00, 0x02, 0x08, 0x00, 0x45, 0x00, + 0x00, 0x26, 0x00, 0x00, 0x00, 0x00, 0x40, 0x11, + 0xF3, 0x73, 0xC0, 0xA8, 0x01, 0x02, 0xC4, 0xA8, + 0x01, 0x01, 0x00, 0x3F, 0x00, 0x3F, 0x00, 0x12, + 0x63, 0xDF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, + 0x06, 0x07, 0x08, 0x09, 0x80, 0x98, 0xB8, 0x18, +}; + +/** + * ICMPv6 echo request + */ +static const uint8_t test_packet_ipv6_icmp[] = { + 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x04, 0x00, 0x86, 0xDD, 0x60, 0x30, + 0x00, 0x00, 0x00, 0x08, 0x3A, 0xFF, 0xFE, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x09, 0xFF, 0xFE, 0x00, 0x04, 0x00, 0x35, 0x55, + 0x55, 0x55, 0x66, 0x66, 0x66, 0x66, 0x77, 0x77, + 0x77, 0x77, 0x88, 0x88, 0x88, 0x88, 0x80, 0x00, + 0x1B, 0xC2, 0x00, 0x01, 0x00, 0x02, 0xE0, 0x68, + 0x0E, 0xBA, +}; + +/** + * IPv6 TCP + */ +static const uint8_t test_packet_ipv6_tcp[] = { + 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x04, 0x00, 0x86, 0xDD, 0x60, 0x30, + 0x00, 0x00, 0x00, 0x14, 0x06, 0xFF, 0xFE, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x09, 0xFF, 0xFE, 0x00, 0x04, 0x00, 0x35, 0x55, + 0x55, 0x55, 0x66, 0x66, 0x66, 0x66, 0x77, 0x77, + 0x77, 0x77, 0x88, 0x88, 0x88, 0x88, 0x04, 0xD2, + 0x10, 0xE1, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x02, 0x50, 0x00, 0x00, 0x00, 0x36, 0x37, + 0x00, 0x00, 0x28, 0x67, 0xD2, 0xAF, +}; + +/** + * IPv6 UDP + */ +static const uint8_t test_packet_ipv6_udp[] = { + 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x04, 0x00, 0x86, 0xDD, 0x60, 0x30, + 0x00, 0x00, 0x00, 0x08, 0x11, 0xFF, 0xFE, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x09, 0xFF, 0xFE, 0x00, 0x04, 0x00, 0x35, 0x55, + 0x55, 0x55, 0x66, 0x66, 0x66, 0x66, 0x77, 0x77, + 0x77, 0x77, 0x88, 0x88, 0x88, 0x88, 0x00, 0x3F, + 0x00, 0x3F, 0x00, 0x08, 0x9B, 0x68, 0x35, 0xD3, + 0x64, 0x49, +}; + +/** + * VLAN IPv6 + * - ID: 23 + */ +static const uint8_t test_packet_vlan_ipv6_udp[] = { + 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x04, 0x00, 0x81, 0x00, 0x00, 0x17, + 0x86, 0xDD, 0x60, 0x30, 0x00, 0x00, 0x00, 0x08, + 0x11, 0xFF, 0xFE, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x00, 0x09, 0xFF, 0xFE, 0x00, + 0x04, 0x00, 0x35, 0x55, 0x55, 0x55, 0x66, 0x66, + 0x66, 0x66, 0x77, 0x77, 0x77, 0x77, 0x88, 0x88, + 0x88, 0x88, 0x00, 0x3F, 0x00, 0x3F, 0x00, 0x08, + 0x9B, 0x68, 0xC5, 0xD8, 0x2F, 0x5C, +}; + +#endif diff --git a/test/common_plat/validation/api/pktio/pktio.c b/test/common_plat/validation/api/pktio/pktio.c index a21959ef..43fe515a 100644 --- a/test/common_plat/validation/api/pktio/pktio.c +++ b/test/common_plat/validation/api/pktio/pktio.c @@ -10,6 +10,7 @@
#include <stdlib.h> #include "pktio.h" +#include "parser.h"
#define PKT_BUF_NUM 32 #define PKT_BUF_SIZE (9 * 1024) @@ -143,8 +144,7 @@ static void set_pool_len(odp_pool_param_t *params, odp_pool_capability_t *capa) } }
-static void pktio_pkt_set_macs(odp_packet_t pkt, - odp_pktio_t src, odp_pktio_t dst) +void pktio_pkt_set_macs(odp_packet_t pkt, odp_pktio_t src, odp_pktio_t dst) { uint32_t len; odph_ethhdr_t *eth = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, &len); @@ -2190,6 +2190,7 @@ odp_suiteinfo_t pktio_suites[] = { pktio_suite_term, pktio_suite_unsegmented}, {"Packet I/O Segmented", pktio_suite_init_segmented, pktio_suite_term, pktio_suite_segmented}, + {"Packet parser", parser_suite_init, parser_suite_term, parser_suite}, ODP_SUITE_INFO_NULL };
diff --git a/test/common_plat/validation/api/pktio/pktio.h b/test/common_plat/validation/api/pktio/pktio.h index 8131d05f..b8799d9e 100644 --- a/test/common_plat/validation/api/pktio/pktio.h +++ b/test/common_plat/validation/api/pktio/pktio.h @@ -61,4 +61,7 @@ extern odp_suiteinfo_t pktio_suites[]; /* main test program: */ int pktio_main(int argc, char *argv[]);
+/* functions shared by parser test suite */ +void pktio_pkt_set_macs(odp_packet_t pkt, odp_pktio_t src, odp_pktio_t dst); + #endif
commit 320d1f3195e7aa75e899506392632a7dab72bdac Author: Matias Elo matias.elo@nokia.com Date: Tue Apr 4 09:28:20 2017 +0300
examples: use odp_pktio_config() to select required packet parsing level
Select required packet parsing level when full packet parsing is not required.
Signed-off-by: Matias Elo matias.elo@nokia.com Reviewed-and-tested-by: Bill Fischofer bill.fischofer@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/example/l2fwd_simple/odp_l2fwd_simple.c b/example/l2fwd_simple/odp_l2fwd_simple.c index b97808f4..e6381455 100644 --- a/example/l2fwd_simple/odp_l2fwd_simple.c +++ b/example/l2fwd_simple/odp_l2fwd_simple.c @@ -41,6 +41,7 @@ static odp_pktio_t create_pktio(const char *name, odp_pool_t pool, odp_pktin_queue_param_t in_queue_param; odp_pktout_queue_param_t out_queue_param; odp_pktio_t pktio; + odp_pktio_config_t config;
odp_pktio_param_init(&pktio_param);
@@ -50,6 +51,10 @@ static odp_pktio_t create_pktio(const char *name, odp_pool_t pool, exit(1); }
+ odp_pktio_config_init(&config); + config.parser.layer = ODP_PKTIO_PARSER_LAYER_L2; + odp_pktio_config(pktio, &config); + odp_pktin_queue_param_init(&in_queue_param); odp_pktout_queue_param_init(&out_queue_param);
diff --git a/example/l3fwd/odp_l3fwd.c b/example/l3fwd/odp_l3fwd.c index ba069720..f579d36d 100644 --- a/example/l3fwd/odp_l3fwd.c +++ b/example/l3fwd/odp_l3fwd.c @@ -101,6 +101,7 @@ static int create_pktio(const char *name, odp_pool_t pool, odp_pktio_param_t pktio_param; odp_pktio_t pktio; odp_pktio_capability_t capa; + odp_pktio_config_t config; int rc;
odp_pktio_param_init(&pktio_param); @@ -120,6 +121,12 @@ static int create_pktio(const char *name, odp_pool_t pool, return -1; }
+ odp_pktio_config_init(&config); + config.parser.layer = global.cmd_args.error_check ? + ODP_PKTIO_PARSER_LAYER_ALL : + ODP_PKTIO_PARSER_LAYER_L4; + odp_pktio_config(pktio, &config); + fwd_pktio->nb_rxq = (int)capa.max_input_queues; fwd_pktio->nb_txq = (int)capa.max_output_queues;
diff --git a/example/switch/odp_switch.c b/example/switch/odp_switch.c index 561c2934..5bec6a04 100644 --- a/example/switch/odp_switch.c +++ b/example/switch/odp_switch.c @@ -217,6 +217,7 @@ static int create_pktio(const char *dev, int idx, int num_rx, int num_tx, odp_pktio_t pktio; odp_pktio_param_t pktio_param; odp_pktio_capability_t capa; + odp_pktio_config_t config; odp_pktin_queue_param_t pktin_param; odp_pktout_queue_param_t pktout_param; odp_pktio_op_mode_t mode_rx; @@ -238,6 +239,10 @@ static int create_pktio(const char *dev, int idx, int num_rx, int num_tx, return -1; }
+ odp_pktio_config_init(&config); + config.parser.layer = ODP_PKTIO_PARSER_LAYER_L2; + odp_pktio_config(pktio, &config); + odp_pktin_queue_param_init(&pktin_param); odp_pktout_queue_param_init(&pktout_param);
diff --git a/test/common_plat/performance/odp_l2fwd.c b/test/common_plat/performance/odp_l2fwd.c index 33efc022..78b3633b 100644 --- a/test/common_plat/performance/odp_l2fwd.c +++ b/test/common_plat/performance/odp_l2fwd.c @@ -619,6 +619,7 @@ static int create_pktio(const char *dev, int idx, int num_rx, int num_tx, odp_pktio_param_t pktio_param; odp_schedule_sync_t sync_mode; odp_pktio_capability_t capa; + odp_pktio_config_t config; odp_pktin_queue_param_t pktin_param; odp_pktout_queue_param_t pktout_param; odp_pktio_op_mode_t mode_rx; @@ -655,6 +656,12 @@ static int create_pktio(const char *dev, int idx, int num_rx, int num_tx, return -1; }
+ odp_pktio_config_init(&config); + config.parser.layer = gbl_args->appl.error_check ? + ODP_PKTIO_PARSER_LAYER_ALL : + ODP_PKTIO_PARSER_LAYER_NONE; + odp_pktio_config(pktio, &config); + odp_pktin_queue_param_init(&pktin_param); odp_pktout_queue_param_init(&pktout_param);
diff --git a/test/common_plat/performance/odp_pktio_ordered.c b/test/common_plat/performance/odp_pktio_ordered.c index bff4586e..4bb0bef9 100644 --- a/test/common_plat/performance/odp_pktio_ordered.c +++ b/test/common_plat/performance/odp_pktio_ordered.c @@ -586,6 +586,7 @@ static int create_pktio(const char *dev, int idx, int num_rx, int num_tx, odp_pktio_t pktio; odp_pktio_param_t pktio_param; odp_pktio_capability_t capa; + odp_pktio_config_t config; odp_pktin_queue_param_t pktin_param; odp_pktout_queue_param_t pktout_param; odp_pktio_op_mode_t mode_rx; @@ -611,6 +612,10 @@ static int create_pktio(const char *dev, int idx, int num_rx, int num_tx, return -1; }
+ odp_pktio_config_init(&config); + config.parser.layer = ODP_PKTIO_PARSER_LAYER_L2; + odp_pktio_config(pktio, &config); + odp_pktin_queue_param_init(&pktin_param); odp_pktout_queue_param_init(&pktout_param);
commit d8f38f6d14ef0e966d06dd8630b75eb4db3f01d6 Author: Matias Elo matias.elo@nokia.com Date: Tue Apr 4 09:28:18 2017 +0300
linux-gen: packet: recognize ICMPv6 packets
Signed-off-by: Matias Elo matias.elo@nokia.com Reviewed-and-tested-by: Bill Fischofer bill.fischofer@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/example/generator/odp_generator.c b/example/generator/odp_generator.c index 3ec7d8d1..9336cec1 100644 --- a/example/generator/odp_generator.c +++ b/example/generator/odp_generator.c @@ -319,7 +319,7 @@ static odp_packet_t setup_icmp_pkt_ref(odp_pool_t pool) ip->ttl = 64; ip->tot_len = odp_cpu_to_be_16(args->appl.payload + ODPH_ICMPHDR_LEN + ODPH_IPV4HDR_LEN); - ip->proto = ODPH_IPPROTO_ICMP; + ip->proto = ODPH_IPPROTO_ICMPv4; ip->id = 0; ip->chksum = 0;
@@ -664,7 +664,7 @@ static void print_pkts(int thr, odp_packet_t pkt_tbl[], unsigned len) }
/* icmp */ - if (ip->proto == ODPH_IPPROTO_ICMP) { + if (ip->proto == ODPH_IPPROTO_ICMPv4) { icmp = (odph_icmphdr_t *)(buf + offset);
process_icmp_pkt(icmp, msg); diff --git a/example/ipsec/odp_ipsec_stream.c b/example/ipsec/odp_ipsec_stream.c index 15087cbe..e37fbee2 100644 --- a/example/ipsec/odp_ipsec_stream.c +++ b/example/ipsec/odp_ipsec_stream.c @@ -219,7 +219,7 @@ odp_packet_t create_ipv4_packet(stream_db_entry_t *stream, ip->src_addr = odp_cpu_to_be_32(entry->tun_src_ip); ip->dst_addr = odp_cpu_to_be_32(entry->tun_dst_ip); } else { - ip->proto = ODPH_IPPROTO_ICMP; + ip->proto = ODPH_IPPROTO_ICMPv4; ip->src_addr = odp_cpu_to_be_32(stream->src_ip); ip->dst_addr = odp_cpu_to_be_32(stream->dst_ip); } @@ -262,7 +262,7 @@ odp_packet_t create_ipv4_packet(stream_db_entry_t *stream, inner_ip = (odph_ipv4hdr_t *)data; memset((char *)inner_ip, 0, sizeof(*inner_ip)); inner_ip->ver_ihl = 0x45; - inner_ip->proto = ODPH_IPPROTO_ICMP; + inner_ip->proto = ODPH_IPPROTO_ICMPv4; inner_ip->id = odp_cpu_to_be_16(stream->id); inner_ip->ttl = 64; inner_ip->tos = 0; @@ -519,7 +519,7 @@ clear_packet: icmp = (odph_icmphdr_t *)(inner_ip + 1); data = (uint8_t *)icmp; } else { - if (ODPH_IPPROTO_ICMP != ip->proto) + if (ODPH_IPPROTO_ICMPv4 != ip->proto) return FALSE; icmp = (odph_icmphdr_t *)data; } diff --git a/helper/include/odp/helper/ip.h b/helper/include/odp/helper/ip.h index ba6e675f..91776fad 100644 --- a/helper/include/odp/helper/ip.h +++ b/helper/include/odp/helper/ip.h @@ -205,13 +205,14 @@ typedef struct ODP_PACKED { * IP protocol values (IPv4:'proto' or IPv6:'next_hdr') * @{*/ #define ODPH_IPPROTO_HOPOPTS 0x00 /**< IPv6 hop-by-hop options */ -#define ODPH_IPPROTO_ICMP 0x01 /**< Internet Control Message Protocol (1) */ +#define ODPH_IPPROTO_ICMPv4 0x01 /**< Internet Control Message Protocol (1) */ #define ODPH_IPPROTO_TCP 0x06 /**< Transmission Control Protocol (6) */ #define ODPH_IPPROTO_UDP 0x11 /**< User Datagram Protocol (17) */ #define ODPH_IPPROTO_ROUTE 0x2B /**< IPv6 Routing header (43) */ #define ODPH_IPPROTO_FRAG 0x2C /**< IPv6 Fragment (44) */ #define ODPH_IPPROTO_AH 0x33 /**< Authentication Header (51) */ #define ODPH_IPPROTO_ESP 0x32 /**< Encapsulating Security Payload (50) */ +#define ODPH_IPPROTO_ICMPv6 0x3A /**< Internet Control Message Protocol (58) */ #define ODPH_IPPROTO_INVALID 0xFF /**< Reserved invalid by IANA */
/**@}*/ diff --git a/platform/linux-generic/include/protocols/ip.h b/platform/linux-generic/include/protocols/ip.h index 20041f1c..2b34a753 100644 --- a/platform/linux-generic/include/protocols/ip.h +++ b/platform/linux-generic/include/protocols/ip.h @@ -157,13 +157,14 @@ typedef struct ODP_PACKED { * IP protocol values (IPv4:'proto' or IPv6:'next_hdr') * @{*/ #define _ODP_IPPROTO_HOPOPTS 0x00 /**< IPv6 hop-by-hop options */ -#define _ODP_IPPROTO_ICMP 0x01 /**< Internet Control Message Protocol (1) */ +#define _ODP_IPPROTO_ICMPv4 0x01 /**< Internet Control Message Protocol (1) */ #define _ODP_IPPROTO_TCP 0x06 /**< Transmission Control Protocol (6) */ #define _ODP_IPPROTO_UDP 0x11 /**< User Datagram Protocol (17) */ #define _ODP_IPPROTO_ROUTE 0x2B /**< IPv6 Routing header (43) */ #define _ODP_IPPROTO_FRAG 0x2C /**< IPv6 Fragment (44) */ #define _ODP_IPPROTO_AH 0x33 /**< Authentication Header (51) */ #define _ODP_IPPROTO_ESP 0x32 /**< Encapsulating Security Payload (50) */ +#define _ODP_IPPROTO_ICMPv6 0x3A /**< Internet Control Message Protocol (58) */ #define _ODP_IPPROTO_SCTP 0x84 /**< Stream Control Transmission protocol (132) */ #define _ODP_IPPROTO_INVALID 0xFF /**< Reserved invalid by IANA */ diff --git a/platform/linux-generic/odp_packet.c b/platform/linux-generic/odp_packet.c index e2bb8426..c6962ce9 100644 --- a/platform/linux-generic/odp_packet.c +++ b/platform/linux-generic/odp_packet.c @@ -2078,7 +2078,10 @@ int packet_parse_common(packet_parser_t *prs, const uint8_t *ptr,
/* Parse Layer 4 headers */ switch (prs->ip_proto) { - case _ODP_IPPROTO_ICMP: + case _ODP_IPPROTO_ICMPv4: + /* Fall through */ + + case _ODP_IPPROTO_ICMPv6: prs->input_flags.icmp = 1; break;
commit 77a9d1e16d8a6d35d71aa0f8450c00c98295fb0f Author: Petri Savolainen petri.savolainen@linaro.org Date: Thu Mar 30 13:29:45 2017 +0300
linux-gen: ipsec: add stubs for new functions
Enable application build with IPSEC.
Signed-off-by: Petri Savolainen petri.savolainen@linaro.org Reviewed-by: Bill Fischofer bill.fischofer@linaro.org Reviewed-by: Balasubramanian Manoharan bala.manoharan@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/platform/linux-generic/odp_ipsec.c b/platform/linux-generic/odp_ipsec.c index 588d8d83..5eb1be30 100644 --- a/platform/linux-generic/odp_ipsec.c +++ b/platform/linux-generic/odp_ipsec.c @@ -59,6 +59,13 @@ odp_ipsec_sa_t odp_ipsec_sa_create(odp_ipsec_sa_param_t *param) return ODP_IPSEC_SA_INVALID; }
+int odp_ipsec_sa_disable(odp_ipsec_sa_t sa) +{ + (void)sa; + + return -1; +} + int odp_ipsec_sa_destroy(odp_ipsec_sa_t sa) { (void)sa; @@ -98,6 +105,15 @@ int odp_ipsec_out_enq(const odp_ipsec_op_param_t *input) return -1; }
+int odp_ipsec_out_inline(const odp_ipsec_op_param_t *op_param, + const odp_ipsec_inline_op_param_t *inline_param) +{ + (void)op_param; + (void)inline_param; + + return -1; +} + int odp_ipsec_result(odp_ipsec_op_result_t *result, odp_event_t event) { (void)result; @@ -106,6 +122,14 @@ int odp_ipsec_result(odp_ipsec_op_result_t *result, odp_event_t event) return -1; }
+int odp_ipsec_status(odp_ipsec_status_t *status, odp_event_t event) +{ + (void)status; + (void)event; + + return -1; +} + int odp_ipsec_mtu_update(odp_ipsec_sa_t sa, uint32_t mtu) { (void)sa;
commit a1afe8ff10bcb000ac69fc61eeae1acd14f8e4bd Author: Petri Savolainen petri.savolainen@linaro.org Date: Tue Mar 28 14:07:26 2017 +0300
api: packet: add per packet checksum control
Checksum insertion has pktio interface level configuration options. Per packet override is needed for example when L4 checksumming is enabled and application forwards packets. Forwarded packets need to maintain original, end-to-end checksum value.
Signed-off-by: Petri Savolainen petri.savolainen@linaro.org Reviewed-by: Balasubramanian Manoharan bala.manoharan@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/include/odp/api/spec/packet.h b/include/odp/api/spec/packet.h index 79d8773e..95f5349b 100644 --- a/include/odp/api/spec/packet.h +++ b/include/odp/api/spec/packet.h @@ -1378,6 +1378,32 @@ uint32_t odp_packet_l4_offset(odp_packet_t pkt); int odp_packet_l4_offset_set(odp_packet_t pkt, uint32_t offset);
/** + * Layer 3 checksum insertion override + * + * Override checksum insertion configuration per packet. This per packet setting + * overrides a higher level configuration for checksum insertion into a L3 + * header during packet output processing. + * + * @param pkt Packet handle + * @param l3 0: do not insert L3 checksum + * 1: insert L3 checksum + */ +void odp_packet_l3_chksum_insert(odp_packet_t pkt, int l3); + +/** + * Layer 4 checksum insertion override + * + * Override checksum insertion configuration per packet. This per packet setting + * overrides a higher level configuration for checksum insertion into a L4 + * header during packet output processing. + * + * @param pkt Packet handle + * @param l4 0: do not insert L4 checksum + * 1: insert L4 checksum + */ +void odp_packet_l4_chksum_insert(odp_packet_t pkt, int l4); + +/** * Packet flow hash value * * Returns the hash generated from the packet header. Use
commit ed17c2117dd80b100182d60f29c74735fd65e85c Author: Petri Savolainen petri.savolainen@linaro.org Date: Fri Feb 17 16:20:07 2017 +0200
linux-gen: pktio: parser default config
Fill default parser configuration and capability. All pktios use same parser code, so the capability is the same (all layers).
Signed-off-by: Petri Savolainen petri.savolainen@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/odp_packet_io.c b/platform/linux-generic/odp_packet_io.c index 50a000e5..ea9f2a75 100644 --- a/platform/linux-generic/odp_packet_io.c +++ b/platform/linux-generic/odp_packet_io.c @@ -931,6 +931,8 @@ void odp_pktout_queue_param_init(odp_pktout_queue_param_t *param) void odp_pktio_config_init(odp_pktio_config_t *config) { memset(config, 0, sizeof(odp_pktio_config_t)); + + config->parser.layer = ODP_PKTIO_PARSER_LAYER_ALL; }
int odp_pktio_info(odp_pktio_t hdl, odp_pktio_info_t *info) @@ -1106,6 +1108,7 @@ int odp_pktio_term_global(void) int odp_pktio_capability(odp_pktio_t pktio, odp_pktio_capability_t *capa) { pktio_entry_t *entry; + int ret;
entry = get_pktio_entry(pktio); if (entry == NULL) { @@ -1114,9 +1117,15 @@ int odp_pktio_capability(odp_pktio_t pktio, odp_pktio_capability_t *capa) }
if (entry->s.ops->capability) - return entry->s.ops->capability(entry, capa); + ret = entry->s.ops->capability(entry, capa); + else + ret = single_capability(capa);
- return single_capability(capa); + /* The same parser is used for all pktios */ + if (ret == 0) + capa->config.parser.layer = ODP_PKTIO_PARSER_LAYER_ALL; + + return ret; }
unsigned odp_pktio_max_index(void) diff --git a/test/common_plat/validation/api/pktio/pktio.c b/test/common_plat/validation/api/pktio/pktio.c index 11fe974f..a21959ef 100644 --- a/test/common_plat/validation/api/pktio/pktio.c +++ b/test/common_plat/validation/api/pktio/pktio.c @@ -1182,6 +1182,8 @@ void pktio_test_pktio_config(void)
odp_pktio_config_init(&config);
+ CU_ASSERT(config.parser.layer == ODP_PKTIO_PARSER_LAYER_ALL); + CU_ASSERT(odp_pktio_config(pktio, NULL) == 0);
CU_ASSERT(odp_pktio_config(pktio, &config) == 0);
commit 605b00a21e1d979a124980ad25bc32539bd00139 Author: Petri Savolainen petri.savolainen@linaro.org Date: Fri Feb 17 16:20:06 2017 +0200
api: pktio: add parser configuration
Packet input parsing level configuration is added. An application may express the maximum layer it is interested about. Implementations may optimize packet input performance as parsing can be stopped on the application required level. Implementations are free to parse more layers than application requests.
Lazy parsing (e.g. in current odp-linux) does not work in practice. The implementation cannot continue parsing after the application has got access to packet data, since application may overwrite some packet headers. Parse results must reflect the format of the received packet.
Signed-off-by: Petri Savolainen petri.savolainen@linaro.org Reviewed-and-tested-by: Bill Fischofer bill.fischofer@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/include/odp/api/spec/packet_io.h b/include/odp/api/spec/packet_io.h index 85cd6d18..cec1f22a 100644 --- a/include/odp/api/spec/packet_io.h +++ b/include/odp/api/spec/packet_io.h @@ -346,6 +346,39 @@ typedef union odp_pktout_config_opt_t { } odp_pktout_config_opt_t;
/** + * Parser layers + */ +typedef enum odp_pktio_parser_layer_t { + /** No layers */ + ODP_PKTIO_PARSER_LAYER_NONE = 0, + + /** Layer L2 protocols (Ethernet, VLAN, ARP, etc) */ + ODP_PKTIO_PARSER_LAYER_L2, + + /** Layer L3 protocols (IPv4, IPv6, ICMP, IPsec, etc) */ + ODP_PKTIO_PARSER_LAYER_L3, + + /** Layer L4 protocols (UDP, TCP, SCTP) */ + ODP_PKTIO_PARSER_LAYER_L4, + + /** All layers */ + ODP_PKTIO_PARSER_LAYER_ALL + +} odp_pktio_parser_layer_t; + +/** + * Parser configuration + */ +typedef struct odp_pktio_parser_config_t { + /** Protocol parsing level in packet input + * + * Parse protocol layers in minimum up to this level during packet + * input. The default value is ODP_PKTIO_PARSER_LAYER_ALL. */ + odp_pktio_parser_layer_t layer; + +} odp_pktio_parser_config_t; + +/** * Packet IO configuration options * * Packet IO interface level configuration options. Use odp_pktio_capability() @@ -363,6 +396,9 @@ typedef struct odp_pktio_config_t { * Default value for all bits is zero. */ odp_pktout_config_opt_t pktout;
+ /** Packet input parser configuration */ + odp_pktio_parser_config_t parser; + /** Interface loopback mode * * In this mode the packets sent out through the interface is
commit 7c8cbb741d3c2b9e4e05ce1296ba9d2690f643f4 Author: Petri Savolainen petri.savolainen@linaro.org Date: Fri Feb 17 13:34:14 2017 +0200
linux-gen: ipsec: add stubs for functions
Added stubs for functions so that applications can be built already. A proper implementation follows later on.
Signed-off-by: Petri Savolainen petri.savolainen@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/odp_ipsec.c b/platform/linux-generic/odp_ipsec.c index ce7fded1..588d8d83 100644 --- a/platform/linux-generic/odp_ipsec.c +++ b/platform/linux-generic/odp_ipsec.c @@ -14,3 +14,114 @@ int odp_ipsec_capability(odp_ipsec_capability_t *capa)
return 0; } + +int odp_ipsec_cipher_capability(odp_cipher_alg_t cipher, + odp_crypto_cipher_capability_t capa[], int num) +{ + (void)cipher; + (void)capa; + (void)num; + + return -1; +} + +int odp_ipsec_auth_capability(odp_auth_alg_t auth, + odp_crypto_auth_capability_t capa[], int num) +{ + (void)auth; + (void)capa; + (void)num; + + return -1; +} + +void odp_ipsec_config_init(odp_ipsec_config_t *config) +{ + memset(config, 0, sizeof(odp_ipsec_config_t)); +} + +int odp_ipsec_config(const odp_ipsec_config_t *config) +{ + (void)config; + + return -1; +} + +void odp_ipsec_sa_param_init(odp_ipsec_sa_param_t *param) +{ + memset(param, 0, sizeof(odp_ipsec_sa_param_t)); +} + +odp_ipsec_sa_t odp_ipsec_sa_create(odp_ipsec_sa_param_t *param) +{ + (void)param; + + return ODP_IPSEC_SA_INVALID; +} + +int odp_ipsec_sa_destroy(odp_ipsec_sa_t sa) +{ + (void)sa; + + return -1; +} + +int odp_ipsec_in(const odp_ipsec_op_param_t *input, + odp_ipsec_op_result_t *output) +{ + (void)input; + (void)output; + + return -1; +} + +int odp_ipsec_out(const odp_ipsec_op_param_t *input, + odp_ipsec_op_result_t *output) +{ + (void)input; + (void)output; + + return -1; +} + +int odp_ipsec_in_enq(const odp_ipsec_op_param_t *input) +{ + (void)input; + + return -1; +} + +int odp_ipsec_out_enq(const odp_ipsec_op_param_t *input) +{ + (void)input; + + return -1; +} + +int odp_ipsec_result(odp_ipsec_op_result_t *result, odp_event_t event) +{ + (void)result; + (void)event; + + return -1; +} + +int odp_ipsec_mtu_update(odp_ipsec_sa_t sa, uint32_t mtu) +{ + (void)sa; + (void)mtu; + + return -1; +} + +void *odp_ipsec_sa_context(odp_ipsec_sa_t sa) +{ + (void)sa; + + return NULL; +} + +uint64_t odp_ipsec_sa_to_u64(odp_ipsec_sa_t sa) +{ + return _odp_pri(sa); +}
commit 73d26f022e59c6e93f09545470d6e2e67eda6e86 Author: Matias Elo matias.elo@nokia.com Date: Thu Jan 12 15:21:15 2017 +0200
validation: ipsec: add test for odp_ipsec_capability()
Signed-off-by: Matias Elo matias.elo@nokia.com 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/m4/configure.m4 b/test/common_plat/m4/configure.m4 index be878bd7..5af86594 100644 --- a/test/common_plat/m4/configure.m4 +++ b/test/common_plat/m4/configure.m4 @@ -16,6 +16,7 @@ AC_CONFIG_FILES([test/common_plat/Makefile test/common_plat/validation/api/errno/Makefile test/common_plat/validation/api/hash/Makefile test/common_plat/validation/api/init/Makefile + test/common_plat/validation/api/ipsec/Makefile test/common_plat/validation/api/lock/Makefile test/common_plat/validation/api/Makefile test/common_plat/validation/api/packet/Makefile diff --git a/test/common_plat/validation/api/Makefile.am b/test/common_plat/validation/api/Makefile.am index e2d30a67..0bab4c4f 100644 --- a/test/common_plat/validation/api/Makefile.am +++ b/test/common_plat/validation/api/Makefile.am @@ -7,6 +7,7 @@ ODP_MODULES = atomic \ errno \ hash \ init \ + ipsec \ lock \ queue \ packet \ diff --git a/test/common_plat/validation/api/ipsec/.gitignore b/test/common_plat/validation/api/ipsec/.gitignore new file mode 100644 index 00000000..2def047f --- /dev/null +++ b/test/common_plat/validation/api/ipsec/.gitignore @@ -0,0 +1 @@ +ipsec_main diff --git a/test/common_plat/validation/api/ipsec/Makefile.am b/test/common_plat/validation/api/ipsec/Makefile.am new file mode 100644 index 00000000..106b8dce --- /dev/null +++ b/test/common_plat/validation/api/ipsec/Makefile.am @@ -0,0 +1,10 @@ +include ../Makefile.inc + +noinst_LTLIBRARIES = libtestipsec.la +libtestipsec_la_SOURCES = ipsec.c + +test_PROGRAMS = ipsec_main$(EXEEXT) +dist_ipsec_main_SOURCES = ipsec_main.c +ipsec_main_LDADD = libtestipsec.la $(LIBCUNIT_COMMON) $(LIBODP) + +EXTRA_DIST = ipsec.h diff --git a/test/common_plat/validation/api/ipsec/ipsec.c b/test/common_plat/validation/api/ipsec/ipsec.c new file mode 100644 index 00000000..78348032 --- /dev/null +++ b/test/common_plat/validation/api/ipsec/ipsec.c @@ -0,0 +1,44 @@ +/* Copyright (c) 2017, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <odp_api.h> +#include <odp_cunit_common.h> +#include <unistd.h> + +#include "ipsec.h" + +void ipsec_test_capability(void) +{ + odp_ipsec_capability_t capa; + + CU_ASSERT(odp_ipsec_capability(&capa) == 0); +} + +odp_testinfo_t ipsec_suite[] = { + ODP_TEST_INFO(ipsec_test_capability), + ODP_TEST_INFO_NULL +}; + +odp_suiteinfo_t ipsec_suites[] = { + {"IPsec", NULL, NULL, ipsec_suite}, + ODP_SUITE_INFO_NULL, +}; + +int ipsec_main(int argc, char *argv[]) +{ + int ret; + + /* parse common options: */ + if (odp_cunit_parse_options(argc, argv)) + return -1; + + ret = odp_cunit_register(ipsec_suites); + + if (ret == 0) + ret = odp_cunit_run(); + + return ret; +} diff --git a/test/common_plat/validation/api/ipsec/ipsec.h b/test/common_plat/validation/api/ipsec/ipsec.h new file mode 100644 index 00000000..290a186f --- /dev/null +++ b/test/common_plat/validation/api/ipsec/ipsec.h @@ -0,0 +1,24 @@ +/* Copyright (c) 2017, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _ODP_TEST_IPSEC_H_ +#define _ODP_TEST_IPSEC_H_ + +#include <odp_cunit_common.h> + +/* test functions: */ +void ipsec_test_capability(void); + +/* test arrays: */ +extern odp_testinfo_t ipsec_suite[]; + +/* test registry: */ +extern odp_suiteinfo_t ipsec_suites[]; + +/* main test program: */ +int ipsec_main(int argc, char *argv[]); + +#endif diff --git a/test/common_plat/validation/api/ipsec/ipsec_main.c b/test/common_plat/validation/api/ipsec/ipsec_main.c new file mode 100644 index 00000000..63a7a55f --- /dev/null +++ b/test/common_plat/validation/api/ipsec/ipsec_main.c @@ -0,0 +1,12 @@ +/* Copyright (c) 2017, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "ipsec.h" + +int main(int argc, char *argv[]) +{ + return ipsec_main(argc, argv); +} diff --git a/test/linux-generic/Makefile.am b/test/linux-generic/Makefile.am index 38516a43..88a9275c 100644 --- a/test/linux-generic/Makefile.am +++ b/test/linux-generic/Makefile.am @@ -20,6 +20,7 @@ TESTS = validation/api/pktio/pktio_run.sh \ $(ALL_API_VALIDATION_DIR)/init/init_main_ok$(EXEEXT) \ $(ALL_API_VALIDATION_DIR)/init/init_main_abort$(EXEEXT) \ $(ALL_API_VALIDATION_DIR)/init/init_main_log$(EXEEXT) \ + $(ALL_API_VALIDATION_DIR)/ipsec/ipsec_main$(EXEEXT) \ $(ALL_API_VALIDATION_DIR)/lock/lock_main$(EXEEXT) \ $(ALL_API_VALIDATION_DIR)/packet/packet_main$(EXEEXT) \ $(ALL_API_VALIDATION_DIR)/pool/pool_main$(EXEEXT) \
commit 9f38efb09731b5f03b2eaf787a066620e778127e Author: Matias Elo matias.elo@nokia.com Date: Thu Jan 12 15:21:14 2017 +0200
linux-gen: ipsec: add capability function
Add IPsec capability function (groundwork for a proper IPsec implementation).
Signed-off-by: Matias Elo matias.elo@nokia.com 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/Makefile.am b/platform/linux-generic/Makefile.am index 22c3247e..12de626c 100644 --- a/platform/linux-generic/Makefile.am +++ b/platform/linux-generic/Makefile.am @@ -176,6 +176,7 @@ __LIB__libodp_linux_la_SOURCES = \ odp_hash.c \ odp_init.c \ odp_impl.c \ + odp_ipsec.c \ odp_name_table.c \ odp_packet.c \ odp_packet_flags.c \ diff --git a/platform/linux-generic/odp_ipsec.c b/platform/linux-generic/odp_ipsec.c new file mode 100644 index 00000000..ce7fded1 --- /dev/null +++ b/platform/linux-generic/odp_ipsec.c @@ -0,0 +1,16 @@ +/* Copyright (c) 2017, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <odp/api/ipsec.h> + +#include <string.h> + +int odp_ipsec_capability(odp_ipsec_capability_t *capa) +{ + memset(capa, 0, sizeof(odp_ipsec_capability_t)); + + return 0; +}
commit 6fb137874e77f2dfdae42d30308dd74bc06118f0 Author: Petri Savolainen petri.savolainen@nokia.com Date: Thu Dec 8 16:25:58 2016 +0200
linux-gen: crypto: add algo capability functions
Implemented cipher and authentication algorithm capability functions.
Signed-off-by: Petri Savolainen petri.savolainen@nokia.com Reviewed-by: Bill Fischofer bill.fischofer@linaro.org Reviewed-by: Balasubramanian Manoharan bala.manoharan@linaro.org Reviewed-by: Nikhil Agarwal nikhil.agarwal@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/platform/linux-generic/odp_crypto.c b/platform/linux-generic/odp_crypto.c index dfeb9f3f..6963ee62 100644 --- a/platform/linux-generic/odp_crypto.c +++ b/platform/linux-generic/odp_crypto.c @@ -656,6 +656,83 @@ int odp_crypto_auth_capability(odp_auth_alg_t auth, return num; }
+int odp_crypto_cipher_capability(odp_cipher_alg_t cipher, + odp_crypto_cipher_capability_t dst[], + int num_copy) +{ + const odp_crypto_cipher_capability_t *src; + int num; + int size = sizeof(odp_crypto_cipher_capability_t); + + switch (cipher) { + case ODP_CIPHER_ALG_NULL: + src = NULL; + num = 0; + break; + case ODP_CIPHER_ALG_DES: + src = cipher_capa_des; + num = sizeof(cipher_capa_des) / size; + break; + case ODP_CIPHER_ALG_3DES_CBC: + src = cipher_capa_trides_cbc; + num = sizeof(cipher_capa_trides_cbc) / size; + break; + case ODP_CIPHER_ALG_AES_CBC: + src = cipher_capa_aes_cbc; + num = sizeof(cipher_capa_aes_cbc) / size; + break; + case ODP_CIPHER_ALG_AES_GCM: + src = cipher_capa_aes_gcm; + num = sizeof(cipher_capa_aes_gcm) / size; + break; + default: + return -1; + } + + if (num < num_copy) + num_copy = num; + + memcpy(dst, src, num_copy * size); + + return num; +} + +int odp_crypto_auth_capability(odp_auth_alg_t auth, + odp_crypto_auth_capability_t dst[], int num_copy) +{ + const odp_crypto_auth_capability_t *src; + int num; + int size = sizeof(odp_crypto_auth_capability_t); + + switch (auth) { + case ODP_AUTH_ALG_NULL: + src = NULL; + num = 0; + break; + case ODP_AUTH_ALG_MD5_HMAC: + src = auth_capa_md5_hmac; + num = sizeof(auth_capa_md5_hmac) / size; + break; + case ODP_AUTH_ALG_SHA256_HMAC: + src = auth_capa_sha256_hmac; + num = sizeof(auth_capa_sha256_hmac) / size; + break; + case ODP_AUTH_ALG_AES_GCM: + src = auth_capa_aes_gcm; + num = sizeof(auth_capa_aes_gcm) / size; + break; + default: + return -1; + } + + if (num < num_copy) + num_copy = num; + + memcpy(dst, src, num_copy * size); + + return num; +} + int odp_crypto_session_create(odp_crypto_session_param_t *param, odp_crypto_session_t *session_out,
commit d41e230e73243cbd63902dce005889581b23085b Author: Christophe Milard christophe.milard@linaro.org Date: Fri Aug 19 17:10:12 2016 +0200
doc: application-api-guide: excluding drv interface
The input files parsed to generate the ODP platform specific API doc included (wrongly) part of the drv interface specification. This led to warning on undefined symbols. Fixed by restricting imput files to API only.
Signed-off-by: Christophe Milard christophe.milard@linaro.org Reviewed-by: Bill Fischofer bill.fischofer@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/doc/platform-api-guide/Doxyfile b/doc/platform-api-guide/Doxyfile index 12d356e3..1f2d49a4 100644 --- a/doc/platform-api-guide/Doxyfile +++ b/doc/platform-api-guide/Doxyfile @@ -5,9 +5,9 @@ PROJECT_NUMBER = $(VERSION) PROJECT_LOGO = $(SRCDIR)/doc/images/ODP-Logo-HQ.svg INPUT = $(SRCDIR)/doc/application-api-guide \ $(SRCDIR)/doc/platform-api-guide \ - $(SRCDIR)/include \ + $(SRCDIR)/include/odp/api \ $(SRCDIR)/platform/$(WITH_PLATFORM)/doc \ - $(SRCDIR)/platform/$(WITH_PLATFORM)/include/odp \ + $(SRCDIR)/platform/$(WITH_PLATFORM)/include/odp/api \ $(SRCDIR)/platform/$(WITH_PLATFORM)/arch/$(WITH_ARCH) EXAMPLE_PATH = $(SRCDIR)/example $(SRCDIR)/platform $(SRCDIR) PREDEFINED = __GNUC__ \
commit db72c685127c33e3f34c6b49ef053335849990cf Author: Petri Savolainen petri.savolainen@linaro.org Date: Thu Mar 30 16:58:53 2017 +0300
api: hints: remove ODP_DEPRECATED from API
Remove ODP_DEPRECATED macro as it depends on (GCC) compiler type attribute, which may not be supported (the same way) by all compilers. Also the attribute works only for types, but not e.g. for fields of structure.
A new configuration option will be added to control deprecated definitions.
Signed-off-by: Petri Savolainen petri.savolainen@linaro.org Reviewed-by: Dmitry Eremin-Solenikov dmitry.ereminsolenikov@linaro.org Reviewed-by: Bill Fischofer bill.fischofer@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/include/odp/api/spec/hints.h b/include/odp/api/spec/hints.h index 82400f07..7434c6a5 100644 --- a/include/odp/api/spec/hints.h +++ b/include/odp/api/spec/hints.h @@ -52,11 +52,6 @@ extern "C" { #define ODP_PRINTF_FORMAT(x, y) __attribute__((format(printf, (x), (y))))
/** - * Indicate deprecated variables, functions or types - */ -#define ODP_DEPRECATED __attribute__((__deprecated__)) - -/** * Intentionally unused variables of functions */ #define ODP_UNUSED __attribute__((__unused__)) @@ -96,7 +91,6 @@ extern "C" { #define ODP_WEAK_SYMBOL #define ODP_HOT_CODE #define ODP_COLD_CODE -#define ODP_DEPRECATED #define ODP_UNUSED #define odp_likely(x) #define odp_unlikely(x)
commit 40c3619a6ce16b0e7521b649a9625e98aee85160 Author: Petri Savolainen petri.savolainen@linaro.org Date: Thu Mar 30 16:58:55 2017 +0300
test: crypto: remove references to deprecated crypto apis
Remove last remaining references to deprecated API definitions.
Signed-off-by: Petri Savolainen petri.savolainen@linaro.org Reviewed-by: Dmitry Eremin-Solenikov dmitry.ereminsolenikov@linaro.org Reviewed-by: Bill Fischofer bill.fischofer@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/example/ipsec/odp_ipsec_misc.h b/example/ipsec/odp_ipsec_misc.h index e0320eb4..45cb022e 100644 --- a/example/ipsec/odp_ipsec_misc.h +++ b/example/ipsec/odp_ipsec_misc.h @@ -98,10 +98,10 @@ int parse_key_string(char *keystring, key->length = key_bits_in / 8;
} else { - if ((alg->u.auth == ODP_AUTH_ALG_MD5_96) && + if ((alg->u.auth == ODP_AUTH_ALG_MD5_HMAC) && (KEY_BITS_MD5_96 == key_bits_in)) key->length = key_bits_in / 8; - else if ((alg->u.auth == ODP_AUTH_ALG_SHA256_128) && + else if ((alg->u.auth == ODP_AUTH_ALG_SHA256_HMAC) && (KEY_BITS_SHA256_128 == key_bits_in)) key->length = key_bits_in / 8; } diff --git a/example/ipsec/odp_ipsec_sa_db.c b/example/ipsec/odp_ipsec_sa_db.c index 28215b5b..10bbcb8f 100644 --- a/example/ipsec/odp_ipsec_sa_db.c +++ b/example/ipsec/odp_ipsec_sa_db.c @@ -111,11 +111,11 @@ int create_sa_db_entry(char *input, odp_bool_t cipher) } else { if (0 == strcmp(token, "md5")) { entry->alg.u.auth = - ODP_AUTH_ALG_MD5_96; + ODP_AUTH_ALG_MD5_HMAC; entry->icv_len = 12; } else if (!strcmp(token, "sha256")) { entry->alg.u.auth = - ODP_AUTH_ALG_SHA256_128; + ODP_AUTH_ALG_SHA256_HMAC; entry->icv_len = 16; } else { entry->alg.u.auth = ODP_AUTH_ALG_NULL; diff --git a/example/ipsec/odp_ipsec_stream.c b/example/ipsec/odp_ipsec_stream.c index 428ec04d..15087cbe 100644 --- a/example/ipsec/odp_ipsec_stream.c +++ b/example/ipsec/odp_ipsec_stream.c @@ -227,8 +227,8 @@ odp_packet_t create_ipv4_packet(stream_db_entry_t *stream, /* AH (if specified) */ if (entry && (entry == stream->input.entry) && (ODP_AUTH_ALG_NULL != entry->ah.alg)) { - if (entry->ah.alg != ODP_AUTH_ALG_MD5_96 && - entry->ah.alg != ODP_AUTH_ALG_SHA256_128) + if (entry->ah.alg != ODP_AUTH_ALG_MD5_HMAC && + entry->ah.alg != ODP_AUTH_ALG_SHA256_HMAC) abort();
ah = (odph_ahhdr_t *)data; @@ -424,7 +424,7 @@ odp_bool_t verify_ipv4_packet(stream_db_entry_t *stream, return FALSE; if (odp_be_to_cpu_32(ah->spi) != entry->ah.spi) return FALSE; - if (ODP_AUTH_ALG_MD5_96 != entry->ah.alg) + if (ODP_AUTH_ALG_MD5_HMAC != entry->ah.alg) abort(); } else { if (entry && (ODP_AUTH_ALG_NULL != entry->ah.alg)) diff --git a/test/common_plat/performance/odp_crypto.c b/test/common_plat/performance/odp_crypto.c index 954bdb79..b3857973 100644 --- a/test/common_plat/performance/odp_crypto.c +++ b/test/common_plat/performance/odp_crypto.c @@ -205,7 +205,7 @@ static crypto_alg_config_t algs_config[] = { .data = test_iv, .length = 8, }, - .auth_alg = ODP_AUTH_ALG_MD5_96, + .auth_alg = ODP_AUTH_ALG_MD5_HMAC, .auth_key = { .data = test_key16, .length = sizeof(test_key16) @@ -217,7 +217,7 @@ static crypto_alg_config_t algs_config[] = { .name = "null-hmac-md5-96", .session = { .cipher_alg = ODP_CIPHER_ALG_NULL, - .auth_alg = ODP_AUTH_ALG_MD5_96, + .auth_alg = ODP_AUTH_ALG_MD5_HMAC, .auth_key = { .data = test_key16, .length = sizeof(test_key16)
commit 7ec1d26bf7307f300b1aad331535f601b63522b1 Author: Petri Savolainen petri.savolainen@linaro.org Date: Thu Mar 30 16:58:54 2017 +0300
api: deprecated: add configure option and macros
Added configuration option --enable-deprecated to control if deprecated APIs are enabled or disabled.
Added ODP_DEPRECATED_API macro into the API. Its value can be used to check if deprecated API definitions are enabled or disabled. Deprecated APIs are disabled by default. Deprecated APIs are meant to be removed completely in a later API version.
Added ODP_DEPRECATE() macro to enforce deprecation of API definitions. When deprecated APIs are disabled, the macro renames API definitions so that application cannot use those any more, but a single implementation library can serve applications built with both options.
Signed-off-by: Petri Savolainen petri.savolainen@linaro.org Reviewed-by: Dmitry Eremin-Solenikov dmitry.ereminsolenikov@linaro.org Reviewed-by: Bill Fischofer bill.fischofer@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/configure.ac b/configure.ac index 7569ebe0..0743f761 100644 --- a/configure.ac +++ b/configure.ac @@ -16,7 +16,8 @@ ODP_VERSION_API_MAJOR=odpapi_major_version AC_SUBST(ODP_VERSION_API_MAJOR) ODP_VERSION_API_MINOR=odpapi_minor_version AC_SUBST(ODP_VERSION_API_MINOR) -AC_CONFIG_FILES([include/odp/api/spec/version.h]) +AC_CONFIG_FILES([include/odp/api/spec/version.h + include/odp/api/spec/deprecated.h])
AM_INIT_AUTOMAKE([1.9 tar-pax subdir-objects]) AC_CONFIG_SRCDIR([helper/config.h.in]) @@ -283,7 +284,7 @@ ODP_CFLAGS="$ODP_CFLAGS -DODP_DEBUG=$ODP_DEBUG" ODP_ABI_COMPAT=1 abi_compat=yes AC_ARG_ENABLE([abi-compat], - [ --disable-abi-compat disables ABI compatible mode, enables inline code in header files], + [ --disable-abi-compat disables ABI compatible mode, enables inline code in header files], [if test "x$enableval" = "xno"; then ODP_ABI_COMPAT=0 abi_compat=no @@ -293,6 +294,19 @@ AC_ARG_ENABLE([abi-compat], AC_SUBST(ODP_ABI_COMPAT)
########################################################################## +# Enable/disable deprecated API definitions +########################################################################## +ODP_DEPRECATED_API=0 +deprecated=no +AC_ARG_ENABLE([deprecated], + [ --enable-deprecated enable deprecated API definitions], + [if test "x$enableval" = "xyes"; then + ODP_DEPRECATED_API=1 + deprecated=yes + fi]) +AC_SUBST(ODP_DEPRECATED_API) + +########################################################################## # Default warning setup ########################################################################## ODP_CFLAGS="$ODP_CFLAGS -W -Wall -Werror -Wstrict-prototypes -Wmissing-prototypes" @@ -382,6 +396,7 @@ AC_MSG_RESULT([ static libraries: ${enable_static} shared libraries: ${enable_shared} ABI compatible: ${abi_compat} + Deprecated APIs: ${deprecated} cunit: ${cunit_support} test_vald: ${test_vald} test_perf: ${test_perf} diff --git a/doc/application-api-guide/api_guide_lines.dox b/doc/application-api-guide/api_guide_lines.dox index 394e9582..a6488c32 100644 --- a/doc/application-api-guide/api_guide_lines.dox +++ b/doc/application-api-guide/api_guide_lines.dox @@ -75,7 +75,7 @@ The former is a compile-time assertion and hence adds no additional path length. The latter is controlled by the ODP_NO_DEBUG compile-time switch and so is suitable for use in development/debug builds that can be compiled out for production use. Other mechanisms available to the implementer are: - ODP_ABORT() is provided for situations where further execution of the code must not occur and a level of tracing information should be left in the log. - - ODP_DEPRECATED() is used to signify that a call is planned for obsolescence. + - ODP_DEPRECATE() is used to signify that a call is planned for obsolescence. - ODP_LOG() is used to direct implementation messages to the application.
@@ -197,8 +197,8 @@ This is one of the reasons why some features MAY be defined as OPTIONAL. While allowed, the proliferation of OPTIONAL features SHOULD be avoided to enable broad application portability across many implementations. At the same time, a "least common denominator" approach MUST NOT be taken as that defeats the purpose of providing higher-level abstractions in APIs.
-@subsection odp_deprecated ODP DEPRECATED -A deprecated API will remain marked as such in the public API using #ODP_DEPRECATED for two release cycles for the #ODP_VERSION_API_MAJOR number. +@subsection odp_deprecate ODP DEPRECATE +A deprecated API will remain marked as such in the public API using #ODP_DEPRECATE() for two release cycles for the #ODP_VERSION_API_MAJOR number. For example an API marked as deprecated in 1.1.0 will still be present in 1.2.0 and removed in 1.3.0. A deprecated API will contain the doxygen tag @deprecated with a description of the reason for the change.
diff --git a/doc/platform-api-guide/Doxyfile b/doc/platform-api-guide/Doxyfile index 93f6edfe..12d356e3 100644 --- a/doc/platform-api-guide/Doxyfile +++ b/doc/platform-api-guide/Doxyfile @@ -17,4 +17,5 @@ PREDEFINED = __GNUC__ \ __LITTLE_ENDIAN_BITFIELD \ __x86_64__ \ ODP_PACKED \ + ODP_DEPRECATE(x)=x \ "ODP_HANDLE_T(type)=odp_handle_t type" diff --git a/doc/process-guide/release-guide.adoc b/doc/process-guide/release-guide.adoc index 8ea147af..595af91a 100644 --- a/doc/process-guide/release-guide.adoc +++ b/doc/process-guide/release-guide.adoc @@ -251,7 +251,7 @@ Deleting or changing the published API follows the normal <<anchor-1,process>>, * A deprecated indication is applied to the old API using the @deprecated doxygen syntax. * For a function change the old API it is additionally marked using the -ODP_DEPRECATED preprocessor macro. +ODP_DEPRECATE() preprocessor macro. * The CHANGELOG will have an entry in the API change section. * The Release Manager will resolve the duration for which the deprecated API. will be supported, and determine which future release it will be applied to. + @@ -275,7 +275,7 @@ The new API must have comparable coverage to the old API. * * @param name ... */ -odp_foo_t odp_foo_create(const char *name) ODP_DEPRECATED; +odp_foo_t ODP_DEPRECATE(odp_foo_create)(const char *name);
/** * Create a bar @@ -298,7 +298,7 @@ compiler warning. * * @param name ... */ -odp_foo_t odp_foo_create(const char *name) ODP_DEPRECATED; +odp_foo_t ODP_DEPRECATE(odp_foo_create)(const char *name); ----
=== Changing a struct member diff --git a/include/odp/api/spec/.gitignore b/include/odp/api/spec/.gitignore index 67020331..df9c87d9 100644 --- a/include/odp/api/spec/.gitignore +++ b/include/odp/api/spec/.gitignore @@ -1 +1,2 @@ +deprecated.h version.h diff --git a/include/odp/api/spec/deprecated.h.in b/include/odp/api/spec/deprecated.h.in new file mode 100644 index 00000000..224f60ff --- /dev/null +++ b/include/odp/api/spec/deprecated.h.in @@ -0,0 +1,50 @@ +/* Copyright (c) 2017, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @file + * + * Macro for deprecated API definitions + */ + +#ifndef ODP_API_DEPRECATED_H_ +#define ODP_API_DEPRECATED_H_ +#include <odp/visibility_begin.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Deprecated API definitions + * + * Some API definitions may be deprecated by this or a previous API version. + * This macro controls if those are enabled (and visible to the application) + * or disabled. + * + * * 0: Deprecated API definitions are disabled (default) + * * 1: Deprecated API definitions are enabled + */ +#define ODP_DEPRECATED_API @ODP_DEPRECATED_API@ + +/** + * @def ODP_DEPRECATE + * + * Macro to deprecate API definitions + */ + +#if ODP_DEPRECATED_API +#define ODP_DEPRECATE(x) x +#else +#define ODP_DEPRECATE(x) _deprecated_ ## x +#endif + +#ifdef __cplusplus +} +#endif + +#include <odp/visibility_end.h> +#endif diff --git a/include/odp_api.h b/include/odp_api.h index ec7fcd2e..060ec888 100644 --- a/include/odp_api.h +++ b/include/odp_api.h @@ -18,6 +18,7 @@ extern "C" { #endif
+#include <odp/api/deprecated.h> #include <odp/api/version.h> #include <odp/api/std_types.h> #include <odp/api/compiler.h> diff --git a/platform/Makefile.inc b/platform/Makefile.inc index 7059d910..59a57724 100644 --- a/platform/Makefile.inc +++ b/platform/Makefile.inc @@ -29,6 +29,7 @@ odpapispecinclude_HEADERS = \ $(top_srcdir)/include/odp/api/spec/cpumask.h \ $(top_srcdir)/include/odp/api/spec/crypto.h \ $(top_srcdir)/include/odp/api/spec/debug.h \ + $(top_srcdir)/include/odp/api/spec/deprecated.h \ $(top_srcdir)/include/odp/api/spec/errno.h \ $(top_srcdir)/include/odp/api/spec/event.h \ $(top_srcdir)/include/odp/api/spec/hash.h \ diff --git a/platform/linux-generic/Makefile.am b/platform/linux-generic/Makefile.am index 69fdf8b9..22c3247e 100644 --- a/platform/linux-generic/Makefile.am +++ b/platform/linux-generic/Makefile.am @@ -33,6 +33,7 @@ odpapiinclude_HEADERS = \ $(srcdir)/include/odp/api/cpumask.h \ $(srcdir)/include/odp/api/crypto.h \ $(srcdir)/include/odp/api/debug.h \ + $(srcdir)/include/odp/api/deprecated.h \ $(srcdir)/include/odp/api/errno.h \ $(srcdir)/include/odp/api/event.h \ $(srcdir)/include/odp/api/hash.h \ diff --git a/platform/linux-generic/include/odp/api/deprecated.h b/platform/linux-generic/include/odp/api/deprecated.h new file mode 100644 index 00000000..82797ebc --- /dev/null +++ b/platform/linux-generic/include/odp/api/deprecated.h @@ -0,0 +1,26 @@ +/* Copyright (c) 2017, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @file + * + * Control deprecated API definitions + */ + +#ifndef ODP_PLAT_DEPRECATED_H_ +#define ODP_PLAT_DEPRECATED_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/spec/deprecated.h> + +#ifdef __cplusplus +} +#endif + +#endif
commit b1f25eafa5b29ed21a87eecbc125a71ca38ed40b Author: Dmitry Eremin-Solenikov dmitry.ereminsolenikov@linaro.org Date: Thu May 4 14:30:50 2017 +0300
api: packet: introduce odp_packet_data_range_t
Rename odp_crypto_data_range_t to odp_packet_data_range_t, as it is relevant not only to the crypto interface.
Signed-off-by: Dmitry Eremin-Solenikov dmitry.ereminsolenikov@linaro.org Reviewed-by: Petri Savolainen petri.savolainen@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/include/odp/api/spec/crypto.h b/include/odp/api/spec/crypto.h index 1f83e819..c47d3149 100644 --- a/include/odp/api/spec/crypto.h +++ b/include/odp/api/spec/crypto.h @@ -21,6 +21,8 @@ extern "C" { #endif
+#include <odp/api/packet.h> + /** @defgroup odp_crypto ODP CRYPTO * Macros, enums, types and operations to utilise crypto. * @{ @@ -243,15 +245,10 @@ typedef struct odp_crypto_iv {
/** * Crypto API data range specifier + * + * @deprecated Use odp_packet_data_range_t instead */ -typedef struct odp_crypto_data_range { - /** Offset from beginning of packet */ - uint32_t offset; - - /** Length of data to operate on */ - uint32_t length; - -} odp_crypto_data_range_t; +typedef odp_packet_data_range_t ODP_DEPRECATE(odp_crypto_data_range_t);
/** * Crypto API session creation parameters @@ -386,10 +383,10 @@ typedef struct odp_crypto_op_param_t { } aad;
/** Data range to apply cipher */ - odp_crypto_data_range_t cipher_range; + odp_packet_data_range_t cipher_range;
/** Data range to authenticate */ - odp_crypto_data_range_t auth_range; + odp_packet_data_range_t auth_range;
} odp_crypto_op_param_t;
diff --git a/include/odp/api/spec/packet.h b/include/odp/api/spec/packet.h index 92c35ae6..79d8773e 100644 --- a/include/odp/api/spec/packet.h +++ b/include/odp/api/spec/packet.h @@ -71,6 +71,18 @@ extern "C" { * Packet is red */
+/** + * Packet API data range specifier + */ +typedef struct odp_packet_data_range { + /** Offset from beginning of packet */ + uint32_t offset; + + /** Length of data to operate on */ + uint32_t length; + +} odp_packet_data_range_t; + /* * * Alloc and free diff --git a/test/common_plat/validation/api/crypto/odp_crypto_test_inp.c b/test/common_plat/validation/api/crypto/odp_crypto_test_inp.c index a415f5c1..57e7c0e0 100644 --- a/test/common_plat/validation/api/crypto/odp_crypto_test_inp.c +++ b/test/common_plat/validation/api/crypto/odp_crypto_test_inp.c @@ -72,8 +72,8 @@ static void alg_test(odp_crypto_op_t op, odp_crypto_key_t cipher_key, odp_auth_alg_t auth_alg, odp_crypto_key_t auth_key, - odp_crypto_data_range_t *cipher_range, - odp_crypto_data_range_t *auth_range, + odp_packet_data_range_t *cipher_range, + odp_packet_data_range_t *auth_range, const uint8_t *plaintext, unsigned int plaintext_len, const uint8_t *ciphertext, diff --git a/test/common_plat/validation/api/crypto/test_vectors.h b/test/common_plat/validation/api/crypto/test_vectors.h index da4610f3..a1cf4faf 100644 --- a/test/common_plat/validation/api/crypto/test_vectors.h +++ b/test/common_plat/validation/api/crypto/test_vectors.h @@ -139,14 +139,14 @@ static uint8_t aes128_gcm_reference_iv[][AES128_GCM_IV_LEN] = {
static uint32_t aes128_gcm_reference_length[] = { 84, 72, 72, 40};
-static odp_crypto_data_range_t aes128_gcm_cipher_range[] = { +static odp_packet_data_range_t aes128_gcm_cipher_range[] = { { .offset = 12, .length = 72 }, { .offset = 8, .length = 64 }, { .offset = 8, .length = 64 }, { .offset = 12, .length = 28 }, };
-static odp_crypto_data_range_t aes128_gcm_auth_range[] = { +static odp_packet_data_range_t aes128_gcm_auth_range[] = { { .offset = 0, .length = 84 }, { .offset = 0, .length = 72 }, { .offset = 0, .length = 72 },
commit 36c39aa5a8bcbeb9bf153f6ba91fc1f569c78e72 Author: Petri Savolainen petri.savolainen@linaro.org Date: Thu May 4 15:55:57 2017 +0300
api: crypto: add AAD operation parameters
Authentication capabilities list supported AAD lengths per algorithm, but application did not have means to select which length is used. Also pointer to AAD is added, since it may be constructed also outside of packet data.
Signed-off-by: Petri Savolainen petri.savolainen@linaro.org Reviewed-by: Dmitry Eremin-Solenikov dmitry.ereminsolenikov@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/include/odp/api/spec/crypto.h b/include/odp/api/spec/crypto.h index 76977204..1f83e819 100644 --- a/include/odp/api/spec/crypto.h +++ b/include/odp/api/spec/crypto.h @@ -375,6 +375,16 @@ typedef struct odp_crypto_op_param_t { */ uint32_t hash_result_offset;
+ /** Additional Authenticated Data (AAD) */ + struct { + /** Pointer to ADD */ + uint8_t *ptr; + + /** AAD length in bytes. Use odp_crypto_auth_capa() for + * supported AAD lengths. */ + uint32_t length; + } aad; + /** Data range to apply cipher */ odp_crypto_data_range_t cipher_range;
commit a3dce4d2b259ce80f7cdaf0115b13f315353d358 Author: Petri Savolainen petri.savolainen@linaro.org Date: Thu May 4 15:55:56 2017 +0300
api: crypto: add digest length session parameter
Authentication capabilities list supported digest lengths per algorithm, but application did not have means to select which length is used.
Signed-off-by: Petri Savolainen petri.savolainen@linaro.org Reviewed-by: Dmitry Eremin-Solenikov dmitry.ereminsolenikov@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/include/odp/api/spec/crypto.h b/include/odp/api/spec/crypto.h index 181c0cc4..76977204 100644 --- a/include/odp/api/spec/crypto.h +++ b/include/odp/api/spec/crypto.h @@ -299,10 +299,16 @@ typedef struct odp_crypto_session_param_t {
/** Authentication key * - * Use odp_crypto_auth_capa() for supported digest and key lengths. + * Use odp_crypto_auth_capa() for supported key lengths. */ odp_crypto_key_t auth_key;
+ /** Authentication digest length in bytes + * + * Use odp_crypto_auth_capa() for supported digest lengths. + */ + uint32_t auth_digest_len; + /** Async mode completion event queue * * When odp_crypto_operation() is asynchronous, the completion queue is
commit db181a6eca25a99aa07128a0e4d984eaee1372a9 Author: Petri Savolainen petri.savolainen@linaro.org Date: Thu Mar 30 16:58:56 2017 +0300
api: crypto: enforce deprecated API status
Used ODP_DEPRECATE() to control if deprecated API definitions are visible in the API or not.
Signed-off-by: Petri Savolainen petri.savolainen@linaro.org Reviewed-by: Dmitry Eremin-Solenikov dmitry.ereminsolenikov@linaro.org Reviewed-by: Bill Fischofer bill.fischofer@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/include/odp/api/spec/crypto.h b/include/odp/api/spec/crypto.h index d30f050f..181c0cc4 100644 --- a/include/odp/api/spec/crypto.h +++ b/include/odp/api/spec/crypto.h @@ -15,6 +15,8 @@ #define ODP_API_CRYPTO_H_ #include <odp/visibility_begin.h>
+#include <odp/api/deprecated.h> + #ifdef __cplusplus extern "C" { #endif @@ -82,10 +84,10 @@ typedef enum { ODP_CIPHER_ALG_AES_GCM,
/** @deprecated Use ODP_CIPHER_ALG_AES_CBC instead */ - ODP_CIPHER_ALG_AES128_CBC, + ODP_DEPRECATE(ODP_CIPHER_ALG_AES128_CBC),
/** @deprecated Use ODP_CIPHER_ALG_AES_GCM instead */ - ODP_CIPHER_ALG_AES128_GCM + ODP_DEPRECATE(ODP_CIPHER_ALG_AES128_GCM)
} odp_cipher_alg_t;
@@ -127,13 +129,14 @@ typedef enum { ODP_AUTH_ALG_AES_GCM,
/** @deprecated Use ODP_AUTH_ALG_MD5_HMAC instead */ - ODP_AUTH_ALG_MD5_96, + ODP_DEPRECATE(ODP_AUTH_ALG_MD5_96),
/** @deprecated Use ODP_AUTH_ALG_SHA256_HMAC instead */ - ODP_AUTH_ALG_SHA256_128, + ODP_DEPRECATE(ODP_AUTH_ALG_SHA256_128),
/** @deprecated Use ODP_AUTH_ALG_AES_GCM instead */ - ODP_AUTH_ALG_AES128_GCM + ODP_DEPRECATE(ODP_AUTH_ALG_AES128_GCM) + } odp_auth_alg_t;
/** @@ -158,10 +161,11 @@ typedef union odp_crypto_cipher_algos_t { uint32_t aes_gcm : 1;
/** @deprecated Use aes_cbc instead */ - uint32_t aes128_cbc : 1; + uint32_t ODP_DEPRECATE(aes128_cbc) : 1;
/** @deprecated Use aes_gcm instead */ - uint32_t aes128_gcm : 1; + uint32_t ODP_DEPRECATE(aes128_gcm) : 1; + } bit;
/** All bits of the bit field structure @@ -196,13 +200,14 @@ typedef union odp_crypto_auth_algos_t { uint32_t aes_gcm : 1;
/** @deprecated Use md5_hmac instead */ - uint32_t md5_96 : 1; + uint32_t ODP_DEPRECATE(md5_96) : 1;
/** @deprecated Use sha256_hmac instead */ - uint32_t sha256_128 : 1; + uint32_t ODP_DEPRECATE(sha256_128) : 1;
/** @deprecated Use aes_gcm instead */ - uint32_t aes128_gcm : 1; + uint32_t ODP_DEPRECATE(aes128_gcm) : 1; + } bit;
/** All bits of the bit field structure @@ -317,7 +322,7 @@ typedef struct odp_crypto_session_param_t { } odp_crypto_session_param_t;
/** @deprecated Use odp_crypto_session_param_t instead */ -typedef odp_crypto_session_param_t odp_crypto_session_params_t; +typedef odp_crypto_session_param_t ODP_DEPRECATE(odp_crypto_session_params_t);
/** * Crypto API per packet operation parameters @@ -373,7 +378,7 @@ typedef struct odp_crypto_op_param_t { } odp_crypto_op_param_t;
/** @deprecated Use odp_crypto_op_param_t instead */ -typedef odp_crypto_op_param_t odp_crypto_op_params_t; +typedef odp_crypto_op_param_t ODP_DEPRECATE(odp_crypto_op_params_t);
/** * Crypto API session creation return code diff --git a/platform/linux-generic/odp_crypto.c b/platform/linux-generic/odp_crypto.c index de67ad36..dfeb9f3f 100644 --- a/platform/linux-generic/odp_crypto.c +++ b/platform/linux-generic/odp_crypto.c @@ -566,12 +566,13 @@ int odp_crypto_capability(odp_crypto_capability_t *capa) capa->auths.bit.sha512_hmac = 0; capa->auths.bit.aes_gcm = 1;
- /* Deprecated */ +#if ODP_DEPRECATED_API capa->ciphers.bit.aes128_cbc = 1; capa->ciphers.bit.aes128_gcm = 1; capa->auths.bit.md5_96 = 1; capa->auths.bit.sha256_128 = 1; capa->auths.bit.aes128_gcm = 1; +#endif
capa->max_sessions = MAX_SESSIONS;
@@ -662,6 +663,7 @@ odp_crypto_session_create(odp_crypto_session_param_t *param, { int rc; odp_crypto_generic_session_t *session; + int aes_gcm = 0;
/* Default to successful result */ *status = ODP_CRYPTO_SES_CREATE_ERR_NONE; @@ -705,17 +707,21 @@ odp_crypto_session_create(odp_crypto_session_param_t *param, rc = process_des_param(session); break; case ODP_CIPHER_ALG_AES_CBC: - /* deprecated */ +#if ODP_DEPRECATED_API case ODP_CIPHER_ALG_AES128_CBC: +#endif rc = process_aes_param(session); break; - case ODP_CIPHER_ALG_AES_GCM: - /* deprecated */ +#if ODP_DEPRECATED_API case ODP_CIPHER_ALG_AES128_GCM: + if (param->auth_alg == ODP_AUTH_ALG_AES128_GCM) + aes_gcm = 1; + /* Fallthrough */ +#endif + case ODP_CIPHER_ALG_AES_GCM: /* AES-GCM requires to do both auth and * cipher at the same time */ - if (param->auth_alg == ODP_AUTH_ALG_AES_GCM || - param->auth_alg == ODP_AUTH_ALG_AES128_GCM) + if (param->auth_alg == ODP_AUTH_ALG_AES_GCM || aes_gcm) rc = process_aes_gcm_param(session); else rc = -1; @@ -731,6 +737,8 @@ odp_crypto_session_create(odp_crypto_session_param_t *param, return -1; }
+ aes_gcm = 0; + /* Process based on auth */ switch (param->auth_alg) { case ODP_AUTH_ALG_NULL: @@ -738,22 +746,27 @@ odp_crypto_session_create(odp_crypto_session_param_t *param, rc = 0; break; case ODP_AUTH_ALG_MD5_HMAC: - /* deprecated */ +#if ODP_DEPRECATED_API case ODP_AUTH_ALG_MD5_96: +#endif rc = process_auth_param(session, 96, 16, EVP_md5()); break; case ODP_AUTH_ALG_SHA256_HMAC: - /* deprecated */ +#if ODP_DEPRECATED_API case ODP_AUTH_ALG_SHA256_128: +#endif rc = process_auth_param(session, 128, 32, EVP_sha256()); break; - case ODP_AUTH_ALG_AES_GCM: - /* deprecated */ +#if ODP_DEPRECATED_API case ODP_AUTH_ALG_AES128_GCM: + if (param->cipher_alg == ODP_CIPHER_ALG_AES128_GCM) + aes_gcm = 1; + /* Fallthrough */ +#endif + case ODP_AUTH_ALG_AES_GCM: /* AES-GCM requires to do both auth and * cipher at the same time */ - if (param->cipher_alg == ODP_CIPHER_ALG_AES_GCM || - param->cipher_alg == ODP_CIPHER_ALG_AES128_GCM) { + if (param->cipher_alg == ODP_CIPHER_ALG_AES_GCM || aes_gcm) { session->auth.func = null_crypto_routine; rc = 0; } else { @@ -779,10 +792,14 @@ odp_crypto_session_create(odp_crypto_session_param_t *param, int odp_crypto_session_destroy(odp_crypto_session_t session) { odp_crypto_generic_session_t *generic; + int aes_gcm = 0;
generic = (odp_crypto_generic_session_t *)(intptr_t)session; - if (generic->p.cipher_alg == ODP_CIPHER_ALG_AES128_GCM || - generic->p.cipher_alg == ODP_CIPHER_ALG_AES_GCM) +#if ODP_DEPRECATED_API + if (generic->p.cipher_alg == ODP_CIPHER_ALG_AES128_GCM) + aes_gcm = 1; +#endif + if (generic->p.cipher_alg == ODP_CIPHER_ALG_AES_GCM || aes_gcm) EVP_CIPHER_CTX_free(generic->cipher.data.aes_gcm.ctx); memset(generic, 0, sizeof(*generic)); free_session(generic);
commit f4504d7c1e3ce5f92b7c68c0b93b288bcd018e04 Author: Petri Savolainen petri.savolainen@linaro.org Date: Wed Feb 22 17:08:24 2017 +0200
linux-gen: crypto: sha-1 and sha-512 not implemented yet
Explicitly set capabilities to zero.
Signed-off-by: Petri Savolainen petri.savolainen@linaro.org Reviewed-by: Dmitry Eremin-Solenikov dmitry.ereminsolenikov@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/platform/linux-generic/odp_crypto.c b/platform/linux-generic/odp_crypto.c index c5473d95..de67ad36 100644 --- a/platform/linux-generic/odp_crypto.c +++ b/platform/linux-generic/odp_crypto.c @@ -561,7 +561,9 @@ int odp_crypto_capability(odp_crypto_capability_t *capa)
capa->auths.bit.null = 1; capa->auths.bit.md5_hmac = 1; + capa->auths.bit.sha1_hmac = 0; capa->auths.bit.sha256_hmac = 1; + capa->auths.bit.sha512_hmac = 0; capa->auths.bit.aes_gcm = 1;
/* Deprecated */
commit c0aaad8e02f277b40bd8deaaadae8bf122ea6657 Author: Petri Savolainen petri.savolainen@linaro.org Date: Wed Feb 22 17:08:23 2017 +0200
api: crypto: add sha-1 and sha-512 enumerations
Added enumerations for HMAC-SHA-1 and HMAC-SHA-256 authentication algorithms.
Signed-off-by: Petri Savolainen petri.savolainen@linaro.org Reviewed-by: Dmitry Eremin-Solenikov dmitry.ereminsolenikov@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/include/odp/api/spec/crypto.h b/include/odp/api/spec/crypto.h index 9855bf98..d30f050f 100644 --- a/include/odp/api/spec/crypto.h +++ b/include/odp/api/spec/crypto.h @@ -102,12 +102,24 @@ typedef enum { */ ODP_AUTH_ALG_MD5_HMAC,
+ /** HMAC-SHA-1 + * + * SHA-1 algorithm in HMAC mode + */ + ODP_AUTH_ALG_SHA1_HMAC, + /** HMAC-SHA-256 * * SHA-256 algorithm in HMAC mode */ ODP_AUTH_ALG_SHA256_HMAC,
+ /** HMAC-SHA-512 + * + * SHA-512 algorithm in HMAC mode + */ + ODP_AUTH_ALG_SHA512_HMAC, + /** AES in Galois/Counter Mode * * @note Must be paired with cipher ODP_CIPHER_ALG_AES_GCM @@ -171,9 +183,15 @@ typedef union odp_crypto_auth_algos_t { /** ODP_AUTH_ALG_MD5_HMAC */ uint32_t md5_hmac : 1;
+ /** ODP_AUTH_ALG_SHA1_HMAC */ + uint32_t sha1_hmac : 1; + /** ODP_AUTH_ALG_SHA256_HMAC */ uint32_t sha256_hmac : 1;
+ /** ODP_AUTH_ALG_SHA512_HMAC */ + uint32_t sha512_hmac : 1; + /** ODP_AUTH_ALG_AES_GCM */ uint32_t aes_gcm : 1;
commit 033cd2a5c7c7dbc325d792c8e91389af7aa2eef0 Author: Petri Savolainen petri.savolainen@linaro.org Date: Wed Feb 22 17:08:22 2017 +0200
abi: event: add ODP_EVENT_IPSEC_RESULT
Update ABI spec with the new IPSEC event type.
Signed-off-by: Petri Savolainen petri.savolainen@linaro.org Signed-off-by: Dmitry Eremin-Solenikov dmitry.ereminsolenikov@linaro.org Reviewed-by: Dmitry Eremin-Solenikov dmitry.ereminsolenikov@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/include/odp/arch/default/api/abi/event.h b/include/odp/arch/default/api/abi/event.h index 4f6596b1..ab141572 100644 --- a/include/odp/arch/default/api/abi/event.h +++ b/include/odp/arch/default/api/abi/event.h @@ -28,7 +28,8 @@ typedef enum odp_event_type_t { ODP_EVENT_BUFFER = 1, ODP_EVENT_PACKET = 2, ODP_EVENT_TIMEOUT = 3, - ODP_EVENT_CRYPTO_COMPL = 4 + ODP_EVENT_CRYPTO_COMPL = 4, + ODP_EVENT_IPSEC_RESULT = 5 } odp_event_type_t;
/**
commit c7f11e9d3c5339c9805598f1046024e7165eb3e3 Author: Bill Fischofer bill.fischofer@linaro.org Date: Fri Apr 21 09:25:20 2017 -0500
api: classification: add additional doxygen documentation
Resolve Bug https://bugs.linaro.org/show_bug.cgi?id=2952 by adding additional field documentation to avoid problems with doxygen 1.8.13 and higher.
Signed-off-by: Bill Fischofer bill.fischofer@linaro.org Reviewed-by: Petri Savolainen petri.savolainen@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/include/odp/api/spec/classification.h b/include/odp/api/spec/classification.h index 0e1addd6..39831b24 100644 --- a/include/odp/api/spec/classification.h +++ b/include/odp/api/spec/classification.h @@ -366,7 +366,9 @@ typedef struct odp_pmr_param_t { /** True if the value is range and false if match */ odp_bool_t range_term;
+ /** Variant mappings for types of matches */ union { + /** Parameters for single-valued matches */ struct { /** Value to be matched */ const void *value; @@ -374,6 +376,8 @@ typedef struct odp_pmr_param_t { /** Masked set of bits to be matched */ const void *mask; } match; + + /** Parameter for range value matches */ struct { /** Start and End values are included in the range */ /** start value of range */
-----------------------------------------------------------------------
Summary of changes: .travis.yml | 143 +- configure.ac | 1 + doc/platform-api-guide/Doxyfile | 4 +- example/generator/odp_generator.c | 4 +- example/ipsec/odp_ipsec_stream.c | 6 +- example/l2fwd_simple/odp_l2fwd_simple.c | 5 + example/l3fwd/odp_l3fwd.c | 7 + example/switch/odp_switch.c | 5 + helper/cuckootable.c | 1 + helper/include/odp/helper/icmp.h | 11 +- helper/include/odp/helper/ip.h | 3 +- helper/include/odp/helper/strong_types.h | 3 +- helper/include/odp/helper/table.h | 2 +- helper/include/odp/helper/tcp.h | 35 +- helper/include/odp/helper/threads.h | 7 +- include/odp/api/spec/event.h | 2 +- include/odp/api/spec/hints.h | 6 - include/odp/api/spec/ipsec.h | 1359 ++++++++++++++++++++ include/odp/api/spec/packet.h | 26 + include/odp/api/spec/packet_io.h | 68 + include/odp/api/spec/pool.h | 6 + include/odp/api/spec/queue.h | 39 +- include/odp/api/spec/support.h | 57 + include/odp/api/spec/system_info.h | 9 + include/odp/api/spec/time.h | 13 - include/odp/api/spec/traffic_mngr.h | 5 +- include/odp/arch/default/api/abi/event.h | 4 +- include/odp_api.h | 2 + platform/Makefile.inc | 6 +- platform/linux-generic/Makefile.am | 9 + platform/linux-generic/arch/arm/odp_cpu_arch.c | 16 + .../linux-generic/arch/arm/odp_sysinfo_parse.c | 4 + platform/linux-generic/arch/default/odp_cpu_arch.c | 16 + .../linux-generic/arch/default/odp_sysinfo_parse.c | 4 + platform/linux-generic/arch/mips64/odp_cpu_arch.c | 16 + .../linux-generic/arch/mips64/odp_sysinfo_parse.c | 4 + platform/linux-generic/arch/powerpc/odp_cpu_arch.c | 16 + .../linux-generic/arch/powerpc/odp_sysinfo_parse.c | 4 + platform/linux-generic/arch/x86/cpu_flags.c | 368 ++++++ .../odp_errno_define.h => arch/x86/cpu_flags.h} | 12 +- platform/linux-generic/arch/x86/odp_cpu_arch.c | 68 + .../linux-generic/arch/x86/odp_sysinfo_parse.c | 6 + platform/linux-generic/include/odp/api/debug.h | 8 + .../include/odp/{drv/compiler.h => api/ipsec.h} | 12 +- .../include/odp/api/plat/event_types.h | 1 + .../include/odp/api/plat/ipsec_types.h | 39 + .../include/odp/api/plat/packet_types.h | 2 +- .../include/odp/api/plat/time_types.h | 19 +- .../include/odp/api/plat/traffic_mngr_types.h | 2 +- .../include/odp/api/{deprecated.h => support.h} | 16 +- platform/linux-generic/include/odp_internal.h | 1 + .../linux-generic/include/odp_packet_internal.h | 45 +- .../{odp/api/deprecated.h => odp_time_internal.h} | 16 +- platform/linux-generic/include/protocols/ip.h | 3 +- platform/linux-generic/odp_classification.c | 7 +- platform/linux-generic/odp_crypto.c | 4 +- platform/linux-generic/odp_ipsec.c | 151 +++ platform/linux-generic/odp_packet.c | 425 +++--- platform/linux-generic/odp_packet_flags.c | 111 +- platform/linux-generic/odp_packet_io.c | 15 +- platform/linux-generic/odp_queue.c | 2 + platform/linux-generic/odp_system_info.c | 30 + platform/linux-generic/odp_time.c | 256 ++-- platform/linux-generic/pktio/dpdk.c | 3 +- platform/linux-generic/pktio/loop.c | 3 +- platform/linux-generic/pktio/netmap.c | 3 +- platform/linux-generic/pktio/pcap.c | 3 +- platform/linux-generic/pktio/socket.c | 3 +- platform/linux-generic/pktio/socket_mmap.c | 3 +- platform/linux-generic/pktio/tap.c | 3 +- test/common_plat/m4/configure.m4 | 1 + test/common_plat/performance/odp_l2fwd.c | 7 + test/common_plat/performance/odp_pktio_ordered.c | 5 + test/common_plat/performance/odp_sched_latency.c | 18 +- test/common_plat/validation/api/Makefile.am | 1 + .../validation/api/crypto/odp_crypto_test_inp.c | 40 + test/common_plat/validation/api/ipsec/.gitignore | 1 + test/common_plat/validation/api/ipsec/Makefile.am | 10 + test/common_plat/validation/api/ipsec/ipsec.c | 44 + test/common_plat/validation/api/ipsec/ipsec.h | 24 + .../common_plat/validation/api/ipsec/ipsec_main.c | 7 +- test/common_plat/validation/api/pktio/Makefile.am | 4 +- test/common_plat/validation/api/pktio/parser.c | 545 ++++++++ test/common_plat/validation/api/pktio/parser.h | 180 +++ test/common_plat/validation/api/pktio/pktio.c | 14 +- test/common_plat/validation/api/pktio/pktio.h | 3 + test/common_plat/validation/api/queue/queue.c | 49 +- .../validation/api/scheduler/scheduler.c | 20 +- test/common_plat/validation/api/system/system.c | 8 + test/common_plat/validation/api/system/system.h | 1 + test/common_plat/validation/api/time/Makefile.am | 2 +- test/common_plat/validation/api/time/time.c | 77 +- test/common_plat/validation/api/time/time_main.c | 2 +- .../validation/api/time/{time.h => time_test.h} | 2 - test/linux-generic/Makefile.am | 1 + test/linux-generic/pktio_ipc/pktio_ipc_run.sh | 3 - 96 files changed, 3966 insertions(+), 671 deletions(-) create mode 100644 include/odp/api/spec/ipsec.h create mode 100644 include/odp/api/spec/support.h create mode 100644 platform/linux-generic/arch/x86/cpu_flags.c copy platform/linux-generic/{include/odp_errno_define.h => arch/x86/cpu_flags.h} (58%) copy platform/linux-generic/include/odp/{drv/compiler.h => api/ipsec.h} (55%) create mode 100644 platform/linux-generic/include/odp/api/plat/ipsec_types.h copy platform/linux-generic/include/odp/api/{deprecated.h => support.h} (53%) copy platform/linux-generic/include/{odp/api/deprecated.h => odp_time_internal.h} (52%) create mode 100644 platform/linux-generic/odp_ipsec.c create mode 100644 test/common_plat/validation/api/ipsec/.gitignore create mode 100644 test/common_plat/validation/api/ipsec/Makefile.am create mode 100644 test/common_plat/validation/api/ipsec/ipsec.c create mode 100644 test/common_plat/validation/api/ipsec/ipsec.h copy include/odp/arch/arm32-linux/odp/api/abi/event.h => test/common_plat/validation/api/ipsec/ipsec_main.c (56%) create mode 100644 test/common_plat/validation/api/pktio/parser.c create mode 100644 test/common_plat/validation/api/pktio/parser.h rename test/common_plat/validation/api/time/{time.h => time_test.h} (92%)
hooks/post-receive