void pktio_test_send_on_ronly(void) { odp_pktio_t pktio; odp_packet_t pkt; int ret; pktio = create_pktio(0, ODP_PKTIN_MODE_RECV, ODP_PKTOUT_MODE_DISABLED); if (pktio == ODP_PKTIO_INVALID) { CU_FAIL("failed to open pktio"); return; } ret = odp_pktio_start(pktio); CU_ASSERT_FATAL(ret == 0); pkt = odp_packet_alloc(default_pkt_pool, packet_len); CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID) pktio_init_packet(pkt); ret = odp_pktio_send(pktio, &pkt, 1); CU_ASSERT(ret < 0); if (ret <= 0) odp_packet_free(pkt); ret = odp_pktio_stop(pktio); CU_ASSERT_FATAL(ret == 0); ret = odp_pktio_close(pktio); CU_ASSERT_FATAL(ret == 0); }
static void test_queue(void) { struct ofp_ifqueue ifq; struct ifq_entry e; ifq.ifq_tail = NULL; ifq.ifq_len = 0; e.next = NULL; odp_packet_t m = odp_packet_alloc(ofp_packet_pool, 0); IF_ENQUEUE(&ifq, m) while (0); CU_ASSERT_PTR_NOT_NULL(ifq.ifq_head); CU_ASSERT_PTR_EQUAL(ifq.ifq_head, ifq.ifq_tail); CU_ASSERT_PTR_NULL(ifq.ifq_tail->next); CU_ASSERT_EQUAL(ifq.ifq_len, 1); ifq.ifq_head = ifq.ifq_tail = &e; IF_ENQUEUE(&ifq, m) while (0); CU_ASSERT_PTR_NOT_NULL(ifq.ifq_head); CU_ASSERT_PTR_NOT_NULL(ifq.ifq_tail); CU_ASSERT_PTR_NOT_EQUAL(ifq.ifq_head, ifq.ifq_tail); CU_ASSERT_PTR_EQUAL(ifq.ifq_head->next, ifq.ifq_tail); CU_ASSERT_PTR_NULL(ifq.ifq_tail->next); CU_ASSERT_EQUAL(ifq.ifq_len, 2); odp_packet_free(m); }
static void send_arp_request(struct ofp_ifnet *dev, uint32_t gw) { char buf[sizeof(struct ofp_ether_vlan_header) + sizeof(struct ofp_arphdr)]; struct ofp_arphdr *arp; struct ofp_ether_header *e1 = (struct ofp_ether_header *)buf; struct ofp_ether_vlan_header *e2 = (struct ofp_ether_vlan_header *)buf; size_t size; odp_packet_t pkt; memset(buf, 0, sizeof(buf)); memset(e1->ether_dhost, 0xff, OFP_ETHER_ADDR_LEN); memcpy(e1->ether_shost, dev->mac, OFP_ETHER_ADDR_LEN); if (ETH_WITH_VLAN(dev)) { arp = (struct ofp_arphdr *) (e2 + 1); e2->evl_encap_proto = odp_cpu_to_be_16(OFP_ETHERTYPE_VLAN); e2->evl_tag = odp_cpu_to_be_16(dev->vlan); e2->evl_proto = odp_cpu_to_be_16(OFP_ETHERTYPE_ARP); size = sizeof(*arp) + sizeof(*e2); } else { arp = (struct ofp_arphdr *) (e1 + 1); e1->ether_type = odp_cpu_to_be_16(OFP_ETHERTYPE_ARP); size = sizeof(*arp) + sizeof(*e1); } arp->hrd = odp_cpu_to_be_16(OFP_ARPHDR_ETHER); arp->pro = odp_cpu_to_be_16(OFP_ETHERTYPE_IP); arp->hln = OFP_ETHER_ADDR_LEN; arp->pln = sizeof(struct ofp_in_addr); arp->op = odp_cpu_to_be_16(OFP_ARPOP_REQUEST); memcpy(arp->eth_src, e1->ether_shost, OFP_ETHER_ADDR_LEN); arp->ip_src = dev->ip_addr; memcpy(arp->eth_dst, e1->ether_dhost, OFP_ETHER_ADDR_LEN); arp->ip_dst = gw; pkt = odp_packet_alloc(ofp_packet_pool, size); if (pkt == ODP_PACKET_INVALID) { OFP_ERR("odp_packet_alloc falied"); return; } memcpy(odp_packet_data(pkt), buf, size); if (odp_unlikely(dev->port == VXLAN_PORTS)) { ofp_vxlan_send_arp_request(pkt, dev); return; } odp_packet_has_eth_set(pkt, 1); odp_packet_has_arp_set(pkt, 1); odp_packet_l2_offset_set(pkt, 0); odp_packet_l3_offset_set(pkt, size - sizeof(struct ofp_arphdr)); if (send_pkt_out(dev, pkt) == OFP_PKT_DROP) odp_packet_free(pkt); }
/** * Set up an icmp packet * * @param pool Buffer pool to create packet in * * @return Handle of created packet * @retval ODP_PACKET_INVALID Packet could not be created */ static odp_packet_t pack_icmp_pkt(odp_pool_t pool) { odp_packet_t pkt; char *buf; odph_ethhdr_t *eth; odph_ipv4hdr_t *ip; odph_icmphdr_t *icmp; struct timeval tval; uint8_t *tval_d; unsigned short seq; args->appl.payload = 56; pkt = odp_packet_alloc(pool, args->appl.payload + ODPH_ICMPHDR_LEN + ODPH_IPV4HDR_LEN + ODPH_ETHHDR_LEN); if (pkt == ODP_PACKET_INVALID) return pkt; buf = odp_packet_data(pkt); /* ether */ odp_packet_l2_offset_set(pkt, 0); eth = (odph_ethhdr_t *)buf; memcpy((char *)eth->src.addr, args->appl.srcmac.addr, ODPH_ETHADDR_LEN); memcpy((char *)eth->dst.addr, args->appl.dstmac.addr, ODPH_ETHADDR_LEN); eth->type = odp_cpu_to_be_16(ODPH_ETHTYPE_IPV4); /* ip */ odp_packet_l3_offset_set(pkt, ODPH_ETHHDR_LEN); ip = (odph_ipv4hdr_t *)(buf + ODPH_ETHHDR_LEN); ip->dst_addr = odp_cpu_to_be_32(args->appl.dstip); ip->src_addr = odp_cpu_to_be_32(args->appl.srcip); ip->ver_ihl = ODPH_IPV4 << 4 | ODPH_IPV4HDR_IHL_MIN; ip->tot_len = odp_cpu_to_be_16(args->appl.payload + ODPH_ICMPHDR_LEN + ODPH_IPV4HDR_LEN); ip->proto = ODPH_IPPROTO_ICMP; seq = odp_atomic_fetch_add_u64(&counters.seq, 1) % 0xffff; ip->id = odp_cpu_to_be_16(seq); ip->chksum = 0; odph_ipv4_csum_update(pkt); /* icmp */ icmp = (odph_icmphdr_t *)(buf + ODPH_ETHHDR_LEN + ODPH_IPV4HDR_LEN); icmp->type = ICMP_ECHO; icmp->code = 0; icmp->un.echo.id = 0; icmp->un.echo.sequence = ip->id; tval_d = (uint8_t *)(buf + ODPH_ETHHDR_LEN + ODPH_IPV4HDR_LEN + ODPH_ICMPHDR_LEN); /* TODO This should be changed to use an * ODP timer API once one exists. */ gettimeofday(&tval, NULL); memcpy(tval_d, &tval, sizeof(struct timeval)); icmp->chksum = 0; icmp->chksum = odp_chksum(icmp, args->appl.payload + ODPH_ICMPHDR_LEN); return pkt; }
static int create_odp_packet_ip4(odp_packet_t *opkt, uint8_t *pkt_data, int plen, uint32_t dst_addr) { odp_pool_t pool; uint8_t *buf; odp_packet_t pkt = ODP_PACKET_INVALID; struct ofp_ip *iphdr; memset(orig_pkt_data, 0x0, sizeof(orig_pkt_data)); pool = odp_pool_lookup("packet_pool"); if (pool == ODP_POOL_INVALID) { fail_with_odp("ODP packet_pool not found\n"); return -1; } pkt = odp_packet_alloc(pool, plen); if (pkt == ODP_PACKET_INVALID) { fail_with_odp("ODP packet alloc failed"); return -1; } buf = odp_packet_data(pkt); if (odp_packet_copy_from_mem(pkt, 0, plen, pkt_data) < 0) { fail_with_odp("Packet data copy failed\n"); return -1; }; iphdr = (struct ofp_ip *)&buf[OFP_ETHER_HDR_LEN]; /* changes to the default packet. Recalculate ip checksum */ if (dst_addr) { iphdr->ip_dst.s_addr = dst_addr; iphdr->ip_sum = 0; iphdr->ip_sum = ofp_cksum_buffer((uint16_t *)iphdr, iphdr->ip_hl<<2); } /* END OF changes to the default packet */ odp_packet_has_eth_set(pkt, 1); odp_packet_has_ipv4_set(pkt, 1); odp_packet_l2_offset_set(pkt, 0); odp_packet_l3_offset_set(pkt, OFP_ETHER_HDR_LEN); odp_packet_l4_offset_set(pkt, OFP_ETHER_HDR_LEN + (iphdr->ip_hl<<2)); *opkt = pkt; memcpy(orig_pkt_data, pkt_data, plen); return 0; }
static odp_packet_t pack_pkt(odp_pool_t pool, odph_ethaddr_t eth_src, odph_ethaddr_t eth_dst, uint32_t ip_src, uint32_t ip_dst, int payload, int is_ip) { odp_packet_t pkt; char *buf; odph_ethhdr_t *eth; odph_ipv4hdr_t *ip; odph_udphdr_t *udp; static unsigned short seq = 0; pkt = odp_packet_alloc(pool, payload + ODPH_UDPHDR_LEN + ODPH_IPV4HDR_LEN + ODPH_ETHHDR_LEN); if (pkt == ODP_PACKET_INVALID) return pkt; buf = odp_packet_data(pkt); /* ether */ odp_packet_l2_offset_set(pkt, 0); eth = (odph_ethhdr_t *)buf; memcpy((char *)eth->src.addr, eth_src.addr, ODPH_ETHADDR_LEN); memcpy((char *)eth->dst.addr, eth_dst.addr, ODPH_ETHADDR_LEN); if ( is_ip ) { eth->type = odp_cpu_to_be_16(ODPH_ETHTYPE_IPV4); odp_packet_l3_offset_set(pkt, ODPH_ETHHDR_LEN); ip = (odph_ipv4hdr_t *)(buf + ODPH_ETHHDR_LEN); ip->dst_addr = odp_cpu_to_be_32(ip_dst); ip->src_addr = odp_cpu_to_be_32(ip_src); ip->ver_ihl = ODPH_IPV4 << 4 | ODPH_IPV4HDR_IHL_MIN; ip->tot_len = odp_cpu_to_be_16(payload + ODPH_UDPHDR_LEN + ODPH_IPV4HDR_LEN); ip->proto = ODPH_IPPROTO_UDP; seq++; ip->id = odp_cpu_to_be_16(seq); ip->chksum = 0; odph_ipv4_csum_update(pkt); odp_packet_l4_offset_set(pkt, ODPH_ETHHDR_LEN + ODPH_IPV4HDR_LEN); udp = (odph_udphdr_t *)(buf + ODPH_ETHHDR_LEN + ODPH_IPV4HDR_LEN); udp->src_port = 0; udp->dst_port = 0; udp->length = odp_cpu_to_be_16(payload + ODPH_UDPHDR_LEN); udp->chksum = 0; udp->chksum = odp_cpu_to_be_16(odph_ipv4_udp_chksum(pkt)); } else { eth->type = odp_cpu_to_be_16(0xbeef); } return pkt; }
/** * set up an udp packet * * @param pool Buffer pool to create packet in * * @return Handle of created packet * @retval ODP_PACKET_INVALID Packet could not be created */ static odp_packet_t pack_udp_pkt(odp_pool_t pool) { odp_packet_t pkt; char *buf; odph_ethhdr_t *eth; odph_ipv4hdr_t *ip; odph_udphdr_t *udp; unsigned short seq; pkt = odp_packet_alloc(pool, args->appl.payload + ODPH_UDPHDR_LEN + ODPH_IPV4HDR_LEN + ODPH_ETHHDR_LEN); if (pkt == ODP_PACKET_INVALID) return pkt; buf = odp_packet_data(pkt); /* ether */ odp_packet_l2_offset_set(pkt, 0); eth = (odph_ethhdr_t *)buf; memcpy((char *)eth->src.addr, args->appl.srcmac.addr, ODPH_ETHADDR_LEN); memcpy((char *)eth->dst.addr, args->appl.dstmac.addr, ODPH_ETHADDR_LEN); eth->type = odp_cpu_to_be_16(ODPH_ETHTYPE_IPV4); /* ip */ odp_packet_l3_offset_set(pkt, ODPH_ETHHDR_LEN); ip = (odph_ipv4hdr_t *)(buf + ODPH_ETHHDR_LEN); ip->dst_addr = odp_cpu_to_be_32(args->appl.dstip); ip->src_addr = odp_cpu_to_be_32(args->appl.srcip); ip->ver_ihl = ODPH_IPV4 << 4 | ODPH_IPV4HDR_IHL_MIN; ip->tot_len = odp_cpu_to_be_16(args->appl.payload + ODPH_UDPHDR_LEN + ODPH_IPV4HDR_LEN); ip->proto = ODPH_IPPROTO_UDP; seq = odp_atomic_fetch_add_u64(&counters.seq, 1) % 0xFFFF; ip->id = odp_cpu_to_be_16(seq); ip->chksum = 0; odph_ipv4_csum_update(pkt); /* udp */ odp_packet_l4_offset_set(pkt, ODPH_ETHHDR_LEN + ODPH_IPV4HDR_LEN); udp = (odph_udphdr_t *)(buf + ODPH_ETHHDR_LEN + ODPH_IPV4HDR_LEN); udp->src_port = 0; udp->dst_port = 0; udp->length = odp_cpu_to_be_16(args->appl.payload + ODPH_UDPHDR_LEN); udp->chksum = 0; udp->chksum = odp_cpu_to_be_16(odph_ipv4_udp_chksum(pkt)); return pkt; }
static odp_packet_t make_odp_packet(uint16_t pkt_len) { odp_packet_t odp_pkt; uint8_t rand8a, rand8b, pkt_color, drop_eligible; rand8a = random_8(); rand8b = random_8(); pkt_color = (rand8a < 224) ? 0 : ((rand8a < 248) ? 1 : 2); drop_eligible = (rand8b < 240) ? 1 : 0; odp_pkt = odp_packet_alloc(odp_pool, pkt_len); if (odp_pkt == ODP_PACKET_INVALID) { printf("%s odp_packet_alloc failure *******\n", __func__); return 0; } odp_packet_color_set(odp_pkt, pkt_color); odp_packet_drop_eligible_set(odp_pkt, drop_eligible); odp_packet_shaper_len_adjust_set(odp_pkt, 24); return odp_pkt; }
static int create_odp_packet_ip6(odp_packet_t *opkt, uint8_t *pkt_data, int plen) { odp_pool_t pool; odp_packet_t pkt = ODP_PACKET_INVALID; memset(orig_pkt_data, 0x0, sizeof(orig_pkt_data)); pool = odp_pool_lookup("packet_pool"); if (pool == ODP_POOL_INVALID) { fail_with_odp("ODP packet_pool not found\n"); return -1; } pkt = odp_packet_alloc(pool, plen); if (pkt == ODP_PACKET_INVALID) { fail_with_odp("ODP packet alloc failed"); return -1; } if (odp_packet_copy_from_mem(pkt, 0, plen, pkt_data) < 0) { fail_with_odp("Packet data copy failed\n"); return -1; }; odp_packet_has_eth_set(pkt, 1); odp_packet_has_l2_set(pkt, 1); odp_packet_has_ipv6_set(pkt, 1); odp_packet_l2_offset_set(pkt, 0); odp_packet_l3_offset_set(pkt, OFP_ETHER_HDR_LEN); *opkt = pkt; odp_packet_copy_to_mem(pkt, 0, plen, orig_pkt_data); return 0; }
odp_packet_t create_ipv4_packet(stream_db_entry_t *stream, uint8_t *dmac, odp_pool_t pkt_pool) { ipsec_cache_entry_t *entry = NULL; odp_packet_t pkt; uint8_t *base; uint8_t *data; odph_ethhdr_t *eth; odph_ipv4hdr_t *ip; odph_ipv4hdr_t *inner_ip = NULL; odph_ahhdr_t *ah = NULL; odph_esphdr_t *esp = NULL; odph_icmphdr_t *icmp; stream_pkt_hdr_t *test; unsigned i; if (stream->input.entry) entry = stream->input.entry; else if (stream->output.entry) entry = stream->output.entry; /* Get packet */ pkt = odp_packet_alloc(pkt_pool, 0); if (ODP_PACKET_INVALID == pkt) return ODP_PACKET_INVALID; base = odp_packet_data(pkt); data = odp_packet_data(pkt); /* Ethernet */ odp_packet_has_eth_set(pkt, 1); eth = (odph_ethhdr_t *)data; data += sizeof(*eth); memset((char *)eth->src.addr, (0x80 | stream->id), ODPH_ETHADDR_LEN); memcpy((char *)eth->dst.addr, dmac, ODPH_ETHADDR_LEN); eth->type = odp_cpu_to_be_16(ODPH_ETHTYPE_IPV4); /* IPv4 */ odp_packet_has_ipv4_set(pkt, 1); ip = (odph_ipv4hdr_t *)data; data += sizeof(*ip); /* Wait until almost finished to fill in mutable fields */ memset((char *)ip, 0, sizeof(*ip)); ip->ver_ihl = 0x45; ip->id = odp_cpu_to_be_16(stream->id); /* Outer IP header in tunnel mode */ if (entry && entry->mode == IPSEC_SA_MODE_TUNNEL && (entry == stream->input.entry)) { ip->proto = ODPH_IPV4; 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->src_addr = odp_cpu_to_be_32(stream->src_ip); ip->dst_addr = odp_cpu_to_be_32(stream->dst_ip); } /* AH (if specified) */ if (entry && (entry == stream->input.entry) && (ODP_AUTH_ALG_NULL != entry->ah.alg)) { if (ODP_AUTH_ALG_MD5_96 != entry->ah.alg) abort(); ah = (odph_ahhdr_t *)data; data += sizeof(*ah); data += entry->ah.icv_len; memset((char *)ah, 0, sizeof(*ah) + entry->ah.icv_len); ah->ah_len = 1 + (entry->ah.icv_len / 4); ah->spi = odp_cpu_to_be_32(entry->ah.spi); ah->seq_no = odp_cpu_to_be_32(stream->input.ah_seq++); } /* ESP (if specified) */ if (entry && (entry == stream->input.entry) && (ODP_CIPHER_ALG_NULL != entry->esp.alg)) { if (ODP_CIPHER_ALG_3DES_CBC != entry->esp.alg) abort(); esp = (odph_esphdr_t *)data; data += sizeof(*esp); data += entry->esp.iv_len; esp->spi = odp_cpu_to_be_32(entry->esp.spi); esp->seq_no = odp_cpu_to_be_32(stream->input.esp_seq++); RAND_bytes(esp->iv, 8); } /* Inner IP header in tunnel mode */ if (entry && (entry == stream->input.entry) && (entry->mode == IPSEC_SA_MODE_TUNNEL)) { 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->id = odp_cpu_to_be_16(stream->id); inner_ip->ttl = 64; inner_ip->tos = 0; inner_ip->frag_offset = 0; inner_ip->src_addr = odp_cpu_to_be_32(stream->src_ip); inner_ip->dst_addr = odp_cpu_to_be_32(stream->dst_ip); inner_ip->chksum = odp_chksum(inner_ip, sizeof(*inner_ip)); data += sizeof(*inner_ip); } /* ICMP header so we can see it on wireshark */ icmp = (odph_icmphdr_t *)data; data += sizeof(*icmp); icmp->type = ICMP_ECHO; icmp->code = 0; icmp->un.echo.id = odp_cpu_to_be_16(0x1234); icmp->un.echo.sequence = odp_cpu_to_be_16(stream->created); /* Packet payload of incrementing bytes */ test = (stream_pkt_hdr_t *)data; data += sizeof(*test); test->magic = odp_cpu_to_be_64(STREAM_MAGIC); for (i = 0; i < stream->length; i++) *data++ = (uint8_t)i; /* Close ICMP */ icmp->chksum = 0; icmp->chksum = odp_chksum(icmp, data - (uint8_t *)icmp); /* Close ESP if specified */ if (esp) { int payload_len = data - (uint8_t *)icmp; uint8_t *encrypt_start = (uint8_t *)icmp; if (entry->mode == IPSEC_SA_MODE_TUNNEL) { payload_len = data - (uint8_t *)inner_ip; encrypt_start = (uint8_t *)inner_ip; } int encrypt_len; odph_esptrl_t *esp_t; DES_key_schedule ks1, ks2, ks3; uint8_t iv[8]; memcpy(iv, esp->iv, sizeof(iv)); encrypt_len = ESP_ENCODE_LEN(payload_len + sizeof(*esp_t), entry->esp.block_len); memset(data, 0, encrypt_len - payload_len); data += encrypt_len - payload_len; esp_t = (odph_esptrl_t *)(data) - 1; esp_t->pad_len = encrypt_len - payload_len - sizeof(*esp_t); esp_t->next_header = ip->proto; ip->proto = ODPH_IPPROTO_ESP; DES_set_key((DES_cblock *)&entry->esp.key.data[0], &ks1); DES_set_key((DES_cblock *)&entry->esp.key.data[8], &ks2); DES_set_key((DES_cblock *)&entry->esp.key.data[16], &ks3); DES_ede3_cbc_encrypt(encrypt_start, encrypt_start, encrypt_len, &ks1, &ks2, &ks3, (DES_cblock *)iv, 1); } /* Since ESP can pad we can now fix IP length */ ip->tot_len = odp_cpu_to_be_16(data - (uint8_t *)ip); /* Close AH if specified */ if (ah) { uint8_t hash[EVP_MAX_MD_SIZE]; int auth_len = data - (uint8_t *)ip; ah->next_header = ip->proto; ip->proto = ODPH_IPPROTO_AH; HMAC(EVP_md5(), entry->ah.key.data, entry->ah.key.length, (uint8_t *)ip, auth_len, hash, NULL); memcpy(ah->icv, hash, 12); } /* Correct set packet length offsets */ odp_packet_push_tail(pkt, data - base); odp_packet_l2_offset_set(pkt, (uint8_t *)eth - base); odp_packet_l3_offset_set(pkt, (uint8_t *)ip - base); odp_packet_l4_offset_set(pkt, ((uint8_t *)ip - base) + sizeof(*ip)); /* Now fill in final IP header fields */ ip->ttl = 64; ip->tos = 0; ip->frag_offset = 0; ip->chksum = 0; odph_ipv4_csum_update(pkt); return pkt; }
static int ipc_second_process(void) { odp_pktio_t ipc_pktio; odp_pool_param_t params; odp_pool_t pool; odp_packet_t pkt_tbl[MAX_PKT_BURST]; odp_packet_t alloc_pkt; int pkts; int ret; int i; odp_time_t start_cycle; odp_time_t cycle; odp_time_t diff; odp_time_t wait; uint64_t stat_pkts = 0; odp_pktin_queue_t pktin; /* Create packet pool */ memset(¶ms, 0, sizeof(params)); params.pkt.seg_len = SHM_PKT_POOL_BUF_SIZE; params.pkt.len = SHM_PKT_POOL_BUF_SIZE; params.pkt.num = SHM_PKT_POOL_SIZE; params.type = ODP_POOL_PACKET; pool = odp_pool_create("packet_pool2", ¶ms); if (pool == ODP_POOL_INVALID) { EXAMPLE_ERR("Error: packet pool create failed.\n"); exit(EXIT_FAILURE); } ipc_pktio = create_pktio(pool); wait = odp_time_local_from_ns(run_time_sec * ODP_TIME_SEC_IN_NS); start_cycle = odp_time_local(); if (odp_pktin_queue(ipc_pktio, &pktin, 1) != 1) { EXAMPLE_ERR("no input queue\n"); return -1; } /* start ipc pktio, i.e. wait until other process connects */ for (;;) { /* 1. exit loop if time specified */ if (run_time_sec) { cycle = odp_time_local(); diff = odp_time_diff(cycle, start_cycle); if (odp_time_cmp(wait, diff) < 0) { printf("timeout exit, run_time_sec %d\n", run_time_sec); goto not_started; } } ret = odp_pktio_start(ipc_pktio); if (!ret) break; } for (;;) { /* exit loop if time specified */ if (run_time_sec) { cycle = odp_time_local(); diff = odp_time_diff(cycle, start_cycle); if (odp_time_cmp(wait, diff) < 0) { EXAMPLE_DBG("exit after %d seconds\n", run_time_sec); break; } } /* recv some packets and change MAGIC to MAGIC_2 */ pkts = odp_pktin_recv(pktin, pkt_tbl, MAX_PKT_BURST); if (pkts <= 0) continue; for (i = 0; i < pkts; i++) { odp_packet_t pkt = pkt_tbl[i]; pkt_head_t head; size_t off; off = odp_packet_l4_offset(pkt); if (off == ODP_PACKET_OFFSET_INVALID) EXAMPLE_ABORT("invalid l4 offset\n"); off += ODPH_UDPHDR_LEN; ret = odp_packet_copy_to_mem(pkt, off, sizeof(head), &head); if (ret) EXAMPLE_ABORT("unable copy out head data"); if (head.magic != TEST_SEQ_MAGIC) EXAMPLE_ABORT("Wrong head magic!"); /* Modify magic number in packet */ head.magic = TEST_SEQ_MAGIC_2; ret = odp_packet_copy_from_mem(pkt, off, sizeof(head), &head); if (ret) EXAMPLE_ABORT("unable to copy in head data"); } /* send all packets back */ ret = ipc_odp_packet_send_or_free(ipc_pktio, pkt_tbl, pkts); if (ret < 0) EXAMPLE_ABORT("can not send packets\n"); stat_pkts += ret; /* alloc packet from local pool, set magic to ALLOC_MAGIC, * and send it.*/ alloc_pkt = odp_packet_alloc(pool, SHM_PKT_POOL_BUF_SIZE); if (alloc_pkt != ODP_PACKET_INVALID) { pkt_head_t head; size_t off; odp_packet_l4_offset_set(alloc_pkt, 30); head.magic = TEST_ALLOC_MAGIC; off = odp_packet_l4_offset(alloc_pkt); off += ODPH_UDPHDR_LEN; ret = odp_packet_copy_from_mem(alloc_pkt, off, sizeof(head), &head); if (ret) EXAMPLE_ABORT("unable to copy in head data"); pkt_tbl[0] = alloc_pkt; ret = ipc_odp_packet_send_or_free(ipc_pktio, pkt_tbl, 1); if (ret < 0) EXAMPLE_ABORT("can not send packets\n"); stat_pkts += 1; } } /* cleanup and exit */ ret = odp_pktio_stop(ipc_pktio); if (ret) { EXAMPLE_DBG("ipc2: odp_pktio_stop error %d\n", ret); return -1; } not_started: ret = odp_pktio_close(ipc_pktio); if (ret) { EXAMPLE_DBG("ipc2: odp_pktio_close error %d\n", ret); return -1; } ret = odp_pool_destroy(pool); if (ret) EXAMPLE_DBG("ipc2: pool_destroy error %d\n", ret); return stat_pkts > 1000 ? 0 : -1; }
static enum ofp_return_code ofp_fragment_pkt(odp_packet_t pkt, struct ofp_ifnet *dev_out, uint8_t is_local_address) { struct ofp_ip *ip, *ip_new; uint16_t vlan = dev_out->vlan; int tot_len, pl_len, seg_len, pl_pos, flen, hwlen; uint16_t frag, frag_new; uint8_t *payload_new; uint32_t payload_offset; odp_pool_t pkt_pool; odp_packet_t pkt_new; struct ofp_ether_header *eth, *eth_new; struct ofp_ether_vlan_header *eth_vlan, *eth_new_vlan; int ret = OFP_PKT_PROCESSED; if (!vlan) eth = odp_packet_l2_ptr(pkt, NULL); else eth_vlan = odp_packet_l2_ptr(pkt, NULL); ip = (struct ofp_ip *)odp_packet_l3_ptr(pkt, NULL); pkt_pool = ofp_packet_pool; tot_len = odp_be_to_cpu_16(ip->ip_len); pl_len = tot_len - (ip->ip_hl<<2); seg_len = (dev_out->if_mtu - sizeof(struct ofp_ip)) & 0xfff8; pl_pos = 0; frag = odp_be_to_cpu_16(ip->ip_off); payload_offset = odp_packet_l3_offset(pkt) + (ip->ip_hl<<2); OFP_UPDATE_PACKET_STAT(tx_eth_frag, 1); while (pl_pos < pl_len) { flen = (pl_len - pl_pos) > seg_len ? seg_len : (pl_len - pl_pos); hwlen = flen + sizeof(struct ofp_ip) + (vlan ? sizeof(struct ofp_ether_vlan_header) : sizeof(struct ofp_ether_header)); pkt_new = odp_packet_alloc(pkt_pool, hwlen); if (pkt_new == ODP_PACKET_INVALID) { OFP_ERR("odp_packet_alloc failed"); return OFP_PKT_DROP; } odp_packet_user_ptr_set(pkt_new, odp_packet_user_ptr(pkt)); odp_packet_l2_offset_set(pkt_new, 0); if (vlan) { eth_new_vlan = odp_packet_l2_ptr(pkt_new, NULL); *eth_new_vlan = *eth_vlan; ip_new = (struct ofp_ip *)(eth_new_vlan + 1); odp_packet_l3_offset_set(pkt_new, OFP_ETHER_HDR_LEN + OFP_ETHER_VLAN_ENCAP_LEN); } else { eth_new = odp_packet_l2_ptr(pkt_new, NULL); *eth_new = *eth; ip_new = (struct ofp_ip *)(eth_new + 1); odp_packet_l3_offset_set(pkt_new, OFP_ETHER_HDR_LEN); } *ip_new = *ip; payload_new = (uint8_t *)(ip_new + 1); if (odp_packet_copydata_out(pkt, payload_offset + pl_pos, flen, payload_new) < 0) { OFP_ERR("odp_packet_copydata_out failed"); return OFP_PKT_DROP; }; ip_new->ip_len = odp_cpu_to_be_16(flen + sizeof(*ip_new)); frag_new = frag + pl_pos/8; pl_pos += flen; if (pl_pos < pl_len) frag_new |= OFP_IP_MF; ip_new->ip_off = odp_cpu_to_be_16(frag_new); ip_new->ip_sum = 0; ip_new->ip_sum = ofp_cksum_buffer((uint16_t *)ip_new, sizeof(*ip_new)); if (is_local_address) ret = send_pkt_loop(dev_out, pkt_new); else ret = send_pkt_out(dev_out, pkt_new); if (ret == OFP_PKT_DROP) { odp_packet_free(pkt_new); return OFP_PKT_DROP; } } odp_packet_free(pkt); return OFP_PKT_PROCESSED; }
odp_packet_t create_packet(odp_pool_t pool, bool vlan, odp_atomic_u32_t *seq, bool flag_udp) { uint32_t seqno; odph_ethhdr_t *ethhdr; odph_udphdr_t *udp; odph_tcphdr_t *tcp; odph_ipv4hdr_t *ip; uint8_t payload_len; char src_mac[ODPH_ETHADDR_LEN] = {0}; char dst_mac[ODPH_ETHADDR_LEN] = {0}; uint32_t addr = 0; uint32_t mask; int offset; odp_packet_t pkt; int packet_len = 0; payload_len = sizeof(cls_test_packet_t); packet_len += ODPH_ETHHDR_LEN; packet_len += ODPH_IPV4HDR_LEN; if (flag_udp) packet_len += ODPH_UDPHDR_LEN; else packet_len += ODPH_TCPHDR_LEN; packet_len += payload_len; if (vlan) packet_len += ODPH_VLANHDR_LEN; pkt = odp_packet_alloc(pool, packet_len); CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); /* Ethernet Header */ offset = 0; odp_packet_l2_offset_set(pkt, offset); ethhdr = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, NULL); memcpy(ethhdr->src.addr, src_mac, ODPH_ETHADDR_LEN); memcpy(ethhdr->dst.addr, dst_mac, ODPH_ETHADDR_LEN); offset += sizeof(odph_ethhdr_t); if (vlan) { /* Default vlan header */ uint8_t *parseptr; odph_vlanhdr_t *vlan; vlan = (odph_vlanhdr_t *)(ðhdr->type); parseptr = (uint8_t *)vlan; vlan->tci = odp_cpu_to_be_16(0); vlan->tpid = odp_cpu_to_be_16(ODPH_ETHTYPE_VLAN); offset += sizeof(odph_vlanhdr_t); parseptr += sizeof(odph_vlanhdr_t); uint16be_t *type = (uint16be_t *)(void *)parseptr; *type = odp_cpu_to_be_16(ODPH_ETHTYPE_IPV4); } else { ethhdr->type = odp_cpu_to_be_16(ODPH_ETHTYPE_IPV4); } odp_packet_l3_offset_set(pkt, offset); /* ipv4 */ ip = (odph_ipv4hdr_t *)odp_packet_l3_ptr(pkt, NULL); parse_ipv4_string(CLS_DEFAULT_SADDR, &addr, &mask); ip->dst_addr = odp_cpu_to_be_32(addr); parse_ipv4_string(CLS_DEFAULT_DADDR, &addr, &mask); ip->src_addr = odp_cpu_to_be_32(addr); ip->ver_ihl = ODPH_IPV4 << 4 | ODPH_IPV4HDR_IHL_MIN; if (flag_udp) ip->tot_len = odp_cpu_to_be_16(ODPH_UDPHDR_LEN + payload_len + ODPH_IPV4HDR_LEN); else ip->tot_len = odp_cpu_to_be_16(ODPH_TCPHDR_LEN + payload_len + ODPH_IPV4HDR_LEN); ip->ttl = 128; if (flag_udp) ip->proto = ODPH_IPPROTO_UDP; else ip->proto = ODPH_IPPROTO_TCP; seqno = odp_atomic_fetch_inc_u32(seq); ip->id = odp_cpu_to_be_16(seqno); ip->chksum = 0; ip->chksum = odph_ipv4_csum_update(pkt); offset += ODPH_IPV4HDR_LEN; /* udp */ if (flag_udp) { odp_packet_l4_offset_set(pkt, offset); udp = (odph_udphdr_t *)odp_packet_l4_ptr(pkt, NULL); udp->src_port = odp_cpu_to_be_16(CLS_DEFAULT_SPORT); udp->dst_port = odp_cpu_to_be_16(CLS_DEFAULT_DPORT); udp->length = odp_cpu_to_be_16(payload_len + ODPH_UDPHDR_LEN); udp->chksum = 0; } else { odp_packet_l4_offset_set(pkt, offset); tcp = (odph_tcphdr_t *)odp_packet_l4_ptr(pkt, NULL); tcp->src_port = odp_cpu_to_be_16(CLS_DEFAULT_SPORT); tcp->dst_port = odp_cpu_to_be_16(CLS_DEFAULT_DPORT); tcp->hl = ODPH_TCPHDR_LEN / 4; /* TODO: checksum field has to be updated */ tcp->cksm = 0; } /* set pkt sequence number */ cls_pkt_set_seq(pkt); return pkt; }
/* * Generate a single test packet for transmission. */ static odp_packet_t pktio_create_packet(void) { odp_packet_t pkt; odph_ethhdr_t *eth; odph_ipv4hdr_t *ip; odph_udphdr_t *udp; char *buf; uint16_t seq; uint32_t offset; pkt_head_t pkt_hdr; size_t payload_len; uint8_t mac[ODPH_ETHADDR_LEN] = {0}; payload_len = sizeof(pkt_hdr) + gbl_args->args.pkt_len; pkt = odp_packet_alloc(transmit_pkt_pool, payload_len + ODPH_UDPHDR_LEN + ODPH_IPV4HDR_LEN + ODPH_ETHHDR_LEN); if (pkt == ODP_PACKET_INVALID) return ODP_PACKET_INVALID; buf = odp_packet_data(pkt); /* Ethernet */ offset = 0; odp_packet_l2_offset_set(pkt, offset); eth = (odph_ethhdr_t *)buf; memcpy(eth->src.addr, mac, ODPH_ETHADDR_LEN); memcpy(eth->dst.addr, mac, ODPH_ETHADDR_LEN); eth->type = odp_cpu_to_be_16(ODPH_ETHTYPE_IPV4); /* IP */ offset += ODPH_ETHHDR_LEN; odp_packet_l3_offset_set(pkt, ODPH_ETHHDR_LEN); ip = (odph_ipv4hdr_t *)(buf + ODPH_ETHHDR_LEN); ip->dst_addr = odp_cpu_to_be_32(0); ip->src_addr = odp_cpu_to_be_32(0); ip->ver_ihl = ODPH_IPV4 << 4 | ODPH_IPV4HDR_IHL_MIN; ip->tot_len = odp_cpu_to_be_16(payload_len + ODPH_UDPHDR_LEN + ODPH_IPV4HDR_LEN); ip->ttl = 128; ip->proto = ODPH_IPPROTO_UDP; seq = odp_atomic_fetch_inc_u32(&ip_seq); ip->id = odp_cpu_to_be_16(seq); ip->chksum = 0; odph_ipv4_csum_update(pkt); /* UDP */ offset += ODPH_IPV4HDR_LEN; odp_packet_l4_offset_set(pkt, offset); udp = (odph_udphdr_t *)(buf + offset); udp->src_port = odp_cpu_to_be_16(0); udp->dst_port = odp_cpu_to_be_16(0); udp->length = odp_cpu_to_be_16(payload_len + ODPH_UDPHDR_LEN); udp->chksum = 0; /* payload */ offset += ODPH_UDPHDR_LEN; pkt_hdr.magic = TEST_HDR_MAGIC; if (odp_packet_copydata_in(pkt, offset, sizeof(pkt_hdr), &pkt_hdr) != 0) LOG_ABORT("Failed to generate test packet.\n"); return pkt; }
static void pktio_txrx_multi(pktio_info_t *pktio_a, pktio_info_t *pktio_b, int num_pkts) { odp_packet_t tx_pkt[num_pkts]; odp_event_t tx_ev[num_pkts]; odp_packet_t rx_pkt; uint32_t tx_seq[num_pkts]; int i, ret; /* generate test packets to send */ for (i = 0; i < num_pkts; ++i) { tx_pkt[i] = odp_packet_alloc(default_pkt_pool, packet_len); if (tx_pkt[i] == ODP_PACKET_INVALID) break; tx_seq[i] = pktio_init_packet(tx_pkt[i]); if (tx_seq[i] == TEST_SEQ_INVALID) { odp_packet_free(tx_pkt[i]); break; } pktio_pkt_set_macs(tx_pkt[i], pktio_a->id, pktio_b->id); if (pktio_fixup_checksums(tx_pkt[i]) != 0) { odp_packet_free(tx_pkt[i]); break; } tx_ev[i] = odp_packet_to_event(tx_pkt[i]); } if (i != num_pkts) { CU_FAIL("failed to generate test packets"); return; } /* send packet(s) out */ if (num_pkts == 1) { ret = odp_queue_enq(pktio_a->outq, tx_ev[0]); if (ret != 0) { CU_FAIL("failed to enqueue test packet"); odp_packet_free(tx_pkt[0]); return; } } else { ret = odp_queue_enq_multi(pktio_a->outq, tx_ev, num_pkts); if (ret != num_pkts) { CU_FAIL("failed to enqueue test packets"); i = ret < 0 ? 0 : ret; for ( ; i < num_pkts; i++) odp_packet_free(tx_pkt[i]); return; } } /* and wait for them to arrive back */ for (i = 0; i < num_pkts; ++i) { rx_pkt = wait_for_packet(pktio_b, tx_seq[i], ODP_TIME_SEC_IN_NS); if (rx_pkt == ODP_PACKET_INVALID) break; CU_ASSERT(odp_packet_input(rx_pkt) == pktio_b->id); CU_ASSERT(odp_packet_has_error(rx_pkt) == 0); odp_packet_free(rx_pkt); } CU_ASSERT(i == num_pkts); }
/* Basic algorithm run function for async inplace mode. * Creates a session from input parameters and runs one operation * on input_vec. Checks the output of the crypto operation against * output_vec. Operation completion event is dequeued polling the * session output queue. Completion context pointer is retrieved * and checked against the one set before the operation. * Completion event can be a separate buffer or the input packet * buffer can be used. * */ static void alg_test(enum odp_crypto_op op, enum odp_cipher_alg cipher_alg, odp_crypto_iv_t ses_iv, uint8_t *op_iv_ptr, odp_crypto_key_t cipher_key, enum odp_auth_alg auth_alg, odp_crypto_key_t auth_key, uint8_t *input_vec, unsigned int input_vec_len, uint8_t *output_vec, unsigned int output_vec_len) { odp_crypto_session_t session; int rc; enum odp_crypto_ses_create_err status; odp_bool_t posted; odp_event_t event; odp_crypto_compl_t compl_event; odp_crypto_op_result_t result; /* Create a crypto session */ odp_crypto_session_params_t ses_params; memset(&ses_params, 0, sizeof(ses_params)); ses_params.op = op; ses_params.auth_cipher_text = false; ses_params.pref_mode = suite_context.pref_mode; ses_params.cipher_alg = cipher_alg; ses_params.auth_alg = auth_alg; ses_params.compl_queue = suite_context.queue; ses_params.output_pool = suite_context.pool; ses_params.cipher_key = cipher_key; ses_params.iv = ses_iv; ses_params.auth_key = auth_key; rc = odp_crypto_session_create(&ses_params, &session, &status); CU_ASSERT(!rc); CU_ASSERT(status == ODP_CRYPTO_SES_CREATE_ERR_NONE); CU_ASSERT(odp_crypto_session_to_u64(session) != odp_crypto_session_to_u64(ODP_CRYPTO_SESSION_INVALID)); /* Prepare input data */ odp_packet_t pkt = odp_packet_alloc(suite_context.pool, input_vec_len); CU_ASSERT(pkt != ODP_PACKET_INVALID); uint8_t *data_addr = odp_packet_data(pkt); memcpy(data_addr, input_vec, input_vec_len); const int data_off = 0; /* Prepare input/output params */ odp_crypto_op_params_t op_params; memset(&op_params, 0, sizeof(op_params)); op_params.session = session; op_params.pkt = pkt; op_params.out_pkt = pkt; op_params.ctx = (void *)0xdeadbeef; if (cipher_alg != ODP_CIPHER_ALG_NULL && auth_alg == ODP_AUTH_ALG_NULL) { op_params.cipher_range.offset = data_off; op_params.cipher_range.length = input_vec_len; if (op_iv_ptr) op_params.override_iv_ptr = op_iv_ptr; } else if (cipher_alg == ODP_CIPHER_ALG_NULL && auth_alg != ODP_AUTH_ALG_NULL) { op_params.auth_range.offset = data_off; op_params.auth_range.length = input_vec_len; op_params.hash_result_offset = data_off; } else { CU_FAIL("%s : not implemented for combined alg mode\n"); } rc = odp_crypto_operation(&op_params, &posted, &result); if (rc < 0) { CU_FAIL("Failed odp_crypto_operation()"); goto cleanup; } if (posted) { /* Poll completion queue for results */ do { event = odp_queue_deq(suite_context.queue); } while (event == ODP_EVENT_INVALID); compl_event = odp_crypto_compl_from_event(event); CU_ASSERT(odp_crypto_compl_to_u64(compl_event) == odp_crypto_compl_to_u64(odp_crypto_compl_from_event(event))); odp_crypto_compl_result(compl_event, &result); odp_crypto_compl_free(compl_event); } CU_ASSERT(result.ok); CU_ASSERT(result.pkt == pkt); CU_ASSERT(!memcmp(data_addr, output_vec, output_vec_len)); CU_ASSERT(result.ctx == (void *)0xdeadbeef); cleanup: rc = odp_crypto_session_destroy(session); CU_ASSERT(!rc); odp_packet_free(pkt); }
void pktio_test_start_stop(void) { odp_pktio_t pktio[MAX_NUM_IFACES]; odp_packet_t pkt; odp_event_t tx_ev[100]; odp_event_t ev; int i, pkts, ret, alloc = 0; odp_queue_t outq; uint64_t wait = odp_schedule_wait_time(ODP_TIME_MSEC_IN_NS); for (i = 0; i < num_ifaces; i++) { pktio[i] = create_pktio(i, ODP_PKTIN_MODE_SCHED, ODP_PKTOUT_MODE_SEND); CU_ASSERT_FATAL(pktio[i] != ODP_PKTIO_INVALID); create_inq(pktio[i], ODP_QUEUE_TYPE_SCHED); } outq = odp_pktio_outq_getdef(pktio[0]); /* Interfaces are stopped by default, * Check that stop when stopped generates an error */ ret = odp_pktio_stop(pktio[0]); CU_ASSERT(ret <= 0); /* start first */ ret = odp_pktio_start(pktio[0]); CU_ASSERT(ret == 0); /* Check that start when started generates an error */ ret = odp_pktio_start(pktio[0]); CU_ASSERT(ret < 0); /* Test Rx on a stopped interface. Only works if there are 2 */ if (num_ifaces > 1) { for (alloc = 0; alloc < 100; alloc++) { pkt = odp_packet_alloc(default_pkt_pool, packet_len); if (pkt == ODP_PACKET_INVALID) break; pktio_init_packet(pkt); pktio_pkt_set_macs(pkt, pktio[0], pktio[1]); if (pktio_fixup_checksums(pkt) != 0) { odp_packet_free(pkt); break; } tx_ev[alloc] = odp_packet_to_event(pkt); } for (pkts = 0; pkts != alloc; ) { ret = odp_queue_enq_multi(outq, &tx_ev[pkts], alloc - pkts); if (ret < 0) { CU_FAIL("unable to enqueue packet\n"); break; } pkts += ret; } /* check that packets did not arrive */ for (i = 0, pkts = 0; i < 1000; i++) { ev = odp_schedule(NULL, wait); if (ev == ODP_EVENT_INVALID) continue; if (odp_event_type(ev) == ODP_EVENT_PACKET) { pkt = odp_packet_from_event(ev); if (pktio_pkt_seq(pkt) != TEST_SEQ_INVALID) pkts++; } odp_event_free(ev); } if (pkts) CU_FAIL("pktio stopped, received unexpected events"); /* start both, send and get packets */ /* 0 already started */ ret = odp_pktio_start(pktio[1]); CU_ASSERT(ret == 0); /* flush packets with magic number in pipes */ for (i = 0; i < 1000; i++) { ev = odp_schedule(NULL, wait); if (ev != ODP_EVENT_INVALID) odp_event_free(ev); } } /* alloc */ for (alloc = 0; alloc < 100; alloc++) { pkt = odp_packet_alloc(default_pkt_pool, packet_len); if (pkt == ODP_PACKET_INVALID) break; pktio_init_packet(pkt); if (num_ifaces > 1) { pktio_pkt_set_macs(pkt, pktio[0], pktio[1]); if (pktio_fixup_checksums(pkt) != 0) { odp_packet_free(pkt); break; } } tx_ev[alloc] = odp_packet_to_event(pkt); } /* send */ for (pkts = 0; pkts != alloc; ) { ret = odp_queue_enq_multi(outq, &tx_ev[pkts], alloc - pkts); if (ret < 0) { CU_FAIL("unable to enqueue packet\n"); break; } pkts += ret; } /* get */ for (i = 0, pkts = 0; i < 100; i++) { ev = odp_schedule(NULL, wait); if (ev != ODP_EVENT_INVALID) { if (odp_event_type(ev) == ODP_EVENT_PACKET) { pkt = odp_packet_from_event(ev); if (pktio_pkt_seq(pkt) != TEST_SEQ_INVALID) pkts++; } odp_event_free(ev); } } CU_ASSERT(pkts == alloc); for (i = 0; i < num_ifaces; i++) { CU_ASSERT(odp_pktio_stop(pktio[i]) == 0); destroy_inq(pktio[i]); CU_ASSERT(odp_pktio_close(pktio[i]) == 0); } }
/* Basic algorithm run function for async inplace mode. * Creates a session from input parameters and runs one operation * on input_vec. Checks the output of the crypto operation against * output_vec. Operation completion event is dequeued polling the * session output queue. Completion context pointer is retrieved * and checked against the one set before the operation. * Completion event can be a separate buffer or the input packet * buffer can be used. * */ static void alg_test(odp_crypto_op_t op, odp_cipher_alg_t cipher_alg, odp_crypto_iv_t ses_iv, uint8_t *op_iv_ptr, 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, const uint8_t *plaintext, unsigned int plaintext_len, const uint8_t *ciphertext, unsigned int ciphertext_len, const uint8_t *digest, unsigned int digest_len ) { odp_crypto_session_t session; int rc; odp_crypto_ses_create_err_t status; odp_bool_t posted; odp_event_t event; odp_crypto_compl_t compl_event; odp_crypto_op_result_t result; /* Create a crypto session */ odp_crypto_session_params_t ses_params; memset(&ses_params, 0, sizeof(ses_params)); ses_params.op = op; ses_params.auth_cipher_text = false; ses_params.pref_mode = suite_context.pref_mode; ses_params.cipher_alg = cipher_alg; ses_params.auth_alg = auth_alg; ses_params.compl_queue = suite_context.queue; ses_params.output_pool = suite_context.pool; ses_params.cipher_key = cipher_key; ses_params.iv = ses_iv; ses_params.auth_key = auth_key; rc = odp_crypto_session_create(&ses_params, &session, &status); CU_ASSERT_FATAL(!rc); CU_ASSERT(status == ODP_CRYPTO_SES_CREATE_ERR_NONE); CU_ASSERT(odp_crypto_session_to_u64(session) != odp_crypto_session_to_u64(ODP_CRYPTO_SESSION_INVALID)); /* Prepare input data */ odp_packet_t pkt = odp_packet_alloc(suite_context.pool, plaintext_len + digest_len); CU_ASSERT(pkt != ODP_PACKET_INVALID); uint8_t *data_addr = odp_packet_data(pkt); memcpy(data_addr, plaintext, plaintext_len); int data_off = 0; /* Prepare input/output params */ odp_crypto_op_params_t op_params; memset(&op_params, 0, sizeof(op_params)); op_params.session = session; op_params.pkt = pkt; op_params.out_pkt = pkt; op_params.ctx = (void *)0xdeadbeef; if (cipher_range) { op_params.cipher_range = *cipher_range; data_off = cipher_range->offset; } else { op_params.cipher_range.offset = data_off; op_params.cipher_range.length = plaintext_len; } if (auth_range) { op_params.auth_range = *auth_range; } else { op_params.auth_range.offset = data_off; op_params.auth_range.length = plaintext_len; } if (op_iv_ptr) op_params.override_iv_ptr = op_iv_ptr; op_params.hash_result_offset = plaintext_len; rc = odp_crypto_operation(&op_params, &posted, &result); if (rc < 0) { CU_FAIL("Failed odp_crypto_operation()"); goto cleanup; } if (posted) { /* Poll completion queue for results */ do { event = odp_queue_deq(suite_context.queue); } while (event == ODP_EVENT_INVALID); compl_event = odp_crypto_compl_from_event(event); CU_ASSERT(odp_crypto_compl_to_u64(compl_event) == odp_crypto_compl_to_u64(odp_crypto_compl_from_event(event))); odp_crypto_compl_result(compl_event, &result); odp_crypto_compl_free(compl_event); } CU_ASSERT(result.ok); CU_ASSERT(result.pkt == pkt); if (cipher_alg != ODP_CIPHER_ALG_NULL) { CU_ASSERT(!memcmp(data_addr, ciphertext, ciphertext_len)); if (memcmp(data_addr, ciphertext, ciphertext_len)) { printf("data:\n"); unsigned j; for (j = 0; j < ciphertext_len; ++j) printf("%02x ", data_addr[j]); printf("\ncipher: \n"); for (j = 0; j < ciphertext_len; ++j) printf("%02x ", ciphertext[j]); printf("\n\n"); }; }; if (op == ODP_CRYPTO_OP_ENCODE && auth_alg != ODP_AUTH_ALG_NULL) CU_ASSERT(!memcmp(data_addr + op_params.hash_result_offset, digest, digest_len)); CU_ASSERT(result.ctx == (void *)0xdeadbeef); cleanup: rc = odp_crypto_session_destroy(session); CU_ASSERT(!rc); odp_packet_free(pkt); }
void pktio_test_send_failure(void) { odp_pktio_t pktio_tx, pktio_rx; odp_packet_t pkt_tbl[TX_BATCH_LEN]; uint32_t pkt_seq[TX_BATCH_LEN]; int ret, mtu, i, alloc_pkts; odp_pool_param_t pool_params; odp_pool_t pkt_pool; int long_pkt_idx = TX_BATCH_LEN / 2; pktio_info_t info_rx; pktio_tx = create_pktio(0, ODP_PKTIN_MODE_RECV, ODP_PKTOUT_MODE_SEND); if (pktio_tx == ODP_PKTIO_INVALID) { CU_FAIL("failed to open pktio"); return; } /* read the MTU from the transmit interface */ mtu = odp_pktio_mtu(pktio_tx); ret = odp_pktio_start(pktio_tx); CU_ASSERT_FATAL(ret == 0); /* configure the pool so that we can generate test packets larger * than the interface MTU */ memset(&pool_params, 0, sizeof(pool_params)); pool_params.pkt.len = mtu + 32; pool_params.pkt.seg_len = pool_params.pkt.len; pool_params.pkt.num = TX_BATCH_LEN + 1; pool_params.type = ODP_POOL_PACKET; pkt_pool = odp_pool_create("pkt_pool_oversize", &pool_params); CU_ASSERT_FATAL(pkt_pool != ODP_POOL_INVALID); if (num_ifaces > 1) { pktio_rx = create_pktio(1, ODP_PKTIN_MODE_RECV, ODP_PKTOUT_MODE_SEND); ret = odp_pktio_start(pktio_rx); CU_ASSERT_FATAL(ret == 0); } else { pktio_rx = pktio_tx; } /* generate a batch of packets with a single overly long packet * in the middle */ for (i = 0; i < TX_BATCH_LEN; ++i) { uint32_t pkt_len; if (i == long_pkt_idx) pkt_len = pool_params.pkt.len; else pkt_len = PKT_LEN_NORMAL; pkt_tbl[i] = odp_packet_alloc(pkt_pool, pkt_len); if (pkt_tbl[i] == ODP_PACKET_INVALID) break; pkt_seq[i] = pktio_init_packet(pkt_tbl[i]); pktio_pkt_set_macs(pkt_tbl[i], pktio_tx, pktio_rx); if (pktio_fixup_checksums(pkt_tbl[i]) != 0) { odp_packet_free(pkt_tbl[i]); break; } if (pkt_seq[i] == TEST_SEQ_INVALID) { odp_packet_free(pkt_tbl[i]); break; } } alloc_pkts = i; if (alloc_pkts == TX_BATCH_LEN) { /* try to send the batch with the long packet in the middle, * the initial short packets should be sent successfully */ odp_errno_zero(); ret = odp_pktio_send(pktio_tx, pkt_tbl, TX_BATCH_LEN); CU_ASSERT(ret == long_pkt_idx); CU_ASSERT(odp_errno() == 0); info_rx.id = pktio_rx; info_rx.outq = ODP_QUEUE_INVALID; info_rx.inq = ODP_QUEUE_INVALID; info_rx.in_mode = ODP_PKTIN_MODE_RECV; for (i = 0; i < ret; ++i) { pkt_tbl[i] = wait_for_packet(&info_rx, pkt_seq[i], ODP_TIME_SEC_IN_NS); if (pkt_tbl[i] == ODP_PACKET_INVALID) break; } if (i == ret) { /* now try to send starting with the too-long packet * and verify it fails */ odp_errno_zero(); ret = odp_pktio_send(pktio_tx, &pkt_tbl[long_pkt_idx], TX_BATCH_LEN - long_pkt_idx); CU_ASSERT(ret == -1); CU_ASSERT(odp_errno() != 0); } else { CU_FAIL("failed to receive transmitted packets\n"); } /* now reduce the size of the long packet and attempt to send * again - should work this time */ i = long_pkt_idx; odp_packet_pull_tail(pkt_tbl[i], odp_packet_len(pkt_tbl[i]) - PKT_LEN_NORMAL); pkt_seq[i] = pktio_init_packet(pkt_tbl[i]); pktio_pkt_set_macs(pkt_tbl[i], pktio_tx, pktio_rx); ret = pktio_fixup_checksums(pkt_tbl[i]); CU_ASSERT_FATAL(ret == 0); CU_ASSERT_FATAL(pkt_seq[i] != TEST_SEQ_INVALID); ret = odp_pktio_send(pktio_tx, &pkt_tbl[i], TX_BATCH_LEN - i); CU_ASSERT_FATAL(ret == (TX_BATCH_LEN - i)); for (; i < TX_BATCH_LEN; ++i) { pkt_tbl[i] = wait_for_packet(&info_rx, pkt_seq[i], ODP_TIME_SEC_IN_NS); if (pkt_tbl[i] == ODP_PACKET_INVALID) break; } CU_ASSERT(i == TX_BATCH_LEN); } else { CU_FAIL("failed to generate test packets\n"); } for (i = 0; i < alloc_pkts; ++i) { if (pkt_tbl[i] != ODP_PACKET_INVALID) odp_packet_free(pkt_tbl[i]); } if (pktio_rx != pktio_tx) CU_ASSERT(odp_pktio_close(pktio_rx) == 0); CU_ASSERT(odp_pktio_close(pktio_tx) == 0); CU_ASSERT(odp_pool_destroy(pkt_pool) == 0); }