summaryrefslogtreecommitdiff
path: root/meta-openbmc-mods/meta-common/recipes-network/network/phosphor-network
diff options
context:
space:
mode:
Diffstat (limited to 'meta-openbmc-mods/meta-common/recipes-network/network/phosphor-network')
-rw-r--r--meta-openbmc-mods/meta-common/recipes-network/network/phosphor-network/0003-Adding-channel-specific-privilege-to-network.patch20
-rw-r--r--meta-openbmc-mods/meta-common/recipes-network/network/phosphor-network/0008-Added-enable-disable-control-of-the-Network-Interfac.patch191
-rw-r--r--meta-openbmc-mods/meta-common/recipes-network/network/phosphor-network/0010-Enable-the-network-link-carrier-state-to-be-reported.patch137
-rw-r--r--meta-openbmc-mods/meta-common/recipes-network/network/phosphor-network/0011-Added-enable-disable-control-of-the-Network-Interfac.patch189
4 files changed, 242 insertions, 295 deletions
diff --git a/meta-openbmc-mods/meta-common/recipes-network/network/phosphor-network/0003-Adding-channel-specific-privilege-to-network.patch b/meta-openbmc-mods/meta-common/recipes-network/network/phosphor-network/0003-Adding-channel-specific-privilege-to-network.patch
index 53f381af8..ac7d7f8a7 100644
--- a/meta-openbmc-mods/meta-common/recipes-network/network/phosphor-network/0003-Adding-channel-specific-privilege-to-network.patch
+++ b/meta-openbmc-mods/meta-common/recipes-network/network/phosphor-network/0003-Adding-channel-specific-privilege-to-network.patch
@@ -18,7 +18,7 @@ Change-Id: I3b592a19363eef684e31d5f7c34dad8f2f9211df
Signed-off-by: AppaRao Puli <apparao.puli@linux.intel.com>
Signed-off-by: Yong Li <yong.b.li@linux.intel.com>
---
- ethernet_interface.cpp | 116 +++++++++++++++++++++++++++++++++++++++++
+ ethernet_interface.cpp | 122 +++++++++++++++++++++++++++++++++++++++++
ethernet_interface.hpp | 39 +++++++++++++-
network_manager.cpp | 104 ++++++++++++++++++++++++++++++++++++
network_manager.hpp | 9 ++++
@@ -46,7 +46,7 @@ index 2375482..c3edd4b 100644
// Emit deferred signal.
if (emitSignal)
-@@ -823,5 +827,117 @@ void EthernetInterface::deleteAll()
+@@ -823,5 +827,123 @@ void EthernetInterface::deleteAll()
manager.writeToConfigurationFile();
}
@@ -133,6 +133,12 @@ index 2375482..c3edd4b 100644
+{
+ std::string intfName = interfaceName();
+
++ if (manager.supportedPrivList.empty())
++ {
++ // Populate the supported privilege list
++ manager.initSupportedPrivilges();
++ }
++
+ if (!priv.empty() && (std::find(manager.supportedPrivList.begin(),
+ manager.supportedPrivList.end(),
+ priv) == manager.supportedPrivList.end()))
@@ -377,26 +383,26 @@ diff --git a/network_manager.hpp b/network_manager.hpp
index edb341f..e16b205 100644
--- a/network_manager.hpp
+++ b/network_manager.hpp
-@@ -137,6 +137,9 @@ class Manager : public details::VLANCreateIface
+@@ -137,6 +137,12 @@ class Manager : public details::VLANCreateIface
return (interfaces.find(intf) != interfaces.end());
}
+ /** supported privilege list **/
+ std::vector<std::string> supportedPrivList;
+
++ /** @brief initializes the supportedPrivilege List */
++ void initSupportedPrivilges();
++
protected:
/** @brief Persistent sdbusplus DBus bus connection. */
sdbusplus::bus::bus& bus;
-@@ -159,6 +162,12 @@ class Manager : public details::VLANCreateIface
+@@ -159,6 +162,9 @@ class Manager : public details::VLANCreateIface
/** @brief Network Configuration directory. */
fs::path confDir;
+
+ /** Get the user management service name dynamically **/
+ std::string getUserServiceName();
-+
-+ /** @brief initializes the supportedPrivilege List */
-+ void initSupportedPrivilges();
};
} // namespace network
diff --git a/meta-openbmc-mods/meta-common/recipes-network/network/phosphor-network/0008-Added-enable-disable-control-of-the-Network-Interfac.patch b/meta-openbmc-mods/meta-common/recipes-network/network/phosphor-network/0008-Added-enable-disable-control-of-the-Network-Interfac.patch
deleted file mode 100644
index e1972e815..000000000
--- a/meta-openbmc-mods/meta-common/recipes-network/network/phosphor-network/0008-Added-enable-disable-control-of-the-Network-Interfac.patch
+++ /dev/null
@@ -1,191 +0,0 @@
-From 0e415f23b7a97e9a0f0fa616b6bcccec6035bbed Mon Sep 17 00:00:00 2001
-From: Johnathan Mantey <johnathanx.mantey@intel.com>
-Date: Tue, 29 Oct 2019 16:20:28 -0700
-Subject: [PATCH] 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>
----
- ethernet_interface.cpp | 70 ++++++++++++++++++++++++++++++++++++++++--
- ethernet_interface.hpp | 7 ++++-
- 2 files changed, 74 insertions(+), 3 deletions(-)
-
-diff --git a/ethernet_interface.cpp b/ethernet_interface.cpp
-index ba6195e..671e8c4 100644
---- a/ethernet_interface.cpp
-+++ b/ethernet_interface.cpp
-@@ -60,6 +60,7 @@ EthernetInterface::EthernetInterface(sdbusplus::bus::bus& bus,
- #if NIC_SUPPORTS_ETHTOOL
- InterfaceInfo ifInfo = EthernetInterface::getInterfaceInfo();
-
-+ EthernetInterfaceIntf::nICEnabled(std::get<3>(ifInfo));
- EthernetInterfaceIntf::autoNeg(std::get<2>(ifInfo));
- EthernetInterfaceIntf::speed(std::get<0>(ifInfo));
- #endif
-@@ -300,6 +301,7 @@ InterfaceInfo EthernetInterface::getInterfaceInfo() const
- LinkSpeed speed{0};
- Autoneg autoneg{0};
- DuplexMode duplex{0};
-+ NICEnabled nicEnabled{false};
- do
- {
- sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
-@@ -324,13 +326,21 @@ InterfaceInfo EthernetInterface::getInterfaceInfo() const
- speed = edata.speed;
- duplex = edata.duplex;
- autoneg = edata.autoneg;
-+
-+ if (ioctl(sock, SIOCGIFFLAGS, &ifr) < 0)
-+ {
-+ log<level::ERR>("ioctl failed for SIOCGIFFLAGS:",
-+ entry("ERROR=%s", strerror(errno)));
-+ break;
-+ }
-+ nicEnabled = static_cast<bool>(ifr.ifr_flags & IFF_UP);
- } while (0);
-
-- if (sock)
-+ if (sock >= 0)
- {
- close(sock);
- }
-- return std::make_tuple(speed, duplex, autoneg);
-+ return std::make_tuple(speed, duplex, autoneg, nicEnabled);
- }
- #endif
-
-@@ -355,9 +365,11 @@ std::string
- {
- log<level::ERR>("ioctl failed for SIOCGIFHWADDR:",
- entry("ERROR=%s", strerror(errno)));
-+ close(sock);
- elog<InternalFailure>();
- }
-
-+ close(sock);
- static_assert(sizeof(ifr.ifr_hwaddr.sa_data) >= sizeof(ether_addr));
- std::string_view hwaddr(reinterpret_cast<char*>(ifr.ifr_hwaddr.sa_data),
- sizeof(ifr.ifr_hwaddr.sa_data));
-@@ -514,6 +526,55 @@ EthernetInterface::DHCPConf EthernetInterface::dHCPEnabled(DHCPConf value)
- return value;
- }
-
-+bool EthernetInterface::nICEnabled(bool value)
-+{
-+ if (value == EthernetInterfaceIntf::nICEnabled())
-+ {
-+ return value;
-+ }
-+
-+ int sock{-1};
-+ ifreq ifr{0};
-+ EthernetInterfaceIntf::nICEnabled(value);
-+ sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
-+ if (sock < 0)
-+ {
-+ log<level::ERR>("socket creation failed:",
-+ entry("ERROR=%s", strerror(errno)));
-+ return value;
-+ }
-+
-+ do
-+ {
-+ std::strncpy(ifr.ifr_name, interfaceName().c_str(), IF_NAMESIZE);
-+ if (ioctl(sock, SIOCGIFFLAGS, &ifr) != 0)
-+ {
-+ log<level::ERR>("ioctl failed for SIOCGIFFLAGS:",
-+ entry("ERROR=%s", strerror(errno)));
-+ break;
-+ }
-+
-+ ifr.ifr_flags &= ~IFF_UP;
-+ if (value)
-+ {
-+ ifr.ifr_flags |= IFF_UP;
-+ }
-+
-+ if (ioctl(sock, SIOCSIFFLAGS, &ifr) != 0)
-+ {
-+ log<level::ERR>("ioctl failed for SIOCSIFFLAGS:",
-+ entry("ERROR=%s", strerror(errno)));
-+ break;
-+ }
-+ } while (0);
-+
-+ close(sock);
-+ writeConfigurationFile();
-+ manager.restartSystemdUnit(networkdService);
-+
-+ return value;
-+}
-+
- ServerList EthernetInterface::nameservers(ServerList value)
- {
- for (const auto& nameserverip : value)
-@@ -704,6 +765,11 @@ void EthernetInterface::writeConfigurationFile()
- 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 a962751..3dee311 100644
---- a/ethernet_interface.hpp
-+++ b/ethernet_interface.hpp
-@@ -59,9 +59,10 @@ class Neighbor;
- using LinkSpeed = uint16_t;
- using DuplexMode = uint8_t;
- using Autoneg = uint8_t;
-+using NICEnabled = bool;
- using VlanId = uint32_t;
- using InterfaceName = std::string;
--using InterfaceInfo = std::tuple<LinkSpeed, DuplexMode, Autoneg>;
-+using InterfaceInfo = std::tuple<LinkSpeed, DuplexMode, Autoneg, NICEnabled>;
- using AddressMap = std::map<std::string, std::shared_ptr<IPAddress>>;
- using NeighborMap = std::map<std::string, std::shared_ptr<Neighbor>>;
- using VlanInterfaceMap =
-@@ -186,6 +187,9 @@ class EthernetInterface : public Ifaces
- */
- void disableDHCP(IP::Protocol protocol);
-
-+ /** 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.
-@@ -241,6 +245,7 @@ class EthernetInterface : public Ifaces
- using ChannelAccessIntf::maxPrivilege;
- using EthernetInterfaceIntf::dHCPEnabled;
- using EthernetInterfaceIntf::interfaceName;
-+ using EthernetInterfaceIntf::nICEnabled;
- using MacAddressIntf::mACAddress;
-
- /** @brief Absolute path of the resolv conf file */
---
-2.24.1
-
diff --git a/meta-openbmc-mods/meta-common/recipes-network/network/phosphor-network/0010-Enable-the-network-link-carrier-state-to-be-reported.patch b/meta-openbmc-mods/meta-common/recipes-network/network/phosphor-network/0010-Enable-the-network-link-carrier-state-to-be-reported.patch
index 51957ffff..eb4efab8f 100644
--- a/meta-openbmc-mods/meta-common/recipes-network/network/phosphor-network/0010-Enable-the-network-link-carrier-state-to-be-reported.patch
+++ b/meta-openbmc-mods/meta-common/recipes-network/network/phosphor-network/0010-Enable-the-network-link-carrier-state-to-be-reported.patch
@@ -1,4 +1,4 @@
-From 8f6f3ccb1f5a4af8065485c2e683402ec2b38abf Mon Sep 17 00:00:00 2001
+From 7e99cfbb5cdbf47cd0350d869be236c88f982fd3 Mon Sep 17 00:00:00 2001
From: Johnathan Mantey <johnathanx.mantey@intel.com>
Date: Wed, 8 Jan 2020 10:38:58 -0800
Subject: [PATCH] Enable the network link carrier state to be reported.
@@ -24,12 +24,12 @@ Get bmc/EthernetInterfaces/eth0 from Redfish # LinkStatus = Linkup
Change-Id: I5530cf7882cfbfdba1436dd34b3219c735047c5e
Signed-off-by: Johnathan Mantey <johnathanx.mantey@intel.com>
---
- ethernet_interface.cpp | 141 +++++++++++++++++++++++++----------------
- ethernet_interface.hpp | 8 ++-
- 2 files changed, 92 insertions(+), 57 deletions(-)
+ ethernet_interface.cpp | 104 ++++++++++++++++++++++++++++-------------
+ ethernet_interface.hpp | 7 ++-
+ 2 files changed, 77 insertions(+), 34 deletions(-)
diff --git a/ethernet_interface.cpp b/ethernet_interface.cpp
-index 671e8c4..018f2e1 100644
+index ba6195e..8b8f698 100644
--- a/ethernet_interface.cpp
+++ b/ethernet_interface.cpp
@@ -42,6 +42,28 @@ static constexpr const char* defaultChannelPriv = "priv-admin";
@@ -49,7 +49,7 @@ index 671e8c4..018f2e1 100644
+
+ ~EthernetIntfSocket()
+ {
-+ if (sock > 0)
++ if (sock >= 0)
+ {
+ close(sock);
+ }
@@ -61,42 +61,24 @@ index 671e8c4..018f2e1 100644
EthernetInterface::EthernetInterface(sdbusplus::bus::bus& bus,
const std::string& objPath,
DHCPConf dhcpEnabled, Manager& parent,
-@@ -57,12 +79,12 @@ EthernetInterface::EthernetInterface(sdbusplus::bus::bus& bus,
- MacAddressIntf::mACAddress(getMACAddress(intfName));
- EthernetInterfaceIntf::nTPServers(getNTPServersFromConf());
- EthernetInterfaceIntf::nameservers(getNameServerFromConf());
--#if NIC_SUPPORTS_ETHTOOL
- InterfaceInfo ifInfo = EthernetInterface::getInterfaceInfo();
--
-- EthernetInterfaceIntf::nICEnabled(std::get<3>(ifInfo));
-+#if NIC_SUPPORTS_ETHTOOL
+@@ -62,6 +84,7 @@ EthernetInterface::EthernetInterface(sdbusplus::bus::bus& bus,
+
EthernetInterfaceIntf::autoNeg(std::get<2>(ifInfo));
EthernetInterfaceIntf::speed(std::get<0>(ifInfo));
-+ EthernetInterfaceIntf::nICEnabled(std::get<3>(ifInfo));
-+ EthernetInterfaceIntf::linkUp(std::get<4>(ifInfo));
++ EthernetInterfaceIntf::linkUp(std::get<3>(ifInfo));
#endif
getChannelPrivilege(intfName);
-@@ -286,63 +308,47 @@ ObjectPath EthernetInterface::neighbor(std::string iPAddress,
- return objectPath;
- }
-
--#if NIC_SUPPORTS_ETHTOOL
--/*
-- Enable this code if your NIC driver supports the ETHTOOL features.
-- Do this by adding the following to your phosphor-network*.bbappend file.
-- EXTRA_OECONF_append = " --enable-nic-ethtool=yes"
-- The default compile mode is to omit getInterfaceInfo()
--*/
+@@ -294,43 +317,33 @@ ObjectPath EthernetInterface::neighbor(std::string iPAddress,
+ */
InterfaceInfo EthernetInterface::getInterfaceInfo() const
{
- int sock{-1};
-- ifreq ifr{0};
-- ethtool_cmd edata{0};
+ ifreq ifr{0};
+ ethtool_cmd edata{0};
LinkSpeed speed{0};
Autoneg autoneg{0};
DuplexMode duplex{0};
- NICEnabled nicEnabled{false};
- do
- {
- sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
@@ -107,67 +89,46 @@ index 671e8c4..018f2e1 100644
- break;
- }
+ LinkUp linkState{false};
++ EthernetIntfSocket eifSocket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
- strcpy(ifr.ifr_name, interfaceName().c_str());
- ifr.ifr_data = reinterpret_cast<char*>(&edata);
-+#if NIC_SUPPORTS_ETHTOOL
-+ /*
-+ Enable this code if your NIC driver supports the ETHTOOL features.
-+ Do this by adding the following to your phosphor-network*.bbappend
-+ file. EXTRA_OECONF_append = " --enable-nic-ethtool=yes" The
-+ default compile mode is to omit getInterfaceInfo()
-+ */
-+ ifreq ifr{0};
-+ ethtool_cmd edata{0};
-+ EthernetIntfSocket eifSocket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
-
-- edata.cmd = ETHTOOL_GSET;
+ if (eifSocket.sock < 0)
+ {
-+ return std::make_tuple(speed, duplex, autoneg, nicEnabled, linkState);
++ return std::make_tuple(speed, duplex, autoneg, linkState);
+ }
+- edata.cmd = ETHTOOL_GSET;
++ std::strncpy(ifr.ifr_name, interfaceName().c_str(), IFNAMSIZ - 1);
++ ifr.ifr_data = reinterpret_cast<char*>(&edata);
+
- if (ioctl(sock, SIOCETHTOOL, &ifr) < 0)
- {
- log<level::ERR>("ioctl failed for SIOCETHTOOL:",
- entry("ERROR=%s", strerror(errno)));
- break;
- }
-+ std::strncpy(ifr.ifr_name, interfaceName().c_str(), IFNAMSIZ - 1);
-+ ifr.ifr_data = reinterpret_cast<char*>(&edata);
-+
+ edata.cmd = ETHTOOL_GSET;
+ if (ioctl(eifSocket.sock, SIOCETHTOOL, &ifr) >= 0)
+ {
speed = edata.speed;
duplex = edata.duplex;
autoneg = edata.autoneg;
-+ }
-+#endif
-
-- if (ioctl(sock, SIOCGIFFLAGS, &ifr) < 0)
-- {
-- log<level::ERR>("ioctl failed for SIOCGIFFLAGS:",
-- entry("ERROR=%s", strerror(errno)));
-- break;
-- }
-- nicEnabled = static_cast<bool>(ifr.ifr_flags & IFF_UP);
- } while (0);
-+ nicEnabled = nICEnabled();
-+ linkState = linkUp();
-
-- if (sock >= 0)
+-
+- if (sock)
- {
- close(sock);
-- }
-- return std::make_tuple(speed, duplex, autoneg, nicEnabled);
-+ return std::make_tuple(speed, duplex, autoneg, nicEnabled, linkState);
+ }
+- return std::make_tuple(speed, duplex, autoneg);
++
++ linkState = linkUp();
++
++ return std::make_tuple(speed, duplex, autoneg, linkState);
}
--#endif
+ #endif
- /** @brief get the mac address of the interface.
- * @return macaddress on success
-@@ -351,25 +357,23 @@ InterfaceInfo EthernetInterface::getInterfaceInfo() const
+@@ -341,17 +354,17 @@ InterfaceInfo EthernetInterface::getInterfaceInfo() const
std::string
EthernetInterface::getMACAddress(const std::string& interfaceName) const
{
@@ -193,24 +154,7 @@ index 671e8c4..018f2e1 100644
{
log<level::ERR>("ioctl failed for SIOCGIFHWADDR:",
entry("ERROR=%s", strerror(errno)));
-- close(sock);
- elog<InternalFailure>();
- }
-
-- close(sock);
- static_assert(sizeof(ifr.ifr_hwaddr.sa_data) >= sizeof(ether_addr));
- std::string_view hwaddr(reinterpret_cast<char*>(ifr.ifr_hwaddr.sa_data),
- sizeof(ifr.ifr_hwaddr.sa_data));
-@@ -546,7 +550,7 @@ bool EthernetInterface::nICEnabled(bool value)
-
- do
- {
-- std::strncpy(ifr.ifr_name, interfaceName().c_str(), IF_NAMESIZE);
-+ std::strncpy(ifr.ifr_name, interfaceName().c_str(), IF_NAMESIZE - 1);
- if (ioctl(sock, SIOCGIFFLAGS, &ifr) != 0)
- {
- log<level::ERR>("ioctl failed for SIOCGIFFLAGS:",
-@@ -575,6 +579,31 @@ bool EthernetInterface::nICEnabled(bool value)
+@@ -514,6 +527,31 @@ EthernetInterface::DHCPConf EthernetInterface::dHCPEnabled(DHCPConf value)
return value;
}
@@ -243,25 +187,24 @@ index 671e8c4..018f2e1 100644
{
for (const auto& nameserverip : value)
diff --git a/ethernet_interface.hpp b/ethernet_interface.hpp
-index 3dee311..83d7cb5 100644
+index a962751..4e36ae8 100644
--- a/ethernet_interface.hpp
+++ b/ethernet_interface.hpp
-@@ -60,9 +60,11 @@ using LinkSpeed = uint16_t;
+@@ -59,9 +59,10 @@ class Neighbor;
+ using LinkSpeed = uint16_t;
using DuplexMode = uint8_t;
using Autoneg = uint8_t;
- using NICEnabled = bool;
+using LinkUp = bool;
using VlanId = uint32_t;
using InterfaceName = std::string;
--using InterfaceInfo = std::tuple<LinkSpeed, DuplexMode, Autoneg, NICEnabled>;
-+using InterfaceInfo =
-+ std::tuple<LinkSpeed, DuplexMode, Autoneg, NICEnabled, LinkUp>;
+-using InterfaceInfo = std::tuple<LinkSpeed, DuplexMode, Autoneg>;
++using InterfaceInfo = std::tuple<LinkSpeed, DuplexMode, Autoneg, LinkUp>;
using AddressMap = std::map<std::string, std::shared_ptr<IPAddress>>;
using NeighborMap = std::map<std::string, std::shared_ptr<Neighbor>>;
using VlanInterfaceMap =
-@@ -190,6 +192,9 @@ class EthernetInterface : public Ifaces
- /** Set value of NICEnabled */
- bool nICEnabled(bool value) override;
+@@ -186,6 +187,9 @@ class EthernetInterface : public Ifaces
+ */
+ void disableDHCP(IP::Protocol protocol);
+ /** Retrieve Link State */
+ bool linkUp() const override;
@@ -269,14 +212,14 @@ index 3dee311..83d7cb5 100644
/** @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.
-@@ -245,6 +250,7 @@ class EthernetInterface : public Ifaces
+@@ -241,6 +245,7 @@ class EthernetInterface : public Ifaces
using ChannelAccessIntf::maxPrivilege;
using EthernetInterfaceIntf::dHCPEnabled;
using EthernetInterfaceIntf::interfaceName;
+ using EthernetInterfaceIntf::linkUp;
- using EthernetInterfaceIntf::nICEnabled;
using MacAddressIntf::mACAddress;
+ /** @brief Absolute path of the resolv conf file */
--
2.24.1
diff --git a/meta-openbmc-mods/meta-common/recipes-network/network/phosphor-network/0011-Added-enable-disable-control-of-the-Network-Interfac.patch b/meta-openbmc-mods/meta-common/recipes-network/network/phosphor-network/0011-Added-enable-disable-control-of-the-Network-Interfac.patch
new file mode 100644
index 000000000..58dcf3f21
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-network/network/phosphor-network/0011-Added-enable-disable-control-of-the-Network-Interfac.patch
@@ -0,0 +1,189 @@
+From 4bfb4ad5ff795d78e06fbeaf1664df6819880f50 Mon Sep 17 00:00:00 2001
+From: Johnathan Mantey <johnathanx.mantey@intel.com>
+Date: Tue, 29 Oct 2019 16:20:28 -0700
+Subject: [PATCH] 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>
+---
+ ethernet_interface.cpp | 73 ++++++++++++++++++++++++++++++++++++++++--
+ ethernet_interface.hpp | 11 ++++++-
+ 2 files changed, 81 insertions(+), 3 deletions(-)
+
+diff --git a/ethernet_interface.cpp b/ethernet_interface.cpp
+index 8b8f698..a2754a4 100644
+--- a/ethernet_interface.cpp
++++ b/ethernet_interface.cpp
+@@ -85,6 +85,7 @@ EthernetInterface::EthernetInterface(sdbusplus::bus::bus& bus,
+ 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
+ getChannelPrivilege(intfName);
+
+@@ -323,11 +324,12 @@ InterfaceInfo EthernetInterface::getInterfaceInfo() const
+ 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);
+@@ -341,9 +343,10 @@ InterfaceInfo EthernetInterface::getInterfaceInfo() const
+ 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
+
+@@ -548,6 +551,67 @@ bool EthernetInterface::linkUp() const
+ 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();
++ manager.restartSystemdUnit(networkdService);
+
+ return value;
+ }
+@@ -742,6 +806,11 @@ void EthernetInterface::writeConfigurationFile()
+ 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 4e36ae8..104750e 100644
+--- a/ethernet_interface.hpp
++++ b/ethernet_interface.hpp
+@@ -60,9 +60,11 @@ using LinkSpeed = uint16_t;
+ 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 =
+@@ -190,6 +192,12 @@ class EthernetInterface : public Ifaces
+ /** 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.
+@@ -246,6 +254,7 @@ class EthernetInterface : public Ifaces
+ using EthernetInterfaceIntf::dHCPEnabled;
+ using EthernetInterfaceIntf::interfaceName;
+ using EthernetInterfaceIntf::linkUp;
++ using EthernetInterfaceIntf::nICEnabled;
+ using MacAddressIntf::mACAddress;
+
+ /** @brief Absolute path of the resolv conf file */
+--
+2.24.1
+