patch 'net/tap: fix build with LTO' has been queued to stable release 24.11.4

Kevin Traynor ktraynor at redhat.com
Fri Oct 31 15:33:40 CET 2025


Hi,

FYI, your patch has been queued to stable release 24.11.4

Note it hasn't been pushed to http://dpdk.org/browse/dpdk-stable yet.
It will be pushed if I get no objections before 11/05/25. So please
shout if anyone has objections.

Also note that after the patch there's a diff of the upstream commit vs the
patch applied to the branch. This will indicate if there was any rebasing
needed to apply to the stable branch. If there were code changes for rebasing
(ie: not only metadata diffs), please double check that the rebase was
correctly done.

Queued patches are on a temporary branch at:
https://github.com/kevintraynor/dpdk-stable

This queued commit can be viewed at:
https://github.com/kevintraynor/dpdk-stable/commit/47c59eea7dff208663f62c9bd4d7f3a68f7c074c

Thanks.

Kevin

---
>From 47c59eea7dff208663f62c9bd4d7f3a68f7c074c Mon Sep 17 00:00:00 2001
From: David Marchand <david.marchand at redhat.com>
Date: Mon, 22 Sep 2025 09:30:43 +0200
Subject: [PATCH] net/tap: fix build with LTO

[ upstream commit adb95cc6644103d055609f5bcae5df91afea02ab ]

The compiler has trouble understanding that the code is actually pointing
at the data in the message past the nh struct.

Update the tap_nlattr_add* helpers and the NLMSG_TAIL macro passing a
pointer to msg.

Bugzilla ID: 1511
Fixes: 7c25284e30c2 ("net/tap: add netlink back-end for flow API")

Signed-off-by: David Marchand <david.marchand at redhat.com>
Acked-by: Stephen Hemminger <stephen at networkplumber.org>
---
 drivers/net/tap/tap_flow.c    | 117 +++++++++++++---------------------
 drivers/net/tap/tap_netlink.c |  24 +++----
 drivers/net/tap/tap_netlink.h |  10 +--
 drivers/net/tap/tap_tcmsgs.c  |   6 +-
 4 files changed, 65 insertions(+), 92 deletions(-)

diff --git a/drivers/net/tap/tap_flow.c b/drivers/net/tap/tap_flow.c
index c0e44bb1a7..55fb39fc7d 100644
--- a/drivers/net/tap/tap_flow.c
+++ b/drivers/net/tap/tap_flow.c
@@ -431,18 +431,14 @@ tap_flow_create_eth(const struct rte_flow_item *item, struct convert_data *info)
 	msg = &flow->msg;
 	if (!rte_is_zero_ether_addr(&mask->hdr.dst_addr)) {
-		tap_nlattr_add(&msg->nh, TCA_FLOWER_KEY_ETH_DST,
-			RTE_ETHER_ADDR_LEN,
-			   &spec->hdr.dst_addr.addr_bytes);
-		tap_nlattr_add(&msg->nh,
-			   TCA_FLOWER_KEY_ETH_DST_MASK, RTE_ETHER_ADDR_LEN,
-			   &mask->hdr.dst_addr.addr_bytes);
+		tap_nlattr_add(msg, TCA_FLOWER_KEY_ETH_DST, RTE_ETHER_ADDR_LEN,
+			&spec->hdr.dst_addr.addr_bytes);
+		tap_nlattr_add(msg, TCA_FLOWER_KEY_ETH_DST_MASK, RTE_ETHER_ADDR_LEN,
+			&mask->hdr.dst_addr.addr_bytes);
 	}
 	if (!rte_is_zero_ether_addr(&mask->hdr.src_addr)) {
-		tap_nlattr_add(&msg->nh, TCA_FLOWER_KEY_ETH_SRC,
-			RTE_ETHER_ADDR_LEN,
+		tap_nlattr_add(msg, TCA_FLOWER_KEY_ETH_SRC, RTE_ETHER_ADDR_LEN,
 			&spec->hdr.src_addr.addr_bytes);
-		tap_nlattr_add(&msg->nh,
-			   TCA_FLOWER_KEY_ETH_SRC_MASK, RTE_ETHER_ADDR_LEN,
-			   &mask->hdr.src_addr.addr_bytes);
+		tap_nlattr_add(msg, TCA_FLOWER_KEY_ETH_SRC_MASK, RTE_ETHER_ADDR_LEN,
+			&mask->hdr.src_addr.addr_bytes);
 	}
 	return 0;
@@ -499,9 +495,7 @@ tap_flow_create_vlan(const struct rte_flow_item *item, struct convert_data *info
 
 		if (prio)
-			tap_nlattr_add8(&msg->nh,
-					TCA_FLOWER_KEY_VLAN_PRIO, prio);
+			tap_nlattr_add8(msg, TCA_FLOWER_KEY_VLAN_PRIO, prio);
 		if (vid)
-			tap_nlattr_add16(&msg->nh,
-					 TCA_FLOWER_KEY_VLAN_ID, vid);
+			tap_nlattr_add16(msg, TCA_FLOWER_KEY_VLAN_ID, vid);
 	}
 	return 0;
@@ -545,18 +539,13 @@ tap_flow_create_ipv4(const struct rte_flow_item *item, struct convert_data *info
 		return 0;
 	if (mask->hdr.dst_addr) {
-		tap_nlattr_add32(&msg->nh, TCA_FLOWER_KEY_IPV4_DST,
-			     spec->hdr.dst_addr);
-		tap_nlattr_add32(&msg->nh, TCA_FLOWER_KEY_IPV4_DST_MASK,
-			     mask->hdr.dst_addr);
+		tap_nlattr_add32(msg, TCA_FLOWER_KEY_IPV4_DST, spec->hdr.dst_addr);
+		tap_nlattr_add32(msg, TCA_FLOWER_KEY_IPV4_DST_MASK, mask->hdr.dst_addr);
 	}
 	if (mask->hdr.src_addr) {
-		tap_nlattr_add32(&msg->nh, TCA_FLOWER_KEY_IPV4_SRC,
-			     spec->hdr.src_addr);
-		tap_nlattr_add32(&msg->nh, TCA_FLOWER_KEY_IPV4_SRC_MASK,
-			     mask->hdr.src_addr);
+		tap_nlattr_add32(msg, TCA_FLOWER_KEY_IPV4_SRC, spec->hdr.src_addr);
+		tap_nlattr_add32(msg, TCA_FLOWER_KEY_IPV4_SRC_MASK, mask->hdr.src_addr);
 	}
 	if (spec->hdr.next_proto_id)
-		tap_nlattr_add8(&msg->nh, TCA_FLOWER_KEY_IP_PROTO,
-			    spec->hdr.next_proto_id);
+		tap_nlattr_add8(msg, TCA_FLOWER_KEY_IP_PROTO, spec->hdr.next_proto_id);
 	return 0;
 }
@@ -600,18 +589,17 @@ tap_flow_create_ipv6(const struct rte_flow_item *item, struct convert_data *info
 		return 0;
 	if (memcmp(&mask->hdr.dst_addr, empty_addr, 16)) {
-		tap_nlattr_add(&msg->nh, TCA_FLOWER_KEY_IPV6_DST,
-			   sizeof(spec->hdr.dst_addr), &spec->hdr.dst_addr);
-		tap_nlattr_add(&msg->nh, TCA_FLOWER_KEY_IPV6_DST_MASK,
-			   sizeof(mask->hdr.dst_addr), &mask->hdr.dst_addr);
+		tap_nlattr_add(msg, TCA_FLOWER_KEY_IPV6_DST, sizeof(spec->hdr.dst_addr),
+			&spec->hdr.dst_addr);
+		tap_nlattr_add(msg, TCA_FLOWER_KEY_IPV6_DST_MASK, sizeof(mask->hdr.dst_addr),
+			&mask->hdr.dst_addr);
 	}
 	if (memcmp(&mask->hdr.src_addr, empty_addr, 16)) {
-		tap_nlattr_add(&msg->nh, TCA_FLOWER_KEY_IPV6_SRC,
-			   sizeof(spec->hdr.src_addr), &spec->hdr.src_addr);
-		tap_nlattr_add(&msg->nh, TCA_FLOWER_KEY_IPV6_SRC_MASK,
-			   sizeof(mask->hdr.src_addr), &mask->hdr.src_addr);
+		tap_nlattr_add(msg, TCA_FLOWER_KEY_IPV6_SRC, sizeof(spec->hdr.src_addr),
+			&spec->hdr.src_addr);
+		tap_nlattr_add(msg, TCA_FLOWER_KEY_IPV6_SRC_MASK, sizeof(mask->hdr.src_addr),
+			&mask->hdr.src_addr);
 	}
 	if (spec->hdr.proto)
-		tap_nlattr_add8(&msg->nh,
-				TCA_FLOWER_KEY_IP_PROTO, spec->hdr.proto);
+		tap_nlattr_add8(msg, TCA_FLOWER_KEY_IP_PROTO, spec->hdr.proto);
 	return 0;
 }
@@ -650,13 +638,11 @@ tap_flow_create_udp(const struct rte_flow_item *item, struct convert_data *info)
 		return 0;
 	msg = &flow->msg;
-	tap_nlattr_add8(&msg->nh, TCA_FLOWER_KEY_IP_PROTO, IPPROTO_UDP);
+	tap_nlattr_add8(msg, TCA_FLOWER_KEY_IP_PROTO, IPPROTO_UDP);
 	if (!spec)
 		return 0;
 	if (mask->hdr.dst_port)
-		tap_nlattr_add16(&msg->nh, TCA_FLOWER_KEY_UDP_DST,
-			     spec->hdr.dst_port);
+		tap_nlattr_add16(msg, TCA_FLOWER_KEY_UDP_DST, spec->hdr.dst_port);
 	if (mask->hdr.src_port)
-		tap_nlattr_add16(&msg->nh, TCA_FLOWER_KEY_UDP_SRC,
-			     spec->hdr.src_port);
+		tap_nlattr_add16(msg, TCA_FLOWER_KEY_UDP_SRC, spec->hdr.src_port);
 	return 0;
 }
@@ -695,13 +681,11 @@ tap_flow_create_tcp(const struct rte_flow_item *item, struct convert_data *info)
 		return 0;
 	msg = &flow->msg;
-	tap_nlattr_add8(&msg->nh, TCA_FLOWER_KEY_IP_PROTO, IPPROTO_TCP);
+	tap_nlattr_add8(msg, TCA_FLOWER_KEY_IP_PROTO, IPPROTO_TCP);
 	if (!spec)
 		return 0;
 	if (mask->hdr.dst_port)
-		tap_nlattr_add16(&msg->nh, TCA_FLOWER_KEY_TCP_DST,
-			     spec->hdr.dst_port);
+		tap_nlattr_add16(msg, TCA_FLOWER_KEY_TCP_DST, spec->hdr.dst_port);
 	if (mask->hdr.src_port)
-		tap_nlattr_add16(&msg->nh, TCA_FLOWER_KEY_TCP_SRC,
-			     spec->hdr.src_port);
+		tap_nlattr_add16(msg, TCA_FLOWER_KEY_TCP_SRC, spec->hdr.src_port);
 	return 0;
 }
@@ -811,11 +795,9 @@ add_action(struct rte_flow *flow, size_t *act_index, struct action_data *adata)
 		return -1;
 
-	tap_nlattr_add(&msg->nh, TCA_ACT_KIND,
-				strlen(adata->id) + 1, adata->id);
+	tap_nlattr_add(msg, TCA_ACT_KIND, strlen(adata->id) + 1, adata->id);
 	if (tap_nlattr_nested_start(msg, TCA_ACT_OPTIONS) < 0)
 		return -1;
 	if (strcmp("gact", adata->id) == 0) {
-		tap_nlattr_add(&msg->nh, TCA_GACT_PARMS, sizeof(adata->gact),
-			   &adata->gact);
+		tap_nlattr_add(msg, TCA_GACT_PARMS, sizeof(adata->gact), &adata->gact);
 	} else if (strcmp("mirred", adata->id) == 0) {
 		if (adata->mirred.eaction == TCA_EGRESS_MIRROR)
@@ -823,23 +805,18 @@ add_action(struct rte_flow *flow, size_t *act_index, struct action_data *adata)
 		else /* REDIRECT */
 			adata->mirred.action = TC_ACT_STOLEN;
-		tap_nlattr_add(&msg->nh, TCA_MIRRED_PARMS,
-			   sizeof(adata->mirred),
-			   &adata->mirred);
+		tap_nlattr_add(msg, TCA_MIRRED_PARMS, sizeof(adata->mirred), &adata->mirred);
 	} else if (strcmp("skbedit", adata->id) == 0) {
-		tap_nlattr_add(&msg->nh, TCA_SKBEDIT_PARMS,
-			   sizeof(adata->skbedit.skbedit), &adata->skbedit.skbedit);
+		tap_nlattr_add(msg, TCA_SKBEDIT_PARMS, sizeof(adata->skbedit.skbedit),
+			&adata->skbedit.skbedit);
 		if (adata->skbedit.mark)
-			tap_nlattr_add32(&msg->nh, TCA_SKBEDIT_MARK, adata->skbedit.mark);
+			tap_nlattr_add32(msg, TCA_SKBEDIT_MARK, adata->skbedit.mark);
 		else
-			tap_nlattr_add16(&msg->nh, TCA_SKBEDIT_QUEUE_MAPPING, adata->skbedit.queue);
+			tap_nlattr_add16(msg, TCA_SKBEDIT_QUEUE_MAPPING, adata->skbedit.queue);
 	} else if (strcmp("bpf", adata->id) == 0) {
 #ifdef HAVE_BPF_RSS
-		tap_nlattr_add32(&msg->nh, TCA_ACT_BPF_FD, adata->bpf.bpf_fd);
-		tap_nlattr_add(&msg->nh, TCA_ACT_BPF_NAME,
-			   strlen(adata->bpf.annotation) + 1,
-			   adata->bpf.annotation);
-		tap_nlattr_add(&msg->nh, TCA_ACT_BPF_PARMS,
-			   sizeof(adata->bpf.bpf),
-			   &adata->bpf.bpf);
+		tap_nlattr_add32(msg, TCA_ACT_BPF_FD, adata->bpf.bpf_fd);
+		tap_nlattr_add(msg, TCA_ACT_BPF_NAME, strlen(adata->bpf.annotation) + 1,
+			adata->bpf.annotation);
+		tap_nlattr_add(msg, TCA_ACT_BPF_PARMS, sizeof(adata->bpf.bpf), &adata->bpf.bpf);
 #else
 		TAP_LOG(ERR, "Internal error: bpf requested but not supported");
@@ -976,5 +953,5 @@ priv_flow_process(struct pmd_internals *pmd,
 		}
 		/* use flower filter type */
-		tap_nlattr_add(&flow->msg.nh, TCA_KIND, sizeof("flower"), "flower");
+		tap_nlattr_add(&flow->msg, TCA_KIND, sizeof("flower"), "flower");
 		if (tap_nlattr_nested_start(&flow->msg, TCA_OPTIONS) < 0) {
 			rte_flow_error_set(error, ENOMEM, RTE_FLOW_ERROR_TYPE_ACTION,
@@ -1016,13 +993,9 @@ priv_flow_process(struct pmd_internals *pmd,
 	if (flow) {
 		if (data.vlan) {
-			tap_nlattr_add16(&flow->msg.nh, TCA_FLOWER_KEY_ETH_TYPE,
-				     htons(ETH_P_8021Q));
-			tap_nlattr_add16(&flow->msg.nh,
-				     TCA_FLOWER_KEY_VLAN_ETH_TYPE,
-				     data.eth_type ?
-				     data.eth_type : htons(ETH_P_ALL));
+			tap_nlattr_add16(&flow->msg, TCA_FLOWER_KEY_ETH_TYPE, htons(ETH_P_8021Q));
+			tap_nlattr_add16(&flow->msg, TCA_FLOWER_KEY_VLAN_ETH_TYPE,
+				data.eth_type ?  data.eth_type : htons(ETH_P_ALL));
 		} else if (data.eth_type) {
-			tap_nlattr_add16(&flow->msg.nh, TCA_FLOWER_KEY_ETH_TYPE,
-				     data.eth_type);
+			tap_nlattr_add16(&flow->msg, TCA_FLOWER_KEY_ETH_TYPE, data.eth_type);
 		}
 	}
diff --git a/drivers/net/tap/tap_netlink.c b/drivers/net/tap/tap_netlink.c
index 8a57c9242c..5ff60f41d4 100644
--- a/drivers/net/tap/tap_netlink.c
+++ b/drivers/net/tap/tap_netlink.c
@@ -294,5 +294,5 @@ retry:
  */
 void
-tap_nlattr_add(struct nlmsghdr *nh, unsigned short type,
+tap_nlattr_add(struct tap_nlmsg *msg, unsigned short type,
 	   unsigned int data_len, const void *data)
 {
@@ -300,10 +300,10 @@ tap_nlattr_add(struct nlmsghdr *nh, unsigned short type,
 	struct rtattr *rta;
 
-	rta = (struct rtattr *)NLMSG_TAIL(nh);
+	rta = (struct rtattr *)NLMSG_TAIL(msg);
 	rta->rta_len = RTA_LENGTH(data_len);
 	rta->rta_type = type;
 	if (data_len > 0)
 		memcpy(RTA_DATA(rta), data, data_len);
-	nh->nlmsg_len = NLMSG_ALIGN(nh->nlmsg_len) + RTA_ALIGN(rta->rta_len);
+	msg->nh.nlmsg_len = NLMSG_ALIGN(msg->nh.nlmsg_len) + RTA_ALIGN(rta->rta_len);
 }
 
@@ -319,7 +319,7 @@ tap_nlattr_add(struct nlmsghdr *nh, unsigned short type,
  */
 void
-tap_nlattr_add8(struct nlmsghdr *nh, unsigned short type, uint8_t data)
+tap_nlattr_add8(struct tap_nlmsg *msg, unsigned short type, uint8_t data)
 {
-	tap_nlattr_add(nh, type, sizeof(uint8_t), &data);
+	tap_nlattr_add(msg, type, sizeof(uint8_t), &data);
 }
 
@@ -335,7 +335,7 @@ tap_nlattr_add8(struct nlmsghdr *nh, unsigned short type, uint8_t data)
  */
 void
-tap_nlattr_add16(struct nlmsghdr *nh, unsigned short type, uint16_t data)
+tap_nlattr_add16(struct tap_nlmsg *msg, unsigned short type, uint16_t data)
 {
-	tap_nlattr_add(nh, type, sizeof(uint16_t), &data);
+	tap_nlattr_add(msg, type, sizeof(uint16_t), &data);
 }
 
@@ -351,7 +351,7 @@ tap_nlattr_add16(struct nlmsghdr *nh, unsigned short type, uint16_t data)
  */
 void
-tap_nlattr_add32(struct nlmsghdr *nh, unsigned short type, uint32_t data)
+tap_nlattr_add32(struct tap_nlmsg *msg, unsigned short type, uint32_t data)
 {
-	tap_nlattr_add(nh, type, sizeof(uint32_t), &data);
+	tap_nlattr_add(msg, type, sizeof(uint32_t), &data);
 }
 
@@ -380,7 +380,7 @@ tap_nlattr_nested_start(struct tap_nlmsg *msg, uint16_t type)
 	}
 
-	tail->tail = (struct rtattr *)NLMSG_TAIL(&msg->nh);
+	tail->tail = (struct rtattr *)NLMSG_TAIL(msg);
 
-	tap_nlattr_add(&msg->nh, type, 0, NULL);
+	tap_nlattr_add(msg, type, 0, NULL);
 
 	tail->prev = msg->nested_tails;
@@ -405,5 +405,5 @@ tap_nlattr_nested_finish(struct tap_nlmsg *msg)
 	struct nested_tail *tail = msg->nested_tails;
 
-	tail->tail->rta_len = (char *)NLMSG_TAIL(&msg->nh) - (char *)tail->tail;
+	tail->tail->rta_len = (char *)NLMSG_TAIL(msg) - (char *)tail->tail;
 
 	if (tail->prev)
diff --git a/drivers/net/tap/tap_netlink.h b/drivers/net/tap/tap_netlink.h
index 466c47a6d7..5eff6edbb1 100644
--- a/drivers/net/tap/tap_netlink.h
+++ b/drivers/net/tap/tap_netlink.h
@@ -24,5 +24,5 @@ struct tap_nlmsg {
 };
 
-#define NLMSG_TAIL(nlh) (void *)((char *)(nlh) + NLMSG_ALIGN((nlh)->nlmsg_len))
+#define NLMSG_TAIL(msg) (void *)((char *)(msg) + NLMSG_ALIGN((msg)->nh.nlmsg_len))
 
 int tap_nl_init(uint32_t nl_groups);
@@ -32,9 +32,9 @@ int tap_nl_recv(int nlsk_fd, int (*callback)(struct nlmsghdr *, void *),
 		void *arg);
 int tap_nl_recv_ack(int nlsk_fd);
-void tap_nlattr_add(struct nlmsghdr *nh, unsigned short type,
+void tap_nlattr_add(struct tap_nlmsg *msg, unsigned short type,
 		    unsigned int data_len, const void *data);
-void tap_nlattr_add8(struct nlmsghdr *nh, unsigned short type, uint8_t data);
-void tap_nlattr_add16(struct nlmsghdr *nh, unsigned short type, uint16_t data);
-void tap_nlattr_add32(struct nlmsghdr *nh, unsigned short type, uint32_t data);
+void tap_nlattr_add8(struct tap_nlmsg *msg, unsigned short type, uint8_t data);
+void tap_nlattr_add16(struct tap_nlmsg *msg, unsigned short type, uint16_t data);
+void tap_nlattr_add32(struct tap_nlmsg *msg, unsigned short type, uint32_t data);
 int tap_nlattr_nested_start(struct tap_nlmsg *msg, uint16_t type);
 void tap_nlattr_nested_finish(struct tap_nlmsg *msg);
diff --git a/drivers/net/tap/tap_tcmsgs.c b/drivers/net/tap/tap_tcmsgs.c
index caca9445c8..c32f0ff815 100644
--- a/drivers/net/tap/tap_tcmsgs.c
+++ b/drivers/net/tap/tap_tcmsgs.c
@@ -124,6 +124,6 @@ qdisc_add_multiq(int nlsk_fd, unsigned int ifindex)
 	msg.t.tcm_handle = TC_H_MAKE(MULTIQ_MAJOR_HANDLE, 0);
 	msg.t.tcm_parent = TC_H_ROOT;
-	tap_nlattr_add(&msg.nh, TCA_KIND, sizeof("multiq"), "multiq");
-	tap_nlattr_add(&msg.nh, TCA_OPTIONS, sizeof(opt), &opt);
+	tap_nlattr_add(&msg, TCA_KIND, sizeof("multiq"), "multiq");
+	tap_nlattr_add(&msg, TCA_OPTIONS, sizeof(opt), &opt);
 	if (tap_nl_send(nlsk_fd, &msg.nh) < 0)
 		return -1;
@@ -153,5 +153,5 @@ qdisc_add_ingress(int nlsk_fd, unsigned int ifindex)
 	msg.t.tcm_handle = TC_H_MAKE(TC_H_INGRESS, 0);
 	msg.t.tcm_parent = TC_H_INGRESS;
-	tap_nlattr_add(&msg.nh, TCA_KIND, sizeof("ingress"), "ingress");
+	tap_nlattr_add(&msg, TCA_KIND, sizeof("ingress"), "ingress");
 	if (tap_nl_send(nlsk_fd, &msg.nh) < 0)
 		return -1;
-- 
2.51.0

---
  Diff of the applied patch vs upstream commit (please double-check if non-empty:
---
--- -	2025-10-31 13:53:55.220637250 +0000
+++ 0098-net-tap-fix-build-with-LTO.patch	2025-10-31 13:53:52.275524114 +0000
@@ -1 +1 @@
-From adb95cc6644103d055609f5bcae5df91afea02ab Mon Sep 17 00:00:00 2001
+From 47c59eea7dff208663f62c9bd4d7f3a68f7c074c Mon Sep 17 00:00:00 2001
@@ -5,0 +6,2 @@
+[ upstream commit adb95cc6644103d055609f5bcae5df91afea02ab ]
+
@@ -14 +15,0 @@
-Cc: stable at dpdk.org
@@ -26 +27 @@
-index 373b773e2d..9d4ef27a8a 100644
+index c0e44bb1a7..55fb39fc7d 100644



More information about the stable mailing list