Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

VLAN generates 2 "new" events #411

Open
And-yW opened this issue Nov 13, 2024 · 3 comments
Open

VLAN generates 2 "new" events #411

And-yW opened this issue Nov 13, 2024 · 3 comments

Comments

@And-yW
Copy link

And-yW commented Nov 13, 2024

Hi

When creating a new VLAN interface on eth0 it generates 2 NL_ACT_NEW events if IPv6 is active on eth0, this doesn't happen if there is no IPv6.

After some debugging this seems to happen since the l_family of the 2nd event does not match the already cached entry, the cached entry has l_family == 0 but the 2nd has l_family == AF_INET6 and the compare function doesn't match.

Is this intended behavior or is there a work-around to not get the 2nd event since deleting it only generates one event?

@thom311
Copy link
Owner

thom311 commented Nov 13, 2024

I don't know the answer.

Also, you don't show any code, so it's not even clear what "events" exactly are or how you use the API.

The first question is to look at the netlink events from kernel. Are they different? If yes, is that a kernel bug? Should libnl try to workaround that? If they are not different, is that a kernel bug? Should there be two events that are the same? Should libnl somehow filter them out? etc.

@And-yW
Copy link
Author

And-yW commented Nov 13, 2024

Sorry I wasn't very clear.

I tested with "nl-monitor -d7 link" but there doesn't seem to be much difference in the log output, I'll attach them here
maybe you can see something I don't.

nl-mon-ipv4.txt
nl-mon-ipv4_and_ipv6.txt

I have a cache manger setup:

_monitor->socket = nl_socket_alloc();
nl_cache_mngr_alloc(_monitor->socket, NETLINK_ROUTE, 0, &_monitor->cache_mngr);
rtnl_link_alloc_cache(_monitor->socket, AF_UNSPEC, &_monitor->link_cache);
nl_cache_mngr_add_cache_v2(_monitor->cache_mngr, _monitor->link_cache, &monitor_link_cache_cb, _monitor);

And then I run a test that creates a VLAN (eth0.4) on eth0 in the same way as the example iin "test-create-vlan.c" and then deletes it.

When I run with both IPv4 and IPv6 enabled I get 2 calls monitor_link_cache_cb() with NL_ACT_NEW set.
When I run with only IPv4 enabled I only get one such call.

I've added this debug patch to libnl (I disabled the hashtable lookup to make debugging easier, hopefully not a problem?):

--- a/lib/cache.c
+++ b/lib/cache.c
@@ -1108,8 +1108,8 @@ struct nl_object *nl_cache_search(struct nl_cache *cache,
 {
        struct nl_object *obj;
 
-       if (cache->hashtable)
-               return __cache_fast_lookup(cache, needle);
+       // if (cache->hashtable)
+       //      return __cache_fast_lookup(cache, needle);
 
        nl_list_for_each_entry(obj, &cache->c_items, ce_list) {
                if (nl_object_identical(obj, needle)) {
diff --git a/lib/route/link.c b/lib/route/link.c
index 9b72574..0317d7e 100644
--- a/lib/route/link.c
+++ b/lib/route/link.c
@@ -1176,6 +1176,8 @@ static uint64_t link_compare(struct nl_object *_a, struct nl_object *_b,
 
        diff |= _DIFF(LINK_ATTR_LINKINFO, rtnl_link_info_data_compare(a, b, flags) != 0);
 out:
+
+       fprintf(stderr, "ANDY: link_compare() a: name: %s family: %X, b: name: %s family: %X\n", a->l_name, a->l_family, b->l_name, b->l_family);
        return diff;


When running with this patch, I can see this log print for IPv6 and IPv4, where "a" is the cached entry and "b" the new entry:
2024-11-13T16:17:13.401+01:00 [ INFO ] : ANDY: link_compare() a: name: eth0.4 family: 0, b: name: eth0.4 family: A

Since this doesn't match it seems that libnl generates a "NL_ACT_NEW" message to the callback.
Is family relevant for link messages ?

@And-yW
Copy link
Author

And-yW commented Nov 14, 2024

I've tested some more and captured logs with NLDBG=5, hopefully this is more helpful.

The netlink message that triggers the 2nd NEW callback is at line 3217 in this log:
ipv6_ipv4.log

Also I've captured the same log with just ipv4:
ipv4_only.log

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants