Project

General

Profile

Actions

Bug #464

open

bat_v: batadv_v_neigh_is_sob is not searching for the best neighbor

Added by Sven Eckelmann about 1 month ago. Updated 13 days ago.

Status:
In Progress
Priority:
Normal
Target version:
Start date:
08/06/2026
Due date:
% Done:

0%

Estimated time:

Description

Since the original commit b05bbab5e1fc ("batman-adv: B.A.T.M.A.N. V - implement neighbor comparison API calls") from @Antonio Quartulli, the code in batadv_v_neigh_is_sob is searching for the lowest throughput in the neighbor+outif combination:

static bool batadv_v_neigh_is_sob(struct batadv_neigh_node *neigh1,
                                  struct batadv_hard_iface *if_outgoing1,
                                  struct batadv_neigh_node *neigh2,
                                  struct batadv_hard_iface *if_outgoing2)
{
        struct batadv_neigh_ifinfo *ifinfo1, *ifinfo2;
        u32 threshold;

        ifinfo1 = batadv_neigh_ifinfo_get(neigh1, if_outgoing1);
        ifinfo2 = batadv_neigh_ifinfo_get(neigh2, if_outgoing2);

        threshold = ifinfo1->bat_v.throughput / 4;
        threshold = ifinfo1->bat_v.throughput - threshold;

        return ifinfo2->bat_v.throughput > threshold;
}

# comparison is basically: reference > (3./4. * candidate)

It returns always true when neigh2 (the reference) has a better throughput than 3/4 of the neigh1 (candidate) throughput.

This is rather odd because the B.A.T.M.A.N. IV metric checks for the if the neigh1 (candidate) has a better metric than neigh2 (the reference):

static bool
batadv_iv_ogm_neigh_is_sob(struct batadv_neigh_node *candidate,
               struct batadv_hard_iface *if_outgoing_cand,
               struct batadv_neigh_node *reference,
               struct batadv_hard_iface *if_outgoing_ref)
{
    bool ret;
    int diff;

    ret = batadv_iv_ogm_neigh_diff(candidate, if_outgoing_cand,
                       reference, if_outgoing_ref,
                       &diff);
    if (!ret)
        return false;

    ret = diff > -BATADV_TQ_SIMILARITY_THRESHOLD;
    return ret;
}

# comparison is basically: candidate >  (reference - BATADV_TQ_SIMILARITY_THRESHOLD);

This doesn't make a lot of sense in my opinion. Because batadv_find_router is now searching for especially slow candidates for bonding instead of fast candidates:

struct batadv_neigh_node *
batadv_find_router(struct batadv_priv *bat_priv,
           struct batadv_orig_node *orig_node,
           struct batadv_hard_iface *recv_if)
{
[...]
    /* only consider bonding for recv_if == BATADV_IF_DEFAULT (first hop)
     * and if activated.
     */
    if (!(recv_if == BATADV_IF_DEFAULT && READ_ONCE(bat_priv->bonding)))
        return router;

[...]
    hlist_for_each_entry_rcu(cand, &orig_node->ifinfo_list, list) {
        /* acquire some structures and references ... */
        if (!kref_get_unless_zero(&cand->refcount))
            continue;
[...]
        /* alternative candidate should be good enough to be
         * considered
         */
        if (!bao->neigh.is_similar_or_better(cand_router,
                             cand->if_outgoing, router,
                             recv_if))
            goto next;

[...]
}
Actions #1

Updated by Sven Eckelmann about 1 month ago

  • Status changed from New to In Progress
Actions #2

Updated by Sven Eckelmann 13 days ago

  • Target version set to 2026.04
Actions

Also available in: Atom PDF