[spp] [PATCH 1/4] spp_nfv: add pcap pmd

ogawa.yasufumi at lab.ntt.co.jp ogawa.yasufumi at lab.ntt.co.jp
Wed Jan 31 12:21:10 CET 2018


From: ogawa.yasufumi at lab.ntt.co.jp

From: Yasufumi Ogawa <ogawa.yasufumi at lab.ntt.co.jp>

Add libpcap-based PMD[1] support to read and write packets from files
on host. As ring or vhost PMD, pcap PMD is created from add_pcap_pmd().
Pcap device is created as '/tmp/rx_*.pcap' and '/tmp/tx_*.pcap' from
rte_eth_dev_attach().

[1] https://dpdk.org/doc/guides/nics/pcap_ring.html

Signed-off-by: Yasufumi Ogawa <ogawa.yasufumi at lab.ntt.co.jp>
Signed-off-by: Naoki Takada <takada.naoki at lab.ntt.co.jp>
---
 src/nfv/nfv.c       | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
 src/shared/common.c |  5 ++++
 src/shared/common.h | 10 +++++++
 3 files changed, 99 insertions(+), 1 deletion(-)

diff --git a/src/nfv/nfv.c b/src/nfv/nfv.c
index fd82690..c1a48e9 100644
--- a/src/nfv/nfv.c
+++ b/src/nfv/nfv.c
@@ -346,7 +346,6 @@ do_del(char *token_list[], int max_token)
 		if (port_id < 0)
 			return -1;
 
-
 	} else if (!strcmp(token_list[1], "ring")) {
 		char name[RTE_ETH_NAME_MAX_LEN];
 
@@ -358,6 +357,18 @@ do_del(char *token_list[], int max_token)
 			return -1;
 
 		rte_eth_dev_detach(port_id, name);
+
+	} else if (!strcmp(token_list[1], "pcap")) {
+		char name[RTE_ETH_NAME_MAX_LEN];
+
+		if (spp_atoi(token_list[2], &id) < 0)
+			return 0;
+
+		port_id = find_port_id(id, PCAP);
+		if (port_id < 0)
+			return -1;
+
+		rte_eth_dev_detach(port_id, name);
 	}
 
 	forward_array_remove(port_id);
@@ -484,6 +495,71 @@ add_vhost_pmd(int index)
 }
 
 static int
+add_pcap_pmd(int index)
+{
+	struct rte_eth_conf port_conf = {
+		.rxmode = { .max_rx_pkt_len = ETHER_MAX_LEN }
+	};
+
+	struct rte_mempool *mp;
+	const char *name;
+	char devargs[256];
+	uint16_t pcap_pmd_port_id;
+	uint16_t nr_queues = 1;
+
+	int ret;
+
+	mp = rte_mempool_lookup(PKTMBUF_POOL_NAME);
+	if (mp == NULL)
+		rte_exit(EXIT_FAILURE, "Cannon get mempool for mbuf\n");
+
+	name = get_pcap_pmd_name(index);
+	sprintf(devargs,
+		"%s,rx_pcap=/tmp/rx_%d.pcap,tx_pcap=/tmp/tx_%d.pcap",
+		name, index, index);
+	ret = rte_eth_dev_attach(devargs, &pcap_pmd_port_id);
+
+	if (ret < 0)
+		return ret;
+
+	ret = rte_eth_dev_configure(
+			pcap_pmd_port_id, nr_queues, nr_queues, &port_conf);
+
+	if (ret < 0)
+		return ret;
+
+	/* Allocate and set up 1 RX queue per Ethernet port. */
+	uint16_t q;
+	for (q = 0; q < nr_queues; q++) {
+		ret = rte_eth_rx_queue_setup(
+				pcap_pmd_port_id, q, NR_DESCS,
+				rte_eth_dev_socket_id(pcap_pmd_port_id),
+				NULL, mp);
+		if (ret < 0)
+			return ret;
+	}
+
+	/* Allocate and set up 1 TX queue per Ethernet port. */
+	for (q = 0; q < nr_queues; q++) {
+		ret = rte_eth_tx_queue_setup(
+				pcap_pmd_port_id, q, NR_DESCS,
+				rte_eth_dev_socket_id(pcap_pmd_port_id),
+				NULL);
+		if (ret < 0)
+			return ret;
+	}
+
+	ret = rte_eth_dev_start(pcap_pmd_port_id);
+
+	if (ret < 0)
+		return ret;
+
+	RTE_LOG(DEBUG, APP, "pcap port id %d\n", pcap_pmd_port_id);
+
+	return pcap_pmd_port_id;
+}
+
+static int
 do_add(char *token_list[], int max_token)
 {
 	enum port_type type = UNDEF;
@@ -506,6 +582,13 @@ do_add(char *token_list[], int max_token)
 
 		type = RING;
 		port_id = add_ring_pmd(id);
+
+	} else if (!strcmp(token_list[1], "pcap")) {
+		if (spp_atoi(token_list[2], &id) < 0)
+			return 0;
+
+		type = PCAP;
+		port_id = add_pcap_pmd(id);
 	}
 
 	if (port_id < 0)
diff --git a/src/shared/common.c b/src/shared/common.c
index 5b87385..c577d12 100644
--- a/src/shared/common.c
+++ b/src/shared/common.c
@@ -297,6 +297,11 @@ print_active_ports(char *str, uint16_t client_id,
 			sprintf(str + strlen(str), "VHOST(%u),",
 				port_map[i].id);
 			break;
+		case PCAP:
+			RTE_LOG(INFO, APP, "Type: PCAP\n");
+			sprintf(str + strlen(str), "PCAP(%u),",
+					port_map[i].id);
+			break;
 		case UNDEF:
 			RTE_LOG(INFO, APP, "Type: UDF\n");
 			sprintf(str + strlen(str), "UDF,");
diff --git a/src/shared/common.h b/src/shared/common.h
index 5defbb0..c5f39d1 100644
--- a/src/shared/common.h
+++ b/src/shared/common.h
@@ -118,6 +118,7 @@ enum port_type {
 	PHY,
 	RING,
 	VHOST,
+	PCAP,
 	UNDEF,
 };
 
@@ -143,6 +144,7 @@ struct port {
 #define MZ_PORT_INFO "MProc_port_info"
 #define VHOST_BACKEND_NAME "eth_vhost%u"
 #define VHOST_IFACE_NAME "/tmp/sock%u"
+#define PCAP_PMD_DEV_NAME "eth_pcap%u"
 
 /*
  * Given the rx queue name template above, get the queue name
@@ -186,6 +188,14 @@ get_vhost_iface_name(unsigned int id)
 	return buffer;
 }
 
+static inline const char *
+get_pcap_pmd_name(int id)
+{
+	static char buffer[sizeof(PCAP_PMD_DEV_NAME) + 2];
+	snprintf(buffer, sizeof(buffer) - 1, PCAP_PMD_DEV_NAME, id);
+	return buffer;
+}
+
 void check_all_ports_link_status(struct port_info *ports, uint16_t port_num,
 		uint32_t port_mask);
 
-- 
2.13.1




More information about the spp mailing list