| Gunnar Mills | 57d9c50 | 2018-09-14 14:42:34 -0500 | [diff] [blame] | 1 | #include "config.h" | 
 | 2 |  | 
| Patrick Venture | 189d44e | 2018-07-09 12:30:59 -0700 | [diff] [blame] | 3 | #include "ethernet_interface.hpp" | 
 | 4 |  | 
| Ratan Gupta | 497c0c9 | 2017-08-22 19:15:59 +0530 | [diff] [blame] | 5 | #include "config_parser.hpp" | 
| William A. Kennington III | 0850579 | 2019-01-30 16:00:04 -0800 | [diff] [blame] | 6 | #include "neighbor.hpp" | 
| Ratan Gupta | 4f1c18b | 2017-05-25 12:59:35 +0530 | [diff] [blame] | 7 | #include "network_manager.hpp" | 
| Ratan Gupta | 2b10653 | 2017-07-25 16:05:02 +0530 | [diff] [blame] | 8 | #include "vlan_interface.hpp" | 
| Ratan Gupta | 91a99cc | 2017-04-14 16:32:09 +0530 | [diff] [blame] | 9 |  | 
| Ratan Gupta | 82549cc | 2017-04-21 08:45:23 +0530 | [diff] [blame] | 10 | #include <arpa/inet.h> | 
| Ratan Gupta | 91a99cc | 2017-04-14 16:32:09 +0530 | [diff] [blame] | 11 | #include <linux/ethtool.h> | 
| William A. Kennington III | d7946a7 | 2019-04-19 14:24:09 -0700 | [diff] [blame] | 12 | #include <linux/rtnetlink.h> | 
| Ratan Gupta | 91a99cc | 2017-04-14 16:32:09 +0530 | [diff] [blame] | 13 | #include <linux/sockios.h> | 
| Ratan Gupta | 2b10653 | 2017-07-25 16:05:02 +0530 | [diff] [blame] | 14 | #include <net/if.h> | 
| Ratan Gupta | 91a99cc | 2017-04-14 16:32:09 +0530 | [diff] [blame] | 15 | #include <netinet/in.h> | 
 | 16 | #include <sys/ioctl.h> | 
 | 17 | #include <sys/socket.h> | 
 | 18 | #include <unistd.h> | 
 | 19 |  | 
| Ratan Gupta | 82549cc | 2017-04-21 08:45:23 +0530 | [diff] [blame] | 20 | #include <algorithm> | 
| Manojkiran Eda | a879baa | 2020-06-13 14:39:08 +0530 | [diff] [blame] | 21 | #include <filesystem> | 
| Ratan Gupta | 2b10653 | 2017-07-25 16:05:02 +0530 | [diff] [blame] | 22 | #include <fstream> | 
| Patrick Venture | 189d44e | 2018-07-09 12:30:59 -0700 | [diff] [blame] | 23 | #include <phosphor-logging/elog-errors.hpp> | 
 | 24 | #include <phosphor-logging/log.hpp> | 
| Ratan Gupta | 2b10653 | 2017-07-25 16:05:02 +0530 | [diff] [blame] | 25 | #include <sstream> | 
| William A. Kennington III | 12beaad | 2020-06-13 19:30:41 -0700 | [diff] [blame] | 26 | #include <stdplus/raw.hpp> | 
| Ratan Gupta | 2b10653 | 2017-07-25 16:05:02 +0530 | [diff] [blame] | 27 | #include <string> | 
| William A. Kennington III | 1137a97 | 2019-04-20 20:49:58 -0700 | [diff] [blame] | 28 | #include <string_view> | 
| Patrick Venture | 189d44e | 2018-07-09 12:30:59 -0700 | [diff] [blame] | 29 | #include <xyz/openbmc_project/Common/error.hpp> | 
| Ratan Gupta | 82549cc | 2017-04-21 08:45:23 +0530 | [diff] [blame] | 30 |  | 
| Ratan Gupta | 91a99cc | 2017-04-14 16:32:09 +0530 | [diff] [blame] | 31 | namespace phosphor | 
 | 32 | { | 
 | 33 | namespace network | 
 | 34 | { | 
 | 35 |  | 
 | 36 | using namespace phosphor::logging; | 
| Ratan Gupta | 2b10653 | 2017-07-25 16:05:02 +0530 | [diff] [blame] | 37 | using namespace sdbusplus::xyz::openbmc_project::Common::Error; | 
| Manojkiran Eda | acd6dd5 | 2019-10-15 15:00:51 +0530 | [diff] [blame] | 38 | using NotAllowed = sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed; | 
 | 39 | using NotAllowedArgument = xyz::openbmc_project::Common::NotAllowed; | 
| Nagaraju Goruganti | 66b974d | 2017-10-03 08:43:08 -0500 | [diff] [blame] | 40 | using Argument = xyz::openbmc_project::Common::InvalidArgument; | 
| Manojkiran Eda | acd6dd5 | 2019-10-15 15:00:51 +0530 | [diff] [blame] | 41 | constexpr auto RESOLVED_SERVICE = "org.freedesktop.resolve1"; | 
 | 42 | constexpr auto RESOLVED_INTERFACE = "org.freedesktop.resolve1.Link"; | 
 | 43 | constexpr auto PROPERTY_INTERFACE = "org.freedesktop.DBus.Properties"; | 
 | 44 | constexpr auto RESOLVED_SERVICE_PATH = "/org/freedesktop/resolve1/link/"; | 
 | 45 | constexpr auto METHOD_GET = "Get"; | 
| Ratan Gupta | 2b10653 | 2017-07-25 16:05:02 +0530 | [diff] [blame] | 46 |  | 
| Johnathan Mantey | faa72e5 | 2020-01-08 10:38:58 -0800 | [diff] [blame] | 47 | struct EthernetIntfSocket | 
 | 48 | { | 
 | 49 |     EthernetIntfSocket(int domain, int type, int protocol) | 
 | 50 |     { | 
 | 51 |         if ((sock = socket(domain, type, protocol)) < 0) | 
 | 52 |         { | 
 | 53 |             log<level::ERR>("socket creation failed:", | 
 | 54 |                             entry("ERROR=%s", strerror(errno))); | 
 | 55 |         } | 
 | 56 |     } | 
 | 57 |  | 
 | 58 |     ~EthernetIntfSocket() | 
 | 59 |     { | 
 | 60 |         if (sock >= 0) | 
 | 61 |         { | 
 | 62 |             close(sock); | 
 | 63 |         } | 
 | 64 |     } | 
 | 65 |  | 
 | 66 |     int sock{-1}; | 
 | 67 | }; | 
 | 68 |  | 
| Johnathan Mantey | 817012a | 2020-01-30 15:07:39 -0800 | [diff] [blame] | 69 | std::map<EthernetInterface::DHCPConf, std::string> mapDHCPToSystemd = { | 
 | 70 |     {EthernetInterface::DHCPConf::both, "true"}, | 
 | 71 |     {EthernetInterface::DHCPConf::v4, "ipv4"}, | 
 | 72 |     {EthernetInterface::DHCPConf::v6, "ipv6"}, | 
 | 73 |     {EthernetInterface::DHCPConf::none, "false"}}; | 
 | 74 |  | 
| Ratan Gupta | 91a99cc | 2017-04-14 16:32:09 +0530 | [diff] [blame] | 75 | EthernetInterface::EthernetInterface(sdbusplus::bus::bus& bus, | 
 | 76 |                                      const std::string& objPath, | 
| Johnathan Mantey | 817012a | 2020-01-30 15:07:39 -0800 | [diff] [blame] | 77 |                                      DHCPConf dhcpEnabled, Manager& parent, | 
| Ratan Gupta | 3d3e4fc | 2017-07-25 13:38:19 +0530 | [diff] [blame] | 78 |                                      bool emitSignal) : | 
| Gunnar Mills | 57d9c50 | 2018-09-14 14:42:34 -0500 | [diff] [blame] | 79 |     Ifaces(bus, objPath.c_str(), true), | 
 | 80 |     bus(bus), manager(parent), objPath(objPath) | 
| Ratan Gupta | 91a99cc | 2017-04-14 16:32:09 +0530 | [diff] [blame] | 81 | { | 
 | 82 |     auto intfName = objPath.substr(objPath.rfind("/") + 1); | 
| Ratan Gupta | 5978dd1 | 2017-07-25 13:47:13 +0530 | [diff] [blame] | 83 |     std::replace(intfName.begin(), intfName.end(), '_', '.'); | 
| Ratan Gupta | 91a99cc | 2017-04-14 16:32:09 +0530 | [diff] [blame] | 84 |     interfaceName(intfName); | 
| Ratan Gupta | c35481d | 2017-08-18 06:12:26 +0530 | [diff] [blame] | 85 |     EthernetInterfaceIntf::dHCPEnabled(dhcpEnabled); | 
| Johnathan Mantey | 5b023f5 | 2019-06-24 16:06:37 -0700 | [diff] [blame] | 86 |     EthernetInterfaceIntf::iPv6AcceptRA(getIPv6AcceptRAFromConf()); | 
| Ratan Gupta | 99801ce | 2020-01-09 18:37:16 +0530 | [diff] [blame] | 87 |     // Don't get the mac address from the system as the mac address | 
 | 88 |     // would be same as parent interface. | 
 | 89 |     if (intfName.find(".") == std::string::npos) | 
 | 90 |     { | 
 | 91 |         MacAddressIntf::mACAddress(getMACAddress(intfName)); | 
 | 92 |     } | 
| Ratan Gupta | 497c0c9 | 2017-08-22 19:15:59 +0530 | [diff] [blame] | 93 |     EthernetInterfaceIntf::nTPServers(getNTPServersFromConf()); | 
| Ratan Gupta | 613a012 | 2020-04-24 15:18:53 +0530 | [diff] [blame] | 94 |  | 
 | 95 |     EthernetInterfaceIntf::linkUp(linkUp()); | 
 | 96 |     EthernetInterfaceIntf::nICEnabled(nICEnabled()); | 
 | 97 |  | 
| Johnathan Mantey | ad4bf5c | 2020-01-24 13:30:39 -0800 | [diff] [blame] | 98 | #if NIC_SUPPORTS_ETHTOOL | 
| Johnathan Mantey | cb42fe2 | 2019-08-01 13:35:29 -0700 | [diff] [blame] | 99 |     InterfaceInfo ifInfo = EthernetInterface::getInterfaceInfo(); | 
 | 100 |  | 
 | 101 |     EthernetInterfaceIntf::autoNeg(std::get<2>(ifInfo)); | 
 | 102 |     EthernetInterfaceIntf::speed(std::get<0>(ifInfo)); | 
| Johnathan Mantey | ad4bf5c | 2020-01-24 13:30:39 -0800 | [diff] [blame] | 103 | #endif | 
| Ratan Gupta | 6dec390 | 2017-08-20 15:28:12 +0530 | [diff] [blame] | 104 |  | 
| Ratan Gupta | 29b0e43 | 2017-05-25 12:51:40 +0530 | [diff] [blame] | 105 |     // Emit deferred signal. | 
| Ratan Gupta | 3d3e4fc | 2017-07-25 13:38:19 +0530 | [diff] [blame] | 106 |     if (emitSignal) | 
 | 107 |     { | 
 | 108 |         this->emit_object_added(); | 
 | 109 |     } | 
| Ratan Gupta | 29b0e43 | 2017-05-25 12:51:40 +0530 | [diff] [blame] | 110 | } | 
 | 111 |  | 
| William A. Kennington III | fbafa25 | 2018-11-30 16:53:52 -0800 | [diff] [blame] | 112 | static IP::Protocol convertFamily(int family) | 
 | 113 | { | 
 | 114 |     switch (family) | 
 | 115 |     { | 
 | 116 |         case AF_INET: | 
 | 117 |             return IP::Protocol::IPv4; | 
 | 118 |         case AF_INET6: | 
 | 119 |             return IP::Protocol::IPv6; | 
 | 120 |     } | 
 | 121 |  | 
 | 122 |     throw std::invalid_argument("Bad address family"); | 
 | 123 | } | 
 | 124 |  | 
| Johnathan Mantey | 817012a | 2020-01-30 15:07:39 -0800 | [diff] [blame] | 125 | void EthernetInterface::disableDHCP(IP::Protocol protocol) | 
 | 126 | { | 
 | 127 |     DHCPConf dhcpState = EthernetInterfaceIntf::dHCPEnabled(); | 
 | 128 |     if (dhcpState == EthernetInterface::DHCPConf::both) | 
 | 129 |     { | 
 | 130 |         if (protocol == IP::Protocol::IPv4) | 
 | 131 |         { | 
 | 132 |             dHCPEnabled(EthernetInterface::DHCPConf::v6); | 
 | 133 |         } | 
 | 134 |         else if (protocol == IP::Protocol::IPv6) | 
 | 135 |         { | 
 | 136 |             dHCPEnabled(EthernetInterface::DHCPConf::v4); | 
 | 137 |         } | 
 | 138 |     } | 
 | 139 |     else if ((dhcpState == EthernetInterface::DHCPConf::v4) && | 
 | 140 |              (protocol == IP::Protocol::IPv4)) | 
 | 141 |     { | 
 | 142 |         dHCPEnabled(EthernetInterface::DHCPConf::none); | 
 | 143 |     } | 
 | 144 |     else if ((dhcpState == EthernetInterface::DHCPConf::v6) && | 
 | 145 |              (protocol == IP::Protocol::IPv6)) | 
 | 146 |     { | 
 | 147 |         dHCPEnabled(EthernetInterface::DHCPConf::none); | 
 | 148 |     } | 
 | 149 | } | 
 | 150 |  | 
 | 151 | bool EthernetInterface::dhcpIsEnabled(IP::Protocol family, bool ignoreProtocol) | 
 | 152 | { | 
 | 153 |     return ((EthernetInterfaceIntf::dHCPEnabled() == | 
 | 154 |              EthernetInterface::DHCPConf::both) || | 
 | 155 |             ((EthernetInterfaceIntf::dHCPEnabled() == | 
 | 156 |               EthernetInterface::DHCPConf::v6) && | 
 | 157 |              ((family == IP::Protocol::IPv6) || ignoreProtocol)) || | 
 | 158 |             ((EthernetInterfaceIntf::dHCPEnabled() == | 
 | 159 |               EthernetInterface::DHCPConf::v4) && | 
 | 160 |              ((family == IP::Protocol::IPv4) || ignoreProtocol))); | 
 | 161 | } | 
 | 162 |  | 
 | 163 | bool EthernetInterface::dhcpToBeEnabled(IP::Protocol family, | 
 | 164 |                                         const std::string& nextDHCPState) | 
 | 165 | { | 
 | 166 |     return ((nextDHCPState == "true") || | 
 | 167 |             ((nextDHCPState == "ipv6") && (family == IP::Protocol::IPv6)) || | 
 | 168 |             ((nextDHCPState == "ipv4") && (family == IP::Protocol::IPv4))); | 
 | 169 | } | 
 | 170 |  | 
 | 171 | bool EthernetInterface::originIsManuallyAssigned(IP::AddressOrigin origin) | 
 | 172 | { | 
 | 173 |     return ( | 
 | 174 | #ifdef LINK_LOCAL_AUTOCONFIGURATION | 
 | 175 |         (origin == IP::AddressOrigin::Static) | 
 | 176 | #else | 
 | 177 |         (origin == IP::AddressOrigin::Static || | 
 | 178 |          origin == IP::AddressOrigin::LinkLocal) | 
 | 179 | #endif | 
 | 180 |  | 
 | 181 |     ); | 
 | 182 | } | 
 | 183 |  | 
| Ratan Gupta | 87c1398 | 2017-06-15 09:27:27 +0530 | [diff] [blame] | 184 | void EthernetInterface::createIPAddressObjects() | 
| Ratan Gupta | 29b0e43 | 2017-05-25 12:51:40 +0530 | [diff] [blame] | 185 | { | 
| Ratan Gupta | 87c1398 | 2017-06-15 09:27:27 +0530 | [diff] [blame] | 186 |     addrs.clear(); | 
| Ratan Gupta | 82549cc | 2017-04-21 08:45:23 +0530 | [diff] [blame] | 187 |  | 
| Ratan Gupta | 87c1398 | 2017-06-15 09:27:27 +0530 | [diff] [blame] | 188 |     auto addrs = getInterfaceAddrs()[interfaceName()]; | 
| Ratan Gupta | 5978dd1 | 2017-07-25 13:47:13 +0530 | [diff] [blame] | 189 |  | 
| Ratan Gupta | 6a387c1 | 2017-08-03 13:26:19 +0530 | [diff] [blame] | 190 |     for (auto& addr : addrs) | 
| Ratan Gupta | 82549cc | 2017-04-21 08:45:23 +0530 | [diff] [blame] | 191 |     { | 
| William A. Kennington III | fbafa25 | 2018-11-30 16:53:52 -0800 | [diff] [blame] | 192 |         IP::Protocol addressType = convertFamily(addr.addrType); | 
 | 193 |         IP::AddressOrigin origin = IP::AddressOrigin::Static; | 
| Johnathan Mantey | 817012a | 2020-01-30 15:07:39 -0800 | [diff] [blame] | 194 |         if (dhcpIsEnabled(addressType)) | 
| Ratan Gupta | fc2c724 | 2017-05-29 08:46:06 +0530 | [diff] [blame] | 195 |         { | 
 | 196 |             origin = IP::AddressOrigin::DHCP; | 
 | 197 |         } | 
| William A. Kennington III | 1689380 | 2019-01-30 16:01:01 -0800 | [diff] [blame] | 198 |         if (isLinkLocalIP(addr.ipaddress)) | 
| Ratan Gupta | fc2c724 | 2017-05-29 08:46:06 +0530 | [diff] [blame] | 199 |         { | 
 | 200 |             origin = IP::AddressOrigin::LinkLocal; | 
 | 201 |         } | 
| William A. Kennington III | f8c78f2 | 2019-04-20 20:32:59 -0700 | [diff] [blame] | 202 |         // Obsolete parameter | 
 | 203 |         std::string gateway = ""; | 
| Ratan Gupta | 82549cc | 2017-04-21 08:45:23 +0530 | [diff] [blame] | 204 |  | 
| Gunnar Mills | 57d9c50 | 2018-09-14 14:42:34 -0500 | [diff] [blame] | 205 |         std::string ipAddressObjectPath = generateObjectPath( | 
 | 206 |             addressType, addr.ipaddress, addr.prefix, gateway); | 
| Ratan Gupta | fc2c724 | 2017-05-29 08:46:06 +0530 | [diff] [blame] | 207 |  | 
| Gunnar Mills | 57d9c50 | 2018-09-14 14:42:34 -0500 | [diff] [blame] | 208 |         this->addrs.emplace(addr.ipaddress, | 
 | 209 |                             std::make_shared<phosphor::network::IPAddress>( | 
 | 210 |                                 bus, ipAddressObjectPath.c_str(), *this, | 
 | 211 |                                 addressType, addr.ipaddress, origin, | 
 | 212 |                                 addr.prefix, gateway)); | 
| Ratan Gupta | 82549cc | 2017-04-21 08:45:23 +0530 | [diff] [blame] | 213 |     } | 
| Ratan Gupta | 91a99cc | 2017-04-14 16:32:09 +0530 | [diff] [blame] | 214 | } | 
 | 215 |  | 
| William A. Kennington III | 0850579 | 2019-01-30 16:00:04 -0800 | [diff] [blame] | 216 | void EthernetInterface::createStaticNeighborObjects() | 
 | 217 | { | 
 | 218 |     staticNeighbors.clear(); | 
 | 219 |  | 
| William A. Kennington III | d7946a7 | 2019-04-19 14:24:09 -0700 | [diff] [blame] | 220 |     NeighborFilter filter; | 
 | 221 |     filter.interface = ifIndex(); | 
 | 222 |     filter.state = NUD_PERMANENT; | 
 | 223 |     auto neighbors = getCurrentNeighbors(filter); | 
| William A. Kennington III | 0850579 | 2019-01-30 16:00:04 -0800 | [diff] [blame] | 224 |     for (const auto& neighbor : neighbors) | 
 | 225 |     { | 
| William A. Kennington III | d7946a7 | 2019-04-19 14:24:09 -0700 | [diff] [blame] | 226 |         if (!neighbor.mac) | 
| William A. Kennington III | 0850579 | 2019-01-30 16:00:04 -0800 | [diff] [blame] | 227 |         { | 
 | 228 |             continue; | 
 | 229 |         } | 
 | 230 |         std::string ip = toString(neighbor.address); | 
 | 231 |         std::string mac = mac_address::toString(*neighbor.mac); | 
 | 232 |         std::string objectPath = generateStaticNeighborObjectPath(ip, mac); | 
 | 233 |         staticNeighbors.emplace(ip, | 
 | 234 |                                 std::make_shared<phosphor::network::Neighbor>( | 
 | 235 |                                     bus, objectPath.c_str(), *this, ip, mac, | 
 | 236 |                                     Neighbor::State::Permanent)); | 
 | 237 |     } | 
 | 238 | } | 
 | 239 |  | 
| William A. Kennington III | d7946a7 | 2019-04-19 14:24:09 -0700 | [diff] [blame] | 240 | unsigned EthernetInterface::ifIndex() const | 
 | 241 | { | 
 | 242 |     unsigned idx = if_nametoindex(interfaceName().c_str()); | 
 | 243 |     if (idx == 0) | 
 | 244 |     { | 
 | 245 |         throw std::system_error(errno, std::generic_category(), | 
 | 246 |                                 "if_nametoindex"); | 
 | 247 |     } | 
 | 248 |     return idx; | 
 | 249 | } | 
 | 250 |  | 
| raviteja-b | ce37956 | 2019-03-28 05:59:36 -0500 | [diff] [blame] | 251 | ObjectPath EthernetInterface::iP(IP::Protocol protType, std::string ipaddress, | 
 | 252 |                                  uint8_t prefixLength, std::string gateway) | 
| Ratan Gupta | 82549cc | 2017-04-21 08:45:23 +0530 | [diff] [blame] | 253 | { | 
| Ratan Gupta | fc2c724 | 2017-05-29 08:46:06 +0530 | [diff] [blame] | 254 |  | 
| Johnathan Mantey | 817012a | 2020-01-30 15:07:39 -0800 | [diff] [blame] | 255 |     if (dhcpIsEnabled(protType)) | 
| Ratan Gupta | fc2c724 | 2017-05-29 08:46:06 +0530 | [diff] [blame] | 256 |     { | 
| Ratan Gupta | 82e1ef9 | 2017-06-15 08:39:15 +0530 | [diff] [blame] | 257 |         log<level::INFO>("DHCP enabled on the interface"), | 
| Nagaraju Goruganti | 66b974d | 2017-10-03 08:43:08 -0500 | [diff] [blame] | 258 |             entry("INTERFACE=%s", interfaceName().c_str()); | 
| Johnathan Mantey | 817012a | 2020-01-30 15:07:39 -0800 | [diff] [blame] | 259 |         disableDHCP(protType); | 
| Nagaraju Goruganti | 66b974d | 2017-10-03 08:43:08 -0500 | [diff] [blame] | 260 |     } | 
 | 261 |  | 
| Nagaraju Goruganti | 66b974d | 2017-10-03 08:43:08 -0500 | [diff] [blame] | 262 |     IP::AddressOrigin origin = IP::AddressOrigin::Static; | 
 | 263 |  | 
 | 264 |     int addressFamily = (protType == IP::Protocol::IPv4) ? AF_INET : AF_INET6; | 
 | 265 |  | 
 | 266 |     if (!isValidIP(addressFamily, ipaddress)) | 
 | 267 |     { | 
 | 268 |         log<level::ERR>("Not a valid IP address"), | 
 | 269 |             entry("ADDRESS=%s", ipaddress.c_str()); | 
 | 270 |         elog<InvalidArgument>(Argument::ARGUMENT_NAME("ipaddress"), | 
 | 271 |                               Argument::ARGUMENT_VALUE(ipaddress.c_str())); | 
 | 272 |     } | 
 | 273 |  | 
| William A. Kennington III | f8c78f2 | 2019-04-20 20:32:59 -0700 | [diff] [blame] | 274 |     // Gateway is an obsolete parameter | 
 | 275 |     gateway = ""; | 
| Nagaraju Goruganti | 66b974d | 2017-10-03 08:43:08 -0500 | [diff] [blame] | 276 |  | 
 | 277 |     if (!isValidPrefix(addressFamily, prefixLength)) | 
 | 278 |     { | 
 | 279 |         log<level::ERR>("PrefixLength is not correct "), | 
| William A. Kennington III | f8c78f2 | 2019-04-20 20:32:59 -0700 | [diff] [blame] | 280 |             entry("PREFIXLENGTH=%" PRIu8, prefixLength); | 
| Gunnar Mills | 57d9c50 | 2018-09-14 14:42:34 -0500 | [diff] [blame] | 281 |         elog<InvalidArgument>( | 
 | 282 |             Argument::ARGUMENT_NAME("prefixLength"), | 
 | 283 |             Argument::ARGUMENT_VALUE(std::to_string(prefixLength).c_str())); | 
| Ratan Gupta | fc2c724 | 2017-05-29 08:46:06 +0530 | [diff] [blame] | 284 |     } | 
 | 285 |  | 
| Gunnar Mills | 57d9c50 | 2018-09-14 14:42:34 -0500 | [diff] [blame] | 286 |     std::string objectPath = | 
 | 287 |         generateObjectPath(protType, ipaddress, prefixLength, gateway); | 
 | 288 |     this->addrs.emplace(ipaddress, | 
 | 289 |                         std::make_shared<phosphor::network::IPAddress>( | 
 | 290 |                             bus, objectPath.c_str(), *this, protType, ipaddress, | 
 | 291 |                             origin, prefixLength, gateway)); | 
| Ratan Gupta | 4f1c18b | 2017-05-25 12:59:35 +0530 | [diff] [blame] | 292 |  | 
| Ratan Gupta | e05083a | 2017-09-16 07:12:11 +0530 | [diff] [blame] | 293 |     manager.writeToConfigurationFile(); | 
| raviteja-b | ce37956 | 2019-03-28 05:59:36 -0500 | [diff] [blame] | 294 |     return objectPath; | 
| Ratan Gupta | 82549cc | 2017-04-21 08:45:23 +0530 | [diff] [blame] | 295 | } | 
 | 296 |  | 
| William A. Kennington III | 0850579 | 2019-01-30 16:00:04 -0800 | [diff] [blame] | 297 | ObjectPath EthernetInterface::neighbor(std::string iPAddress, | 
 | 298 |                                        std::string mACAddress) | 
 | 299 | { | 
 | 300 |     if (!isValidIP(AF_INET, iPAddress) && !isValidIP(AF_INET6, iPAddress)) | 
 | 301 |     { | 
 | 302 |         log<level::ERR>("Not a valid IP address", | 
 | 303 |                         entry("ADDRESS=%s", iPAddress.c_str())); | 
 | 304 |         elog<InvalidArgument>(Argument::ARGUMENT_NAME("iPAddress"), | 
 | 305 |                               Argument::ARGUMENT_VALUE(iPAddress.c_str())); | 
 | 306 |     } | 
| William A. Kennington III | 1137a97 | 2019-04-20 20:49:58 -0700 | [diff] [blame] | 307 |     if (!mac_address::isUnicast(mac_address::fromString(mACAddress))) | 
| William A. Kennington III | 0850579 | 2019-01-30 16:00:04 -0800 | [diff] [blame] | 308 |     { | 
 | 309 |         log<level::ERR>("Not a valid MAC address", | 
 | 310 |                         entry("MACADDRESS=%s", iPAddress.c_str())); | 
 | 311 |         elog<InvalidArgument>(Argument::ARGUMENT_NAME("mACAddress"), | 
 | 312 |                               Argument::ARGUMENT_VALUE(mACAddress.c_str())); | 
 | 313 |     } | 
 | 314 |  | 
 | 315 |     std::string objectPath = | 
 | 316 |         generateStaticNeighborObjectPath(iPAddress, mACAddress); | 
 | 317 |     staticNeighbors.emplace(iPAddress, | 
 | 318 |                             std::make_shared<phosphor::network::Neighbor>( | 
 | 319 |                                 bus, objectPath.c_str(), *this, iPAddress, | 
 | 320 |                                 mACAddress, Neighbor::State::Permanent)); | 
 | 321 |     manager.writeToConfigurationFile(); | 
 | 322 |     return objectPath; | 
 | 323 | } | 
 | 324 |  | 
| Johnathan Mantey | ad4bf5c | 2020-01-24 13:30:39 -0800 | [diff] [blame] | 325 | #if NIC_SUPPORTS_ETHTOOL | 
| Ratan Gupta | 91a99cc | 2017-04-14 16:32:09 +0530 | [diff] [blame] | 326 | /* | 
| Johnathan Mantey | ad4bf5c | 2020-01-24 13:30:39 -0800 | [diff] [blame] | 327 |   Enable this code if your NIC driver supports the ETHTOOL features. | 
 | 328 |   Do this by adding the following to your phosphor-network*.bbappend file. | 
 | 329 |      EXTRA_OECONF_append = " --enable-nic-ethtool=yes" | 
 | 330 |   The default compile mode is to omit getInterfaceInfo() | 
| Ratan Gupta | 91a99cc | 2017-04-14 16:32:09 +0530 | [diff] [blame] | 331 | */ | 
 | 332 | InterfaceInfo EthernetInterface::getInterfaceInfo() const | 
 | 333 | { | 
| Ratan K Gupta | 1a054ae | 2018-09-15 00:49:51 -0400 | [diff] [blame] | 334 |     ifreq ifr{0}; | 
 | 335 |     ethtool_cmd edata{0}; | 
| Gunnar Mills | 57d9c50 | 2018-09-14 14:42:34 -0500 | [diff] [blame] | 336 |     LinkSpeed speed{0}; | 
 | 337 |     Autoneg autoneg{0}; | 
 | 338 |     DuplexMode duplex{0}; | 
| Johnathan Mantey | faa72e5 | 2020-01-08 10:38:58 -0800 | [diff] [blame] | 339 |     LinkUp linkState{false}; | 
| Johnathan Mantey | d0679f9 | 2019-10-29 16:20:28 -0700 | [diff] [blame] | 340 |     NICEnabled nicEnabled{false}; | 
| Johnathan Mantey | faa72e5 | 2020-01-08 10:38:58 -0800 | [diff] [blame] | 341 |     EthernetIntfSocket eifSocket(PF_INET, SOCK_DGRAM, IPPROTO_IP); | 
 | 342 |  | 
 | 343 |     if (eifSocket.sock < 0) | 
| Ratan Gupta | 91a99cc | 2017-04-14 16:32:09 +0530 | [diff] [blame] | 344 |     { | 
| Johnathan Mantey | d0679f9 | 2019-10-29 16:20:28 -0700 | [diff] [blame] | 345 |         return std::make_tuple(speed, duplex, autoneg, linkState, nicEnabled); | 
| Johnathan Mantey | faa72e5 | 2020-01-08 10:38:58 -0800 | [diff] [blame] | 346 |     } | 
| Ratan Gupta | 91a99cc | 2017-04-14 16:32:09 +0530 | [diff] [blame] | 347 |  | 
| Johnathan Mantey | faa72e5 | 2020-01-08 10:38:58 -0800 | [diff] [blame] | 348 |     std::strncpy(ifr.ifr_name, interfaceName().c_str(), IFNAMSIZ - 1); | 
 | 349 |     ifr.ifr_data = reinterpret_cast<char*>(&edata); | 
| Ratan Gupta | 91a99cc | 2017-04-14 16:32:09 +0530 | [diff] [blame] | 350 |  | 
| Johnathan Mantey | faa72e5 | 2020-01-08 10:38:58 -0800 | [diff] [blame] | 351 |     edata.cmd = ETHTOOL_GSET; | 
 | 352 |     if (ioctl(eifSocket.sock, SIOCETHTOOL, &ifr) >= 0) | 
 | 353 |     { | 
| Ratan Gupta | 91a99cc | 2017-04-14 16:32:09 +0530 | [diff] [blame] | 354 |         speed = edata.speed; | 
 | 355 |         duplex = edata.duplex; | 
 | 356 |         autoneg = edata.autoneg; | 
| Ratan Gupta | 91a99cc | 2017-04-14 16:32:09 +0530 | [diff] [blame] | 357 |     } | 
| Johnathan Mantey | faa72e5 | 2020-01-08 10:38:58 -0800 | [diff] [blame] | 358 |  | 
| Johnathan Mantey | d0679f9 | 2019-10-29 16:20:28 -0700 | [diff] [blame] | 359 |     nicEnabled = nICEnabled(); | 
| Johnathan Mantey | faa72e5 | 2020-01-08 10:38:58 -0800 | [diff] [blame] | 360 |     linkState = linkUp(); | 
 | 361 |  | 
| Johnathan Mantey | d0679f9 | 2019-10-29 16:20:28 -0700 | [diff] [blame] | 362 |     return std::make_tuple(speed, duplex, autoneg, linkState, nicEnabled); | 
| Ratan Gupta | 91a99cc | 2017-04-14 16:32:09 +0530 | [diff] [blame] | 363 | } | 
| Johnathan Mantey | ad4bf5c | 2020-01-24 13:30:39 -0800 | [diff] [blame] | 364 | #endif | 
| Ratan Gupta | 91a99cc | 2017-04-14 16:32:09 +0530 | [diff] [blame] | 365 |  | 
 | 366 | /** @brief get the mac address of the interface. | 
 | 367 |  *  @return macaddress on success | 
 | 368 |  */ | 
 | 369 |  | 
| Gunnar Mills | 57d9c50 | 2018-09-14 14:42:34 -0500 | [diff] [blame] | 370 | std::string | 
 | 371 |     EthernetInterface::getMACAddress(const std::string& interfaceName) const | 
| Ratan Gupta | 91a99cc | 2017-04-14 16:32:09 +0530 | [diff] [blame] | 372 | { | 
| Johnathan Mantey | faa72e5 | 2020-01-08 10:38:58 -0800 | [diff] [blame] | 373 |     std::string activeMACAddr = MacAddressIntf::mACAddress(); | 
 | 374 |     EthernetIntfSocket eifSocket(PF_INET, SOCK_DGRAM, IPPROTO_IP); | 
 | 375 |  | 
 | 376 |     if (eifSocket.sock < 0) | 
| Ratan Gupta | 91a99cc | 2017-04-14 16:32:09 +0530 | [diff] [blame] | 377 |     { | 
| Johnathan Mantey | faa72e5 | 2020-01-08 10:38:58 -0800 | [diff] [blame] | 378 |         return activeMACAddr; | 
| Ratan Gupta | 91a99cc | 2017-04-14 16:32:09 +0530 | [diff] [blame] | 379 |     } | 
 | 380 |  | 
| Johnathan Mantey | faa72e5 | 2020-01-08 10:38:58 -0800 | [diff] [blame] | 381 |     ifreq ifr{0}; | 
 | 382 |     std::strncpy(ifr.ifr_name, interfaceName.c_str(), IFNAMSIZ - 1); | 
 | 383 |     if (ioctl(eifSocket.sock, SIOCGIFHWADDR, &ifr) != 0) | 
| Ratan Gupta | 91a99cc | 2017-04-14 16:32:09 +0530 | [diff] [blame] | 384 |     { | 
| Ratan Gupta | da7d3af | 2017-08-13 17:49:56 +0530 | [diff] [blame] | 385 |         log<level::ERR>("ioctl failed for SIOCGIFHWADDR:", | 
| Gunnar Mills | 57d9c50 | 2018-09-14 14:42:34 -0500 | [diff] [blame] | 386 |                         entry("ERROR=%s", strerror(errno))); | 
| William A. Kennington III | 7ed1b28 | 2019-04-21 23:38:42 -0700 | [diff] [blame] | 387 |         elog<InternalFailure>(); | 
| Ratan Gupta | 91a99cc | 2017-04-14 16:32:09 +0530 | [diff] [blame] | 388 |     } | 
 | 389 |  | 
| William A. Kennington III | 1137a97 | 2019-04-20 20:49:58 -0700 | [diff] [blame] | 390 |     static_assert(sizeof(ifr.ifr_hwaddr.sa_data) >= sizeof(ether_addr)); | 
 | 391 |     std::string_view hwaddr(reinterpret_cast<char*>(ifr.ifr_hwaddr.sa_data), | 
 | 392 |                             sizeof(ifr.ifr_hwaddr.sa_data)); | 
| William A. Kennington III | 12beaad | 2020-06-13 19:30:41 -0700 | [diff] [blame] | 393 |     return mac_address::toString(stdplus::raw::copyFrom<ether_addr>(hwaddr)); | 
| Ratan Gupta | 91a99cc | 2017-04-14 16:32:09 +0530 | [diff] [blame] | 394 | } | 
| Ratan Gupta | 2eff84f | 2017-04-20 19:19:15 +0530 | [diff] [blame] | 395 |  | 
| Ratan Gupta | 65e5abe | 2017-05-23 13:20:44 +0530 | [diff] [blame] | 396 | std::string EthernetInterface::generateId(const std::string& ipaddress, | 
 | 397 |                                           uint8_t prefixLength, | 
 | 398 |                                           const std::string& gateway) | 
| Ratan Gupta | 82549cc | 2017-04-21 08:45:23 +0530 | [diff] [blame] | 399 | { | 
| Ratan Gupta | 65e5abe | 2017-05-23 13:20:44 +0530 | [diff] [blame] | 400 |     std::stringstream hexId; | 
 | 401 |     std::string hashString = ipaddress; | 
 | 402 |     hashString += std::to_string(prefixLength); | 
 | 403 |     hashString += gateway; | 
| Ratan Gupta | 82549cc | 2017-04-21 08:45:23 +0530 | [diff] [blame] | 404 |  | 
| Ratan Gupta | 65e5abe | 2017-05-23 13:20:44 +0530 | [diff] [blame] | 405 |     // Only want 8 hex digits. | 
| Gunnar Mills | 57d9c50 | 2018-09-14 14:42:34 -0500 | [diff] [blame] | 406 |     hexId << std::hex << ((std::hash<std::string>{}(hashString)) & 0xFFFFFFFF); | 
| Ratan Gupta | 65e5abe | 2017-05-23 13:20:44 +0530 | [diff] [blame] | 407 |     return hexId.str(); | 
| Ratan Gupta | 82549cc | 2017-04-21 08:45:23 +0530 | [diff] [blame] | 408 | } | 
 | 409 |  | 
| William A. Kennington III | 0850579 | 2019-01-30 16:00:04 -0800 | [diff] [blame] | 410 | std::string EthernetInterface::generateNeighborId(const std::string& iPAddress, | 
 | 411 |                                                   const std::string& mACAddress) | 
 | 412 | { | 
 | 413 |     std::stringstream hexId; | 
 | 414 |     std::string hashString = iPAddress + mACAddress; | 
 | 415 |  | 
 | 416 |     // Only want 8 hex digits. | 
 | 417 |     hexId << std::hex << ((std::hash<std::string>{}(hashString)) & 0xFFFFFFFF); | 
 | 418 |     return hexId.str(); | 
 | 419 | } | 
 | 420 |  | 
| Ratan Gupta | 2eff84f | 2017-04-20 19:19:15 +0530 | [diff] [blame] | 421 | void EthernetInterface::deleteObject(const std::string& ipaddress) | 
 | 422 | { | 
| Ratan Gupta | 29b0e43 | 2017-05-25 12:51:40 +0530 | [diff] [blame] | 423 |     auto it = addrs.find(ipaddress); | 
| Ratan Gupta | fc2c724 | 2017-05-29 08:46:06 +0530 | [diff] [blame] | 424 |     if (it == addrs.end()) | 
| Ratan Gupta | 29b0e43 | 2017-05-25 12:51:40 +0530 | [diff] [blame] | 425 |     { | 
| Ratan Gupta | fc2c724 | 2017-05-29 08:46:06 +0530 | [diff] [blame] | 426 |         log<level::ERR>("DeleteObject:Unable to find the object."); | 
 | 427 |         return; | 
| Ratan Gupta | 29b0e43 | 2017-05-25 12:51:40 +0530 | [diff] [blame] | 428 |     } | 
 | 429 |     this->addrs.erase(it); | 
| Ratan Gupta | e05083a | 2017-09-16 07:12:11 +0530 | [diff] [blame] | 430 |     manager.writeToConfigurationFile(); | 
| Ratan Gupta | 82549cc | 2017-04-21 08:45:23 +0530 | [diff] [blame] | 431 | } | 
 | 432 |  | 
| William A. Kennington III | 0850579 | 2019-01-30 16:00:04 -0800 | [diff] [blame] | 433 | void EthernetInterface::deleteStaticNeighborObject(const std::string& iPAddress) | 
 | 434 | { | 
 | 435 |     auto it = staticNeighbors.find(iPAddress); | 
 | 436 |     if (it == staticNeighbors.end()) | 
 | 437 |     { | 
 | 438 |         log<level::ERR>( | 
 | 439 |             "DeleteStaticNeighborObject:Unable to find the object."); | 
 | 440 |         return; | 
 | 441 |     } | 
 | 442 |     staticNeighbors.erase(it); | 
 | 443 |     manager.writeToConfigurationFile(); | 
 | 444 | } | 
 | 445 |  | 
| Ratan Gupta | e9c9b81 | 2017-09-22 17:15:37 +0530 | [diff] [blame] | 446 | void EthernetInterface::deleteVLANFromSystem(const std::string& interface) | 
| Ratan Gupta | bc88629 | 2017-07-25 18:29:57 +0530 | [diff] [blame] | 447 | { | 
| Ratan Gupta | bc88629 | 2017-07-25 18:29:57 +0530 | [diff] [blame] | 448 |     auto confDir = manager.getConfDir(); | 
 | 449 |     fs::path networkFile = confDir; | 
 | 450 |     networkFile /= systemd::config::networkFilePrefix + interface + | 
 | 451 |                    systemd::config::networkFileSuffix; | 
 | 452 |  | 
 | 453 |     fs::path deviceFile = confDir; | 
 | 454 |     deviceFile /= interface + systemd::config::deviceFileSuffix; | 
 | 455 |  | 
 | 456 |     // delete the vlan network file | 
 | 457 |     if (fs::is_regular_file(networkFile)) | 
 | 458 |     { | 
 | 459 |         fs::remove(networkFile); | 
 | 460 |     } | 
 | 461 |  | 
 | 462 |     // delete the vlan device file | 
 | 463 |     if (fs::is_regular_file(deviceFile)) | 
 | 464 |     { | 
 | 465 |         fs::remove(deviceFile); | 
 | 466 |     } | 
| Ratan Gupta | bc88629 | 2017-07-25 18:29:57 +0530 | [diff] [blame] | 467 |  | 
 | 468 |     // TODO  systemd doesn't delete the virtual network interface | 
 | 469 |     // even after deleting all the related configuartion. | 
 | 470 |     // https://github.com/systemd/systemd/issues/6600 | 
 | 471 |     try | 
 | 472 |     { | 
 | 473 |         deleteInterface(interface); | 
 | 474 |     } | 
 | 475 |     catch (InternalFailure& e) | 
 | 476 |     { | 
 | 477 |         commit<InternalFailure>(); | 
 | 478 |     } | 
| Ratan Gupta | e9c9b81 | 2017-09-22 17:15:37 +0530 | [diff] [blame] | 479 | } | 
 | 480 |  | 
 | 481 | void EthernetInterface::deleteVLANObject(const std::string& interface) | 
 | 482 | { | 
 | 483 |     auto it = vlanInterfaces.find(interface); | 
 | 484 |     if (it == vlanInterfaces.end()) | 
 | 485 |     { | 
 | 486 |         log<level::ERR>("DeleteVLANObject:Unable to find the object", | 
| Gunnar Mills | 57d9c50 | 2018-09-14 14:42:34 -0500 | [diff] [blame] | 487 |                         entry("INTERFACE=%s", interface.c_str())); | 
| Ratan Gupta | e9c9b81 | 2017-09-22 17:15:37 +0530 | [diff] [blame] | 488 |         return; | 
 | 489 |     } | 
 | 490 |  | 
 | 491 |     deleteVLANFromSystem(interface); | 
 | 492 |     // delete the interface | 
 | 493 |     vlanInterfaces.erase(it); | 
 | 494 |  | 
| Ratan Gupta | e05083a | 2017-09-16 07:12:11 +0530 | [diff] [blame] | 495 |     manager.writeToConfigurationFile(); | 
| Ratan Gupta | bc88629 | 2017-07-25 18:29:57 +0530 | [diff] [blame] | 496 | } | 
 | 497 |  | 
| Gunnar Mills | 57d9c50 | 2018-09-14 14:42:34 -0500 | [diff] [blame] | 498 | std::string EthernetInterface::generateObjectPath( | 
 | 499 |     IP::Protocol addressType, const std::string& ipaddress, | 
 | 500 |     uint8_t prefixLength, const std::string& gateway) const | 
| Ratan Gupta | 82549cc | 2017-04-21 08:45:23 +0530 | [diff] [blame] | 501 | { | 
| Ratan Gupta | 82549cc | 2017-04-21 08:45:23 +0530 | [diff] [blame] | 502 |     std::string type = convertForMessage(addressType); | 
| Ratan Gupta | 29b0e43 | 2017-05-25 12:51:40 +0530 | [diff] [blame] | 503 |     type = type.substr(type.rfind('.') + 1); | 
| Ratan Gupta | 82549cc | 2017-04-21 08:45:23 +0530 | [diff] [blame] | 504 |     std::transform(type.begin(), type.end(), type.begin(), ::tolower); | 
 | 505 |  | 
| Manojkiran Eda | a879baa | 2020-06-13 14:39:08 +0530 | [diff] [blame] | 506 |     std::filesystem::path objectPath; | 
| Ratan Gupta | 47722dc | 2017-05-26 18:32:23 +0530 | [diff] [blame] | 507 |     objectPath /= objPath; | 
| Ratan Gupta | 82549cc | 2017-04-21 08:45:23 +0530 | [diff] [blame] | 508 |     objectPath /= type; | 
| Ratan Gupta | 29b0e43 | 2017-05-25 12:51:40 +0530 | [diff] [blame] | 509 |     objectPath /= generateId(ipaddress, prefixLength, gateway); | 
| Ratan Gupta | 82549cc | 2017-04-21 08:45:23 +0530 | [diff] [blame] | 510 |     return objectPath.string(); | 
| Ratan Gupta | 2eff84f | 2017-04-20 19:19:15 +0530 | [diff] [blame] | 511 | } | 
 | 512 |  | 
| William A. Kennington III | 0850579 | 2019-01-30 16:00:04 -0800 | [diff] [blame] | 513 | std::string EthernetInterface::generateStaticNeighborObjectPath( | 
 | 514 |     const std::string& iPAddress, const std::string& mACAddress) const | 
 | 515 | { | 
| Manojkiran Eda | a879baa | 2020-06-13 14:39:08 +0530 | [diff] [blame] | 516 |     std::filesystem::path objectPath; | 
| William A. Kennington III | 0850579 | 2019-01-30 16:00:04 -0800 | [diff] [blame] | 517 |     objectPath /= objPath; | 
 | 518 |     objectPath /= "static_neighbor"; | 
 | 519 |     objectPath /= generateNeighborId(iPAddress, mACAddress); | 
 | 520 |     return objectPath.string(); | 
 | 521 | } | 
 | 522 |  | 
| Johnathan Mantey | 5b023f5 | 2019-06-24 16:06:37 -0700 | [diff] [blame] | 523 | bool EthernetInterface::iPv6AcceptRA(bool value) | 
 | 524 | { | 
 | 525 |     if (value == EthernetInterfaceIntf::iPv6AcceptRA()) | 
 | 526 |     { | 
 | 527 |         return value; | 
 | 528 |     } | 
 | 529 |     EthernetInterfaceIntf::iPv6AcceptRA(value); | 
 | 530 |     manager.writeToConfigurationFile(); | 
 | 531 |     return value; | 
 | 532 | } | 
 | 533 |  | 
| Johnathan Mantey | 817012a | 2020-01-30 15:07:39 -0800 | [diff] [blame] | 534 | EthernetInterface::DHCPConf EthernetInterface::dHCPEnabled(DHCPConf value) | 
| Ratan Gupta | 87c1398 | 2017-06-15 09:27:27 +0530 | [diff] [blame] | 535 | { | 
| Ratan Gupta | 5978dd1 | 2017-07-25 13:47:13 +0530 | [diff] [blame] | 536 |     if (value == EthernetInterfaceIntf::dHCPEnabled()) | 
 | 537 |     { | 
 | 538 |         return value; | 
 | 539 |     } | 
 | 540 |  | 
| Ratan Gupta | 87c1398 | 2017-06-15 09:27:27 +0530 | [diff] [blame] | 541 |     EthernetInterfaceIntf::dHCPEnabled(value); | 
| Ratan Gupta | e05083a | 2017-09-16 07:12:11 +0530 | [diff] [blame] | 542 |     manager.writeToConfigurationFile(); | 
| Ratan Gupta | 87c1398 | 2017-06-15 09:27:27 +0530 | [diff] [blame] | 543 |     return value; | 
 | 544 | } | 
 | 545 |  | 
| Johnathan Mantey | faa72e5 | 2020-01-08 10:38:58 -0800 | [diff] [blame] | 546 | bool EthernetInterface::linkUp() const | 
 | 547 | { | 
 | 548 |     EthernetIntfSocket eifSocket(PF_INET, SOCK_DGRAM, IPPROTO_IP); | 
 | 549 |     bool value = EthernetInterfaceIntf::linkUp(); | 
 | 550 |  | 
 | 551 |     if (eifSocket.sock < 0) | 
 | 552 |     { | 
 | 553 |         return value; | 
 | 554 |     } | 
 | 555 |  | 
 | 556 |     ifreq ifr{0}; | 
 | 557 |     std::strncpy(ifr.ifr_name, interfaceName().c_str(), IF_NAMESIZE - 1); | 
 | 558 |     if (ioctl(eifSocket.sock, SIOCGIFFLAGS, &ifr) == 0) | 
 | 559 |     { | 
 | 560 |         value = static_cast<bool>(ifr.ifr_flags & IFF_RUNNING); | 
 | 561 |     } | 
 | 562 |     else | 
 | 563 |     { | 
 | 564 |         log<level::ERR>("ioctl failed for SIOCGIFFLAGS:", | 
 | 565 |                         entry("ERROR=%s", strerror(errno))); | 
 | 566 |     } | 
| Johnathan Mantey | d0679f9 | 2019-10-29 16:20:28 -0700 | [diff] [blame] | 567 |     return value; | 
 | 568 | } | 
 | 569 |  | 
 | 570 | bool EthernetInterface::nICEnabled() const | 
 | 571 | { | 
 | 572 |     EthernetIntfSocket eifSocket(PF_INET, SOCK_DGRAM, IPPROTO_IP); | 
 | 573 |     bool value = EthernetInterfaceIntf::nICEnabled(); | 
 | 574 |  | 
 | 575 |     if (eifSocket.sock < 0) | 
 | 576 |     { | 
 | 577 |         return value; | 
 | 578 |     } | 
 | 579 |  | 
 | 580 |     ifreq ifr{0}; | 
 | 581 |     std::strncpy(ifr.ifr_name, interfaceName().c_str(), IF_NAMESIZE - 1); | 
 | 582 |     if (ioctl(eifSocket.sock, SIOCGIFFLAGS, &ifr) == 0) | 
 | 583 |     { | 
 | 584 |         value = static_cast<bool>(ifr.ifr_flags & IFF_UP); | 
 | 585 |     } | 
 | 586 |     else | 
 | 587 |     { | 
 | 588 |         log<level::ERR>("ioctl failed for SIOCGIFFLAGS:", | 
 | 589 |                         entry("ERROR=%s", strerror(errno))); | 
 | 590 |     } | 
 | 591 |     return value; | 
 | 592 | } | 
 | 593 |  | 
 | 594 | bool EthernetInterface::nICEnabled(bool value) | 
 | 595 | { | 
 | 596 |     if (value == EthernetInterfaceIntf::nICEnabled()) | 
 | 597 |     { | 
 | 598 |         return value; | 
 | 599 |     } | 
 | 600 |  | 
 | 601 |     EthernetIntfSocket eifSocket(PF_INET, SOCK_DGRAM, IPPROTO_IP); | 
 | 602 |     if (eifSocket.sock < 0) | 
 | 603 |     { | 
 | 604 |         return EthernetInterfaceIntf::nICEnabled(); | 
 | 605 |     } | 
 | 606 |  | 
 | 607 |     ifreq ifr{0}; | 
 | 608 |     std::strncpy(ifr.ifr_name, interfaceName().c_str(), IF_NAMESIZE - 1); | 
 | 609 |     if (ioctl(eifSocket.sock, SIOCGIFFLAGS, &ifr) != 0) | 
 | 610 |     { | 
 | 611 |         log<level::ERR>("ioctl failed for SIOCGIFFLAGS:", | 
 | 612 |                         entry("ERROR=%s", strerror(errno))); | 
 | 613 |         return EthernetInterfaceIntf::nICEnabled(); | 
 | 614 |     } | 
 | 615 |  | 
 | 616 |     ifr.ifr_flags &= ~IFF_UP; | 
 | 617 |     ifr.ifr_flags |= value ? IFF_UP : 0; | 
 | 618 |  | 
 | 619 |     if (ioctl(eifSocket.sock, SIOCSIFFLAGS, &ifr) != 0) | 
 | 620 |     { | 
 | 621 |         log<level::ERR>("ioctl failed for SIOCSIFFLAGS:", | 
 | 622 |                         entry("ERROR=%s", strerror(errno))); | 
 | 623 |         return EthernetInterfaceIntf::nICEnabled(); | 
 | 624 |     } | 
 | 625 |     EthernetInterfaceIntf::nICEnabled(value); | 
 | 626 |     writeConfigurationFile(); | 
| Johnathan Mantey | faa72e5 | 2020-01-08 10:38:58 -0800 | [diff] [blame] | 627 |  | 
 | 628 |     return value; | 
 | 629 | } | 
 | 630 |  | 
| Manojkiran Eda | aa57fa5 | 2020-06-13 14:59:53 +0530 | [diff] [blame] | 631 | ServerList EthernetInterface::nameservers(ServerList /*value*/) | 
| Ratan Gupta | 6dec390 | 2017-08-20 15:28:12 +0530 | [diff] [blame] | 632 | { | 
| Manojkiran Eda | acd6dd5 | 2019-10-15 15:00:51 +0530 | [diff] [blame] | 633 |     elog<NotAllowed>(NotAllowedArgument::REASON("ReadOnly Property")); | 
 | 634 |     return EthernetInterfaceIntf::nameservers(); | 
 | 635 | } | 
 | 636 |  | 
 | 637 | ServerList EthernetInterface::staticNameServers(ServerList value) | 
 | 638 | { | 
| Manojkiran Eda | 5fb6c33 | 2019-08-21 16:37:29 +0530 | [diff] [blame] | 639 |     for (const auto& nameserverip : value) | 
 | 640 |     { | 
 | 641 |         if (!isValidIP(AF_INET, nameserverip) && | 
 | 642 |             !isValidIP(AF_INET6, nameserverip)) | 
 | 643 |         { | 
 | 644 |             log<level::ERR>("Not a valid IP address"), | 
 | 645 |                 entry("ADDRESS=%s", nameserverip.c_str()); | 
 | 646 |             elog<InvalidArgument>( | 
| Manojkiran Eda | acd6dd5 | 2019-10-15 15:00:51 +0530 | [diff] [blame] | 647 |                 Argument::ARGUMENT_NAME("StaticNameserver"), | 
| Manojkiran Eda | 5fb6c33 | 2019-08-21 16:37:29 +0530 | [diff] [blame] | 648 |                 Argument::ARGUMENT_VALUE(nameserverip.c_str())); | 
 | 649 |         } | 
 | 650 |     } | 
| Ratan Gupta | 6dec390 | 2017-08-20 15:28:12 +0530 | [diff] [blame] | 651 |     try | 
 | 652 |     { | 
| Manojkiran Eda | acd6dd5 | 2019-10-15 15:00:51 +0530 | [diff] [blame] | 653 |         EthernetInterfaceIntf::staticNameServers(value); | 
| Ratan Gupta | 6dec390 | 2017-08-20 15:28:12 +0530 | [diff] [blame] | 654 |         writeConfigurationFile(); | 
| Ratan Gupta | b400597 | 2019-09-19 06:19:16 +0530 | [diff] [blame] | 655 |         // resolved reads the DNS server configuration from the | 
 | 656 |         // network file. | 
 | 657 |         manager.restartSystemdUnit(networkdService); | 
| Ratan Gupta | 6dec390 | 2017-08-20 15:28:12 +0530 | [diff] [blame] | 658 |     } | 
 | 659 |     catch (InternalFailure& e) | 
 | 660 |     { | 
 | 661 |         log<level::ERR>("Exception processing DNS entries"); | 
 | 662 |     } | 
| Manojkiran Eda | acd6dd5 | 2019-10-15 15:00:51 +0530 | [diff] [blame] | 663 |     return EthernetInterfaceIntf::staticNameServers(); | 
| Ratan Gupta | 6dec390 | 2017-08-20 15:28:12 +0530 | [diff] [blame] | 664 | } | 
 | 665 |  | 
| Manojkiran Eda | acd6dd5 | 2019-10-15 15:00:51 +0530 | [diff] [blame] | 666 | void EthernetInterface::loadNameServers() | 
 | 667 | { | 
 | 668 |     EthernetInterfaceIntf::nameservers(getNameServerFromResolvd()); | 
 | 669 |     EthernetInterfaceIntf::staticNameServers(getstaticNameServerFromConf()); | 
 | 670 | } | 
 | 671 |  | 
 | 672 | ServerList EthernetInterface::getstaticNameServerFromConf() | 
| Ratan Gupta | 6dec390 | 2017-08-20 15:28:12 +0530 | [diff] [blame] | 673 | { | 
 | 674 |     fs::path confPath = manager.getConfDir(); | 
 | 675 |  | 
 | 676 |     std::string fileName = systemd::config::networkFilePrefix + | 
| Gunnar Mills | 57d9c50 | 2018-09-14 14:42:34 -0500 | [diff] [blame] | 677 |                            interfaceName() + systemd::config::networkFileSuffix; | 
| Ratan Gupta | 6dec390 | 2017-08-20 15:28:12 +0530 | [diff] [blame] | 678 |     confPath /= fileName; | 
 | 679 |     ServerList servers; | 
| Ratan Gupta | c27170a | 2017-11-22 15:44:42 +0530 | [diff] [blame] | 680 |     config::Parser parser(confPath.string()); | 
 | 681 |     auto rc = config::ReturnCode::SUCCESS; | 
 | 682 |  | 
 | 683 |     std::tie(rc, servers) = parser.getValues("Network", "DNS"); | 
 | 684 |     if (rc != config::ReturnCode::SUCCESS) | 
| Ratan Gupta | 6dec390 | 2017-08-20 15:28:12 +0530 | [diff] [blame] | 685 |     { | 
| Ratan Gupta | c27170a | 2017-11-22 15:44:42 +0530 | [diff] [blame] | 686 |         log<level::DEBUG>("Unable to get the value for network[DNS]", | 
 | 687 |                           entry("RC=%d", rc)); | 
| Ratan Gupta | 6dec390 | 2017-08-20 15:28:12 +0530 | [diff] [blame] | 688 |     } | 
 | 689 |     return servers; | 
 | 690 | } | 
 | 691 |  | 
| Manojkiran Eda | acd6dd5 | 2019-10-15 15:00:51 +0530 | [diff] [blame] | 692 | ServerList EthernetInterface::getNameServerFromResolvd() | 
 | 693 | { | 
 | 694 |     ServerList servers; | 
 | 695 |     std::string OBJ_PATH = RESOLVED_SERVICE_PATH + std::to_string(ifIndex()); | 
 | 696 |  | 
 | 697 |     /* | 
 | 698 |       The DNS property under org.freedesktop.resolve1.Link interface contains | 
 | 699 |       an array containing all DNS servers currently used by resolved. It | 
 | 700 |       contains similar information as the DNS server data written to | 
 | 701 |       /run/systemd/resolve/resolv.conf. | 
 | 702 |  | 
 | 703 |       Each structure in the array consists of a numeric network interface index, | 
 | 704 |       an address family, and a byte array containing the DNS server address | 
 | 705 |       (either 4 bytes in length for IPv4 or 16 bytes in lengths for IPv6). | 
 | 706 |       The array contains DNS servers configured system-wide, including those | 
 | 707 |       possibly read from a foreign /etc/resolv.conf or the DNS= setting in | 
 | 708 |       /etc/systemd/resolved.conf, as well as per-interface DNS server | 
 | 709 |       information either retrieved from systemd-networkd or configured by | 
 | 710 |       external software via SetLinkDNS(). | 
 | 711 |     */ | 
 | 712 |  | 
 | 713 |     using type = std::vector<std::tuple<int32_t, std::vector<uint8_t>>>; | 
 | 714 |     std::variant<type> name; // Variable to capture the DNS property | 
 | 715 |     auto method = bus.new_method_call(RESOLVED_SERVICE, OBJ_PATH.c_str(), | 
 | 716 |                                       PROPERTY_INTERFACE, METHOD_GET); | 
 | 717 |  | 
 | 718 |     method.append(RESOLVED_INTERFACE, "DNS"); | 
 | 719 |     auto reply = bus.call(method); | 
 | 720 |  | 
 | 721 |     try | 
 | 722 |     { | 
 | 723 |         reply.read(name); | 
 | 724 |     } | 
 | 725 |     catch (const sdbusplus::exception::SdBusError& e) | 
 | 726 |     { | 
 | 727 |         log<level::ERR>("Failed to get DNS information from Systemd-Resolved"); | 
 | 728 |     } | 
 | 729 |     auto tupleVector = std::get_if<type>(&name); | 
 | 730 |     for (auto i = tupleVector->begin(); i != tupleVector->end(); ++i) | 
 | 731 |     { | 
 | 732 |         std::vector<uint8_t> ipaddress = std::get<1>(*i); | 
 | 733 |         std::string address; | 
 | 734 |         for (auto byte : ipaddress) | 
 | 735 |         { | 
 | 736 |             address += std::to_string(byte) + "."; | 
 | 737 |         } | 
 | 738 |         address.pop_back(); | 
 | 739 |         servers.push_back(address); | 
 | 740 |     } | 
 | 741 |     return servers; | 
 | 742 | } | 
 | 743 |  | 
| Ratan Gupta | 92bc2fe | 2017-07-26 22:40:21 +0530 | [diff] [blame] | 744 | void EthernetInterface::loadVLAN(VlanId id) | 
 | 745 | { | 
| Gunnar Mills | 57d9c50 | 2018-09-14 14:42:34 -0500 | [diff] [blame] | 746 |     std::string vlanInterfaceName = interfaceName() + "." + std::to_string(id); | 
| Ratan Gupta | 92bc2fe | 2017-07-26 22:40:21 +0530 | [diff] [blame] | 747 |     std::string path = objPath; | 
 | 748 |     path += "_" + std::to_string(id); | 
 | 749 |  | 
| Johnathan Mantey | 817012a | 2020-01-30 15:07:39 -0800 | [diff] [blame] | 750 |     DHCPConf dhcpEnabled = | 
| Gunnar Mills | 57d9c50 | 2018-09-14 14:42:34 -0500 | [diff] [blame] | 751 |         getDHCPValue(manager.getConfDir().string(), vlanInterfaceName); | 
| Ratan Gupta | 92bc2fe | 2017-07-26 22:40:21 +0530 | [diff] [blame] | 752 |     auto vlanIntf = std::make_unique<phosphor::network::VlanInterface>( | 
| Johnathan Mantey | 817012a | 2020-01-30 15:07:39 -0800 | [diff] [blame] | 753 |         bus, path.c_str(), dhcpEnabled, EthernetInterfaceIntf::nICEnabled(), id, | 
 | 754 |         *this, manager); | 
| Ratan Gupta | 92bc2fe | 2017-07-26 22:40:21 +0530 | [diff] [blame] | 755 |  | 
| Gunnar Mills | 57d9c50 | 2018-09-14 14:42:34 -0500 | [diff] [blame] | 756 |     // Fetch the ip address from the system | 
 | 757 |     // and create the dbus object. | 
| Ratan Gupta | 92bc2fe | 2017-07-26 22:40:21 +0530 | [diff] [blame] | 758 |     vlanIntf->createIPAddressObjects(); | 
| William A. Kennington III | 0850579 | 2019-01-30 16:00:04 -0800 | [diff] [blame] | 759 |     vlanIntf->createStaticNeighborObjects(); | 
| Ratan Gupta | 92bc2fe | 2017-07-26 22:40:21 +0530 | [diff] [blame] | 760 |  | 
 | 761 |     this->vlanInterfaces.emplace(std::move(vlanInterfaceName), | 
 | 762 |                                  std::move(vlanIntf)); | 
 | 763 | } | 
 | 764 |  | 
| William A. Kennington III | f4b4ff8 | 2019-04-09 19:06:52 -0700 | [diff] [blame] | 765 | ObjectPath EthernetInterface::createVLAN(VlanId id) | 
| Ratan Gupta | 5978dd1 | 2017-07-25 13:47:13 +0530 | [diff] [blame] | 766 | { | 
| Gunnar Mills | 57d9c50 | 2018-09-14 14:42:34 -0500 | [diff] [blame] | 767 |     std::string vlanInterfaceName = interfaceName() + "." + std::to_string(id); | 
| Ratan Gupta | 5978dd1 | 2017-07-25 13:47:13 +0530 | [diff] [blame] | 768 |     std::string path = objPath; | 
 | 769 |     path += "_" + std::to_string(id); | 
 | 770 |  | 
| Manojkiran Eda | ca8b91b | 2020-05-28 09:28:42 +0530 | [diff] [blame] | 771 |     // Pass the parents nICEnabled property, so that the child | 
 | 772 |     // VLAN interface can inherit. | 
 | 773 |  | 
| Ratan Gupta | 5978dd1 | 2017-07-25 13:47:13 +0530 | [diff] [blame] | 774 |     auto vlanIntf = std::make_unique<phosphor::network::VlanInterface>( | 
| Johnathan Mantey | 817012a | 2020-01-30 15:07:39 -0800 | [diff] [blame] | 775 |         bus, path.c_str(), EthernetInterface::DHCPConf::none, | 
 | 776 |         EthernetInterfaceIntf::nICEnabled(), id, *this, manager); | 
| Ratan Gupta | 5978dd1 | 2017-07-25 13:47:13 +0530 | [diff] [blame] | 777 |  | 
 | 778 |     // write the device file for the vlan interface. | 
 | 779 |     vlanIntf->writeDeviceFile(); | 
 | 780 |  | 
| Gunnar Mills | 57d9c50 | 2018-09-14 14:42:34 -0500 | [diff] [blame] | 781 |     this->vlanInterfaces.emplace(vlanInterfaceName, std::move(vlanIntf)); | 
| Ratan Gupta | 5978dd1 | 2017-07-25 13:47:13 +0530 | [diff] [blame] | 782 |     // write the new vlan device entry to the configuration(network) file. | 
| Ratan Gupta | e05083a | 2017-09-16 07:12:11 +0530 | [diff] [blame] | 783 |     manager.writeToConfigurationFile(); | 
| William A. Kennington III | f4b4ff8 | 2019-04-09 19:06:52 -0700 | [diff] [blame] | 784 |  | 
 | 785 |     return path; | 
| Ratan Gupta | 5978dd1 | 2017-07-25 13:47:13 +0530 | [diff] [blame] | 786 | } | 
| Ratan Gupta | 2b10653 | 2017-07-25 16:05:02 +0530 | [diff] [blame] | 787 |  | 
| Johnathan Mantey | 5b023f5 | 2019-06-24 16:06:37 -0700 | [diff] [blame] | 788 | bool EthernetInterface::getIPv6AcceptRAFromConf() | 
 | 789 | { | 
 | 790 |     fs::path confPath = manager.getConfDir(); | 
 | 791 |  | 
 | 792 |     std::string fileName = systemd::config::networkFilePrefix + | 
 | 793 |                            interfaceName() + systemd::config::networkFileSuffix; | 
 | 794 |     confPath /= fileName; | 
 | 795 |     config::ValueList values; | 
 | 796 |     config::Parser parser(confPath.string()); | 
 | 797 |     auto rc = config::ReturnCode::SUCCESS; | 
 | 798 |     std::tie(rc, values) = parser.getValues("Network", "IPv6AcceptRA"); | 
 | 799 |     if (rc != config::ReturnCode::SUCCESS) | 
 | 800 |     { | 
 | 801 |         log<level::DEBUG>("Unable to get the value for Network[IPv6AcceptRA]", | 
 | 802 |                           entry("rc=%d", rc)); | 
 | 803 |         return false; | 
 | 804 |     } | 
 | 805 |     return (values[0] == "true"); | 
 | 806 | } | 
 | 807 |  | 
| Ratan Gupta | 497c0c9 | 2017-08-22 19:15:59 +0530 | [diff] [blame] | 808 | ServerList EthernetInterface::getNTPServersFromConf() | 
 | 809 | { | 
 | 810 |     fs::path confPath = manager.getConfDir(); | 
 | 811 |  | 
| Gunnar Mills | 57d9c50 | 2018-09-14 14:42:34 -0500 | [diff] [blame] | 812 |     std::string fileName = systemd::config::networkFilePrefix + | 
 | 813 |                            interfaceName() + systemd::config::networkFileSuffix; | 
| Ratan Gupta | 497c0c9 | 2017-08-22 19:15:59 +0530 | [diff] [blame] | 814 |     confPath /= fileName; | 
| Ratan Gupta | c27170a | 2017-11-22 15:44:42 +0530 | [diff] [blame] | 815 |  | 
| Ratan Gupta | 497c0c9 | 2017-08-22 19:15:59 +0530 | [diff] [blame] | 816 |     ServerList servers; | 
| Ratan Gupta | c27170a | 2017-11-22 15:44:42 +0530 | [diff] [blame] | 817 |     config::Parser parser(confPath.string()); | 
 | 818 |     auto rc = config::ReturnCode::SUCCESS; | 
 | 819 |  | 
 | 820 |     std::tie(rc, servers) = parser.getValues("Network", "NTP"); | 
 | 821 |     if (rc != config::ReturnCode::SUCCESS) | 
| Ratan Gupta | 497c0c9 | 2017-08-22 19:15:59 +0530 | [diff] [blame] | 822 |     { | 
| Ratan Gupta | c27170a | 2017-11-22 15:44:42 +0530 | [diff] [blame] | 823 |         log<level::DEBUG>("Unable to get the value for Network[NTP]", | 
 | 824 |                           entry("rc=%d", rc)); | 
| Ratan Gupta | 497c0c9 | 2017-08-22 19:15:59 +0530 | [diff] [blame] | 825 |     } | 
| Ratan Gupta | c27170a | 2017-11-22 15:44:42 +0530 | [diff] [blame] | 826 |  | 
| Ratan Gupta | 497c0c9 | 2017-08-22 19:15:59 +0530 | [diff] [blame] | 827 |     return servers; | 
 | 828 | } | 
 | 829 |  | 
 | 830 | ServerList EthernetInterface::nTPServers(ServerList servers) | 
 | 831 | { | 
| Gunnar Mills | 57d9c50 | 2018-09-14 14:42:34 -0500 | [diff] [blame] | 832 |     auto ntpServers = EthernetInterfaceIntf::nTPServers(servers); | 
| Ratan Gupta | 497c0c9 | 2017-08-22 19:15:59 +0530 | [diff] [blame] | 833 |  | 
 | 834 |     writeConfigurationFile(); | 
 | 835 |     // timesynchd reads the NTP server configuration from the | 
 | 836 |     // network file. | 
| Ratan Gupta | 895f9e5 | 2018-11-26 20:57:34 +0530 | [diff] [blame] | 837 |     manager.restartSystemdUnit(networkdService); | 
| Ratan Gupta | 497c0c9 | 2017-08-22 19:15:59 +0530 | [diff] [blame] | 838 |     return ntpServers; | 
 | 839 | } | 
| Ratan Gupta | 2b10653 | 2017-07-25 16:05:02 +0530 | [diff] [blame] | 840 | // Need to merge the below function with the code which writes the | 
 | 841 | // config file during factory reset. | 
 | 842 | // TODO openbmc/openbmc#1751 | 
 | 843 |  | 
 | 844 | void EthernetInterface::writeConfigurationFile() | 
 | 845 | { | 
 | 846 |     // write all the static ip address in the systemd-network conf file | 
 | 847 |  | 
 | 848 |     using namespace std::string_literals; | 
| Manojkiran Eda | a879baa | 2020-06-13 14:39:08 +0530 | [diff] [blame] | 849 |     namespace fs = std::filesystem; | 
| Ratan Gupta | e05083a | 2017-09-16 07:12:11 +0530 | [diff] [blame] | 850 |  | 
 | 851 |     // if there is vlan interafce then write the configuration file | 
 | 852 |     // for vlan also. | 
 | 853 |  | 
| Gunnar Mills | 57d9c50 | 2018-09-14 14:42:34 -0500 | [diff] [blame] | 854 |     for (const auto& intf : vlanInterfaces) | 
| Ratan Gupta | e05083a | 2017-09-16 07:12:11 +0530 | [diff] [blame] | 855 |     { | 
 | 856 |         intf.second->writeConfigurationFile(); | 
 | 857 |     } | 
 | 858 |  | 
| Ratan Gupta | 2b10653 | 2017-07-25 16:05:02 +0530 | [diff] [blame] | 859 |     fs::path confPath = manager.getConfDir(); | 
 | 860 |  | 
| Gunnar Mills | 57d9c50 | 2018-09-14 14:42:34 -0500 | [diff] [blame] | 861 |     std::string fileName = systemd::config::networkFilePrefix + | 
 | 862 |                            interfaceName() + systemd::config::networkFileSuffix; | 
| Ratan Gupta | 2b10653 | 2017-07-25 16:05:02 +0530 | [diff] [blame] | 863 |     confPath /= fileName; | 
 | 864 |     std::fstream stream; | 
 | 865 |  | 
 | 866 |     stream.open(confPath.c_str(), std::fstream::out); | 
 | 867 |     if (!stream.is_open()) | 
 | 868 |     { | 
 | 869 |         log<level::ERR>("Unable to open the file", | 
 | 870 |                         entry("FILE=%s", confPath.c_str())); | 
 | 871 |         elog<InternalFailure>(); | 
 | 872 |     } | 
 | 873 |  | 
 | 874 |     // Write the device | 
| Ratan K Gupta | 1a054ae | 2018-09-15 00:49:51 -0400 | [diff] [blame] | 875 |     stream << "[Match]\n"; | 
| Ratan Gupta | 2b10653 | 2017-07-25 16:05:02 +0530 | [diff] [blame] | 876 |     stream << "Name=" << interfaceName() << "\n"; | 
 | 877 |  | 
 | 878 |     auto addrs = getAddresses(); | 
 | 879 |  | 
| William A. Kennington III | 1578721 | 2019-04-23 19:18:01 -0700 | [diff] [blame] | 880 |     // Write the link section | 
 | 881 |     stream << "[Link]\n"; | 
 | 882 |     auto mac = MacAddressIntf::mACAddress(); | 
 | 883 |     if (!mac.empty()) | 
 | 884 |     { | 
 | 885 |         stream << "MACAddress=" << mac << "\n"; | 
 | 886 |     } | 
 | 887 |  | 
| Ratan Gupta | 40a51df | 2020-04-24 15:11:05 +0530 | [diff] [blame] | 888 |     if (!EthernetInterfaceIntf::nICEnabled()) | 
| Johnathan Mantey | d0679f9 | 2019-10-29 16:20:28 -0700 | [diff] [blame] | 889 |     { | 
 | 890 |         stream << "Unmanaged=yes\n"; | 
 | 891 |     } | 
 | 892 |  | 
| Ratan Gupta | 2b10653 | 2017-07-25 16:05:02 +0530 | [diff] [blame] | 893 |     // write the network section | 
| Ratan K Gupta | 1a054ae | 2018-09-15 00:49:51 -0400 | [diff] [blame] | 894 |     stream << "[Network]\n"; | 
| Oskar Senft | ad21fc2 | 2018-07-26 16:32:23 -0400 | [diff] [blame] | 895 | #ifdef LINK_LOCAL_AUTOCONFIGURATION | 
| Nagaraju Goruganti | 24afe36 | 2017-09-21 07:40:26 -0500 | [diff] [blame] | 896 |     stream << "LinkLocalAddressing=yes\n"; | 
| Oskar Senft | ad21fc2 | 2018-07-26 16:32:23 -0400 | [diff] [blame] | 897 | #else | 
 | 898 |     stream << "LinkLocalAddressing=no\n"; | 
 | 899 | #endif | 
| Johnathan Mantey | 5b023f5 | 2019-06-24 16:06:37 -0700 | [diff] [blame] | 900 |     stream << std::boolalpha | 
 | 901 |            << "IPv6AcceptRA=" << EthernetInterfaceIntf::iPv6AcceptRA() << "\n"; | 
| Ratan Gupta | 4f67dac | 2017-08-28 22:18:21 +0530 | [diff] [blame] | 902 |  | 
 | 903 |     // Add the VLAN entry | 
| Gunnar Mills | 57d9c50 | 2018-09-14 14:42:34 -0500 | [diff] [blame] | 904 |     for (const auto& intf : vlanInterfaces) | 
| Ratan Gupta | 4f67dac | 2017-08-28 22:18:21 +0530 | [diff] [blame] | 905 |     { | 
 | 906 |         stream << "VLAN=" << intf.second->EthernetInterface::interfaceName() | 
| Gunnar Mills | 57d9c50 | 2018-09-14 14:42:34 -0500 | [diff] [blame] | 907 |                << "\n"; | 
| Ratan Gupta | 4f67dac | 2017-08-28 22:18:21 +0530 | [diff] [blame] | 908 |     } | 
| Ratan Gupta | 046b2a0 | 2019-09-20 15:49:51 +0530 | [diff] [blame] | 909 |     // Add the NTP server | 
 | 910 |     for (const auto& ntp : EthernetInterfaceIntf::nTPServers()) | 
 | 911 |     { | 
 | 912 |         stream << "NTP=" << ntp << "\n"; | 
 | 913 |     } | 
 | 914 |  | 
 | 915 |     // Add the DNS entry | 
| Manojkiran Eda | acd6dd5 | 2019-10-15 15:00:51 +0530 | [diff] [blame] | 916 |     for (const auto& dns : EthernetInterfaceIntf::staticNameServers()) | 
| Ratan Gupta | 046b2a0 | 2019-09-20 15:49:51 +0530 | [diff] [blame] | 917 |     { | 
 | 918 |         stream << "DNS=" << dns << "\n"; | 
 | 919 |     } | 
 | 920 |  | 
| Nagaraju Goruganti | e8b83ec | 2018-03-26 05:21:45 -0500 | [diff] [blame] | 921 |     // Add the DHCP entry | 
| Johnathan Mantey | 817012a | 2020-01-30 15:07:39 -0800 | [diff] [blame] | 922 |     stream << "DHCP="s + | 
 | 923 |                   mapDHCPToSystemd[EthernetInterfaceIntf::dHCPEnabled()] + "\n"; | 
| Nagaraju Goruganti | e8b83ec | 2018-03-26 05:21:45 -0500 | [diff] [blame] | 924 |  | 
| Johnathan Mantey | 817012a | 2020-01-30 15:07:39 -0800 | [diff] [blame] | 925 |     // Static IP addresses | 
 | 926 |     for (const auto& addr : addrs) | 
| Ratan Gupta | 2b10653 | 2017-07-25 16:05:02 +0530 | [diff] [blame] | 927 |     { | 
| Johnathan Mantey | 817012a | 2020-01-30 15:07:39 -0800 | [diff] [blame] | 928 |         if (originIsManuallyAssigned(addr.second->origin()) && | 
 | 929 |             !dhcpIsEnabled(addr.second->type())) | 
| Nagaraju Goruganti | 210420a | 2018-03-07 09:22:28 -0600 | [diff] [blame] | 930 |         { | 
| Johnathan Mantey | 817012a | 2020-01-30 15:07:39 -0800 | [diff] [blame] | 931 |             // Process all static addresses | 
 | 932 |             std::string address = addr.second->address() + "/" + | 
 | 933 |                                   std::to_string(addr.second->prefixLength()); | 
| Ratan Gupta | 2b10653 | 2017-07-25 16:05:02 +0530 | [diff] [blame] | 934 |  | 
| Johnathan Mantey | 817012a | 2020-01-30 15:07:39 -0800 | [diff] [blame] | 935 |             // build the address entries. Do not use [Network] shortcuts to | 
 | 936 |             // insert address entries. | 
 | 937 |             stream << "[Address]\n"; | 
 | 938 |             stream << "Address=" << address << "\n"; | 
| Nagaraju Goruganti | 210420a | 2018-03-07 09:22:28 -0600 | [diff] [blame] | 939 |         } | 
| Johnathan Mantey | 817012a | 2020-01-30 15:07:39 -0800 | [diff] [blame] | 940 |     } | 
| Nagaraju Goruganti | 210420a | 2018-03-07 09:22:28 -0600 | [diff] [blame] | 941 |  | 
| Johnathan Mantey | 817012a | 2020-01-30 15:07:39 -0800 | [diff] [blame] | 942 |     if (manager.getSystemConf()) | 
 | 943 |     { | 
 | 944 |         stream << "[Route]\n"; | 
 | 945 |         const auto& gateway = manager.getSystemConf()->defaultGateway(); | 
 | 946 |         if (!gateway.empty()) | 
| Nagaraju Goruganti | 210420a | 2018-03-07 09:22:28 -0600 | [diff] [blame] | 947 |         { | 
| Johnathan Mantey | 817012a | 2020-01-30 15:07:39 -0800 | [diff] [blame] | 948 |             stream << "Gateway=" << gateway << "\n"; | 
 | 949 |         } | 
 | 950 |         const auto& gateway6 = manager.getSystemConf()->defaultGateway6(); | 
 | 951 |         if (!gateway6.empty()) | 
 | 952 |         { | 
 | 953 |             stream << "Gateway=" << gateway6 << "\n"; | 
| Nagaraju Goruganti | 210420a | 2018-03-07 09:22:28 -0600 | [diff] [blame] | 954 |         } | 
| Ratan Gupta | 2b10653 | 2017-07-25 16:05:02 +0530 | [diff] [blame] | 955 |     } | 
 | 956 |  | 
| William A. Kennington III | 0850579 | 2019-01-30 16:00:04 -0800 | [diff] [blame] | 957 |     // Write the neighbor sections | 
 | 958 |     for (const auto& neighbor : staticNeighbors) | 
 | 959 |     { | 
 | 960 |         stream << "[Neighbor]" | 
 | 961 |                << "\n"; | 
 | 962 |         stream << "Address=" << neighbor.second->iPAddress() << "\n"; | 
 | 963 |         stream << "MACAddress=" << neighbor.second->mACAddress() << "\n"; | 
 | 964 |     } | 
 | 965 |  | 
| Nagaraju Goruganti | 210420a | 2018-03-07 09:22:28 -0600 | [diff] [blame] | 966 |     // Write the dhcp section irrespective of whether DHCP is enabled or not | 
 | 967 |     writeDHCPSection(stream); | 
 | 968 |  | 
| Ratan Gupta | 2b10653 | 2017-07-25 16:05:02 +0530 | [diff] [blame] | 969 |     stream.close(); | 
| Ratan Gupta | 2b10653 | 2017-07-25 16:05:02 +0530 | [diff] [blame] | 970 | } | 
 | 971 |  | 
 | 972 | void EthernetInterface::writeDHCPSection(std::fstream& stream) | 
 | 973 | { | 
 | 974 |     using namespace std::string_literals; | 
| Ratan Gupta | 2b10653 | 2017-07-25 16:05:02 +0530 | [diff] [blame] | 975 |     // write the dhcp section | 
 | 976 |     stream << "[DHCP]\n"; | 
 | 977 |  | 
 | 978 |     // Hardcoding the client identifier to mac, to address below issue | 
 | 979 |     // https://github.com/openbmc/openbmc/issues/1280 | 
 | 980 |     stream << "ClientIdentifier=mac\n"; | 
 | 981 |     if (manager.getDHCPConf()) | 
 | 982 |     { | 
 | 983 |         auto value = manager.getDHCPConf()->dNSEnabled() ? "true"s : "false"s; | 
 | 984 |         stream << "UseDNS="s + value + "\n"; | 
 | 985 |  | 
 | 986 |         value = manager.getDHCPConf()->nTPEnabled() ? "true"s : "false"s; | 
 | 987 |         stream << "UseNTP="s + value + "\n"; | 
 | 988 |  | 
 | 989 |         value = manager.getDHCPConf()->hostNameEnabled() ? "true"s : "false"s; | 
 | 990 |         stream << "UseHostname="s + value + "\n"; | 
| Nagaraju Goruganti | e8fca1d | 2018-02-05 20:32:45 -0600 | [diff] [blame] | 991 |  | 
 | 992 |         value = | 
 | 993 |             manager.getDHCPConf()->sendHostNameEnabled() ? "true"s : "false"s; | 
 | 994 |         stream << "SendHostname="s + value + "\n"; | 
| Ratan Gupta | 2b10653 | 2017-07-25 16:05:02 +0530 | [diff] [blame] | 995 |     } | 
 | 996 | } | 
 | 997 |  | 
| Ratan Gupta | bd303b1 | 2017-08-18 17:10:07 +0530 | [diff] [blame] | 998 | std::string EthernetInterface::mACAddress(std::string value) | 
 | 999 | { | 
| William A. Kennington III | 1137a97 | 2019-04-20 20:49:58 -0700 | [diff] [blame] | 1000 |     ether_addr newMAC = mac_address::fromString(value); | 
 | 1001 |     if (!mac_address::isUnicast(newMAC)) | 
| Ratan Gupta | bd303b1 | 2017-08-18 17:10:07 +0530 | [diff] [blame] | 1002 |     { | 
| Gunnar Mills | 90480c4 | 2018-06-19 16:02:17 -0500 | [diff] [blame] | 1003 |         log<level::ERR>("MACAddress is not valid.", | 
| Gunnar Mills | 57d9c50 | 2018-09-14 14:42:34 -0500 | [diff] [blame] | 1004 |                         entry("MAC=%s", value.c_str())); | 
| Gunnar Mills | 90480c4 | 2018-06-19 16:02:17 -0500 | [diff] [blame] | 1005 |         elog<InvalidArgument>(Argument::ARGUMENT_NAME("MACAddress"), | 
 | 1006 |                               Argument::ARGUMENT_VALUE(value.c_str())); | 
| Ratan Gupta | bd303b1 | 2017-08-18 17:10:07 +0530 | [diff] [blame] | 1007 |     } | 
 | 1008 |  | 
| Alexander Filippov | 76b2aa3 | 2020-07-10 13:28:55 +0300 | [diff] [blame^] | 1009 |     auto interface = interfaceName(); | 
 | 1010 |  | 
| William A. Kennington III | 1137a97 | 2019-04-20 20:49:58 -0700 | [diff] [blame] | 1011 |     // We don't need to update the system if the address is unchanged | 
 | 1012 |     ether_addr oldMAC = mac_address::fromString(MacAddressIntf::mACAddress()); | 
| William A. Kennington III | 12beaad | 2020-06-13 19:30:41 -0700 | [diff] [blame] | 1013 |     if (!stdplus::raw::equal(newMAC, oldMAC)) | 
| Ratan Gupta | bd303b1 | 2017-08-18 17:10:07 +0530 | [diff] [blame] | 1014 |     { | 
| William A. Kennington III | 1137a97 | 2019-04-20 20:49:58 -0700 | [diff] [blame] | 1015 |         // Update everything that depends on the MAC value | 
 | 1016 |         for (const auto& [name, intf] : vlanInterfaces) | 
| Ratan Gupta | bd303b1 | 2017-08-18 17:10:07 +0530 | [diff] [blame] | 1017 |         { | 
| William A. Kennington III | 1137a97 | 2019-04-20 20:49:58 -0700 | [diff] [blame] | 1018 |             intf->MacAddressIntf::mACAddress(value); | 
| Ratan Gupta | bd303b1 | 2017-08-18 17:10:07 +0530 | [diff] [blame] | 1019 |         } | 
| William A. Kennington III | 1137a97 | 2019-04-20 20:49:58 -0700 | [diff] [blame] | 1020 |         MacAddressIntf::mACAddress(value); | 
| Ratan Gupta | bd303b1 | 2017-08-18 17:10:07 +0530 | [diff] [blame] | 1021 |  | 
| William A. Kennington III | 1578721 | 2019-04-23 19:18:01 -0700 | [diff] [blame] | 1022 |         // TODO: would remove the call below and | 
 | 1023 |         //      just restart systemd-netwokd | 
| William A. Kennington III | 1137a97 | 2019-04-20 20:49:58 -0700 | [diff] [blame] | 1024 |         //      through https://github.com/systemd/systemd/issues/6696 | 
 | 1025 |         execute("/sbin/ip", "ip", "link", "set", "dev", interface.c_str(), | 
 | 1026 |                 "down"); | 
| William A. Kennington III | 1578721 | 2019-04-23 19:18:01 -0700 | [diff] [blame] | 1027 |         manager.writeToConfigurationFile(); | 
| Ratan Gupta | 677ae12 | 2017-09-18 16:28:50 +0530 | [diff] [blame] | 1028 |     } | 
| William A. Kennington III | 1137a97 | 2019-04-20 20:49:58 -0700 | [diff] [blame] | 1029 |  | 
| Alexander Filippov | 76b2aa3 | 2020-07-10 13:28:55 +0300 | [diff] [blame^] | 1030 | #ifdef HAVE_UBOOT_ENV | 
 | 1031 |     // Ensure that the valid address is stored in the u-boot-env | 
 | 1032 |     auto envVar = interfaceToUbootEthAddr(interface.c_str()); | 
 | 1033 |     if (envVar) | 
 | 1034 |     { | 
 | 1035 |         execute("/sbin/fw_setenv", "fw_setenv", envVar->c_str(), value.c_str()); | 
 | 1036 |     } | 
 | 1037 | #endif // HAVE_UBOOT_ENV | 
 | 1038 |  | 
| William A. Kennington III | 1137a97 | 2019-04-20 20:49:58 -0700 | [diff] [blame] | 1039 |     return value; | 
| Ratan Gupta | bd303b1 | 2017-08-18 17:10:07 +0530 | [diff] [blame] | 1040 | } | 
 | 1041 |  | 
| Ratan Gupta | e9c9b81 | 2017-09-22 17:15:37 +0530 | [diff] [blame] | 1042 | void EthernetInterface::deleteAll() | 
 | 1043 | { | 
| Johnathan Mantey | 817012a | 2020-01-30 15:07:39 -0800 | [diff] [blame] | 1044 |     if (dhcpIsEnabled(IP::Protocol::IPv4, true)) | 
| Ratan Gupta | e9c9b81 | 2017-09-22 17:15:37 +0530 | [diff] [blame] | 1045 |     { | 
 | 1046 |         log<level::INFO>("DHCP enabled on the interface"), | 
| Gunnar Mills | 57d9c50 | 2018-09-14 14:42:34 -0500 | [diff] [blame] | 1047 |             entry("INTERFACE=%s", interfaceName().c_str()); | 
| Ratan Gupta | e9c9b81 | 2017-09-22 17:15:37 +0530 | [diff] [blame] | 1048 |     } | 
 | 1049 |  | 
 | 1050 |     // clear all the ip on the interface | 
 | 1051 |     addrs.clear(); | 
 | 1052 |     manager.writeToConfigurationFile(); | 
 | 1053 | } | 
 | 1054 |  | 
| Gunnar Mills | 57d9c50 | 2018-09-14 14:42:34 -0500 | [diff] [blame] | 1055 | } // namespace network | 
 | 1056 | } // namespace phosphor |