rtnetlink_server: Don't refresh for addresses
We can dynamically add and remove addresses without having to recreate
all of the objects.
Change-Id: Ic510263cc6ba5d2ec228ce94fa83cf5fe4664c6d
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/src/ethernet_interface.cpp b/src/ethernet_interface.cpp
index a0c6193..3df966d 100644
--- a/src/ethernet_interface.cpp
+++ b/src/ethernet_interface.cpp
@@ -173,31 +173,35 @@
);
}
+void EthernetInterface::addAddr(const AddressInfo& info)
+{
+ if (info.flags & IFA_F_DEPRECATED)
+ {
+ return;
+ }
+ IP::AddressOrigin origin = IP::AddressOrigin::Static;
+ if (dhcpIsEnabled(info.ifaddr.getAddr()))
+ {
+ origin = IP::AddressOrigin::DHCP;
+ }
+#ifdef LINK_LOCAL_AUTOCONFIGURATION
+ if (info.scope == RT_SCOPE_LINK)
+ {
+ origin = IP::AddressOrigin::LinkLocal;
+ }
+#endif
+
+ this->addrs.insert_or_assign(
+ info.ifaddr, std::make_unique<IPAddress>(bus, std::string_view(objPath),
+ *this, info.ifaddr, origin));
+}
+
void EthernetInterface::createIPAddressObjects()
{
addrs.clear();
for (const auto& addr : system::getAddresses({.ifidx = ifIdx}))
{
- if (addr.flags & IFA_F_DEPRECATED)
- {
- continue;
- }
- IP::AddressOrigin origin = IP::AddressOrigin::Static;
- if (dhcpIsEnabled(addr.ifaddr.getAddr()))
- {
- origin = IP::AddressOrigin::DHCP;
- }
-#ifdef LINK_LOCAL_AUTOCONFIGURATION
- if (addr.scope == RT_SCOPE_LINK)
- {
- origin = IP::AddressOrigin::LinkLocal;
- }
-#endif
-
- this->addrs.insert_or_assign(
- addr.ifaddr,
- std::make_unique<IPAddress>(bus, std::string_view(objPath), *this,
- addr.ifaddr, origin));
+ addAddr(addr);
}
}
@@ -270,7 +274,7 @@
ifaddr, IP::AddressOrigin::Static));
writeConfigurationFile();
- manager.reloadConfigs();
+ manager.reloadConfigsNoRefresh();
return it->second->getObjPath();
}
diff --git a/src/ethernet_interface.hpp b/src/ethernet_interface.hpp
index 7d14385..f14e069 100644
--- a/src/ethernet_interface.hpp
+++ b/src/ethernet_interface.hpp
@@ -100,6 +100,8 @@
/** @brief Persistent map of Neighbor dbus objects and their names */
std::unordered_map<InAddrAny, std::unique_ptr<Neighbor>> staticNeighbors;
+ void addAddr(const AddressInfo& info);
+
/** @brief Updates the interface information based on new InterfaceInfo */
void updateInfo(const system::InterfaceInfo& info);
diff --git a/src/ipaddress.cpp b/src/ipaddress.cpp
index 560129d..b3ca3db 100644
--- a/src/ipaddress.cpp
+++ b/src/ipaddress.cpp
@@ -111,7 +111,7 @@
}
parent.writeConfigurationFile();
- parent.manager.reloadConfigs();
+ parent.manager.reloadConfigsNoRefresh();
}
} // namespace network
diff --git a/src/rtnetlink_server.cpp b/src/rtnetlink_server.cpp
index 880eba1..2a0ab38 100644
--- a/src/rtnetlink_server.cpp
+++ b/src/rtnetlink_server.cpp
@@ -36,8 +36,6 @@
{
case RTM_NEWLINK:
case RTM_DELLINK:
- case RTM_NEWADDR:
- case RTM_DELADDR:
return true;
case RTM_NEWNEIGH:
case RTM_DELNEIGH:
@@ -103,6 +101,26 @@
std::get<InAddrAny>(*ret));
}
+static void addrhandler(Manager& m, bool n, std::string_view data)
+{
+ auto info = netlink::addrFromRtm(data);
+ auto it = m.interfacesByIdx.find(info.ifidx);
+ if (it == m.interfacesByIdx.end())
+ {
+ auto msg = fmt::format("Interface `{}` not found for addr", info.ifidx);
+ log<level::ERR>(msg.c_str(), entry("IFIDX=%u", info.ifidx));
+ return;
+ }
+ if (n)
+ {
+ it->second->addAddr(info);
+ }
+ else
+ {
+ it->second->addrs.erase(info.ifaddr);
+ }
+}
+
static void handler(Manager& m, const nlmsghdr& hdr, std::string_view data)
{
if (shouldRefresh(hdr, data) && !refreshObjectTimer->isEnabled())
@@ -117,6 +135,12 @@
case RTM_DELROUTE:
rthandler(m, false, data);
break;
+ case RTM_NEWADDR:
+ addrhandler(m, true, data);
+ break;
+ case RTM_DELADDR:
+ addrhandler(m, false, data);
+ break;
}
}