blob: d09c7df6f3fd125031c710939f2da867f18709a4 [file] [log] [blame]
Junxiao Shicde37ad2015-12-24 01:02:05 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Junxiao Shi84d62cb2017-07-12 16:15:18 +00002/*
Davide Pesaventod7083a52023-10-19 17:51:16 -04003 * Copyright (c) 2014-2023, Regents of the University of California,
Junxiao Shicde37ad2015-12-24 01:02:05 -07004 * Arizona Board of Regents,
5 * Colorado State University,
6 * University Pierre & Marie Curie, Sorbonne University,
7 * Washington University in St. Louis,
8 * Beijing Institute of Technology,
9 * The University of Memphis.
10 *
11 * This file is part of NFD (Named Data Networking Forwarding Daemon).
12 * See AUTHORS.md for complete list of NFD authors and contributors.
13 *
14 * NFD is free software: you can redistribute it and/or modify it under the terms
15 * of the GNU General Public License as published by the Free Software Foundation,
16 * either version 3 of the License, or (at your option) any later version.
17 *
18 * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
19 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
20 * PURPOSE. See the GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License along with
23 * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
24 */
25
26#include "face/ethernet-factory.hpp"
27
Junxiao Shi7003c602017-01-10 13:35:28 +000028#include "ethernet-fixture.hpp"
29#include "face-system-fixture.hpp"
Junxiao Shi79a92082017-08-08 02:40:59 +000030#include "factory-test-common.hpp"
Davide Pesaventob15276f2017-07-15 16:27:13 -040031
Junxiao Shi7003c602017-01-10 13:35:28 +000032#include <boost/algorithm/string/replace.hpp>
Junxiao Shicde37ad2015-12-24 01:02:05 -070033
Davide Pesaventoe422f9e2022-06-03 01:30:23 -040034namespace nfd::tests {
35
36using face::EthernetFactory;
Junxiao Shicde37ad2015-12-24 01:02:05 -070037
Junxiao Shi0ba6d642017-07-17 00:53:22 +000038class EthernetFactoryFixture : public EthernetFixture
39 , public FaceSystemFactoryFixture<EthernetFactory>
Junxiao Shi7003c602017-01-10 13:35:28 +000040{
Junxiao Shi0ba6d642017-07-17 00:53:22 +000041protected:
Davide Pesaventob15276f2017-07-15 16:27:13 -040042 std::set<std::string>
43 listUrisOfAvailableNetifs() const
44 {
45 std::set<std::string> uris;
46 std::transform(netifs.begin(), netifs.end(), std::inserter(uris, uris.end()),
Davide Pesaventod7083a52023-10-19 17:51:16 -040047 [] (const auto& netif) { return FaceUri::fromDev(netif->getName()).toString(); });
Davide Pesaventob15276f2017-07-15 16:27:13 -040048 return uris;
49 }
50
Junxiao Shi7003c602017-01-10 13:35:28 +000051 std::vector<const Face*>
Teng Liangbfea5752017-03-29 04:51:10 +000052 listEtherMcastFaces(ndn::nfd::LinkType linkType = ndn::nfd::LINK_TYPE_MULTI_ACCESS) const
Junxiao Shi7003c602017-01-10 13:35:28 +000053 {
Davide Pesaventod7083a52023-10-19 17:51:16 -040054 return listFacesByScheme("ether", linkType);
Junxiao Shi7003c602017-01-10 13:35:28 +000055 }
56
Davide Pesaventoa9ec67c2023-10-19 20:04:04 -040057 shared_ptr<ndn::net::NetworkInterface>
58 makeFakeNetif()
Junxiao Shi7003c602017-01-10 13:35:28 +000059 {
Davide Pesaventoa9ec67c2023-10-19 20:04:04 -040060 static int counter = 0;
61 ++counter;
62
63 auto netif = netmon->makeNetworkInterface();
64 netif->setIndex(1000 + counter);
65 netif->setName("ethdummy" + std::to_string(counter));
66 netif->setType(ndn::net::InterfaceType::ETHERNET);
67 netif->setFlags(IFF_MULTICAST | IFF_UP);
68 netif->setState(ndn::net::InterfaceState::RUNNING);
69 netif->setMtu(1500);
70 netif->setEthernetAddress(ethernet::Address{0x00, 0x00, 0x5e, 0x00, 0x53, 0x5e});
71 return netif;
72 }
73};
74
75class EthernetFactoryFixtureWithRealNetifs : public EthernetFactoryFixture
76{
77protected:
78 EthernetFactoryFixtureWithRealNetifs()
79 {
80 copyRealNetifsToNetmon();
Junxiao Shi7003c602017-01-10 13:35:28 +000081 }
82};
83
Junxiao Shi0ba6d642017-07-17 00:53:22 +000084BOOST_AUTO_TEST_SUITE(Face)
Davide Pesaventoa9ec67c2023-10-19 20:04:04 -040085BOOST_AUTO_TEST_SUITE(TestEthernetFactory)
Junxiao Shi0ba6d642017-07-17 00:53:22 +000086
Davide Pesaventoa9ec67c2023-10-19 20:04:04 -040087BOOST_FIXTURE_TEST_SUITE(ProcessConfig, EthernetFactoryFixtureWithRealNetifs)
Junxiao Shi7003c602017-01-10 13:35:28 +000088
Davide Pesavento494a9552018-02-04 22:16:05 -050089BOOST_AUTO_TEST_CASE(Defaults)
Junxiao Shi7003c602017-01-10 13:35:28 +000090{
91 SKIP_IF_ETHERNET_NETIF_COUNT_LT(1);
92
93 const std::string CONFIG = R"CONFIG(
94 face_system
95 {
96 ether
Davide Pesaventob15276f2017-07-15 16:27:13 -040097 }
98 )CONFIG";
99
100 parseConfig(CONFIG, true);
101 parseConfig(CONFIG, false);
102
Davide Pesaventob15276f2017-07-15 16:27:13 -0400103 checkChannelListEqual(factory, this->listUrisOfAvailableNetifs());
Davide Pesavento494a9552018-02-04 22:16:05 -0500104 auto channels = factory.getChannels();
105 BOOST_CHECK(std::all_of(channels.begin(), channels.end(),
Davide Pesaventod27841b2018-11-13 00:22:24 -0500106 [] (const auto& ch) { return ch->isListening(); }));
Davide Pesaventoa9ec67c2023-10-19 20:04:04 -0400107 BOOST_CHECK_EQUAL(this->listEtherMcastFaces().size(), netifs.size());
Davide Pesaventob15276f2017-07-15 16:27:13 -0400108}
109
Davide Pesaventoa9ec67c2023-10-19 20:04:04 -0400110BOOST_AUTO_TEST_CASE(DisableListenAndMcast)
Davide Pesaventob15276f2017-07-15 16:27:13 -0400111{
112 SKIP_IF_ETHERNET_NETIF_COUNT_LT(1);
113
114 const std::string CONFIG = R"CONFIG(
115 face_system
116 {
117 ether
118 {
119 listen no
120 idle_timeout 60
121 mcast no
122 }
123 }
124 )CONFIG";
125
126 parseConfig(CONFIG, true);
127 parseConfig(CONFIG, false);
128
Davide Pesaventob15276f2017-07-15 16:27:13 -0400129 checkChannelListEqual(factory, this->listUrisOfAvailableNetifs());
Davide Pesavento494a9552018-02-04 22:16:05 -0500130 auto channels = factory.getChannels();
131 BOOST_CHECK(std::none_of(channels.begin(), channels.end(),
Davide Pesaventod27841b2018-11-13 00:22:24 -0500132 [] (const auto& ch) { return ch->isListening(); }));
Davide Pesaventoa9ec67c2023-10-19 20:04:04 -0400133 BOOST_CHECK_EQUAL(this->listEtherMcastFaces().size(), 0);
Davide Pesaventob15276f2017-07-15 16:27:13 -0400134}
135
Davide Pesaventob15276f2017-07-15 16:27:13 -0400136BOOST_AUTO_TEST_CASE(McastNormal)
137{
Davide Pesaventob15276f2017-07-15 16:27:13 -0400138 const std::string CONFIG = R"CONFIG(
139 face_system
140 {
141 ether
142 {
143 listen no
Junxiao Shi7003c602017-01-10 13:35:28 +0000144 mcast yes
145 mcast_group 01:00:5E:00:17:AA
Teng Liangbfea5752017-03-29 04:51:10 +0000146 mcast_ad_hoc no
Junxiao Shi7003c602017-01-10 13:35:28 +0000147 whitelist
148 {
149 *
150 }
151 blacklist
152 {
153 }
154 }
155 }
156 )CONFIG";
157
Junxiao Shi1b65ca12017-01-21 23:04:41 +0000158 parseConfig(CONFIG, true);
159 parseConfig(CONFIG, false);
Junxiao Shi7003c602017-01-10 13:35:28 +0000160
Davide Pesaventoa9ec67c2023-10-19 20:04:04 -0400161 auto etherMcastFaces = this->listEtherMcastFaces();
162 BOOST_CHECK_EQUAL(etherMcastFaces.size(), netifs.size());
163 for (const auto* face : etherMcastFaces) {
Alexander Afanasyev3a2339a2020-05-27 23:05:06 -0400164 BOOST_REQUIRE(face->getChannel().lock());
165 // not universal, but for Ethernet, local URI of a mcast face matches URI of the associated channel
166 BOOST_CHECK_EQUAL(face->getLocalUri(), face->getChannel().lock()->getUri());
167 }
Junxiao Shi7003c602017-01-10 13:35:28 +0000168}
169
Teng Liangbfea5752017-03-29 04:51:10 +0000170BOOST_AUTO_TEST_CASE(EnableDisableMcast)
Junxiao Shi7003c602017-01-10 13:35:28 +0000171{
Teng Liangbfea5752017-03-29 04:51:10 +0000172 const std::string CONFIG_WITH_MCAST = R"CONFIG(
Junxiao Shi7003c602017-01-10 13:35:28 +0000173 face_system
174 {
Teng Liangbfea5752017-03-29 04:51:10 +0000175 ether
176 {
Davide Pesaventob15276f2017-07-15 16:27:13 -0400177 listen no
Teng Liangbfea5752017-03-29 04:51:10 +0000178 mcast yes
179 }
180 }
181 )CONFIG";
182 const std::string CONFIG_WITHOUT_MCAST = R"CONFIG(
183 face_system
184 {
185 ether
186 {
Davide Pesaventob15276f2017-07-15 16:27:13 -0400187 listen no
Teng Liangbfea5752017-03-29 04:51:10 +0000188 mcast no
189 }
Junxiao Shi7003c602017-01-10 13:35:28 +0000190 }
191 )CONFIG";
192
Teng Liangbfea5752017-03-29 04:51:10 +0000193 parseConfig(CONFIG_WITHOUT_MCAST, false);
Davide Pesaventoa9ec67c2023-10-19 20:04:04 -0400194 BOOST_CHECK_EQUAL(this->listEtherMcastFaces().size(), 0);
Teng Liangbfea5752017-03-29 04:51:10 +0000195
196 SKIP_IF_ETHERNET_NETIF_COUNT_LT(1);
197
198 parseConfig(CONFIG_WITH_MCAST, false);
199 g_io.poll();
Davide Pesaventoa9ec67c2023-10-19 20:04:04 -0400200 BOOST_CHECK_EQUAL(this->listEtherMcastFaces().size(), netifs.size());
Teng Liangbfea5752017-03-29 04:51:10 +0000201
202 parseConfig(CONFIG_WITHOUT_MCAST, false);
203 g_io.poll();
Davide Pesaventoa9ec67c2023-10-19 20:04:04 -0400204 BOOST_CHECK_EQUAL(this->listEtherMcastFaces().size(), 0);
Teng Liangbfea5752017-03-29 04:51:10 +0000205}
206
207BOOST_AUTO_TEST_CASE(McastAdHoc)
208{
209 SKIP_IF_ETHERNET_NETIF_COUNT_LT(1);
210
211 const std::string CONFIG = R"CONFIG(
212 face_system
213 {
214 ether
215 {
Davide Pesaventob15276f2017-07-15 16:27:13 -0400216 listen no
Teng Liangbfea5752017-03-29 04:51:10 +0000217 mcast_ad_hoc yes
218 }
219 }
220 )CONFIG";
221
222 parseConfig(CONFIG, false);
Davide Pesaventoa9ec67c2023-10-19 20:04:04 -0400223 BOOST_CHECK_EQUAL(this->listEtherMcastFaces(ndn::nfd::LINK_TYPE_MULTI_ACCESS).size(), 0);
224 BOOST_CHECK_EQUAL(this->listEtherMcastFaces(ndn::nfd::LINK_TYPE_AD_HOC).size(), netifs.size());
Teng Liangbfea5752017-03-29 04:51:10 +0000225}
226
227BOOST_AUTO_TEST_CASE(ChangeMcastGroup)
228{
229 SKIP_IF_ETHERNET_NETIF_COUNT_LT(1);
230
231 const std::string CONFIG1 = R"CONFIG(
232 face_system
233 {
234 ether
235 {
Davide Pesavento43ff2a92017-05-18 19:50:57 -0400236 mcast_group 01:00:5e:90:10:01
Teng Liangbfea5752017-03-29 04:51:10 +0000237 }
238 }
239 )CONFIG";
240 const std::string CONFIG2 = R"CONFIG(
241 face_system
242 {
243 ether
244 {
Davide Pesavento43ff2a92017-05-18 19:50:57 -0400245 mcast_group 01:00:5e:90:10:02
Teng Liangbfea5752017-03-29 04:51:10 +0000246 }
247 }
248 )CONFIG";
249
250 parseConfig(CONFIG1, false);
Davide Pesaventoa9ec67c2023-10-19 20:04:04 -0400251 g_io.poll();
Teng Liangbfea5752017-03-29 04:51:10 +0000252 auto etherMcastFaces = this->listEtherMcastFaces();
253 BOOST_REQUIRE_EQUAL(etherMcastFaces.size(), netifs.size());
254 BOOST_CHECK_EQUAL(etherMcastFaces.front()->getRemoteUri(),
Davide Pesavento43ff2a92017-05-18 19:50:57 -0400255 FaceUri(ethernet::Address{0x01, 0x00, 0x5e, 0x90, 0x10, 0x01}));
Teng Liangbfea5752017-03-29 04:51:10 +0000256
257 parseConfig(CONFIG2, false);
258 g_io.poll();
259 etherMcastFaces = this->listEtherMcastFaces();
260 BOOST_REQUIRE_EQUAL(etherMcastFaces.size(), netifs.size());
261 BOOST_CHECK_EQUAL(etherMcastFaces.front()->getRemoteUri(),
Davide Pesavento43ff2a92017-05-18 19:50:57 -0400262 FaceUri(ethernet::Address{0x01, 0x00, 0x5e, 0x90, 0x10, 0x02}));
Junxiao Shi7003c602017-01-10 13:35:28 +0000263}
264
265BOOST_AUTO_TEST_CASE(Whitelist)
266{
267 SKIP_IF_ETHERNET_NETIF_COUNT_LT(1);
268
269 std::string CONFIG = R"CONFIG(
270 face_system
271 {
272 ether
273 {
274 whitelist
275 {
276 ifname %ifname
277 }
278 }
279 }
280 )CONFIG";
Davide Pesaventob15276f2017-07-15 16:27:13 -0400281 auto ifname = netifs.front()->getName();
282 boost::replace_first(CONFIG, "%ifname", ifname);
Junxiao Shi7003c602017-01-10 13:35:28 +0000283
Junxiao Shi1b65ca12017-01-21 23:04:41 +0000284 parseConfig(CONFIG, false);
Davide Pesaventob15276f2017-07-15 16:27:13 -0400285
Junxiao Shi7003c602017-01-10 13:35:28 +0000286 auto etherMcastFaces = this->listEtherMcastFaces();
287 BOOST_REQUIRE_EQUAL(etherMcastFaces.size(), 1);
Davide Pesaventob15276f2017-07-15 16:27:13 -0400288 BOOST_CHECK_EQUAL(etherMcastFaces.front()->getLocalUri(), FaceUri::fromDev(ifname));
Junxiao Shi7003c602017-01-10 13:35:28 +0000289}
290
291BOOST_AUTO_TEST_CASE(Blacklist)
292{
293 SKIP_IF_ETHERNET_NETIF_COUNT_LT(1);
294
295 std::string CONFIG = R"CONFIG(
296 face_system
297 {
298 ether
299 {
300 blacklist
301 {
302 ifname %ifname
303 }
304 }
305 }
306 )CONFIG";
Davide Pesaventob15276f2017-07-15 16:27:13 -0400307 auto ifname = netifs.front()->getName();
308 boost::replace_first(CONFIG, "%ifname", ifname);
Junxiao Shi7003c602017-01-10 13:35:28 +0000309
Junxiao Shi1b65ca12017-01-21 23:04:41 +0000310 parseConfig(CONFIG, false);
Davide Pesaventob15276f2017-07-15 16:27:13 -0400311
Junxiao Shi7003c602017-01-10 13:35:28 +0000312 auto etherMcastFaces = this->listEtherMcastFaces();
313 BOOST_CHECK_EQUAL(etherMcastFaces.size(), netifs.size() - 1);
Davide Pesavento494a9552018-02-04 22:16:05 -0500314 BOOST_CHECK(std::none_of(etherMcastFaces.begin(), etherMcastFaces.end(),
Davide Pesaventod7083a52023-10-19 17:51:16 -0400315 [uri = FaceUri::fromDev(ifname)] (const auto* face) {
316 return face->getLocalUri() == uri;
317 }));
Junxiao Shi7003c602017-01-10 13:35:28 +0000318}
319
Teng Liangbfea5752017-03-29 04:51:10 +0000320BOOST_AUTO_TEST_CASE(Omitted)
Junxiao Shi7003c602017-01-10 13:35:28 +0000321{
Teng Liangbfea5752017-03-29 04:51:10 +0000322 const std::string CONFIG = R"CONFIG(
Junxiao Shi7003c602017-01-10 13:35:28 +0000323 face_system
324 {
Junxiao Shi7003c602017-01-10 13:35:28 +0000325 }
326 )CONFIG";
327
Teng Liangbfea5752017-03-29 04:51:10 +0000328 parseConfig(CONFIG, true);
329 parseConfig(CONFIG, false);
330
Davide Pesaventoa9ec67c2023-10-19 20:04:04 -0400331 BOOST_CHECK_EQUAL(this->listEtherMcastFaces().size(), 0);
Junxiao Shi7003c602017-01-10 13:35:28 +0000332}
333
Davide Pesavento494a9552018-02-04 22:16:05 -0500334BOOST_AUTO_TEST_CASE(BadListen)
335{
336 const std::string CONFIG = R"CONFIG(
337 face_system
338 {
339 ether
340 {
341 listen hello
342 }
343 }
344 )CONFIG";
345
346 BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
347 BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
348}
349
Davide Pesavento494a9552018-02-04 22:16:05 -0500350BOOST_AUTO_TEST_CASE(BadIdleTimeout)
351{
352 // not a number
353 const std::string CONFIG1 = R"CONFIG(
354 face_system
355 {
356 ether
357 {
358 idle_timeout hello
359 }
360 }
361 )CONFIG";
362
363 BOOST_CHECK_THROW(parseConfig(CONFIG1, true), ConfigFile::Error);
364 BOOST_CHECK_THROW(parseConfig(CONFIG1, false), ConfigFile::Error);
365
366 // negative number
367 const std::string CONFIG2 = R"CONFIG(
368 face_system
369 {
370 ether
371 {
372 idle_timeout -15
373 }
374 }
375 )CONFIG";
376
377 BOOST_CHECK_THROW(parseConfig(CONFIG2, true), ConfigFile::Error);
378 BOOST_CHECK_THROW(parseConfig(CONFIG2, false), ConfigFile::Error);
379}
380
Junxiao Shi7003c602017-01-10 13:35:28 +0000381BOOST_AUTO_TEST_CASE(BadMcast)
382{
383 const std::string CONFIG = R"CONFIG(
384 face_system
385 {
386 ether
387 {
388 mcast hello
389 }
390 }
391 )CONFIG";
392
393 BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
394 BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
395}
396
397BOOST_AUTO_TEST_CASE(BadMcastGroup)
398{
Davide Pesavento494a9552018-02-04 22:16:05 -0500399 // not an address
400 const std::string CONFIG1 = R"CONFIG(
Junxiao Shi7003c602017-01-10 13:35:28 +0000401 face_system
402 {
403 ether
404 {
Junxiao Shi7003c602017-01-10 13:35:28 +0000405 mcast_group hello
406 }
407 }
408 )CONFIG";
409
Davide Pesavento494a9552018-02-04 22:16:05 -0500410 BOOST_CHECK_THROW(parseConfig(CONFIG1, true), ConfigFile::Error);
411 BOOST_CHECK_THROW(parseConfig(CONFIG1, false), ConfigFile::Error);
Junxiao Shi7003c602017-01-10 13:35:28 +0000412
Davide Pesavento494a9552018-02-04 22:16:05 -0500413 // non-multicast address
414 const std::string CONFIG2 = R"CONFIG(
Junxiao Shi7003c602017-01-10 13:35:28 +0000415 face_system
416 {
417 ether
418 {
Davide Pesavento43ff2a92017-05-18 19:50:57 -0400419 mcast_group 00:00:5e:00:53:5e
Junxiao Shi7003c602017-01-10 13:35:28 +0000420 }
421 }
422 )CONFIG";
423
Davide Pesavento494a9552018-02-04 22:16:05 -0500424 BOOST_CHECK_THROW(parseConfig(CONFIG2, true), ConfigFile::Error);
425 BOOST_CHECK_THROW(parseConfig(CONFIG2, false), ConfigFile::Error);
Junxiao Shi7003c602017-01-10 13:35:28 +0000426}
427
428BOOST_AUTO_TEST_CASE(UnknownOption)
429{
430 const std::string CONFIG = R"CONFIG(
431 face_system
432 {
433 ether
434 {
435 hello
436 }
437 }
438 )CONFIG";
439
440 BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
441 BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
442}
443
444BOOST_AUTO_TEST_SUITE_END() // ProcessConfig
Junxiao Shicde37ad2015-12-24 01:02:05 -0700445
Davide Pesaventoa9ec67c2023-10-19 20:04:04 -0400446BOOST_FIXTURE_TEST_CASE(GetChannels, EthernetFactoryFixtureWithRealNetifs)
Junxiao Shicde37ad2015-12-24 01:02:05 -0700447{
Davide Pesaventob15276f2017-07-15 16:27:13 -0400448 BOOST_CHECK_EQUAL(factory.getChannels().empty(), true);
Davide Pesaventod7083a52023-10-19 17:51:16 -0400449
Davide Pesaventob15276f2017-07-15 16:27:13 -0400450 SKIP_IF_ETHERNET_NETIF_COUNT_LT(1);
451
Davide Pesavento14e71f02019-03-28 17:35:25 -0400452 factory.createChannel(netifs.front(), 1_min);
Davide Pesaventob15276f2017-07-15 16:27:13 -0400453 checkChannelListEqual(factory, {FaceUri::fromDev(netifs.front()->getName()).toString()});
Junxiao Shicde37ad2015-12-24 01:02:05 -0700454}
455
Davide Pesaventoa9ec67c2023-10-19 20:04:04 -0400456BOOST_FIXTURE_TEST_CASE(CreateChannel, EthernetFactoryFixtureWithRealNetifs)
Davide Pesaventob15276f2017-07-15 16:27:13 -0400457{
458 SKIP_IF_ETHERNET_NETIF_COUNT_LT(1);
459
Davide Pesavento14e71f02019-03-28 17:35:25 -0400460 auto channel1 = factory.createChannel(netifs.front(), 1_min);
461 auto channel1a = factory.createChannel(netifs.front(), 5_min);
Davide Pesaventob15276f2017-07-15 16:27:13 -0400462 BOOST_CHECK_EQUAL(channel1, channel1a);
Davide Pesaventoa9ec67c2023-10-19 20:04:04 -0400463 checkChannelListEqual(factory, {FaceUri::fromDev(netifs.front()->getName()).toString()});
Davide Pesaventob15276f2017-07-15 16:27:13 -0400464
465 SKIP_IF_ETHERNET_NETIF_COUNT_LT(2);
466
Davide Pesavento14e71f02019-03-28 17:35:25 -0400467 auto channel2 = factory.createChannel(netifs.back(), 1_min);
Davide Pesaventob15276f2017-07-15 16:27:13 -0400468 BOOST_CHECK_NE(channel1, channel2);
Davide Pesaventoa9ec67c2023-10-19 20:04:04 -0400469 BOOST_CHECK_EQUAL(factory.getChannels().size(), 2);
Davide Pesaventob15276f2017-07-15 16:27:13 -0400470}
471
Davide Pesaventoa9ec67c2023-10-19 20:04:04 -0400472BOOST_FIXTURE_TEST_CASE(CreateFace, EthernetFactoryFixtureWithRealNetifs)
Davide Pesaventob15276f2017-07-15 16:27:13 -0400473{
474 createFace(factory,
475 FaceUri("ether://[00:00:5e:00:53:5e]"),
476 FaceUri("dev://eth0"),
Eric Newberry812d6152018-06-06 15:06:01 -0700477 {ndn::nfd::FACE_PERSISTENCY_PERSISTENT, {}, {}, {}, false, false, false},
Davide Pesaventob15276f2017-07-15 16:27:13 -0400478 {CreateFaceExpectedResult::FAILURE, 504, "No channels available to connect"});
479
480 SKIP_IF_ETHERNET_NETIF_COUNT_LT(1);
Davide Pesavento14e71f02019-03-28 17:35:25 -0400481 auto localUri = factory.createChannel(netifs.front(), 1_min)->getUri();
Davide Pesaventob15276f2017-07-15 16:27:13 -0400482
483 createFace(factory,
484 FaceUri("ether://[00:00:5e:00:53:5e]"),
485 localUri,
Eric Newberry812d6152018-06-06 15:06:01 -0700486 {ndn::nfd::FACE_PERSISTENCY_PERSISTENT, {}, {}, {}, false, false, false},
Davide Pesaventob15276f2017-07-15 16:27:13 -0400487 {CreateFaceExpectedResult::SUCCESS, 0, ""});
488
489 createFace(factory,
490 FaceUri("ether://[00:00:5e:00:53:5e]"),
491 localUri,
Eric Newberry812d6152018-06-06 15:06:01 -0700492 {ndn::nfd::FACE_PERSISTENCY_PERMANENT, {}, {}, {}, false, false, false},
Davide Pesaventob15276f2017-07-15 16:27:13 -0400493 {CreateFaceExpectedResult::SUCCESS, 0, ""});
494
495 createFace(factory,
496 FaceUri("ether://[00:00:5e:00:53:53]"),
497 localUri,
Eric Newberry812d6152018-06-06 15:06:01 -0700498 {ndn::nfd::FACE_PERSISTENCY_PERMANENT, {}, {}, {}, false, false, false},
Eric Newberry2642cd22017-07-13 21:34:53 -0400499 {CreateFaceExpectedResult::SUCCESS, 0, ""});
500
501 createFace(factory,
502 FaceUri("ether://[00:00:5e:00:53:57]"),
503 localUri,
Eric Newberry812d6152018-06-06 15:06:01 -0700504 {ndn::nfd::FACE_PERSISTENCY_PERMANENT, {}, {}, {}, false, true, false},
Eric Newberry0c3e57b2018-01-25 20:54:46 -0700505 {CreateFaceExpectedResult::SUCCESS, 0, ""});
506
507 createFace(factory,
508 FaceUri("ether://[00:00:5e:00:53:5b]"),
509 localUri,
Eric Newberry812d6152018-06-06 15:06:01 -0700510 {ndn::nfd::FACE_PERSISTENCY_PERMANENT, {}, {}, {}, false, false, true},
511 {CreateFaceExpectedResult::SUCCESS, 0, ""});
512
513 createFace(factory,
514 FaceUri("ether://[00:00:5e:00:53:5c]"),
515 localUri,
516 {ndn::nfd::FACE_PERSISTENCY_PERSISTENT, {}, {}, 1000, false, false, false},
Davide Pesaventob15276f2017-07-15 16:27:13 -0400517 {CreateFaceExpectedResult::SUCCESS, 0, ""});
518}
519
Davide Pesaventoa9ec67c2023-10-19 20:04:04 -0400520BOOST_FIXTURE_TEST_CASE(CreateFaceInvalidRequest, EthernetFactoryFixture)
Junxiao Shicde37ad2015-12-24 01:02:05 -0700521{
Eric Newberry42602412016-08-27 09:33:18 -0700522 createFace(factory,
Davide Pesavento46afec42017-05-28 14:28:47 -0400523 FaceUri("ether://[00:00:5e:00:53:5e]"),
Eric Newberry78e32b02017-04-01 14:34:44 +0000524 {},
Eric Newberry812d6152018-06-06 15:06:01 -0700525 {ndn::nfd::FACE_PERSISTENCY_PERSISTENT, {}, {}, {}, false, false, false},
Davide Pesavento46afec42017-05-28 14:28:47 -0400526 {CreateFaceExpectedResult::FAILURE, 406,
527 "Creation of unicast Ethernet faces requires a LocalUri with dev:// scheme"});
528
529 createFace(factory,
530 FaceUri("ether://[00:00:5e:00:53:5e]"),
531 FaceUri("udp4://127.0.0.1:20071"),
Eric Newberry812d6152018-06-06 15:06:01 -0700532 {ndn::nfd::FACE_PERSISTENCY_PERSISTENT, {}, {}, {}, false, false, false},
Davide Pesavento46afec42017-05-28 14:28:47 -0400533 {CreateFaceExpectedResult::FAILURE, 406,
534 "Creation of unicast Ethernet faces requires a LocalUri with dev:// scheme"});
535
536 createFace(factory,
537 FaceUri("ether://[00:00:5e:00:53:5e]"),
538 FaceUri("dev://eth0"),
Eric Newberry812d6152018-06-06 15:06:01 -0700539 {ndn::nfd::FACE_PERSISTENCY_ON_DEMAND, {}, {}, {}, false, false, false},
Davide Pesavento46afec42017-05-28 14:28:47 -0400540 {CreateFaceExpectedResult::FAILURE, 406,
541 "Outgoing Ethernet faces do not support on-demand persistency"});
542
543 createFace(factory,
544 FaceUri("ether://[01:00:5e:90:10:5e]"),
545 FaceUri("dev://eth0"),
Eric Newberry812d6152018-06-06 15:06:01 -0700546 {ndn::nfd::FACE_PERSISTENCY_PERSISTENT, {}, {}, {}, false, false, false},
Davide Pesavento46afec42017-05-28 14:28:47 -0400547 {CreateFaceExpectedResult::FAILURE, 406,
548 "Cannot create multicast Ethernet faces"});
549
550 createFace(factory,
551 FaceUri("ether://[00:00:5e:00:53:5e]"),
552 FaceUri("dev://eth0"),
Eric Newberry812d6152018-06-06 15:06:01 -0700553 {ndn::nfd::FACE_PERSISTENCY_PERSISTENT, {}, {}, {}, true, false, false},
Davide Pesavento46afec42017-05-28 14:28:47 -0400554 {CreateFaceExpectedResult::FAILURE, 406,
555 "Local fields can only be enabled on faces with local scope"});
Davide Pesaventoa9ec67c2023-10-19 20:04:04 -0400556
557 createFace(factory,
558 FaceUri("ether://[00:00:5e:00:53:5e]"),
559 FaceUri("dev://eth0"),
560 {ndn::nfd::FACE_PERSISTENCY_PERSISTENT, {}, {}, 42, false, false, false},
561 {CreateFaceExpectedResult::FAILURE, 406,
562 "Override MTU cannot be less than 64"});
Junxiao Shicde37ad2015-12-24 01:02:05 -0700563}
564
Davide Pesaventoa9ec67c2023-10-19 20:04:04 -0400565BOOST_FIXTURE_TEST_SUITE(OnInterfaceAdded, EthernetFactoryFixture)
566
567BOOST_AUTO_TEST_CASE(EligibleForChannelAndMcast)
568{
569 parseConfig(R"CONFIG(
570 face_system
571 {
572 ether
573 }
574 )CONFIG", false);
575 g_io.poll();
576 BOOST_CHECK_EQUAL(factory.getChannels().size(), 0);
577 BOOST_CHECK_EQUAL(this->listEtherMcastFaces().size(), 0);
578
579 // Add a fake interface that satisfies both unicast and multicast criteria.
580 netmon->addInterface(this->makeFakeNetif());
581 // The channel fails to listen because the interface is fake.
582 // However, it's not removed from the channel list (issue #4400).
583 BOOST_CHECK_EQUAL(factory.getChannels().size(), 1);
584 // Multicast face creation fails because the interface is fake.
585 // This test is to ensure that the factory handles failures gracefully.
586 BOOST_CHECK_EQUAL(this->listEtherMcastFaces().size(), 0);
587
588 SKIP_IF_ETHERNET_NETIF_COUNT_LT(1);
589
590 // Now add a real interface: both channel and multicast face should be created successfully.
591 netmon->addInterface(const_pointer_cast<ndn::net::NetworkInterface>(netifs.front()));
592 BOOST_CHECK_EQUAL(factory.getChannels().size(), 2);
593 auto etherMcastFaces = this->listEtherMcastFaces();
594 BOOST_REQUIRE_EQUAL(etherMcastFaces.size(), 1);
595 BOOST_CHECK_EQUAL(etherMcastFaces.front()->getLocalUri(), FaceUri::fromDev(netifs.front()->getName()));
596}
597
598BOOST_AUTO_TEST_CASE(EligibleForChannelOnly)
599{
600 SKIP_IF_ETHERNET_NETIF_COUNT_LT(1);
601
602 parseConfig(R"CONFIG(
603 face_system
604 {
605 ether
606 {
607 listen no
608 }
609 }
610 )CONFIG", false);
611 g_io.poll();
612 BOOST_CHECK_EQUAL(factory.getChannels().size(), 0);
613 BOOST_CHECK_EQUAL(this->listEtherMcastFaces().size(), 0);
614
615 // Add an interface that satisfies only the unicast criteria.
616 auto netif = const_pointer_cast<ndn::net::NetworkInterface>(netifs.front());
617 netif->setFlags(netif->getFlags() & ~IFF_MULTICAST);
618 netmon->addInterface(netif);
619 checkChannelListEqual(factory, {FaceUri::fromDev(netifs.front()->getName()).toString()});
620 BOOST_CHECK_EQUAL(this->listEtherMcastFaces().size(), 0);
621}
622
623BOOST_AUTO_TEST_CASE(Ineligible)
624{
625 parseConfig(R"CONFIG(
626 face_system
627 {
628 ether
629 }
630 )CONFIG", false);
631 g_io.poll();
632
633 // netif is down
634 auto netif = this->makeFakeNetif();
635 netif->setFlags(netif->getFlags() & ~IFF_UP);
636 netmon->addInterface(netif);
637 BOOST_CHECK_EQUAL(factory.getChannels().size(), 0);
638 BOOST_CHECK_EQUAL(this->listEtherMcastFaces().size(), 0);
639
640 // incompatible netif type
641 netif = this->makeFakeNetif();
642 netif->setType(ndn::net::InterfaceType::LOOPBACK);
643 netmon->addInterface(netif);
644 BOOST_CHECK_EQUAL(factory.getChannels().size(), 0);
645 BOOST_CHECK_EQUAL(this->listEtherMcastFaces().size(), 0);
646
647 // invalid Ethernet address
648 netif = this->makeFakeNetif();
649 netif->setEthernetAddress(ethernet::Address{});
650 netmon->addInterface(netif);
651 BOOST_CHECK_EQUAL(factory.getChannels().size(), 0);
652 BOOST_CHECK_EQUAL(this->listEtherMcastFaces().size(), 0);
653}
654
655BOOST_AUTO_TEST_CASE(Disabled)
656{
657 SKIP_IF_ETHERNET_NETIF_COUNT_LT(1);
658
659 parseConfig("", false);
660 g_io.poll();
661
662 netmon->addInterface(const_pointer_cast<ndn::net::NetworkInterface>(netifs.front()));
663 BOOST_CHECK_EQUAL(factory.getChannels().size(), 0);
664 BOOST_CHECK_EQUAL(this->listEtherMcastFaces().size(), 0);
665}
666
667BOOST_AUTO_TEST_SUITE_END() // OnInterfaceAdded
668
Junxiao Shicde37ad2015-12-24 01:02:05 -0700669BOOST_AUTO_TEST_SUITE_END() // TestEthernetFactory
670BOOST_AUTO_TEST_SUITE_END() // Face
671
Davide Pesaventoe422f9e2022-06-03 01:30:23 -0400672} // namespace nfd::tests