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