| Ratan Gupta | 6811f82 | 2017-04-14 16:34:56 +0530 | [diff] [blame] | 1 | #include "config.h" | 
|  | 2 | #include "network_manager.hpp" | 
|  | 3 |  | 
|  | 4 | #include <phosphor-logging/log.hpp> | 
|  | 5 |  | 
|  | 6 | #include <algorithm> | 
| Ratan Gupta | 738a67f | 2017-04-21 10:38:05 +0530 | [diff] [blame] | 7 | #include <bitset> | 
| Ratan Gupta | 82549cc | 2017-04-21 08:45:23 +0530 | [diff] [blame] | 8 | #include <experimental/filesystem> | 
| Ratan Gupta | 738a67f | 2017-04-21 10:38:05 +0530 | [diff] [blame] | 9 | #include <map> | 
|  | 10 |  | 
| Ratan Gupta | 6811f82 | 2017-04-14 16:34:56 +0530 | [diff] [blame] | 11 | #include <arpa/inet.h> | 
|  | 12 | #include <dirent.h> | 
|  | 13 | #include <net/if.h> | 
|  | 14 |  | 
|  | 15 |  | 
|  | 16 | namespace phosphor | 
|  | 17 | { | 
|  | 18 | namespace network | 
|  | 19 | { | 
| Ratan Gupta | 82549cc | 2017-04-21 08:45:23 +0530 | [diff] [blame] | 20 |  | 
| Ratan Gupta | 6811f82 | 2017-04-14 16:34:56 +0530 | [diff] [blame] | 21 | using namespace phosphor::logging; | 
| Ratan Gupta | 82549cc | 2017-04-21 08:45:23 +0530 | [diff] [blame] | 22 | namespace fs = std::experimental::filesystem; | 
| Ratan Gupta | 6811f82 | 2017-04-14 16:34:56 +0530 | [diff] [blame] | 23 |  | 
|  | 24 | Manager::Manager(sdbusplus::bus::bus& bus, const char* objPath): | 
|  | 25 | details::VLANCreateIface(bus, objPath, true) | 
|  | 26 | { | 
| Ratan Gupta | 82549cc | 2017-04-21 08:45:23 +0530 | [diff] [blame] | 27 | auto interfaceInfoList = getInterfaceAddrs(); | 
| Ratan Gupta | 6811f82 | 2017-04-14 16:34:56 +0530 | [diff] [blame] | 28 |  | 
| Ratan Gupta | 738a67f | 2017-04-21 10:38:05 +0530 | [diff] [blame] | 29 | for (const auto& intfInfo : interfaceInfoList) | 
|  | 30 |  | 
| Ratan Gupta | 6811f82 | 2017-04-14 16:34:56 +0530 | [diff] [blame] | 31 | { | 
| Ratan Gupta | 82549cc | 2017-04-21 08:45:23 +0530 | [diff] [blame] | 32 |  | 
|  | 33 | fs::path objectPath = std::string(OBJ_NETWORK); | 
|  | 34 | objectPath /= intfInfo.first; | 
| Ratan Gupta | 6811f82 | 2017-04-14 16:34:56 +0530 | [diff] [blame] | 35 |  | 
|  | 36 | this->interfaces.emplace(std::make_pair( | 
| Ratan Gupta | 738a67f | 2017-04-21 10:38:05 +0530 | [diff] [blame] | 37 | intfInfo.first, | 
|  | 38 | std::make_unique< | 
|  | 39 | phosphor::network::EthernetInterface> | 
|  | 40 | (bus, | 
|  | 41 | objectPath.string(), | 
|  | 42 | false, | 
|  | 43 | intfInfo.second))); | 
| Ratan Gupta | 6811f82 | 2017-04-14 16:34:56 +0530 | [diff] [blame] | 44 | } | 
|  | 45 | } | 
|  | 46 |  | 
| Ratan Gupta | 82549cc | 2017-04-21 08:45:23 +0530 | [diff] [blame] | 47 | void Manager::vLAN(IntfName interfaceName, uint16_t id) | 
| Ratan Gupta | 6811f82 | 2017-04-14 16:34:56 +0530 | [diff] [blame] | 48 | { | 
|  | 49 | } | 
|  | 50 |  | 
| Ratan Gupta | 82549cc | 2017-04-21 08:45:23 +0530 | [diff] [blame] | 51 | IntfAddrMap Manager::getInterfaceAddrs() const | 
| Ratan Gupta | 6811f82 | 2017-04-14 16:34:56 +0530 | [diff] [blame] | 52 | { | 
| Ratan Gupta | 82549cc | 2017-04-21 08:45:23 +0530 | [diff] [blame] | 53 | IntfAddrMap intfMap; | 
|  | 54 | AddrList addrList; | 
| Ratan Gupta | 6811f82 | 2017-04-14 16:34:56 +0530 | [diff] [blame] | 55 | 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 Gupta | 82549cc | 2017-04-21 08:45:23 +0530 | [diff] [blame] | 99 | AddrInfo info; | 
|  | 100 | char ip[INET6_ADDRSTRLEN] = { 0 }; | 
| Ratan Gupta | 738a67f | 2017-04-21 10:38:05 +0530 | [diff] [blame] | 101 | char subnetMask[INET6_ADDRSTRLEN] = { 0 }; | 
|  | 102 | uint16_t prefix = { 0 }; | 
| Ratan Gupta | 6811f82 | 2017-04-14 16:34:56 +0530 | [diff] [blame] | 103 |  | 
|  | 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 Gupta | 82549cc | 2017-04-21 08:45:23 +0530 | [diff] [blame] | 109 | ip, | 
|  | 110 | sizeof(ip)); | 
| Ratan Gupta | 738a67f | 2017-04-21 10:38:05 +0530 | [diff] [blame] | 111 |  | 
|  | 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 Gupta | 6811f82 | 2017-04-14 16:34:56 +0530 | [diff] [blame] | 119 | } | 
|  | 120 | else | 
|  | 121 | { | 
|  | 122 | inet_ntop(ifa->ifa_addr->sa_family, | 
|  | 123 | &(((struct sockaddr_in6*)(ifa->ifa_addr))->sin6_addr), | 
| Ratan Gupta | 82549cc | 2017-04-21 08:45:23 +0530 | [diff] [blame] | 124 | ip, | 
|  | 125 | sizeof(ip)); | 
| Ratan Gupta | 6811f82 | 2017-04-14 16:34:56 +0530 | [diff] [blame] | 126 |  | 
| Ratan Gupta | 738a67f | 2017-04-21 10:38:05 +0530 | [diff] [blame] | 127 | 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 Gupta | 6811f82 | 2017-04-14 16:34:56 +0530 | [diff] [blame] | 134 | } | 
|  | 135 |  | 
|  | 136 | info.addrType = ifa->ifa_addr->sa_family; | 
| Ratan Gupta | 82549cc | 2017-04-21 08:45:23 +0530 | [diff] [blame] | 137 | info.ipaddress = ip; | 
| Ratan Gupta | 738a67f | 2017-04-21 10:38:05 +0530 | [diff] [blame] | 138 | info.prefix = prefix; | 
| Ratan Gupta | 6811f82 | 2017-04-14 16:34:56 +0530 | [diff] [blame] | 139 | addrList.emplace_back(info); | 
|  | 140 | } | 
|  | 141 | } | 
|  | 142 | intfMap.emplace(intfName, addrList); | 
|  | 143 | return intfMap; | 
|  | 144 | } | 
| Ratan Gupta | 738a67f | 2017-04-21 10:38:05 +0530 | [diff] [blame] | 145 |  | 
|  | 146 | uint8_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 Gupta | 6811f82 | 2017-04-14 16:34:56 +0530 | [diff] [blame] | 171 | }//namespace network | 
|  | 172 | }//namespace phosphor |