1 #include "ipaddress.hpp"
2
3 #include "ethernet_interface.hpp"
4 #include "network_manager.hpp"
5 #include "util.hpp"
6
7 #include <phosphor-logging/elog-errors.hpp>
8 #include <phosphor-logging/lg2.hpp>
9 #include <xyz/openbmc_project/Common/error.hpp>
10
11 #include <stdexcept>
12 #include <string>
13 #include <string_view>
14
15 namespace phosphor
16 {
17 namespace network
18 {
19
20 using namespace phosphor::logging;
21 using namespace sdbusplus::xyz::openbmc_project::Common::Error;
22 using NotAllowed = sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed;
23 using Reason = xyz::openbmc_project::Common::NotAllowed::REASON;
24
makeObjPath(std::string_view root,stdplus::SubnetAny addr)25 static auto makeObjPath(std::string_view root, stdplus::SubnetAny addr)
26 {
27 auto ret = sdbusplus::message::object_path(std::string(root));
28 stdplus::ToStrHandle<stdplus::ToStr<stdplus::SubnetAny>> tsh;
29 ret /= tsh(addr);
30 return ret;
31 }
32
33 template <typename T>
34 struct Proto
35 {};
36
37 template <>
38 struct Proto<stdplus::In4Addr>
39 {
40 static inline constexpr auto value = IP::Protocol::IPv4;
41 };
42
43 template <>
44 struct Proto<stdplus::In6Addr>
45 {
46 static inline constexpr auto value = IP::Protocol::IPv6;
47 };
48
IPAddress(sdbusplus::bus_t & bus,std::string_view objRoot,stdplus::PinnedRef<EthernetInterface> parent,stdplus::SubnetAny addr,AddressOrigin origin)49 IPAddress::IPAddress(sdbusplus::bus_t& bus, std::string_view objRoot,
50 stdplus::PinnedRef<EthernetInterface> parent,
51 stdplus::SubnetAny addr, AddressOrigin origin) :
52 IPAddress(bus, makeObjPath(objRoot, addr), parent, addr, origin)
53 {}
54
IPAddress(sdbusplus::bus_t & bus,sdbusplus::message::object_path objPath,stdplus::PinnedRef<EthernetInterface> parent,stdplus::SubnetAny addr,AddressOrigin origin)55 IPAddress::IPAddress(sdbusplus::bus_t& bus,
56 sdbusplus::message::object_path objPath,
57 stdplus::PinnedRef<EthernetInterface> parent,
58 stdplus::SubnetAny addr, AddressOrigin origin) :
59 IPIfaces(bus, objPath.str.c_str(), IPIfaces::action::defer_emit),
60 parent(parent), objPath(std::move(objPath))
61 {
62 IP::address(stdplus::toStr(addr.getAddr()), true);
63 IP::prefixLength(addr.getPfx(), true);
64 IP::type(std::visit([](auto v) { return Proto<decltype(v)>::value; },
65 addr.getAddr()),
66 true);
67 IP::origin(origin, true);
68 emit_object_added();
69 }
address(std::string)70 std::string IPAddress::address(std::string /*ipAddress*/)
71 {
72 elog<NotAllowed>(Reason("Property update is not allowed"));
73 }
prefixLength(uint8_t)74 uint8_t IPAddress::prefixLength(uint8_t /*value*/)
75 {
76 elog<NotAllowed>(Reason("Property update is not allowed"));
77 }
gateway(std::string)78 std::string IPAddress::gateway(std::string /*gateway*/)
79 {
80 elog<NotAllowed>(Reason("Property update is not allowed"));
81 }
type(IP::Protocol)82 IP::Protocol IPAddress::type(IP::Protocol /*type*/)
83 {
84 elog<NotAllowed>(Reason("Property update is not allowed"));
85 }
origin(IP::AddressOrigin)86 IP::AddressOrigin IPAddress::origin(IP::AddressOrigin /*origin*/)
87 {
88 elog<NotAllowed>(Reason("Property update is not allowed"));
89 }
delete_()90 void IPAddress::delete_()
91 {
92 if (origin() != IP::AddressOrigin::Static)
93 {
94 lg2::error("Tried to delete a non-static address {NET_IP} prefix "
95 "{NET_PFX} interface {NET_INTF}",
96 "NET_IP", address(), "NET_PFX", prefixLength(), "NET_INTF",
97 parent.get().interfaceName());
98
99 elog<NotAllowed>(Reason("Not allowed to delete a non-static address"));
100 }
101
102 std::unique_ptr<IPAddress> ptr;
103 auto& addrs = parent.get().addrs;
104 for (auto it = addrs.begin(); it != addrs.end(); ++it)
105 {
106 if (it->second.get() == this)
107 {
108 ptr = std::move(it->second);
109 addrs.erase(it);
110 break;
111 }
112 }
113
114 parent.get().writeConfigurationFile();
115 parent.get().manager.get().reloadConfigs();
116 }
117
118 } // namespace network
119 } // namespace phosphor
120