Issues with rtnl_neigh_get on RHEL 7.0 and RHEL 7.1

Thomas Haller thaller at redhat.com
Tue Aug 18 09:44:58 PDT 2015


On Tue, 2015-08-18 at 14:32 +0000, Haggai Abramovsky wrote:
> The following commit:
> 64fcb47 Add AF_BRIDGE support to neigh cache
> 
> Added the following check:
> @@ -496,7 +515,8 @@ struct rtnl_neigh * rtnl_neigh_get(struct
> nl_cache *cache, int ifindex,
>         struct rtnl_neigh *neigh;
> 
>         nl_list_for_each_entry(neigh, &cache->c_items, ce_list) {
> -           if (neigh->n_ifindex == ifindex &&
> +         if (neigh->n_family == AF_UNSPEC &&
> +             neigh->n_ifindex == ifindex &&
>                     !nl_addr_cmp(neigh->n_dst, dst)) {
>                         nl_object_get((struct nl_object *) neigh);
>                         return neigh;
> 
> Which was later removed by the following commit:
> 8571f58 neigh: Remove check for AF_UNSPEC in rtnl_neigh_get()
> 
> Between these two commits, when the n_family doesn't equal to
> AF_UNSPEC, the libnl won't search for neighbor in the cache, and will
> return NULL.
> 
> RHEL 7.0 and RHEL 7.1 has the previous check, which causes our
> library, that uses the libnl, to fail although the neighbor is in
> cache.
> 
> Is there a way to solve this? Is there any work around we can use to
> allow our library to run with the n_family check?

If this bug causes you problems that you cannot workaround you should
open a bugreport
https://bugzilla.redhat.com/enter_bug.cgi?product=Red%20Hat%20Enterprise%20Linux%207

The problem is, that the fix (obviously) changes behavior, so it's a
bit problematic to fix in RHEL-7 because it might break other users.


Also, you probably anyway need a way to properly handle the buggy and
the fixed version.

Do you call rtnl_neigh_get() directly? Can you not implement your own
version of it?



struct rtnl_neigh * my_rtnl_neigh_get(struct nl_cache *cache, int ifindex,
                                      struct nl_addr *dst)
{
    struct rtnl_neigh *neigh;

    neigh = (struct rtnl_neigh *)nl_cache_get_first (cache);
    while (neigh) {
        if (rtnl_neigh_get_ifindex (neigh) == ifindex) {
            struct nl_addr *d;

            d = rtnl_neigh_get_dst (neigh);
            if (d && !nl_addr_cmp(d, dst)) {
                nl_object_get((struct nl_object *) neigh);
                return neigh;
            }
         }
         neigh = (struct rtnl_neigh *)nl_cache_get_next ((struct nl_object *)neigh);
    }
    return NULL;
}




Thomas
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/libnl/attachments/20150818/20ab04bf/attachment.sig>


More information about the libnl mailing list