blob: e65d03c3e26561f31c78971daeb0646926cf21d2 [file] [log] [blame]
Ratan Guptac9645fe2017-08-23 16:53:52 +05301#include "config_parser.hpp"
Ratan Gupta5978dd12017-07-25 13:47:13 +05302#include "ipaddress.hpp"
Ratan Gupta35297172018-11-28 18:40:16 +05303#include "mock_network_manager.hpp"
Gunnar Mills57d9c502018-09-14 14:42:34 -05004#include "mock_syscall.hpp"
William A. Kennington IIIfd862be2022-10-09 18:40:55 -07005#include "system_queries.hpp"
William A. Kennington IIIcb64b992019-04-21 18:45:07 -07006#include "util.hpp"
Ratan Gupta47722dc2017-05-26 18:32:23 +05307
Ratan Gupta255d5142017-08-10 09:02:08 +05308#include <arpa/inet.h>
Ratan Gupta47722dc2017-05-26 18:32:23 +05309#include <net/if.h>
10#include <netinet/in.h>
Ratan Gupta255d5142017-08-10 09:02:08 +053011#include <stdlib.h>
12
William A. Kennington III991a8e82022-10-11 15:02:47 -070013#include <charconv>
Ratan Gupta47722dc2017-05-26 18:32:23 +053014#include <exception>
Gunnar Mills57d9c502018-09-14 14:42:34 -050015#include <sdbusplus/bus.hpp>
William A. Kennington III84bfe672022-07-13 14:15:30 -070016#include <stdplus/gtest/tmp.hpp>
William A. Kennington III991a8e82022-10-11 15:02:47 -070017#include <string_view>
Asmitha Karunanithi003b8b72022-01-06 04:17:59 -060018#include <xyz/openbmc_project/Common/error.hpp>
Gunnar Mills57d9c502018-09-14 14:42:34 -050019
20#include <gtest/gtest.h>
Ratan Gupta47722dc2017-05-26 18:32:23 +053021
22namespace phosphor
23{
24namespace network
25{
26
William A. Kennington III991a8e82022-10-11 15:02:47 -070027using std::literals::string_view_literals::operator""sv;
28
William A. Kennington III84bfe672022-07-13 14:15:30 -070029class TestEthernetInterface : public stdplus::gtest::TestWithTmp
Ratan Gupta47722dc2017-05-26 18:32:23 +053030{
Gunnar Mills57d9c502018-09-14 14:42:34 -050031 public:
Patrick Williamsc38b0712022-07-22 19:26:54 -050032 sdbusplus::bus_t bus;
William A. Kennington III84bfe672022-07-13 14:15:30 -070033 std::string confDir;
Ratan Gupta35297172018-11-28 18:40:16 +053034 MockManager manager;
Manojkiran Edaacd6dd52019-10-15 15:00:51 +053035 MockEthernetInterface interface;
Gunnar Mills57d9c502018-09-14 14:42:34 -050036 TestEthernetInterface() :
William A. Kennington III84bfe672022-07-13 14:15:30 -070037 bus(sdbusplus::bus::new_default()), confDir(CaseTmpDir()),
38 manager(bus, "/xyz/openbmc_test/network", confDir),
William A. Kennington IIIebb1ad02019-04-21 18:02:49 -070039 interface(makeInterface(bus, manager))
Ratan Gupta47722dc2017-05-26 18:32:23 +053040
Gunnar Mills57d9c502018-09-14 14:42:34 -050041 {
Gunnar Mills57d9c502018-09-14 14:42:34 -050042 }
Ratan Gupta47722dc2017-05-26 18:32:23 +053043
Patrick Williamsc38b0712022-07-22 19:26:54 -050044 static MockEthernetInterface makeInterface(sdbusplus::bus_t& bus,
Manojkiran Edaacd6dd52019-10-15 15:00:51 +053045 MockManager& manager)
William A. Kennington IIIebb1ad02019-04-21 18:02:49 -070046 {
William A. Kennington III862275a2019-04-22 20:37:08 -070047 mock_clear();
William A. Kennington III9ecb90e2022-10-14 03:12:43 -070048 mock_addIF("test0", /*idx=*/1);
William A. Kennington IIIfd862be2022-10-09 18:40:55 -070049 return {bus, manager,
50 system::InterfaceInfo{.idx = 1, .flags = 0, .name = "test0"},
William A. Kennington IIId298f932022-10-17 14:31:38 -070051 "/xyz/openbmc_test/network"sv, config::Parser()};
William A. Kennington IIIebb1ad02019-04-21 18:02:49 -070052 }
53
Gunnar Mills57d9c502018-09-14 14:42:34 -050054 int countIPObjects()
55 {
56 return interface.getAddresses().size();
57 }
58
59 bool isIPObjectExist(const std::string& ipaddress)
60 {
61 auto address = interface.getAddresses().find(ipaddress);
62 if (address == interface.getAddresses().end())
Ratan Gupta255d5142017-08-10 09:02:08 +053063 {
Gunnar Mills57d9c502018-09-14 14:42:34 -050064 return false;
Ratan Gupta255d5142017-08-10 09:02:08 +053065 }
Gunnar Mills57d9c502018-09-14 14:42:34 -050066 return true;
67 }
Ratan Gupta255d5142017-08-10 09:02:08 +053068
Gunnar Mills57d9c502018-09-14 14:42:34 -050069 bool deleteIPObject(const std::string& ipaddress)
70 {
71 auto address = interface.getAddresses().find(ipaddress);
72 if (address == interface.getAddresses().end())
Ratan Gupta255d5142017-08-10 09:02:08 +053073 {
Gunnar Mills57d9c502018-09-14 14:42:34 -050074 return false;
Ratan Gupta255d5142017-08-10 09:02:08 +053075 }
Gunnar Mills57d9c502018-09-14 14:42:34 -050076 address->second->delete_();
77 return true;
78 }
Ratan Gupta255d5142017-08-10 09:02:08 +053079
Gunnar Mills57d9c502018-09-14 14:42:34 -050080 std::string getObjectPath(const std::string& ipaddress, uint8_t subnetMask,
Lei YU34027572021-08-11 15:23:52 +080081 IP::AddressOrigin origin)
Gunnar Mills57d9c502018-09-14 14:42:34 -050082 {
83 IP::Protocol addressType = IP::Protocol::IPv4;
Ratan Gupta255d5142017-08-10 09:02:08 +053084
Gunnar Mills57d9c502018-09-14 14:42:34 -050085 return interface.generateObjectPath(addressType, ipaddress, subnetMask,
William A. Kennington IIIe25f8b42022-10-11 14:43:28 -070086 origin);
Gunnar Mills57d9c502018-09-14 14:42:34 -050087 }
88
89 void createIPObject(IP::Protocol addressType, const std::string& ipaddress,
William A. Kennington IIIe25f8b42022-10-11 14:43:28 -070090 uint8_t subnetMask)
Gunnar Mills57d9c502018-09-14 14:42:34 -050091 {
William A. Kennington IIIe25f8b42022-10-11 14:43:28 -070092 interface.ip(addressType, ipaddress, subnetMask, "");
Gunnar Mills57d9c502018-09-14 14:42:34 -050093 }
Asmitha Karunanithi003b8b72022-01-06 04:17:59 -060094
95 void setNtpServers()
96 {
97 ServerList ntpServers = {"10.1.1.1", "10.2.2.2", "10.3.3.3"};
98 interface.EthernetInterfaceIntf::ntpServers(ntpServers);
99 }
100
101 ServerList getNtpServers()
102 {
103 return interface.EthernetInterfaceIntf::ntpServers();
104 }
Ratan Gupta47722dc2017-05-26 18:32:23 +0530105};
106
William A. Kennington III9ecb90e2022-10-14 03:12:43 -0700107TEST_F(TestEthernetInterface, Fields)
108{
109 EXPECT_EQ(0, interface.mtu());
110 EXPECT_EQ("", interface.macAddress());
111 EXPECT_FALSE(interface.linkUp());
112
113 constexpr unsigned idx = 2;
114 constexpr ether_addr mac{0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
115 constexpr unsigned mtu = 150;
116
117 mock_addIF("test1", idx, IFF_RUNNING, mac, mtu);
William A. Kennington IIIfd862be2022-10-09 18:40:55 -0700118 MockEthernetInterface intf(bus, manager,
119 system::InterfaceInfo{.idx = idx,
120 .flags = IFF_RUNNING,
121 .name = "test1",
122 .mac = mac,
123 .mtu = mtu},
William A. Kennington IIId298f932022-10-17 14:31:38 -0700124 "/xyz/openbmc_test/network"sv, config::Parser());
William A. Kennington III9ecb90e2022-10-14 03:12:43 -0700125
126 EXPECT_EQ(mtu, intf.mtu());
William A. Kennington IIIbb0eacc2022-10-21 15:22:06 -0700127 EXPECT_EQ(std::to_string(mac), intf.macAddress());
William A. Kennington III9ecb90e2022-10-14 03:12:43 -0700128 EXPECT_TRUE(intf.linkUp());
129}
130
Ratan Gupta47722dc2017-05-26 18:32:23 +0530131TEST_F(TestEthernetInterface, NoIPaddress)
132{
133 EXPECT_EQ(countIPObjects(), 0);
Ratan Gupta47722dc2017-05-26 18:32:23 +0530134}
135
136TEST_F(TestEthernetInterface, AddIPAddress)
137{
138 IP::Protocol addressType = IP::Protocol::IPv4;
William A. Kennington IIIe25f8b42022-10-11 14:43:28 -0700139 createIPObject(addressType, "10.10.10.10", 16);
Ratan Gupta47722dc2017-05-26 18:32:23 +0530140 EXPECT_EQ(true, isIPObjectExist("10.10.10.10"));
Ratan Gupta47722dc2017-05-26 18:32:23 +0530141}
142
143TEST_F(TestEthernetInterface, AddMultipleAddress)
144{
145 IP::Protocol addressType = IP::Protocol::IPv4;
William A. Kennington IIIe25f8b42022-10-11 14:43:28 -0700146 createIPObject(addressType, "10.10.10.10", 16);
147 createIPObject(addressType, "20.20.20.20", 16);
Ratan Gupta47722dc2017-05-26 18:32:23 +0530148 EXPECT_EQ(true, isIPObjectExist("10.10.10.10"));
149 EXPECT_EQ(true, isIPObjectExist("20.20.20.20"));
Ratan Gupta47722dc2017-05-26 18:32:23 +0530150}
151
152TEST_F(TestEthernetInterface, DeleteIPAddress)
153{
154 IP::Protocol addressType = IP::Protocol::IPv4;
William A. Kennington IIIe25f8b42022-10-11 14:43:28 -0700155 createIPObject(addressType, "10.10.10.10", 16);
156 createIPObject(addressType, "20.20.20.20", 16);
Ratan Gupta47722dc2017-05-26 18:32:23 +0530157 deleteIPObject("10.10.10.10");
158 EXPECT_EQ(false, isIPObjectExist("10.10.10.10"));
159 EXPECT_EQ(true, isIPObjectExist("20.20.20.20"));
Ratan Gupta47722dc2017-05-26 18:32:23 +0530160}
161
162TEST_F(TestEthernetInterface, DeleteInvalidIPAddress)
163{
164 EXPECT_EQ(false, deleteIPObject("10.10.10.10"));
165}
166
167TEST_F(TestEthernetInterface, CheckObjectPath)
168{
169 std::string ipaddress = "10.10.10.10";
170 uint8_t prefix = 16;
Lei YU34027572021-08-11 15:23:52 +0800171 IP::AddressOrigin origin = IP::AddressOrigin::Static;
Ratan Gupta47722dc2017-05-26 18:32:23 +0530172
William A. Kennington III991a8e82022-10-11 15:02:47 -0700173 auto path = getObjectPath(ipaddress, prefix, origin);
174 auto pathsv = std::string_view(path);
175 constexpr auto expectedPrefix = "/xyz/openbmc_test/network/test0/ipv4/"sv;
176 EXPECT_TRUE(pathsv.starts_with(expectedPrefix));
177 pathsv.remove_prefix(expectedPrefix.size());
178 uint32_t val;
179 auto [ptr, res] = std::from_chars(pathsv.begin(), pathsv.end(), val, 16);
180 EXPECT_EQ(res, std::errc());
181 EXPECT_EQ(ptr, pathsv.end());
Ratan Gupta47722dc2017-05-26 18:32:23 +0530182
William A. Kennington III991a8e82022-10-11 15:02:47 -0700183 EXPECT_EQ(path, getObjectPath(ipaddress, prefix, origin));
Lei YU34027572021-08-11 15:23:52 +0800184 origin = IP::AddressOrigin::DHCP;
William A. Kennington III991a8e82022-10-11 15:02:47 -0700185 EXPECT_NE(path, getObjectPath(ipaddress, prefix, origin));
Ratan Gupta47722dc2017-05-26 18:32:23 +0530186}
187
Manojkiran Edaacd6dd52019-10-15 15:00:51 +0530188TEST_F(TestEthernetInterface, addStaticNameServers)
Ratan Gupta09f61572017-08-23 16:53:52 +0530189{
Gunnar Mills57d9c502018-09-14 14:42:34 -0500190 ServerList servers = {"9.1.1.1", "9.2.2.2", "9.3.3.3"};
William A. Kennington IIIbd649af2021-10-08 17:55:13 -0700191 EXPECT_CALL(manager, reloadConfigs());
Manojkiran Edaacd6dd52019-10-15 15:00:51 +0530192 interface.staticNameServers(servers);
Ratan Gupta09f61572017-08-23 16:53:52 +0530193 fs::path filePath = confDir;
194 filePath /= "00-bmc-test0.network";
195 config::Parser parser(filePath.string());
William A. Kennington III34bb3e22022-08-18 15:17:22 -0700196 EXPECT_EQ(servers, parser.map.getValueStrings("Network", "DNS"));
Ratan Gupta09f61572017-08-23 16:53:52 +0530197}
198
Manojkiran Edaacd6dd52019-10-15 15:00:51 +0530199TEST_F(TestEthernetInterface, getDynamicNameServers)
200{
201 ServerList servers = {"9.1.1.1", "9.2.2.2", "9.3.3.3"};
202 EXPECT_CALL(interface, getNameServerFromResolvd())
203 .WillRepeatedly(testing::Return(servers));
204 EXPECT_EQ(interface.getNameServerFromResolvd(), servers);
205}
206
Asmitha Karunanithi003b8b72022-01-06 04:17:59 -0600207TEST_F(TestEthernetInterface, addStaticNTPServers)
Ratan Guptac9645fe2017-08-23 16:53:52 +0530208{
Gunnar Mills57d9c502018-09-14 14:42:34 -0500209 ServerList servers = {"10.1.1.1", "10.2.2.2", "10.3.3.3"};
William A. Kennington IIIbd649af2021-10-08 17:55:13 -0700210 EXPECT_CALL(manager, reloadConfigs());
Asmitha Karunanithi003b8b72022-01-06 04:17:59 -0600211 interface.staticNTPServers(servers);
Ratan Guptac9645fe2017-08-23 16:53:52 +0530212 fs::path filePath = confDir;
213 filePath /= "00-bmc-test0.network";
214 config::Parser parser(filePath.string());
William A. Kennington III34bb3e22022-08-18 15:17:22 -0700215 EXPECT_EQ(servers, parser.map.getValueStrings("Network", "NTP"));
Ratan Guptac9645fe2017-08-23 16:53:52 +0530216}
217
Asmitha Karunanithi003b8b72022-01-06 04:17:59 -0600218TEST_F(TestEthernetInterface, addNTPServers)
219{
220 using namespace sdbusplus::xyz::openbmc_project::Common::Error;
221 ServerList servers = {"10.1.1.1", "10.2.2.2", "10.3.3.3"};
222 EXPECT_THROW(interface.ntpServers(servers), NotAllowed);
223}
224
225TEST_F(TestEthernetInterface, getNTPServers)
226{
227 ServerList servers = {"10.1.1.1", "10.2.2.2", "10.3.3.3"};
228 setNtpServers();
229 EXPECT_EQ(getNtpServers(), servers);
230}
231
Ravi Tejaa5a09442020-07-17 00:57:33 -0500232TEST_F(TestEthernetInterface, addGateway)
233{
234 std::string gateway = "10.3.3.3";
235 interface.defaultGateway(gateway);
236 EXPECT_EQ(interface.defaultGateway(), gateway);
Jiaqing Zhaoc2e061f2022-04-07 21:55:48 +0800237 interface.defaultGateway("");
238 EXPECT_EQ(interface.defaultGateway(), "");
Ravi Tejaa5a09442020-07-17 00:57:33 -0500239}
240
241TEST_F(TestEthernetInterface, addGateway6)
242{
243 std::string gateway6 = "ffff:ffff:ffff:fe80::1";
244 interface.defaultGateway6(gateway6);
245 EXPECT_EQ(interface.defaultGateway6(), gateway6);
Jiaqing Zhaoc2e061f2022-04-07 21:55:48 +0800246 interface.defaultGateway6("");
247 EXPECT_EQ(interface.defaultGateway6(), "");
Ravi Tejaa5a09442020-07-17 00:57:33 -0500248}
249
William A. Kennington III8060c0d2022-08-18 19:19:34 -0700250TEST_F(TestEthernetInterface, DHCPEnabled)
251{
252 EXPECT_CALL(manager, reloadConfigs()).WillRepeatedly(testing::Return());
253
254 using DHCPConf = EthernetInterfaceIntf::DHCPConf;
255 auto test = [&](DHCPConf conf, bool dhcp4, bool dhcp6, bool ra) {
256 EXPECT_EQ(conf, interface.dhcpEnabled());
257 EXPECT_EQ(dhcp4, interface.dhcp4());
258 EXPECT_EQ(dhcp6, interface.dhcp6());
259 EXPECT_EQ(ra, interface.ipv6AcceptRA());
260 };
261 test(DHCPConf::both, /*dhcp4=*/true, /*dhcp6=*/true, /*ra=*/true);
262
263 auto set_test = [&](DHCPConf conf, bool dhcp4, bool dhcp6, bool ra) {
264 EXPECT_EQ(conf, interface.dhcpEnabled(conf));
265 test(conf, dhcp4, dhcp6, ra);
266 };
267 set_test(DHCPConf::none, /*dhcp4=*/false, /*dhcp6=*/false, /*ra=*/false);
268 set_test(DHCPConf::v4, /*dhcp4=*/true, /*dhcp6=*/false, /*ra=*/false);
269 set_test(DHCPConf::v6stateless, /*dhcp4=*/false, /*dhcp6=*/false,
270 /*ra=*/true);
271 set_test(DHCPConf::v6, /*dhcp4=*/false, /*dhcp6=*/true, /*ra=*/true);
272 set_test(DHCPConf::v4v6stateless, /*dhcp4=*/true, /*dhcp6=*/false,
273 /*ra=*/true);
274 set_test(DHCPConf::both, /*dhcp4=*/true, /*dhcp6=*/true, /*ra=*/true);
275
276 auto ind_test = [&](DHCPConf conf, bool dhcp4, bool dhcp6, bool ra) {
277 EXPECT_EQ(dhcp4, interface.dhcp4(dhcp4));
278 EXPECT_EQ(dhcp6, interface.dhcp6(dhcp6));
279 EXPECT_EQ(ra, interface.ipv6AcceptRA(ra));
280 test(conf, dhcp4, dhcp6, ra);
281 };
282 ind_test(DHCPConf::none, /*dhcp4=*/false, /*dhcp6=*/false, /*ra=*/false);
283 ind_test(DHCPConf::v4, /*dhcp4=*/true, /*dhcp6=*/false, /*ra=*/false);
284 ind_test(DHCPConf::v6stateless, /*dhcp4=*/false, /*dhcp6=*/false,
285 /*ra=*/true);
286 ind_test(DHCPConf::v6, /*dhcp4=*/false, /*dhcp6=*/true, /*ra=*/false);
287 set_test(DHCPConf::v6, /*dhcp4=*/false, /*dhcp6=*/true, /*ra=*/true);
288 ind_test(DHCPConf::v4v6stateless, /*dhcp4=*/true, /*dhcp6=*/false,
289 /*ra=*/true);
290 ind_test(DHCPConf::both, /*dhcp4=*/true, /*dhcp6=*/true, /*ra=*/false);
291 set_test(DHCPConf::both, /*dhcp4=*/true, /*dhcp6=*/true, /*ra=*/true);
292}
293
Gunnar Mills57d9c502018-09-14 14:42:34 -0500294} // namespace network
295} // namespace phosphor