1 #include "config.h"
2 
3 #include "system_configuration.hpp"
4 
5 #include "network_manager.hpp"
6 
7 #include <phosphor-logging/elog-errors.hpp>
8 #include <phosphor-logging/log.hpp>
9 #include <xyz/openbmc_project/Common/error.hpp>
10 
11 namespace phosphor
12 {
13 namespace network
14 {
15 
16 // systemd service to kick start a target.
17 constexpr auto HOSTNAMED_SERVICE = "org.freedesktop.hostname1";
18 constexpr auto HOSTNAMED_SERVICE_PATH = "/org/freedesktop/hostname1";
19 constexpr auto HOSTNAMED_INTERFACE = "org.freedesktop.hostname1";
20 constexpr auto PROPERTY_INTERFACE = "org.freedesktop.DBus.Properties";
21 constexpr auto METHOD_GET = "Get";
22 constexpr auto METHOD_SET = "SetStaticHostname";
23 
24 using namespace phosphor::logging;
25 using namespace sdbusplus::xyz::openbmc_project::Common::Error;
26 using InvalidArgumentMetadata = xyz::openbmc_project::Common::InvalidArgument;
27 
28 using SystemConfigIntf =
29     sdbusplus::xyz::openbmc_project::Network::server::SystemConfiguration;
30 
31 SystemConfiguration::SystemConfiguration(sdbusplus::bus::bus& bus,
32                                          const std::string& objPath,
33                                          Manager& parent) :
34     Iface(bus, objPath.c_str(), true),
35     bus(bus), manager(parent)
36 {
37     auto name = getHostNameFromSystem();
38 
39     SystemConfigIntf::hostName(name);
40     const auto& gatewayList = manager.getRouteTable().getDefaultGateway();
41     const auto& gateway6List = manager.getRouteTable().getDefaultGateway6();
42     // Assign first entry of gateway list
43     std::string gateway;
44     std::string gateway6;
45     if (!gatewayList.empty())
46     {
47         gateway = gatewayList.begin()->second;
48     }
49     if (!gateway6List.empty())
50     {
51         gateway6 = gateway6List.begin()->second;
52     }
53 
54     SystemConfigIntf::defaultGateway(gateway);
55     SystemConfigIntf::defaultGateway6(gateway6);
56 
57     this->emit_object_added();
58 }
59 
60 std::string SystemConfiguration::hostName(std::string name)
61 {
62     if (SystemConfigIntf::hostName() == name)
63     {
64         return name;
65     }
66     auto method = bus.new_method_call(HOSTNAMED_SERVICE, HOSTNAMED_SERVICE_PATH,
67                                       HOSTNAMED_INTERFACE, METHOD_SET);
68 
69     method.append(name, true);
70 
71     if (!bus.call(method))
72     {
73         log<level::ERR>("Failed to set the hostname");
74         report<InternalFailure>();
75         return SystemConfigIntf::hostName();
76     }
77 
78     return SystemConfigIntf::hostName(name);
79 }
80 
81 std::string SystemConfiguration::getHostNameFromSystem() const
82 {
83     try
84     {
85         std::variant<std::string> name;
86         auto method =
87             bus.new_method_call(HOSTNAMED_SERVICE, HOSTNAMED_SERVICE_PATH,
88                                 PROPERTY_INTERFACE, METHOD_GET);
89 
90         method.append(HOSTNAMED_INTERFACE, "Hostname");
91 
92         auto reply = bus.call(method);
93 
94         reply.read(name);
95         return std::get<std::string>(name);
96     }
97     catch (const sdbusplus::exception::exception& ex)
98     {
99         log<level::ERR>(
100             "Failed to get the hostname from systemd-hostnamed service",
101             entry("ERR=%s", ex.what()));
102     }
103     return "";
104 }
105 
106 std::string SystemConfiguration::defaultGateway(std::string gateway)
107 {
108     auto gw = SystemConfigIntf::defaultGateway();
109     if (gw == gateway)
110     {
111         return gw;
112     }
113 
114     if (!isValidIP(AF_INET, gateway))
115     {
116         log<level::ERR>("Not a valid v4 Gateway",
117                         entry("GATEWAY=%s", gateway.c_str()));
118         elog<InvalidArgument>(
119             InvalidArgumentMetadata::ARGUMENT_NAME("GATEWAY"),
120             InvalidArgumentMetadata::ARGUMENT_VALUE(gateway.c_str()));
121     }
122     gw = SystemConfigIntf::defaultGateway(gateway);
123 
124     manager.writeToConfigurationFile();
125     manager.reloadConfigs();
126 
127     return gw;
128 }
129 
130 std::string SystemConfiguration::defaultGateway6(std::string gateway)
131 {
132     auto gw = SystemConfigIntf::defaultGateway6();
133     if (gw == gateway)
134     {
135         return gw;
136     }
137 
138     if (!isValidIP(AF_INET6, gateway))
139     {
140         log<level::ERR>("Not a valid v6 Gateway",
141                         entry("GATEWAY=%s", gateway.c_str()));
142         elog<InvalidArgument>(
143             InvalidArgumentMetadata::ARGUMENT_NAME("GATEWAY"),
144             InvalidArgumentMetadata::ARGUMENT_VALUE(gateway.c_str()));
145     }
146     gw = SystemConfigIntf::defaultGateway6(gateway);
147 
148     manager.writeToConfigurationFile();
149     manager.reloadConfigs();
150 
151     return gw;
152 }
153 
154 } // namespace network
155 } // namespace phosphor
156