Beispiel #1
0
void
send_arp(struct arp *arp_pkt)
{
    struct rte_mbuf *mbuf = NULL;
    struct arp *arp_hdr = NULL;
    struct ether_hdr *eth = NULL;
    int i;

    mbuf = get_mbuf();
    assert(mbuf != NULL);
    arp_hdr = (struct arp *)rte_pktmbuf_prepend (mbuf, sizeof(struct arp));
    eth = (struct ether_hdr *)rte_pktmbuf_prepend (mbuf, sizeof(struct ether_hdr));
    logger(ARP, NORMAL, "Sending arp packet\n");
    memcpy(arp_hdr, arp_pkt, sizeof(struct arp));
    if(arp_pkt->opcode == ntohs(ARP_REQ)) {
        logger(ARP, ALL, "Sending arp request");
        eth->ether_type = htons(ETHER_TYPE_ARP);
        for(i=0; i<6; i++) {
            eth->d_addr.addr_bytes[i] = 0xff;
        }
        memcpy(&eth->s_addr.addr_bytes[0], arp_pkt->src_hw_add, sizeof(arp_pkt->hw_len));
    }
    if(arp_pkt->opcode == ntohs(ARP_REPLY)) {
        logger(ARP, ALL, "Sending arp reply");
        eth->ether_type = htons(ETHER_TYPE_ARP);
        for(i=0; i<6; i++) {
            eth->d_addr.addr_bytes[i] = 0xff;  // should not be a brodcast ideally. fix it.
        }
        // memcpy(&eth->d_addr.addr_bytes[0], arp_pkt->src_hw_add, sizeof(arp_pkt->hw_len));
        memcpy(&eth->s_addr.addr_bytes[0], arp_pkt->src_hw_add, sizeof(arp_pkt->hw_len));
    }
    send_packet_out(mbuf, 0);
}
Beispiel #2
0
void sendtcpdata(struct tcb *ptcb, unsigned char *data, int len)
{
   printf("Sending tcp data\n");
   static int counter_id = -1;
   if(counter_id == -1) {
      counter_id = create_counter("tcp_sent");
   }
   counter_inc(counter_id, len);
   //uint8_t tcp_len = 0x50 + add_mss_option(mbuf, 1300);// + add_winscale_option(mbuf, 7);
   struct rte_mbuf *mbuf = get_mbuf(); // remove mbuf from parameters.
   uint8_t data_len = add_tcp_data(mbuf, data, len);
   uint8_t option_len = 0;//add_winscale_option(mbuf, 7) + add_mss_option(mbuf, 1300) + add_timestamp_option(mbuf, 203032, 0);
   uint8_t tcp_len = 20 + option_len;
   uint8_t pad = (tcp_len%4) ? 4 - (tcp_len % 4): 0;
   tcp_len += pad;
   logger(LOG_TCP, NORMAL, "padding option %d for tcb %u\n",  pad, ptcb->identifier); 
   char *nop = rte_pktmbuf_prepend (mbuf, pad); // always pad the option to make total size multiple of 4.
   memset(nop, 0, pad);
   tcp_len = (tcp_len + 3) / 4;  // len is in multiple of 4 bytes;  20  will be 5
   tcp_len = tcp_len << 4; // len has upper 4 bits position in tcp header.
   logger(LOG_TCP, NORMAL, "sending tcp data of len %d total %d for tcb %u\n", data_len, tcp_len, ptcb->identifier);
   struct tcp_hdr *ptcphdr = (struct tcp_hdr *)rte_pktmbuf_prepend (mbuf, sizeof(struct tcp_hdr));
  // printf("head room2 = %d\n", rte_pktmbuf_headroom(mbuf));
   if(ptcphdr == NULL) {
    //  printf("tcp header is null\n");
   }
   ptcphdr->src_port = htons(ptcb->dport);
   ptcphdr->dst_port = htons(ptcb->sport);
   ptcphdr->sent_seq = htonl(ptcb->next_seq);
   ptcb->next_seq += data_len;
   if(((ptcb->tcp_flags & TCP_FLAG_SYN) == TCP_FLAG_SYN) || ((ptcb->tcp_flags & TCP_FLAG_FIN) == TCP_FLAG_FIN)) {
      logger(LOG_TCP, NORMAL, "Increasing seq number by one for flag syn or fin for tcb %u\n", ptcb->identifier);
      ptcb->next_seq += 1;
   }
   logger(LOG_TCP, LOG_LEVEL_NORMAL, "Next seq number is %u flags %u for tcb %u\n", ptcb->next_seq, ptcb->tcp_flags, ptcb->identifier);
   ptcphdr->recv_ack = htonl(ptcb->ack);
   ptcphdr->data_off = tcp_len;
   ptcphdr->tcp_flags =  ptcb->tcp_flags;
   ptcphdr->rx_win = 12000;
   ptcphdr->cksum = 0x0000;
   ptcphdr->tcp_urp = 0; 

   ptcb->tcp_flags = 0; //reset the flags as we have sent them in packet now.
   //mbuf->ol_flags |=  PKT_TX_IP_CKSUM; // someday will calclate checkum here only.
   
 //  printf(" null\n");
  // fflush(stdout);
   logger(LOG_TCP, NORMAL, "[SENDING TCP PACKET] sending tcp packet seq %u ack %u and datalen %u for tcb %u\n", ntohl(ptcphdr->sent_seq), ntohl(ptcphdr->recv_ack), data_len, ptcb->identifier);
   // push the mbuf in send_window unacknowledged data and increase the refrence count of this segment also start the rto timer for this tcb.
   PushDataToSendWindow(ptcb, mbuf, ntohl(ptcphdr->sent_seq), ptcb->next_seq, data_len);  
   ip_out(ptcb, mbuf, ptcphdr, data_len); 
}
Beispiel #3
0
//smallboy: We change the whole func here;
int ip_local_out(struct sk_buff *skb)
{
	//us_nic_port	*port = NULL;
	//port = get_local_out_port(skb);
	//if (port == NULL  ){
	//	IP_INC_STATS_BH(skb->pnet, IPSTATS_MIB_OUTNOROUTES);
	//	return US_ENETUNREACH;
	//}

	s32 ret = US_RET_OK;
	u32 n ;
	struct rte_mbuf *mbuf = (struct rte_mbuf*)(skb->head);
	struct net		*pnet = skb->pnet;

	if(skb->nohdr ){
		if( skb->nf_trace || skb->used > 0 ){
			rte_pktmbuf_prepend(mbuf, skb->mac_len);
		}

		mbuf_rebuild(skb , pnet->port);	
		//ret = ip_send_out(pnet,mbuf,skb);				//smallboy:  unkown error here; ip traunked; ???
		
		recv_pkt_dump(&mbuf, 1);

		n = rte_eth_tx_burst(pnet->port_id, pnet->send_queue_id , &mbuf, 1);	
		if(n < 1){
			US_ERR("TH:%u ,tx_burst failed on skb_id:%u sk_id:%u \n"
					,US_GET_LCORE(),skb->skb_id,skb->sk->sk_id);
			IP_ADD_STATS(skb->pnet,IPSTATS_MIB_OUTDISCARDS , 1); 
			ret = US_ENETDOWN;  
		}else{
			ret = US_RET_OK;
			IP_ADD_STATS(skb->pnet,IPSTATS_MIB_OUTPKTS , 1);  //skb->gso_segs == 1;
		}

		if(skb->users == 1){		//smallboy: More attention about the users,clone,used and nf_trace;
			__kfree_skb(skb,US_MBUF_FREE_BY_OTHER);		//users == 1; not cloned;  or errors here;
		}else{
			if(ret == US_RET_OK)	//smallboy: data send failed; No recover the users too;	
				skb->users--;
			skb->used++;
			skb_reset_data_header(skb);
		}
	}else{
		if(skb_can_gso(skb)){
			ret = ip_send_out_batch(skb,pnet);
		}
		
		if(skb->users == 1){		//smallboy: More attention about the users,clone,used and nf_trace;
			__kfree_skb(skb,US_MBUF_FREE_BY_STACK);		//users == 1; not cloned;  or errors here;
		}else{
			if(ret == US_RET_OK)
				skb->users--;
			skb->used++;
			skb_reset_data_header(skb);
		}		
	}

	return ret;
}
Beispiel #4
0
/*
 * Push&pop operations
 */
rofl_result_t push_datapacket_offset(datapacket_dpdk_t *dpkt, unsigned int offset, unsigned int num_of_bytes){
	
	uint8_t *src_ptr = get_buffer_dpdk(dpkt);
	uint8_t *dst_ptr = (uint8_t*)rte_pktmbuf_prepend(dpkt->mbuf, num_of_bytes);
	//NOTE dst_ptr = src_ptr - num_of_bytes
	
	if( NULL==dst_ptr )
		return ROFL_FAILURE;
	
	if(false==rte_pktmbuf_is_contiguous(dpkt->mbuf)){
		assert(0);
		return ROFL_FAILURE;
	}

	// move header num_of_bytes backward
	memmove(dst_ptr, src_ptr, offset);
	
#ifndef NDEBUG
	// initialize new pushed memory area with 0x00
	memset(dst_ptr + offset, 0x00, num_of_bytes);
#endif

	dpkt->clas_state.base = get_buffer_dpdk(dpkt);
	dpkt->clas_state.len = get_buffer_length_dpdk(dpkt);

	return ROFL_SUCCESS;
}
Beispiel #5
0
// remove this api. not used now
void sendfin(struct tcb *ptcb)
{
   struct rte_mbuf *mbuf = get_mbuf();
   uint8_t tcp_len = 20 ;
   tcp_len = (tcp_len + 3) / 4;  // len is in multiple of 4 bytes;  20  will be 5
   tcp_len = tcp_len << 4; // len has upper 4 bits position in tcp header.
   logger(LOG_TCP, NORMAL, "sending tcp packet\n");
   struct tcp_hdr *ptcphdr = (struct tcp_hdr *)rte_pktmbuf_prepend (mbuf, sizeof(struct tcp_hdr));
  // printf("head room2 = %d\n", rte_pktmbuf_headroom(mbuf));
   if(ptcphdr == NULL) {
    //  printf("tcp header is null\n");
   }
   ptcphdr->src_port = htons(ptcb->dport);
   ptcphdr->dst_port = htons(ptcb->sport);
   ptcphdr->sent_seq = htonl(ptcb->next_seq);
   ptcb->next_seq ++; // for fin
   ptcphdr->recv_ack = htonl(ptcb->ack);
   ptcphdr->data_off = tcp_len;
   ptcphdr->tcp_flags =  ptcb->tcp_flags | TCP_FLAG_FIN;
   ptcphdr->rx_win = 12000;
//   ptcphdr->cksum = 0x0001;
   ptcphdr->tcp_urp = 0; 
   //mbuf->ol_flags |=  PKT_TX_IP_CKSUM; // someday will calclate checkum here only.
   
 //  printf(" null\n");
  // fflush(stdout);
   ip_out(ptcb, mbuf, ptcphdr, 0); 
}
Beispiel #6
0
int
send_arp_request(unsigned char *src_pr_add, unsigned char *dst_pr_add)
{
    int i;
    struct rte_mbuf *new_mbuf = get_mbuf();
    struct arp *arp_reply = (struct arp *)rte_pktmbuf_prepend (new_mbuf, sizeof(struct arp));

    char mac[6];
// http://www.tcpipguide.com/free/t_ARPMessageFormat.htm
    arp_reply->hw_type = htons(HW_TYPE_ETHERNET);
    arp_reply->pr_type = htons(SW_TYPE_IPV4);
    arp_reply->hw_len = HW_LEN_ETHER;
    arp_reply->pr_len = PR_LEN_IPV4;
    arp_reply->opcode = htons(1);
    unsigned char dest_mac[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
    uint32_t ip_add = GetIntAddFromChar(src_pr_add, 1);

    struct Interface *temp = NULL;
    temp = InterfaceList;
    while(temp && ip_add != GetIntAddFromChar(temp->IP, 1)) {
        temp = temp->Next;
    }
    if(temp == NULL) {
        logger(ARP, NORMAL, "Arp request failed, address not hosted\n");
        return 0;
    }
    logger(ARP, NORMAL, "IP found in interface list\n");
    int status = GetInterfaceMac(temp->InterfaceNumber, mac);
    memcpy(arp_reply->src_hw_add, mac, HW_LEN_ETHER);
    memcpy(arp_reply->dst_hw_add, dest_mac, HW_LEN_ETHER);
    memcpy(arp_reply->src_pr_add, src_pr_add, PR_LEN_IPV4);
    memcpy(arp_reply->dst_pr_add, dst_pr_add, PR_LEN_IPV4);
    send_arp(arp_reply);
}
Beispiel #7
0
uint8_t add_winscale_option(struct rte_mbuf *mbuf, uint8_t value)
{
   struct tcp_winscale_option *option = (struct tcp_winscale_option *)rte_pktmbuf_prepend (mbuf, sizeof(struct tcp_winscale_option));
   option->type = 3;
   option->len = 3;
   option->value = value;
   return 3;
}
Beispiel #8
0
uint8_t add_mss_option(struct rte_mbuf *mbuf, uint16_t mss_value)
{
   struct tcp_mss_option *mss_option = (struct tcp_mss_option *)rte_pktmbuf_prepend (mbuf, sizeof(struct tcp_mss_option));
   mss_option->type = 2;
   mss_option->len = 4;
   mss_option->value = htons(mss_value);
   return 4; // 1 * 4 bytes
}
Beispiel #9
0
uint8_t add_timestamp_option(struct rte_mbuf *mbuf, uint32_t value, uint32_t echo)
{
   struct tcp_timestamp_option *option = (struct tcp_timestamp_option *)rte_pktmbuf_prepend (mbuf, sizeof(struct tcp_timestamp_option));
   option->type = 8;
   option->len = 10;
   option->value = value;
   option->echo = echo;
   return 10;
}
Beispiel #10
0
static inline void
app_pkt_metadata_flush(struct rte_mbuf *pkt)
{
	struct app_pkt_metadata *pkt_meta = (struct app_pkt_metadata *)
		RTE_MBUF_METADATA_UINT8_PTR(pkt, 0);
	struct ether_hdr *ether_hdr = (struct ether_hdr *)
		rte_pktmbuf_prepend(pkt, (uint16_t) sizeof(struct ether_hdr));

	ether_addr_copy(&pkt_meta->nh_arp, &ether_hdr->d_addr);
	ether_addr_copy(&local_ether_addr, &ether_hdr->s_addr);
	ether_hdr->ether_type = rte_bswap16(ETHER_TYPE_IPv4);
	pkt->pkt.vlan_macip.f.l2_len = sizeof(struct ether_hdr);
}
Beispiel #11
0
/*
 * Function sends unmatched packets to vswitchd.
 */
void
send_packet_to_vswitchd(struct rte_mbuf *mbuf, struct dpdk_upcall *info)
{
	int rslt = 0;
	void *mbuf_ptr = NULL;
	const uint64_t dpif_send_tsc =
		(rte_get_tsc_hz() + US_PER_S - 1) / US_PER_S * DPIF_SEND_US;
	uint64_t cur_tsc = 0;
	uint64_t diff_tsc = 0;
	static uint64_t prev_tsc = 0;

	/* send one packet, delete information about segments */
	rte_pktmbuf_pkt_len(mbuf) = rte_pktmbuf_data_len(mbuf);

	/* allocate space before the packet for the upcall info */
	mbuf_ptr = rte_pktmbuf_prepend(mbuf, sizeof(*info));

	if (mbuf_ptr == NULL) {
		printf("Cannot prepend upcall info\n");
		rte_pktmbuf_free(mbuf);
		stats_vswitch_tx_drop_increment(INC_BY_1);
		stats_vport_tx_drop_increment(VSWITCHD, INC_BY_1);
		return;
	}

	rte_memcpy(mbuf_ptr, info, sizeof(*info));

	/* send the packet and the upcall info to the daemon */
	rslt = rte_ring_mp_enqueue(vswitchd_packet_ring, mbuf);
	if (rslt < 0) {
		if (rslt == -ENOBUFS) {
			rte_pktmbuf_free(mbuf);
			stats_vswitch_tx_drop_increment(INC_BY_1);
			stats_vport_tx_drop_increment(VSWITCHD, INC_BY_1);
			return;
		} else {
			stats_vport_overrun_increment(VSWITCHD, INC_BY_1);
		}
	}

	stats_vport_tx_increment(VSWITCHD, INC_BY_1);

	cur_tsc = rte_rdtsc();
	diff_tsc = cur_tsc - prev_tsc;
	prev_tsc = cur_tsc;
	/* Only signal the daemon after 100 milliseconds */
	if (unlikely(diff_tsc > dpif_send_tsc))
		send_signal_to_dpif();
}
Beispiel #12
0
void send_reset(struct ipv4_hdr *ip_hdr, struct tcp_hdr *t_hdr)
{
   printf("sending reset\n");
   logger(LOG_TCP, LOG_LEVEL_CRITICAL, "sending reset\n");
   struct rte_mbuf *mbuf = get_mbuf();
   //printf("head room = %d\n", rte_pktmbuf_headroom(mbuf));
  // rte_pktmbuf_adj(mbuf, sizeof(struct tcp_hdr) + sizeof(struct ipv4_hdr) + sizeof(struct ether_hdr));
   struct tcp_hdr *ptcphdr = (struct tcp_hdr *)rte_pktmbuf_prepend (mbuf, sizeof(struct tcp_hdr));
   //printf("head room2 = %d\n", rte_pktmbuf_headroom(mbuf));
   if(ptcphdr == NULL) {
      //printf("tcp header is null\n");
   }


   uint8_t tcp_len = 20 ;
   tcp_len = (tcp_len + 3) / 4;  // len is in multiple of 4 bytes;  20  will be 5
   tcp_len = tcp_len << 4; // len has upper 4 bits position in tcp header.
  // printf("head room2 = %d\n", rte_pktmbuf_headroom(mbuf));
   if(ptcphdr == NULL) {
    //  printf("tcp header is null\n");
   }
   ptcphdr->data_off = tcp_len;


   ptcphdr->src_port = t_hdr->dst_port;
   ptcphdr->dst_port = t_hdr->src_port;
   ptcphdr->sent_seq = t_hdr->recv_ack;
   ptcphdr->recv_ack = 0;
   ptcphdr->tcp_flags =  TCP_FLAG_RST;
   ptcphdr->rx_win = 12000;
   ptcphdr->tcp_urp = 0; 
   
  // struct ipv4_hdr *hdr = (struct ipv4_hdr *)rte_pktmbuf_prepend (mbuf, sizeof(struct ipv4_hdr));
   //printf("head room4 = %d\n", rte_pktmbuf_headroom(mbuf));
       //printf("ip header is null\n");
   //    fflush(stdout);
   struct tcb ptcb;
   ptcb.identifier = 0; // dummy 
   
   ptcb.ipv4_dst = ip_hdr->dst_addr;  // fix it future , why we have htonl only for src
   ptcb.ipv4_src = htonl(ip_hdr->src_addr);
   fflush(stdout);
   ip_out(&ptcb, mbuf, ptcphdr, 0); 
}
/* Encapsulate IPv6 packet in QinQ where the QinQ is derived from the IPv6 address */
static inline uint8_t handle_qinq_encap6(struct rte_mbuf *mbuf, struct task_qinq_encap6 *task)
{
	struct qinq_hdr *pqinq = (struct qinq_hdr *)rte_pktmbuf_prepend(mbuf, 2 * sizeof(struct vlan_hdr));

	PROX_RUNTIME_ASSERT(pqinq);
	struct ipv6_hdr *pip6 = (struct ipv6_hdr *)(pqinq + 1);

	if (pip6->hop_limits) {
		pip6->hop_limits--;
	}
	else {
		plog_info("TTL = 0 => Dropping\n");
		return NO_PORT_AVAIL;
	}

	// TODO: optimize to use bulk as intended with the rte_table_library
	uint64_t pkts_mask = RTE_LEN2MASK(1, uint64_t);
	uint64_t lookup_hit_mask;
	struct cpe_data* entries[64]; // TODO: use bulk size
	rte_table_hash_ext_dosig_ops.f_lookup(task->cpe_table, &mbuf, pkts_mask, &lookup_hit_mask, (void**)entries);

	if (lookup_hit_mask == 0x1) {
		/* will also overwrite part of the destination addr */
		(*(uint64_t *)pqinq) = entries[0]->mac_port_8bytes;
		pqinq->svlan.eth_proto = task->qinq_tag;
		pqinq->cvlan.eth_proto = ETYPE_VLAN;
		pqinq->svlan.vlan_tci = entries[0]->qinq_svlan;
		pqinq->cvlan.vlan_tci = entries[0]->qinq_cvlan;
		pqinq->ether_type = ETYPE_IPv6;

		/* classification can only be done from this point */
		if (task->runtime_flags & TASK_CLASSIFY) {
			rte_sched_port_pkt_write(mbuf, 0, entries[0]->user, 0, 0, 0);
		}
		return 0;
	}
	else {
		plogx_err("Unknown IP " IPv6_BYTES_FMT "\n", IPv6_BYTES(pip6->dst_addr));
		return NO_PORT_AVAIL;
	}
}
Beispiel #14
0
int
ether_out(unsigned char *dst_mac, char *src_mac, uint16_t ether_type, struct rte_mbuf *mbuf)
{
   int i = 0;
   struct ether_hdr *eth;
   eth = (struct ether_hdr *)rte_pktmbuf_prepend (mbuf, sizeof(struct ether_hdr)); 
   eth->ether_type = htons(ether_type);
   for(i=0;i<6;i++) {
      eth->d_addr.addr_bytes[i] = dst_mac[i];
   }
//   for(i=0;i<6;i++) {
   eth->s_addr.addr_bytes[0] = 0x6a;
   eth->s_addr.addr_bytes[1] = 0x9c;
   eth->s_addr.addr_bytes[2] = 0xba;
   eth->s_addr.addr_bytes[3] = 0xa0;
   eth->s_addr.addr_bytes[4] = 0x96;
   eth->s_addr.addr_bytes[5] = 0x24;
//   }
// fix this this should be automatically detect the network interface id.
   send_packet_out(mbuf, 0);
   static int counter_id = -1;
   if(counter_id == -1) {
      counter_id = create_counter("sent_rate");
   }
   int data_len = rte_pktmbuf_data_len(mbuf);

   counter_abs(counter_id, data_len);
   {
      static int counter_id = -1;
      if(counter_id == -1) {
         counter_id = create_counter("wire_sent");
      }
      int data_len = rte_pktmbuf_data_len(mbuf);
 
      counter_inc(counter_id, data_len);
   }
   (void) src_mac; // jusat to avoid warning
   src_mac = NULL;
   return 0;
}
Beispiel #15
0
/*
 * Function sends unmatched packets to vswitchd.
 */
static void
send_packet_to_vswitchd(struct rte_mbuf *mbuf, struct dpdk_upcall *info)
{
	int rslt = 0;
	struct statistics *vswd_stat = NULL;
	void *mbuf_ptr = NULL;

	vswd_stat = &vport_stats[VSWITCHD];

	/* send one packet, delete information about segments */
	rte_pktmbuf_pkt_len(mbuf) = rte_pktmbuf_data_len(mbuf);

	/* allocate space before the packet for the upcall info */
	mbuf_ptr = rte_pktmbuf_prepend(mbuf, sizeof(*info));

	if (mbuf_ptr == NULL) {
		printf("Cannot prepend upcall info\n");
		rte_pktmbuf_free(mbuf);
		switch_tx_drop++;
		vswd_stat->tx_drop++;
		return;
	}

	rte_memcpy(mbuf_ptr, info, sizeof(*info));

	/* send the packet and the upcall info to the daemon */
	rslt = rte_ring_sp_enqueue(vswitch_packet_ring, mbuf);
	if (rslt < 0) {
		if (rslt == -ENOBUFS) {
			rte_pktmbuf_free(mbuf);
			switch_tx_drop++;
			vswd_stat->tx_drop++;
			return;
		} else {
			overruns++;
		}
	}

	vswd_stat->tx++;
}
Beispiel #16
0
void sendtcpack(struct tcb *ptcb, struct rte_mbuf *mbuf, unsigned char *data, int len)
{
   //uint8_t tcp_len = 0x50 + add_mss_option(mbuf, 1300);// + add_winscale_option(mbuf, 7);
   uint8_t data_len = add_tcp_data(mbuf, data, len);
   uint8_t option_len = add_winscale_option(mbuf, 7) + add_mss_option(mbuf, 1300) + add_timestamp_option(mbuf, 203032, 0);

   uint8_t tcp_len = 20 + option_len;
   uint8_t pad = (tcp_len%4) ? 4 - (tcp_len % 4): 0;
   tcp_len += pad;
   logger(LOG_TCP, NORMAL, "padding option %d\n",  pad); 
   char *nop = rte_pktmbuf_append (mbuf, pad); // always pad the option to make total size multiple of 4.
   memset(nop, 0, pad);

   tcp_len = (tcp_len + 3) / 4;  // len is in multiple of 4 bytes;  20  will be 5
   tcp_len = tcp_len << 4; // len has upper 4 bits position in tcp header.
   logger(LOG_TCP, NORMAL, "sending tcp packet\n");
   struct tcp_hdr *ptcphdr = (struct tcp_hdr *)rte_pktmbuf_prepend (mbuf, sizeof(struct tcp_hdr));
  // printf("head room2 = %d\n", rte_pktmbuf_headroom(mbuf));
   if(ptcphdr == NULL) {
    //  printf("tcp header is null\n");
   }
   ptcphdr->src_port = htons(ptcb->dport);
   ptcphdr->dst_port = htons(ptcb->sport);
   ptcphdr->sent_seq = htonl(ptcb->next_seq);
   ptcb->next_seq += data_len;
  // ptcb->next_seq ++;  // for syn 
   ptcphdr->recv_ack = htonl(ptcb->ack);
   ptcphdr->data_off = tcp_len;
   ptcphdr->tcp_flags =  TCP_FLAG_ACK;
   ptcphdr->rx_win = 12000;
//   ptcphdr->cksum = 0x0001;
   ptcphdr->tcp_urp = 0; 
   //mbuf->ol_flags |=  PKT_TX_IP_CKSUM; // someday will calclate checkum here only.
   
 //  printf(" null\n");
  // fflush(stdout);
   ip_out(ptcb, mbuf, ptcphdr, data_len); 

}
Beispiel #17
0
int
ether_out(unsigned char *dst_mac, char *src_mac, uint16_t ether_type, struct rte_mbuf *mbuf)
{
   int i = 0;
   struct ether_hdr *eth;
   eth = (struct ether_hdr *)rte_pktmbuf_prepend (mbuf, sizeof(struct ether_hdr)); 
   eth->ether_type = htons(ether_type);
   for(i=0;i<6;i++) {
      eth->d_addr.addr_bytes[i] = dst_mac[i];
   }
//   for(i=0;i<6;i++) {
   eth->s_addr.addr_bytes[0] = 0x6a;
   eth->s_addr.addr_bytes[1] = 0x9c;
   eth->s_addr.addr_bytes[2] = 0xba;
   eth->s_addr.addr_bytes[3] = 0xa0;
   eth->s_addr.addr_bytes[4] = 0x96;
   eth->s_addr.addr_bytes[5] = 0x24;
//   }
// fix this this should be automatically detect the port id.
   send_packet_out(mbuf, 0);
   (void) src_mac; // jusat to avoid warning
   src_mac = NULL;
   return 0;
}
static int
test_blockcipher_one_case(const struct blockcipher_test_case *t,
	struct rte_mempool *mbuf_pool,
	struct rte_mempool *op_mpool,
	uint8_t dev_id,
	enum rte_cryptodev_type cryptodev_type,
	char *test_msg)
{
	struct rte_mbuf *ibuf = NULL;
	struct rte_mbuf *obuf = NULL;
	struct rte_mbuf *iobuf;
	struct rte_crypto_sym_xform *cipher_xform = NULL;
	struct rte_crypto_sym_xform *auth_xform = NULL;
	struct rte_crypto_sym_xform *init_xform = NULL;
	struct rte_crypto_sym_op *sym_op = NULL;
	struct rte_crypto_op *op = NULL;
	struct rte_cryptodev_sym_session *sess = NULL;
	struct rte_cryptodev_info dev_info;

	int status = TEST_SUCCESS;
	const struct blockcipher_test_data *tdata = t->test_data;
	uint8_t cipher_key[tdata->cipher_key.len];
	uint8_t auth_key[tdata->auth_key.len];
	uint32_t buf_len = tdata->ciphertext.len;
	uint32_t digest_len = 0;
	char *buf_p = NULL;
	uint8_t src_pattern = 0xa5;
	uint8_t dst_pattern = 0xb6;
	uint8_t tmp_src_buf[MBUF_SIZE];
	uint8_t tmp_dst_buf[MBUF_SIZE];

	int nb_segs = 1;

	if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SG) {
		rte_cryptodev_info_get(dev_id, &dev_info);
		if (!(dev_info.feature_flags &
				RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER)) {
			printf("Device doesn't support scatter-gather. "
					"Test Skipped.\n");
			return 0;
		}
		nb_segs = 3;
	}

	if (tdata->cipher_key.len)
		memcpy(cipher_key, tdata->cipher_key.data,
			tdata->cipher_key.len);
	if (tdata->auth_key.len)
		memcpy(auth_key, tdata->auth_key.data,
			tdata->auth_key.len);

	switch (cryptodev_type) {
	case RTE_CRYPTODEV_QAT_SYM_PMD:
	case RTE_CRYPTODEV_OPENSSL_PMD:
	case RTE_CRYPTODEV_ARMV8_PMD: /* Fall through */
		digest_len = tdata->digest.len;
		break;
	case RTE_CRYPTODEV_AESNI_MB_PMD:
	case RTE_CRYPTODEV_SCHEDULER_PMD:
		digest_len = tdata->digest.truncated_len;
		break;
	default:
		snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN,
			"line %u FAILED: %s",
			__LINE__, "Unsupported PMD type");
		status = TEST_FAILED;
		goto error_exit;
	}

	/* preparing data */
	if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER)
		buf_len += tdata->iv.len;
	if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH)
		buf_len += digest_len;

	/* for contiguous mbuf, nb_segs is 1 */
	ibuf = create_segmented_mbuf(mbuf_pool,
			tdata->ciphertext.len, nb_segs, src_pattern);
	if (ibuf == NULL) {
		snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN,
			"line %u FAILED: %s",
			__LINE__, "Cannot create source mbuf");
		status = TEST_FAILED;
		goto error_exit;
	}

	/* only encryption requires plaintext.data input,
	 * decryption/(digest gen)/(digest verify) use ciphertext.data
	 * to be computed
	 */
	if (t->op_mask & BLOCKCIPHER_TEST_OP_ENCRYPT)
		pktmbuf_write(ibuf, 0, tdata->plaintext.len,
				tdata->plaintext.data);
	else
		pktmbuf_write(ibuf, 0, tdata->ciphertext.len,
				tdata->ciphertext.data);

	if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER) {
		rte_memcpy(rte_pktmbuf_prepend(ibuf, tdata->iv.len),
				tdata->iv.data, tdata->iv.len);
	}
	buf_p = rte_pktmbuf_append(ibuf, digest_len);
	if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_VERIFY)
		rte_memcpy(buf_p, tdata->digest.data, digest_len);
	else
		memset(buf_p, 0, digest_len);

	if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_OOP) {
		obuf = rte_pktmbuf_alloc(mbuf_pool);
		if (!obuf) {
			snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u "
				"FAILED: %s", __LINE__,
				"Allocation of rte_mbuf failed");
			status = TEST_FAILED;
			goto error_exit;
		}
		memset(obuf->buf_addr, dst_pattern, obuf->buf_len);

		buf_p = rte_pktmbuf_append(obuf, buf_len);
		if (!buf_p) {
			snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u "
				"FAILED: %s", __LINE__,
				"No room to append mbuf");
			status = TEST_FAILED;
			goto error_exit;
		}
		memset(buf_p, 0, buf_len);
	}

	/* Generate Crypto op data structure */
	op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_SYMMETRIC);
	if (!op) {
		snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN,
			"line %u FAILED: %s",
			__LINE__, "Failed to allocate symmetric crypto "
			"operation struct");
		status = TEST_FAILED;
		goto error_exit;
	}

	sym_op = op->sym;

	sym_op->m_src = ibuf;

	if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_OOP) {
		sym_op->m_dst = obuf;
		iobuf = obuf;
	} else {
		sym_op->m_dst = NULL;
		iobuf = ibuf;
	}

	/* sessionless op requires allocate xform using
	 * rte_crypto_op_sym_xforms_alloc(), otherwise rte_zmalloc()
	 * is used
	 */
	if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS) {
		uint32_t n_xforms = 0;

		if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER)
			n_xforms++;
		if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH)
			n_xforms++;

		if (rte_crypto_op_sym_xforms_alloc(op, n_xforms)
			== NULL) {
			snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u "
				"FAILED: %s", __LINE__, "Failed to "
				"allocate space for crypto transforms");
			status = TEST_FAILED;
			goto error_exit;
		}
	} else {
		cipher_xform = rte_zmalloc(NULL,
			sizeof(struct rte_crypto_sym_xform), 0);

		auth_xform = rte_zmalloc(NULL,
			sizeof(struct rte_crypto_sym_xform), 0);

		if (!cipher_xform || !auth_xform) {
			snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u "
				"FAILED: %s", __LINE__, "Failed to "
				"allocate memory for crypto transforms");
			status = TEST_FAILED;
			goto error_exit;
		}
	}

	/* preparing xform, for sessioned op, init_xform is initialized
	 * here and later as param in rte_cryptodev_sym_session_create() call
	 */
	if (t->op_mask == BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN) {
		if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS) {
			cipher_xform = op->sym->xform;
			auth_xform = cipher_xform->next;
			auth_xform->next = NULL;
		} else {
			cipher_xform->next = auth_xform;
			auth_xform->next = NULL;
			init_xform = cipher_xform;
		}
	} else if (t->op_mask == BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC) {
		if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS) {
			auth_xform = op->sym->xform;
			cipher_xform = auth_xform->next;
			cipher_xform->next = NULL;
		} else {
			auth_xform->next = cipher_xform;
			cipher_xform->next = NULL;
			init_xform = auth_xform;
		}
	} else if ((t->op_mask == BLOCKCIPHER_TEST_OP_ENCRYPT) ||
			(t->op_mask == BLOCKCIPHER_TEST_OP_DECRYPT)) {
		if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS)
			cipher_xform = op->sym->xform;
		else
			init_xform = cipher_xform;
		cipher_xform->next = NULL;
	} else if ((t->op_mask == BLOCKCIPHER_TEST_OP_AUTH_GEN) ||
			(t->op_mask == BLOCKCIPHER_TEST_OP_AUTH_VERIFY)) {
		if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS)
			auth_xform = op->sym->xform;
		else
			init_xform = auth_xform;
		auth_xform->next = NULL;
	} else {
		snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN,
			"line %u FAILED: %s",
			__LINE__, "Unrecognized operation");
		status = TEST_FAILED;
		goto error_exit;
	}

	/*configure xforms & sym_op cipher and auth data*/
	if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER) {
		cipher_xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER;
		cipher_xform->cipher.algo = tdata->crypto_algo;
		if (t->op_mask & BLOCKCIPHER_TEST_OP_ENCRYPT)
			cipher_xform->cipher.op =
				RTE_CRYPTO_CIPHER_OP_ENCRYPT;
		else
			cipher_xform->cipher.op =
				RTE_CRYPTO_CIPHER_OP_DECRYPT;
		cipher_xform->cipher.key.data = cipher_key;
		cipher_xform->cipher.key.length = tdata->cipher_key.len;

		sym_op->cipher.data.offset = tdata->iv.len;
		sym_op->cipher.data.length = tdata->ciphertext.len;
		sym_op->cipher.iv.data = rte_pktmbuf_mtod(sym_op->m_src,
			uint8_t *);
		sym_op->cipher.iv.length = tdata->iv.len;
		sym_op->cipher.iv.phys_addr = rte_pktmbuf_mtophys(
			sym_op->m_src);
	}
Beispiel #19
0
/*
 * test data manipulation in mbuf
 */
static int
test_one_pktmbuf(void)
{
	struct rte_mbuf *m = NULL;
	char *data, *data2, *hdr;
	unsigned i;

	printf("Test pktmbuf API\n");

	/* alloc a mbuf */

	m = rte_pktmbuf_alloc(pktmbuf_pool);
	if (m == NULL)
		GOTO_FAIL("Cannot allocate mbuf");
	if (rte_pktmbuf_pkt_len(m) != 0)
		GOTO_FAIL("Bad length");

	rte_pktmbuf_dump(m, 0);

	/* append data */

	data = rte_pktmbuf_append(m, MBUF_TEST_DATA_LEN);
	if (data == NULL)
		GOTO_FAIL("Cannot append data");
	if (rte_pktmbuf_pkt_len(m) != MBUF_TEST_DATA_LEN)
		GOTO_FAIL("Bad pkt length");
	if (rte_pktmbuf_data_len(m) != MBUF_TEST_DATA_LEN)
		GOTO_FAIL("Bad data length");
	memset(data, 0x66, rte_pktmbuf_pkt_len(m));
	if (!rte_pktmbuf_is_contiguous(m))
		GOTO_FAIL("Buffer should be continuous");
	rte_pktmbuf_dump(m, MBUF_TEST_DATA_LEN);
	rte_pktmbuf_dump(m, 2*MBUF_TEST_DATA_LEN);

	/* this append should fail */

	data2 = rte_pktmbuf_append(m, (uint16_t)(rte_pktmbuf_tailroom(m) + 1));
	if (data2 != NULL)
		GOTO_FAIL("Append should not succeed");

	/* append some more data */

	data2 = rte_pktmbuf_append(m, MBUF_TEST_DATA_LEN2);
	if (data2 == NULL)
		GOTO_FAIL("Cannot append data");
	if (rte_pktmbuf_pkt_len(m) != MBUF_TEST_DATA_LEN + MBUF_TEST_DATA_LEN2)
		GOTO_FAIL("Bad pkt length");
	if (rte_pktmbuf_data_len(m) != MBUF_TEST_DATA_LEN + MBUF_TEST_DATA_LEN2)
		GOTO_FAIL("Bad data length");
	if (!rte_pktmbuf_is_contiguous(m))
		GOTO_FAIL("Buffer should be continuous");

	/* trim data at the end of mbuf */

	if (rte_pktmbuf_trim(m, MBUF_TEST_DATA_LEN2) < 0)
		GOTO_FAIL("Cannot trim data");
	if (rte_pktmbuf_pkt_len(m) != MBUF_TEST_DATA_LEN)
		GOTO_FAIL("Bad pkt length");
	if (rte_pktmbuf_data_len(m) != MBUF_TEST_DATA_LEN)
		GOTO_FAIL("Bad data length");
	if (!rte_pktmbuf_is_contiguous(m))
		GOTO_FAIL("Buffer should be continuous");

	/* this trim should fail */

	if (rte_pktmbuf_trim(m, (uint16_t)(rte_pktmbuf_data_len(m) + 1)) == 0)
		GOTO_FAIL("trim should not succeed");

	/* prepend one header */

	hdr = rte_pktmbuf_prepend(m, MBUF_TEST_HDR1_LEN);
	if (hdr == NULL)
		GOTO_FAIL("Cannot prepend");
	if (data - hdr != MBUF_TEST_HDR1_LEN)
		GOTO_FAIL("Prepend failed");
	if (rte_pktmbuf_pkt_len(m) != MBUF_TEST_DATA_LEN + MBUF_TEST_HDR1_LEN)
		GOTO_FAIL("Bad pkt length");
	if (rte_pktmbuf_data_len(m) != MBUF_TEST_DATA_LEN + MBUF_TEST_HDR1_LEN)
		GOTO_FAIL("Bad data length");
	if (!rte_pktmbuf_is_contiguous(m))
		GOTO_FAIL("Buffer should be continuous");
	memset(hdr, 0x55, MBUF_TEST_HDR1_LEN);

	/* prepend another header */

	hdr = rte_pktmbuf_prepend(m, MBUF_TEST_HDR2_LEN);
	if (hdr == NULL)
		GOTO_FAIL("Cannot prepend");
	if (data - hdr != MBUF_TEST_ALL_HDRS_LEN)
		GOTO_FAIL("Prepend failed");
	if (rte_pktmbuf_pkt_len(m) != MBUF_TEST_DATA_LEN + MBUF_TEST_ALL_HDRS_LEN)
		GOTO_FAIL("Bad pkt length");
	if (rte_pktmbuf_data_len(m) != MBUF_TEST_DATA_LEN + MBUF_TEST_ALL_HDRS_LEN)
		GOTO_FAIL("Bad data length");
	if (!rte_pktmbuf_is_contiguous(m))
		GOTO_FAIL("Buffer should be continuous");
	memset(hdr, 0x55, MBUF_TEST_HDR2_LEN);

	rte_mbuf_sanity_check(m, RTE_MBUF_PKT, 1);
	rte_mbuf_sanity_check(m, RTE_MBUF_PKT, 0);
	rte_pktmbuf_dump(m, 0);

	/* this prepend should fail */

	hdr = rte_pktmbuf_prepend(m, (uint16_t)(rte_pktmbuf_headroom(m) + 1));
	if (hdr != NULL)
		GOTO_FAIL("prepend should not succeed");

	/* remove data at beginning of mbuf (adj) */

	if (data != rte_pktmbuf_adj(m, MBUF_TEST_ALL_HDRS_LEN))
		GOTO_FAIL("rte_pktmbuf_adj failed");
	if (rte_pktmbuf_pkt_len(m) != MBUF_TEST_DATA_LEN)
		GOTO_FAIL("Bad pkt length");
	if (rte_pktmbuf_data_len(m) != MBUF_TEST_DATA_LEN)
		GOTO_FAIL("Bad data length");
	if (!rte_pktmbuf_is_contiguous(m))
		GOTO_FAIL("Buffer should be continuous");

	/* this adj should fail */

	if (rte_pktmbuf_adj(m, (uint16_t)(rte_pktmbuf_data_len(m) + 1)) != NULL)
		GOTO_FAIL("rte_pktmbuf_adj should not succeed");

	/* check data */

	if (!rte_pktmbuf_is_contiguous(m))
		GOTO_FAIL("Buffer should be continuous");

	for (i=0; i<MBUF_TEST_DATA_LEN; i++) {
		if (data[i] != 0x66)
			GOTO_FAIL("Data corrupted at offset %u", i);
	}

	/* free mbuf */

	rte_pktmbuf_free(m);
	m = NULL;
	return 0;

fail:
	if (m)
		rte_pktmbuf_free(m);
	return -1;
}