Soft Patch Panel
 help / color / mirror / Atom feed
From: x-fn-spp@sl.ntt-tx.co.jp
To: ferruh.yigit@intel.com, ogawa.yasufumi@lab.ntt.co.jp
Cc: spp@dpdk.org
Subject: [spp] [PATCH v2 3/7] spp_pcap: add management function
Date: Fri,  8 Feb 2019 17:44:34 +0900	[thread overview]
Message-ID: <201902080844.x188ic6d030814@imss04.silk.ntt-tx.co.jp> (raw)
In-Reply-To: <20190208084438.7952-1-x-fn-spp@sl.ntt-tx.co.jp>

From: Hideyuki Yamashita <yamashita.hideyuki@po.ntt-tx.co.jp>

Add data or interface management function for spp_pcap.

Signed-off-by: Hideyuki Yamashita <yamashita.hideyuki@po.ntt-tx.co.jp>
Signed-off-by: Naoki Takada <takada.naoki@lab.ntt.co.jp>
---
 src/pcap/spp_proc.c | 289 ++++++++++++++++++++++++++++++++
 src/pcap/spp_proc.h | 389 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 678 insertions(+)
 create mode 100644 src/pcap/spp_proc.c
 create mode 100644 src/pcap/spp_proc.h

diff --git a/src/pcap/spp_proc.c b/src/pcap/spp_proc.c
new file mode 100644
index 0000000..ab08337
--- /dev/null
+++ b/src/pcap/spp_proc.c
@@ -0,0 +1,289 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018 Nippon Telegraph and Telephone Corporation
+ */
+
+#include <unistd.h>
+#include <string.h>
+
+#include <rte_eth_ring.h>
+#include <rte_log.h>
+
+#include "spp_proc.h"
+
+#define RTE_LOGTYPE_SPP_PROC RTE_LOGTYPE_USER2
+
+/* Manage data to addoress */
+struct manage_data_addr_info {
+	struct startup_param	  *p_startup_param;
+	struct iface_info	  *p_iface_info;
+	struct core_mng_info	  *p_core_info;
+	int			  *p_capture_request;
+	int			  *p_capture_status;
+	unsigned int		  main_lcore_id;
+};
+
+/* Declare global variables */
+/* Logical core ID for main process */
+static struct manage_data_addr_info g_mng_data_addr;
+
+/* generation of the ring port */
+int
+add_ring_pmd(int ring_id)
+{
+	struct rte_ring *ring;
+	int ring_port_id;
+
+	/* Lookup ring of given id */
+	ring = rte_ring_lookup(get_rx_queue_name(ring_id));
+	if (unlikely(ring == NULL)) {
+		RTE_LOG(ERR, SPP_PROC,
+			"Cannot get RX ring - is server process running?\n");
+		return SPP_RET_NG;
+	}
+
+	/* Create ring pmd */
+	ring_port_id = rte_eth_from_ring(ring);
+	RTE_LOG(INFO, SPP_PROC, "ring port add. (no = %d / port = %d)\n",
+			ring_id, ring_port_id);
+	return ring_port_id;
+}
+
+/* Get core status */
+enum spp_core_status
+spp_get_core_status(unsigned int lcore_id)
+{
+	return (g_mng_data_addr.p_core_info + lcore_id)->status;
+}
+
+/**
+ * Check status of all of cores is same as given
+ *
+ * It returns SPP_RET_NG as status mismatch if status is not same.
+ * If core is in use, status will be checked.
+ */
+static int
+check_core_status(enum spp_core_status status)
+{
+	unsigned int lcore_id = 0;
+	RTE_LCORE_FOREACH_SLAVE(lcore_id) {
+		if ((g_mng_data_addr.p_core_info + lcore_id)->status !=
+								status) {
+			/* Status is mismatched */
+			return SPP_RET_NG;
+		}
+	}
+	return SPP_RET_OK;
+}
+
+int
+check_core_status_wait(enum spp_core_status status)
+{
+	int cnt = 0;
+	for (cnt = 0; cnt < SPP_CORE_STATUS_CHECK_MAX; cnt++) {
+		sleep(1);
+		int ret = check_core_status(status);
+		if (ret == 0)
+			return SPP_RET_OK;
+	}
+
+	RTE_LOG(ERR, SPP_PROC,
+			"Status check time out. (status = %d)\n", status);
+	return SPP_RET_NG;
+}
+
+/* Set core status */
+void
+set_core_status(unsigned int lcore_id,
+		enum spp_core_status status)
+{
+	(g_mng_data_addr.p_core_info + lcore_id)->status = status;
+}
+
+/* Set all core to given status */
+void
+set_all_core_status(enum spp_core_status status)
+{
+	unsigned int lcore_id = 0;
+	RTE_LCORE_FOREACH_SLAVE(lcore_id) {
+		(g_mng_data_addr.p_core_info + lcore_id)->status = status;
+	}
+}
+
+/**
+ * Set all of component status to SPP_CORE_STOP_REQUEST if received signal
+ * is SIGTERM or SIGINT
+ */
+void
+stop_process(int signal)
+{
+	if (unlikely(signal != SIGTERM) &&
+			unlikely(signal != SIGINT)) {
+		return;
+	}
+
+	(g_mng_data_addr.p_core_info + g_mng_data_addr.main_lcore_id)->status =
+							SPP_CORE_STOP_REQUEST;
+	set_all_core_status(SPP_CORE_STOP_REQUEST);
+}
+
+/**
+ * Return port info of given type and num of interface
+ *
+ * It returns NULL value if given type is invalid.
+ */
+struct spp_port_info *
+get_iface_info(enum port_type iface_type, int iface_no)
+{
+	struct iface_info *iface_info = g_mng_data_addr.p_iface_info;
+
+	switch (iface_type) {
+	case PHY:
+		return &iface_info->nic[iface_no];
+	case RING:
+		return &iface_info->ring[iface_no];
+	default:
+		return NULL;
+	}
+}
+
+/**
+ * Initialize g_iface_info
+ *
+ * Clear g_iface_info and set initial value.
+ */
+static void
+init_iface_info(void)
+{
+	int port_cnt;  /* increment ether ports */
+	struct iface_info *p_iface_info = g_mng_data_addr.p_iface_info;
+	memset(p_iface_info, 0x00, sizeof(struct iface_info));
+	for (port_cnt = 0; port_cnt < RTE_MAX_ETHPORTS; port_cnt++) {
+		p_iface_info->nic[port_cnt].iface_type = UNDEF;
+		p_iface_info->nic[port_cnt].iface_no   = port_cnt;
+		p_iface_info->nic[port_cnt].dpdk_port  = -1;
+		p_iface_info->nic[port_cnt].class_id.vlantag.vid =
+				ETH_VLAN_ID_MAX;
+		p_iface_info->ring[port_cnt].iface_type = UNDEF;
+		p_iface_info->ring[port_cnt].iface_no   = port_cnt;
+		p_iface_info->ring[port_cnt].dpdk_port  = -1;
+		p_iface_info->ring[port_cnt].class_id.vlantag.vid =
+				ETH_VLAN_ID_MAX;
+	}
+}
+
+/* Initialize g_core_info */
+static void
+init_core_info(void)
+{
+	struct core_mng_info *p_core_info = g_mng_data_addr.p_core_info;
+	memset(p_core_info, 0x00,
+			sizeof(struct core_mng_info)*RTE_MAX_LCORE);
+	set_all_core_status(SPP_CORE_STOP);
+	*g_mng_data_addr.p_capture_request = SPP_CAPTURE_IDLE;
+	*g_mng_data_addr.p_capture_status = SPP_CAPTURE_IDLE;
+}
+
+/* Setup port info of port on host */
+static int
+set_nic_interface(void)
+{
+	int nic_cnt = 0;
+	struct iface_info *p_iface_info = g_mng_data_addr.p_iface_info;
+
+	/* NIC Setting */
+	p_iface_info->num_nic = rte_eth_dev_count_avail();
+	if (p_iface_info->num_nic > RTE_MAX_ETHPORTS)
+		p_iface_info->num_nic = RTE_MAX_ETHPORTS;
+
+	for (nic_cnt = 0; nic_cnt < p_iface_info->num_nic; nic_cnt++) {
+		p_iface_info->nic[nic_cnt].iface_type   = PHY;
+		p_iface_info->nic[nic_cnt].dpdk_port = nic_cnt;
+	}
+
+	return SPP_RET_OK;
+}
+
+/* Setup management info for spp_pcap */
+int
+init_mng_data(void)
+{
+	/* Initialize interface and core information */
+	init_iface_info();
+	init_core_info();
+
+	int ret_nic = set_nic_interface();
+	if (unlikely(ret_nic != SPP_RET_OK))
+		return SPP_RET_NG;
+
+	return SPP_RET_OK;
+}
+
+/**
+ * Generate a formatted string of combination from interface type and
+ * number and assign to given 'port'
+ */
+int spp_format_port_string(char *port, enum port_type iface_type, int iface_no)
+{
+	const char *iface_type_str;
+
+	switch (iface_type) {
+	case PHY:
+		iface_type_str = SPP_IFTYPE_NIC_STR;
+		break;
+	case RING:
+		iface_type_str = SPP_IFTYPE_RING_STR;
+		break;
+	default:
+		return SPP_RET_NG;
+	}
+
+	sprintf(port, "%s:%d", iface_type_str, iface_no);
+
+	return SPP_RET_OK;
+}
+
+/* Set mange data address */
+int spp_set_mng_data_addr(struct startup_param *startup_param_addr,
+			  struct iface_info *iface_addr,
+			  struct core_mng_info *core_mng_addr,
+			  int *capture_request_addr,
+			  int *capture_status_addr,
+			  unsigned int main_lcore_id)
+{
+	if (startup_param_addr == NULL || iface_addr == NULL ||
+			core_mng_addr == NULL ||
+			capture_request_addr == NULL ||
+			capture_status_addr == NULL ||
+			main_lcore_id == 0xffffffff)
+		return SPP_RET_NG;
+
+	g_mng_data_addr.p_startup_param = startup_param_addr;
+	g_mng_data_addr.p_iface_info = iface_addr;
+	g_mng_data_addr.p_core_info = core_mng_addr;
+	g_mng_data_addr.p_capture_request = capture_request_addr;
+	g_mng_data_addr.p_capture_status = capture_status_addr;
+	g_mng_data_addr.main_lcore_id = main_lcore_id;
+
+	return SPP_RET_OK;
+}
+
+/* Get manage data address */
+void spp_get_mng_data_addr(struct startup_param **startup_param_addr,
+			   struct iface_info **iface_addr,
+			   struct core_mng_info **core_mng_addr,
+			   int **capture_request_addr,
+			   int **capture_status_addr)
+{
+
+	if (startup_param_addr != NULL)
+		*startup_param_addr = g_mng_data_addr.p_startup_param;
+	if (iface_addr != NULL)
+		*iface_addr = g_mng_data_addr.p_iface_info;
+	if (core_mng_addr != NULL)
+		*core_mng_addr = g_mng_data_addr.p_core_info;
+	if (capture_request_addr != NULL)
+		*capture_request_addr = g_mng_data_addr.p_capture_request;
+	if (capture_status_addr != NULL)
+		*capture_status_addr = g_mng_data_addr.p_capture_status;
+
+}
diff --git a/src/pcap/spp_proc.h b/src/pcap/spp_proc.h
new file mode 100644
index 0000000..6da5c5e
--- /dev/null
+++ b/src/pcap/spp_proc.h
@@ -0,0 +1,389 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018 Nippon Telegraph and Telephone Corporation
+ */
+
+#ifndef _SPP_PROC_H_
+#define _SPP_PROC_H_
+
+/**
+ * @file
+ * SPP process
+ *
+ * SPP component common function.
+ */
+
+#include <netinet/in.h>
+#include "shared/common.h"
+
+/* Max number of core status check */
+#define SPP_CORE_STATUS_CHECK_MAX 5
+
+/** The length of shortest character string */
+#define SPP_MIN_STR_LEN   32
+
+/** The length of NAME string */
+#define SPP_NAME_STR_LEN  128
+
+/** Maximum number of port abilities available */
+#define SPP_PORT_ABILITY_MAX 4
+
+/** Identifier string for each interface */
+#define SPP_IFTYPE_NIC_STR   "phy"
+#define SPP_IFTYPE_RING_STR  "ring"
+
+/* State on core */
+enum spp_core_status {
+	SPP_CORE_UNUSE,        /**< Not used */
+	SPP_CORE_STOP,         /**< Stopped */
+	SPP_CORE_IDLE,         /**< Idling */
+	SPP_CORE_FORWARD,      /**< Forwarding  */
+	SPP_CORE_STOP_REQUEST, /**< Request stopping */
+	SPP_CORE_IDLE_REQUEST  /**< Request idling */
+};
+
+/* State on capture */
+enum spp_capture_status {
+	SPP_CAPTURE_IDLE,      /* Idling */
+	SPP_CAPTURE_RUNNING     /* Running */
+};
+
+enum spp_return_value {
+	SPP_RET_OK = 0,  /**< succeeded */
+	SPP_RET_NG = -1, /**< failed */
+};
+
+/**
+ * Port type (rx or tx) to indicate which direction packet goes
+ * (e.g. receiving or transmitting)
+ */
+enum spp_port_rxtx {
+	SPP_PORT_RXTX_NONE, /**< none */
+	SPP_PORT_RXTX_RX,   /**< rx port */
+	SPP_PORT_RXTX_TX,   /**< tx port */
+	SPP_PORT_RXTX_ALL,  /**< rx/tx port */
+};
+
+/* Process type for each component */
+enum spp_component_type {
+	SPP_COMPONENT_UNUSE,          /**< Not used */
+	SPP_COMPONENT_CLASSIFIER_MAC, /**< Classifier_mac */
+	SPP_COMPONENT_MERGE,          /**< Merger */
+	SPP_COMPONENT_FORWARD,        /**< Forwarder */
+	SPP_COMPONENT_MIRROR,         /**< Mirror */
+};
+
+/**
+ * Port ability operation which indicates vlan tag operation on the port
+ * (e.g. add vlan tag or delete vlan tag)
+ */
+enum spp_port_ability_ope {
+	SPP_PORT_ABILITY_OPE_NONE,        /**< none */
+	SPP_PORT_ABILITY_OPE_ADD_VLANTAG, /**< add VLAN tag */
+	SPP_PORT_ABILITY_OPE_DEL_VLANTAG, /**< delete VLAN tag */
+};
+
+/* getopt_long return value for long option */
+enum SPP_LONGOPT_RETVAL {
+	SPP_LONGOPT_RETVAL__ = 127,
+
+	/*
+	 * Return value definition for getopt_long()
+	 * Only for long option
+	 */
+	SPP_LONGOPT_RETVAL_CLIENT_ID,      /* --client-id       */
+	SPP_LONGOPT_RETVAL_OUTPUT,         /* --output          */
+	SPP_LONGOPT_RETVAL_LIMIT_FILE_SIZE /* --limit_file_size */
+};
+
+/* Interface information structure */
+struct spp_port_index {
+	enum port_type  iface_type; /**< Interface type (phy/ring) */
+	int             iface_no;   /**< Interface number */
+};
+
+/** VLAN tag information */
+struct spp_vlantag_info {
+	int vid; /**< VLAN ID */
+	int pcp; /**< Priority Code Point */
+	int tci; /**< Tag Control Information */
+};
+
+/**
+ * Data for each port ability which indicates vlantag related information
+ * for the port
+ */
+union spp_ability_data {
+	/** VLAN tag information */
+	struct spp_vlantag_info vlantag;
+};
+
+/** Port ability information */
+struct spp_port_ability {
+	enum spp_port_ability_ope ope; /**< Operation */
+	enum spp_port_rxtx rxtx;       /**< rx/tx identifier */
+	union spp_ability_data data;   /**< Port ability data */
+};
+
+/** Port class identifier for classifying */
+struct spp_port_class_identifier {
+	uint64_t mac_addr;                      /**< Mac address (binary) */
+	char     mac_addr_str[SPP_MIN_STR_LEN]; /**< Mac address (text) */
+	struct spp_vlantag_info vlantag;        /**< VLAN tag information */
+};
+
+/* Port info */
+struct spp_port_info {
+	enum port_type iface_type;      /**< Interface type (phy/vhost/ring) */
+	int            iface_no;        /**< Interface number */
+	int            dpdk_port;       /**< DPDK port number */
+	struct spp_port_class_identifier class_id;
+					/**< Port class identifier */
+	struct spp_port_ability ability[SPP_PORT_ABILITY_MAX];
+					/**< Port ability */
+};
+
+/* Component info */
+struct spp_component_info {
+	char name[SPP_NAME_STR_LEN];    /**< Component name */
+	enum spp_component_type type;   /**< Component type */
+	unsigned int lcore_id;          /**< Logical core ID for component */
+	int component_id;               /**< Component ID */
+	int num_rx_port;                /**< The number of rx ports */
+	int num_tx_port;                /**< The number of tx ports */
+	struct spp_port_info *rx_ports[RTE_MAX_ETHPORTS];
+					/**< Array of pointers to rx ports */
+	struct spp_port_info *tx_ports[RTE_MAX_ETHPORTS];
+					/**< Array of pointers to tx ports */
+};
+
+/* Manage given options as global variable */
+struct startup_param {
+	int client_id;		/* Client ID */
+	char server_ip[INET_ADDRSTRLEN];
+				/* IP address stiring of spp-ctl */
+	int server_port;	/* Port Number of spp-ctl */
+};
+
+/* Manage interfaces and port information as global variable */
+struct iface_info {
+	int num_nic;            /* The number of phy */
+	int num_ring;           /* The number of ring */
+	struct spp_port_info nic[RTE_MAX_ETHPORTS];
+				/* Port information of phy */
+	struct spp_port_info ring[RTE_MAX_ETHPORTS];
+				/* Port information of ring */
+};
+
+/* Manage core status and component information as global variable */
+struct core_mng_info {
+	/* Status of cpu core */
+	volatile enum spp_core_status status;
+};
+
+struct spp_iterate_core_params;
+/**
+ * definition of iterated core element procedure function
+ * which is member of spp_iterate_core_params structure.
+ * Above structure is used when listing core information
+ * (e.g) create resonse to status command.
+ */
+typedef int (*spp_iterate_core_element_proc)(
+		struct spp_iterate_core_params *params,
+		const unsigned int lcore_id,
+		const char *name,
+		const char *type,
+		const int num_rx,
+		const struct spp_port_index *rx_ports,
+		const int num_tx,
+		const struct spp_port_index *tx_ports);
+
+/**
+ * iterate core table parameters which is
+ * used when listing core table content
+ * (e.g.) create response to status command.
+ */
+struct spp_iterate_core_params {
+	/** Output buffer */
+	char *output;
+
+	/** The function for creating core information */
+	spp_iterate_core_element_proc element_proc;
+};
+
+/**
+ * added ring_pmd
+ *
+ * @param ring_id
+ *  added ring id.
+ *
+ * @retval 0~   ring_port_id.
+ * @retval -1   failed.
+ */
+int add_ring_pmd(int ring_id);
+
+/**
+ * Get core status
+ *
+ * @param lcore_id
+ *  Logical core ID.
+ *
+ * @return
+ *  Status of specified logical core.
+ */
+enum spp_core_status spp_get_core_status(unsigned int lcore_id);
+
+/**
+ * Run check_core_status() for SPP_CORE_STATUS_CHECK_MAX times with
+ * interval time (1sec)
+ *
+ * @param status
+ *  wait check status.
+ *
+ * @retval 0  succeeded.
+ * @retval -1 failed.
+ */
+int check_core_status_wait(enum spp_core_status status);
+
+/**
+ * Set core status
+ *
+ * @param lcore_id
+ *  Logical core ID.
+ * @param status
+ *  set status.
+ *
+ */
+void set_core_status(unsigned int lcore_id, enum spp_core_status status);
+
+/**
+ * Set all core status to given
+ *
+ * @param status
+ *  set status.
+ *
+ */
+void set_all_core_status(enum spp_core_status status);
+
+/**
+ * Set all of component status to SPP_CORE_STOP_REQUEST if received signal
+ * is SIGTERM or SIGINT
+ *
+ * @param signl
+ *  received signal.
+ *
+ */
+void stop_process(int signal);
+
+/**
+ * Return port info of given type and num of interface
+ *
+ * @param iface_type
+ *  Interface type to be validated.
+ * @param iface_no
+ *  Interface number to be validated.
+ *
+ * @retval !NULL  spp_port_info.
+ * @retval NULL   failed.
+ */
+struct spp_port_info *
+get_iface_info(enum port_type iface_type, int iface_no);
+
+/**
+ * Setup management info for spp_vf
+ */
+int init_mng_data(void);
+
+/**
+ * Get component type of target core
+ *
+ * @param lcore_id
+ *  Logical core ID.
+ *
+ * @return
+ *  Type of component executed on specified logical core
+ */
+enum spp_component_type
+spp_get_component_type(unsigned int lcore_id);
+
+/* Get core information which is in use */
+struct core_info *get_core_info(unsigned int lcore_id);
+
+/**
+ * Port type to string
+ *
+ * @param port
+ *  Character string of Port type to be converted.
+ * @param iface_type
+ *  port interface type
+ * @param iface_no
+ *  interface no
+ *
+ * @retval SPP_RET_OK succeeded.
+ * @retval SPP_RET_NG failed.
+ */
+int
+spp_format_port_string(char *port, enum port_type iface_type, int iface_no);
+
+/**
+ * Port type to string
+ *
+ * @param port
+ *  Character string of Port type to be converted.
+ * @param iface_type
+ *  port interface type
+ * @param iface_no
+ *  interface no
+ *
+ * @retval SPP_RET_OK succeeded.
+ * @retval SPP_RET_NG failed.
+ */
+int
+spp_format_port_string(char *port, enum port_type iface_type, int iface_no);
+
+/**
+ * Set mange data address
+ *
+ * @param startup_param_addr
+ *  g_startup_param address
+ * @param iface_addr
+ *  g_iface_info address
+ * @param core_mng_addr
+ *  g_core_info address
+ * @param capture_request_addr
+ *  g_capture_request address
+ * @param capture_status_addr
+ *  g_capture_status address
+ * @param main_lcore_id
+ *  main_lcore_id mask
+ *
+ * @retval SPP_RET_OK succeeded.
+ * @retval SPP_RET_NG failed.
+ */
+int spp_set_mng_data_addr(struct startup_param *startup_param_addr,
+			  struct iface_info *iface_addr,
+			  struct core_mng_info *core_mng_addr,
+			  int *capture_request_addr,
+			  int *capture_status_addr,
+			  unsigned int main_lcore_id);
+
+/**
+ * Get mange data address
+ *
+ * @param iface_addr
+ *  g_startup_param write address
+ * @param iface_addr
+ *  g_iface_info write address
+ * @param core_mng_addr
+ *  g_core_mng_info write address
+ * @param change_core_addr
+ *  g_capture_request write address
+ * @param change_component_addr
+ *  g_capture_status write address
+ */
+void spp_get_mng_data_addr(struct startup_param **startup_param_addr,
+			   struct iface_info **iface_addr,
+			   struct core_mng_info **core_mng_addr,
+			   int **capture_request_addr,
+			   int **capture_status_addr);
+
+#endif /* _SPP_PROC_H_ */
-- 
2.17.1

  parent reply	other threads:[~2019-02-08  8:46 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20190208084438.7952-1-x-fn-spp@sl.ntt-tx.co.jp>
2019-02-08  8:44 ` [spp] [PATCH v2 1/7] spp_pcap: add command main x-fn-spp
2019-02-08  8:44 ` [spp] [PATCH v2 2/7] spp_pcap: add command decode x-fn-spp
2019-02-08  8:44 ` x-fn-spp [this message]
2019-02-08  8:44 ` [spp] [PATCH v2 4/7] spp_pcap: add spp_pcap main function x-fn-spp
2019-02-08  8:44 ` [spp] [PATCH v2 5/7] spp_pcap: add Makefile for spp_pcap x-fn-spp
2019-02-08  8:44 ` [spp] [PATCH v2 6/7] controller: add SppPcap class x-fn-spp
2019-02-08  8:44 ` [spp] [PATCH v2 7/7] controller: add pcap command to SPP controller x-fn-spp

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=201902080844.x188ic6d030814@imss04.silk.ntt-tx.co.jp \
    --to=x-fn-spp@sl.ntt-tx.co.jp \
    --cc=ferruh.yigit@intel.com \
    --cc=ogawa.yasufumi@lab.ntt.co.jp \
    --cc=spp@dpdk.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).