blob: 73e254412db0c244b6570cfcca7ba6ab14b68dab [file] [log] [blame]
Ratan Gupta1dc91782018-04-19 16:47:12 +05301#include "config.h"
Patrick Williams1334b7b2021-02-22 17:15:12 -06002
Ratan Gupta1dc91782018-04-19 16:47:12 +05303#include "snmp_conf_manager.hpp"
Patrick Williams1334b7b2021-02-22 17:15:12 -06004
Ratan Gupta212f53e2018-04-30 17:28:05 +05305#include "snmp_serialize.hpp"
Ratan Gupta213517b2018-04-28 13:41:09 +05306#include "snmp_util.hpp"
7#include "xyz/openbmc_project/Common/error.hpp"
8
Patrick Williams1334b7b2021-02-22 17:15:12 -06009#include <arpa/inet.h>
10
Ratan Gupta213517b2018-04-28 13:41:09 +053011#include <phosphor-logging/elog-errors.hpp>
Ratan Gupta1dc91782018-04-19 16:47:12 +053012#include <phosphor-logging/log.hpp>
13
14#include <experimental/filesystem>
15
16namespace phosphor
17{
18namespace network
19{
20namespace snmp
21{
22
23using namespace phosphor::logging;
Ratan Gupta213517b2018-04-28 13:41:09 +053024using namespace sdbusplus::xyz::openbmc_project::Common::Error;
25using Argument = xyz::openbmc_project::Common::InvalidArgument;
Ratan Gupta1dc91782018-04-19 16:47:12 +053026
27ConfManager::ConfManager(sdbusplus::bus::bus& bus, const char* objPath) :
Ratan Gupta212f53e2018-04-30 17:28:05 +053028 details::CreateIface(bus, objPath, true),
29 dbusPersistentLocation(SNMP_CONF_PERSIST_PATH), bus(bus),
30 objectPath(objPath)
Patrick Williams1334b7b2021-02-22 17:15:12 -060031{}
Ratan Gupta1dc91782018-04-19 16:47:12 +053032
Ratan Guptad84e3272018-09-06 16:52:52 +053033std::string ConfManager::client(std::string address, uint16_t port)
Ratan Gupta1dc91782018-04-19 16:47:12 +053034{
Ratan Gupta9c4fed62018-11-16 17:47:54 +053035 // will throw exception if it is already configured.
36 checkClientConfigured(address, port);
Ratan Guptaa7ff3852018-11-16 14:05:57 +053037
38 lastClientId++;
Ratan Gupta213517b2018-04-28 13:41:09 +053039 try
40 {
41 // just to check whether given address is valid or not.
42 resolveAddress(address);
43 }
Patrick Williamsc3600d82021-10-06 12:38:25 -050044 catch (const InternalFailure& e)
Ratan Gupta213517b2018-04-28 13:41:09 +053045 {
46 log<level::ERR>("Not a valid address"),
47 entry("ADDRESS=%s", address.c_str());
48 elog<InvalidArgument>(Argument::ARGUMENT_NAME("Address"),
49 Argument::ARGUMENT_VALUE(address.c_str()));
50 }
Ratan Guptad84e3272018-09-06 16:52:52 +053051
Ratan Guptaa7ff3852018-11-16 14:05:57 +053052 // create the D-Bus object
Ratan Gupta213517b2018-04-28 13:41:09 +053053 std::experimental::filesystem::path objPath;
54 objPath /= objectPath;
Ratan Guptaa7ff3852018-11-16 14:05:57 +053055 objPath /= std::to_string(lastClientId);
56
Ratan Gupta212f53e2018-04-30 17:28:05 +053057 auto client = std::make_unique<phosphor::network::snmp::Client>(
58 bus, objPath.string().c_str(), *this, address, port);
Ratan Gupta212f53e2018-04-30 17:28:05 +053059
Ratan Guptaa7ff3852018-11-16 14:05:57 +053060 // save the D-Bus object
61 serialize(lastClientId, *client, dbusPersistentLocation);
62
63 this->clients.emplace(lastClientId, std::move(client));
Ratan Guptad84e3272018-09-06 16:52:52 +053064 return objPath.string();
Ratan Gupta1dc91782018-04-19 16:47:12 +053065}
66
Ratan Gupta9c4fed62018-11-16 17:47:54 +053067void ConfManager::checkClientConfigured(const std::string& address,
68 uint16_t port)
69{
70 if (address.empty())
71 {
72 log<level::ERR>("Invalid address");
73 elog<InvalidArgument>(Argument::ARGUMENT_NAME("ADDRESS"),
74 Argument::ARGUMENT_VALUE(address.c_str()));
75 }
76
Asmitha Karunanithi9e60ef52021-05-31 05:52:48 -050077 unsigned char buf[sizeof(struct in6_addr)];
78 int isValid = inet_pton(AF_INET, address.c_str(), buf);
79 if (isValid < 1)
80 {
81 log<level::ERR>("Invalid address");
82 elog<InvalidArgument>(Argument::ARGUMENT_NAME("ADDRESS"),
83 Argument::ARGUMENT_VALUE(address.c_str()));
84 }
85
Ratan Gupta9c4fed62018-11-16 17:47:54 +053086 for (const auto& val : clients)
87 {
88 if (val.second.get()->address() == address &&
89 val.second.get()->port() == port)
90 {
91 log<level::ERR>("Client already exist");
92 // TODO Add the error(Object already exist) in the D-Bus interface
93 // then make the change here,meanwhile send the Internal Failure.
94 elog<InvalidArgument>(
95 Argument::ARGUMENT_NAME("ADDRESS"),
96 Argument::ARGUMENT_VALUE("Client already exist."));
97 }
98 }
99}
100
Ratan Guptaa7ff3852018-11-16 14:05:57 +0530101void ConfManager::deleteSNMPClient(Id id)
Ratan Gupta1dc91782018-04-19 16:47:12 +0530102{
Ratan Guptaa7ff3852018-11-16 14:05:57 +0530103 auto it = clients.find(id);
Ratan Gupta1dc91782018-04-19 16:47:12 +0530104 if (it == clients.end())
105 {
106 log<level::ERR>("Unable to delete the snmp client.",
Ratan Guptaa7ff3852018-11-16 14:05:57 +0530107 entry("ID=%d", id));
Ratan Gupta1dc91782018-04-19 16:47:12 +0530108 return;
109 }
Ratan Gupta212f53e2018-04-30 17:28:05 +0530110
111 std::error_code ec;
112 // remove the persistent file
113 fs::path fileName = dbusPersistentLocation;
Ratan Guptaa7ff3852018-11-16 14:05:57 +0530114 fileName /= std::to_string(id);
Ratan Gupta212f53e2018-04-30 17:28:05 +0530115
116 if (fs::exists(fileName))
117 {
118 if (!fs::remove(fileName, ec))
119 {
120 log<level::ERR>("Unable to delete the file",
121 entry("FILE=%s", fileName.c_str()),
122 entry("ERROR=%d", ec.value()));
123 }
124 }
125 else
126 {
127 log<level::ERR>("File doesn't exist",
128 entry("FILE=%s", fileName.c_str()));
129 }
130 // remove the D-Bus Object.
Ratan Gupta1dc91782018-04-19 16:47:12 +0530131 this->clients.erase(it);
132}
133
Ratan Gupta212f53e2018-04-30 17:28:05 +0530134void ConfManager::restoreClients()
135{
136 if (!fs::exists(dbusPersistentLocation) ||
137 fs::is_empty(dbusPersistentLocation))
138 {
139 return;
140 }
141
142 for (auto& confFile :
143 fs::recursive_directory_iterator(dbusPersistentLocation))
144 {
145 if (!fs::is_regular_file(confFile))
146 {
147 continue;
148 }
149
150 auto managerID = confFile.path().filename().string();
Ratan Guptaa7ff3852018-11-16 14:05:57 +0530151 Id idNum = std::stol(managerID);
Ratan Gupta212f53e2018-04-30 17:28:05 +0530152
153 fs::path objPath = objectPath;
Ratan Guptaa7ff3852018-11-16 14:05:57 +0530154 objPath /= managerID;
Ratan Gupta212f53e2018-04-30 17:28:05 +0530155 auto manager =
156 std::make_unique<Client>(bus, objPath.string().c_str(), *this);
157 if (deserialize(confFile.path(), *manager))
158 {
159 manager->emit_object_added();
Ratan Guptaa7ff3852018-11-16 14:05:57 +0530160 this->clients.emplace(idNum, std::move(manager));
161 if (idNum > lastClientId)
162 {
163 lastClientId = idNum;
164 }
Ratan Gupta212f53e2018-04-30 17:28:05 +0530165 }
166 }
167}
168
Ratan Gupta1dc91782018-04-19 16:47:12 +0530169} // namespace snmp
170} // namespace network
171} // namespace phosphor