From: Sven Eckelmann 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 With the current callers, the old implementation is not triggering any unexpected behavior. The behavior is only adjusted for new code which might need more reliable return values. Signed-off-by: Sven Eckelmann Signed-off-by: Simon Wunderlich --- net/batman-adv/routing.c | 4 +++- net/batman-adv/tvlv.c | 22 ++++++++++++++-------- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c index bbd40fe3a8e59..a9d657f2a831a 100644 --- a/net/batman-adv/routing.c +++ b/net/batman-adv/routing.c @@ -1334,7 +1334,9 @@ 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_DROP if the skb is not consumed, NET_RX_SUCCESS otherwise. + * Return: NET_RX_SUCCESS if the skb was locally received, NET_RX_DROP otherwise + * 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 49bf2ed9ecdc3..cc14a76582b5a 100644 --- a/net/batman-adv/tvlv.c +++ b/net/batman-adv/tvlv.c @@ -383,8 +383,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, @@ -524,8 +525,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, @@ -540,6 +542,7 @@ int batadv_tvlv_containers_process(struct batadv_priv *bat_priv, u16 tvlv_value_cont_len; u8 cifnotfound = BATADV_TVLV_HANDLER_OGM_CIFNOTFND; int ret = NET_RX_SUCCESS; + int res; while ((tvlv_hdr = batadv_tvlv_hdr_next(&tvlv_value, &tvlv_value_len))) { tvlv_value_cont_len = ntohs(tvlv_hdr->len); @@ -548,10 +551,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); } -- 2.47.3