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 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; }
static inline unsigned pkt_mmap_v2_rx(pktio_entry_t *pktio_entry, pkt_sock_mmap_t *pkt_sock, odp_packet_t pkt_table[], unsigned len, unsigned char if_mac[]) { union frame_map ppd; odp_time_t ts_val; odp_time_t *ts = NULL; unsigned frame_num, next_frame_num; uint8_t *pkt_buf; int pkt_len; struct ethhdr *eth_hdr; unsigned i; unsigned nb_rx; struct ring *ring; int ret; if (pktio_entry->s.config.pktin.bit.ts_all || pktio_entry->s.config.pktin.bit.ts_ptp) ts = &ts_val; ring = &pkt_sock->rx_ring; frame_num = ring->frame_num; for (i = 0, nb_rx = 0; i < len; i++) { odp_packet_hdr_t *hdr; odp_packet_hdr_t parsed_hdr; odp_pool_t pool = pkt_sock->pool; int num; if (!mmap_rx_kernel_ready(ring->rd[frame_num].iov_base)) break; if (ts != NULL) ts_val = odp_time_global(); ppd.raw = ring->rd[frame_num].iov_base; next_frame_num = (frame_num + 1) % ring->rd_num; pkt_buf = (uint8_t *)ppd.raw + ppd.v2->tp_h.tp_mac; pkt_len = ppd.v2->tp_h.tp_snaplen; /* Don't receive packets sent by ourselves */ eth_hdr = (struct ethhdr *)pkt_buf; if (odp_unlikely(ethaddrs_equal(if_mac, eth_hdr->h_source))) { mmap_rx_user_ready(ppd.raw); /* drop */ frame_num = next_frame_num; continue; } if (ppd.v2->tp_h.tp_status & TP_STATUS_VLAN_VALID) pkt_buf = pkt_mmap_vlan_insert(pkt_buf, ppd.v2->tp_h.tp_mac, ppd.v2->tp_h.tp_vlan_tci, &pkt_len); if (pktio_cls_enabled(pktio_entry)) { if (cls_classify_packet(pktio_entry, pkt_buf, pkt_len, pkt_len, &pool, &parsed_hdr)) { mmap_rx_user_ready(ppd.raw); /* drop */ frame_num = next_frame_num; continue; } } num = packet_alloc_multi(pool, pkt_len, &pkt_table[nb_rx], 1); if (odp_unlikely(num != 1)) { pkt_table[nb_rx] = ODP_PACKET_INVALID; mmap_rx_user_ready(ppd.raw); /* drop */ frame_num = next_frame_num; continue; } hdr = odp_packet_hdr(pkt_table[nb_rx]); ret = odp_packet_copy_from_mem(pkt_table[nb_rx], 0, pkt_len, pkt_buf); if (ret != 0) { odp_packet_free(pkt_table[nb_rx]); mmap_rx_user_ready(ppd.raw); /* drop */ frame_num = next_frame_num; continue; } hdr->input = pktio_entry->s.handle; if (pktio_cls_enabled(pktio_entry)) copy_packet_cls_metadata(&parsed_hdr, hdr); else packet_parse_l2(&hdr->p, pkt_len); packet_set_ts(hdr, ts); mmap_rx_user_ready(ppd.raw); frame_num = next_frame_num; nb_rx++; } ring->frame_num = frame_num; return nb_rx; }
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; }
/* * 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; 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, gbl_args->src_mac, ODPH_ETHADDR_LEN); memcpy(eth->dst.addr, gbl_args->dst_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_copy_from_mem(pkt, offset, sizeof(pkt_hdr), &pkt_hdr) != 0) LOG_ABORT("Failed to generate test packet.\n"); return pkt; }