transporthandler: Fix path check
Right now, paths for channel names can sometimes conflict if we have
an interface whose name is a subset of another interface. This makes the
match much more explicit. It also happens to remove the string search
completely.
Change-Id: Ia3a91e4a04a28d0b76eade2c5e716017c5431e71
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/transporthandler.cpp b/transporthandler.cpp
index dc602af..a9bc7c8 100644
--- a/transporthandler.cpp
+++ b/transporthandler.cpp
@@ -64,6 +64,16 @@
static constexpr uint8_t oemCmdStart = 192;
static constexpr uint8_t oemCmdEnd = 255;
+// Checks if the ifname is part of the networkd path
+// This assumes the path came from the network subtree PATH_ROOT
+bool ifnameInPath(std::string_view ifname, std::string_view path)
+{
+ constexpr auto rs = PATH_ROOT.size() + 1; // ROOT + separator
+ const auto is = rs + ifname.size(); // ROOT + sep + ifname
+ return path.size() > rs && path.substr(rs).starts_with(ifname) &&
+ (path.size() == is || path[is] == '/');
+}
+
std::optional<ChannelParams> maybeGetChannelParams(sdbusplus::bus_t& bus,
uint8_t channel)
{
@@ -76,7 +86,7 @@
// Enumerate all VLAN + ETHERNET interfaces
auto req = bus.new_method_call(MAPPER_BUS_NAME, MAPPER_OBJ, MAPPER_INTF,
"GetSubTree");
- req.append(PATH_ROOT, 0,
+ req.append(std::string_view(PATH_ROOT), 0,
std::vector<std::string>{INTF_VLAN, INTF_ETHERNET});
auto reply = bus.call(req);
ObjectTree objs;
@@ -85,7 +95,7 @@
ChannelParams params;
for (const auto& [path, impls] : objs)
{
- if (path.find(ifname) == path.npos)
+ if (!ifnameInPath(ifname, path))
{
continue;
}
@@ -474,13 +484,14 @@
// Delete all objects associated with the interface
auto objreq = bus.new_method_call(MAPPER_BUS_NAME, MAPPER_OBJ, MAPPER_INTF,
"GetSubTree");
- objreq.append(PATH_ROOT, 0, std::vector<std::string>{DELETE_INTERFACE});
+ objreq.append(std::string_view(PATH_ROOT), 0,
+ std::vector<std::string>{DELETE_INTERFACE});
auto objreply = bus.call(objreq);
ObjectTree objs;
objreply.read(objs);
for (const auto& [path, impls] : objs)
{
- if (path.find(params.ifname) == path.npos)
+ if (!ifnameInPath(params.ifname, path))
{
continue;
}
@@ -514,7 +525,7 @@
return;
}
- auto req = bus.new_method_call(params.service.c_str(), PATH_ROOT,
+ auto req = bus.new_method_call(params.service.c_str(), PATH_ROOT.c_str(),
INTF_VLAN_CREATE, "VLAN");
req.append(params.ifname, static_cast<uint32_t>(vlan));
auto reply = bus.call(req);
diff --git a/transporthandler.hpp b/transporthandler.hpp
index 019311b..f4a7585 100644
--- a/transporthandler.hpp
+++ b/transporthandler.hpp
@@ -17,6 +17,7 @@
#include <stdplus/net/addr/ether.hpp>
#include <stdplus/net/addr/ip.hpp>
#include <stdplus/str/conv.hpp>
+#include <stdplus/zstring_view.hpp>
#include <user_channel/channel_layer.hpp>
#include <xyz/openbmc_project/Common/error.hpp>
#include <xyz/openbmc_project/Network/EthernetInterface/server.hpp>
@@ -37,8 +38,10 @@
namespace transport
{
+using stdplus::operator""_zsv;
+
// D-Bus Network Daemon definitions
-constexpr auto PATH_ROOT = "/xyz/openbmc_project/network";
+constexpr auto PATH_ROOT = "/xyz/openbmc_project/network"_zsv;
constexpr auto INTF_ETHERNET = "xyz.openbmc_project.Network.EthernetInterface";
constexpr auto INTF_IP = "xyz.openbmc_project.Network.IP";
constexpr auto INTF_IP_CREATE = "xyz.openbmc_project.Network.IP.Create";