Redfish(Network): Add support for IPv4StaticAddresses
Added GET and PATCH support for IPv4StaticAddresses
and modified IPv4Addresses as read-only property
Tested by:
GET
PATCH -D patch.txt -d '{"IPv4StaticAddresses": [{},{},{"Address": "10.7.8.7","SubnetMask": "255.255.0.0","Gateway":"10.7.8.1"}]}'
PATCH -D patch.txt -d '{"IPv4StaticAddresses": [{},{"Address": "10.7.7.8","SubnetMask": "255.255.0.0","Gateway":"10.7.7.1"}]}'
PATCH -D patch.txt -d '{"IPv4StaticAddresses": [null,{},{"Address": "10.7.7.9","SubnetMask": "255.255.0.0","Gateway":"10.7.7.1"}]}']}'
PATCH -D patch.txt -d '{"IPv4StaticAddresses": [{},{"Address": "10.8.8.9"}]}'
Tested with validator and no errors.
Signed-off-by: Ravi Teja <raviteja28031990@gmail.com>
Change-Id: I580787933f1d93d0734e32f71ac9fc80dc108247
diff --git a/redfish-core/lib/ethernet.hpp b/redfish-core/lib/ethernet.hpp
index 2375d68..2667052 100644
--- a/redfish-core/lib/ethernet.hpp
+++ b/redfish-core/lib/ethernet.hpp
@@ -382,10 +382,10 @@
}
// Helper function that extracts data for single ethernet ipv4 address
-inline void
- extractIPData(const std::string ðiface_id,
- const GetManagedObjects &dbus_data,
- boost::container::flat_set<IPv4AddressData> &ipv4_config)
+inline void extractIPData(
+ const std::string ðiface_id, const GetManagedObjects &dbus_data,
+ boost::container::flat_set<IPv4AddressData> &ipv4_config,
+ boost::container::flat_set<IPv4AddressData> &ipv4_static_config)
{
const std::string ipv4PathStart =
"/xyz/openbmc_project/network/" + ethiface_id + "/ipv4/";
@@ -457,6 +457,17 @@
<< " on the " << objpath.first.str << " object";
}
}
+
+ if (ipv4_address.origin == "Static")
+ {
+ IPv4AddressData ipv4_static_address = {
+ objpath.first.str.substr(ipv4PathStart.size())};
+ ipv4_static_address.address = ipv4_address.address;
+ ipv4_static_address.gateway = ipv4_address.gateway;
+ ipv4_static_address.netmask = ipv4_address.netmask;
+ ipv4_static_config.emplace(ipv4_static_address);
+ }
+
// Check if given address is local, or global
ipv4_address.linktype =
boost::starts_with(ipv4_address.address, "169.254.")
@@ -820,12 +831,14 @@
const GetManagedObjects &resp) {
EthernetInterfaceData ethData{};
boost::container::flat_set<IPv4AddressData> ipv4Data;
+ boost::container::flat_set<IPv4AddressData> ipv4StaticData;
boost::container::flat_set<IPv6AddressData> ipv6Data;
boost::container::flat_set<IPv6AddressData> ipv6StaticData;
if (error_code)
{
- callback(false, ethData, ipv4Data, ipv6Data, ipv6StaticData);
+ callback(false, ethData, ipv4Data, ipv4StaticData, ipv6Data,
+ ipv6StaticData);
return;
}
@@ -833,11 +846,12 @@
extractEthernetInterfaceData(ethiface_id, resp, ethData);
if (!found)
{
- callback(false, ethData, ipv4Data, ipv6Data, ipv6StaticData);
+ callback(false, ethData, ipv4Data, ipv4StaticData, ipv6Data,
+ ipv6StaticData);
return;
}
- extractIPData(ethiface_id, resp, ipv4Data);
+ extractIPData(ethiface_id, resp, ipv4Data, ipv4StaticData);
// Fix global GW
for (IPv4AddressData &ipv4 : ipv4Data)
{
@@ -850,7 +864,8 @@
extractIPV6Data(ethiface_id, resp, ipv6Data, ipv6StaticData);
// Finally make a callback with usefull data
- callback(true, ethData, ipv4Data, ipv6Data, ipv6StaticData);
+ callback(true, ethData, ipv4Data, ipv4StaticData, ipv6Data,
+ ipv6StaticData);
},
"xyz.openbmc_project.Network", "/xyz/openbmc_project/network",
"org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
@@ -1122,29 +1137,29 @@
setDHCPv4Config("NTPEnabled", *useNTPServers, asyncResp);
}
}
- void handleIPv4Patch(
+ void handleIPv4StaticPatch(
const std::string &ifaceId, nlohmann::json &input,
- const boost::container::flat_set<IPv4AddressData> &ipv4Data,
+ const boost::container::flat_set<IPv4AddressData> &ipv4StaticData,
const std::shared_ptr<AsyncResp> asyncResp)
{
if (!input.is_array())
{
messages::propertyValueTypeError(asyncResp->res, input.dump(),
- "IPv4Addresses");
+ "IPv4StaticAddresses");
return;
}
int entryIdx = 0;
boost::container::flat_set<IPv4AddressData>::const_iterator thisData =
- ipv4Data.begin();
+ ipv4StaticData.begin();
for (nlohmann::json &thisJson : input)
{
std::string pathString =
- "IPv4Addresses/" + std::to_string(entryIdx);
+ "IPv4StaticAddresses/" + std::to_string(entryIdx);
if (thisJson.is_null())
{
- if (thisData != ipv4Data.end())
+ if (thisData != ipv4StaticData.end())
{
deleteIPv4(ifaceId, thisData->id, asyncResp);
thisData++;
@@ -1166,7 +1181,7 @@
if (thisJson.empty())
{
- if (thisData != ipv4Data.end())
+ if (thisData != ipv4StaticData.end())
{
thisData++;
}
@@ -1229,7 +1244,7 @@
}
// if IP address exist then modify it.
- if (thisData != ipv4Data.end())
+ if (thisData != ipv4StaticData.end())
{
// Apply changes
if (address)
@@ -1308,11 +1323,11 @@
createIPv4(ifaceId, entryIdx, prefixLength, *gateway, *address,
asyncResp);
- nlohmann::json &ipv4AddressJson =
- asyncResp->res.jsonValue["IPv4Addresses"][entryIdx];
- ipv4AddressJson["Address"] = *address;
- ipv4AddressJson["SubnetMask"] = *subnetMask;
- ipv4AddressJson["Gateway"] = *gateway;
+ nlohmann::json &ipv4StaticAddressJson =
+ asyncResp->res.jsonValue["IPv4StaticAddresses"][entryIdx];
+ ipv4StaticAddressJson["Address"] = *address;
+ ipv4StaticAddressJson["SubnetMask"] = *subnetMask;
+ ipv4StaticAddressJson["Gateway"] = *gateway;
}
entryIdx++;
}
@@ -1480,6 +1495,7 @@
nlohmann::json &json_response, const std::string &iface_id,
const EthernetInterfaceData ðData,
const boost::container::flat_set<IPv4AddressData> &ipv4Data,
+ const boost::container::flat_set<IPv4AddressData> &ipv4StaticData,
const boost::container::flat_set<IPv6AddressData> &ipv6Data,
const boost::container::flat_set<IPv6AddressData> &ipv6StaticData)
{
@@ -1524,25 +1540,41 @@
json_response["NameServers"] = ethData.nameservers;
json_response["StaticNameServers"] = ethData.nameservers;
- if (ipv4Data.size() > 0)
+ nlohmann::json &ipv4_array = json_response["IPv4Addresses"];
+ ipv4_array = nlohmann::json::array();
+ for (auto &ipv4_config : ipv4Data)
{
- nlohmann::json &ipv4_array = json_response["IPv4Addresses"];
- ipv4_array = nlohmann::json::array();
- for (auto &ipv4_config : ipv4Data)
+
+ std::string gatewayStr = ipv4_config.gateway;
+ if (gatewayStr.empty())
{
-
- std::string gatewayStr = ipv4_config.gateway;
- if (gatewayStr.empty())
- {
- gatewayStr = "0.0.0.0";
- }
-
- ipv4_array.push_back({{"AddressOrigin", ipv4_config.origin},
- {"SubnetMask", ipv4_config.netmask},
- {"Address", ipv4_config.address},
- {"Gateway", gatewayStr}});
+ gatewayStr = "0.0.0.0";
}
+
+ ipv4_array.push_back({{"AddressOrigin", ipv4_config.origin},
+ {"SubnetMask", ipv4_config.netmask},
+ {"Address", ipv4_config.address},
+ {"Gateway", gatewayStr}});
}
+
+ nlohmann::json &ipv4_static_array =
+ json_response["IPv4StaticAddresses"];
+ ipv4_static_array = nlohmann::json::array();
+ for (auto &ipv4_static_config : ipv4StaticData)
+ {
+
+ std::string gatewayStr = ipv4_static_config.gateway;
+ if (gatewayStr.empty())
+ {
+ gatewayStr = "0.0.0.0";
+ }
+
+ ipv4_static_array.push_back(
+ {{"SubnetMask", ipv4_static_config.netmask},
+ {"Address", ipv4_static_config.address},
+ {"Gateway", gatewayStr}});
+ }
+
json_response["IPv6DefaultGateway"] = ethData.ipv6_default_gateway;
nlohmann::json &ipv6_array = json_response["IPv6Addresses"];
@@ -1583,6 +1615,8 @@
[this, asyncResp, iface_id{std::string(params[0])}](
const bool &success, const EthernetInterfaceData ðData,
const boost::container::flat_set<IPv4AddressData> &ipv4Data,
+ const boost::container::flat_set<IPv4AddressData>
+ &ipv4StaticData,
const boost::container::flat_set<IPv6AddressData> &ipv6Data,
const boost::container::flat_set<IPv6AddressData>
&ipv6StaticData) {
@@ -1609,7 +1643,8 @@
"Management Network Interface";
parseInterfaceData(asyncResp->res.jsonValue, iface_id, ethData,
- ipv4Data, ipv6Data, ipv6StaticData);
+ ipv4Data, ipv4StaticData, ipv6Data,
+ ipv6StaticData);
});
}
@@ -1629,6 +1664,7 @@
std::optional<std::string> macAddress;
std::optional<std::string> ipv6DefaultGateway;
std::optional<nlohmann::json> ipv4Addresses;
+ std::optional<nlohmann::json> ipv4StaticAddresses;
std::optional<nlohmann::json> ipv6Addresses;
std::optional<nlohmann::json> ipv6StaticAddresses;
std::optional<std::vector<std::string>> staticNameServers;
@@ -1637,10 +1673,11 @@
if (!json_util::readJson(
req, res, "HostName", hostname, "IPv4Addresses", ipv4Addresses,
- "MACAddress", macAddress, "StaticNameServers",
- staticNameServers, "IPv6DefaultGateway", ipv6DefaultGateway,
- "IPv6StaticAddresses", ipv6StaticAddresses, "NameServers",
- nameServers, "DHCPv4", dhcpv4))
+ "IPv4StaticAddresses", ipv4StaticAddresses, "MACAddress",
+ macAddress, "StaticNameServers", staticNameServers,
+ "IPv6DefaultGateway", ipv6DefaultGateway, "IPv6StaticAddresses",
+ ipv6StaticAddresses, "NameServers", nameServers, "DHCPv4",
+ dhcpv4))
{
return;
}
@@ -1657,12 +1694,15 @@
[this, asyncResp, iface_id, hostname = std::move(hostname),
macAddress = std::move(macAddress),
ipv4Addresses = std::move(ipv4Addresses),
+ ipv4StaticAddresses = std::move(ipv4StaticAddresses),
ipv6DefaultGateway = std::move(ipv6DefaultGateway),
ipv6StaticAddresses = std::move(ipv6StaticAddresses),
staticNameServers = std::move(staticNameServers),
nameServers = std::move(nameServers)](
const bool &success, const EthernetInterfaceData ðData,
const boost::container::flat_set<IPv4AddressData> &ipv4Data,
+ const boost::container::flat_set<IPv4AddressData>
+ &ipv4StaticData,
const boost::container::flat_set<IPv6AddressData> &ipv6Data,
const boost::container::flat_set<IPv6AddressData>
&ipv6StaticData) {
@@ -1688,14 +1728,21 @@
if (ipv4Addresses)
{
+ messages::propertyNotWritable(asyncResp->res,
+ "IPv4Addresses");
+ }
+
+ if (ipv4StaticAddresses)
+ {
// TODO(ed) for some reason the capture of ipv4Addresses
// above is returning a const value, not a non-const value.
// This doesn't really work for us, as we need to be able to
// efficiently move out the intermedia nlohmann::json
// objects. This makes a copy of the structure, and operates
// on that, but could be done more efficiently
- nlohmann::json ipv4 = std::move(*ipv4Addresses);
- handleIPv4Patch(iface_id, ipv4, ipv4Data, asyncResp);
+ nlohmann::json ipv4Static = std::move(*ipv4StaticAddresses);
+ handleIPv4StaticPatch(iface_id, ipv4Static, ipv4StaticData,
+ asyncResp);
}
if (nameServers)
@@ -1757,6 +1804,7 @@
nlohmann::json &json_response, const std::string &parent_iface_id,
const std::string &iface_id, const EthernetInterfaceData ðData,
const boost::container::flat_set<IPv4AddressData> &ipv4Data,
+ const boost::container::flat_set<IPv4AddressData> &ipv4StaticData,
const boost::container::flat_set<IPv6AddressData> &ipv6Data,
const boost::container::flat_set<IPv6AddressData> &ipv6StaticData)
{
@@ -1824,6 +1872,8 @@
iface_id{std::string(params[1])}](
const bool &success, const EthernetInterfaceData ðData,
const boost::container::flat_set<IPv4AddressData> &ipv4Data,
+ const boost::container::flat_set<IPv4AddressData>
+ &ipv4StaticData,
const boost::container::flat_set<IPv6AddressData> &ipv6Data,
const boost::container::flat_set<IPv6AddressData>
&ipv6StaticData) {
@@ -1831,7 +1881,8 @@
{
parseInterfaceData(asyncResp->res.jsonValue,
parent_iface_id, iface_id, ethData,
- ipv4Data, ipv6Data, ipv6StaticData);
+ ipv4Data, ipv4StaticData, ipv6Data,
+ ipv6StaticData);
}
else
{
@@ -1881,6 +1932,8 @@
ifaceId{std::string(params[1])}, &vlanEnable, &vlanId](
const bool &success, const EthernetInterfaceData ðData,
const boost::container::flat_set<IPv4AddressData> &ipv4Data,
+ const boost::container::flat_set<IPv4AddressData>
+ &ipv4StaticData,
const boost::container::flat_set<IPv6AddressData> &ipv6Data,
const boost::container::flat_set<IPv6AddressData>
&ipv6StaticData) {
@@ -1953,6 +2006,8 @@
ifaceId{std::string(params[1])}](
const bool &success, const EthernetInterfaceData ðData,
const boost::container::flat_set<IPv4AddressData> &ipv4Data,
+ const boost::container::flat_set<IPv4AddressData>
+ &ipv4StaticData,
const boost::container::flat_set<IPv6AddressData> &ipv6Data,
const boost::container::flat_set<IPv6AddressData>
&ipv6StaticData) {