blob: ad30c0a0fa7776050f10d933d17c0ce6f1e78226 [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 IIIcb64b992019-04-21 18:45:07 -07005#include "util.hpp"
Ratan Gupta47722dc2017-05-26 18:32:23 +05306
Ratan Gupta255d5142017-08-10 09:02:08 +05307#include <arpa/inet.h>
Ratan Gupta47722dc2017-05-26 18:32:23 +05308#include <net/if.h>
9#include <netinet/in.h>
Ratan Gupta255d5142017-08-10 09:02:08 +053010#include <stdlib.h>
11
William A. Kennington III991a8e82022-10-11 15:02:47 -070012#include <charconv>
Ratan Gupta47722dc2017-05-26 18:32:23 +053013#include <exception>
Gunnar Mills57d9c502018-09-14 14:42:34 -050014#include <sdbusplus/bus.hpp>
William A. Kennington III84bfe672022-07-13 14:15:30 -070015#include <stdplus/gtest/tmp.hpp>
William A. Kennington III991a8e82022-10-11 15:02:47 -070016#include <string_view>
Gunnar Mills57d9c502018-09-14 14:42:34 -050017
18#include <gtest/gtest.h>
Ratan Gupta47722dc2017-05-26 18:32:23 +053019
20namespace phosphor
21{
22namespace network
23{
24
William A. Kennington III991a8e82022-10-11 15:02:47 -070025using std::literals::string_view_literals::operator""sv;
26
William A. Kennington III84bfe672022-07-13 14:15:30 -070027class TestEthernetInterface : public stdplus::gtest::TestWithTmp
Ratan Gupta47722dc2017-05-26 18:32:23 +053028{
Gunnar Mills57d9c502018-09-14 14:42:34 -050029 public:
Patrick Williamsc38b0712022-07-22 19:26:54 -050030 sdbusplus::bus_t bus;
William A. Kennington III84bfe672022-07-13 14:15:30 -070031 std::string confDir;
Ratan Gupta35297172018-11-28 18:40:16 +053032 MockManager manager;
Manojkiran Edaacd6dd52019-10-15 15:00:51 +053033 MockEthernetInterface interface;
Gunnar Mills57d9c502018-09-14 14:42:34 -050034 TestEthernetInterface() :
William A. Kennington III84bfe672022-07-13 14:15:30 -070035 bus(sdbusplus::bus::new_default()), confDir(CaseTmpDir()),
36 manager(bus, "/xyz/openbmc_test/network", confDir),
William A. Kennington IIIebb1ad02019-04-21 18:02:49 -070037 interface(makeInterface(bus, manager))
Ratan Gupta47722dc2017-05-26 18:32:23 +053038
Gunnar Mills57d9c502018-09-14 14:42:34 -050039 {
Gunnar Mills57d9c502018-09-14 14:42:34 -050040 }
Ratan Gupta47722dc2017-05-26 18:32:23 +053041
Patrick Williamsc38b0712022-07-22 19:26:54 -050042 static MockEthernetInterface makeInterface(sdbusplus::bus_t& bus,
Manojkiran Edaacd6dd52019-10-15 15:00:51 +053043 MockManager& manager)
William A. Kennington IIIebb1ad02019-04-21 18:02:49 -070044 {
William A. Kennington III862275a2019-04-22 20:37:08 -070045 mock_clear();
William A. Kennington III9ecb90e2022-10-14 03:12:43 -070046 mock_addIF("test0", /*idx=*/1);
William A. Kennington III0caf2212022-08-18 18:15:51 -070047 return {bus, "/xyz/openbmc_test/network/test0", config::Parser(),
William A. Kennington III9ecb90e2022-10-14 03:12:43 -070048 manager};
William A. Kennington IIIebb1ad02019-04-21 18:02:49 -070049 }
50
Gunnar Mills57d9c502018-09-14 14:42:34 -050051 int countIPObjects()
52 {
53 return interface.getAddresses().size();
54 }
55
56 bool isIPObjectExist(const std::string& ipaddress)
57 {
58 auto address = interface.getAddresses().find(ipaddress);
59 if (address == interface.getAddresses().end())
Ratan Gupta255d5142017-08-10 09:02:08 +053060 {
Gunnar Mills57d9c502018-09-14 14:42:34 -050061 return false;
Ratan Gupta255d5142017-08-10 09:02:08 +053062 }
Gunnar Mills57d9c502018-09-14 14:42:34 -050063 return true;
64 }
Ratan Gupta255d5142017-08-10 09:02:08 +053065
Gunnar Mills57d9c502018-09-14 14:42:34 -050066 bool deleteIPObject(const std::string& ipaddress)
67 {
68 auto address = interface.getAddresses().find(ipaddress);
69 if (address == interface.getAddresses().end())
Ratan Gupta255d5142017-08-10 09:02:08 +053070 {
Gunnar Mills57d9c502018-09-14 14:42:34 -050071 return false;
Ratan Gupta255d5142017-08-10 09:02:08 +053072 }
Gunnar Mills57d9c502018-09-14 14:42:34 -050073 address->second->delete_();
74 return true;
75 }
Ratan Gupta255d5142017-08-10 09:02:08 +053076
Gunnar Mills57d9c502018-09-14 14:42:34 -050077 std::string getObjectPath(const std::string& ipaddress, uint8_t subnetMask,
Lei YU34027572021-08-11 15:23:52 +080078 IP::AddressOrigin origin)
Gunnar Mills57d9c502018-09-14 14:42:34 -050079 {
80 IP::Protocol addressType = IP::Protocol::IPv4;
Ratan Gupta255d5142017-08-10 09:02:08 +053081
Gunnar Mills57d9c502018-09-14 14:42:34 -050082 return interface.generateObjectPath(addressType, ipaddress, subnetMask,
William A. Kennington IIIe25f8b42022-10-11 14:43:28 -070083 origin);
Gunnar Mills57d9c502018-09-14 14:42:34 -050084 }
85
86 void createIPObject(IP::Protocol addressType, const std::string& ipaddress,
William A. Kennington IIIe25f8b42022-10-11 14:43:28 -070087 uint8_t subnetMask)
Gunnar Mills57d9c502018-09-14 14:42:34 -050088 {
William A. Kennington IIIe25f8b42022-10-11 14:43:28 -070089 interface.ip(addressType, ipaddress, subnetMask, "");
Gunnar Mills57d9c502018-09-14 14:42:34 -050090 }
Ratan Gupta47722dc2017-05-26 18:32:23 +053091};
92
William A. Kennington III9ecb90e2022-10-14 03:12:43 -070093TEST_F(TestEthernetInterface, Fields)
94{
95 EXPECT_EQ(0, interface.mtu());
96 EXPECT_EQ("", interface.macAddress());
97 EXPECT_FALSE(interface.linkUp());
98
99 constexpr unsigned idx = 2;
100 constexpr ether_addr mac{0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
101 constexpr unsigned mtu = 150;
102
103 mock_addIF("test1", idx, IFF_RUNNING, mac, mtu);
104 MockEthernetInterface intf(bus, "/xyz/openbmc_test/network/test1",
105 config::Parser(), manager);
106
107 EXPECT_EQ(mtu, intf.mtu());
108 EXPECT_EQ(mac_address::toString(mac), intf.macAddress());
109 EXPECT_TRUE(intf.linkUp());
110}
111
Ratan Gupta47722dc2017-05-26 18:32:23 +0530112TEST_F(TestEthernetInterface, NoIPaddress)
113{
114 EXPECT_EQ(countIPObjects(), 0);
Ratan Gupta47722dc2017-05-26 18:32:23 +0530115}
116
117TEST_F(TestEthernetInterface, AddIPAddress)
118{
119 IP::Protocol addressType = IP::Protocol::IPv4;
William A. Kennington IIIe25f8b42022-10-11 14:43:28 -0700120 createIPObject(addressType, "10.10.10.10", 16);
Ratan Gupta47722dc2017-05-26 18:32:23 +0530121 EXPECT_EQ(true, isIPObjectExist("10.10.10.10"));
Ratan Gupta47722dc2017-05-26 18:32:23 +0530122}
123
124TEST_F(TestEthernetInterface, AddMultipleAddress)
125{
126 IP::Protocol addressType = IP::Protocol::IPv4;
William A. Kennington IIIe25f8b42022-10-11 14:43:28 -0700127 createIPObject(addressType, "10.10.10.10", 16);
128 createIPObject(addressType, "20.20.20.20", 16);
Ratan Gupta47722dc2017-05-26 18:32:23 +0530129 EXPECT_EQ(true, isIPObjectExist("10.10.10.10"));
130 EXPECT_EQ(true, isIPObjectExist("20.20.20.20"));
Ratan Gupta47722dc2017-05-26 18:32:23 +0530131}
132
133TEST_F(TestEthernetInterface, DeleteIPAddress)
134{
135 IP::Protocol addressType = IP::Protocol::IPv4;
William A. Kennington IIIe25f8b42022-10-11 14:43:28 -0700136 createIPObject(addressType, "10.10.10.10", 16);
137 createIPObject(addressType, "20.20.20.20", 16);
Ratan Gupta47722dc2017-05-26 18:32:23 +0530138 deleteIPObject("10.10.10.10");
139 EXPECT_EQ(false, isIPObjectExist("10.10.10.10"));
140 EXPECT_EQ(true, isIPObjectExist("20.20.20.20"));
Ratan Gupta47722dc2017-05-26 18:32:23 +0530141}
142
143TEST_F(TestEthernetInterface, DeleteInvalidIPAddress)
144{
145 EXPECT_EQ(false, deleteIPObject("10.10.10.10"));
146}
147
148TEST_F(TestEthernetInterface, CheckObjectPath)
149{
150 std::string ipaddress = "10.10.10.10";
151 uint8_t prefix = 16;
Lei YU34027572021-08-11 15:23:52 +0800152 IP::AddressOrigin origin = IP::AddressOrigin::Static;
Ratan Gupta47722dc2017-05-26 18:32:23 +0530153
William A. Kennington III991a8e82022-10-11 15:02:47 -0700154 auto path = getObjectPath(ipaddress, prefix, origin);
155 auto pathsv = std::string_view(path);
156 constexpr auto expectedPrefix = "/xyz/openbmc_test/network/test0/ipv4/"sv;
157 EXPECT_TRUE(pathsv.starts_with(expectedPrefix));
158 pathsv.remove_prefix(expectedPrefix.size());
159 uint32_t val;
160 auto [ptr, res] = std::from_chars(pathsv.begin(), pathsv.end(), val, 16);
161 EXPECT_EQ(res, std::errc());
162 EXPECT_EQ(ptr, pathsv.end());
Ratan Gupta47722dc2017-05-26 18:32:23 +0530163
William A. Kennington III991a8e82022-10-11 15:02:47 -0700164 EXPECT_EQ(path, getObjectPath(ipaddress, prefix, origin));
Lei YU34027572021-08-11 15:23:52 +0800165 origin = IP::AddressOrigin::DHCP;
William A. Kennington III991a8e82022-10-11 15:02:47 -0700166 EXPECT_NE(path, getObjectPath(ipaddress, prefix, origin));
Ratan Gupta47722dc2017-05-26 18:32:23 +0530167}
168
Manojkiran Edaacd6dd52019-10-15 15:00:51 +0530169TEST_F(TestEthernetInterface, addStaticNameServers)
Ratan Gupta09f61572017-08-23 16:53:52 +0530170{
Gunnar Mills57d9c502018-09-14 14:42:34 -0500171 ServerList servers = {"9.1.1.1", "9.2.2.2", "9.3.3.3"};
William A. Kennington IIIbd649af2021-10-08 17:55:13 -0700172 EXPECT_CALL(manager, reloadConfigs());
Manojkiran Edaacd6dd52019-10-15 15:00:51 +0530173 interface.staticNameServers(servers);
Ratan Gupta09f61572017-08-23 16:53:52 +0530174 fs::path filePath = confDir;
175 filePath /= "00-bmc-test0.network";
176 config::Parser parser(filePath.string());
William A. Kennington III34bb3e22022-08-18 15:17:22 -0700177 EXPECT_EQ(servers, parser.map.getValueStrings("Network", "DNS"));
Ratan Gupta09f61572017-08-23 16:53:52 +0530178}
179
Manojkiran Edaacd6dd52019-10-15 15:00:51 +0530180TEST_F(TestEthernetInterface, getDynamicNameServers)
181{
182 ServerList servers = {"9.1.1.1", "9.2.2.2", "9.3.3.3"};
183 EXPECT_CALL(interface, getNameServerFromResolvd())
184 .WillRepeatedly(testing::Return(servers));
185 EXPECT_EQ(interface.getNameServerFromResolvd(), servers);
186}
187
Ratan Guptac9645fe2017-08-23 16:53:52 +0530188TEST_F(TestEthernetInterface, addNTPServers)
189{
Gunnar Mills57d9c502018-09-14 14:42:34 -0500190 ServerList servers = {"10.1.1.1", "10.2.2.2", "10.3.3.3"};
William A. Kennington IIIbd649af2021-10-08 17:55:13 -0700191 EXPECT_CALL(manager, reloadConfigs());
Patrick Williams6aef7692021-05-01 06:39:41 -0500192 interface.ntpServers(servers);
Ratan Guptac9645fe2017-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", "NTP"));
Ratan Guptac9645fe2017-08-23 16:53:52 +0530197}
198
Ravi Tejaa5a09442020-07-17 00:57:33 -0500199TEST_F(TestEthernetInterface, addGateway)
200{
201 std::string gateway = "10.3.3.3";
202 interface.defaultGateway(gateway);
203 EXPECT_EQ(interface.defaultGateway(), gateway);
Jiaqing Zhaoc2e061f2022-04-07 21:55:48 +0800204 interface.defaultGateway("");
205 EXPECT_EQ(interface.defaultGateway(), "");
Ravi Tejaa5a09442020-07-17 00:57:33 -0500206}
207
208TEST_F(TestEthernetInterface, addGateway6)
209{
210 std::string gateway6 = "ffff:ffff:ffff:fe80::1";
211 interface.defaultGateway6(gateway6);
212 EXPECT_EQ(interface.defaultGateway6(), gateway6);
Jiaqing Zhaoc2e061f2022-04-07 21:55:48 +0800213 interface.defaultGateway6("");
214 EXPECT_EQ(interface.defaultGateway6(), "");
Ravi Tejaa5a09442020-07-17 00:57:33 -0500215}
216
William A. Kennington III8060c0d2022-08-18 19:19:34 -0700217TEST_F(TestEthernetInterface, DHCPEnabled)
218{
219 EXPECT_CALL(manager, reloadConfigs()).WillRepeatedly(testing::Return());
220
221 using DHCPConf = EthernetInterfaceIntf::DHCPConf;
222 auto test = [&](DHCPConf conf, bool dhcp4, bool dhcp6, bool ra) {
223 EXPECT_EQ(conf, interface.dhcpEnabled());
224 EXPECT_EQ(dhcp4, interface.dhcp4());
225 EXPECT_EQ(dhcp6, interface.dhcp6());
226 EXPECT_EQ(ra, interface.ipv6AcceptRA());
227 };
228 test(DHCPConf::both, /*dhcp4=*/true, /*dhcp6=*/true, /*ra=*/true);
229
230 auto set_test = [&](DHCPConf conf, bool dhcp4, bool dhcp6, bool ra) {
231 EXPECT_EQ(conf, interface.dhcpEnabled(conf));
232 test(conf, dhcp4, dhcp6, ra);
233 };
234 set_test(DHCPConf::none, /*dhcp4=*/false, /*dhcp6=*/false, /*ra=*/false);
235 set_test(DHCPConf::v4, /*dhcp4=*/true, /*dhcp6=*/false, /*ra=*/false);
236 set_test(DHCPConf::v6stateless, /*dhcp4=*/false, /*dhcp6=*/false,
237 /*ra=*/true);
238 set_test(DHCPConf::v6, /*dhcp4=*/false, /*dhcp6=*/true, /*ra=*/true);
239 set_test(DHCPConf::v4v6stateless, /*dhcp4=*/true, /*dhcp6=*/false,
240 /*ra=*/true);
241 set_test(DHCPConf::both, /*dhcp4=*/true, /*dhcp6=*/true, /*ra=*/true);
242
243 auto ind_test = [&](DHCPConf conf, bool dhcp4, bool dhcp6, bool ra) {
244 EXPECT_EQ(dhcp4, interface.dhcp4(dhcp4));
245 EXPECT_EQ(dhcp6, interface.dhcp6(dhcp6));
246 EXPECT_EQ(ra, interface.ipv6AcceptRA(ra));
247 test(conf, dhcp4, dhcp6, ra);
248 };
249 ind_test(DHCPConf::none, /*dhcp4=*/false, /*dhcp6=*/false, /*ra=*/false);
250 ind_test(DHCPConf::v4, /*dhcp4=*/true, /*dhcp6=*/false, /*ra=*/false);
251 ind_test(DHCPConf::v6stateless, /*dhcp4=*/false, /*dhcp6=*/false,
252 /*ra=*/true);
253 ind_test(DHCPConf::v6, /*dhcp4=*/false, /*dhcp6=*/true, /*ra=*/false);
254 set_test(DHCPConf::v6, /*dhcp4=*/false, /*dhcp6=*/true, /*ra=*/true);
255 ind_test(DHCPConf::v4v6stateless, /*dhcp4=*/true, /*dhcp6=*/false,
256 /*ra=*/true);
257 ind_test(DHCPConf::both, /*dhcp4=*/true, /*dhcp6=*/true, /*ra=*/false);
258 set_test(DHCPConf::both, /*dhcp4=*/true, /*dhcp6=*/true, /*ra=*/true);
259}
260
Gunnar Mills57d9c502018-09-14 14:42:34 -0500261} // namespace network
262} // namespace phosphor