diff options
author | Ratan Gupta <ratagupt@in.ibm.com> | 2017-08-18 17:10:07 +0530 |
---|---|---|
committer | Ratan Gupta <ratagupt@in.ibm.com> | 2017-09-09 00:44:57 +0530 |
commit | bd303b1097695f6e6ddadef96d64476830fbdc19 (patch) | |
tree | 930362073665d9a0d1c881f07eb5d4e7c4ba580b /ethernet_interface.cpp | |
parent | 4f67dac2061f5fafbae83aba9d44029b994275a7 (diff) | |
download | phosphor-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.cpp | 78 |
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 |