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();
     }