blob: 95e14769745f8872afcda656198222a82af21aad [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 Gupta6811f822017-04-14 16:34:56 +05304
5#include <phosphor-logging/log.hpp>
6
7#include <algorithm>
Ratan Gupta738a67f2017-04-21 10:38:05 +05308#include <bitset>
Ratan Gupta82549cc2017-04-21 08:45:23 +05309#include <experimental/filesystem>
Ratan Gupta738a67f2017-04-21 10:38:05 +053010#include <map>
11
Ratan Gupta6811f822017-04-14 16:34:56 +053012#include <arpa/inet.h>
13#include <dirent.h>
14#include <net/if.h>
15
Michael Tritz29f2fd62017-05-22 15:27:26 -050016#include <string>
Ratan Gupta6811f822017-04-14 16:34:56 +053017
18namespace phosphor
19{
20namespace network
21{
Ratan Gupta82549cc2017-04-21 08:45:23 +053022
Ratan Gupta6811f822017-04-14 16:34:56 +053023using namespace phosphor::logging;
Ratan Gupta82549cc2017-04-21 08:45:23 +053024namespace fs = std::experimental::filesystem;
Ratan Gupta6811f822017-04-14 16:34:56 +053025
26Manager::Manager(sdbusplus::bus::bus& bus, const char* objPath):
27 details::VLANCreateIface(bus, objPath, true)
28{
Ratan Gupta82549cc2017-04-21 08:45:23 +053029 auto interfaceInfoList = getInterfaceAddrs();
Ratan Gupta6811f822017-04-14 16:34:56 +053030
Ratan Gupta738a67f2017-04-21 10:38:05 +053031 for (const auto& intfInfo : interfaceInfoList)
32
Ratan Gupta6811f822017-04-14 16:34:56 +053033 {
Ratan Gupta82549cc2017-04-21 08:45:23 +053034
35 fs::path objectPath = std::string(OBJ_NETWORK);
36 objectPath /= intfInfo.first;
Ratan Gupta6811f822017-04-14 16:34:56 +053037
38 this->interfaces.emplace(std::make_pair(
Ratan Gupta738a67f2017-04-21 10:38:05 +053039 intfInfo.first,
40 std::make_unique<
41 phosphor::network::EthernetInterface>
42 (bus,
43 objectPath.string(),
44 false,
45 intfInfo.second)));
Ratan Gupta6811f822017-04-14 16:34:56 +053046 }
47}
48
Ratan Gupta82549cc2017-04-21 08:45:23 +053049void Manager::vLAN(IntfName interfaceName, uint16_t id)
Ratan Gupta6811f822017-04-14 16:34:56 +053050{
51}
52
Michael Tritz29f2fd62017-05-22 15:27:26 -050053void Manager::reset()
54{
55 const std::string networkConfig = "/etc/systemd/network/";
56 bool filesExist, interfacesMapped = false;
57
58 if(fs::is_directory(networkConfig))
59 {
60 for(auto& file : fs::directory_iterator(networkConfig))
61 {
62 std::string filename = file.path().filename().c_str();
63
64 if(filename.substr(filename.find_last_of(".") + 1) == "network")
65 {
66 fs::remove(file.path());
67 filesExist = true;
68 }
69 }
70
71 if(!filesExist)
72 {
73 log<level::INFO>("No existing network configuration was found.");
74 }
75
76 for (auto& intf : interfaces)
77 {
78 std::string filename = networkConfig + "00-bmc-" + intf.first +
79 ".network";
80
81 bmc::writeDHCPDefault(filename, intf.first);
82 interfacesMapped = true;
83 }
84
85 if(interfacesMapped)
86 {
87 log<level::INFO>("Network configuration reset to DHCP.");
88 }
89 else
90 {
91 log<level::ERR>("No network interfaces are mapped.");
92 // TODO: openbmc/openbmc#1721 - Log ResetFailed error here.
93 }
94 }
95 else
96 {
97 log<level::ERR>("Network configuration directory not found!");
98 // TODO: openbmc/openbmc#1721 - Log ResetFailed error here.
99 }
100
101 return;
102}
103
Ratan Gupta82549cc2017-04-21 08:45:23 +0530104IntfAddrMap Manager::getInterfaceAddrs() const
Ratan Gupta6811f822017-04-14 16:34:56 +0530105{
Ratan Gupta82549cc2017-04-21 08:45:23 +0530106 IntfAddrMap intfMap;
107 AddrList addrList;
Ratan Gupta6811f822017-04-14 16:34:56 +0530108 struct ifaddrs* ifaddr;
109 // attempt to fill struct with ifaddrs
110 if (getifaddrs(&ifaddr) == -1)
111 {
112 log<level::ERR>("getifaddrs failed:",
113 entry("ERRNO=%s", strerror(errno)));
114
115 //TODO: openbmc/openbmc#1462 <create the error log>
116
117 return intfMap;
118 }
119
120 details::AddrPtr ifaddrPtr(ifaddr);
121 ifaddr = nullptr;
122
123 std::string intfName;
124
125 for (ifaddrs* ifa = ifaddrPtr.get(); ifa != nullptr; ifa = ifa->ifa_next)
126 {
127 // walk interfaces
128 if (ifa->ifa_addr == nullptr)
129 {
130 continue;
131 }
132
133 // get only INET interfaces not ipv6
134 if (ifa->ifa_addr->sa_family == AF_INET ||
135 ifa->ifa_addr->sa_family == AF_INET6)
136 {
137 // if loopback, or not running ignore
138 if ((ifa->ifa_flags & IFF_LOOPBACK) ||
139 !(ifa->ifa_flags & IFF_RUNNING))
140 {
141 continue;
142 }
143 // if the interface name is not same as the previous
144 // iteration then add the addr list into
145 // the map.
146 if (intfName != "" && intfName != std::string(ifa->ifa_name))
147 {
148 intfMap.emplace(intfName, addrList);
149 addrList.clear();
150 }
151 intfName = ifa->ifa_name;
Ratan Gupta82549cc2017-04-21 08:45:23 +0530152 AddrInfo info;
153 char ip[INET6_ADDRSTRLEN] = { 0 };
Ratan Gupta738a67f2017-04-21 10:38:05 +0530154 char subnetMask[INET6_ADDRSTRLEN] = { 0 };
155 uint16_t prefix = { 0 };
Ratan Gupta6811f822017-04-14 16:34:56 +0530156
157 if (ifa->ifa_addr->sa_family == AF_INET)
158 {
159
160 inet_ntop(ifa->ifa_addr->sa_family,
161 &(((struct sockaddr_in*)(ifa->ifa_addr))->sin_addr),
Ratan Gupta82549cc2017-04-21 08:45:23 +0530162 ip,
163 sizeof(ip));
Ratan Gupta738a67f2017-04-21 10:38:05 +0530164
165 inet_ntop(ifa->ifa_addr->sa_family,
166 &(((struct sockaddr_in*)(ifa->ifa_netmask))->sin_addr),
167 subnetMask,
168 sizeof(subnetMask));
169
170 prefix = toCidr(subnetMask);
171
Ratan Gupta6811f822017-04-14 16:34:56 +0530172 }
173 else
174 {
175 inet_ntop(ifa->ifa_addr->sa_family,
176 &(((struct sockaddr_in6*)(ifa->ifa_addr))->sin6_addr),
Ratan Gupta82549cc2017-04-21 08:45:23 +0530177 ip,
178 sizeof(ip));
Ratan Gupta6811f822017-04-14 16:34:56 +0530179
Ratan Gupta738a67f2017-04-21 10:38:05 +0530180 inet_ntop(ifa->ifa_addr->sa_family,
181 &(((struct sockaddr_in6*)(ifa->ifa_netmask))->sin6_addr),
182 subnetMask,
183 sizeof(subnetMask));
184
185 //TODO: convert v6 mask into cidr
186
Ratan Gupta6811f822017-04-14 16:34:56 +0530187 }
188
189 info.addrType = ifa->ifa_addr->sa_family;
Ratan Gupta82549cc2017-04-21 08:45:23 +0530190 info.ipaddress = ip;
Ratan Gupta738a67f2017-04-21 10:38:05 +0530191 info.prefix = prefix;
Ratan Gupta6811f822017-04-14 16:34:56 +0530192 addrList.emplace_back(info);
193 }
194 }
195 intfMap.emplace(intfName, addrList);
196 return intfMap;
197}
Ratan Gupta738a67f2017-04-21 10:38:05 +0530198
199uint8_t Manager::toCidr(const char* subnetMask) const
200{
201 uint32_t buff = 0;
202
203 auto rc = inet_pton(AF_INET, subnetMask, &buff);
204 if (rc <= 0)
205 {
206 log<level::ERR>("inet_pton failed:",
207 entry("Mask=%s", subnetMask));
208 return 0;
209 }
210
211 buff = be32toh(buff);
212 // total no of bits - total no of leading zero == total no of ones
213 if (((sizeof(buff) * 8) - (__builtin_ctz(buff))) == __builtin_popcount(buff))
214 {
215 return __builtin_popcount(buff);
216 }
217 else
218 {
219 log<level::ERR>("Invalid Mask",
220 entry("Mask=%s", subnetMask));
221 return 0;
222 }
223}
Ratan Gupta6811f822017-04-14 16:34:56 +0530224}//namespace network
225}//namespace phosphor