void test_pktio_pmr_match_set_cos(void) { uint32_t addr = 0; uint32_t mask; odph_ipv4hdr_t *ip; odph_udphdr_t *udp; odp_packet_t pkt; odp_queue_t queue; uint32_t seq; pkt = create_packet(false); seq = cls_pkt_get_seq(pkt); ip = (odph_ipv4hdr_t *)odp_packet_l3_ptr(pkt, NULL); parse_ipv4_string(CLS_PMR_SET_SADDR, &addr, &mask); ip->src_addr = odp_cpu_to_be_32(addr); ip->chksum = 0; ip->chksum = odp_cpu_to_be_16(odph_ipv4_csum_update(pkt)); udp = (odph_udphdr_t *)odp_packet_l4_ptr(pkt, NULL); udp->src_port = odp_cpu_to_be_16(CLS_PMR_SET_SPORT); enqueue_loop_interface(pkt); pkt = receive_packet(&queue, ODP_TIME_SEC); CU_ASSERT(queue == queue_list[CLS_PMR_SET]); CU_ASSERT(seq == cls_pkt_get_seq(pkt)); odp_packet_free(pkt); }
void configure_pktio_pmr_match_set_cos(void) { int retval; odp_pmr_match_t pmr_terms[2]; uint16_t val; uint16_t maskport; int num_terms = 2; /* one pmr for each L3 and L4 */ odp_queue_param_t qparam; char cosname[ODP_COS_NAME_LEN]; char queuename[ODP_QUEUE_NAME_LEN]; uint32_t addr = 0; uint32_t mask; parse_ipv4_string(CLS_PMR_SET_SADDR, &addr, &mask); pmr_terms[0].term = ODP_PMR_SIP_ADDR; pmr_terms[0].val = &addr; pmr_terms[0].mask = &mask; pmr_terms[0].val_sz = sizeof(addr); val = CLS_PMR_SET_SPORT; maskport = 0xffff; pmr_terms[1].term = ODP_PMR_UDP_SPORT; pmr_terms[1].val = &val; pmr_terms[1].mask = &maskport; pmr_terms[1].val_sz = sizeof(val); retval = odp_pmr_match_set_create(num_terms, pmr_terms, &pmr_set); CU_ASSERT(retval > 0); sprintf(cosname, "cos_pmr_set"); cos_list[CLS_PMR_SET] = odp_cos_create(cosname); CU_ASSERT_FATAL(cos_list[CLS_PMR_SET] != ODP_COS_INVALID) qparam.sched.prio = ODP_SCHED_PRIO_HIGHEST; qparam.sched.sync = ODP_SCHED_SYNC_NONE; qparam.sched.group = ODP_SCHED_GROUP_ALL; sprintf(queuename, "%s", "cos_pmr_set_queue"); queue_list[CLS_PMR_SET] = odp_queue_create(queuename, ODP_QUEUE_TYPE_SCHED, &qparam); CU_ASSERT_FATAL(queue_list[CLS_PMR_SET] != ODP_QUEUE_INVALID); retval = odp_cos_set_queue(cos_list[CLS_PMR_SET], queue_list[CLS_PMR_SET]); CU_ASSERT(retval == 0); retval = odp_pktio_pmr_match_set_cos(pmr_set, pktio_loop, cos_list[CLS_PMR_SET]); CU_ASSERT(retval == 0); }
int create_stream_db_entry(char *input) { int pos = 0; char *local; char *str; char *save; char *token; stream_db_entry_t *entry = &stream_db->array[stream_db->index]; /* Verify we have a good entry */ if (MAX_DB <= stream_db->index) return -1; /* Make a local copy */ local = malloc(strlen(input) + 1); if (NULL == local) return -1; strcpy(local, input); /* Setup for using "strtok_r" to search input string */ str = local; save = NULL; /* Parse tokens separated by ':' */ while (NULL != (token = strtok_r(str, ":", &save))) { str = NULL; /* reset str for subsequent strtok_r calls */ /* Parse token based on its position */ switch (pos) { case 0: parse_ipv4_string(token, &entry->src_ip, NULL); break; case 1: parse_ipv4_string(token, &entry->dst_ip, NULL); break; case 2: entry->input.loop = loop_if_index(token); if (entry->input.loop < 0) { EXAMPLE_ERR("Error: stream must have input" " loop\n"); exit(EXIT_FAILURE); } break; case 3: entry->output.loop = loop_if_index(token); break; case 4: entry->count = atoi(token); break; case 5: entry->length = atoi(token); if (entry->length < sizeof(stream_pkt_hdr_t)) entry->length = 0; else entry->length -= sizeof(stream_pkt_hdr_t); break; default: printf("ERROR: extra token \"%s\" at position %d\n", token, pos); break; } /* Advance to next position */ pos++; } /* Verify we parsed exactly the number of tokens we expected */ if (6 != pos) { printf("ERROR: \"%s\" contains %d tokens, expected 6\n", input, pos); free(local); return -1; } /* Add stream to the list */ entry->id = stream_db->index++; entry->next = stream_db->list; stream_db->list = entry; free(local); return 0; }
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; }
int create_fwd_db_entry(char *input) { int pos = 0; char *local; char *str; char *save; char *token; fwd_db_entry_t *entry = &fwd_db->array[fwd_db->index]; /* Verify we haven't run out of space */ if (MAX_DB <= fwd_db->index) return -1; /* Make a local copy */ local = malloc(strlen(input) + 1); if (NULL == local) return -1; strcpy(local, input); /* Setup for using "strtok_r" to search input string */ str = local; save = NULL; /* Parse tokens separated by ':' */ while (NULL != (token = strtok_r(str, ":", &save))) { str = NULL; /* reset str for subsequent strtok_r calls */ /* Parse token based on its position */ switch (pos) { case 0: parse_ipv4_string(token, &entry->subnet.addr, &entry->subnet.mask); break; case 1: strncpy(entry->oif, token, OIF_LEN - 1); entry->oif[OIF_LEN - 1] = 0; break; case 2: parse_mac_string(token, entry->dst_mac); break; default: printf("ERROR: extra token \"%s\" at position %d\n", token, pos); break; } /* Advance to next position */ pos++; } /* Verify we parsed exactly the number of tokens we expected */ if (3 != pos) { printf("ERROR: \"%s\" contains %d tokens, expected 3\n", input, pos); free(local); return -1; } /* Reset queue to invalid */ entry->queue = ODP_QUEUE_INVALID; /* Add route to the list */ fwd_db->index++; entry->next = fwd_db->list; fwd_db->list = entry; free(local); return 0; }
void configure_cls_pmr_chain(void) { /* PKTIO --> PMR_SRC(SRC IP ADDR) --> PMR_DST (TCP SPORT) */ /* Packet matching only the SRC IP ADDR should be delivered in queue[CLS_PMR_CHAIN_SRC] and a packet matching both SRC IP ADDR and TCP SPORT should be delivered to queue[CLS_PMR_CHAIN_DST] */ uint16_t val; uint16_t maskport; int retval; char cosname[ODP_QUEUE_NAME_LEN]; odp_queue_param_t qparam; char queuename[ODP_QUEUE_NAME_LEN]; uint32_t addr; uint32_t mask; sprintf(cosname, "SrcCos"); cos_list[CLS_PMR_CHAIN_SRC] = odp_cos_create(cosname); CU_ASSERT_FATAL(cos_list[CLS_PMR_CHAIN_SRC] != ODP_COS_INVALID) qparam.sched.prio = ODP_SCHED_PRIO_NORMAL; qparam.sched.sync = ODP_SCHED_SYNC_NONE; qparam.sched.group = ODP_SCHED_GROUP_ALL; sprintf(queuename, "%s", "SrcQueue"); queue_list[CLS_PMR_CHAIN_SRC] = odp_queue_create(queuename, ODP_QUEUE_TYPE_SCHED, &qparam); CU_ASSERT_FATAL(queue_list[CLS_PMR_CHAIN_SRC] != ODP_QUEUE_INVALID); retval = odp_cos_set_queue(cos_list[CLS_PMR_CHAIN_SRC], queue_list[CLS_PMR_CHAIN_SRC]); CU_ASSERT(retval == 0); sprintf(cosname, "DstCos"); cos_list[CLS_PMR_CHAIN_DST] = odp_cos_create(cosname); CU_ASSERT_FATAL(cos_list[CLS_PMR_CHAIN_DST] != ODP_COS_INVALID); qparam.sched.prio = ODP_SCHED_PRIO_NORMAL; qparam.sched.sync = ODP_SCHED_SYNC_NONE; qparam.sched.group = ODP_SCHED_GROUP_ALL; sprintf(queuename, "%s", "DstQueue"); queue_list[CLS_PMR_CHAIN_DST] = odp_queue_create(queuename, ODP_QUEUE_TYPE_SCHED, &qparam); CU_ASSERT_FATAL(queue_list[CLS_PMR_CHAIN_DST] != ODP_QUEUE_INVALID); retval = odp_cos_set_queue(cos_list[CLS_PMR_CHAIN_DST], queue_list[CLS_PMR_CHAIN_DST]); parse_ipv4_string(CLS_PMR_CHAIN_SADDR, &addr, &mask); pmr_list[CLS_PMR_CHAIN_SRC] = odp_pmr_create(ODP_PMR_SIP_ADDR, &addr, &mask, sizeof(addr)); CU_ASSERT_FATAL(pmr_list[CLS_PMR_CHAIN_SRC] != ODP_PMR_INVAL); val = CLS_PMR_CHAIN_SPORT; maskport = 0xffff; pmr_list[CLS_PMR_CHAIN_DST] = odp_pmr_create(ODP_PMR_UDP_SPORT, &val, &maskport, sizeof(val)); CU_ASSERT_FATAL(pmr_list[CLS_PMR_CHAIN_DST] != ODP_PMR_INVAL); retval = odp_pktio_pmr_cos(pmr_list[CLS_PMR_CHAIN_SRC], pktio_loop, cos_list[CLS_PMR_CHAIN_SRC]); CU_ASSERT(retval == 0); retval = odp_cos_pmr_cos(pmr_list[CLS_PMR_CHAIN_DST], cos_list[CLS_PMR_CHAIN_SRC], cos_list[CLS_PMR_CHAIN_DST]); CU_ASSERT(retval == 0); }