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 
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 
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 
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 }
70 std::string IPAddress::address(std::string /*ipAddress*/)
71 {
72     elog<NotAllowed>(Reason("Property update is not allowed"));
73 }
74 uint8_t IPAddress::prefixLength(uint8_t /*value*/)
75 {
76     elog<NotAllowed>(Reason("Property update is not allowed"));
77 }
78 std::string IPAddress::gateway(std::string /*gateway*/)
79 {
80     elog<NotAllowed>(Reason("Property update is not allowed"));
81 }
82 IP::Protocol IPAddress::type(IP::Protocol /*type*/)
83 {
84     elog<NotAllowed>(Reason("Property update is not allowed"));
85 }
86 IP::AddressOrigin IPAddress::origin(IP::AddressOrigin /*origin*/)
87 {
88     elog<NotAllowed>(Reason("Property update is not allowed"));
89 }
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