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; } }
void dump() { int ret; struct ps_chunk chunk; char flag = 0; struct ps_handle* handle = &handles[my_cpu]; chunk.queue.ifindex = devices_attached[0]; chunk.queue.qidx = my_cpu; ret = ps_alloc_chunk(handle, &chunk); if (ret != 0) { perror("ps_alloc_chunk"); exit(1); } chunk.cnt = 128; /* no batching */ chunk.recv_blocking = 1; for (;;) { int ret = ps_recv_chunk(handle, &chunk); if (ret < 0) { if (errno == EINTR){ printf("dump errno == EINTR\n"); continue; } if (!chunk.recv_blocking && errno == EWOULDBLOCK){ printf("dump !chunk.recv_blocking && errno == EWOULDBLOCK\n"); break; } assert(0); } if(ret > 0) { if(!flag) { flag = 1; gettimeofday(&start, NULL); } else stat_signal(0); chunk.retcnt = ret; chunk.front = (chunk.front + ret) & (MAX_CHUNK_SIZE - 1); } } }
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); }
void dump() { int ret; struct ps_chunk chunk; ret = ps_alloc_chunk(&handle, &chunk); if (ret != 0) { perror("ps_alloc_chunk"); exit(1); } chunk.cnt = 128; /* no batching */ chunk.recv_blocking = 1; gettimeofday(&startime, NULL); for (;;) { int ret = ps_recv_chunk(&handle, &chunk); //printf("%d pkts from queue %d\n", chunk.cnt, chunk.queue.qidx); if (ret < 0) { if (errno == EINTR) continue; if (!chunk.recv_blocking && errno == EWOULDBLOCK) break; assert(0); } if (ret > 0) { printf("%d ", ret); } /* if (ret > 0) { struct ps_packet packet; printf("%s:%d ", devices[chunk.queue.ifindex].name, chunk.queue.qidx); dump_packet(chunk.buf + chunk.info[0].offset, chunk.info[0].len); packet.arrived_ifindex = chunk.queue.ifindex; packet.len = chunk.info[0].len; packet.buf = chunk.buf + chunk.info[0].offset; assert(ps_slowpath_packet(&handle, &packet) == 0); } printf("--> %d\n", chunk.queue.qidx); chunk.cnt = 1; */ //assert(chunk.cnt == 128); /* if (chunk.cnt != 128) printf("(%d)", chunk.cnt); int i, j=0; for (i = 0; i < chunk.cnt; i ++) { //assert(chunk.info[i].len != 0); if (chunk.info[i].len == 0) { printf("#%d", i); j = 1; } //else printf("0"); } if (j == 1) printf("\n"); */ } }
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; }
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); }