app/testpmd: VXLAN packet identification
authorJijiang Liu <jijiang.liu@intel.com>
Thu, 23 Oct 2014 13:18:55 +0000 (21:18 +0800)
committerThomas Monjalon <thomas.monjalon@6wind.com>
Mon, 27 Oct 2014 13:37:34 +0000 (14:37 +0100)
Add two commands to test VXLAN packet identification.
The test steps are as follows:
 1> use commands to add/delete VxLAN UDP port.
 2> use rxonly mode to receive VxLAN packet.

Signed-off-by: Jijiang Liu <jijiang.liu@intel.com>
Acked-by: Helin Zhang <helin.zhang@intel.com>
Tested-by: Yong Liu <yong.liu@intel.com>
app/test-pmd/cmdline.c
app/test-pmd/rxonly.c

index 0b972f9..4d7b4d1 100644 (file)
@@ -285,6 +285,12 @@ static void cmd_help_long_parsed(void *parsed_result,
                        "    Set the outer VLAN TPID for Packet Filtering on"
                        " a port\n\n"
 
+                       "rx_vxlan_port add (udp_port) (port_id)\n"
+                       "    Add an UDP port for VxLAN packet filter on a port\n\n"
+
+                       "rx_vxlan_port rm (udp_port) (port_id)\n"
+                       "    Remove an UDP port for VxLAN packet filter on a port\n\n"
+
                        "tx_vlan set vlan_id (port_id)\n"
                        "    Set hardware insertion of VLAN ID in packets sent"
                        " on a port.\n\n"
@@ -6225,6 +6231,64 @@ cmdline_parse_inst_t cmd_vf_rate_limit = {
        },
 };
 
+/* *** CONFIGURE TUNNEL UDP PORT *** */
+struct cmd_tunnel_udp_config {
+       cmdline_fixed_string_t cmd;
+       cmdline_fixed_string_t what;
+       uint16_t udp_port;
+       uint8_t port_id;
+};
+
+static void
+cmd_tunnel_udp_config_parsed(void *parsed_result,
+                         __attribute__((unused)) struct cmdline *cl,
+                         __attribute__((unused)) void *data)
+{
+       struct cmd_tunnel_udp_config *res = parsed_result;
+       struct rte_eth_udp_tunnel tunnel_udp;
+       int ret;
+
+       tunnel_udp.udp_port = res->udp_port;
+
+       if (!strcmp(res->cmd, "rx_vxlan_port"))
+               tunnel_udp.prot_type = RTE_TUNNEL_TYPE_VXLAN;
+
+       if (!strcmp(res->what, "add"))
+               ret = rte_eth_dev_udp_tunnel_add(res->port_id, &tunnel_udp);
+       else
+               ret = rte_eth_dev_udp_tunnel_delete(res->port_id, &tunnel_udp);
+
+       if (ret < 0)
+               printf("udp tunneling add error: (%s)\n", strerror(-ret));
+}
+
+cmdline_parse_token_string_t cmd_tunnel_udp_config_cmd =
+       TOKEN_STRING_INITIALIZER(struct cmd_tunnel_udp_config,
+                               cmd, "rx_vxlan_port");
+cmdline_parse_token_string_t cmd_tunnel_udp_config_what =
+       TOKEN_STRING_INITIALIZER(struct cmd_tunnel_udp_config,
+                               what, "add#rm");
+cmdline_parse_token_num_t cmd_tunnel_udp_config_udp_port =
+       TOKEN_NUM_INITIALIZER(struct cmd_tunnel_udp_config,
+                               udp_port, UINT16);
+cmdline_parse_token_num_t cmd_tunnel_udp_config_port_id =
+       TOKEN_NUM_INITIALIZER(struct cmd_tunnel_udp_config,
+                               port_id, UINT8);
+
+cmdline_parse_inst_t cmd_tunnel_udp_config = {
+       .f = cmd_tunnel_udp_config_parsed,
+       .data = (void *)0,
+       .help_str = "add/rm an tunneling UDP port filter: "
+                       "rx_vxlan_port add udp_port port_id",
+       .tokens = {
+               (void *)&cmd_tunnel_udp_config_cmd,
+               (void *)&cmd_tunnel_udp_config_what,
+               (void *)&cmd_tunnel_udp_config_udp_port,
+               (void *)&cmd_tunnel_udp_config_port_id,
+               NULL,
+       },
+};
+
 /* *** CONFIGURE VM MIRROR VLAN/POOL RULE *** */
 struct cmd_set_mirror_mask_result {
        cmdline_fixed_string_t set;
@@ -7518,6 +7582,7 @@ cmdline_parse_ctx_t main_ctx[] = {
        (cmdline_parse_inst_t *)&cmd_vf_rxvlan_filter,
        (cmdline_parse_inst_t *)&cmd_queue_rate_limit,
        (cmdline_parse_inst_t *)&cmd_vf_rate_limit,
+       (cmdline_parse_inst_t *)&cmd_tunnel_udp_config,
        (cmdline_parse_inst_t *)&cmd_set_mirror_mask,
        (cmdline_parse_inst_t *)&cmd_set_mirror_link,
        (cmdline_parse_inst_t *)&cmd_reset_mirror_rule,
index 98c788b..a5a80a7 100644 (file)
 #include <rte_ether.h>
 #include <rte_ethdev.h>
 #include <rte_string_fns.h>
+#include <rte_ip.h>
+#include <rte_udp.h>
 
 #include "testpmd.h"
 
-#define MAX_PKT_RX_FLAGS 11
+#define MAX_PKT_RX_FLAGS 13
 static const char *pkt_rx_flag_names[MAX_PKT_RX_FLAGS] = {
        "VLAN_PKT",
        "RSS_HASH",
@@ -84,6 +86,9 @@ static const char *pkt_rx_flag_names[MAX_PKT_RX_FLAGS] = {
 
        "IEEE1588_PTP",
        "IEEE1588_TMST",
+
+       "TUNNEL_IPV4_HDR",
+       "TUNNEL_IPV6_HDR",
 };
 
 static inline void
@@ -111,7 +116,9 @@ pkt_burst_receive(struct fwd_stream *fs)
        uint16_t eth_type;
        uint64_t ol_flags;
        uint16_t nb_rx;
-       uint16_t i;
+       uint16_t i, packet_type;
+       uint64_t is_encapsulation;
+
 #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
        uint64_t start_tsc;
        uint64_t end_tsc;
@@ -152,6 +159,11 @@ pkt_burst_receive(struct fwd_stream *fs)
                eth_hdr = rte_pktmbuf_mtod(mb, struct ether_hdr *);
                eth_type = RTE_BE_TO_CPU_16(eth_hdr->ether_type);
                ol_flags = mb->ol_flags;
+               packet_type = mb->packet_type;
+
+               is_encapsulation = ol_flags & (PKT_RX_TUNNEL_IPV4_HDR |
+                               PKT_RX_TUNNEL_IPV6_HDR);
+
                print_ether_addr("  src=", &eth_hdr->s_addr);
                print_ether_addr(" - dst=", &eth_hdr->d_addr);
                printf(" - type=0x%04x - length=%u - nb_segs=%d",
@@ -166,6 +178,45 @@ pkt_burst_receive(struct fwd_stream *fs)
                               mb->hash.fdir.hash, mb->hash.fdir.id);
                if (ol_flags & PKT_RX_VLAN_PKT)
                        printf(" - VLAN tci=0x%x", mb->vlan_tci);
+               if (is_encapsulation) {
+                       struct ipv4_hdr *ipv4_hdr;
+                       struct ipv6_hdr *ipv6_hdr;
+                       struct udp_hdr *udp_hdr;
+                       uint8_t l2_len;
+                       uint8_t l3_len;
+                       uint8_t l4_len;
+                       uint8_t l4_proto;
+                       struct  vxlan_hdr *vxlan_hdr;
+
+                       l2_len  = sizeof(struct ether_hdr);
+
+                        /* Do not support ipv4 option field */
+                       if (ol_flags & PKT_RX_TUNNEL_IPV4_HDR) {
+                               l3_len = sizeof(struct ipv4_hdr);
+                               ipv4_hdr = (struct ipv4_hdr *) (rte_pktmbuf_mtod(mb,
+                                               unsigned char *) + l2_len);
+                               l4_proto = ipv4_hdr->next_proto_id;
+                       } else {
+                               l3_len = sizeof(struct ipv6_hdr);
+                               ipv6_hdr = (struct ipv6_hdr *) (rte_pktmbuf_mtod(mb,
+                                               unsigned char *) + l2_len);
+                               l4_proto = ipv6_hdr->proto;
+                       }
+                       if (l4_proto == IPPROTO_UDP) {
+                               udp_hdr = (struct udp_hdr *) (rte_pktmbuf_mtod(mb,
+                                               unsigned char *) + l2_len + l3_len);
+                               l4_len = sizeof(struct udp_hdr);
+                               vxlan_hdr = (struct vxlan_hdr *) (rte_pktmbuf_mtod(mb,
+                                               unsigned char *) + l2_len + l3_len
+                                                + l4_len);
+
+                               printf(" - VxLAN packet: packet type =%d, "
+                                       "Destination UDP port =%d, VNI = %d",
+                                       packet_type, RTE_BE_TO_CPU_16(udp_hdr->dst_port),
+                                       rte_be_to_cpu_32(vxlan_hdr->vx_vni) >> 8);
+                       }
+               }
+               printf(" - Receive queue=0x%x", (unsigned) fs->rx_queue);
                printf("\n");
                if (ol_flags != 0) {
                        int rxf;