redfish: network protocol fix for multiple interfaces
Some OpenBMC systems may have multiple ethernet interfaces available but
choose to only enable a subset of them. In these situations, the bmcweb
code needs to ensure it has the proper logic to determine if a
particular protocol is enabled under the redfish API:
redfish/v1/Managers/bmc/NetworkProtocol
For example, to determine if the IPMI service is enabled, bmcweb looks
at systemd units (phosphor-ipmi-net@<eth>.socket) that are instantiated
based on the ethernet interfaces in the system.
This commit changes the logic which determines if a particular protocol
is enabled to look to see if the systemd service is enabled on _any_
network interface. If it is found on any interface then it is considered
to be enabled. For example, if the netipmid application is running
against any of the available network interfaces then it should be
returned to the user that the IPMI protocol is enabled.
The current behavior of the code is somewhat undefined in that it just
uses the state of the last phosphor-ipmi-net@ethX.socket to determine
what it returns to the user.
Tested:
- Confirmed on system with netipmid running on eth0 and not on eth1 that
response was IPMI enabled
- Confirmed on same system that a POST to disable IPMI worked, netipmid
was stopped, and the NetworkProtocol response indicated IPMI disabled*
- Confirmed on same system that a POST to enable IPMI worked, netipmid
was running on eth0, and the NetworkProtocol response indicated IPMI
enabled
- Confirmed on system with both eth0 and eth1 enabled that we got
expected behavior
- No issues in Redfish Validator
* Testing showed an issue introduced with 5c3e927 where a default of
"Disabled" is no longer returned when services like IPMI and SSH are
disabled. The protocol is simply not shown in the NetworkProtocol
response. It can still be enabled via a PATCH operation. As this issue
is unrelated to this patch, I'll submit a separate commit to discuss
whether we should go back to a default when protocols are disabled.
Change-Id: Ib55914b1403ca96ed7ace450f79af3b47b5c8e59
Signed-off-by: Andrew Geissler <geissonator@yahoo.com>
diff --git a/redfish-core/lib/redfish_util.hpp b/redfish-core/lib/redfish_util.hpp
index 2e4c6e5..f5c68d1 100644
--- a/redfish-core/lib/redfish_util.hpp
+++ b/redfish-core/lib/redfish_util.hpp
@@ -163,6 +163,34 @@
bool isProtocolEnabled = ((unitState == "running") ||
(unitState == "listening"));
+ // Some protocols may have multiple services associated with
+ // them (for example IPMI). Look to see if we've already added
+ // an entry for the current protocol.
+ auto find = std::find_if(
+ socketData.begin(), socketData.end(),
+ [&kv](const std::tuple<std::string, std::string, bool>& i) {
+ return std::get<1>(i) == kv.first;
+ });
+ if (find != socketData.end())
+ {
+ // It only takes one enabled systemd service to consider a
+ // protocol enabled so if the current entry already has it
+ // enabled (or the new one is disabled) then just continue,
+ // otherwise remove the current one and add this new one.
+ if (std::get<2>(*find) || !isProtocolEnabled)
+ {
+ // Already registered as enabled or current one is not
+ // enabled, nothing to do
+ BMCWEB_LOG_DEBUG
+ << "protocolName: " << kv.first
+ << ", already true or current one is false: "
+ << isProtocolEnabled;
+ break;
+ }
+ // Remove existing entry and replace with new one (below)
+ socketData.erase(find);
+ }
+
socketData.emplace_back(socketPath, std::string(kv.first),
isProtocolEnabled);
// We found service, return from inner loop.