Open And-yW opened 1 week ago
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.
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 ?
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
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?