blob: e0ebdfc9003621046d0185afa92e4c1cd0981b88 [file] [log] [blame]
Ratan Gupta6811f822017-04-14 16:34:56 +05301#include "config.h"
2#include "network_manager.hpp"
3
4#include <phosphor-logging/log.hpp>
5
6#include <algorithm>
Ratan Gupta738a67f2017-04-21 10:38:05 +05307#include <bitset>
Ratan Gupta82549cc2017-04-21 08:45:23 +05308#include <experimental/filesystem>
Ratan Gupta738a67f2017-04-21 10:38:05 +05309#include <map>
10
Ratan Gupta6811f822017-04-14 16:34:56 +053011#include <arpa/inet.h>
12#include <dirent.h>
13#include <net/if.h>
14
15
16namespace phosphor
17{
18namespace network
19{
Ratan Gupta82549cc2017-04-21 08:45:23 +053020
Ratan Gupta6811f822017-04-14 16:34:56 +053021using namespace phosphor::logging;
Ratan Gupta82549cc2017-04-21 08:45:23 +053022namespace fs = std::experimental::filesystem;
Ratan Gupta6811f822017-04-14 16:34:56 +053023
24Manager::Manager(sdbusplus::bus::bus& bus, const char* objPath):
25 details::VLANCreateIface(bus, objPath, true)
26{
Ratan Gupta82549cc2017-04-21 08:45:23 +053027 auto interfaceInfoList = getInterfaceAddrs();
Ratan Gupta6811f822017-04-14 16:34:56 +053028
Ratan Gupta738a67f2017-04-21 10:38:05 +053029 for (const auto& intfInfo : interfaceInfoList)
30
Ratan Gupta6811f822017-04-14 16:34:56 +053031 {
Ratan Gupta82549cc2017-04-21 08:45:23 +053032
33 fs::path objectPath = std::string(OBJ_NETWORK);
34 objectPath /= intfInfo.first;
Ratan Gupta6811f822017-04-14 16:34:56 +053035
36 this->interfaces.emplace(std::make_pair(
Ratan Gupta738a67f2017-04-21 10:38:05 +053037 intfInfo.first,
38 std::make_unique<
39 phosphor::network::EthernetInterface>
40 (bus,
41 objectPath.string(),
42 false,
43 intfInfo.second)));
Ratan Gupta6811f822017-04-14 16:34:56 +053044 }
45}
46
Ratan Gupta82549cc2017-04-21 08:45:23 +053047void Manager::vLAN(IntfName interfaceName, uint16_t id)
Ratan Gupta6811f822017-04-14 16:34:56 +053048{
49}
50
Ratan Gupta82549cc2017-04-21 08:45:23 +053051IntfAddrMap Manager::getInterfaceAddrs() const
Ratan Gupta6811f822017-04-14 16:34:56 +053052{
Ratan Gupta82549cc2017-04-21 08:45:23 +053053 IntfAddrMap intfMap;
54 AddrList addrList;
Ratan Gupta6811f822017-04-14 16:34:56 +053055 struct ifaddrs* ifaddr;
56 // attempt to fill struct with ifaddrs
57 if (getifaddrs(&ifaddr) == -1)
58 {
59 log<level::ERR>("getifaddrs failed:",
60 entry("ERRNO=%s", strerror(errno)));
61
62 //TODO: openbmc/openbmc#1462 <create the error log>
63
64 return intfMap;
65 }
66
67 details::AddrPtr ifaddrPtr(ifaddr);
68 ifaddr = nullptr;
69
70 std::string intfName;
71
72 for (ifaddrs* ifa = ifaddrPtr.get(); ifa != nullptr; ifa = ifa->ifa_next)
73 {
74 // walk interfaces
75 if (ifa->ifa_addr == nullptr)
76 {
77 continue;
78 }
79
80 // get only INET interfaces not ipv6
81 if (ifa->ifa_addr->sa_family == AF_INET ||
82 ifa->ifa_addr->sa_family == AF_INET6)
83 {
84 // if loopback, or not running ignore
85 if ((ifa->ifa_flags & IFF_LOOPBACK) ||
86 !(ifa->ifa_flags & IFF_RUNNING))
87 {
88 continue;
89 }
90 // if the interface name is not same as the previous
91 // iteration then add the addr list into
92 // the map.
93 if (intfName != "" && intfName != std::string(ifa->ifa_name))
94 {
95 intfMap.emplace(intfName, addrList);
96 addrList.clear();
97 }
98 intfName = ifa->ifa_name;
Ratan Gupta82549cc2017-04-21 08:45:23 +053099 AddrInfo info;
100 char ip[INET6_ADDRSTRLEN] = { 0 };
Ratan Gupta738a67f2017-04-21 10:38:05 +0530101 char subnetMask[INET6_ADDRSTRLEN] = { 0 };
102 uint16_t prefix = { 0 };
Ratan Gupta6811f822017-04-14 16:34:56 +0530103
104 if (ifa->ifa_addr->sa_family == AF_INET)
105 {
106
107 inet_ntop(ifa->ifa_addr->sa_family,
108 &(((struct sockaddr_in*)(ifa->ifa_addr))->sin_addr),
Ratan Gupta82549cc2017-04-21 08:45:23 +0530109 ip,
110 sizeof(ip));
Ratan Gupta738a67f2017-04-21 10:38:05 +0530111
112 inet_ntop(ifa->ifa_addr->sa_family,
113 &(((struct sockaddr_in*)(ifa->ifa_netmask))->sin_addr),
114 subnetMask,
115 sizeof(subnetMask));
116
117 prefix = toCidr(subnetMask);
118
Ratan Gupta6811f822017-04-14 16:34:56 +0530119 }
120 else
121 {
122 inet_ntop(ifa->ifa_addr->sa_family,
123 &(((struct sockaddr_in6*)(ifa->ifa_addr))->sin6_addr),
Ratan Gupta82549cc2017-04-21 08:45:23 +0530124 ip,
125 sizeof(ip));
Ratan Gupta6811f822017-04-14 16:34:56 +0530126
Ratan Gupta738a67f2017-04-21 10:38:05 +0530127 inet_ntop(ifa->ifa_addr->sa_family,
128 &(((struct sockaddr_in6*)(ifa->ifa_netmask))->sin6_addr),
129 subnetMask,
130 sizeof(subnetMask));
131
132 //TODO: convert v6 mask into cidr
133
Ratan Gupta6811f822017-04-14 16:34:56 +0530134 }
135
136 info.addrType = ifa->ifa_addr->sa_family;
Ratan Gupta82549cc2017-04-21 08:45:23 +0530137 info.ipaddress = ip;
Ratan Gupta738a67f2017-04-21 10:38:05 +0530138 info.prefix = prefix;
Ratan Gupta6811f822017-04-14 16:34:56 +0530139 addrList.emplace_back(info);
140 }
141 }
142 intfMap.emplace(intfName, addrList);
143 return intfMap;
144}
Ratan Gupta738a67f2017-04-21 10:38:05 +0530145
146uint8_t Manager::toCidr(const char* subnetMask) const
147{
148 uint32_t buff = 0;
149
150 auto rc = inet_pton(AF_INET, subnetMask, &buff);
151 if (rc <= 0)
152 {
153 log<level::ERR>("inet_pton failed:",
154 entry("Mask=%s", subnetMask));
155 return 0;
156 }
157
158 buff = be32toh(buff);
159 // total no of bits - total no of leading zero == total no of ones
160 if (((sizeof(buff) * 8) - (__builtin_ctz(buff))) == __builtin_popcount(buff))
161 {
162 return __builtin_popcount(buff);
163 }
164 else
165 {
166 log<level::ERR>("Invalid Mask",
167 entry("Mask=%s", subnetMask));
168 return 0;
169 }
170}
Ratan Gupta6811f822017-04-14 16:34:56 +0530171}//namespace network
172}//namespace phosphor