ethernet_interface: Remove ip binary invocation
We can directly drop the interface without needing to execute another
binary using the same code as nicEnabled().
Change-Id: Ic889fd6464a898022d0d9c3febfeb43c885b6b79
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/src/ethernet_interface.cpp b/src/ethernet_interface.cpp
index a42488d..2e15803 100644
--- a/src/ethernet_interface.cpp
+++ b/src/ethernet_interface.cpp
@@ -760,6 +760,28 @@
return *ret;
}
+static void setNICAdminState(int fd, const char* intf, bool up)
+{
+ ifreq ifr = {};
+ std::strncpy(ifr.ifr_name, intf, IF_NAMESIZE - 1);
+ if (ioctl(fd, SIOCGIFFLAGS, &ifr) != 0)
+ {
+ log<level::ERR>("ioctl failed for SIOCGIFFLAGS:",
+ entry("ERROR=%s", strerror(errno)));
+ elog<InternalFailure>();
+ }
+
+ ifr.ifr_flags &= ~IFF_UP;
+ ifr.ifr_flags |= up ? IFF_UP : 0;
+
+ if (ioctl(fd, SIOCSIFFLAGS, &ifr) != 0)
+ {
+ log<level::ERR>("ioctl failed for SIOCSIFFLAGS:",
+ entry("ERROR=%s", strerror(errno)));
+ elog<InternalFailure>();
+ }
+}
+
bool EthernetInterface::nicEnabled(bool value)
{
if (value == EthernetInterfaceIntf::nicEnabled())
@@ -772,25 +794,9 @@
{
return EthernetInterfaceIntf::nicEnabled();
}
+ auto ifname = interfaceName();
+ setNICAdminState(eifSocket.sock, ifname.c_str(), value);
- ifreq ifr = {};
- std::strncpy(ifr.ifr_name, interfaceName().c_str(), IF_NAMESIZE - 1);
- if (ioctl(eifSocket.sock, SIOCGIFFLAGS, &ifr) != 0)
- {
- log<level::ERR>("ioctl failed for SIOCGIFFLAGS:",
- entry("ERROR=%s", strerror(errno)));
- return EthernetInterfaceIntf::nicEnabled();
- }
-
- ifr.ifr_flags &= ~IFF_UP;
- ifr.ifr_flags |= value ? IFF_UP : 0;
-
- if (ioctl(eifSocket.sock, SIOCSIFFLAGS, &ifr) != 0)
- {
- log<level::ERR>("ioctl failed for SIOCSIFFLAGS:",
- entry("ERROR=%s", strerror(errno)));
- return EthernetInterfaceIntf::nicEnabled();
- }
EthernetInterfaceIntf::nicEnabled(value);
writeConfigurationFile();
@@ -1234,12 +1240,10 @@
}
MacAddressIntf::macAddress(validMAC);
- // TODO: would remove the call below and
- // just restart systemd-netwokd
- // through https://github.com/systemd/systemd/issues/6696
- execute("/sbin/ip", "ip", "link", "set", "dev", interface.c_str(),
- "down");
writeConfigurationFile();
+ // The MAC and LLADDRs will only update if the NIC is already down
+ EthernetIntfSocket eifSocket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
+ setNICAdminState(eifSocket.sock, interface.c_str(), false);
manager.reloadConfigs();
}