[PATCH batadv] batman-adv: tvlv: handle negative tvlv processing return codes

Sven Eckelmann <[email protected]> Thu, 30 Jul 2026 10:57:53 +0200
Newsgroups org.open-mesh.lists.batman
Message-ID <[email protected]>
batadv_tvlv_containers_process() was implemented with only two return codes
from the handlers in mind:

* NET_RX_SUCCESS (0)
* NET_RX_DROP (1)

The multicast handlers broke this convention and are also returning
negative return codes. But the processing code was never updated to
correctly aggregate them.

To handle negative return codes for non-OGM(2) handlers, they are now
aggregated to:

* NET_RX_SUCCESS when no handlers returned a different return code
* the last negative return code when at least one handler returned a
  negative return code
* NET_RX_DROP otherwise

Fixes: 8ed36122d709 ("batman-adv: mcast: implement multicast packet reception and forwarding")
Signed-off-by: Sven Eckelmann <[email protected]>
---
 net/batman-adv/routing.c |  3 ++-
 net/batman-adv/tvlv.c    | 22 ++++++++++++++--------
 2 files changed, 16 insertions(+), 9 deletions(-)

diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c
index 15ef47d3..3996ffd1 100644
--- a/net/batman-adv/routing.c
+++ b/net/batman-adv/routing.c
@@ -1385,7 +1385,8 @@ int batadv_recv_bcast_packet(struct sk_buff *skb,
  * contents of its TVLV forwards it and/or decapsulates it to hand it to the
  * mesh interface.
  *
- * Return: NET_RX_SUCCESS on success or NET_RX_DROP in case of failure
+ * Return: NET_RX_SUCCESS on success, NET_RX_DROP in case of failure or a
+ * negative errno code when the multicast tracker TVLV could not be processed
  */
 int batadv_recv_mcast_packet(struct sk_buff *skb,
 			     struct batadv_hard_iface *recv_if)
diff --git a/net/batman-adv/tvlv.c b/net/batman-adv/tvlv.c
index 5600aaf0..de907c07 100644
--- a/net/batman-adv/tvlv.c
+++ b/net/batman-adv/tvlv.c
@@ -386,8 +386,9 @@ int batadv_tvlv_container_ogm_append(struct batadv_priv *bat_priv,
  * @tvlv_value: tvlv content
  * @tvlv_value_len: tvlv content length
  *
- * Return: success if the handler was not found or the return value of the
- * handler callback.
+ * Return: NET_RX_SUCCESS if the handler was not found or the return value of
+ * the handler callback. The latter is NET_RX_SUCCESS or NET_RX_DROP for the
+ * unicast handler and additionally a negative errno code for the mcast handler.
  */
 static int batadv_tvlv_call_handler(struct batadv_priv *bat_priv,
 				    struct batadv_tvlv_handler *tvlv_handler,
@@ -528,8 +529,9 @@ static bool batadv_tvlv_containers_contain(void *tvlv_value,
  * @tvlv_value: tvlv content
  * @tvlv_value_len: tvlv content length
  *
- * Return: success when processing an OGM or the return value of all called
- * handler callbacks.
+ * Return: NET_RX_SUCCESS when processing an OGM or the combined return value of
+ * all called handler callbacks. The latter is NET_RX_SUCCESS, NET_RX_DROP or,
+ * for BATADV_MCAST packets, a negative errno code.
  */
 int batadv_tvlv_containers_process(struct batadv_priv *bat_priv,
 				   u8 packet_type,
@@ -544,6 +546,7 @@ int batadv_tvlv_containers_process(struct batadv_priv *bat_priv,
 	struct batadv_tvlv_hdr *tvlv_hdr;
 	int ret = NET_RX_SUCCESS;
 	u16 tvlv_value_cont_len;
+	int res;
 
 	while ((tvlv_hdr = batadv_tvlv_hdr_next(&tvlv_value, &tvlv_value_len))) {
 		tvlv_value_cont_len = ntohs(tvlv_hdr->len);
@@ -552,10 +555,13 @@ int batadv_tvlv_containers_process(struct batadv_priv *bat_priv,
 						       tvlv_hdr->type,
 						       tvlv_hdr->version);
 
-		ret |= batadv_tvlv_call_handler(bat_priv, tvlv_handler,
-						packet_type, orig_node, skb,
-						tvlv_hdr + 1,
-						tvlv_value_cont_len);
+		res = batadv_tvlv_call_handler(bat_priv, tvlv_handler,
+					       packet_type, orig_node, skb,
+					       tvlv_hdr + 1,
+					       tvlv_value_cont_len);
+		if (ret == NET_RX_SUCCESS || res < 0)
+			ret = res;
+
 		batadv_tvlv_handler_put(tvlv_handler);
 	}
 

---
base-commit: 95b6f66b2659f617ce1937e790f48dc578ee014c
change-id: 20260730-tvlv-negative-return-a66346d97fc1

Best regards,
--  
Sven Eckelmann <[email protected]>