| Rapkiewicz, Pawel | 9391bb9 | 2018-03-20 03:12:18 +0100 | [diff] [blame] | 1 | /* | 
 | 2 | // Copyright (c) 2018 Intel Corporation | 
 | 3 | // | 
 | 4 | // Licensed under the Apache License, Version 2.0 (the "License"); | 
 | 5 | // you may not use this file except in compliance with the License. | 
 | 6 | // You may obtain a copy of the License at | 
 | 7 | // | 
 | 8 | //      http://www.apache.org/licenses/LICENSE-2.0 | 
 | 9 | // | 
 | 10 | // Unless required by applicable law or agreed to in writing, software | 
 | 11 | // distributed under the License is distributed on an "AS IS" BASIS, | 
 | 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
 | 13 | // See the License for the specific language governing permissions and | 
 | 14 | // limitations under the License. | 
 | 15 | */ | 
 | 16 | #pragma once | 
 | 17 |  | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 18 | #include <boost/container/flat_map.hpp> | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 19 | #include <boost/container/flat_set.hpp> | 
| Kowalski, Kamil | 179db1d | 2018-04-23 11:12:41 +0200 | [diff] [blame] | 20 | #include <dbus_singleton.hpp> | 
| Kowalski, Kamil | 588c3f0 | 2018-04-03 14:55:27 +0200 | [diff] [blame] | 21 | #include <error_messages.hpp> | 
| Kowalski, Kamil | 179db1d | 2018-04-23 11:12:41 +0200 | [diff] [blame] | 22 | #include <node.hpp> | 
| Ed Tanous | a24526d | 2018-12-10 15:17:59 -0800 | [diff] [blame] | 23 | #include <optional> | 
| Kowalski, Kamil | 588c3f0 | 2018-04-03 14:55:27 +0200 | [diff] [blame] | 24 | #include <utils/json_utils.hpp> | 
| Ed Tanous | abf2add | 2019-01-22 16:40:12 -0800 | [diff] [blame] | 25 | #include <variant> | 
| Rapkiewicz, Pawel | 9391bb9 | 2018-03-20 03:12:18 +0100 | [diff] [blame] | 26 |  | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 27 | namespace redfish | 
 | 28 | { | 
| Rapkiewicz, Pawel | 9391bb9 | 2018-03-20 03:12:18 +0100 | [diff] [blame] | 29 |  | 
 | 30 | /** | 
 | 31 |  * DBus types primitives for several generic DBus interfaces | 
 | 32 |  * TODO(Pawel) consider move this to separate file into boost::dbus | 
 | 33 |  */ | 
| Ed Tanous | aa2e59c | 2018-04-12 12:17:20 -0700 | [diff] [blame] | 34 | using PropertiesMapType = boost::container::flat_map< | 
| Ed Tanous | abf2add | 2019-01-22 16:40:12 -0800 | [diff] [blame] | 35 |     std::string, std::variant<std::string, bool, uint8_t, int16_t, uint16_t, | 
 | 36 |                               int32_t, uint32_t, int64_t, uint64_t, double>>; | 
| Rapkiewicz, Pawel | 9391bb9 | 2018-03-20 03:12:18 +0100 | [diff] [blame] | 37 |  | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 38 | using GetManagedObjects = std::vector<std::pair< | 
| Ed Tanous | aa2e59c | 2018-04-12 12:17:20 -0700 | [diff] [blame] | 39 |     sdbusplus::message::object_path, | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 40 |     std::vector<std::pair< | 
| Ed Tanous | aa2e59c | 2018-04-12 12:17:20 -0700 | [diff] [blame] | 41 |         std::string, | 
 | 42 |         boost::container::flat_map< | 
| Ed Tanous | 029573d | 2019-02-01 10:57:49 -0800 | [diff] [blame^] | 43 |             std::string, sdbusplus::message::variant< | 
 | 44 |                              std::string, bool, uint8_t, int16_t, uint16_t, | 
 | 45 |                              int32_t, uint32_t, int64_t, uint64_t, double, | 
 | 46 |                              std::vector<std::string>>>>>>>; | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 47 |  | 
 | 48 | enum class LinkType | 
 | 49 | { | 
 | 50 |     Local, | 
 | 51 |     Global | 
 | 52 | }; | 
| Rapkiewicz, Pawel | 9391bb9 | 2018-03-20 03:12:18 +0100 | [diff] [blame] | 53 |  | 
 | 54 | /** | 
 | 55 |  * Structure for keeping IPv4 data required by Redfish | 
| Rapkiewicz, Pawel | 9391bb9 | 2018-03-20 03:12:18 +0100 | [diff] [blame] | 56 |  */ | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 57 | struct IPv4AddressData | 
 | 58 | { | 
 | 59 |     std::string id; | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 60 |     std::string address; | 
 | 61 |     std::string domain; | 
 | 62 |     std::string gateway; | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 63 |     std::string netmask; | 
 | 64 |     std::string origin; | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 65 |     LinkType linktype; | 
 | 66 |  | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 67 |     bool operator<(const IPv4AddressData &obj) const | 
 | 68 |     { | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 69 |         return id < obj.id; | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 70 |     } | 
| Rapkiewicz, Pawel | 9391bb9 | 2018-03-20 03:12:18 +0100 | [diff] [blame] | 71 | }; | 
 | 72 |  | 
 | 73 | /** | 
 | 74 |  * Structure for keeping basic single Ethernet Interface information | 
 | 75 |  * available from DBus | 
 | 76 |  */ | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 77 | struct EthernetInterfaceData | 
 | 78 | { | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 79 |     uint32_t speed; | 
 | 80 |     bool auto_neg; | 
 | 81 |     std::string hostname; | 
 | 82 |     std::string default_gateway; | 
 | 83 |     std::string mac_address; | 
| Ed Tanous | a24526d | 2018-12-10 15:17:59 -0800 | [diff] [blame] | 84 |     std::optional<uint32_t> vlan_id; | 
| Ed Tanous | 029573d | 2019-02-01 10:57:49 -0800 | [diff] [blame^] | 85 |     std::vector<std::string> nameservers; | 
| Rapkiewicz, Pawel | 9391bb9 | 2018-03-20 03:12:18 +0100 | [diff] [blame] | 86 | }; | 
 | 87 |  | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 88 | // Helper function that changes bits netmask notation (i.e. /24) | 
 | 89 | // into full dot notation | 
 | 90 | inline std::string getNetmask(unsigned int bits) | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 91 | { | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 92 |     uint32_t value = 0xffffffff << (32 - bits); | 
 | 93 |     std::string netmask = std::to_string((value >> 24) & 0xff) + "." + | 
 | 94 |                           std::to_string((value >> 16) & 0xff) + "." + | 
 | 95 |                           std::to_string((value >> 8) & 0xff) + "." + | 
 | 96 |                           std::to_string(value & 0xff); | 
 | 97 |     return netmask; | 
 | 98 | } | 
| Rapkiewicz, Pawel | 9391bb9 | 2018-03-20 03:12:18 +0100 | [diff] [blame] | 99 |  | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 100 | inline std::string | 
 | 101 |     translateAddressOriginDbusToRedfish(const std::string &inputOrigin, | 
 | 102 |                                         bool isIPv4) | 
 | 103 | { | 
 | 104 |     if (inputOrigin == "xyz.openbmc_project.Network.IP.AddressOrigin.Static") | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 105 |     { | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 106 |         return "Static"; | 
 | 107 |     } | 
 | 108 |     if (inputOrigin == "xyz.openbmc_project.Network.IP.AddressOrigin.LinkLocal") | 
 | 109 |     { | 
 | 110 |         if (isIPv4) | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 111 |         { | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 112 |             return "IPv4LinkLocal"; | 
 | 113 |         } | 
 | 114 |         else | 
 | 115 |         { | 
 | 116 |             return "LinkLocal"; | 
 | 117 |         } | 
 | 118 |     } | 
 | 119 |     if (inputOrigin == "xyz.openbmc_project.Network.IP.AddressOrigin.DHCP") | 
 | 120 |     { | 
 | 121 |         if (isIPv4) | 
 | 122 |         { | 
 | 123 |             return "DHCP"; | 
 | 124 |         } | 
 | 125 |         else | 
 | 126 |         { | 
 | 127 |             return "DHCPv6"; | 
 | 128 |         } | 
 | 129 |     } | 
 | 130 |     if (inputOrigin == "xyz.openbmc_project.Network.IP.AddressOrigin.SLAAC") | 
 | 131 |     { | 
 | 132 |         return "SLAAC"; | 
 | 133 |     } | 
 | 134 |     return ""; | 
 | 135 | } | 
 | 136 |  | 
 | 137 | inline std::string | 
 | 138 |     translateAddressOriginRedfishToDbus(const std::string &inputOrigin) | 
 | 139 | { | 
 | 140 |     if (inputOrigin == "Static") | 
 | 141 |     { | 
 | 142 |         return "xyz.openbmc_project.Network.IP.AddressOrigin.Static"; | 
 | 143 |     } | 
 | 144 |     if (inputOrigin == "DHCP" || inputOrigin == "DHCPv6") | 
 | 145 |     { | 
 | 146 |         return "xyz.openbmc_project.Network.IP.AddressOrigin.DHCP"; | 
 | 147 |     } | 
 | 148 |     if (inputOrigin == "IPv4LinkLocal" || inputOrigin == "LinkLocal") | 
 | 149 |     { | 
 | 150 |         return "xyz.openbmc_project.Network.IP.AddressOrigin.LinkLocal"; | 
 | 151 |     } | 
 | 152 |     if (inputOrigin == "SLAAC") | 
 | 153 |     { | 
 | 154 |         return "xyz.openbmc_project.Network.IP.AddressOrigin.SLAAC"; | 
 | 155 |     } | 
 | 156 |     return ""; | 
 | 157 | } | 
 | 158 |  | 
 | 159 | inline void extractEthernetInterfaceData(const std::string ðiface_id, | 
 | 160 |                                          const GetManagedObjects &dbus_data, | 
 | 161 |                                          EthernetInterfaceData ðData) | 
 | 162 | { | 
 | 163 |     for (const auto &objpath : dbus_data) | 
 | 164 |     { | 
| Ed Tanous | 029573d | 2019-02-01 10:57:49 -0800 | [diff] [blame^] | 165 |         for (const auto &ifacePair : objpath.second) | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 166 |         { | 
| Ed Tanous | 029573d | 2019-02-01 10:57:49 -0800 | [diff] [blame^] | 167 |             if (objpath.first == "/xyz/openbmc_project/network/" + ethiface_id) | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 168 |             { | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 169 |                 if (ifacePair.first == "xyz.openbmc_project.Network.MACAddress") | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 170 |                 { | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 171 |                     for (const auto &propertyPair : ifacePair.second) | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 172 |                     { | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 173 |                         if (propertyPair.first == "MACAddress") | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 174 |                         { | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 175 |                             const std::string *mac = | 
| Ed Tanous | abf2add | 2019-01-22 16:40:12 -0800 | [diff] [blame] | 176 |                                 std::get_if<std::string>(&propertyPair.second); | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 177 |                             if (mac != nullptr) | 
 | 178 |                             { | 
 | 179 |                                 ethData.mac_address = *mac; | 
 | 180 |                             } | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 181 |                         } | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 182 |                     } | 
 | 183 |                 } | 
 | 184 |                 else if (ifacePair.first == "xyz.openbmc_project.Network.VLAN") | 
 | 185 |                 { | 
 | 186 |                     for (const auto &propertyPair : ifacePair.second) | 
 | 187 |                     { | 
 | 188 |                         if (propertyPair.first == "Id") | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 189 |                         { | 
| Ed Tanous | 1b6b96c | 2018-11-30 11:35:41 -0800 | [diff] [blame] | 190 |                             const uint32_t *id = | 
| Ed Tanous | abf2add | 2019-01-22 16:40:12 -0800 | [diff] [blame] | 191 |                                 std::get_if<uint32_t>(&propertyPair.second); | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 192 |                             if (id != nullptr) | 
 | 193 |                             { | 
 | 194 |                                 ethData.vlan_id = *id; | 
 | 195 |                             } | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 196 |                         } | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 197 |                     } | 
 | 198 |                 } | 
 | 199 |                 else if (ifacePair.first == | 
 | 200 |                          "xyz.openbmc_project.Network.EthernetInterface") | 
 | 201 |                 { | 
 | 202 |                     for (const auto &propertyPair : ifacePair.second) | 
 | 203 |                     { | 
 | 204 |                         if (propertyPair.first == "AutoNeg") | 
 | 205 |                         { | 
 | 206 |                             const bool *auto_neg = | 
| Ed Tanous | abf2add | 2019-01-22 16:40:12 -0800 | [diff] [blame] | 207 |                                 std::get_if<bool>(&propertyPair.second); | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 208 |                             if (auto_neg != nullptr) | 
 | 209 |                             { | 
 | 210 |                                 ethData.auto_neg = *auto_neg; | 
 | 211 |                             } | 
 | 212 |                         } | 
 | 213 |                         else if (propertyPair.first == "Speed") | 
 | 214 |                         { | 
 | 215 |                             const uint32_t *speed = | 
| Ed Tanous | abf2add | 2019-01-22 16:40:12 -0800 | [diff] [blame] | 216 |                                 std::get_if<uint32_t>(&propertyPair.second); | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 217 |                             if (speed != nullptr) | 
 | 218 |                             { | 
 | 219 |                                 ethData.speed = *speed; | 
 | 220 |                             } | 
 | 221 |                         } | 
| Ed Tanous | 029573d | 2019-02-01 10:57:49 -0800 | [diff] [blame^] | 222 |                         else if (propertyPair.first == "NameServers") | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 223 |                         { | 
| Ed Tanous | 029573d | 2019-02-01 10:57:49 -0800 | [diff] [blame^] | 224 |                             const std::vector<std::string> *nameservers = | 
 | 225 |                                 sdbusplus::message::variant_ns::get_if< | 
 | 226 |                                     std::vector<std::string>>( | 
 | 227 |                                     &propertyPair.second); | 
 | 228 |                             if (nameservers != nullptr) | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 229 |                             { | 
| Ed Tanous | 029573d | 2019-02-01 10:57:49 -0800 | [diff] [blame^] | 230 |                                 ethData.nameservers = std::move(*nameservers); | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 231 |                             } | 
 | 232 |                         } | 
| Ed Tanous | 029573d | 2019-02-01 10:57:49 -0800 | [diff] [blame^] | 233 |                     } | 
 | 234 |                 } | 
 | 235 |             } | 
 | 236 |             // System configuration shows up in the global namespace, so no need | 
 | 237 |             // to check eth number | 
 | 238 |             if (ifacePair.first == | 
 | 239 |                 "xyz.openbmc_project.Network.SystemConfiguration") | 
 | 240 |             { | 
 | 241 |                 for (const auto &propertyPair : ifacePair.second) | 
 | 242 |                 { | 
 | 243 |                     if (propertyPair.first == "HostName") | 
 | 244 |                     { | 
 | 245 |                         const std::string *hostname = | 
 | 246 |                             sdbusplus::message::variant_ns::get_if<std::string>( | 
 | 247 |                                 &propertyPair.second); | 
 | 248 |                         if (hostname != nullptr) | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 249 |                         { | 
| Ed Tanous | 029573d | 2019-02-01 10:57:49 -0800 | [diff] [blame^] | 250 |                             ethData.hostname = *hostname; | 
 | 251 |                         } | 
 | 252 |                     } | 
 | 253 |                     else if (propertyPair.first == "DefaultGateway") | 
 | 254 |                     { | 
 | 255 |                         const std::string *defaultGateway = | 
 | 256 |                             sdbusplus::message::variant_ns::get_if<std::string>( | 
 | 257 |                                 &propertyPair.second); | 
 | 258 |                         if (defaultGateway != nullptr) | 
 | 259 |                         { | 
 | 260 |                             ethData.default_gateway = *defaultGateway; | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 261 |                         } | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 262 |                     } | 
 | 263 |                 } | 
 | 264 |             } | 
 | 265 |         } | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 266 |     } | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 267 | } | 
 | 268 |  | 
 | 269 | // Helper function that extracts data for single ethernet ipv4 address | 
 | 270 | inline void | 
 | 271 |     extractIPData(const std::string ðiface_id, | 
 | 272 |                   const GetManagedObjects &dbus_data, | 
 | 273 |                   boost::container::flat_set<IPv4AddressData> &ipv4_config) | 
 | 274 | { | 
 | 275 |     const std::string ipv4PathStart = | 
 | 276 |         "/xyz/openbmc_project/network/" + ethiface_id + "/ipv4/"; | 
 | 277 |  | 
 | 278 |     // Since there might be several IPv4 configurations aligned with | 
 | 279 |     // single ethernet interface, loop over all of them | 
 | 280 |     for (const auto &objpath : dbus_data) | 
 | 281 |     { | 
 | 282 |         // Check if proper pattern for object path appears | 
 | 283 |         if (boost::starts_with(objpath.first.str, ipv4PathStart)) | 
 | 284 |         { | 
 | 285 |             for (auto &interface : objpath.second) | 
 | 286 |             { | 
 | 287 |                 if (interface.first == "xyz.openbmc_project.Network.IP") | 
 | 288 |                 { | 
 | 289 |                     // Instance IPv4AddressData structure, and set as | 
 | 290 |                     // appropriate | 
 | 291 |                     std::pair< | 
 | 292 |                         boost::container::flat_set<IPv4AddressData>::iterator, | 
 | 293 |                         bool> | 
 | 294 |                         it = ipv4_config.insert( | 
 | 295 |                             {objpath.first.str.substr(ipv4PathStart.size())}); | 
 | 296 |                     IPv4AddressData &ipv4_address = *it.first; | 
 | 297 |                     for (auto &property : interface.second) | 
 | 298 |                     { | 
 | 299 |                         if (property.first == "Address") | 
 | 300 |                         { | 
 | 301 |                             const std::string *address = | 
| Ed Tanous | abf2add | 2019-01-22 16:40:12 -0800 | [diff] [blame] | 302 |                                 std::get_if<std::string>(&property.second); | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 303 |                             if (address != nullptr) | 
 | 304 |                             { | 
 | 305 |                                 ipv4_address.address = *address; | 
 | 306 |                             } | 
 | 307 |                         } | 
 | 308 |                         else if (property.first == "Gateway") | 
 | 309 |                         { | 
 | 310 |                             const std::string *gateway = | 
| Ed Tanous | abf2add | 2019-01-22 16:40:12 -0800 | [diff] [blame] | 311 |                                 std::get_if<std::string>(&property.second); | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 312 |                             if (gateway != nullptr) | 
 | 313 |                             { | 
 | 314 |                                 ipv4_address.gateway = *gateway; | 
 | 315 |                             } | 
 | 316 |                         } | 
 | 317 |                         else if (property.first == "Origin") | 
 | 318 |                         { | 
 | 319 |                             const std::string *origin = | 
| Ed Tanous | abf2add | 2019-01-22 16:40:12 -0800 | [diff] [blame] | 320 |                                 std::get_if<std::string>(&property.second); | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 321 |                             if (origin != nullptr) | 
 | 322 |                             { | 
 | 323 |                                 ipv4_address.origin = | 
 | 324 |                                     translateAddressOriginDbusToRedfish(*origin, | 
 | 325 |                                                                         true); | 
 | 326 |                             } | 
 | 327 |                         } | 
 | 328 |                         else if (property.first == "PrefixLength") | 
 | 329 |                         { | 
 | 330 |                             const uint8_t *mask = | 
| Ed Tanous | abf2add | 2019-01-22 16:40:12 -0800 | [diff] [blame] | 331 |                                 std::get_if<uint8_t>(&property.second); | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 332 |                             if (mask != nullptr) | 
 | 333 |                             { | 
 | 334 |                                 // convert it to the string | 
 | 335 |                                 ipv4_address.netmask = getNetmask(*mask); | 
 | 336 |                             } | 
 | 337 |                         } | 
 | 338 |                         else | 
 | 339 |                         { | 
 | 340 |                             BMCWEB_LOG_ERROR | 
 | 341 |                                 << "Got extra property: " << property.first | 
 | 342 |                                 << " on the " << objpath.first.str << " object"; | 
 | 343 |                         } | 
 | 344 |                     } | 
 | 345 |                     // Check if given address is local, or global | 
 | 346 |                     ipv4_address.linktype = | 
 | 347 |                         boost::starts_with(ipv4_address.address, "169.254.") | 
 | 348 |                             ? LinkType::Global | 
 | 349 |                             : LinkType::Local; | 
 | 350 |                 } | 
 | 351 |             } | 
 | 352 |         } | 
 | 353 |     } | 
 | 354 | } | 
 | 355 |  | 
 | 356 | /** | 
 | 357 |  * @brief Sets given Id on the given VLAN interface through D-Bus | 
 | 358 |  * | 
 | 359 |  * @param[in] ifaceId       Id of VLAN interface that should be modified | 
 | 360 |  * @param[in] inputVlanId   New ID of the VLAN | 
 | 361 |  * @param[in] callback      Function that will be called after the operation | 
 | 362 |  * | 
 | 363 |  * @return None. | 
 | 364 |  */ | 
 | 365 | template <typename CallbackFunc> | 
 | 366 | void changeVlanId(const std::string &ifaceId, const uint32_t &inputVlanId, | 
 | 367 |                   CallbackFunc &&callback) | 
 | 368 | { | 
 | 369 |     crow::connections::systemBus->async_method_call( | 
 | 370 |         callback, "xyz.openbmc_project.Network", | 
 | 371 |         std::string("/xyz/openbmc_project/network/") + ifaceId, | 
 | 372 |         "org.freedesktop.DBus.Properties", "Set", | 
 | 373 |         "xyz.openbmc_project.Network.VLAN", "Id", | 
| Ed Tanous | abf2add | 2019-01-22 16:40:12 -0800 | [diff] [blame] | 374 |         std::variant<uint32_t>(inputVlanId)); | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 375 | } | 
 | 376 |  | 
 | 377 | /** | 
 | 378 |  * @brief Helper function that verifies IP address to check if it is in | 
 | 379 |  *        proper format. If bits pointer is provided, also calculates active | 
 | 380 |  *        bit count for Subnet Mask. | 
 | 381 |  * | 
 | 382 |  * @param[in]  ip     IP that will be verified | 
 | 383 |  * @param[out] bits   Calculated mask in bits notation | 
 | 384 |  * | 
 | 385 |  * @return true in case of success, false otherwise | 
 | 386 |  */ | 
 | 387 | inline bool ipv4VerifyIpAndGetBitcount(const std::string &ip, | 
 | 388 |                                        uint8_t *bits = nullptr) | 
 | 389 | { | 
 | 390 |     std::vector<std::string> bytesInMask; | 
 | 391 |  | 
 | 392 |     boost::split(bytesInMask, ip, boost::is_any_of(".")); | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 393 |  | 
 | 394 |     static const constexpr int ipV4AddressSectionsCount = 4; | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 395 |     if (bytesInMask.size() != ipV4AddressSectionsCount) | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 396 |     { | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 397 |         return false; | 
 | 398 |     } | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 399 |  | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 400 |     if (bits != nullptr) | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 401 |     { | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 402 |         *bits = 0; | 
 | 403 |     } | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 404 |  | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 405 |     char *endPtr; | 
 | 406 |     long previousValue = 255; | 
 | 407 |     bool firstZeroInByteHit; | 
 | 408 |     for (const std::string &byte : bytesInMask) | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 409 |     { | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 410 |         if (byte.empty()) | 
 | 411 |         { | 
 | 412 |             return false; | 
 | 413 |         } | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 414 |  | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 415 |         // Use strtol instead of stroi to avoid exceptions | 
 | 416 |         long value = std::strtol(byte.c_str(), &endPtr, 10); | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 417 |  | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 418 |         // endPtr should point to the end of the string, otherwise given string | 
 | 419 |         // is not 100% number | 
 | 420 |         if (*endPtr != '\0') | 
 | 421 |         { | 
 | 422 |             return false; | 
 | 423 |         } | 
 | 424 |  | 
 | 425 |         // Value should be contained in byte | 
 | 426 |         if (value < 0 || value > 255) | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 427 |         { | 
 | 428 |             return false; | 
 | 429 |         } | 
 | 430 |  | 
 | 431 |         if (bits != nullptr) | 
 | 432 |         { | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 433 |             // Mask has to be continuous between bytes | 
 | 434 |             if (previousValue != 255 && value != 0) | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 435 |             { | 
 | 436 |                 return false; | 
 | 437 |             } | 
 | 438 |  | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 439 |             // Mask has to be continuous inside bytes | 
 | 440 |             firstZeroInByteHit = false; | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 441 |  | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 442 |             // Count bits | 
 | 443 |             for (int bitIdx = 7; bitIdx >= 0; bitIdx--) | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 444 |             { | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 445 |                 if (value & (1 << bitIdx)) | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 446 |                 { | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 447 |                     if (firstZeroInByteHit) | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 448 |                     { | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 449 |                         // Continuity not preserved | 
 | 450 |                         return false; | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 451 |                     } | 
 | 452 |                     else | 
 | 453 |                     { | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 454 |                         (*bits)++; | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 455 |                     } | 
 | 456 |                 } | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 457 |                 else | 
 | 458 |                 { | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 459 |                     firstZeroInByteHit = true; | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 460 |                 } | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 461 |             } | 
 | 462 |         } | 
 | 463 |  | 
 | 464 |         previousValue = value; | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 465 |     } | 
 | 466 |  | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 467 |     return true; | 
 | 468 | } | 
 | 469 |  | 
 | 470 | /** | 
 | 471 |  * @brief Changes IPv4 address type property (Address, Gateway) | 
 | 472 |  * | 
 | 473 |  * @param[in] ifaceId     Id of interface whose IP should be modified | 
 | 474 |  * @param[in] ipIdx       Index of IP in input array that should be modified | 
 | 475 |  * @param[in] ipHash      DBus Hash id of modified IP | 
 | 476 |  * @param[in] name        Name of field in JSON representation | 
 | 477 |  * @param[in] newValue    New value that should be written | 
 | 478 |  * @param[io] asyncResp   Response object that will be returned to client | 
 | 479 |  * | 
 | 480 |  * @return true if give IP is valid and has been sent do D-Bus, false | 
 | 481 |  * otherwise | 
 | 482 |  */ | 
 | 483 | inline void changeIPv4AddressProperty( | 
 | 484 |     const std::string &ifaceId, int ipIdx, const std::string &ipHash, | 
 | 485 |     const std::string &name, const std::string &newValue, | 
 | 486 |     const std::shared_ptr<AsyncResp> asyncResp) | 
 | 487 | { | 
 | 488 |     auto callback = [asyncResp, ipIdx, name{std::string(name)}, | 
 | 489 |                      newValue{std::move(newValue)}]( | 
 | 490 |                         const boost::system::error_code ec) { | 
 | 491 |         if (ec) | 
 | 492 |         { | 
| Jason M. Bills | a08b46c | 2018-11-06 15:01:08 -0800 | [diff] [blame] | 493 |             messages::internalError(asyncResp->res); | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 494 |         } | 
 | 495 |         else | 
 | 496 |         { | 
 | 497 |             asyncResp->res.jsonValue["IPv4Addresses"][ipIdx][name] = newValue; | 
 | 498 |         } | 
 | 499 |     }; | 
 | 500 |  | 
 | 501 |     crow::connections::systemBus->async_method_call( | 
 | 502 |         std::move(callback), "xyz.openbmc_project.Network", | 
 | 503 |         "/xyz/openbmc_project/network/" + ifaceId + "/ipv4/" + ipHash, | 
 | 504 |         "org.freedesktop.DBus.Properties", "Set", | 
 | 505 |         "xyz.openbmc_project.Network.IP", name, | 
| Ed Tanous | abf2add | 2019-01-22 16:40:12 -0800 | [diff] [blame] | 506 |         std::variant<std::string>(newValue)); | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 507 | } | 
 | 508 |  | 
 | 509 | /** | 
 | 510 |  * @brief Changes IPv4 address origin property | 
 | 511 |  * | 
 | 512 |  * @param[in] ifaceId       Id of interface whose IP should be modified | 
 | 513 |  * @param[in] ipIdx         Index of IP in input array that should be | 
 | 514 |  * modified | 
 | 515 |  * @param[in] ipHash        DBus Hash id of modified IP | 
 | 516 |  * @param[in] newValue      New value in Redfish format | 
 | 517 |  * @param[in] newValueDbus  New value in D-Bus format | 
 | 518 |  * @param[io] asyncResp     Response object that will be returned to client | 
 | 519 |  * | 
 | 520 |  * @return true if give IP is valid and has been sent do D-Bus, false | 
 | 521 |  * otherwise | 
 | 522 |  */ | 
 | 523 | inline void changeIPv4Origin(const std::string &ifaceId, int ipIdx, | 
 | 524 |                              const std::string &ipHash, | 
 | 525 |                              const std::string &newValue, | 
 | 526 |                              const std::string &newValueDbus, | 
 | 527 |                              const std::shared_ptr<AsyncResp> asyncResp) | 
 | 528 | { | 
 | 529 |     auto callback = [asyncResp, ipIdx, newValue{std::move(newValue)}]( | 
 | 530 |                         const boost::system::error_code ec) { | 
 | 531 |         if (ec) | 
 | 532 |         { | 
| Jason M. Bills | a08b46c | 2018-11-06 15:01:08 -0800 | [diff] [blame] | 533 |             messages::internalError(asyncResp->res); | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 534 |         } | 
 | 535 |         else | 
 | 536 |         { | 
 | 537 |             asyncResp->res.jsonValue["IPv4Addresses"][ipIdx]["AddressOrigin"] = | 
 | 538 |                 newValue; | 
 | 539 |         } | 
 | 540 |     }; | 
 | 541 |  | 
 | 542 |     crow::connections::systemBus->async_method_call( | 
 | 543 |         std::move(callback), "xyz.openbmc_project.Network", | 
 | 544 |         "/xyz/openbmc_project/network/" + ifaceId + "/ipv4/" + ipHash, | 
 | 545 |         "org.freedesktop.DBus.Properties", "Set", | 
 | 546 |         "xyz.openbmc_project.Network.IP", "Origin", | 
| Ed Tanous | abf2add | 2019-01-22 16:40:12 -0800 | [diff] [blame] | 547 |         std::variant<std::string>(newValueDbus)); | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 548 | } | 
 | 549 |  | 
 | 550 | /** | 
 | 551 |  * @brief Modifies SubnetMask for given IP | 
 | 552 |  * | 
 | 553 |  * @param[in] ifaceId      Id of interface whose IP should be modified | 
 | 554 |  * @param[in] ipIdx        Index of IP in input array that should be | 
 | 555 |  * modified | 
 | 556 |  * @param[in] ipHash       DBus Hash id of modified IP | 
 | 557 |  * @param[in] newValueStr  Mask in dot notation as string | 
 | 558 |  * @param[in] newValue     Mask as PrefixLength in bitcount | 
 | 559 |  * @param[io] asyncResp   Response object that will be returned to client | 
 | 560 |  * | 
 | 561 |  * @return None | 
 | 562 |  */ | 
 | 563 | inline void changeIPv4SubnetMaskProperty(const std::string &ifaceId, int ipIdx, | 
 | 564 |                                          const std::string &ipHash, | 
 | 565 |                                          const std::string &newValueStr, | 
 | 566 |                                          uint8_t &newValue, | 
 | 567 |                                          std::shared_ptr<AsyncResp> asyncResp) | 
 | 568 | { | 
 | 569 |     auto callback = [asyncResp, ipIdx, newValueStr{std::move(newValueStr)}]( | 
 | 570 |                         const boost::system::error_code ec) { | 
 | 571 |         if (ec) | 
 | 572 |         { | 
| Jason M. Bills | a08b46c | 2018-11-06 15:01:08 -0800 | [diff] [blame] | 573 |             messages::internalError(asyncResp->res); | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 574 |         } | 
 | 575 |         else | 
 | 576 |         { | 
 | 577 |             asyncResp->res.jsonValue["IPv4Addresses"][ipIdx]["SubnetMask"] = | 
 | 578 |                 newValueStr; | 
 | 579 |         } | 
 | 580 |     }; | 
 | 581 |  | 
 | 582 |     crow::connections::systemBus->async_method_call( | 
 | 583 |         std::move(callback), "xyz.openbmc_project.Network", | 
 | 584 |         "/xyz/openbmc_project/network/" + ifaceId + "/ipv4/" + ipHash, | 
 | 585 |         "org.freedesktop.DBus.Properties", "Set", | 
 | 586 |         "xyz.openbmc_project.Network.IP", "PrefixLength", | 
| Ed Tanous | abf2add | 2019-01-22 16:40:12 -0800 | [diff] [blame] | 587 |         std::variant<uint8_t>(newValue)); | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 588 | } | 
 | 589 |  | 
 | 590 | /** | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 591 |  * @brief Deletes given IPv4 | 
 | 592 |  * | 
 | 593 |  * @param[in] ifaceId     Id of interface whose IP should be deleted | 
 | 594 |  * @param[in] ipIdx       Index of IP in input array that should be deleted | 
 | 595 |  * @param[in] ipHash      DBus Hash id of IP that should be deleted | 
 | 596 |  * @param[io] asyncResp   Response object that will be returned to client | 
 | 597 |  * | 
 | 598 |  * @return None | 
 | 599 |  */ | 
 | 600 | inline void deleteIPv4(const std::string &ifaceId, const std::string &ipHash, | 
 | 601 |                        unsigned int ipIdx, | 
 | 602 |                        const std::shared_ptr<AsyncResp> asyncResp) | 
 | 603 | { | 
 | 604 |     crow::connections::systemBus->async_method_call( | 
 | 605 |         [ipIdx, asyncResp](const boost::system::error_code ec) { | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 606 |             if (ec) | 
 | 607 |             { | 
| Jason M. Bills | a08b46c | 2018-11-06 15:01:08 -0800 | [diff] [blame] | 608 |                 messages::internalError(asyncResp->res); | 
| Rapkiewicz, Pawel | 9391bb9 | 2018-03-20 03:12:18 +0100 | [diff] [blame] | 609 |             } | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 610 |             else | 
 | 611 |             { | 
 | 612 |                 asyncResp->res.jsonValue["IPv4Addresses"][ipIdx] = nullptr; | 
 | 613 |             } | 
 | 614 |         }, | 
 | 615 |         "xyz.openbmc_project.Network", | 
 | 616 |         "/xyz/openbmc_project/network/" + ifaceId + "/ipv4/" + ipHash, | 
 | 617 |         "xyz.openbmc_project.Object.Delete", "Delete"); | 
 | 618 | } | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 619 |  | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 620 | /** | 
 | 621 |  * @brief Creates IPv4 with given data | 
 | 622 |  * | 
 | 623 |  * @param[in] ifaceId     Id of interface whose IP should be deleted | 
 | 624 |  * @param[in] ipIdx       Index of IP in input array that should be deleted | 
 | 625 |  * @param[in] ipHash      DBus Hash id of IP that should be deleted | 
 | 626 |  * @param[io] asyncResp   Response object that will be returned to client | 
 | 627 |  * | 
 | 628 |  * @return None | 
 | 629 |  */ | 
 | 630 | inline void createIPv4(const std::string &ifaceId, unsigned int ipIdx, | 
 | 631 |                        uint8_t subnetMask, const std::string &gateway, | 
 | 632 |                        const std::string &address, | 
 | 633 |                        std::shared_ptr<AsyncResp> asyncResp) | 
 | 634 | { | 
 | 635 |     auto createIpHandler = [ipIdx, | 
 | 636 |                             asyncResp](const boost::system::error_code ec) { | 
 | 637 |         if (ec) | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 638 |         { | 
| Jason M. Bills | a08b46c | 2018-11-06 15:01:08 -0800 | [diff] [blame] | 639 |             messages::internalError(asyncResp->res); | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 640 |         } | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 641 |     }; | 
 | 642 |  | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 643 |     crow::connections::systemBus->async_method_call( | 
 | 644 |         std::move(createIpHandler), "xyz.openbmc_project.Network", | 
 | 645 |         "/xyz/openbmc_project/network/" + ifaceId, | 
 | 646 |         "xyz.openbmc_project.Network.IP.Create", "IP", | 
 | 647 |         "xyz.openbmc_project.Network.IP.Protocol.IPv4", address, subnetMask, | 
 | 648 |         gateway); | 
 | 649 | } | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 650 |  | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 651 | /** | 
 | 652 |  * Function that retrieves all properties for given Ethernet Interface | 
 | 653 |  * Object | 
 | 654 |  * from EntityManager Network Manager | 
 | 655 |  * @param ethiface_id a eth interface id to query on DBus | 
 | 656 |  * @param callback a function that shall be called to convert Dbus output | 
 | 657 |  * into JSON | 
 | 658 |  */ | 
 | 659 | template <typename CallbackFunc> | 
 | 660 | void getEthernetIfaceData(const std::string ðiface_id, | 
 | 661 |                           CallbackFunc &&callback) | 
 | 662 | { | 
 | 663 |     crow::connections::systemBus->async_method_call( | 
 | 664 |         [ethiface_id{std::string{ethiface_id}}, callback{std::move(callback)}]( | 
 | 665 |             const boost::system::error_code error_code, | 
 | 666 |             const GetManagedObjects &resp) { | 
 | 667 |             EthernetInterfaceData ethData{}; | 
 | 668 |             boost::container::flat_set<IPv4AddressData> ipv4Data; | 
 | 669 |  | 
 | 670 |             if (error_code) | 
 | 671 |             { | 
 | 672 |                 callback(false, ethData, ipv4Data); | 
 | 673 |                 return; | 
 | 674 |             } | 
 | 675 |  | 
 | 676 |             extractEthernetInterfaceData(ethiface_id, resp, ethData); | 
 | 677 |             extractIPData(ethiface_id, resp, ipv4Data); | 
 | 678 |  | 
 | 679 |             // Fix global GW | 
 | 680 |             for (IPv4AddressData &ipv4 : ipv4Data) | 
 | 681 |             { | 
 | 682 |                 if ((ipv4.linktype == LinkType::Global) && | 
 | 683 |                     (ipv4.gateway == "0.0.0.0")) | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 684 |                 { | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 685 |                     ipv4.gateway = ethData.default_gateway; | 
 | 686 |                 } | 
 | 687 |             } | 
 | 688 |  | 
 | 689 |             // Finally make a callback with usefull data | 
 | 690 |             callback(true, ethData, ipv4Data); | 
 | 691 |         }, | 
 | 692 |         "xyz.openbmc_project.Network", "/xyz/openbmc_project/network", | 
 | 693 |         "org.freedesktop.DBus.ObjectManager", "GetManagedObjects"); | 
 | 694 | }; | 
 | 695 |  | 
 | 696 | /** | 
 | 697 |  * Function that retrieves all Ethernet Interfaces available through Network | 
 | 698 |  * Manager | 
 | 699 |  * @param callback a function that shall be called to convert Dbus output | 
 | 700 |  * into JSON. | 
 | 701 |  */ | 
 | 702 | template <typename CallbackFunc> | 
 | 703 | void getEthernetIfaceList(CallbackFunc &&callback) | 
 | 704 | { | 
 | 705 |     crow::connections::systemBus->async_method_call( | 
 | 706 |         [callback{std::move(callback)}]( | 
 | 707 |             const boost::system::error_code error_code, | 
 | 708 |             GetManagedObjects &resp) { | 
 | 709 |             // Callback requires vector<string> to retrieve all available | 
 | 710 |             // ethernet interfaces | 
 | 711 |             std::vector<std::string> iface_list; | 
 | 712 |             iface_list.reserve(resp.size()); | 
 | 713 |             if (error_code) | 
 | 714 |             { | 
 | 715 |                 callback(false, iface_list); | 
 | 716 |                 return; | 
 | 717 |             } | 
 | 718 |  | 
 | 719 |             // Iterate over all retrieved ObjectPaths. | 
 | 720 |             for (const auto &objpath : resp) | 
 | 721 |             { | 
 | 722 |                 // And all interfaces available for certain ObjectPath. | 
 | 723 |                 for (const auto &interface : objpath.second) | 
 | 724 |                 { | 
 | 725 |                     // If interface is | 
 | 726 |                     // xyz.openbmc_project.Network.EthernetInterface, this is | 
 | 727 |                     // what we're looking for. | 
 | 728 |                     if (interface.first == | 
 | 729 |                         "xyz.openbmc_project.Network.EthernetInterface") | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 730 |                     { | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 731 |                         // Cut out everyting until last "/", ... | 
 | 732 |                         const std::string &iface_id = objpath.first.str; | 
 | 733 |                         std::size_t last_pos = iface_id.rfind("/"); | 
 | 734 |                         if (last_pos != std::string::npos) | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 735 |                         { | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 736 |                             // and put it into output vector. | 
 | 737 |                             iface_list.emplace_back( | 
 | 738 |                                 iface_id.substr(last_pos + 1)); | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 739 |                         } | 
 | 740 |                     } | 
 | 741 |                 } | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 742 |             } | 
 | 743 |             // Finally make a callback with useful data | 
 | 744 |             callback(true, iface_list); | 
 | 745 |         }, | 
 | 746 |         "xyz.openbmc_project.Network", "/xyz/openbmc_project/network", | 
 | 747 |         "org.freedesktop.DBus.ObjectManager", "GetManagedObjects"); | 
| Rapkiewicz, Pawel | 9391bb9 | 2018-03-20 03:12:18 +0100 | [diff] [blame] | 748 | }; | 
 | 749 |  | 
 | 750 | /** | 
 | 751 |  * EthernetCollection derived class for delivering Ethernet Collection Schema | 
 | 752 |  */ | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 753 | class EthernetCollection : public Node | 
 | 754 | { | 
 | 755 |   public: | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 756 |     template <typename CrowApp> | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 757 |     EthernetCollection(CrowApp &app) : | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 758 |         Node(app, "/redfish/v1/Managers/bmc/EthernetInterfaces/") | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 759 |     { | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 760 |         entityPrivileges = { | 
 | 761 |             {boost::beast::http::verb::get, {{"Login"}}}, | 
 | 762 |             {boost::beast::http::verb::head, {{"Login"}}}, | 
 | 763 |             {boost::beast::http::verb::patch, {{"ConfigureComponents"}}}, | 
 | 764 |             {boost::beast::http::verb::put, {{"ConfigureComponents"}}}, | 
 | 765 |             {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}}, | 
 | 766 |             {boost::beast::http::verb::post, {{"ConfigureComponents"}}}}; | 
 | 767 |     } | 
 | 768 |  | 
 | 769 |   private: | 
 | 770 |     /** | 
 | 771 |      * Functions triggers appropriate requests on DBus | 
 | 772 |      */ | 
 | 773 |     void doGet(crow::Response &res, const crow::Request &req, | 
 | 774 |                const std::vector<std::string> ¶ms) override | 
 | 775 |     { | 
| Ed Tanous | 0f74e64 | 2018-11-12 15:17:05 -0800 | [diff] [blame] | 776 |         res.jsonValue["@odata.type"] = | 
 | 777 |             "#EthernetInterfaceCollection.EthernetInterfaceCollection"; | 
 | 778 |         res.jsonValue["@odata.context"] = | 
 | 779 |             "/redfish/v1/" | 
 | 780 |             "$metadata#EthernetInterfaceCollection.EthernetInterfaceCollection"; | 
 | 781 |         res.jsonValue["@odata.id"] = | 
 | 782 |             "/redfish/v1/Managers/bmc/EthernetInterfaces"; | 
 | 783 |         res.jsonValue["Name"] = "Ethernet Network Interface Collection"; | 
 | 784 |         res.jsonValue["Description"] = | 
 | 785 |             "Collection of EthernetInterfaces for this Manager"; | 
 | 786 |  | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 787 |         // Get eth interface list, and call the below callback for JSON | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 788 |         // preparation | 
| Jason M. Bills | f12894f | 2018-10-09 12:45:45 -0700 | [diff] [blame] | 789 |         getEthernetIfaceList( | 
 | 790 |             [&res](const bool &success, | 
 | 791 |                    const std::vector<std::string> &iface_list) { | 
 | 792 |                 if (!success) | 
 | 793 |                 { | 
 | 794 |                     messages::internalError(res); | 
 | 795 |                     res.end(); | 
 | 796 |                     return; | 
 | 797 |                 } | 
 | 798 |  | 
 | 799 |                 nlohmann::json &iface_array = res.jsonValue["Members"]; | 
 | 800 |                 iface_array = nlohmann::json::array(); | 
 | 801 |                 for (const std::string &iface_item : iface_list) | 
 | 802 |                 { | 
 | 803 |                     iface_array.push_back( | 
 | 804 |                         {{"@odata.id", | 
 | 805 |                           "/redfish/v1/Managers/bmc/EthernetInterfaces/" + | 
 | 806 |                               iface_item}}); | 
 | 807 |                 } | 
 | 808 |  | 
 | 809 |                 res.jsonValue["Members@odata.count"] = iface_array.size(); | 
 | 810 |                 res.jsonValue["@odata.id"] = | 
 | 811 |                     "/redfish/v1/Managers/bmc/EthernetInterfaces"; | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 812 |                 res.end(); | 
| Jason M. Bills | f12894f | 2018-10-09 12:45:45 -0700 | [diff] [blame] | 813 |             }); | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 814 |     } | 
| Rapkiewicz, Pawel | 9391bb9 | 2018-03-20 03:12:18 +0100 | [diff] [blame] | 815 | }; | 
 | 816 |  | 
 | 817 | /** | 
 | 818 |  * EthernetInterface derived class for delivering Ethernet Schema | 
 | 819 |  */ | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 820 | class EthernetInterface : public Node | 
 | 821 | { | 
 | 822 |   public: | 
 | 823 |     /* | 
 | 824 |      * Default Constructor | 
 | 825 |      */ | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 826 |     template <typename CrowApp> | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 827 |     EthernetInterface(CrowApp &app) : | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 828 |         Node(app, "/redfish/v1/Managers/bmc/EthernetInterfaces/<str>/", | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 829 |              std::string()) | 
 | 830 |     { | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 831 |         entityPrivileges = { | 
 | 832 |             {boost::beast::http::verb::get, {{"Login"}}}, | 
 | 833 |             {boost::beast::http::verb::head, {{"Login"}}}, | 
 | 834 |             {boost::beast::http::verb::patch, {{"ConfigureComponents"}}}, | 
 | 835 |             {boost::beast::http::verb::put, {{"ConfigureComponents"}}}, | 
 | 836 |             {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}}, | 
 | 837 |             {boost::beast::http::verb::post, {{"ConfigureComponents"}}}}; | 
| Kowalski, Kamil | 588c3f0 | 2018-04-03 14:55:27 +0200 | [diff] [blame] | 838 |     } | 
 | 839 |  | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 840 |     // TODO(kkowalsk) Find a suitable class/namespace for this | 
| Ed Tanous | 0627a2c | 2018-11-29 17:09:23 -0800 | [diff] [blame] | 841 |     static void handleVlanPatch(const std::string &ifaceId, bool vlanEnable, | 
 | 842 |                                 uint64_t vlanId, | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 843 |                                 const EthernetInterfaceData ðData, | 
 | 844 |                                 const std::shared_ptr<AsyncResp> asyncResp) | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 845 |     { | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 846 |         if (!ethData.vlan_id) | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 847 |         { | 
 | 848 |             // This interface is not a VLAN. Cannot do anything with it | 
 | 849 |             // TODO(kkowalsk) Change this message | 
| Jason M. Bills | a08b46c | 2018-11-06 15:01:08 -0800 | [diff] [blame] | 850 |             messages::propertyNotWritable(asyncResp->res, "VLANEnable"); | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 851 |  | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 852 |             return; | 
 | 853 |         } | 
 | 854 |  | 
 | 855 |         // VLAN is configured on the interface | 
| Ed Tanous | 0627a2c | 2018-11-29 17:09:23 -0800 | [diff] [blame] | 856 |         if (vlanEnable == true) | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 857 |         { | 
 | 858 |             // Change VLAN Id | 
| Ed Tanous | 0627a2c | 2018-11-29 17:09:23 -0800 | [diff] [blame] | 859 |             asyncResp->res.jsonValue["VLANId"] = vlanId; | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 860 |             auto callback = [asyncResp](const boost::system::error_code ec) { | 
 | 861 |                 if (ec) | 
 | 862 |                 { | 
| Jason M. Bills | f12894f | 2018-10-09 12:45:45 -0700 | [diff] [blame] | 863 |                     messages::internalError(asyncResp->res); | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 864 |                 } | 
 | 865 |                 else | 
 | 866 |                 { | 
 | 867 |                     asyncResp->res.jsonValue["VLANEnable"] = true; | 
 | 868 |                 } | 
 | 869 |             }; | 
 | 870 |             crow::connections::systemBus->async_method_call( | 
 | 871 |                 std::move(callback), "xyz.openbmc_project.Network", | 
 | 872 |                 "/xyz/openbmc_project/network/" + ifaceId, | 
 | 873 |                 "org.freedesktop.DBus.Properties", "Set", | 
 | 874 |                 "xyz.openbmc_project.Network.VLAN", "Id", | 
| Ed Tanous | abf2add | 2019-01-22 16:40:12 -0800 | [diff] [blame] | 875 |                 std::variant<uint32_t>(vlanId)); | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 876 |         } | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 877 |         else | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 878 |         { | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 879 |             auto callback = [asyncResp](const boost::system::error_code ec) { | 
 | 880 |                 if (ec) | 
 | 881 |                 { | 
| Jason M. Bills | f12894f | 2018-10-09 12:45:45 -0700 | [diff] [blame] | 882 |                     messages::internalError(asyncResp->res); | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 883 |                     return; | 
 | 884 |                 } | 
 | 885 |                 asyncResp->res.jsonValue["VLANEnable"] = false; | 
 | 886 |             }; | 
 | 887 |  | 
 | 888 |             crow::connections::systemBus->async_method_call( | 
 | 889 |                 std::move(callback), "xyz.openbmc_project.Network", | 
 | 890 |                 "/xyz/openbmc_project/network/" + ifaceId, | 
 | 891 |                 "xyz.openbmc_project.Object.Delete", "Delete"); | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 892 |         } | 
 | 893 |     } | 
 | 894 |  | 
 | 895 |   private: | 
| Ed Tanous | bc0bd6e | 2018-12-10 14:07:55 -0800 | [diff] [blame] | 896 |     void handleHostnamePatch(const std::string &hostname, | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 897 |                              const std::shared_ptr<AsyncResp> asyncResp) | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 898 |     { | 
| Ed Tanous | bc0bd6e | 2018-12-10 14:07:55 -0800 | [diff] [blame] | 899 |         asyncResp->res.jsonValue["HostName"] = hostname; | 
 | 900 |         crow::connections::systemBus->async_method_call( | 
 | 901 |             [asyncResp](const boost::system::error_code ec) { | 
 | 902 |                 if (ec) | 
 | 903 |                 { | 
 | 904 |                     messages::internalError(asyncResp->res); | 
 | 905 |                 } | 
 | 906 |             }, | 
 | 907 |             "xyz.openbmc_project.Network", | 
 | 908 |             "/xyz/openbmc_project/network/config", | 
 | 909 |             "org.freedesktop.DBus.Properties", "Set", | 
 | 910 |             "xyz.openbmc_project.Network.SystemConfiguration", "HostName", | 
| Ed Tanous | abf2add | 2019-01-22 16:40:12 -0800 | [diff] [blame] | 911 |             std::variant<std::string>(hostname)); | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 912 |     } | 
 | 913 |  | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 914 |     void handleIPv4Patch( | 
 | 915 |         const std::string &ifaceId, const nlohmann::json &input, | 
 | 916 |         const boost::container::flat_set<IPv4AddressData> &ipv4Data, | 
 | 917 |         const std::shared_ptr<AsyncResp> asyncResp) | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 918 |     { | 
 | 919 |         if (!input.is_array()) | 
 | 920 |         { | 
| Jason M. Bills | f12894f | 2018-10-09 12:45:45 -0700 | [diff] [blame] | 921 |             messages::propertyValueTypeError(asyncResp->res, input.dump(), | 
| Jason M. Bills | a08b46c | 2018-11-06 15:01:08 -0800 | [diff] [blame] | 922 |                                              "IPv4Addresses"); | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 923 |             return; | 
 | 924 |         } | 
 | 925 |  | 
 | 926 |         // According to Redfish PATCH definition, size must be at least equal | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 927 |         if (input.size() < ipv4Data.size()) | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 928 |         { | 
| Jason M. Bills | a08b46c | 2018-11-06 15:01:08 -0800 | [diff] [blame] | 929 |             messages::propertyValueFormatError(asyncResp->res, input.dump(), | 
 | 930 |                                                "IPv4Addresses"); | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 931 |             return; | 
 | 932 |         } | 
 | 933 |  | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 934 |         int entryIdx = 0; | 
 | 935 |         boost::container::flat_set<IPv4AddressData>::const_iterator thisData = | 
 | 936 |             ipv4Data.begin(); | 
 | 937 |         for (const nlohmann::json &thisJson : input) | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 938 |         { | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 939 |             std::string pathString = | 
| Jason M. Bills | a08b46c | 2018-11-06 15:01:08 -0800 | [diff] [blame] | 940 |                 "IPv4Addresses/" + std::to_string(entryIdx); | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 941 |             // Check that entry is not of some unexpected type | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 942 |             if (!thisJson.is_object() && !thisJson.is_null()) | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 943 |             { | 
| Jason M. Bills | a08b46c | 2018-11-06 15:01:08 -0800 | [diff] [blame] | 944 |                 messages::propertyValueTypeError(asyncResp->res, | 
 | 945 |                                                  thisJson.dump(), | 
 | 946 |                                                  pathString + "/IPv4Address"); | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 947 |  | 
 | 948 |                 continue; | 
 | 949 |             } | 
 | 950 |  | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 951 |             nlohmann::json::const_iterator addressFieldIt = | 
 | 952 |                 thisJson.find("Address"); | 
 | 953 |             const std::string *addressField = nullptr; | 
 | 954 |             if (addressFieldIt != thisJson.end()) | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 955 |             { | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 956 |                 addressField = addressFieldIt->get_ptr<const std::string *>(); | 
 | 957 |                 if (addressField == nullptr) | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 958 |                 { | 
| Jason M. Bills | a08b46c | 2018-11-06 15:01:08 -0800 | [diff] [blame] | 959 |                     messages::propertyValueFormatError(asyncResp->res, | 
 | 960 |                                                        addressFieldIt->dump(), | 
 | 961 |                                                        pathString + "/Address"); | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 962 |                     continue; | 
 | 963 |                 } | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 964 |                 else | 
 | 965 |                 { | 
 | 966 |                     if (!ipv4VerifyIpAndGetBitcount(*addressField)) | 
 | 967 |                     { | 
| Jason M. Bills | f12894f | 2018-10-09 12:45:45 -0700 | [diff] [blame] | 968 |                         messages::propertyValueFormatError( | 
| Jason M. Bills | a08b46c | 2018-11-06 15:01:08 -0800 | [diff] [blame] | 969 |                             asyncResp->res, *addressField, | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 970 |                             pathString + "/Address"); | 
 | 971 |                         continue; | 
 | 972 |                     } | 
 | 973 |                 } | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 974 |             } | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 975 |  | 
| Ed Tanous | a24526d | 2018-12-10 15:17:59 -0800 | [diff] [blame] | 976 |             std::optional<uint8_t> prefixLength; | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 977 |             const std::string *subnetField = nullptr; | 
 | 978 |             nlohmann::json::const_iterator subnetFieldIt = | 
 | 979 |                 thisJson.find("SubnetMask"); | 
 | 980 |             if (subnetFieldIt != thisJson.end()) | 
 | 981 |             { | 
 | 982 |                 subnetField = subnetFieldIt->get_ptr<const std::string *>(); | 
 | 983 |                 if (subnetField == nullptr) | 
 | 984 |                 { | 
| Jason M. Bills | f12894f | 2018-10-09 12:45:45 -0700 | [diff] [blame] | 985 |                     messages::propertyValueFormatError( | 
| Jason M. Bills | a08b46c | 2018-11-06 15:01:08 -0800 | [diff] [blame] | 986 |                         asyncResp->res, *subnetField, | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 987 |                         pathString + "/SubnetMask"); | 
 | 988 |                     continue; | 
 | 989 |                 } | 
 | 990 |                 else | 
 | 991 |                 { | 
 | 992 |                     prefixLength = 0; | 
 | 993 |                     if (!ipv4VerifyIpAndGetBitcount(*subnetField, | 
 | 994 |                                                     &*prefixLength)) | 
 | 995 |                     { | 
| Jason M. Bills | f12894f | 2018-10-09 12:45:45 -0700 | [diff] [blame] | 996 |                         messages::propertyValueFormatError( | 
| Jason M. Bills | a08b46c | 2018-11-06 15:01:08 -0800 | [diff] [blame] | 997 |                             asyncResp->res, *subnetField, | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 998 |                             pathString + "/SubnetMask"); | 
 | 999 |                         continue; | 
 | 1000 |                     } | 
 | 1001 |                 } | 
 | 1002 |             } | 
 | 1003 |  | 
 | 1004 |             std::string addressOriginInDBusFormat; | 
 | 1005 |             const std::string *addressOriginField = nullptr; | 
 | 1006 |             nlohmann::json::const_iterator addressOriginFieldIt = | 
 | 1007 |                 thisJson.find("AddressOrigin"); | 
 | 1008 |             if (addressOriginFieldIt != thisJson.end()) | 
 | 1009 |             { | 
 | 1010 |                 const std::string *addressOriginField = | 
 | 1011 |                     addressOriginFieldIt->get_ptr<const std::string *>(); | 
 | 1012 |                 if (addressOriginField == nullptr) | 
 | 1013 |                 { | 
| Jason M. Bills | f12894f | 2018-10-09 12:45:45 -0700 | [diff] [blame] | 1014 |                     messages::propertyValueFormatError( | 
| Jason M. Bills | a08b46c | 2018-11-06 15:01:08 -0800 | [diff] [blame] | 1015 |                         asyncResp->res, *addressOriginField, | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 1016 |                         pathString + "/AddressOrigin"); | 
 | 1017 |                     continue; | 
 | 1018 |                 } | 
 | 1019 |                 else | 
 | 1020 |                 { | 
 | 1021 |                     // Get Address origin in proper format | 
 | 1022 |                     addressOriginInDBusFormat = | 
 | 1023 |                         translateAddressOriginRedfishToDbus( | 
 | 1024 |                             *addressOriginField); | 
 | 1025 |                     if (addressOriginInDBusFormat.empty()) | 
 | 1026 |                     { | 
| Jason M. Bills | f12894f | 2018-10-09 12:45:45 -0700 | [diff] [blame] | 1027 |                         messages::propertyValueNotInList( | 
 | 1028 |                             asyncResp->res, *addressOriginField, | 
| Jason M. Bills | a08b46c | 2018-11-06 15:01:08 -0800 | [diff] [blame] | 1029 |                             pathString + "/AddressOrigin"); | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 1030 |                         continue; | 
 | 1031 |                     } | 
 | 1032 |                 } | 
 | 1033 |             } | 
 | 1034 |  | 
 | 1035 |             nlohmann::json::const_iterator gatewayFieldIt = | 
 | 1036 |                 thisJson.find("Gateway"); | 
 | 1037 |             const std::string *gatewayField = nullptr; | 
 | 1038 |             if (gatewayFieldIt != thisJson.end()) | 
 | 1039 |             { | 
 | 1040 |                 const std::string *gatewayField = | 
 | 1041 |                     gatewayFieldIt->get_ptr<const std::string *>(); | 
 | 1042 |                 if (gatewayField == nullptr || | 
 | 1043 |                     !ipv4VerifyIpAndGetBitcount(*gatewayField)) | 
 | 1044 |                 { | 
| Jason M. Bills | a08b46c | 2018-11-06 15:01:08 -0800 | [diff] [blame] | 1045 |                     messages::propertyValueFormatError( | 
 | 1046 |                         asyncResp->res, *gatewayField, pathString + "/Gateway"); | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 1047 |                     continue; | 
 | 1048 |                 } | 
 | 1049 |             } | 
 | 1050 |  | 
 | 1051 |             // if a vlan already exists, modify the existing | 
 | 1052 |             if (thisData != ipv4Data.end()) | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1053 |             { | 
 | 1054 |                 // Existing object that should be modified/deleted/remain | 
 | 1055 |                 // unchanged | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 1056 |                 if (thisJson.is_null()) | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1057 |                 { | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 1058 |                     auto callback = [entryIdx{std::to_string(entryIdx)}, | 
 | 1059 |                                      asyncResp]( | 
 | 1060 |                                         const boost::system::error_code ec) { | 
 | 1061 |                         if (ec) | 
 | 1062 |                         { | 
| Jason M. Bills | a08b46c | 2018-11-06 15:01:08 -0800 | [diff] [blame] | 1063 |                             messages::internalError(asyncResp->res); | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 1064 |                             return; | 
 | 1065 |                         } | 
 | 1066 |                         asyncResp->res.jsonValue["IPv4Addresses"][entryIdx] = | 
 | 1067 |                             nullptr; | 
 | 1068 |                     }; | 
 | 1069 |                     crow::connections::systemBus->async_method_call( | 
 | 1070 |                         std::move(callback), "xyz.openbmc_project.Network", | 
 | 1071 |                         "/xyz/openbmc_project/network/" + ifaceId + "/ipv4/" + | 
 | 1072 |                             thisData->id, | 
 | 1073 |                         "xyz.openbmc_project.Object.Delete", "Delete"); | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1074 |                 } | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 1075 |                 else if (thisJson.is_object()) | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1076 |                 { | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1077 |                     // Apply changes | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 1078 |                     if (addressField != nullptr) | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1079 |                     { | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 1080 |                         auto callback = | 
 | 1081 |                             [asyncResp, entryIdx, | 
 | 1082 |                              addressField{std::string(*addressField)}]( | 
 | 1083 |                                 const boost::system::error_code ec) { | 
 | 1084 |                                 if (ec) | 
 | 1085 |                                 { | 
| Jason M. Bills | a08b46c | 2018-11-06 15:01:08 -0800 | [diff] [blame] | 1086 |                                     messages::internalError(asyncResp->res); | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 1087 |                                     return; | 
 | 1088 |                                 } | 
 | 1089 |                                 asyncResp->res | 
 | 1090 |                                     .jsonValue["IPv4Addresses"][std::to_string( | 
 | 1091 |                                         entryIdx)]["Address"] = addressField; | 
 | 1092 |                             }; | 
 | 1093 |  | 
 | 1094 |                         crow::connections::systemBus->async_method_call( | 
 | 1095 |                             std::move(callback), "xyz.openbmc_project.Network", | 
 | 1096 |                             "/xyz/openbmc_project/network/" + ifaceId + | 
 | 1097 |                                 "/ipv4/" + thisData->id, | 
 | 1098 |                             "org.freedesktop.DBus.Properties", "Set", | 
 | 1099 |                             "xyz.openbmc_project.Network.IP", "Address", | 
| Ed Tanous | abf2add | 2019-01-22 16:40:12 -0800 | [diff] [blame] | 1100 |                             std::variant<std::string>(*addressField)); | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1101 |                     } | 
 | 1102 |  | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 1103 |                     if (prefixLength && subnetField != nullptr) | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1104 |                     { | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 1105 |                         changeIPv4SubnetMaskProperty(ifaceId, entryIdx, | 
 | 1106 |                                                      thisData->id, *subnetField, | 
 | 1107 |                                                      *prefixLength, asyncResp); | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1108 |                     } | 
 | 1109 |  | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 1110 |                     if (!addressOriginInDBusFormat.empty() && | 
 | 1111 |                         addressOriginField != nullptr) | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1112 |                     { | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 1113 |                         changeIPv4Origin(ifaceId, entryIdx, thisData->id, | 
 | 1114 |                                          *addressOriginField, | 
 | 1115 |                                          addressOriginInDBusFormat, asyncResp); | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1116 |                     } | 
 | 1117 |  | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 1118 |                     if (gatewayField != nullptr) | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1119 |                     { | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 1120 |                         auto callback = | 
 | 1121 |                             [asyncResp, entryIdx, | 
 | 1122 |                              gatewayField{std::string(*gatewayField)}]( | 
 | 1123 |                                 const boost::system::error_code ec) { | 
 | 1124 |                                 if (ec) | 
 | 1125 |                                 { | 
| Jason M. Bills | a08b46c | 2018-11-06 15:01:08 -0800 | [diff] [blame] | 1126 |                                     messages::internalError(asyncResp->res); | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 1127 |                                     return; | 
 | 1128 |                                 } | 
 | 1129 |                                 asyncResp->res | 
 | 1130 |                                     .jsonValue["IPv4Addresses"][std::to_string( | 
 | 1131 |                                         entryIdx)]["Gateway"] = | 
 | 1132 |                                     std::move(gatewayField); | 
 | 1133 |                             }; | 
 | 1134 |  | 
 | 1135 |                         crow::connections::systemBus->async_method_call( | 
 | 1136 |                             std::move(callback), "xyz.openbmc_project.Network", | 
 | 1137 |                             "/xyz/openbmc_project/network/" + ifaceId + | 
 | 1138 |                                 "/ipv4/" + thisData->id, | 
 | 1139 |                             "org.freedesktop.DBus.Properties", "Set", | 
 | 1140 |                             "xyz.openbmc_project.Network.IP", "Gateway", | 
| Ed Tanous | abf2add | 2019-01-22 16:40:12 -0800 | [diff] [blame] | 1141 |                             std::variant<std::string>(*gatewayField)); | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1142 |                     } | 
 | 1143 |                 } | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 1144 |                 thisData++; | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1145 |             } | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 1146 |             else | 
 | 1147 |             { | 
 | 1148 |                 // Create IPv4 with provided data | 
 | 1149 |                 if (gatewayField == nullptr) | 
 | 1150 |                 { | 
| Jason M. Bills | a08b46c | 2018-11-06 15:01:08 -0800 | [diff] [blame] | 1151 |                     messages::propertyMissing(asyncResp->res, | 
| Jason M. Bills | f12894f | 2018-10-09 12:45:45 -0700 | [diff] [blame] | 1152 |                                               pathString + "/Gateway"); | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 1153 |                     continue; | 
 | 1154 |                 } | 
 | 1155 |  | 
 | 1156 |                 if (addressField == nullptr) | 
 | 1157 |                 { | 
| Jason M. Bills | a08b46c | 2018-11-06 15:01:08 -0800 | [diff] [blame] | 1158 |                     messages::propertyMissing(asyncResp->res, | 
| Jason M. Bills | f12894f | 2018-10-09 12:45:45 -0700 | [diff] [blame] | 1159 |                                               pathString + "/Address"); | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 1160 |                     continue; | 
 | 1161 |                 } | 
 | 1162 |  | 
 | 1163 |                 if (!prefixLength) | 
 | 1164 |                 { | 
| Jason M. Bills | a08b46c | 2018-11-06 15:01:08 -0800 | [diff] [blame] | 1165 |                     messages::propertyMissing(asyncResp->res, | 
| Jason M. Bills | f12894f | 2018-10-09 12:45:45 -0700 | [diff] [blame] | 1166 |                                               pathString + "/SubnetMask"); | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 1167 |                     continue; | 
 | 1168 |                 } | 
 | 1169 |  | 
 | 1170 |                 createIPv4(ifaceId, entryIdx, *prefixLength, *gatewayField, | 
 | 1171 |                            *addressField, asyncResp); | 
 | 1172 |                 asyncResp->res.jsonValue["IPv4Addresses"][entryIdx] = thisJson; | 
 | 1173 |             } | 
 | 1174 |             entryIdx++; | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1175 |         } | 
 | 1176 |     } | 
 | 1177 |  | 
| Ed Tanous | 0f74e64 | 2018-11-12 15:17:05 -0800 | [diff] [blame] | 1178 |     void parseInterfaceData( | 
 | 1179 |         nlohmann::json &json_response, const std::string &iface_id, | 
 | 1180 |         const EthernetInterfaceData ðData, | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 1181 |         const boost::container::flat_set<IPv4AddressData> &ipv4Data) | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1182 |     { | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 1183 |         json_response["Id"] = iface_id; | 
 | 1184 |         json_response["@odata.id"] = | 
 | 1185 |             "/redfish/v1/Managers/bmc/EthernetInterfaces/" + iface_id; | 
| Ed Tanous | 029573d | 2019-02-01 10:57:49 -0800 | [diff] [blame^] | 1186 |         json_response["InterfaceEnabled"] = true; | 
 | 1187 |         if (ethData.speed == 0) | 
 | 1188 |         { | 
 | 1189 |             json_response["LinkStatus"] = "NoLink"; | 
 | 1190 |             json_response["Status"] = { | 
 | 1191 |                 {"Health", "OK"}, | 
 | 1192 |                 {"State", "Disabled"}, | 
 | 1193 |             }; | 
 | 1194 |         } | 
 | 1195 |         else | 
 | 1196 |         { | 
 | 1197 |             json_response["LinkStatus"] = "LinkUp"; | 
 | 1198 |             json_response["Status"] = { | 
 | 1199 |                 {"Health", "OK"}, | 
 | 1200 |                 {"State", "Enabled"}, | 
 | 1201 |             }; | 
 | 1202 |         } | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 1203 |         json_response["SpeedMbps"] = ethData.speed; | 
 | 1204 |         json_response["MACAddress"] = ethData.mac_address; | 
 | 1205 |         if (!ethData.hostname.empty()) | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1206 |         { | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 1207 |             json_response["HostName"] = ethData.hostname; | 
 | 1208 |         } | 
 | 1209 |  | 
 | 1210 |         nlohmann::json &vlanObj = json_response["VLAN"]; | 
 | 1211 |         if (ethData.vlan_id) | 
 | 1212 |         { | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1213 |             vlanObj["VLANEnable"] = true; | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 1214 |             vlanObj["VLANId"] = *ethData.vlan_id; | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1215 |         } | 
 | 1216 |         else | 
 | 1217 |         { | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 1218 |             vlanObj["VLANEnable"] = false; | 
 | 1219 |             vlanObj["VLANId"] = 0; | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1220 |         } | 
| Ed Tanous | 029573d | 2019-02-01 10:57:49 -0800 | [diff] [blame^] | 1221 |         json_response["NameServers"] = ethData.nameservers; | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1222 |  | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 1223 |         if (ipv4Data.size() > 0) | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1224 |         { | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 1225 |             nlohmann::json &ipv4_array = json_response["IPv4Addresses"]; | 
 | 1226 |             ipv4_array = nlohmann::json::array(); | 
 | 1227 |             for (auto &ipv4_config : ipv4Data) | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1228 |             { | 
| Ed Tanous | 029573d | 2019-02-01 10:57:49 -0800 | [diff] [blame^] | 1229 |                 ipv4_array.push_back({{"AddressOrigin", ipv4_config.origin}, | 
 | 1230 |                                       {"SubnetMask", ipv4_config.netmask}, | 
 | 1231 |                                       {"Address", ipv4_config.address}, | 
 | 1232 |                                       {"Gateway", ipv4_config.gateway}}); | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1233 |             } | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1234 |         } | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1235 |     } | 
 | 1236 |  | 
 | 1237 |     /** | 
 | 1238 |      * Functions triggers appropriate requests on DBus | 
 | 1239 |      */ | 
 | 1240 |     void doGet(crow::Response &res, const crow::Request &req, | 
 | 1241 |                const std::vector<std::string> ¶ms) override | 
 | 1242 |     { | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 1243 |         std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res); | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1244 |         if (params.size() != 1) | 
 | 1245 |         { | 
| Jason M. Bills | f12894f | 2018-10-09 12:45:45 -0700 | [diff] [blame] | 1246 |             messages::internalError(asyncResp->res); | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1247 |             return; | 
 | 1248 |         } | 
 | 1249 |  | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 1250 |         getEthernetIfaceData( | 
 | 1251 |             params[0], | 
 | 1252 |             [this, asyncResp, iface_id{std::string(params[0])}]( | 
 | 1253 |                 const bool &success, const EthernetInterfaceData ðData, | 
 | 1254 |                 const boost::container::flat_set<IPv4AddressData> &ipv4Data) { | 
 | 1255 |                 if (!success) | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1256 |                 { | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1257 |                     // TODO(Pawel)consider distinguish between non existing | 
 | 1258 |                     // object, and other errors | 
| Jason M. Bills | f12894f | 2018-10-09 12:45:45 -0700 | [diff] [blame] | 1259 |                     messages::resourceNotFound(asyncResp->res, | 
 | 1260 |                                                "EthernetInterface", iface_id); | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 1261 |                     return; | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1262 |                 } | 
| Ed Tanous | 0f74e64 | 2018-11-12 15:17:05 -0800 | [diff] [blame] | 1263 |                 asyncResp->res.jsonValue["@odata.type"] = | 
 | 1264 |                     "#EthernetInterface.v1_2_0.EthernetInterface"; | 
 | 1265 |                 asyncResp->res.jsonValue["@odata.context"] = | 
 | 1266 |                     "/redfish/v1/$metadata#EthernetInterface.EthernetInterface"; | 
 | 1267 |                 asyncResp->res.jsonValue["Name"] = "Manager Ethernet Interface"; | 
 | 1268 |                 asyncResp->res.jsonValue["Description"] = | 
 | 1269 |                     "Management Network Interface"; | 
 | 1270 |  | 
 | 1271 |                 parseInterfaceData(asyncResp->res.jsonValue, iface_id, ethData, | 
 | 1272 |                                    ipv4Data); | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1273 |             }); | 
 | 1274 |     } | 
 | 1275 |  | 
 | 1276 |     void doPatch(crow::Response &res, const crow::Request &req, | 
 | 1277 |                  const std::vector<std::string> ¶ms) override | 
 | 1278 |     { | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 1279 |         std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res); | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1280 |         if (params.size() != 1) | 
 | 1281 |         { | 
| Jason M. Bills | f12894f | 2018-10-09 12:45:45 -0700 | [diff] [blame] | 1282 |             messages::internalError(asyncResp->res); | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1283 |             return; | 
 | 1284 |         } | 
 | 1285 |  | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 1286 |         const std::string &iface_id = params[0]; | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1287 |  | 
| Ed Tanous | 0627a2c | 2018-11-29 17:09:23 -0800 | [diff] [blame] | 1288 |         std::optional<nlohmann::json> vlan; | 
| Ed Tanous | bc0bd6e | 2018-12-10 14:07:55 -0800 | [diff] [blame] | 1289 |         std::optional<std::string> hostname; | 
| Ed Tanous | 0627a2c | 2018-11-29 17:09:23 -0800 | [diff] [blame] | 1290 |         std::optional<nlohmann::json> ipv4Addresses; | 
 | 1291 |         std::optional<nlohmann::json> ipv6Addresses; | 
 | 1292 |  | 
 | 1293 |         if (!json_util::readJson(req, res, "VLAN", vlan, "HostName", hostname, | 
 | 1294 |                                  "IPv4Addresses", ipv4Addresses, | 
 | 1295 |                                  "IPv6Addresses", ipv6Addresses)) | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1296 |         { | 
 | 1297 |             return; | 
 | 1298 |         } | 
| Ed Tanous | 0627a2c | 2018-11-29 17:09:23 -0800 | [diff] [blame] | 1299 |         std::optional<uint64_t> vlanId = 0; | 
 | 1300 |         std::optional<bool> vlanEnable = false; | 
 | 1301 |         if (vlan) | 
 | 1302 |         { | 
 | 1303 |             if (!json_util::readJson(*vlan, res, "VLANEnable", vlanEnable, | 
 | 1304 |                                      "VLANId", vlanId)) | 
 | 1305 |             { | 
 | 1306 |                 return; | 
 | 1307 |             } | 
 | 1308 |             // Need both vlanId and vlanEnable to service this request | 
 | 1309 |             if (static_cast<bool>(vlanId) ^ static_cast<bool>(vlanEnable)) | 
 | 1310 |             { | 
 | 1311 |                 if (vlanId) | 
 | 1312 |                 { | 
 | 1313 |                     messages::propertyMissing(asyncResp->res, "VLANEnable"); | 
 | 1314 |                 } | 
 | 1315 |                 else | 
 | 1316 |                 { | 
 | 1317 |                     messages::propertyMissing(asyncResp->res, "VLANId"); | 
 | 1318 |                 } | 
 | 1319 |  | 
 | 1320 |                 return; | 
 | 1321 |             } | 
 | 1322 |         } | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1323 |  | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 1324 |         // Get single eth interface data, and call the below callback for JSON | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1325 |         // preparation | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 1326 |         getEthernetIfaceData( | 
 | 1327 |             iface_id, | 
| Ed Tanous | 0627a2c | 2018-11-29 17:09:23 -0800 | [diff] [blame] | 1328 |             [this, asyncResp, iface_id, vlanId, vlanEnable, | 
 | 1329 |              hostname = std::move(hostname), | 
 | 1330 |              ipv4Addresses = std::move(ipv4Addresses), | 
 | 1331 |              ipv6Addresses = std::move(ipv6Addresses)]( | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 1332 |                 const bool &success, const EthernetInterfaceData ðData, | 
 | 1333 |                 const boost::container::flat_set<IPv4AddressData> &ipv4Data) { | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1334 |                 if (!success) | 
 | 1335 |                 { | 
 | 1336 |                     // ... otherwise return error | 
 | 1337 |                     // TODO(Pawel)consider distinguish between non existing | 
 | 1338 |                     // object, and other errors | 
| Jason M. Bills | f12894f | 2018-10-09 12:45:45 -0700 | [diff] [blame] | 1339 |                     messages::resourceNotFound( | 
 | 1340 |                         asyncResp->res, "VLAN Network Interface", iface_id); | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1341 |                     return; | 
 | 1342 |                 } | 
 | 1343 |  | 
| Ed Tanous | 0f74e64 | 2018-11-12 15:17:05 -0800 | [diff] [blame] | 1344 |                 parseInterfaceData(asyncResp->res.jsonValue, iface_id, ethData, | 
 | 1345 |                                    ipv4Data); | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1346 |  | 
| Ed Tanous | 0627a2c | 2018-11-29 17:09:23 -0800 | [diff] [blame] | 1347 |                 if (vlanId && vlanEnable) | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1348 |                 { | 
| Ed Tanous | 0627a2c | 2018-11-29 17:09:23 -0800 | [diff] [blame] | 1349 |                     handleVlanPatch(iface_id, *vlanId, *vlanEnable, ethData, | 
 | 1350 |                                     asyncResp); | 
 | 1351 |                 } | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1352 |  | 
| Ed Tanous | 0627a2c | 2018-11-29 17:09:23 -0800 | [diff] [blame] | 1353 |                 if (hostname) | 
 | 1354 |                 { | 
 | 1355 |                     handleHostnamePatch(*hostname, asyncResp); | 
 | 1356 |                 } | 
 | 1357 |  | 
 | 1358 |                 if (ipv4Addresses) | 
 | 1359 |                 { | 
 | 1360 |                     handleIPv4Patch(iface_id, *ipv4Addresses, ipv4Data, | 
 | 1361 |                                     asyncResp); | 
 | 1362 |                 } | 
 | 1363 |  | 
 | 1364 |                 if (ipv6Addresses) | 
 | 1365 |                 { | 
 | 1366 |                     // TODO(kkowalsk) IPv6 Not supported on D-Bus yet | 
 | 1367 |                     messages::propertyNotWritable(asyncResp->res, | 
 | 1368 |                                                   "IPv6Addresses"); | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1369 |                 } | 
 | 1370 |             }); | 
 | 1371 |     } | 
| Rapkiewicz, Pawel | 9391bb9 | 2018-03-20 03:12:18 +0100 | [diff] [blame] | 1372 | }; | 
 | 1373 |  | 
| Kowalski, Kamil | e439f0f | 2018-05-21 08:13:57 +0200 | [diff] [blame] | 1374 | /** | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 1375 |  * VlanNetworkInterface derived class for delivering VLANNetworkInterface | 
 | 1376 |  * Schema | 
| Kowalski, Kamil | e439f0f | 2018-05-21 08:13:57 +0200 | [diff] [blame] | 1377 |  */ | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1378 | class VlanNetworkInterface : public Node | 
 | 1379 | { | 
 | 1380 |   public: | 
 | 1381 |     /* | 
 | 1382 |      * Default Constructor | 
 | 1383 |      */ | 
 | 1384 |     template <typename CrowApp> | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1385 |     VlanNetworkInterface(CrowApp &app) : | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 1386 |         Node(app, | 
| Ed Tanous | 0f74e64 | 2018-11-12 15:17:05 -0800 | [diff] [blame] | 1387 |              "/redfish/v1/Managers/bmc/EthernetInterfaces/<str>/VLANs/<str>", | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 1388 |              std::string(), std::string()) | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1389 |     { | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1390 |         entityPrivileges = { | 
 | 1391 |             {boost::beast::http::verb::get, {{"Login"}}}, | 
 | 1392 |             {boost::beast::http::verb::head, {{"Login"}}}, | 
 | 1393 |             {boost::beast::http::verb::patch, {{"ConfigureComponents"}}}, | 
 | 1394 |             {boost::beast::http::verb::put, {{"ConfigureComponents"}}}, | 
 | 1395 |             {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}}, | 
 | 1396 |             {boost::beast::http::verb::post, {{"ConfigureComponents"}}}}; | 
| Kowalski, Kamil | e439f0f | 2018-05-21 08:13:57 +0200 | [diff] [blame] | 1397 |     } | 
 | 1398 |  | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1399 |   private: | 
| Ed Tanous | 0f74e64 | 2018-11-12 15:17:05 -0800 | [diff] [blame] | 1400 |     void parseInterfaceData( | 
 | 1401 |         nlohmann::json &json_response, const std::string &parent_iface_id, | 
 | 1402 |         const std::string &iface_id, const EthernetInterfaceData ðData, | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 1403 |         const boost::container::flat_set<IPv4AddressData> &ipv4Data) | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1404 |     { | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1405 |         // Fill out obvious data... | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 1406 |         json_response["Id"] = iface_id; | 
 | 1407 |         json_response["@odata.id"] = | 
 | 1408 |             "/redfish/v1/Managers/bmc/EthernetInterfaces/" + parent_iface_id + | 
 | 1409 |             "/VLANs/" + iface_id; | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1410 |  | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 1411 |         json_response["VLANEnable"] = true; | 
 | 1412 |         if (ethData.vlan_id) | 
 | 1413 |         { | 
 | 1414 |             json_response["VLANId"] = *ethData.vlan_id; | 
 | 1415 |         } | 
| Ed Tanous | a434f2b | 2018-07-27 13:04:22 -0700 | [diff] [blame] | 1416 |     } | 
 | 1417 |  | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1418 |     bool verifyNames(crow::Response &res, const std::string &parent, | 
 | 1419 |                      const std::string &iface) | 
 | 1420 |     { | 
| Jason M. Bills | f12894f | 2018-10-09 12:45:45 -0700 | [diff] [blame] | 1421 |         std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res); | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1422 |         if (!boost::starts_with(iface, parent + "_")) | 
 | 1423 |         { | 
| Jason M. Bills | f12894f | 2018-10-09 12:45:45 -0700 | [diff] [blame] | 1424 |             messages::resourceNotFound(asyncResp->res, "VLAN Network Interface", | 
 | 1425 |                                        iface); | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1426 |             return false; | 
 | 1427 |         } | 
 | 1428 |         else | 
 | 1429 |         { | 
 | 1430 |             return true; | 
 | 1431 |         } | 
 | 1432 |     } | 
 | 1433 |  | 
 | 1434 |     /** | 
 | 1435 |      * Functions triggers appropriate requests on DBus | 
 | 1436 |      */ | 
 | 1437 |     void doGet(crow::Response &res, const crow::Request &req, | 
 | 1438 |                const std::vector<std::string> ¶ms) override | 
 | 1439 |     { | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 1440 |         std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res); | 
 | 1441 |         // TODO(Pawel) this shall be parameterized call (two params) to get | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1442 |         // EthernetInterfaces for any Manager, not only hardcoded 'openbmc'. | 
 | 1443 |         // Check if there is required param, truly entering this shall be | 
 | 1444 |         // impossible. | 
 | 1445 |         if (params.size() != 2) | 
 | 1446 |         { | 
| Jason M. Bills | f12894f | 2018-10-09 12:45:45 -0700 | [diff] [blame] | 1447 |             messages::internalError(res); | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1448 |             res.end(); | 
| Kowalski, Kamil | 927a505 | 2018-07-03 14:16:46 +0200 | [diff] [blame] | 1449 |             return; | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1450 |         } | 
| Kowalski, Kamil | 927a505 | 2018-07-03 14:16:46 +0200 | [diff] [blame] | 1451 |  | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 1452 |         const std::string &parent_iface_id = params[0]; | 
 | 1453 |         const std::string &iface_id = params[1]; | 
| Ed Tanous | 0f74e64 | 2018-11-12 15:17:05 -0800 | [diff] [blame] | 1454 |         res.jsonValue["@odata.type"] = | 
 | 1455 |             "#VLanNetworkInterface.v1_1_0.VLanNetworkInterface"; | 
 | 1456 |         res.jsonValue["@odata.context"] = | 
 | 1457 |             "/redfish/v1/$metadata#VLanNetworkInterface.VLanNetworkInterface"; | 
 | 1458 |         res.jsonValue["Name"] = "VLAN Network Interface"; | 
| Kowalski, Kamil | 927a505 | 2018-07-03 14:16:46 +0200 | [diff] [blame] | 1459 |  | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 1460 |         if (!verifyNames(res, parent_iface_id, iface_id)) | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1461 |         { | 
 | 1462 |             return; | 
 | 1463 |         } | 
| Kowalski, Kamil | 927a505 | 2018-07-03 14:16:46 +0200 | [diff] [blame] | 1464 |  | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1465 |         // Get single eth interface data, and call the below callback for JSON | 
 | 1466 |         // preparation | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 1467 |         getEthernetIfaceData( | 
 | 1468 |             iface_id, | 
 | 1469 |             [this, asyncResp, parent_iface_id, iface_id]( | 
 | 1470 |                 const bool &success, const EthernetInterfaceData ðData, | 
 | 1471 |                 const boost::container::flat_set<IPv4AddressData> &ipv4Data) { | 
 | 1472 |                 if (success && ethData.vlan_id) | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1473 |                 { | 
| Ed Tanous | 0f74e64 | 2018-11-12 15:17:05 -0800 | [diff] [blame] | 1474 |                     parseInterfaceData(asyncResp->res.jsonValue, | 
 | 1475 |                                        parent_iface_id, iface_id, ethData, | 
 | 1476 |                                        ipv4Data); | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1477 |                 } | 
 | 1478 |                 else | 
 | 1479 |                 { | 
 | 1480 |                     // ... otherwise return error | 
 | 1481 |                     // TODO(Pawel)consider distinguish between non existing | 
 | 1482 |                     // object, and other errors | 
| Jason M. Bills | f12894f | 2018-10-09 12:45:45 -0700 | [diff] [blame] | 1483 |                     messages::resourceNotFound( | 
 | 1484 |                         asyncResp->res, "VLAN Network Interface", iface_id); | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1485 |                 } | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1486 |             }); | 
| Kowalski, Kamil | e439f0f | 2018-05-21 08:13:57 +0200 | [diff] [blame] | 1487 |     } | 
 | 1488 |  | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1489 |     void doPatch(crow::Response &res, const crow::Request &req, | 
 | 1490 |                  const std::vector<std::string> ¶ms) override | 
 | 1491 |     { | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 1492 |         std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res); | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1493 |         if (params.size() != 2) | 
 | 1494 |         { | 
| Jason M. Bills | f12894f | 2018-10-09 12:45:45 -0700 | [diff] [blame] | 1495 |             messages::internalError(asyncResp->res); | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1496 |             return; | 
 | 1497 |         } | 
| Kowalski, Kamil | e439f0f | 2018-05-21 08:13:57 +0200 | [diff] [blame] | 1498 |  | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1499 |         const std::string &parentIfaceId = params[0]; | 
 | 1500 |         const std::string &ifaceId = params[1]; | 
| Kowalski, Kamil | e439f0f | 2018-05-21 08:13:57 +0200 | [diff] [blame] | 1501 |  | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1502 |         if (!verifyNames(res, parentIfaceId, ifaceId)) | 
 | 1503 |         { | 
 | 1504 |             return; | 
 | 1505 |         } | 
 | 1506 |  | 
| Ed Tanous | 0627a2c | 2018-11-29 17:09:23 -0800 | [diff] [blame] | 1507 |         bool vlanEnable = false; | 
 | 1508 |         uint64_t vlanId = 0; | 
 | 1509 |  | 
 | 1510 |         if (!json_util::readJson(req, res, "VLANEnable", vlanEnable, "VLANId", | 
 | 1511 |                                  vlanId)) | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1512 |         { | 
 | 1513 |             return; | 
 | 1514 |         } | 
 | 1515 |  | 
 | 1516 |         // Get single eth interface data, and call the below callback for JSON | 
 | 1517 |         // preparation | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 1518 |         getEthernetIfaceData( | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1519 |             ifaceId, | 
| Ed Tanous | 0627a2c | 2018-11-29 17:09:23 -0800 | [diff] [blame] | 1520 |             [this, asyncResp, parentIfaceId, ifaceId, vlanEnable, vlanId]( | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 1521 |                 const bool &success, const EthernetInterfaceData ðData, | 
 | 1522 |                 const boost::container::flat_set<IPv4AddressData> &ipv4Data) { | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1523 |                 if (!success) | 
 | 1524 |                 { | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1525 |                     // TODO(Pawel)consider distinguish between non existing | 
 | 1526 |                     // object, and other errors | 
| Jason M. Bills | f12894f | 2018-10-09 12:45:45 -0700 | [diff] [blame] | 1527 |                     messages::resourceNotFound( | 
 | 1528 |                         asyncResp->res, "VLAN Network Interface", ifaceId); | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1529 |  | 
 | 1530 |                     return; | 
 | 1531 |                 } | 
 | 1532 |  | 
| Ed Tanous | 0f74e64 | 2018-11-12 15:17:05 -0800 | [diff] [blame] | 1533 |                 parseInterfaceData(asyncResp->res.jsonValue, parentIfaceId, | 
 | 1534 |                                    ifaceId, ethData, ipv4Data); | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1535 |  | 
| Ed Tanous | 0627a2c | 2018-11-29 17:09:23 -0800 | [diff] [blame] | 1536 |                 EthernetInterface::handleVlanPatch(ifaceId, vlanId, vlanEnable, | 
 | 1537 |                                                    ethData, asyncResp); | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1538 |             }); | 
 | 1539 |     } | 
 | 1540 |  | 
 | 1541 |     void doDelete(crow::Response &res, const crow::Request &req, | 
 | 1542 |                   const std::vector<std::string> ¶ms) override | 
 | 1543 |     { | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 1544 |         std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res); | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1545 |         if (params.size() != 2) | 
 | 1546 |         { | 
| Jason M. Bills | f12894f | 2018-10-09 12:45:45 -0700 | [diff] [blame] | 1547 |             messages::internalError(asyncResp->res); | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1548 |             return; | 
 | 1549 |         } | 
 | 1550 |  | 
 | 1551 |         const std::string &parentIfaceId = params[0]; | 
 | 1552 |         const std::string &ifaceId = params[1]; | 
 | 1553 |  | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 1554 |         if (!verifyNames(asyncResp->res, parentIfaceId, ifaceId)) | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1555 |         { | 
 | 1556 |             return; | 
 | 1557 |         } | 
 | 1558 |  | 
 | 1559 |         // Get single eth interface data, and call the below callback for JSON | 
 | 1560 |         // preparation | 
| Jason M. Bills | f12894f | 2018-10-09 12:45:45 -0700 | [diff] [blame] | 1561 |         getEthernetIfaceData( | 
 | 1562 |             ifaceId, | 
 | 1563 |             [this, asyncResp, parentIfaceId{std::string(parentIfaceId)}, | 
 | 1564 |              ifaceId{std::string(ifaceId)}]( | 
 | 1565 |                 const bool &success, const EthernetInterfaceData ðData, | 
 | 1566 |                 const boost::container::flat_set<IPv4AddressData> &ipv4Data) { | 
 | 1567 |                 if (success && ethData.vlan_id) | 
 | 1568 |                 { | 
| Ed Tanous | 0f74e64 | 2018-11-12 15:17:05 -0800 | [diff] [blame] | 1569 |                     parseInterfaceData(asyncResp->res.jsonValue, parentIfaceId, | 
 | 1570 |                                        ifaceId, ethData, ipv4Data); | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1571 |  | 
| Jason M. Bills | f12894f | 2018-10-09 12:45:45 -0700 | [diff] [blame] | 1572 |                     auto callback = | 
 | 1573 |                         [asyncResp](const boost::system::error_code ec) { | 
 | 1574 |                             if (ec) | 
 | 1575 |                             { | 
 | 1576 |                                 messages::internalError(asyncResp->res); | 
 | 1577 |                             } | 
 | 1578 |                         }; | 
 | 1579 |                     crow::connections::systemBus->async_method_call( | 
 | 1580 |                         std::move(callback), "xyz.openbmc_project.Network", | 
 | 1581 |                         std::string("/xyz/openbmc_project/network/") + ifaceId, | 
 | 1582 |                         "xyz.openbmc_project.Object.Delete", "Delete"); | 
 | 1583 |                 } | 
 | 1584 |                 else | 
 | 1585 |                 { | 
 | 1586 |                     // ... otherwise return error | 
 | 1587 |                     // TODO(Pawel)consider distinguish between non existing | 
 | 1588 |                     // object, and other errors | 
 | 1589 |                     messages::resourceNotFound( | 
 | 1590 |                         asyncResp->res, "VLAN Network Interface", ifaceId); | 
 | 1591 |                 } | 
 | 1592 |             }); | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1593 |     } | 
| Kowalski, Kamil | e439f0f | 2018-05-21 08:13:57 +0200 | [diff] [blame] | 1594 | }; | 
 | 1595 |  | 
 | 1596 | /** | 
 | 1597 |  * VlanNetworkInterfaceCollection derived class for delivering | 
 | 1598 |  * VLANNetworkInterface Collection Schema | 
 | 1599 |  */ | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1600 | class VlanNetworkInterfaceCollection : public Node | 
 | 1601 | { | 
 | 1602 |   public: | 
 | 1603 |     template <typename CrowApp> | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1604 |     VlanNetworkInterfaceCollection(CrowApp &app) : | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 1605 |         Node(app, "/redfish/v1/Managers/bmc/EthernetInterfaces/<str>/VLANs/", | 
 | 1606 |              std::string()) | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1607 |     { | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1608 |         entityPrivileges = { | 
 | 1609 |             {boost::beast::http::verb::get, {{"Login"}}}, | 
 | 1610 |             {boost::beast::http::verb::head, {{"Login"}}}, | 
 | 1611 |             {boost::beast::http::verb::patch, {{"ConfigureComponents"}}}, | 
 | 1612 |             {boost::beast::http::verb::put, {{"ConfigureComponents"}}}, | 
 | 1613 |             {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}}, | 
 | 1614 |             {boost::beast::http::verb::post, {{"ConfigureComponents"}}}}; | 
| Kowalski, Kamil | e439f0f | 2018-05-21 08:13:57 +0200 | [diff] [blame] | 1615 |     } | 
 | 1616 |  | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1617 |   private: | 
 | 1618 |     /** | 
 | 1619 |      * Functions triggers appropriate requests on DBus | 
 | 1620 |      */ | 
 | 1621 |     void doGet(crow::Response &res, const crow::Request &req, | 
 | 1622 |                const std::vector<std::string> ¶ms) override | 
 | 1623 |     { | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 1624 |         std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res); | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1625 |         if (params.size() != 1) | 
 | 1626 |         { | 
 | 1627 |             // This means there is a problem with the router | 
| Jason M. Bills | f12894f | 2018-10-09 12:45:45 -0700 | [diff] [blame] | 1628 |             messages::internalError(asyncResp->res); | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1629 |             return; | 
| Ed Tanous | 8ceb2ec | 2018-08-13 11:11:56 -0700 | [diff] [blame] | 1630 |         } | 
 | 1631 |  | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 1632 |         const std::string &rootInterfaceName = params[0]; | 
| Kowalski, Kamil | e439f0f | 2018-05-21 08:13:57 +0200 | [diff] [blame] | 1633 |  | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 1634 |         // Get eth interface list, and call the below callback for JSON | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1635 |         // preparation | 
| Jason M. Bills | f12894f | 2018-10-09 12:45:45 -0700 | [diff] [blame] | 1636 |         getEthernetIfaceList( | 
 | 1637 |             [this, asyncResp, | 
 | 1638 |              rootInterfaceName{std::string(rootInterfaceName)}]( | 
 | 1639 |                 const bool &success, | 
 | 1640 |                 const std::vector<std::string> &iface_list) { | 
 | 1641 |                 if (!success) | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1642 |                 { | 
| Jason M. Bills | f12894f | 2018-10-09 12:45:45 -0700 | [diff] [blame] | 1643 |                     messages::internalError(asyncResp->res); | 
 | 1644 |                     return; | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1645 |                 } | 
| Ed Tanous | 0f74e64 | 2018-11-12 15:17:05 -0800 | [diff] [blame] | 1646 |                 asyncResp->res.jsonValue["@odata.type"] = | 
 | 1647 |                     "#VLanNetworkInterfaceCollection." | 
 | 1648 |                     "VLanNetworkInterfaceCollection"; | 
 | 1649 |                 asyncResp->res.jsonValue["@odata.context"] = | 
 | 1650 |                     "/redfish/v1/$metadata" | 
 | 1651 |                     "#VLanNetworkInterfaceCollection." | 
 | 1652 |                     "VLanNetworkInterfaceCollection"; | 
 | 1653 |                 asyncResp->res.jsonValue["Name"] = | 
 | 1654 |                     "VLAN Network Interface Collection"; | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 1655 |  | 
| Jason M. Bills | f12894f | 2018-10-09 12:45:45 -0700 | [diff] [blame] | 1656 |                 nlohmann::json iface_array = nlohmann::json::array(); | 
 | 1657 |  | 
 | 1658 |                 for (const std::string &iface_item : iface_list) | 
 | 1659 |                 { | 
 | 1660 |                     if (boost::starts_with(iface_item, rootInterfaceName + "_")) | 
 | 1661 |                     { | 
 | 1662 |                         iface_array.push_back( | 
 | 1663 |                             {{"@odata.id", | 
 | 1664 |                               "/redfish/v1/Managers/bmc/EthernetInterfaces/" + | 
 | 1665 |                                   rootInterfaceName + "/VLANs/" + iface_item}}); | 
 | 1666 |                     } | 
 | 1667 |                 } | 
 | 1668 |  | 
 | 1669 |                 if (iface_array.empty()) | 
 | 1670 |                 { | 
 | 1671 |                     messages::resourceNotFound( | 
 | 1672 |                         asyncResp->res, "EthernetInterface", rootInterfaceName); | 
 | 1673 |                     return; | 
 | 1674 |                 } | 
 | 1675 |                 asyncResp->res.jsonValue["Members@odata.count"] = | 
 | 1676 |                     iface_array.size(); | 
 | 1677 |                 asyncResp->res.jsonValue["Members"] = std::move(iface_array); | 
 | 1678 |                 asyncResp->res.jsonValue["@odata.id"] = | 
 | 1679 |                     "/redfish/v1/Managers/bmc/EthernetInterfaces/" + | 
 | 1680 |                     rootInterfaceName + "/VLANs"; | 
 | 1681 |             }); | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1682 |     } | 
| Kowalski, Kamil | e439f0f | 2018-05-21 08:13:57 +0200 | [diff] [blame] | 1683 |  | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1684 |     void doPost(crow::Response &res, const crow::Request &req, | 
 | 1685 |                 const std::vector<std::string> ¶ms) override | 
 | 1686 |     { | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 1687 |         std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res); | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1688 |         if (params.size() != 1) | 
 | 1689 |         { | 
| Jason M. Bills | f12894f | 2018-10-09 12:45:45 -0700 | [diff] [blame] | 1690 |             messages::internalError(asyncResp->res); | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1691 |             return; | 
 | 1692 |         } | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1693 |  | 
| Ed Tanous | 0627a2c | 2018-11-29 17:09:23 -0800 | [diff] [blame] | 1694 |         uint32_t vlanId = 0; | 
 | 1695 |         if (!json_util::readJson(req, res, "VLANId", vlanId)) | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1696 |         { | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 1697 |             return; | 
 | 1698 |         } | 
 | 1699 |         const std::string &rootInterfaceName = params[0]; | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 1700 |         auto callback = [asyncResp](const boost::system::error_code ec) { | 
 | 1701 |             if (ec) | 
 | 1702 |             { | 
 | 1703 |                 // TODO(ed) make more consistent error messages based on | 
 | 1704 |                 // phosphor-network responses | 
| Jason M. Bills | f12894f | 2018-10-09 12:45:45 -0700 | [diff] [blame] | 1705 |                 messages::internalError(asyncResp->res); | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 1706 |                 return; | 
 | 1707 |             } | 
| Jason M. Bills | f12894f | 2018-10-09 12:45:45 -0700 | [diff] [blame] | 1708 |             messages::created(asyncResp->res); | 
| Ed Tanous | 4a0cb85 | 2018-10-15 07:55:04 -0700 | [diff] [blame] | 1709 |         }; | 
 | 1710 |         crow::connections::systemBus->async_method_call( | 
 | 1711 |             std::move(callback), "xyz.openbmc_project.Network", | 
 | 1712 |             "/xyz/openbmc_project/network", | 
 | 1713 |             "xyz.openbmc_project.Network.VLAN.Create", "VLAN", | 
| Ed Tanous | 0627a2c | 2018-11-29 17:09:23 -0800 | [diff] [blame] | 1714 |             rootInterfaceName, vlanId); | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1715 |     } | 
| Kowalski, Kamil | e439f0f | 2018-05-21 08:13:57 +0200 | [diff] [blame] | 1716 | }; | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 1717 | } // namespace redfish |