Beispiel #1
0
Datei: upro.c Projekt: H1d3r/UPro
void dump(upro_collector_context_t *context)
{
	int ret;
	int queue_id = context->queue_id;

	upro_collector_t *cc = &(collectors[context->id]); 
	assert(ps_init_handle(&(cc->handle)) == 0);

	struct ps_queue queue;
	queue.ifindex = context->ifindex;
	queue.qidx = queue_id;
	printf("[Collector %d] is attaching if:queue %d:%d ...\n", context->id, queue.ifindex, queue.qidx);
	assert(ps_attach_rx_device(&(cc->handle), &queue) == 0);

	struct ps_chunk chunk;
	assert(ps_alloc_chunk(&(cc->handle), &chunk) == 0);
	chunk.recv_blocking = 1;

	gettimeofday(&(cc->startime), NULL);
	
	for (;;) {
		chunk.cnt = config->io_batch_num;

		ret = ps_recv_chunk(&(cc->handle), &chunk);
		if (ret < 0) {
			if (errno == EINTR)
				continue;
			assert(0);
		}

		cc->total_packets += ret;
		cc->total_bytes += ret * 1370;
		continue;
	}
}
Beispiel #2
0
void attach()
{
	int ret;
	int i, j;

	ret = ps_init_handle(&handle);
	if (ret != 0) {
		perror("ps_init_handle");
		exit(1);
	}

	for (i = 0; i < num_devices_attached; i++) {
		struct ps_queue queue;

		printf("num rx queues = %d\n", devices[devices_attached[i]].num_rx_queues);
		queue.ifindex = devices_attached[i];
		//for (j = 0; j < devices[devices_attached[i]].num_rx_queues; j++) {
		//for (j = 0; j < 3; j++) {
			queue.qidx = 3;
			//queue.qidx = j;

			ret = ps_attach_rx_device(&handle, &queue);
			if (ret != 0) {
				perror("ps_attach_rx_device");
				exit(1);
			}
		//}
	}
}
Beispiel #3
0
void attach()
{
	int ret;
	//int i, j;
	int i; 

	//ret = ps_init_handle(&handle);
	ret = ps_init_handle(&handles[my_cpu]);
	if (ret != 0) {
		perror("ps_init_handle");
		exit(1);
	}

	for (i = 0; i < num_devices_attached; i++) {
		struct ps_queue queue;

		queue.ifindex = devices_attached[i];

		//for (j = 0; j < devices[devices_attached[i]].num_rx_queues; j++) {
			//queue.qidx = j;
			queue.qidx = my_cpu;

			ret = ps_attach_rx_device(&handles[my_cpu], &queue);
			if (ret != 0) {
				perror("ps_attach_rx_device");
				exit(1);
			}
		//}
	}
}
Beispiel #4
0
/*----------------------------------------------------------------------------*/
void
psio_init_handle(struct mtcp_thread_context *ctxt)
{
	int i, ret;
	struct psio_private_context *ppc;
	struct timeval cur_ts;

	/* create and initialize private I/O module context */
	ctxt->io_private_context = calloc(1, sizeof(struct psio_private_context));
	if (ctxt->io_private_context == NULL) {
		TRACE_ERROR("Failed to initialize ctxt->io_private_context: "
			    "Can't allocate memory\n");
		exit(EXIT_FAILURE);
	}
	
	ppc = (struct psio_private_context *)ctxt->io_private_context;
	if (ps_init_handle(&ppc->handle)) {
		perror("ps_init_handle");
		TRACE_ERROR("Failed to initialize ps handle.\n");
		exit(EXIT_FAILURE);
	}

	/* create buffer for reading ingress batch of packet */
	if (ps_alloc_chunk(&ppc->handle, &ppc->chunk) != 0) {
		perror("ps_alloc_chunk");
		TRACE_ERROR("Failed to allocate ps_chunk\n");
		exit(EXIT_FAILURE);
	}

	/* create packet write chunk */
	for (i = 0; i < num_devices_attached; i++) {
		ret = ps_alloc_chunk_buf(&ppc->handle, i, ctxt->cpu, &ppc->w_chunk_buf[i]);
		if (ret != 0) {
			TRACE_ERROR("Failed to allocate ps_chunk_buf.\n");
			exit(EXIT_FAILURE);
		}
	}
	
	gettimeofday(&cur_ts, NULL);
	
	/* initialize PSIO parameters */
	ppc->chunk.recv_blocking = 0;
	ppc->event.timeout = PS_SELECT_TIMEOUT;
	ppc->event.qidx = ctxt->cpu;
	NID_ZERO(ppc->event.rx_nids);
	NID_ZERO(ppc->event.tx_nids);
	NID_ZERO(ppc->rx_avail);
	//NID_ZERO(ppc->tx_avail);

	for (i = 0; i < CONFIG.eths_num; i++) {
		ppc->last_tx_set[i] = cur_ts;
		NID_SET(i, ppc->tx_avail);
	}
}
Beispiel #5
0
void echo()
{
	struct ps_handle *handle = &handles[my_cpu];
	struct ps_chunk chunk;

	int i;
	int working = 0;

	assert(ps_init_handle(handle) == 0);

	for (i = 0; i < num_devices_attached; i++) {
		struct ps_queue queue;
		if (devices[devices_attached[i]].num_rx_queues <= my_cpu)
			continue;

		if (devices[devices_attached[i]].num_tx_queues <= my_cpu) {
			printf("WARNING: xge%d has not enough TX queues!\n",
					devices_attached[i]);
			continue;
		}

		working = 1;
		queue.ifindex = devices_attached[i];
		queue.qidx = my_cpu;

		printf("attaching RX queue xge%d:%d to CPU%d\n", queue.ifindex, queue.qidx, my_cpu);
		assert(ps_attach_rx_device(handle, &queue) == 0);
	}

	if (!working)
		goto done;

	assert(ps_alloc_chunk(handle, &chunk) == 0);

	chunk.recv_blocking = 1;

	for (;;) {
		int ret;
		
		chunk.cnt = 64;
		ret = ps_recv_chunk(handle, &chunk);

		if (ret < 0) {
			if (errno == EINTR)
				continue;

			if (!chunk.recv_blocking && errno == EWOULDBLOCK)
				break;

			assert(0);
		}

		if (!sink) {
			chunk.cnt = ret;
			ret = ps_send_chunk(handle, &chunk);
			assert(ret >= 0);
		}
	}

done:
	ps_close_handle(handle);
}
Beispiel #6
0
void send_packets(long packets,
                  int chunk_size,
                  int packet_size,
                  int num_flows)
{
    struct ps_handle *handle = &handles[my_cpu];
    struct ps_chunk chunk;
    char packet[MAX_FLOWS][MAX_PACKET_SIZE];
    int ret;

    int i, j;
    unsigned int next_flow[MAX_DEVICES];

    long sent = 0;
    uint64_t seed = 0;

    if (num_flows == 0)
        seed = time(NULL) + my_cpu;

    for (i = 0; i < num_flows; i++) {
        if (ip_version == 4)
            build_packet(packet[i], packet_size, &seed);
        else if (ip_version == 6)
            build_packet_v6(packet[i], packet_size, &seed);
    }

    assert(ps_init_handle(handle) == 0);

    for (i = 0; i < num_devices_registered; i++)
        next_flow[i] = 0;

    assert(ps_alloc_chunk(handle, &chunk) == 0);
    chunk.queue.qidx = my_cpu; /* CPU_i holds queue_i */

    assert(chunk.info);

    while (1) {
        int working = 0;

        for (i = 0; i < num_devices_registered; i++) {
            chunk.queue.ifindex = devices_registered[i];
            working = 1;

            for (j = 0; j < chunk_size; j++) {
                chunk.info[j].len = packet_size;
                chunk.info[j].offset = j * ALIGN(packet_size, 64);

                if (num_flows == 0) {
                    if (ip_version == 4) {
                        build_packet(chunk.buf + chunk.info[j].offset,
                                     packet_size, &seed);
                    } else {
                        build_packet_v6(chunk.buf + chunk.info[j].offset,
                                        packet_size, &seed);
                    }

                }
                else
                    memcpy_aligned(chunk.buf + chunk.info[j].offset,
                                   packet[(next_flow[i] + j) % num_flows],
                                   packet_size);
            }

            if (packets - sent < chunk_size)
                chunk.cnt = packets - sent;
            else
                chunk.cnt = chunk_size;

            ret = ps_send_chunk(handle, &chunk);
            assert(ret >= 0);

            update_stats(handle);
            sent += ret;

            if (packets <= sent)
                done();

            if (num_flows)
                next_flow[i] = (next_flow[i] + ret) % num_flows;
        }

        if (!working)
            break;
    }

    ps_close_handle(handle);
}
Beispiel #7
0
int fire_worker_start(int queue_id)
{
	int ret, i, j, k, prot, send_ret;

	fire_worker_t *cc = &(workers[queue_id]); 
	assert(ps_init_handle(&(cc->server_handle)) == 0);
	assert(ps_init_handle(&(cc->client_handle)) == 0);

	struct ps_queue server_queue, client_queue;
	server_queue.ifindex = config->server_ifindex;
	server_queue.qidx = queue_id;
	client_queue.ifindex = config->client_ifindex;
	client_queue.qidx = queue_id;

	assert(ps_attach_rx_device(&(cc->server_handle), &server_queue) == 0);
	assert(ps_attach_rx_device(&(cc->client_handle), &client_queue) == 0);

	struct ps_chunk client_chunk, send_client_chunk, server_chunk, send_server_chunk;
	assert(ps_alloc_chunk(&(cc->client_handle), &client_chunk) == 0);
	assert(ps_alloc_chunk(&(cc->client_handle), &send_client_chunk) == 0);
	assert(ps_alloc_chunk(&(cc->server_handle), &server_chunk) == 0);
	assert(ps_alloc_chunk(&(cc->server_handle), &send_server_chunk) == 0);

	client_chunk.queue.ifindex = config->client_ifindex;
	client_chunk.queue.qidx = queue_id;
	send_client_chunk.queue.ifindex = config->client_ifindex;
	send_client_chunk.queue.qidx = queue_id;
	server_chunk.queue.ifindex = config->server_ifindex;
	server_chunk.queue.qidx = queue_id;
	send_server_chunk.queue.ifindex = config->server_ifindex;
	send_server_chunk.queue.qidx = queue_id;

	int num_pkt_to_client = 0, num_pkt_to_server = 0;
	int pret;

	gettimeofday(&(cc->startime), NULL);

#if defined(HIPAC_TCB)
	int hipac_cnt = 0;
#endif

	for (;;) {
		num_pkt_to_client = 0;
		num_pkt_to_server = 0;
		j = 0;
		k = 0;

		client_chunk.cnt = config->io_batch_num;
		client_chunk.recv_blocking = 0;

		ret = ps_recv_chunk(&(cc->client_handle), &client_chunk);
		if (ret <= 0) {
			/* Receive nothing from server, go to the start of the loop to process client again */
			goto process_server;
		}
		cc->total_packets += ret;

		int action;

		for (i = 0; i < ret; i ++) {
			prot = process_packet(client_chunk.buf + client_chunk.info[i].offset, client_chunk.info[i].len);
			switch (prot) {
				case TCP_SYN_SENT:
					action = HiPAC(client_chunk.buf + client_chunk.info[i].offset, client_chunk.info[i].len, l);
					if(action == FORWARD) {
						// first handshake packet
						// construct the response, and send back to client
						//fprint(INFO, "1) TCP_SYN_SENT\n");
						send_client_chunk.info[j].len = client_chunk.info[i].len;
						send_client_chunk.info[j].offset = j * PS_MAX_PACKET_SIZE;
						memcpy(send_client_chunk.buf + send_client_chunk.info[j].offset,
								client_chunk.buf + client_chunk.info[i].offset, client_chunk.info[i].len);
						form_syn_response(send_client_chunk.buf + send_client_chunk.info[j].offset,
								send_client_chunk.info[j].len);
						pret = process_packet(send_client_chunk.buf 
								+ send_client_chunk.info[j].offset, send_client_chunk.info[j].len);
#if 0
						if(pret != TCP_SYN_RECV){
							printf("pret is %d\n", pret);
							printf("client:\n");
							dmesg(client_chunk.buf + client_chunk.info[i].offset);
							printf("server:\n");
							dmesg(send_client_chunk.buf + send_client_chunk.info[j].offset);
							exit(0);
						}
#endif
						assert(pret == TCP_SYN_RECV);
						//fprint(INFO, "2) TCP_SYN_RECV\n");
						j ++;
					}
					else{ 
					//	hipac_cnt ++;
					//	if(hipac_cnt > 0) printf("hipac filter : %d\n", hipac_cnt);
						delete_tcp(client_chunk.buf + client_chunk.info[i].offset);
					}			
					break;

				case TCP_ESTABLISHED:
					// the 3rd handshake packet
					// do nothing and wait for client's real request
					//fprint(INFO, "3) TCP_ESTABLISHED\n");
					break;

				case -2:
					//fprint(INFO, "two buckets full\n");
					break;

				case -1:
					//fprint(INFO, "Error pkt, don't forward to server.\n");
					break;

				default:
					// normal packet, send to server
					//fprint(INFO, "4) Normal packet, send to server\n");
					send_server_chunk.info[k].len = client_chunk.info[i].len;
					send_server_chunk.info[k].offset = k * PS_MAX_PACKET_SIZE;
					memcpy(send_server_chunk.buf + send_server_chunk.info[k].offset,
							client_chunk.buf + client_chunk.info[i].offset, client_chunk.info[i].len);
					k ++;
					break;
			}

			cc->total_bytes += client_chunk.info[i].len; 

		}
	
		if (j > 0) {
			//fprint(INFO, "sending %d SYN/ACK packet to client, queue_id %d, ifindex %d\n", j, queue_id, config->client_ifindex);
			send_client_chunk.cnt = j;
			send_ret = ps_send_chunk(&(cc->client_handle), &send_client_chunk);
			if (send_ret < 0)
				fprint(ERROR, "send packet fail, ret = %d\n", send_ret);
		}

		if (k > 0) {
			//fprint(INFO, "sending %d packets of established connection to server, queue_id %d, ifindex %d\n", k, queue_id, config->server_ifindex);
			send_server_chunk.cnt = k;
			send_ret = ps_send_chunk(&(cc->server_handle), &send_server_chunk);
			if (send_ret < 0)
				fprint(ERROR, "send packet fail, ret = %d\n", send_ret);
		}
#if 0
		/* FIXME: cannot send all packets
		while (ret > 0) {
			chunk.cnt = ret;
			send_ret = ps_send_chunk(&(cc->handle), &send_chunk);
			if (send_ret < 0)
				fprint(ERROR, "send packet fail, ret = %d\n", send_ret);
			ret -= send_ret;
			//assert(ret >= 0);
		}*/
#endif

process_server:
		/*----------------------------------------------------------------------------------*/
		/* Now process server side packet*/
		server_chunk.cnt = config->io_batch_num;
		//server_chunk.recv_blocking = 0;	//modify at the frist time

		server_chunk.recv_blocking = 0;
		j = 0;

		ret = ps_recv_chunk(&(cc->server_handle), &server_chunk);
		if (ret <= 0) {
			if (errno == EINTR)
				continue;
			/* Receive nothing from server, go to the start of the loop to process client again */
			continue;
		}
		for (i = 0; i < ret; i ++) {
			prot = process_packet(server_chunk.buf + server_chunk.info[i].offset, server_chunk.info[i].len);
			if (prot == 0) {
				send_client_chunk.info[j].len = server_chunk.info[i].len;
				send_client_chunk.info[j].offset = j * PS_MAX_PACKET_SIZE;
				memcpy(send_client_chunk.buf + send_client_chunk.info[j].offset,
					server_chunk.buf + server_chunk.info[i].offset, server_chunk.info[i].len);
				j ++;
			} else {
				fprint(ERROR, "wrong packet from server\n");
			}
		}

		if (j > 0) {
			fprint(DEBUG, "sending packet, queue_id %d, num %d, index %d\n", queue_id, ret, config->client_ifindex);
			send_client_chunk.cnt = j;
			send_ret = ps_send_chunk(&(cc->client_handle), &send_client_chunk);
			if (send_ret < 0)
				fprint(ERROR, "send packet fail, ret = %d\n", send_ret);
		}
	}
	return 0;
}
Beispiel #8
0
void echo()
{
	struct ps_handle *handle = &handles[my_cpu];
	struct ps_chunk chunk;

	int i;
	int working = 0;

	assert(ps_init_handle(handle) == 0);

	for (i = 0; i < num_devices_attached; i++) {
		struct ps_queue queue;
		if (devices[devices_attached[i]].num_rx_queues <= my_cpu)
			continue;

		if (devices[devices_attached[i]].num_tx_queues <= my_cpu) {
			printf("WARNING: xge%d has not enough TX queues!\n",
					devices_attached[i]);
			continue;
		}

		working = 1;
		queue.ifindex = devices_attached[i];
		queue.qidx = my_cpu;

		printf("attaching RX queue xge%d:%d to CPU%d\n", queue.ifindex, queue.qidx, my_cpu);
		assert(ps_attach_rx_device(handle, &queue) == 0);
	}

	if (!working)
		goto done;

	assert(ps_alloc_chunk(handle, &chunk) == 0);

	chunk.recv_blocking = 1;

	for (;;) {
		int ret, i, j;
		struct ethhdr *eth;

		chunk.cnt = 64;
		ret = ps_recv_chunk(handle, &chunk);

		if (ret < 0) {
			if (errno == EINTR)
				continue;

			if (!chunk.recv_blocking && errno == EWOULDBLOCK)
				break;

			assert(0);
		}

		if (!echo_as_is) {
			for (i = 0; i < ret; i++) {
				char tmp[6];
				bool drop = true;
				eth = (struct ethhdr *)chunk.buf + chunk.info[i].offset;

				if (!sink)
					for (j = 0; j < num_devices_attached; j++) {
						drop &= !(memcmp(devices[j].dev_addr, eth->h_dest, ETH_ALEN) == 0);
					}

				if (drop) {
					chunk.info[i].offset = -1;
				} else {
					memcpy(tmp, eth->h_dest, 6);
					memcpy(eth->h_dest, eth->h_source, 6);
					memcpy(eth->h_source, tmp, 6);
				}
			}
		}

		if (!sink) {
			chunk.cnt = ret;
			ret = ps_send_chunk(handle, &chunk);
			assert(ret >= 0);
		}
	}

done:
	ps_close_handle(handle);
}