Added enable/disable control of the Network Interface Card
Implemented enable/disable function to perform
"ip link set eth(x) up"
"ip link set eth(x) down"
functionality from DBus.
Tested:
Confirmed Redfish PATCH commands on the InterfaceEnabled property
changes the NIC state. Confirmed the NIC is DOWN/UP using "ip link".
Confirmed "ip link" state changes can be obsserved from dbus-send
commands, and from Redfish GET actions.
Confirmed the link is inactive after a reboot.
Confirmed link stays down despite assigning an IP manually.
Confirmed link stays down despite enabling DHCP.
Change-Id: I4152b53055e6546f7a6ca81b5a5eef6f689bcc66
Signed-off-by: Johnathan Mantey <johnathanx.mantey@intel.com>
diff --git a/ethernet_interface.cpp b/ethernet_interface.cpp
index 600ab83..4827f68 100644
--- a/ethernet_interface.cpp
+++ b/ethernet_interface.cpp
@@ -91,6 +91,7 @@
EthernetInterfaceIntf::autoNeg(std::get<2>(ifInfo));
EthernetInterfaceIntf::speed(std::get<0>(ifInfo));
EthernetInterfaceIntf::linkUp(std::get<3>(ifInfo));
+ EthernetInterfaceIntf::nICEnabled(std::get<4>(ifInfo));
#endif
// Emit deferred signal.
@@ -269,11 +270,12 @@
Autoneg autoneg{0};
DuplexMode duplex{0};
LinkUp linkState{false};
+ NICEnabled nicEnabled{false};
EthernetIntfSocket eifSocket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
if (eifSocket.sock < 0)
{
- return std::make_tuple(speed, duplex, autoneg, linkState);
+ return std::make_tuple(speed, duplex, autoneg, linkState, nicEnabled);
}
std::strncpy(ifr.ifr_name, interfaceName().c_str(), IFNAMSIZ - 1);
@@ -287,9 +289,10 @@
autoneg = edata.autoneg;
}
+ nicEnabled = nICEnabled();
linkState = linkUp();
- return std::make_tuple(speed, duplex, autoneg, linkState);
+ return std::make_tuple(speed, duplex, autoneg, linkState, nicEnabled);
}
#endif
@@ -494,6 +497,66 @@
log<level::ERR>("ioctl failed for SIOCGIFFLAGS:",
entry("ERROR=%s", strerror(errno)));
}
+ return value;
+}
+
+bool EthernetInterface::nICEnabled() const
+{
+ EthernetIntfSocket eifSocket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
+ bool value = EthernetInterfaceIntf::nICEnabled();
+
+ if (eifSocket.sock < 0)
+ {
+ return value;
+ }
+
+ ifreq ifr{0};
+ std::strncpy(ifr.ifr_name, interfaceName().c_str(), IF_NAMESIZE - 1);
+ if (ioctl(eifSocket.sock, SIOCGIFFLAGS, &ifr) == 0)
+ {
+ value = static_cast<bool>(ifr.ifr_flags & IFF_UP);
+ }
+ else
+ {
+ log<level::ERR>("ioctl failed for SIOCGIFFLAGS:",
+ entry("ERROR=%s", strerror(errno)));
+ }
+ return value;
+}
+
+bool EthernetInterface::nICEnabled(bool value)
+{
+ if (value == EthernetInterfaceIntf::nICEnabled())
+ {
+ return value;
+ }
+
+ EthernetIntfSocket eifSocket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
+ if (eifSocket.sock < 0)
+ {
+ return EthernetInterfaceIntf::nICEnabled();
+ }
+
+ ifreq ifr{0};
+ 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();
return value;
}
@@ -753,6 +816,11 @@
stream << "MACAddress=" << mac << "\n";
}
+ if (!nICEnabled())
+ {
+ stream << "Unmanaged=yes\n";
+ }
+
// write the network section
stream << "[Network]\n";
#ifdef LINK_LOCAL_AUTOCONFIGURATION
diff --git a/ethernet_interface.hpp b/ethernet_interface.hpp
index 4a0f030..f8086a4 100644
--- a/ethernet_interface.hpp
+++ b/ethernet_interface.hpp
@@ -51,9 +51,11 @@
using DuplexMode = uint8_t;
using Autoneg = uint8_t;
using LinkUp = bool;
+using NICEnabled = bool;
using VlanId = uint32_t;
using InterfaceName = std::string;
-using InterfaceInfo = std::tuple<LinkSpeed, DuplexMode, Autoneg, LinkUp>;
+using InterfaceInfo =
+ std::tuple<LinkSpeed, DuplexMode, Autoneg, LinkUp, NICEnabled>;
using AddressMap = std::map<std::string, std::shared_ptr<IPAddress>>;
using NeighborMap = std::map<std::string, std::shared_ptr<Neighbor>>;
using VlanInterfaceMap =
@@ -158,6 +160,12 @@
/** Retrieve Link State */
bool linkUp() const override;
+ /** Retrieve NIC State */
+ bool nICEnabled() const override;
+
+ /** Set value of NICEnabled */
+ bool nICEnabled(bool value) override;
+
/** @brief sets the MAC address.
* @param[in] value - MAC address which needs to be set on the system.
* @returns macAddress of the interface or throws an error.
@@ -212,6 +220,7 @@
using EthernetInterfaceIntf::dHCPEnabled;
using EthernetInterfaceIntf::interfaceName;
using EthernetInterfaceIntf::linkUp;
+ using EthernetInterfaceIntf::nICEnabled;
using MacAddressIntf::mACAddress;
/** @brief Absolute path of the resolv conf file */