blob: 40fce1d9022e322402079d9003bfe271e68a2976 [file] [log] [blame]
Ratan Gupta6811f822017-04-14 16:34:56 +05301#include "config.h"
2#include "network_manager.hpp"
Michael Tritz29f2fd62017-05-22 15:27:26 -05003#include "network_config.hpp"
Ratan Gupta44ae86e2017-05-15 21:52:14 +05304#include "xyz/openbmc_project/Common/error.hpp"
Ratan Gupta6811f822017-04-14 16:34:56 +05305
6#include <phosphor-logging/log.hpp>
Ratan Gupta44ae86e2017-05-15 21:52:14 +05307#include <phosphor-logging/elog-errors.hpp>
Ratan Gupta6811f822017-04-14 16:34:56 +05308
9#include <algorithm>
Ratan Gupta738a67f2017-04-21 10:38:05 +053010#include <bitset>
Ratan Gupta82549cc2017-04-21 08:45:23 +053011#include <experimental/filesystem>
Ratan Gupta738a67f2017-04-21 10:38:05 +053012#include <map>
13
Ratan Gupta6811f822017-04-14 16:34:56 +053014#include <arpa/inet.h>
15#include <dirent.h>
16#include <net/if.h>
17
Michael Tritz29f2fd62017-05-22 15:27:26 -050018#include <string>
Ratan Gupta6811f822017-04-14 16:34:56 +053019
20namespace phosphor
21{
22namespace network
23{
Ratan Gupta82549cc2017-04-21 08:45:23 +053024
Ratan Gupta6811f822017-04-14 16:34:56 +053025using namespace phosphor::logging;
Ratan Gupta82549cc2017-04-21 08:45:23 +053026namespace fs = std::experimental::filesystem;
Ratan Gupta6811f822017-04-14 16:34:56 +053027
28Manager::Manager(sdbusplus::bus::bus& bus, const char* objPath):
Ratan Gupta29b0e432017-05-25 12:51:40 +053029 details::VLANCreateIface(bus, objPath, true),
30 bus(bus),
31 objectPath(objPath)
Ratan Gupta6811f822017-04-14 16:34:56 +053032{
Ratan Gupta29b0e432017-05-25 12:51:40 +053033}
34
35void Manager::createInterfaces()
36{
37
Ratan Gupta82549cc2017-04-21 08:45:23 +053038 auto interfaceInfoList = getInterfaceAddrs();
Ratan Gupta6811f822017-04-14 16:34:56 +053039
Ratan Gupta738a67f2017-04-21 10:38:05 +053040 for (const auto& intfInfo : interfaceInfoList)
Ratan Gupta6811f822017-04-14 16:34:56 +053041 {
Ratan Gupta29b0e432017-05-25 12:51:40 +053042 fs::path objPath = objectPath;
43 objPath /= intfInfo.first;
Ratan Gupta6811f822017-04-14 16:34:56 +053044
45 this->interfaces.emplace(std::make_pair(
Ratan Gupta738a67f2017-04-21 10:38:05 +053046 intfInfo.first,
47 std::make_unique<
48 phosphor::network::EthernetInterface>
49 (bus,
Ratan Gupta29b0e432017-05-25 12:51:40 +053050 objPath.string(),
51 false)));
52
53 interfaces[intfInfo.first]->setAddressList(intfInfo.second);
Ratan Gupta6811f822017-04-14 16:34:56 +053054 }
55}
56
Ratan Gupta82549cc2017-04-21 08:45:23 +053057void Manager::vLAN(IntfName interfaceName, uint16_t id)
Ratan Gupta6811f822017-04-14 16:34:56 +053058{
59}
60
Michael Tritz29f2fd62017-05-22 15:27:26 -050061void Manager::reset()
62{
63 const std::string networkConfig = "/etc/systemd/network/";
64 bool filesExist, interfacesMapped = false;
65
66 if(fs::is_directory(networkConfig))
67 {
68 for(auto& file : fs::directory_iterator(networkConfig))
69 {
70 std::string filename = file.path().filename().c_str();
71
72 if(filename.substr(filename.find_last_of(".") + 1) == "network")
73 {
74 fs::remove(file.path());
75 filesExist = true;
76 }
77 }
78
79 if(!filesExist)
80 {
81 log<level::INFO>("No existing network configuration was found.");
82 }
83
84 for (auto& intf : interfaces)
85 {
86 std::string filename = networkConfig + "00-bmc-" + intf.first +
87 ".network";
88
89 bmc::writeDHCPDefault(filename, intf.first);
90 interfacesMapped = true;
91 }
92
93 if(interfacesMapped)
94 {
95 log<level::INFO>("Network configuration reset to DHCP.");
96 }
97 else
98 {
99 log<level::ERR>("No network interfaces are mapped.");
100 // TODO: openbmc/openbmc#1721 - Log ResetFailed error here.
101 }
102 }
103 else
104 {
105 log<level::ERR>("Network configuration directory not found!");
106 // TODO: openbmc/openbmc#1721 - Log ResetFailed error here.
107 }
108
109 return;
110}
111
Ratan Gupta82549cc2017-04-21 08:45:23 +0530112IntfAddrMap Manager::getInterfaceAddrs() const
Ratan Gupta6811f822017-04-14 16:34:56 +0530113{
Ratan Gupta8804feb2017-05-25 10:49:57 +0530114 IntfAddrMap intfMap{};
115 AddrList addrList{};
116 struct ifaddrs* ifaddr = nullptr;
Ratan Gupta44ae86e2017-05-15 21:52:14 +0530117
118 using namespace sdbusplus::xyz::openbmc_project::Common::Error;
Ratan Gupta6811f822017-04-14 16:34:56 +0530119 // attempt to fill struct with ifaddrs
120 if (getifaddrs(&ifaddr) == -1)
121 {
Ratan Gupta44ae86e2017-05-15 21:52:14 +0530122 auto error = errno;
123 log<level::ERR>("Error occurred during the getifaddrs call",
124 entry("ERRNO=%s", strerror(error)));
125 elog<InternalFailure>();
Ratan Gupta6811f822017-04-14 16:34:56 +0530126 }
127
128 details::AddrPtr ifaddrPtr(ifaddr);
129 ifaddr = nullptr;
130
Ratan Gupta8804feb2017-05-25 10:49:57 +0530131 std::string intfName{};
Ratan Gupta6811f822017-04-14 16:34:56 +0530132
133 for (ifaddrs* ifa = ifaddrPtr.get(); ifa != nullptr; ifa = ifa->ifa_next)
134 {
135 // walk interfaces
136 if (ifa->ifa_addr == nullptr)
137 {
138 continue;
139 }
140
141 // get only INET interfaces not ipv6
142 if (ifa->ifa_addr->sa_family == AF_INET ||
143 ifa->ifa_addr->sa_family == AF_INET6)
144 {
145 // if loopback, or not running ignore
146 if ((ifa->ifa_flags & IFF_LOOPBACK) ||
147 !(ifa->ifa_flags & IFF_RUNNING))
148 {
149 continue;
150 }
151 // if the interface name is not same as the previous
152 // iteration then add the addr list into
153 // the map.
154 if (intfName != "" && intfName != std::string(ifa->ifa_name))
155 {
156 intfMap.emplace(intfName, addrList);
157 addrList.clear();
158 }
159 intfName = ifa->ifa_name;
Ratan Gupta8804feb2017-05-25 10:49:57 +0530160 AddrInfo info{};
Ratan Gupta82549cc2017-04-21 08:45:23 +0530161 char ip[INET6_ADDRSTRLEN] = { 0 };
Ratan Gupta738a67f2017-04-21 10:38:05 +0530162 char subnetMask[INET6_ADDRSTRLEN] = { 0 };
Ratan Gupta6811f822017-04-14 16:34:56 +0530163
164 if (ifa->ifa_addr->sa_family == AF_INET)
165 {
166
167 inet_ntop(ifa->ifa_addr->sa_family,
168 &(((struct sockaddr_in*)(ifa->ifa_addr))->sin_addr),
Ratan Gupta82549cc2017-04-21 08:45:23 +0530169 ip,
170 sizeof(ip));
Ratan Gupta738a67f2017-04-21 10:38:05 +0530171
172 inet_ntop(ifa->ifa_addr->sa_family,
173 &(((struct sockaddr_in*)(ifa->ifa_netmask))->sin_addr),
174 subnetMask,
175 sizeof(subnetMask));
176
Ratan Gupta6811f822017-04-14 16:34:56 +0530177 }
178 else
179 {
180 inet_ntop(ifa->ifa_addr->sa_family,
181 &(((struct sockaddr_in6*)(ifa->ifa_addr))->sin6_addr),
Ratan Gupta82549cc2017-04-21 08:45:23 +0530182 ip,
183 sizeof(ip));
Ratan Gupta6811f822017-04-14 16:34:56 +0530184
Ratan Gupta738a67f2017-04-21 10:38:05 +0530185 inet_ntop(ifa->ifa_addr->sa_family,
186 &(((struct sockaddr_in6*)(ifa->ifa_netmask))->sin6_addr),
187 subnetMask,
188 sizeof(subnetMask));
189
Ratan Gupta6811f822017-04-14 16:34:56 +0530190 }
191
192 info.addrType = ifa->ifa_addr->sa_family;
Ratan Gupta82549cc2017-04-21 08:45:23 +0530193 info.ipaddress = ip;
Ratan Gupta8804feb2017-05-25 10:49:57 +0530194 info.prefix = toCidr(info.addrType, std::string(subnetMask));
Ratan Gupta6811f822017-04-14 16:34:56 +0530195 addrList.emplace_back(info);
196 }
197 }
198 intfMap.emplace(intfName, addrList);
199 return intfMap;
200}
Ratan Gupta738a67f2017-04-21 10:38:05 +0530201
Ratan Gupta6811f822017-04-14 16:34:56 +0530202}//namespace network
203}//namespace phosphor