X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=examples%2Ftep_termination%2Fmain.c;h=f97d552a44d94f677e9463092e96baf4bf1bb03a;hb=badb3688ffa8e9731770e686ba84123783060c1b;hp=9154703082534e9ba58560304a681e93570546f6;hpb=16bd87904fbbe476f98d6b39f7b1aeb2ad983811;p=dpdk.git diff --git a/examples/tep_termination/main.c b/examples/tep_termination/main.c index 9154703082..f97d552a44 100644 --- a/examples/tep_termination/main.c +++ b/examples/tep_termination/main.c @@ -53,6 +53,7 @@ #include "main.h" #include "vxlan.h" +#include "vxlan_setup.h" /* the maximum number of external ports supported */ #define MAX_SUP_PORTS 1 @@ -111,6 +112,12 @@ #define MAC_ADDR_CMP 0xFFFFFFFFFFFFULL #define CMD_LINE_OPT_NB_DEVICES "nb-devices" +#define CMD_LINE_OPT_UDP_PORT "udp-port" +#define CMD_LINE_OPT_TX_CHECKSUM "tx-checksum" +#define CMD_LINE_OPT_TSO_SEGSZ "tso-segsz" +#define CMD_LINE_OPT_FILTER_TYPE "filter-type" +#define CMD_LINE_OPT_ENCAP "encap" +#define CMD_LINE_OPT_DECAP "decap" #define CMD_LINE_OPT_RX_RETRY "rx-retry" #define CMD_LINE_OPT_RX_RETRY_DELAY "rx-retry-delay" #define CMD_LINE_OPT_RX_RETRY_NUM "rx-retry-num" @@ -124,7 +131,7 @@ static uint32_t enabled_port_mask; static uint32_t nb_switching_cores; /* number of devices/queues to support*/ -uint32_t nb_devices; +uint16_t nb_devices = 2; /* max ring descriptor, ixgbe, i40e, e1000 all are 4096. */ #define MAX_RING_DESC 4096 @@ -135,6 +142,34 @@ struct vpool { uint32_t buf_size; } vpool_array[MAX_QUEUES+MAX_QUEUES]; +/* UDP tunneling port */ +uint16_t udp_port = 4789; + +/* enable/disable inner TX checksum */ +uint8_t tx_checksum = 0; + +/* TCP segment size */ +uint16_t tso_segsz = 0; + +/* enable/disable decapsulation */ +uint8_t rx_decap = 1; + +/* enable/disable encapsulation */ +uint8_t tx_encap = 1; + +/* RX filter type for tunneling packet */ +uint8_t filter_idx = 1; + +/* overlay packet operation */ +struct ol_switch_ops overlay_options = { + .port_configure = vxlan_port_init, + .tunnel_setup = vxlan_link, + .tunnel_destroy = vxlan_unlink, + .tx_handle = vxlan_tx_pkts, + .rx_handle = vxlan_rx_pkts, + .param_handle = NULL, +}; + /* Enable stats. */ uint32_t enable_stats = 0; /* Enable retries on RX. */ @@ -239,7 +274,16 @@ static void tep_termination_usage(const char *prgname) { RTE_LOG(INFO, VHOST_CONFIG, "%s [EAL options] -- -p PORTMASK\n" + " --udp-port: UDP destination port for VXLAN packet\n" " --nb-devices[1-64]: The number of virtIO device\n" + " --tx-checksum [0|1]: inner Tx checksum offload\n" + " --tso-segsz [0-N]: TCP segment size\n" + " --decap [0|1]: tunneling packet decapsulation\n" + " --encap [0|1]: tunneling packet encapsulation\n" + " --filter-type[1-3]: filter type for tunneling packet\n" + " 1: Inner MAC and tenent ID\n" + " 2: Inner MAC and VLAN, and tenent ID\n" + " 3: Outer MAC, Inner MAC and tenent ID\n" " -p PORTMASK: Set mask for ports to be used by application\n" " --rx-retry [0|1]: disable/enable(default) retries on rx." " Enable retry if destintation queue is full\n" @@ -264,6 +308,12 @@ tep_termination_parse_args(int argc, char **argv) const char *prgname = argv[0]; static struct option long_option[] = { {CMD_LINE_OPT_NB_DEVICES, required_argument, NULL, 0}, + {CMD_LINE_OPT_UDP_PORT, required_argument, NULL, 0}, + {CMD_LINE_OPT_TX_CHECKSUM, required_argument, NULL, 0}, + {CMD_LINE_OPT_TSO_SEGSZ, required_argument, NULL, 0}, + {CMD_LINE_OPT_DECAP, required_argument, NULL, 0}, + {CMD_LINE_OPT_ENCAP, required_argument, NULL, 0}, + {CMD_LINE_OPT_FILTER_TYPE, required_argument, NULL, 0}, {CMD_LINE_OPT_RX_RETRY, required_argument, NULL, 0}, {CMD_LINE_OPT_RX_RETRY_DELAY, required_argument, NULL, 0}, {CMD_LINE_OPT_RX_RETRY_NUM, required_argument, NULL, 0}, @@ -311,9 +361,34 @@ tep_termination_parse_args(int argc, char **argv) "Invalid argument for rx-retry [0|1]\n"); tep_termination_usage(prgname); return -1; - } else { + } else enable_retry = ret; - } + } + + if (!strncmp(long_option[option_index].name, + CMD_LINE_OPT_TSO_SEGSZ, + sizeof(CMD_LINE_OPT_TSO_SEGSZ))) { + ret = parse_num_opt(optarg, INT16_MAX); + if (ret == -1) { + RTE_LOG(INFO, VHOST_CONFIG, + "Invalid argument for TCP segment size [0-N]\n"); + tep_termination_usage(prgname); + return -1; + } else + tso_segsz = ret; + } + + if (!strncmp(long_option[option_index].name, + CMD_LINE_OPT_UDP_PORT, + sizeof(CMD_LINE_OPT_UDP_PORT))) { + ret = parse_num_opt(optarg, INT16_MAX); + if (ret == -1) { + RTE_LOG(INFO, VHOST_CONFIG, + "Invalid argument for UDP port [0-N]\n"); + tep_termination_usage(prgname); + return -1; + } else + udp_port = ret; } /* Specify the retries delay time (in useconds) on RX.*/ @@ -326,9 +401,8 @@ tep_termination_parse_args(int argc, char **argv) "Invalid argument for rx-retry-delay [0-N]\n"); tep_termination_usage(prgname); return -1; - } else { + } else burst_rx_delay_time = ret; - } } /* Specify the retries number on RX. */ @@ -341,9 +415,62 @@ tep_termination_parse_args(int argc, char **argv) "Invalid argument for rx-retry-num [0-N]\n"); tep_termination_usage(prgname); return -1; - } else { + } else burst_rx_retry_num = ret; - } + } + + if (!strncmp(long_option[option_index].name, + CMD_LINE_OPT_TX_CHECKSUM, + sizeof(CMD_LINE_OPT_TX_CHECKSUM))) { + ret = parse_num_opt(optarg, 1); + if (ret == -1) { + RTE_LOG(INFO, VHOST_CONFIG, + "Invalid argument for tx-checksum [0|1]\n"); + tep_termination_usage(prgname); + return -1; + } else + tx_checksum = ret; + } + + if (!strncmp(long_option[option_index].name, + CMD_LINE_OPT_FILTER_TYPE, + sizeof(CMD_LINE_OPT_FILTER_TYPE))) { + ret = parse_num_opt(optarg, 3); + if ((ret == -1) || (ret == 0)) { + RTE_LOG(INFO, VHOST_CONFIG, + "Invalid argument for filter type [1-3]\n"); + tep_termination_usage(prgname); + return -1; + } else + filter_idx = ret - 1; + } + + /* Enable/disable encapsulation on RX. */ + if (!strncmp(long_option[option_index].name, + CMD_LINE_OPT_DECAP, + sizeof(CMD_LINE_OPT_DECAP))) { + ret = parse_num_opt(optarg, 1); + if (ret == -1) { + RTE_LOG(INFO, VHOST_CONFIG, + "Invalid argument for decap [0|1]\n"); + tep_termination_usage(prgname); + return -1; + } else + rx_decap = ret; + } + + /* Enable/disable encapsulation on TX. */ + if (!strncmp(long_option[option_index].name, + CMD_LINE_OPT_ENCAP, + sizeof(CMD_LINE_OPT_ENCAP))) { + ret = parse_num_opt(optarg, 1); + if (ret == -1) { + RTE_LOG(INFO, VHOST_CONFIG, + "Invalid argument for encap [0|1]\n"); + tep_termination_usage(prgname); + return -1; + } else + tx_encap = ret; } /* Enable/disable stats. */ @@ -356,9 +483,8 @@ tep_termination_parse_args(int argc, char **argv) "Invalid argument for stats [0..N]\n"); tep_termination_usage(prgname); return -1; - } else { + } else enable_stats = ret; - } } /* Set character device basename. */ @@ -458,6 +584,10 @@ virtio_tx_route(struct vhost_dev *vdev, struct rte_mbuf *m) if (unlikely(len == MAX_PKT_BURST)) { m_table = (struct rte_mbuf **)tx_q->m_table; + ret = overlay_options.tx_handle(ports[0], + (uint16_t)tx_q->txq_id, m_table, + (uint16_t)tx_q->len); + /* Free any buffers not handled by TX and update * the port stats. */ @@ -524,6 +654,10 @@ switch_worker(__rte_unused void *arg) LOG_DEBUG(VHOST_DATA, "TX queue drained after " "timeout with burst size %u\n", tx_q->len); + ret = overlay_options.tx_handle(ports[0], + (uint16_t)tx_q->txq_id, + (struct rte_mbuf **)tx_q->m_table, + (uint16_t)tx_q->len); if (unlikely(ret < tx_q->len)) { do { rte_pktmbuf_free(tx_q->m_table[ret]); @@ -558,6 +692,7 @@ switch_worker(__rte_unused void *arg) if (unlikely(vdev->remove)) { dev_ll = dev_ll->next; + overlay_options.tunnel_destroy(vdev); vdev->ready = DEVICE_SAFE_REMOVE; continue; } @@ -583,6 +718,7 @@ switch_worker(__rte_unused void *arg) } } + ret_count = overlay_options.rx_handle(dev, pkts_burst, rx_count); if (enable_stats) { rte_atomic64_add( &dev_statistics[dev->device_fh].rx_total_atomic, @@ -605,7 +741,8 @@ switch_worker(__rte_unused void *arg) pkts_burst, MAX_PKT_BURST); /* If this is the first received packet we need to learn the MAC */ if (unlikely(vdev->ready == DEVICE_MAC_LEARNING) && tx_count) { - if (vdev->remove) { + if (vdev->remove || + (overlay_options.tunnel_setup(vdev, pkts_burst[0]) == -1)) { while (tx_count) rte_pktmbuf_free(pkts_burst[--tx_count]); } @@ -961,7 +1098,7 @@ print_stats(void) { struct virtio_net_data_ll *dev_ll; uint64_t tx_dropped, rx_dropped; - uint64_t tx, tx_total, rx, rx_total; + uint64_t tx, tx_total, rx, rx_total, rx_ip_csum, rx_l4_csum; uint32_t device_fh; const char clr[] = { 27, '[', '2', 'J', '\0' }; const char top_left[] = { 27, '[', '1', ';', '1', 'H', '\0' }; @@ -986,12 +1123,18 @@ print_stats(void) rx = rte_atomic64_read( &dev_statistics[device_fh].rx_atomic); rx_dropped = rx_total - rx; + rx_ip_csum = rte_atomic64_read( + &dev_statistics[device_fh].rx_bad_ip_csum); + rx_l4_csum = rte_atomic64_read( + &dev_statistics[device_fh].rx_bad_l4_csum); printf("\nStatistics for device %"PRIu32" ----------" "\nTX total: %"PRIu64"" "\nTX dropped: %"PRIu64"" "\nTX successful: %"PRIu64"" "\nRX total: %"PRIu64"" + "\nRX bad IP csum: %"PRIu64"" + "\nRX bad L4 csum: %"PRIu64"" "\nRX dropped: %"PRIu64"" "\nRX successful: %"PRIu64"", device_fh, @@ -999,6 +1142,8 @@ print_stats(void) tx_dropped, tx, rx_total, + rx_ip_csum, + rx_l4_csum, rx_dropped, rx); @@ -1022,6 +1167,7 @@ main(int argc, char *argv[]) uint8_t portid; uint16_t queue_id; static pthread_t tid; + char thread_name[RTE_MAX_THREAD_NAME_LEN]; /* init EAL */ ret = rte_eal_init(argc, argv); @@ -1058,7 +1204,6 @@ main(int argc, char *argv[]) "but only %u port can be enabled\n", nb_ports, MAX_SUP_PORTS); } - /* Create the mbuf pool. */ mbuf_pool = rte_mempool_create( "MBUF_POOL", @@ -1086,6 +1231,9 @@ main(int argc, char *argv[]) "Skipping disabled port %d\n", portid); continue; } + if (overlay_options.port_configure(portid, mbuf_pool) != 0) + rte_exit(EXIT_FAILURE, + "Cannot initialize network ports\n"); } /* Initialise all linked lists. */ @@ -1096,15 +1244,21 @@ main(int argc, char *argv[]) memset(&dev_statistics, 0, sizeof(dev_statistics)); /* Enable stats if the user option is set. */ - if (enable_stats) - pthread_create(&tid, NULL, (void *)print_stats, NULL); + if (enable_stats) { + ret = pthread_create(&tid, NULL, (void *)print_stats, NULL); + if (ret != 0) + rte_exit(EXIT_FAILURE, "Cannot create print-stats thread\n"); + snprintf(thread_name, RTE_MAX_THREAD_NAME_LEN, "print-stats"); + ret = rte_thread_setname(tid, thread_name); + if (ret != 0) + RTE_LOG(ERR, VHOST_CONFIG, "Cannot set print-stats name\n"); + } /* Launch all data cores. */ RTE_LCORE_FOREACH_SLAVE(lcore_id) { rte_eal_remote_launch(switch_worker, mbuf_pool, lcore_id); } - rte_vhost_feature_disable(1ULL << VIRTIO_NET_F_MRG_RXBUF); /* Register CUSE device to handle IOCTLs. */