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/log.hpp>
9 #include <stdexcept>
10 #include <string>
11 #include <string_view>
12 #include <xyz/openbmc_project/Common/error.hpp>
13 
14 namespace phosphor
15 {
16 namespace network
17 {
18 
19 using namespace phosphor::logging;
20 using namespace sdbusplus::xyz::openbmc_project::Common::Error;
21 using NotAllowed = sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed;
22 using Reason = xyz::openbmc_project::Common::NotAllowed::REASON;
23 
24 static auto makeObjPath(std::string_view root, IfAddr addr)
25 {
26     auto ret = sdbusplus::message::object_path(std::string(root));
27     ret /= std::to_string(addr);
28     return ret;
29 }
30 
31 template <typename T>
32 struct Proto
33 {
34 };
35 
36 template <>
37 struct Proto<in_addr>
38 {
39     static inline constexpr auto value = IP::Protocol::IPv4;
40 };
41 
42 template <>
43 struct Proto<in6_addr>
44 {
45     static inline constexpr auto value = IP::Protocol::IPv6;
46 };
47 
48 IPAddress::IPAddress(sdbusplus::bus_t& bus, std::string_view objRoot,
49                      stdplus::PinnedRef<EthernetInterface> parent, IfAddr addr,
50                      AddressOrigin origin) :
51     IPAddress(bus, makeObjPath(objRoot, addr), parent, addr, origin)
52 {
53 }
54 
55 IPAddress::IPAddress(sdbusplus::bus_t& bus,
56                      sdbusplus::message::object_path objPath,
57                      stdplus::PinnedRef<EthernetInterface> parent, IfAddr addr,
58                      AddressOrigin origin) :
59     IPIfaces(bus, objPath.str.c_str(), IPIfaces::action::defer_emit),
60     parent(parent), objPath(std::move(objPath))
61 {
62     IP::address(std::to_string(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         log<level::ERR>("Tried to delete a non-static address"),
95             entry("ADDRESS=%s", address().c_str()),
96             entry("PREFIX=%" PRIu8, prefixLength()),
97             entry("INTERFACE=%s", parent.get().interfaceName().c_str());
98         elog<InternalFailure>();
99     }
100 
101     std::unique_ptr<IPAddress> ptr;
102     auto& addrs = parent.get().addrs;
103     for (auto it = addrs.begin(); it != addrs.end(); ++it)
104     {
105         if (it->second.get() == this)
106         {
107             ptr = std::move(it->second);
108             addrs.erase(it);
109             break;
110         }
111     }
112 
113     parent.get().writeConfigurationFile();
114     parent.get().manager.get().reloadConfigs();
115 }
116 
117 } // namespace network
118 } // namespace phosphor
119