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 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); } //} } }
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); } //} } }
/*----------------------------------------------------------------------------*/ int psio_link_devices(struct mtcp_thread_context *ctxt) { struct psio_private_context *ppc; int ret; int i, working; ppc = (struct psio_private_context *)ctxt->io_private_context; working = -1; /* attaching (device, queue) */ for (i = 0 ; i < num_devices_attached ; i++) { struct ps_queue queue; queue.ifindex = devices_attached[i]; if (devices[devices_attached[i]].num_rx_queues <= ctxt->cpu) { continue; } working = 0; queue.ifindex = devices_attached[i]; queue.qidx = ctxt->cpu; #if 0 TRACE_DBG("attaching RX queue xge%d:%d to CPU%d\n", queue.ifindex, queue.qidx, mtcp->ctxt->cpu); #endif ret = ps_attach_rx_device(&ppc->handle, &queue); if (ret != 0) { perror("ps_attach_rx_device"); exit(1); } } return working; }
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); }
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); }