From 3ce5505e7aaacefd9fcdd303d021fa371294d30f Mon Sep 17 00:00:00 2001
From: Marina Maslova <Marina.Maslova@iopsys.eu>
Date: Thu, 3 Apr 2025 19:07:24 +0400
Subject: [PATCH] Update IP addresses for local interfaces
---
src/netlink.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 48 insertions(+), 4 deletions(-)
diff --git a/src/netlink.c b/src/netlink.c
index 30bece2..b66be54 100644
--- a/src/netlink.c
+++ b/src/netlink.c
@@ -408,6 +408,51 @@ static int hostmngr_handle_nlevents_link(struct hostmngr_private *priv,
return NL_OK;
}
+static int hostmngr_handle_nlevents_addr(struct hostmngr_private *priv,
+ struct nlmsghdr *hdr)
+{
+ struct ifaddrmsg *ifa = nlmsg_data(hdr);
+ struct nlattr *nla[__IFA_MAX];
+ struct local_interface *iface = NULL;
+ char ifname[IFNAMSIZ] = {0};
+ struct ip_address ips[32] = {0};
+ int num_ipaddrs = 32;
+ int ret;
+
+ if (!nlmsg_valid_hdr(hdr, sizeof(*ifa)) ||
+ (ifa->ifa_family != AF_INET6 && ifa->ifa_family != AF_INET))
+ return NL_SKIP;
+
+ nlmsg_parse(hdr, sizeof(*ifa), nla, __IFA_MAX - 1, NULL);
+
+ if_indextoname(ifa->ifa_index, ifname);
+ iface = hostmngr_ifname_to_interface(priv, ifname);
+ if (!iface)
+ return NL_SKIP;
+
+ ret = if_getaddrs(iface->ifname, ips, &num_ipaddrs);
+ if (ret)
+ return NL_SKIP;
+
+ if (num_ipaddrs == iface->num_ipaddrs &&
+ memcmp(iface->ipaddrs, ips, num_ipaddrs * sizeof(struct ip_address)) == 0)
+ return NL_OK;
+
+ free(iface->ipaddrs);
+ iface->ipaddrs = NULL;
+ iface->num_ipaddrs = 0;
+
+ if (num_ipaddrs > 0) {
+ iface->ipaddrs = calloc(num_ipaddrs, sizeof(struct ip_address));
+ if (iface->ipaddrs) {
+ iface->num_ipaddrs = num_ipaddrs;
+ memcpy(iface->ipaddrs, ips, num_ipaddrs * sizeof(struct ip_address));
+ }
+ }
+
+ return NL_OK;
+}
+
static int hostmngr_nlevents_cb(struct nl_msg *msg, void *arg)
{
struct nlmsghdr *hdr = nlmsg_hdr(msg);
@@ -422,13 +467,11 @@ static int hostmngr_nlevents_cb(struct nl_msg *msg, void *arg)
case RTM_DELLINK:
ret = hostmngr_handle_nlevents_link(priv, hdr, add);
break;
-#if 0 //TODO: when needed
case RTM_NEWADDR:
- add = true;
+ /* falltrough */
case RTM_DELADDR:
- ret = hostmngr_handle_nlevents_addr(priv, hdr, add);
+ ret = hostmngr_handle_nlevents_addr(priv, hdr);
break;
-#endif
case RTM_NEWNEIGH:
add = true;
case RTM_DELNEIGH:
@@ -493,6 +536,7 @@ int hostmngr_register_nlevents(struct hostmngr_private *priv)
hostmngr_nlevents_cb, priv);
if (nl_socket_add_memberships(rtnl_event.sock,
+ RTNLGRP_IPV4_IFADDR, RTNLGRP_IPV6_IFADDR,
RTNLGRP_NEIGH, RTNLGRP_LINK, 0))
goto out_err;
--
GitLab