summaryrefslogtreecommitdiffstats
path: root/ethernet_interface.cpp
diff options
context:
space:
mode:
authorRatan Gupta <ratagupt@in.ibm.com>2017-08-18 17:10:07 +0530
committerRatan Gupta <ratagupt@in.ibm.com>2017-09-09 00:44:57 +0530
commitbd303b1097695f6e6ddadef96d64476830fbdc19 (patch)
tree930362073665d9a0d1c881f07eb5d4e7c4ba580b /ethernet_interface.cpp
parent4f67dac2061f5fafbae83aba9d44029b994275a7 (diff)
downloadphosphor-networkd-bd303b1097695f6e6ddadef96d64476830fbdc19.tar.gz
phosphor-networkd-bd303b1097695f6e6ddadef96d64476830fbdc19.zip
Implement Set function for MAC address
Change-Id: I16992dda259246a66512792f06cbbb874e56a15d Signed-off-by: Ratan Gupta <ratagupt@in.ibm.com>
Diffstat (limited to 'ethernet_interface.cpp')
-rw-r--r--ethernet_interface.cpp78
1 files changed, 70 insertions, 8 deletions
diff --git a/ethernet_interface.cpp b/ethernet_interface.cpp
index c24a3e8..39c12cf 100644
--- a/ethernet_interface.cpp
+++ b/ethernet_interface.cpp
@@ -33,10 +33,6 @@ namespace network
using namespace phosphor::logging;
using namespace sdbusplus::xyz::openbmc_project::Common::Error;
-constexpr auto MAC_ADDRESS_FORMAT = "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx";
-constexpr size_t SIZE_MAC = 18;
-constexpr size_t SIZE_BUFF = 512;
-
EthernetInterface::EthernetInterface(sdbusplus::bus::bus& bus,
const std::string& objPath,
bool dhcpEnabled,
@@ -51,7 +47,7 @@ EthernetInterface::EthernetInterface(sdbusplus::bus::bus& bus,
std::replace(intfName.begin(), intfName.end(), '_', '.');
interfaceName(intfName);
EthernetInterfaceIntf::dHCPEnabled(dhcpEnabled);
- mACAddress(getMACAddress(intfName));
+ MacAddressIntf::mACAddress(getMACAddress(intfName));
// Emit deferred signal.
if (emitSignal)
@@ -116,7 +112,7 @@ void EthernetInterface::iP(IP::Protocol protType,
if (dHCPEnabled())
{
log<level::INFO>("DHCP enabled on the interface"),
- entry("INTERFACE=%s",interfaceName());
+ entry("INTERFACE=%s",interfaceName().c_str());
return;
}
@@ -200,7 +196,7 @@ std::string EthernetInterface::getMACAddress(
const std::string& interfaceName) const
{
struct ifreq ifr{};
- char macAddress[SIZE_MAC] {};
+ char macAddress[mac_address::size] {};
int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
if (sock < 0)
@@ -218,7 +214,7 @@ std::string EthernetInterface::getMACAddress(
return macAddress;
}
- snprintf(macAddress, SIZE_MAC, MAC_ADDRESS_FORMAT,
+ snprintf(macAddress, mac_address::size, mac_address::format,
ifr.ifr_hwaddr.sa_data[0], ifr.ifr_hwaddr.sa_data[1],
ifr.ifr_hwaddr.sa_data[2], ifr.ifr_hwaddr.sa_data[3],
ifr.ifr_hwaddr.sa_data[4], ifr.ifr_hwaddr.sa_data[5]);
@@ -510,5 +506,71 @@ void EthernetInterface::writeDHCPSection(std::fstream& stream)
}
}
+std::string EthernetInterface::mACAddress(std::string value)
+{
+ if (!mac_address::validate(value))
+ {
+ log<level::DEBUG>("MACAddress is not valid.",
+ entry("MAC=%s", value.c_str()));
+ return MacAddressIntf::mACAddress();
+ }
+
+ // check whether MAC is broadcast mac.
+ auto intMac = mac_address::internal::convertToInt(value);
+
+ if (!(intMac ^ mac_address::broadcastMac))
+ {
+ log<level::DEBUG>("MACAddress is a broadcast mac.",
+ entry("MAC=%s", value.c_str()));
+ return MacAddressIntf::mACAddress();
+ }
+
+ // Allow the mac to be set if one of the condition is true.
+ // 1) Incoming Mac is of local admin type.
+ // or
+ // 2) Incoming mac is same as eeprom Mac.
+
+ if (!(intMac & mac_address::localAdminMask))
+ {
+ try
+ {
+ auto inventoryMac = mac_address::getfromInventory(bus);
+ auto intInventoryMac = mac_address::internal::convertToInt(inventoryMac);
+
+ if (intInventoryMac != intMac)
+ {
+ log<level::DEBUG>("Given MAC address is neither a local Admin \
+ type nor is same as in inventory");
+ return MacAddressIntf::mACAddress();
+ }
+ }
+ catch(InternalFailure& e)
+ {
+ log<level::ERR>("Exception occured during getting of MAC \
+ address from Inventory");
+ return MacAddressIntf::mACAddress();
+ }
+ }
+ auto interface = interfaceName();
+ execute("/sbin/fw_setenv", "fw_setenv", "ethaddr", value.c_str());
+ //TODO: would replace below three calls
+ // with restarting of systemd-netwokd
+ // through https://github.com/systemd/systemd/issues/6696
+ execute("/sbin/ip", "ip", "link", "set", "dev", interface.c_str(), "down");
+ execute("/sbin/ip", "ip", "link", "set", "dev", interface.c_str(), "address",
+ value.c_str());
+
+ execute("/sbin/ip", "ip", "link", "set", "dev", interface.c_str(), "up");
+
+ auto mac = MacAddressIntf::mACAddress(std::move(value));
+ //update all the vlan interfaces
+ for(const auto& intf: vlanInterfaces)
+ {
+ intf.second->updateMacAddress();
+ }
+ return mac;
+
+}
+
}//namespace network
}//namespace phosphor
OpenPOWER on IntegriCloud