src/drivers/trex_i40e_fdir.c
static int
i40e_fdir_construct_pkt(struct i40e_pf *pf,
			     const struct trex_rte_eth_fdir_input *fdir_input,
			     unsigned char *raw_pkt)
{
	unsigned char *payload, *ptr;
	struct rte_udp_hdr *udp;
	struct rte_tcp_hdr *tcp;
	struct rte_sctp_hdr *sctp;
	uint8_t size, dst = 0;
	uint8_t i, pit_idx, set_idx = I40E_FLXPLD_L4_IDX; /* use l4 by default*/
	int len;

	/* fill the ethernet and IP head */
	len = i40e_fdir_fill_eth_ip_head(fdir_input, raw_pkt,
					 !!fdir_input->flow_ext.vlan_tci);
	if (len < 0)
		return -EINVAL;

	/* fill the L4 head */
	switch (fdir_input->flow_type) {
	case RTE_ETH_FLOW_NONFRAG_IPV4_UDP:
		udp = (struct rte_udp_hdr *)(raw_pkt + len);
		payload = (unsigned char *)udp + sizeof(struct rte_udp_hdr);
		/*
		 * The source and destination fields in the transmitted packet
		 * need to be presented in a reversed order with respect
		 * to the expected received packets.
		 */
		udp->src_port = fdir_input->flow.udp4_flow.dst_port;
		udp->dst_port = fdir_input->flow.udp4_flow.src_port;
		udp->dgram_len = rte_cpu_to_be_16(I40E_FDIR_UDP_DEFAULT_LEN);
		break;

	case RTE_ETH_FLOW_NONFRAG_IPV4_TCP:
		tcp = (struct rte_tcp_hdr *)(raw_pkt + len);
		payload = (unsigned char *)tcp + sizeof(struct rte_tcp_hdr);
		/*
		 * The source and destination fields in the transmitted packet
		 * need to be presented in a reversed order with respect
		 * to the expected received packets.
		 */
		tcp->src_port = fdir_input->flow.tcp4_flow.dst_port;
		tcp->dst_port = fdir_input->flow.tcp4_flow.src_port;
		tcp->data_off = I40E_FDIR_TCP_DEFAULT_DATAOFF;
		break;

	case RTE_ETH_FLOW_NONFRAG_IPV4_SCTP:
		sctp = (struct rte_sctp_hdr *)(raw_pkt + len);
		payload = (unsigned char *)sctp + sizeof(struct rte_sctp_hdr);
		/*
		 * The source and destination fields in the transmitted packet
		 * need to be presented in a reversed order with respect
		 * to the expected received packets.
		 */
		sctp->src_port = fdir_input->flow.sctp4_flow.dst_port;
		sctp->dst_port = fdir_input->flow.sctp4_flow.src_port;
		sctp->tag = fdir_input->flow.sctp4_flow.verify_tag;
		break;

	case RTE_ETH_FLOW_NONFRAG_IPV4_OTHER:
	case RTE_ETH_FLOW_FRAG_IPV4:
		payload = raw_pkt + len;
		set_idx = I40E_FLXPLD_L3_IDX;
		break;

	case RTE_ETH_FLOW_NONFRAG_IPV6_UDP:
		udp = (struct rte_udp_hdr *)(raw_pkt + len);
		payload = (unsigned char *)udp + sizeof(struct rte_udp_hdr);
		/*
		 * The source and destination fields in the transmitted packet
		 * need to be presented in a reversed order with respect
		 * to the expected received packets.
		 */
		udp->src_port = fdir_input->flow.udp6_flow.dst_port;
		udp->dst_port = fdir_input->flow.udp6_flow.src_port;
		udp->dgram_len = rte_cpu_to_be_16(I40E_FDIR_IPv6_PAYLOAD_LEN);
		break;

	case RTE_ETH_FLOW_NONFRAG_IPV6_TCP:
		tcp = (struct rte_tcp_hdr *)(raw_pkt + len);
		payload = (unsigned char *)tcp + sizeof(struct rte_tcp_hdr);
		/*
		 * The source and destination fields in the transmitted packet
		 * need to be presented in a reversed order with respect
		 * to the expected received packets.
		 */
		tcp->data_off = I40E_FDIR_TCP_DEFAULT_DATAOFF;
		tcp->src_port = fdir_input->flow.udp6_flow.dst_port;
		tcp->dst_port = fdir_input->flow.udp6_flow.src_port;
		break;

	case RTE_ETH_FLOW_NONFRAG_IPV6_SCTP:
		sctp = (struct rte_sctp_hdr *)(raw_pkt + len);
		payload = (unsigned char *)sctp + sizeof(struct rte_sctp_hdr);
		/*
		 * The source and destination fields in the transmitted packet
		 * need to be presented in a reversed order with respect
		 * to the expected received packets.
		 */
		sctp->src_port = fdir_input->flow.sctp6_flow.dst_port;
		sctp->dst_port = fdir_input->flow.sctp6_flow.src_port;
		sctp->tag = fdir_input->flow.sctp6_flow.verify_tag;
		break;

	case RTE_ETH_FLOW_NONFRAG_IPV6_OTHER:
	case RTE_ETH_FLOW_FRAG_IPV6:
		payload = raw_pkt + len;
		set_idx = I40E_FLXPLD_L3_IDX;
		break;
	case RTE_ETH_FLOW_L2_PAYLOAD:
		payload = raw_pkt + len;
		/*
		 * ARP packet is a special case on which the payload
		 * starts after the whole ARP header
		 */
		if (fdir_input->flow.l2_flow.ether_type ==
				rte_cpu_to_be_16(RTE_ETHER_TYPE_ARP))
			payload += sizeof(struct rte_arp_hdr);
		set_idx = I40E_FLXPLD_L2_IDX;
		break;
	default:
		PMD_DRV_LOG(ERR, "unknown flow type %u.", fdir_input->flow_type);
		return -EINVAL;
	}

	/* fill the flexbytes to payload */
	for (i = 0; i < I40E_MAX_FLXPLD_FIED; i++) {
		pit_idx = set_idx * I40E_MAX_FLXPLD_FIED + i;
		size = pf->fdir.flex_set[pit_idx].size;
		if (size == 0)
			continue;
		dst = pf->fdir.flex_set[pit_idx].dst_offset * sizeof(uint16_t);
		ptr = payload +
			pf->fdir.flex_set[pit_idx].src_offset * sizeof(uint16_t);
		rte_memcpy(ptr,
				 &fdir_input->flow_ext.flexbytes[dst],
				 size * sizeof(uint16_t));
	}

	return 0;
}
/*
 * i40e_fdir_construct_pkt - construct packet based on fields in input
 * @pf: board private structure
 * @fdir_input: input set of the flow director entry
 * @raw_pkt: a packet to be constructed
 */
construct packet based on fields in input
@pf: board private structure
@fdir_input: input set of the flow director entry
@raw_pkt: a packet to be constructed
construct packet based on fields in input @pf : board private structure @fdir_input : input set of the flow director entry @raw_pkt : a packet to be constructed
static int
i40e_fdir_construct_pkt(struct i40e_pf *pf,
			     const struct trex_rte_eth_fdir_input *fdir_input,
			     unsigned char *raw_pkt)
{
	unsigned char *payload, *ptr;
	struct rte_udp_hdr *udp;
	struct rte_tcp_hdr *tcp;
	struct rte_sctp_hdr *sctp;
	uint8_t size, dst = 0;
	uint8_t i, pit_idx, set_idx = I40E_FLXPLD_L4_IDX; 
	int len;
	len = i40e_fdir_fill_eth_ip_head(fdir_input, raw_pkt,
					 !!fdir_input->flow_ext.vlan_tci);
	if (len < 0)
		return -EINVAL;
	switch (fdir_input->flow_type) {
	case RTE_ETH_FLOW_NONFRAG_IPV4_UDP:
		udp = (struct rte_udp_hdr *)(raw_pkt + len);
		payload = (unsigned char *)udp + sizeof(struct rte_udp_hdr);
		udp->src_port = fdir_input->flow.udp4_flow.dst_port;
		udp->dst_port = fdir_input->flow.udp4_flow.src_port;
		udp->dgram_len = rte_cpu_to_be_16(I40E_FDIR_UDP_DEFAULT_LEN);
		break;
	case RTE_ETH_FLOW_NONFRAG_IPV4_TCP:
		tcp = (struct rte_tcp_hdr *)(raw_pkt + len);
		payload = (unsigned char *)tcp + sizeof(struct rte_tcp_hdr);
		tcp->src_port = fdir_input->flow.tcp4_flow.dst_port;
		tcp->dst_port = fdir_input->flow.tcp4_flow.src_port;
		tcp->data_off = I40E_FDIR_TCP_DEFAULT_DATAOFF;
		break;
	case RTE_ETH_FLOW_NONFRAG_IPV4_SCTP:
		sctp = (struct rte_sctp_hdr *)(raw_pkt + len);
		payload = (unsigned char *)sctp + sizeof(struct rte_sctp_hdr);
		sctp->src_port = fdir_input->flow.sctp4_flow.dst_port;
		sctp->dst_port = fdir_input->flow.sctp4_flow.src_port;
		sctp->tag = fdir_input->flow.sctp4_flow.verify_tag;
		break;
	case RTE_ETH_FLOW_NONFRAG_IPV4_OTHER:
	case RTE_ETH_FLOW_FRAG_IPV4:
		payload = raw_pkt + len;
		set_idx = I40E_FLXPLD_L3_IDX;
		break;
	case RTE_ETH_FLOW_NONFRAG_IPV6_UDP:
		udp = (struct rte_udp_hdr *)(raw_pkt + len);
		payload = (unsigned char *)udp + sizeof(struct rte_udp_hdr);
		udp->src_port = fdir_input->flow.udp6_flow.dst_port;
		udp->dst_port = fdir_input->flow.udp6_flow.src_port;
		udp->dgram_len = rte_cpu_to_be_16(I40E_FDIR_IPv6_PAYLOAD_LEN);
		break;
	case RTE_ETH_FLOW_NONFRAG_IPV6_TCP:
		tcp = (struct rte_tcp_hdr *)(raw_pkt + len);
		payload = (unsigned char *)tcp + sizeof(struct rte_tcp_hdr);
		tcp->data_off = I40E_FDIR_TCP_DEFAULT_DATAOFF;
		tcp->src_port = fdir_input->flow.udp6_flow.dst_port;
		tcp->dst_port = fdir_input->flow.udp6_flow.src_port;
		break;
	case RTE_ETH_FLOW_NONFRAG_IPV6_SCTP:
		sctp = (struct rte_sctp_hdr *)(raw_pkt + len);
		payload = (unsigned char *)sctp + sizeof(struct rte_sctp_hdr);
		sctp->src_port = fdir_input->flow.sctp6_flow.dst_port;
		sctp->dst_port = fdir_input->flow.sctp6_flow.src_port;
		sctp->tag = fdir_input->flow.sctp6_flow.verify_tag;
		break;
	case RTE_ETH_FLOW_NONFRAG_IPV6_OTHER:
	case RTE_ETH_FLOW_FRAG_IPV6:
		payload = raw_pkt + len;
		set_idx = I40E_FLXPLD_L3_IDX;
		break;
	case RTE_ETH_FLOW_L2_PAYLOAD:
		payload = raw_pkt + len;
		if (fdir_input->flow.l2_flow.ether_type ==
				rte_cpu_to_be_16(RTE_ETHER_TYPE_ARP))
			payload += sizeof(struct rte_arp_hdr);
		set_idx = I40E_FLXPLD_L2_IDX;
		break;
	default:
		PMD_DRV_LOG(ERR, "unknown flow type %u.", fdir_input->flow_type);
		return -EINVAL;
	}
	for (i = 0; i < I40E_MAX_FLXPLD_FIED; i++) {
		pit_idx = set_idx * I40E_MAX_FLXPLD_FIED + i;
		size = pf->fdir.flex_set[pit_idx].size;
		if (size == 0)
			continue;
		dst = pf->fdir.flex_set[pit_idx].dst_offset * sizeof(uint16_t);
		ptr = payload +
			pf->fdir.flex_set[pit_idx].src_offset * sizeof(uint16_t);
		rte_memcpy(ptr,
				 &fdir_input->flow_ext.flexbytes[dst],
				 size * sizeof(uint16_t));
	}
	return 0;
}
static int i40e_fdir_construct_pkt ( struct i40e_pf * pf , const struct trex_rte_eth_fdir_input * fdir_input , unsigned char * raw_pkt ) { unsigned char * payload , * ptr ; struct rte_udp_hdr * udp ; struct rte_tcp_hdr * tcp ; struct rte_sctp_hdr * sctp ; uint8_t size , dst = 0 ; uint8_t i , pit_idx , set_idx = I40E_FLXPLD_L4_IDX ; int len ; len = i40e_fdir_fill_eth_ip_head ( fdir_input , raw_pkt , ! ! fdir_input -> flow_ext . vlan_tci ) ; if ( len < 0 ) return - EINVAL ; switch ( fdir_input -> flow_type ) { case RTE_ETH_FLOW_NONFRAG_IPV4_UDP : udp = ( struct rte_udp_hdr * ) ( raw_pkt + len ) ; payload = ( unsigned char * ) udp + sizeof ( struct rte_udp_hdr ) ; udp -> src_port = fdir_input -> flow . udp4_flow . dst_port ; udp -> dst_port = fdir_input -> flow . udp4_flow . src_port ; udp -> dgram_len = rte_cpu_to_be_16 ( I40E_FDIR_UDP_DEFAULT_LEN ) ; break ; case RTE_ETH_FLOW_NONFRAG_IPV4_TCP : tcp = ( struct rte_tcp_hdr * ) ( raw_pkt + len ) ; payload = ( unsigned char * ) tcp + sizeof ( struct rte_tcp_hdr ) ; tcp -> src_port = fdir_input -> flow . tcp4_flow . dst_port ; tcp -> dst_port = fdir_input -> flow . tcp4_flow . src_port ; tcp -> data_off = I40E_FDIR_TCP_DEFAULT_DATAOFF ; break ; case RTE_ETH_FLOW_NONFRAG_IPV4_SCTP : sctp = ( struct rte_sctp_hdr * ) ( raw_pkt + len ) ; payload = ( unsigned char * ) sctp + sizeof ( struct rte_sctp_hdr ) ; sctp -> src_port = fdir_input -> flow . sctp4_flow . dst_port ; sctp -> dst_port = fdir_input -> flow . sctp4_flow . src_port ; sctp -> tag = fdir_input -> flow . sctp4_flow . verify_tag ; break ; case RTE_ETH_FLOW_NONFRAG_IPV4_OTHER : case RTE_ETH_FLOW_FRAG_IPV4 : payload = raw_pkt + len ; set_idx = I40E_FLXPLD_L3_IDX ; break ; case RTE_ETH_FLOW_NONFRAG_IPV6_UDP : udp = ( struct rte_udp_hdr * ) ( raw_pkt + len ) ; payload = ( unsigned char * ) udp + sizeof ( struct rte_udp_hdr ) ; udp -> src_port = fdir_input -> flow . udp6_flow . dst_port ; udp -> dst_port = fdir_input -> flow . udp6_flow . src_port ; udp -> dgram_len = rte_cpu_to_be_16 ( I40E_FDIR_IPv6_PAYLOAD_LEN ) ; break ; case RTE_ETH_FLOW_NONFRAG_IPV6_TCP : tcp = ( struct rte_tcp_hdr * ) ( raw_pkt + len ) ; payload = ( unsigned char * ) tcp + sizeof ( struct rte_tcp_hdr ) ; tcp -> data_off = I40E_FDIR_TCP_DEFAULT_DATAOFF ; tcp -> src_port = fdir_input -> flow . udp6_flow . dst_port ; tcp -> dst_port = fdir_input -> flow . udp6_flow . src_port ; break ; case RTE_ETH_FLOW_NONFRAG_IPV6_SCTP : sctp = ( struct rte_sctp_hdr * ) ( raw_pkt + len ) ; payload = ( unsigned char * ) sctp + sizeof ( struct rte_sctp_hdr ) ; sctp -> src_port = fdir_input -> flow . sctp6_flow . dst_port ; sctp -> dst_port = fdir_input -> flow . sctp6_flow . src_port ; sctp -> tag = fdir_input -> flow . sctp6_flow . verify_tag ; break ; case RTE_ETH_FLOW_NONFRAG_IPV6_OTHER : case RTE_ETH_FLOW_FRAG_IPV6 : payload = raw_pkt + len ; set_idx = I40E_FLXPLD_L3_IDX ; break ; case RTE_ETH_FLOW_L2_PAYLOAD : payload = raw_pkt + len ; if ( fdir_input -> flow . l2_flow . ether_type == rte_cpu_to_be_16 ( RTE_ETHER_TYPE_ARP ) ) payload += sizeof ( struct rte_arp_hdr ) ; set_idx = I40E_FLXPLD_L2_IDX ; break ; default : PMD_DRV_LOG ( ERR , " " , fdir_input -> flow_type ) ; return - EINVAL ; } for ( i = 0 ; i < I40E_MAX_FLXPLD_FIED ; i ++ ) { pit_idx = set_idx * I40E_MAX_FLXPLD_FIED + i ; size = pf -> fdir . flex_set [ pit_idx ] . size ; if ( size == 0 ) continue ; dst = pf -> fdir . flex_set [ pit_idx ] . dst_offset * sizeof ( uint16_t ) ; ptr = payload + pf -> fdir . flex_set [ pit_idx ] . src_offset * sizeof ( uint16_t ) ; rte_memcpy ( ptr , & fdir_input -> flow_ext . flexbytes [ dst ] , size * sizeof ( uint16_t ) ) ; } return 0 ; }
i40e_fdir_construct_pkt - construct packet based on fields in input
 @pf: board private structure
 @fdir_input: input set of the flow director entry
 @raw_pkt: a packet to be constructed
i40e_fdir_construct_pkt - construct packet based on fields in input @pf : board private structure @fdir_input : input set of the flow director entry @raw_pkt : a packet to be constructed
/* use l4 by default*/ /* fill the ethernet and IP head */ /* fill the L4 head */ /*
		 * The source and destination fields in the transmitted packet
		 * need to be presented in a reversed order with respect
		 * to the expected received packets.
		 */ /*
		 * The source and destination fields in the transmitted packet
		 * need to be presented in a reversed order with respect
		 * to the expected received packets.
		 */ /*
		 * The source and destination fields in the transmitted packet
		 * need to be presented in a reversed order with respect
		 * to the expected received packets.
		 */ /*
		 * The source and destination fields in the transmitted packet
		 * need to be presented in a reversed order with respect
		 * to the expected received packets.
		 */ /*
		 * The source and destination fields in the transmitted packet
		 * need to be presented in a reversed order with respect
		 * to the expected received packets.
		 */ /*
		 * The source and destination fields in the transmitted packet
		 * need to be presented in a reversed order with respect
		 * to the expected received packets.
		 */ /*
		 * ARP packet is a special case on which the payload
		 * starts after the whole ARP header
		 */ /* fill the flexbytes to payload */