DPDK-dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: "Matthew G. McGovern" <matthew@mcgov.dev>
To: Aman Singh <aman.deep.singh@intel.com>
Cc: dev@dpdk.org
Subject: [PATCH] testpmd: allow --tx-ip definitions per-port
Date: Mon, 24 Aug 2026 23:18:21 +0000	[thread overview]
Message-ID: <20260824231805.256714-1-matthew@mcgov.dev> (raw)

Modifies --tx-ip flag to be of the form:

--tx-ip=[port_id:]src,dest

to allow setting the addresses for each port.

Signed-off-by: Matthew G. McGovern <matthew@mcgov.dev>
---
 app/test-pmd/parameters.c             | 57 +++++++++++++++++++++------
 app/test-pmd/testpmd.h                |  4 +-
 app/test-pmd/txonly.c                 | 31 +++++++++++----
 doc/guides/testpmd_app_ug/run_app.rst | 10 ++++-
 4 files changed, 80 insertions(+), 22 deletions(-)

diff --git a/app/test-pmd/parameters.c b/app/test-pmd/parameters.c
index 0032ea4e25..833b14eda4 100644
--- a/app/test-pmd/parameters.c
+++ b/app/test-pmd/parameters.c
@@ -504,7 +504,9 @@ usage(char* progname)
 	printf("  --txonly-multi-flow: generate multiple flows in txonly mode\n");
 	printf("  --txonly-nb-flows=N: number of flows per lcore in txonly"
 	       " multi-flow mode (1-64, default 64)\n");
-	printf("  --tx-ip=src,dst: IP addresses in Tx-only mode\n");
+	printf("  --tx-ip=[port:]src,dst: IP addresses in Tx-only mode.\n"
+	       "    Without a port prefix the addresses apply to all ports.\n"
+	       "    May be given several times to configure ports individually.\n");
 	printf("  --tx-udp=src[,dst]: UDP ports in Tx-only mode\n");
 	printf("  --eth-link-speed: force link speed.\n");
 	printf("  --rxq-share: enable Rx queue sharing per switch and Rx domain\n");
@@ -1039,26 +1041,59 @@ launch_args_parse(int argc, char** argv)
 			break;
 		}
 		case TESTPMD_OPT_TX_IP_NUM: {
+			uint32_t src_addr, dst_addr;
+			unsigned long port_num;
+			bool port_given = false;
+			char *addrs = optarg;
 			struct in_addr in;
-			char *end;
+			portid_t port_id = 0;
+			char *sep, *end;
+
+			/* Optional "PORT:" prefix selects a single Tx port. */
+			sep = strchr(addrs, ':');
+			if (sep != NULL) {
+				*sep = '\0';
+				errno = 0;
+				port_num = strtoul(addrs, &end, 0);
+				if (errno != 0 || end == addrs ||
+						*end != '\0' ||
+						port_num >= RTE_MAX_ETHPORTS)
+					rte_exit(EXIT_FAILURE,
+						"Invalid tx-ip port: %s\n",
+						addrs);
+				port_id = (portid_t)port_num;
+				port_given = true;
+				addrs = sep + 1;
+			}
 
-			end = strchr(optarg, ',');
-			if (end == optarg || !end)
+			end = strchr(addrs, ',');
+			if (end == addrs || end == NULL)
 				rte_exit(EXIT_FAILURE,
-					"Invalid tx-ip: %s", optarg);
+					"Invalid tx-ip: %s\n", addrs);
 
-			*end++ = 0;
-			if (inet_pton(AF_INET, optarg, &in) == 0)
+			*end++ = '\0';
+			if (inet_pton(AF_INET, addrs, &in) == 0)
 				rte_exit(EXIT_FAILURE,
 					"Invalid source IP address: %s\n",
-					optarg);
-			tx_ip_src_addr = rte_be_to_cpu_32(in.s_addr);
+					addrs);
+			src_addr = rte_be_to_cpu_32(in.s_addr);
 
 			if (inet_pton(AF_INET, end, &in) == 0)
 				rte_exit(EXIT_FAILURE,
 					"Invalid destination IP address: %s\n",
-					optarg);
-			tx_ip_dst_addr = rte_be_to_cpu_32(in.s_addr);
+					end);
+			dst_addr = rte_be_to_cpu_32(in.s_addr);
+
+			if (port_given) {
+				tx_ip_src_addr[port_id] = src_addr;
+				tx_ip_dst_addr[port_id] = dst_addr;
+			} else {
+				/* No port given: apply to every port. */
+				for (pid = 0; pid < RTE_MAX_ETHPORTS; pid++) {
+					tx_ip_src_addr[pid] = src_addr;
+					tx_ip_dst_addr[pid] = dst_addr;
+				}
+			}
 			break;
 		}
 		case TESTPMD_OPT_TX_UDP_NUM: {
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index 083171853c..71092dea9e 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -691,8 +691,8 @@ extern int8_t tx_wthresh;
 extern uint16_t tx_udp_src_port;
 extern uint16_t tx_udp_dst_port;
 
-extern uint32_t tx_ip_src_addr;
-extern uint32_t tx_ip_dst_addr;
+extern uint32_t tx_ip_src_addr[RTE_MAX_ETHPORTS];
+extern uint32_t tx_ip_dst_addr[RTE_MAX_ETHPORTS];
 
 extern struct fwd_config cur_fwd_config;
 extern struct fwd_engine *cur_fwd_eng;
diff --git a/app/test-pmd/txonly.c b/app/test-pmd/txonly.c
index a4acb85d29..da197720a9 100644
--- a/app/test-pmd/txonly.c
+++ b/app/test-pmd/txonly.c
@@ -50,12 +50,26 @@ uint16_t tx_udp_src_port = 9;
 uint16_t tx_udp_dst_port = 9;
 
 /* use RFC5735 / RFC2544 reserved network test addresses */
-uint32_t tx_ip_src_addr = (198U << 24) | (18 << 16) | (0 << 8) | 1;
-uint32_t tx_ip_dst_addr = (198U << 24) | (18 << 16) | (0 << 8) | 2;
+#define TX_IP_SRC_ADDR_DEF ((198U << 24) | (18 << 16) | (0 << 8) | 1)
+#define TX_IP_DST_ADDR_DEF ((198U << 24) | (18 << 16) | (0 << 8) | 2)
+
+uint32_t tx_ip_src_addr[RTE_MAX_ETHPORTS];
+uint32_t tx_ip_dst_addr[RTE_MAX_ETHPORTS];
+
+RTE_INIT(tx_ip_addr_init)
+{
+	portid_t pid;
+
+	for (pid = 0; pid < RTE_MAX_ETHPORTS; pid++) {
+		tx_ip_src_addr[pid] = TX_IP_SRC_ADDR_DEF;
+		tx_ip_dst_addr[pid] = TX_IP_DST_ADDR_DEF;
+	}
+}
 
 #define IP_DEFTTL  64   /* from RFC 1340. */
 
-static struct rte_ipv4_hdr pkt_ip_hdr; /**< IP header of transmitted packets. */
+/** IP header of transmitted packets, per Tx port. */
+static struct rte_ipv4_hdr pkt_ip_hdr[RTE_MAX_ETHPORTS];
 RTE_DEFINE_PER_LCORE(uint8_t, _src_port_var); /**< Source port variation */
 static struct rte_udp_hdr pkt_udp_hdr; /**< UDP header of tx packets. */
 
@@ -104,7 +118,8 @@ copy_buf_to_pkt(void* buf, unsigned len, struct rte_mbuf *pkt, unsigned offset)
 static void
 setup_pkt_udp_ip_headers(struct rte_ipv4_hdr *ip_hdr,
 			 struct rte_udp_hdr *udp_hdr,
-			 uint16_t pkt_data_len)
+			 uint16_t pkt_data_len,
+			 portid_t port_id)
 {
 	uint16_t pkt_len;
 
@@ -128,8 +143,8 @@ setup_pkt_udp_ip_headers(struct rte_ipv4_hdr *ip_hdr,
 	ip_hdr->next_proto_id = IPPROTO_UDP;
 	ip_hdr->packet_id = 0;
 	ip_hdr->total_length   = RTE_CPU_TO_BE_16(pkt_len);
-	ip_hdr->src_addr = rte_cpu_to_be_32(tx_ip_src_addr);
-	ip_hdr->dst_addr = rte_cpu_to_be_32(tx_ip_dst_addr);
+	ip_hdr->src_addr = rte_cpu_to_be_32(tx_ip_src_addr[port_id]);
+	ip_hdr->dst_addr = rte_cpu_to_be_32(tx_ip_dst_addr[port_id]);
 
 	/*
 	 * Compute IP header checksum.
@@ -208,7 +223,7 @@ pkt_burst_prepare(struct rte_mbuf *pkt, struct rte_mempool *mbp,
 	 * Copy headers in first packet segment(s).
 	 */
 	copy_buf_to_pkt(eth_hdr, sizeof(*eth_hdr), pkt, 0);
-	copy_buf_to_pkt(&pkt_ip_hdr, sizeof(pkt_ip_hdr), pkt,
+	copy_buf_to_pkt(&pkt_ip_hdr[fs->tx_port], sizeof(*pkt_ip_hdr), pkt,
 			sizeof(struct rte_ether_hdr));
 	copy_buf_to_pkt(&pkt_udp_hdr, sizeof(pkt_udp_hdr), pkt,
 			sizeof(struct rte_ether_hdr) +
@@ -416,7 +431,7 @@ tx_only_begin(portid_t pi)
 		return -EINVAL;
 	}
 
-	setup_pkt_udp_ip_headers(&pkt_ip_hdr, &pkt_udp_hdr, pkt_data_len);
+	setup_pkt_udp_ip_headers(&pkt_ip_hdr[pi], &pkt_udp_hdr, pkt_data_len, pi);
 
 	timestamp_enable = false;
 	timestamp_mask = 0;
diff --git a/doc/guides/testpmd_app_ug/run_app.rst b/doc/guides/testpmd_app_ug/run_app.rst
index 52699efa78..bcfbf33f92 100644
--- a/doc/guides/testpmd_app_ug/run_app.rst
+++ b/doc/guides/testpmd_app_ug/run_app.rst
@@ -155,13 +155,21 @@ The command line options are:
     Set the MAC address ``XX:XX:XX:XX:XX:XX`` of the peer port N,
     where 0 <= N < ``RTE_MAX_ETHPORTS``.
 
-*   ``--tx-ip=SRC,DST``
+*   ``--tx-ip=[N:]SRC,DST``
 
     Set the source and destination IP address used when doing transmit only test.
     The defaults address values are source 198.18.0.1 and
     destination 198.18.0.2. These are special purpose addresses
     reserved for benchmarking (RFC 5735).
 
+    Without the optional port prefix, the addresses apply to all ports.
+    With the prefix ``N:``, where 0 <= N < ``RTE_MAX_ETHPORTS``,
+    the addresses apply only to port N.
+    The option may be given several times to configure ports individually,
+    and later options override earlier ones::
+
+       --tx-ip=198.18.0.1,198.18.0.2 --tx-ip=1:10.1.0.3,10.1.0.4
+
 *   ``--tx-udp=SRC[,DST]``
 
     Set the source and destination UDP port number for transmit test only test.
-- 
2.55.0



             reply	other threads:[~2026-08-24 23:18 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-24 23:18 Matthew G. McGovern [this message]
2026-08-25 14:13 ` [PATCH] testpmd: allow --tx-ip definitions per-port Stephen Hemminger

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=20260824231805.256714-1-matthew@mcgov.dev \
    --to=matthew@mcgov.dev \
    --cc=aman.deep.singh@intel.com \
    --cc=dev@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