blob: 41b57b0b35c3ccd18cda0d58e00c1cd4f59d0d54 [file] [log] [blame]
mukesh agrawald4ef6772012-02-21 16:28:04 -08001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
Paul Stewart75e89d22011-08-01 10:00:02 -07002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Alex Deymocddd2d02014-11-10 19:55:35 -08005#include "shill/routing_table.h"
6
Paul Stewart75e89d22011-08-01 10:00:02 -07007#include <linux/rtnetlink.h>
Alex Vakulenkoa41ab512014-07-23 14:24:23 -07008#include <sys/socket.h>
Paul Stewart75e89d22011-08-01 10:00:02 -07009
Ben Chancd477322014-10-17 14:19:30 -070010#include <memory>
Paul Stewart3f68bb12012-03-15 13:33:10 -070011#include <vector>
12
Peter Qiu8d6b5972014-10-28 15:33:34 -070013#include <base/bind.h>
14#include <base/callback.h>
Darin Petkov13e6d552012-05-09 14:22:23 +020015#include <base/memory/weak_ptr.h>
Eric Shienbrood3e20a232012-02-16 11:35:56 -050016#include <base/stl_util.h>
Paul Stewart75e89d22011-08-01 10:00:02 -070017#include <gtest/gtest.h>
18#include <gmock/gmock.h>
19
Peter Qiu8d6b5972014-10-28 15:33:34 -070020#include "shill/event_dispatcher.h"
21#include "shill/ipconfig.h"
Christopher Wileyb691efd2012-08-09 13:51:51 -070022#include "shill/logging.h"
Paul Stewart75e89d22011-08-01 10:00:02 -070023#include "shill/mock_control.h"
Peter Qiu8d6b5972014-10-28 15:33:34 -070024#include "shill/net/byte_string.h"
25#include "shill/net/mock_rtnl_handler.h"
26#include "shill/net/rtnl_message.h"
Paul Stewart75e89d22011-08-01 10:00:02 -070027#include "shill/routing_table_entry.h"
Paul Stewart75e89d22011-08-01 10:00:02 -070028
Darin Petkovabf6d282012-05-08 15:49:05 +020029using base::Bind;
Eric Shienbrood3e20a232012-02-16 11:35:56 -050030using base::Callback;
Darin Petkovabf6d282012-05-08 15:49:05 +020031using base::Unretained;
Darin Petkovabf6d282012-05-08 15:49:05 +020032using std::deque;
Paul Stewart3f68bb12012-03-15 13:33:10 -070033using std::vector;
Paul Stewart75e89d22011-08-01 10:00:02 -070034using testing::_;
Darin Petkovabf6d282012-05-08 15:49:05 +020035using testing::Field;
Paul Stewartf748a362012-03-07 12:01:20 -080036using testing::Invoke;
Paul Stewart75e89d22011-08-01 10:00:02 -070037using testing::Return;
Paul Stewartf748a362012-03-07 12:01:20 -080038using testing::StrictMock;
Paul Stewart75e89d22011-08-01 10:00:02 -070039using testing::Test;
40
41namespace shill {
42
43class TestEventDispatcher : public EventDispatcher {
44 public:
Paul Stewart3b30ca52015-06-16 13:13:10 -070045 virtual IOHandler* CreateInputHandler(
mukesh agrawal1830fa12011-09-26 14:31:40 -070046 int /*fd*/,
Paul Stewart3b30ca52015-06-16 13:13:10 -070047 const IOHandler::InputCallback& /*input_callback*/,
48 const IOHandler::ErrorCallback& /*error_callback*/) {
Ben Chancc225ef2014-09-30 13:26:51 -070049 return nullptr;
Paul Stewart75e89d22011-08-01 10:00:02 -070050 }
51};
52
53class RoutingTableTest : public Test {
54 public:
Prabhu Kaliamoorthi762bfb82015-02-06 13:17:08 +010055 static const uint8_t kTestTableId;
56
Paul Stewarte93b0382012-04-24 13:11:28 -070057 RoutingTableTest() : routing_table_(new RoutingTable()) {}
Paul Stewart75e89d22011-08-01 10:00:02 -070058
Paul Stewartf748a362012-03-07 12:01:20 -080059 virtual void SetUp() {
60 routing_table_->rtnl_handler_ = &rtnl_handler_;
61 ON_CALL(rtnl_handler_, SendMessage(_)).WillByDefault(Return(true));
Paul Stewart75e89d22011-08-01 10:00:02 -070062 }
63
Paul Stewart65c40f52011-08-08 07:27:46 -070064 virtual void TearDown() {
65 RTNLHandler::GetInstance()->Stop();
66 }
67
Paul Stewart3b30ca52015-06-16 13:13:10 -070068 std::unordered_map<int, vector<RoutingTableEntry>>* GetRoutingTables() {
Paul Stewartf748a362012-03-07 12:01:20 -080069 return &routing_table_->tables_;
70 }
71
Paul Stewart3b30ca52015-06-16 13:13:10 -070072 deque<RoutingTable::Query>* GetQueries() {
Paul Stewarte93b0382012-04-24 13:11:28 -070073 return &routing_table_->route_queries_;
Paul Stewartf748a362012-03-07 12:01:20 -080074 }
75
76 void SendRouteEntry(RTNLMessage::Mode mode,
Ben Chan7fab8972014-08-10 17:14:46 -070077 uint32_t interface_index,
Paul Stewart3b30ca52015-06-16 13:13:10 -070078 const RoutingTableEntry& entry);
Paul Stewartf748a362012-03-07 12:01:20 -080079
80 void SendRouteEntryWithSeqAndProto(RTNLMessage::Mode mode,
Ben Chan7fab8972014-08-10 17:14:46 -070081 uint32_t interface_index,
Paul Stewart3b30ca52015-06-16 13:13:10 -070082 const RoutingTableEntry& entry,
Ben Chan7fab8972014-08-10 17:14:46 -070083 uint32_t seq,
Paul Stewartf748a362012-03-07 12:01:20 -080084 unsigned char proto);
85
Paul Stewart3b30ca52015-06-16 13:13:10 -070086 void SendRouteMessage(const RTNLMessage& msg);
Paul Stewartf748a362012-03-07 12:01:20 -080087
Paul Stewart3b30ca52015-06-16 13:13:10 -070088 bool SetSequenceForMessage(RTNLMessage* message) {
Paul Stewartf748a362012-03-07 12:01:20 -080089 message->set_seq(RoutingTableTest::kTestRequestSeq);
90 return true;
91 }
92
Paul Stewart75e89d22011-08-01 10:00:02 -070093 protected:
Ben Chan7fab8972014-08-10 17:14:46 -070094 static const uint32_t kTestDeviceIndex0;
95 static const uint32_t kTestDeviceIndex1;
Paul Stewart75e89d22011-08-01 10:00:02 -070096 static const char kTestDeviceName0[];
Thieu Lecaef8932012-02-28 16:06:59 -080097 static const char kTestDeviceNetAddress4[];
98 static const char kTestForeignNetAddress4[];
99 static const char kTestForeignNetGateway4[];
100 static const char kTestForeignNetAddress6[];
101 static const char kTestForeignNetGateway6[];
Paul Stewartf748a362012-03-07 12:01:20 -0800102 static const char kTestGatewayAddress4[];
Paul Stewart75e89d22011-08-01 10:00:02 -0700103 static const char kTestNetAddress0[];
104 static const char kTestNetAddress1[];
Paul Stewartf748a362012-03-07 12:01:20 -0800105 static const char kTestRemoteAddress4[];
Paul Stewart3f68bb12012-03-15 13:33:10 -0700106 static const char kTestRemoteNetmask4[];
107 static const char kTestRemoteNetwork4[];
108 static const int kTestRemotePrefix4;
Ben Chan7fab8972014-08-10 17:14:46 -0700109 static const uint32_t kTestRequestSeq;
Paul Stewarte93b0382012-04-24 13:11:28 -0700110 static const int kTestRouteTag;
Paul Stewart75e89d22011-08-01 10:00:02 -0700111
Darin Petkovabf6d282012-05-08 15:49:05 +0200112 class QueryCallbackTarget {
113 public:
114 QueryCallbackTarget()
Darin Petkov13e6d552012-05-09 14:22:23 +0200115 : weak_ptr_factory_(this),
116 mocked_callback_(
117 Bind(&QueryCallbackTarget::MockedTarget, Unretained(this))),
118 unreached_callback_(Bind(&QueryCallbackTarget::UnreachedTarget,
119 weak_ptr_factory_.GetWeakPtr())) {}
Darin Petkovabf6d282012-05-08 15:49:05 +0200120
Darin Petkov13e6d552012-05-09 14:22:23 +0200121 MOCK_METHOD2(MockedTarget,
Paul Stewart3b30ca52015-06-16 13:13:10 -0700122 void(int interface_index, const RoutingTableEntry& entry));
Darin Petkov13e6d552012-05-09 14:22:23 +0200123
Paul Stewart3b30ca52015-06-16 13:13:10 -0700124 void UnreachedTarget(int interface_index, const RoutingTableEntry& entry) {
Darin Petkov13e6d552012-05-09 14:22:23 +0200125 CHECK(false);
126 }
127
Paul Stewart3b30ca52015-06-16 13:13:10 -0700128 const RoutingTable::Query::Callback& mocked_callback() const {
Darin Petkov13e6d552012-05-09 14:22:23 +0200129 return mocked_callback_;
130 }
131
Paul Stewart3b30ca52015-06-16 13:13:10 -0700132 const RoutingTable::Query::Callback& unreached_callback() const {
Darin Petkov13e6d552012-05-09 14:22:23 +0200133 return unreached_callback_;
134 }
Darin Petkovabf6d282012-05-08 15:49:05 +0200135
136 private:
Darin Petkov13e6d552012-05-09 14:22:23 +0200137 base::WeakPtrFactory<QueryCallbackTarget> weak_ptr_factory_;
138 const RoutingTable::Query::Callback mocked_callback_;
139 const RoutingTable::Query::Callback unreached_callback_;
Darin Petkovabf6d282012-05-08 15:49:05 +0200140 };
141
Ben Chancd477322014-10-17 14:19:30 -0700142 std::unique_ptr<RoutingTable> routing_table_;
Paul Stewart75e89d22011-08-01 10:00:02 -0700143 TestEventDispatcher dispatcher_;
Paul Stewartf748a362012-03-07 12:01:20 -0800144 StrictMock<MockRTNLHandler> rtnl_handler_;
Paul Stewart75e89d22011-08-01 10:00:02 -0700145};
146
Ben Chan7fab8972014-08-10 17:14:46 -0700147const uint32_t RoutingTableTest::kTestDeviceIndex0 = 12345;
148const uint32_t RoutingTableTest::kTestDeviceIndex1 = 67890;
Paul Stewart75e89d22011-08-01 10:00:02 -0700149const char RoutingTableTest::kTestDeviceName0[] = "test-device0";
Thieu Lecaef8932012-02-28 16:06:59 -0800150const char RoutingTableTest::kTestDeviceNetAddress4[] = "192.168.2.0/24";
151const char RoutingTableTest::kTestForeignNetAddress4[] = "192.168.2.2";
152const char RoutingTableTest::kTestForeignNetGateway4[] = "192.168.2.1";
153const char RoutingTableTest::kTestForeignNetAddress6[] = "2000::/3";
154const char RoutingTableTest::kTestForeignNetGateway6[] = "fe80:::::1";
Paul Stewartf748a362012-03-07 12:01:20 -0800155const char RoutingTableTest::kTestGatewayAddress4[] = "192.168.2.254";
Paul Stewart75e89d22011-08-01 10:00:02 -0700156const char RoutingTableTest::kTestNetAddress0[] = "192.168.1.1";
157const char RoutingTableTest::kTestNetAddress1[] = "192.168.1.2";
Paul Stewartf748a362012-03-07 12:01:20 -0800158const char RoutingTableTest::kTestRemoteAddress4[] = "192.168.2.254";
Paul Stewart3f68bb12012-03-15 13:33:10 -0700159const char RoutingTableTest::kTestRemoteNetmask4[] = "255.255.255.0";
160const char RoutingTableTest::kTestRemoteNetwork4[] = "192.168.100.0";
161const int RoutingTableTest::kTestRemotePrefix4 = 24;
Ben Chan7fab8972014-08-10 17:14:46 -0700162const uint32_t RoutingTableTest::kTestRequestSeq = 456;
Paul Stewarte93b0382012-04-24 13:11:28 -0700163const int RoutingTableTest::kTestRouteTag = 789;
Prabhu Kaliamoorthi762bfb82015-02-06 13:17:08 +0100164const uint8_t RoutingTableTest::kTestTableId = 0xa5;
Paul Stewart75e89d22011-08-01 10:00:02 -0700165
Darin Petkovabf6d282012-05-08 15:49:05 +0200166namespace {
167
Ben Chana0163122012-09-25 15:10:52 -0700168MATCHER_P3(IsBlackholeRoutingPacket, index, family, metric, "") {
Paul Stewart3b30ca52015-06-16 13:13:10 -0700169 const RTNLMessage::RouteStatus& status = arg->route_status();
Ben Chana0163122012-09-25 15:10:52 -0700170
Ben Chan7fab8972014-08-10 17:14:46 -0700171 uint32_t oif;
172 uint32_t priority;
Ben Chana0163122012-09-25 15:10:52 -0700173
174 return
175 arg->type() == RTNLMessage::kTypeRoute &&
176 arg->family() == family &&
177 arg->flags() == (NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL) &&
Prabhu Kaliamoorthi762bfb82015-02-06 13:17:08 +0100178 status.table == RoutingTableTest::kTestTableId &&
Ben Chana0163122012-09-25 15:10:52 -0700179 status.protocol == RTPROT_BOOT &&
180 status.scope == RT_SCOPE_UNIVERSE &&
181 status.type == RTN_BLACKHOLE &&
182 !arg->HasAttribute(RTA_DST) &&
183 !arg->HasAttribute(RTA_SRC) &&
184 !arg->HasAttribute(RTA_GATEWAY) &&
185 arg->GetAttribute(RTA_OIF).ConvertToCPUUInt32(&oif) &&
186 oif == index &&
187 arg->GetAttribute(RTA_PRIORITY).ConvertToCPUUInt32(&priority) &&
188 priority == metric;
189}
190
Paul Stewart75e89d22011-08-01 10:00:02 -0700191MATCHER_P4(IsRoutingPacket, mode, index, entry, flags, "") {
Paul Stewart3b30ca52015-06-16 13:13:10 -0700192 const RTNLMessage::RouteStatus& status = arg->route_status();
Paul Stewart75e89d22011-08-01 10:00:02 -0700193
Ben Chan7fab8972014-08-10 17:14:46 -0700194 uint32_t oif;
195 uint32_t priority;
Paul Stewart75e89d22011-08-01 10:00:02 -0700196
197 return
Paul Stewartf748a362012-03-07 12:01:20 -0800198 arg->type() == RTNLMessage::kTypeRoute &&
199 arg->family() == entry.gateway.family() &&
200 arg->flags() == (NLM_F_REQUEST | flags) &&
Prabhu Kaliamoorthi762bfb82015-02-06 13:17:08 +0100201 status.table == RoutingTableTest::kTestTableId &&
202 entry.table == RoutingTableTest::kTestTableId &&
Paul Stewartf748a362012-03-07 12:01:20 -0800203 status.protocol == RTPROT_BOOT &&
204 status.scope == entry.scope &&
205 status.type == RTN_UNICAST &&
206 arg->HasAttribute(RTA_DST) &&
207 IPAddress(arg->family(),
208 arg->GetAttribute(RTA_DST),
209 status.dst_prefix).Equals(entry.dst) &&
Paul Stewart4a6748d2012-07-17 14:31:36 -0700210 ((!arg->HasAttribute(RTA_SRC) && entry.src.IsDefault()) ||
211 (arg->HasAttribute(RTA_SRC) && IPAddress(arg->family(),
212 arg->GetAttribute(RTA_SRC),
213 status.src_prefix).Equals(entry.src))) &&
214 ((!arg->HasAttribute(RTA_GATEWAY) && entry.gateway.IsDefault()) ||
215 (arg->HasAttribute(RTA_GATEWAY) && IPAddress(arg->family(),
216 arg->GetAttribute(RTA_GATEWAY)).Equals(entry.gateway))) &&
Paul Stewartf748a362012-03-07 12:01:20 -0800217 arg->GetAttribute(RTA_OIF).ConvertToCPUUInt32(&oif) &&
218 oif == index &&
219 arg->GetAttribute(RTA_PRIORITY).ConvertToCPUUInt32(&priority) &&
220 priority == entry.metric;
Paul Stewart75e89d22011-08-01 10:00:02 -0700221}
222
Darin Petkovabf6d282012-05-08 15:49:05 +0200223} // namespace
224
Paul Stewartf748a362012-03-07 12:01:20 -0800225void RoutingTableTest::SendRouteEntry(RTNLMessage::Mode mode,
Ben Chan7fab8972014-08-10 17:14:46 -0700226 uint32_t interface_index,
Paul Stewart3b30ca52015-06-16 13:13:10 -0700227 const RoutingTableEntry& entry) {
Paul Stewartf748a362012-03-07 12:01:20 -0800228 SendRouteEntryWithSeqAndProto(mode, interface_index, entry, 0, RTPROT_BOOT);
229}
230
231void RoutingTableTest::SendRouteEntryWithSeqAndProto(
232 RTNLMessage::Mode mode,
Ben Chan7fab8972014-08-10 17:14:46 -0700233 uint32_t interface_index,
Paul Stewart3b30ca52015-06-16 13:13:10 -0700234 const RoutingTableEntry& entry,
Ben Chan7fab8972014-08-10 17:14:46 -0700235 uint32_t seq,
Paul Stewartf748a362012-03-07 12:01:20 -0800236 unsigned char proto) {
Paul Stewart75e89d22011-08-01 10:00:02 -0700237 RTNLMessage msg(
Paul Stewart9a908082011-08-31 12:18:48 -0700238 RTNLMessage::kTypeRoute,
Paul Stewart75e89d22011-08-01 10:00:02 -0700239 mode,
240 0,
Paul Stewartf748a362012-03-07 12:01:20 -0800241 seq,
Paul Stewart75e89d22011-08-01 10:00:02 -0700242 0,
243 0,
244 entry.dst.family());
245
246 msg.set_route_status(RTNLMessage::RouteStatus(
Paul Stewart9e3fcd72011-08-26 15:46:16 -0700247 entry.dst.prefix(),
248 entry.src.prefix(),
Prabhu Kaliamoorthi762bfb82015-02-06 13:17:08 +0100249 entry.table,
Paul Stewartf748a362012-03-07 12:01:20 -0800250 proto,
Paul Stewart75e89d22011-08-01 10:00:02 -0700251 entry.scope,
252 RTN_UNICAST,
253 0));
254
255 msg.SetAttribute(RTA_DST, entry.dst.address());
256 if (!entry.src.IsDefault()) {
257 msg.SetAttribute(RTA_SRC, entry.src.address());
258 }
259 if (!entry.gateway.IsDefault()) {
260 msg.SetAttribute(RTA_GATEWAY, entry.gateway.address());
261 }
262 msg.SetAttribute(RTA_PRIORITY, ByteString::CreateFromCPUUInt32(entry.metric));
263 msg.SetAttribute(RTA_OIF, ByteString::CreateFromCPUUInt32(interface_index));
264
Paul Stewartf748a362012-03-07 12:01:20 -0800265 routing_table_->RouteMsgHandler(msg);
Paul Stewart75e89d22011-08-01 10:00:02 -0700266}
267
Paul Stewart3b30ca52015-06-16 13:13:10 -0700268void RoutingTableTest::SendRouteMessage(const RTNLMessage& msg) {
Paul Stewartf748a362012-03-07 12:01:20 -0800269 routing_table_->RouteMsgHandler(msg);
Paul Stewart75e89d22011-08-01 10:00:02 -0700270}
271
Paul Stewartf748a362012-03-07 12:01:20 -0800272TEST_F(RoutingTableTest, Start) {
273 EXPECT_CALL(rtnl_handler_, RequestDump(RTNLHandler::kRequestRoute));
274 routing_table_->Start();
Paul Stewart75e89d22011-08-01 10:00:02 -0700275}
276
277TEST_F(RoutingTableTest, RouteAddDelete) {
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800278 // Expect the tables to be empty by default.
Paul Stewart75e89d22011-08-01 10:00:02 -0700279 EXPECT_EQ(0, GetRoutingTables()->size());
280
Paul Stewart7355ce12011-09-02 10:47:01 -0700281 IPAddress default_address(IPAddress::kFamilyIPv4);
Paul Stewart75e89d22011-08-01 10:00:02 -0700282 default_address.SetAddressToDefault();
283
Paul Stewart7355ce12011-09-02 10:47:01 -0700284 IPAddress gateway_address0(IPAddress::kFamilyIPv4);
Paul Stewart75e89d22011-08-01 10:00:02 -0700285 gateway_address0.SetAddressFromString(kTestNetAddress0);
286
287 int metric = 10;
288
289 RoutingTableEntry entry0(default_address,
Paul Stewart75e89d22011-08-01 10:00:02 -0700290 default_address,
Paul Stewart75e89d22011-08-01 10:00:02 -0700291 gateway_address0,
292 metric,
293 RT_SCOPE_UNIVERSE,
Prabhu Kaliamoorthi762bfb82015-02-06 13:17:08 +0100294 true,
295 kTestTableId,
296 RoutingTableEntry::kDefaultTag);
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800297 // Add a single entry.
Paul Stewartf748a362012-03-07 12:01:20 -0800298 SendRouteEntry(RTNLMessage::kModeAdd,
299 kTestDeviceIndex0,
300 entry0);
Paul Stewart75e89d22011-08-01 10:00:02 -0700301
Paul Stewart3b30ca52015-06-16 13:13:10 -0700302 std::unordered_map<int, vector<RoutingTableEntry>>* tables =
Alex Vakulenko8a532292014-06-16 17:18:44 -0700303 GetRoutingTables();
Paul Stewart75e89d22011-08-01 10:00:02 -0700304
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800305 // We should have a single table, which should in turn have a single entry.
Paul Stewart75e89d22011-08-01 10:00:02 -0700306 EXPECT_EQ(1, tables->size());
307 EXPECT_TRUE(ContainsKey(*tables, kTestDeviceIndex0));
308 EXPECT_EQ(1, (*tables)[kTestDeviceIndex0].size());
309
310 RoutingTableEntry test_entry = (*tables)[kTestDeviceIndex0][0];
311 EXPECT_TRUE(entry0.Equals(test_entry));
312
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800313 // Add a second entry for a different interface.
Paul Stewartf748a362012-03-07 12:01:20 -0800314 SendRouteEntry(RTNLMessage::kModeAdd,
315 kTestDeviceIndex1,
316 entry0);
Paul Stewart75e89d22011-08-01 10:00:02 -0700317
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800318 // We should have two tables, which should have a single entry each.
Paul Stewart75e89d22011-08-01 10:00:02 -0700319 EXPECT_EQ(2, tables->size());
320 EXPECT_TRUE(ContainsKey(*tables, kTestDeviceIndex1));
321 EXPECT_EQ(1, (*tables)[kTestDeviceIndex0].size());
322 EXPECT_EQ(1, (*tables)[kTestDeviceIndex1].size());
323
324 test_entry = (*tables)[kTestDeviceIndex1][0];
325 EXPECT_TRUE(entry0.Equals(test_entry));
326
Paul Stewart7355ce12011-09-02 10:47:01 -0700327 IPAddress gateway_address1(IPAddress::kFamilyIPv4);
Paul Stewart75e89d22011-08-01 10:00:02 -0700328 gateway_address1.SetAddressFromString(kTestNetAddress1);
329
330 RoutingTableEntry entry1(default_address,
Paul Stewart75e89d22011-08-01 10:00:02 -0700331 default_address,
Paul Stewart75e89d22011-08-01 10:00:02 -0700332 gateway_address1,
333 metric,
334 RT_SCOPE_UNIVERSE,
335 true);
336
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800337 // Add a second gateway route to the second interface.
Paul Stewartf748a362012-03-07 12:01:20 -0800338 SendRouteEntry(RTNLMessage::kModeAdd,
339 kTestDeviceIndex1,
340 entry1);
Paul Stewart75e89d22011-08-01 10:00:02 -0700341
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800342 // We should have two tables, one of which has a single entry, the other has
343 // two.
Paul Stewart75e89d22011-08-01 10:00:02 -0700344 EXPECT_EQ(2, tables->size());
345 EXPECT_EQ(1, (*tables)[kTestDeviceIndex0].size());
346 EXPECT_EQ(2, (*tables)[kTestDeviceIndex1].size());
347
348 test_entry = (*tables)[kTestDeviceIndex1][1];
349 EXPECT_TRUE(entry1.Equals(test_entry));
350
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800351 // Remove the first gateway route from the second interface.
Paul Stewartf748a362012-03-07 12:01:20 -0800352 SendRouteEntry(RTNLMessage::kModeDelete,
353 kTestDeviceIndex1,
354 entry0);
Paul Stewart75e89d22011-08-01 10:00:02 -0700355
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800356 // We should be back to having one route per table.
Paul Stewart75e89d22011-08-01 10:00:02 -0700357 EXPECT_EQ(2, tables->size());
358 EXPECT_EQ(1, (*tables)[kTestDeviceIndex0].size());
359 EXPECT_EQ(1, (*tables)[kTestDeviceIndex1].size());
360
361 test_entry = (*tables)[kTestDeviceIndex1][0];
362 EXPECT_TRUE(entry1.Equals(test_entry));
363
Paul Stewart5b7ba8c2012-04-18 09:08:00 -0700364 // Send a duplicate of the second gateway route message, changing the metric.
Paul Stewart75e89d22011-08-01 10:00:02 -0700365 RoutingTableEntry entry2(entry1);
366 entry2.metric++;
Paul Stewartf748a362012-03-07 12:01:20 -0800367 SendRouteEntry(RTNLMessage::kModeAdd,
368 kTestDeviceIndex1,
369 entry2);
Paul Stewart75e89d22011-08-01 10:00:02 -0700370
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800371 // Routing table size shouldn't change, but the new metric should match.
Paul Stewart75e89d22011-08-01 10:00:02 -0700372 EXPECT_EQ(1, (*tables)[kTestDeviceIndex1].size());
373 test_entry = (*tables)[kTestDeviceIndex1][0];
374 EXPECT_TRUE(entry2.Equals(test_entry));
375
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800376 // Find a matching entry.
Paul Stewart75e89d22011-08-01 10:00:02 -0700377 EXPECT_TRUE(routing_table_->GetDefaultRoute(kTestDeviceIndex1,
Paul Stewart7355ce12011-09-02 10:47:01 -0700378 IPAddress::kFamilyIPv4,
Paul Stewart75e89d22011-08-01 10:00:02 -0700379 &test_entry));
380 EXPECT_TRUE(entry2.Equals(test_entry));
381
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800382 // Test that a search for a non-matching family fails.
Paul Stewart75e89d22011-08-01 10:00:02 -0700383 EXPECT_FALSE(routing_table_->GetDefaultRoute(kTestDeviceIndex1,
Paul Stewart7355ce12011-09-02 10:47:01 -0700384 IPAddress::kFamilyIPv6,
Paul Stewart75e89d22011-08-01 10:00:02 -0700385 &test_entry));
386
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800387 // Remove last entry from an existing interface and test that we now fail.
Paul Stewartf748a362012-03-07 12:01:20 -0800388 SendRouteEntry(RTNLMessage::kModeDelete,
389 kTestDeviceIndex1,
390 entry2);
Paul Stewart75e89d22011-08-01 10:00:02 -0700391
392 EXPECT_FALSE(routing_table_->GetDefaultRoute(kTestDeviceIndex1,
Paul Stewart7355ce12011-09-02 10:47:01 -0700393 IPAddress::kFamilyIPv4,
Paul Stewart75e89d22011-08-01 10:00:02 -0700394 &test_entry));
395
Ben Chana6bfe872012-09-26 09:48:34 -0700396 // Add a route to a gateway address.
Paul Stewart5b7ba8c2012-04-18 09:08:00 -0700397 IPAddress gateway_address(IPAddress::kFamilyIPv4);
398 EXPECT_TRUE(gateway_address.SetAddressFromString(kTestNetAddress0));
Paul Stewart75e89d22011-08-01 10:00:02 -0700399
Paul Stewartf748a362012-03-07 12:01:20 -0800400 EXPECT_CALL(rtnl_handler_,
401 SendMessage(IsRoutingPacket(RTNLMessage::kModeAdd,
402 kTestDeviceIndex1,
403 entry0,
404 NLM_F_CREATE | NLM_F_EXCL)));
Paul Stewart75e89d22011-08-01 10:00:02 -0700405 EXPECT_TRUE(routing_table_->SetDefaultRoute(kTestDeviceIndex1,
Paul Stewart5b7ba8c2012-04-18 09:08:00 -0700406 gateway_address,
Prabhu Kaliamoorthi762bfb82015-02-06 13:17:08 +0100407 metric,
408 kTestTableId));
Paul Stewart75e89d22011-08-01 10:00:02 -0700409
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800410 // The table entry should look much like entry0, except with
411 // from_rtnl = false.
Paul Stewart75e89d22011-08-01 10:00:02 -0700412 RoutingTableEntry entry3(entry0);
413 entry3.from_rtnl = false;
414 EXPECT_TRUE(routing_table_->GetDefaultRoute(kTestDeviceIndex1,
Paul Stewart7355ce12011-09-02 10:47:01 -0700415 IPAddress::kFamilyIPv4,
Paul Stewart75e89d22011-08-01 10:00:02 -0700416 &test_entry));
417 EXPECT_TRUE(entry3.Equals(test_entry));
418
419 // Setting the same route on the interface with a different metric should
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800420 // push the route with different flags to indicate we are replacing it,
421 // then it should delete the old entry.
Paul Stewart75e89d22011-08-01 10:00:02 -0700422 RoutingTableEntry entry4(entry3);
423 entry4.metric += 10;
Paul Stewartf748a362012-03-07 12:01:20 -0800424 EXPECT_CALL(rtnl_handler_,
425 SendMessage(IsRoutingPacket(RTNLMessage::kModeAdd,
426 kTestDeviceIndex1,
427 entry4,
428 NLM_F_CREATE | NLM_F_REPLACE)));
429 EXPECT_CALL(rtnl_handler_,
430 SendMessage(IsRoutingPacket(RTNLMessage::kModeDelete,
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800431 kTestDeviceIndex1,
432 entry3,
Paul Stewartf748a362012-03-07 12:01:20 -0800433 0)));
Paul Stewart75e89d22011-08-01 10:00:02 -0700434 EXPECT_TRUE(routing_table_->SetDefaultRoute(kTestDeviceIndex1,
Paul Stewart5b7ba8c2012-04-18 09:08:00 -0700435 gateway_address,
Prabhu Kaliamoorthi762bfb82015-02-06 13:17:08 +0100436 entry4.metric,
437 kTestTableId));
Paul Stewart75e89d22011-08-01 10:00:02 -0700438
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800439 // Test that removing the table causes the route to disappear.
Paul Stewart75e89d22011-08-01 10:00:02 -0700440 routing_table_->ResetTable(kTestDeviceIndex1);
441 EXPECT_FALSE(ContainsKey(*tables, kTestDeviceIndex1));
442 EXPECT_FALSE(routing_table_->GetDefaultRoute(kTestDeviceIndex1,
Paul Stewart7355ce12011-09-02 10:47:01 -0700443 IPAddress::kFamilyIPv4,
Paul Stewart75e89d22011-08-01 10:00:02 -0700444 &test_entry));
445 EXPECT_EQ(1, GetRoutingTables()->size());
446
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800447 // When we set the metric on an existing route, a new add and delete
448 // operation should occur.
Paul Stewart75e89d22011-08-01 10:00:02 -0700449 RoutingTableEntry entry5(entry4);
450 entry5.metric += 10;
Paul Stewartf748a362012-03-07 12:01:20 -0800451 EXPECT_CALL(rtnl_handler_,
452 SendMessage(IsRoutingPacket(RTNLMessage::kModeAdd,
453 kTestDeviceIndex0,
454 entry5,
455 NLM_F_CREATE | NLM_F_REPLACE)));
456 EXPECT_CALL(rtnl_handler_,
457 SendMessage(IsRoutingPacket(RTNLMessage::kModeDelete,
458 kTestDeviceIndex0,
459 entry0,
460 0)));
Paul Stewart75e89d22011-08-01 10:00:02 -0700461 routing_table_->SetDefaultMetric(kTestDeviceIndex0, entry5.metric);
mukesh agrawald4ef6772012-02-21 16:28:04 -0800462 // Furthermore, the routing table should reflect the change in the metric
463 // for the default route for the interface.
464 RoutingTableEntry default_route;
465 EXPECT_TRUE(routing_table_->GetDefaultRoute(kTestDeviceIndex0,
466 IPAddress::kFamilyIPv4,
467 &default_route));
468 EXPECT_EQ(entry5.metric, default_route.metric);
Paul Stewart75e89d22011-08-01 10:00:02 -0700469
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800470 // Ask to flush table0. We should see a delete message sent.
Paul Stewartf748a362012-03-07 12:01:20 -0800471 EXPECT_CALL(rtnl_handler_,
472 SendMessage(IsRoutingPacket(RTNLMessage::kModeDelete,
473 kTestDeviceIndex0,
474 entry5,
475 0)));
Thieu Lefb46caf2012-03-08 11:57:15 -0800476 routing_table_->FlushRoutes(kTestDeviceIndex0);
477 EXPECT_EQ(0, (*tables)[kTestDeviceIndex0].size());
Paul Stewart75e89d22011-08-01 10:00:02 -0700478
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800479 // Test that the routing table size returns to zero.
Paul Stewartf748a362012-03-07 12:01:20 -0800480 SendRouteEntry(RTNLMessage::kModeAdd,
481 kTestDeviceIndex0,
482 entry5);
Paul Stewart75e89d22011-08-01 10:00:02 -0700483 EXPECT_EQ(1, GetRoutingTables()->size());
484 routing_table_->ResetTable(kTestDeviceIndex0);
485 EXPECT_EQ(0, GetRoutingTables()->size());
486
487 routing_table_->Stop();
Paul Stewartf748a362012-03-07 12:01:20 -0800488}
489
Paul Stewart3f68bb12012-03-15 13:33:10 -0700490TEST_F(RoutingTableTest, ConfigureRoutes) {
491 MockControl control;
492 IPConfigRefPtr ipconfig(new IPConfig(&control, kTestDeviceName0));
493 IPConfig::Properties properties;
494 properties.address_family = IPAddress::kFamilyIPv4;
Paul Stewart3b30ca52015-06-16 13:13:10 -0700495 vector<IPConfig::Route>& routes = properties.routes;
Samuel Tan3c3c36a2014-12-16 16:53:19 -0800496 ipconfig->UpdateProperties(properties, true);
Paul Stewart3f68bb12012-03-15 13:33:10 -0700497
498 const int kMetric = 10;
499 EXPECT_TRUE(routing_table_->ConfigureRoutes(kTestDeviceIndex0,
500 ipconfig,
Prabhu Kaliamoorthi762bfb82015-02-06 13:17:08 +0100501 kMetric,
502 kTestTableId));
Paul Stewart3f68bb12012-03-15 13:33:10 -0700503
504 IPConfig::Route route;
505 route.host = kTestRemoteNetwork4;
506 route.netmask = kTestRemoteNetmask4;
507 route.gateway = kTestGatewayAddress4;
508 routes.push_back(route);
Samuel Tan3c3c36a2014-12-16 16:53:19 -0800509 ipconfig->UpdateProperties(properties, true);
Paul Stewart3f68bb12012-03-15 13:33:10 -0700510
511 IPAddress destination_address(IPAddress::kFamilyIPv4);
512 IPAddress source_address(IPAddress::kFamilyIPv4);
513 IPAddress gateway_address(IPAddress::kFamilyIPv4);
514 ASSERT_TRUE(destination_address.SetAddressFromString(kTestRemoteNetwork4));
515 destination_address.set_prefix(kTestRemotePrefix4);
516 ASSERT_TRUE(gateway_address.SetAddressFromString(kTestGatewayAddress4));
517
518 RoutingTableEntry entry(destination_address,
519 source_address,
520 gateway_address,
521 kMetric,
522 RT_SCOPE_UNIVERSE,
Prabhu Kaliamoorthi762bfb82015-02-06 13:17:08 +0100523 false,
524 kTestTableId,
525 RoutingTableEntry::kDefaultTag);
Paul Stewart3f68bb12012-03-15 13:33:10 -0700526
527 EXPECT_CALL(rtnl_handler_,
528 SendMessage(IsRoutingPacket(RTNLMessage::kModeAdd,
529 kTestDeviceIndex0,
530 entry,
531 NLM_F_CREATE | NLM_F_EXCL)));
532 EXPECT_TRUE(routing_table_->ConfigureRoutes(kTestDeviceIndex0,
533 ipconfig,
Prabhu Kaliamoorthi762bfb82015-02-06 13:17:08 +0100534 kMetric,
535 kTestTableId));
Paul Stewart3f68bb12012-03-15 13:33:10 -0700536
537 routes.clear();
538 route.gateway = "xxx"; // Invalid gateway entry -- should be skipped
539 routes.push_back(route);
540 route.host = "xxx"; // Invalid host entry -- should be skipped
541 route.gateway = kTestGatewayAddress4;
542 routes.push_back(route);
543 route.host = kTestRemoteNetwork4;
544 routes.push_back(route);
Samuel Tan3c3c36a2014-12-16 16:53:19 -0800545 ipconfig->UpdateProperties(properties, true);
Paul Stewart3f68bb12012-03-15 13:33:10 -0700546
547 EXPECT_CALL(rtnl_handler_,
548 SendMessage(IsRoutingPacket(RTNLMessage::kModeAdd,
549 kTestDeviceIndex0,
550 entry,
551 NLM_F_CREATE | NLM_F_EXCL)))
552 .Times(1);
553 EXPECT_FALSE(routing_table_->ConfigureRoutes(kTestDeviceIndex0,
554 ipconfig,
Prabhu Kaliamoorthi762bfb82015-02-06 13:17:08 +0100555 kMetric,
556 kTestTableId));
Paul Stewart3f68bb12012-03-15 13:33:10 -0700557}
558
Paul Stewartf748a362012-03-07 12:01:20 -0800559MATCHER_P2(IsRoutingQuery, destination, index, "") {
Paul Stewart3b30ca52015-06-16 13:13:10 -0700560 const RTNLMessage::RouteStatus& status = arg->route_status();
Paul Stewartf748a362012-03-07 12:01:20 -0800561
Ben Chan7fab8972014-08-10 17:14:46 -0700562 uint32_t oif;
Paul Stewartf748a362012-03-07 12:01:20 -0800563
564 return
565 arg->type() == RTNLMessage::kTypeRoute &&
566 arg->family() == destination.family() &&
567 arg->flags() == NLM_F_REQUEST &&
568 status.table == 0 &&
569 status.protocol == 0 &&
570 status.scope == 0 &&
571 status.type == 0 &&
572 arg->HasAttribute(RTA_DST) &&
573 IPAddress(arg->family(),
574 arg->GetAttribute(RTA_DST),
575 status.dst_prefix).Equals(destination) &&
576 !arg->HasAttribute(RTA_SRC) &&
577 !arg->HasAttribute(RTA_GATEWAY) &&
578 arg->GetAttribute(RTA_OIF).ConvertToCPUUInt32(&oif) &&
579 oif == index &&
580 !arg->HasAttribute(RTA_PRIORITY);
581
582 return false;
583}
584
585TEST_F(RoutingTableTest, RequestHostRoute) {
586 IPAddress destination_address(IPAddress::kFamilyIPv4);
587 destination_address.SetAddressFromString(kTestRemoteAddress4);
588 destination_address.set_prefix(24);
589
590 EXPECT_CALL(rtnl_handler_,
591 SendMessage(IsRoutingQuery(destination_address,
592 kTestDeviceIndex0)))
593 .WillOnce(Invoke(this, &RoutingTableTest::SetSequenceForMessage));
Darin Petkovabf6d282012-05-08 15:49:05 +0200594 EXPECT_TRUE(
595 routing_table_->RequestRouteToHost(destination_address,
596 kTestDeviceIndex0,
597 kTestRouteTag,
Prabhu Kaliamoorthi762bfb82015-02-06 13:17:08 +0100598 RoutingTable::Query::Callback(),
599 kTestTableId));
Paul Stewartf748a362012-03-07 12:01:20 -0800600
601 IPAddress gateway_address(IPAddress::kFamilyIPv4);
602 gateway_address.SetAddressFromString(kTestGatewayAddress4);
603
604 IPAddress local_address(IPAddress::kFamilyIPv4);
605 local_address.SetAddressFromString(kTestDeviceNetAddress4);
606
607 const int kMetric = 10;
608 RoutingTableEntry entry(destination_address,
609 local_address,
610 gateway_address,
611 kMetric,
612 RT_SCOPE_UNIVERSE,
Prabhu Kaliamoorthi762bfb82015-02-06 13:17:08 +0100613 true,
614 kTestTableId,
615 RoutingTableEntry::kDefaultTag);
Paul Stewartf748a362012-03-07 12:01:20 -0800616
617 EXPECT_CALL(rtnl_handler_,
618 SendMessage(IsRoutingPacket(RTNLMessage::kModeAdd,
619 kTestDeviceIndex0,
620 entry,
621 NLM_F_CREATE | NLM_F_EXCL)));
622 SendRouteEntryWithSeqAndProto(RTNLMessage::kModeAdd,
623 kTestDeviceIndex0,
624 entry,
625 kTestRequestSeq,
626 RTPROT_UNSPEC);
Paul Stewarte93b0382012-04-24 13:11:28 -0700627
Paul Stewart3b30ca52015-06-16 13:13:10 -0700628 std::unordered_map<int, vector<RoutingTableEntry>>* tables =
Alex Vakulenko8a532292014-06-16 17:18:44 -0700629 GetRoutingTables();
Paul Stewarte93b0382012-04-24 13:11:28 -0700630
631 // We should have a single table, which should in turn have a single entry.
632 EXPECT_EQ(1, tables->size());
633 EXPECT_TRUE(ContainsKey(*tables, kTestDeviceIndex0));
634 EXPECT_EQ(1, (*tables)[kTestDeviceIndex0].size());
635
636 // This entry's tag should match the tag we requested.
637 EXPECT_EQ(kTestRouteTag, (*tables)[kTestDeviceIndex0][0].tag);
638
Darin Petkovabf6d282012-05-08 15:49:05 +0200639 EXPECT_TRUE(GetQueries()->empty());
640
Paul Stewarte93b0382012-04-24 13:11:28 -0700641 // Ask to flush routes with our tag. We should see a delete message sent.
642 EXPECT_CALL(rtnl_handler_,
643 SendMessage(IsRoutingPacket(RTNLMessage::kModeDelete,
644 kTestDeviceIndex0,
645 entry,
646 0)));
647
648 routing_table_->FlushRoutesWithTag(kTestRouteTag);
649
650 // After flushing routes for this tag, we should end up with no routes.
651 EXPECT_EQ(0, (*tables)[kTestDeviceIndex0].size());
Paul Stewartf748a362012-03-07 12:01:20 -0800652}
653
Paul Stewartbbed76d2012-04-27 20:02:13 -0700654TEST_F(RoutingTableTest, RequestHostRouteWithoutGateway) {
655 IPAddress destination_address(IPAddress::kFamilyIPv4);
656 destination_address.SetAddressFromString(kTestRemoteAddress4);
657 destination_address.set_prefix(24);
658
659 EXPECT_CALL(rtnl_handler_,
660 SendMessage(IsRoutingQuery(destination_address,
661 kTestDeviceIndex0)))
662 .WillOnce(Invoke(this, &RoutingTableTest::SetSequenceForMessage));
Darin Petkovabf6d282012-05-08 15:49:05 +0200663 EXPECT_TRUE(
664 routing_table_->RequestRouteToHost(destination_address,
665 kTestDeviceIndex0,
666 kTestRouteTag,
Prabhu Kaliamoorthi762bfb82015-02-06 13:17:08 +0100667 RoutingTable::Query::Callback(),
668 kTestTableId));
Paul Stewartbbed76d2012-04-27 20:02:13 -0700669
670 // Don't specify a gateway address.
671 IPAddress gateway_address(IPAddress::kFamilyIPv4);
672
673 IPAddress local_address(IPAddress::kFamilyIPv4);
674 local_address.SetAddressFromString(kTestDeviceNetAddress4);
675
676 const int kMetric = 10;
677 RoutingTableEntry entry(destination_address,
678 local_address,
679 gateway_address,
680 kMetric,
681 RT_SCOPE_UNIVERSE,
682 true);
683
684 // Ensure that without a gateway entry, we don't create a route.
685 EXPECT_CALL(rtnl_handler_, SendMessage(_)).Times(0);
686 SendRouteEntryWithSeqAndProto(RTNLMessage::kModeAdd,
687 kTestDeviceIndex0,
688 entry,
689 kTestRequestSeq,
690 RTPROT_UNSPEC);
Darin Petkovabf6d282012-05-08 15:49:05 +0200691 EXPECT_TRUE(GetQueries()->empty());
Paul Stewartbbed76d2012-04-27 20:02:13 -0700692}
693
Paul Stewartf748a362012-03-07 12:01:20 -0800694TEST_F(RoutingTableTest, RequestHostRouteBadSequence) {
695 IPAddress destination_address(IPAddress::kFamilyIPv4);
696 destination_address.SetAddressFromString(kTestRemoteAddress4);
Darin Petkovabf6d282012-05-08 15:49:05 +0200697 QueryCallbackTarget target;
Darin Petkov13e6d552012-05-09 14:22:23 +0200698 EXPECT_CALL(target, MockedTarget(_, _)).Times(0);
Paul Stewartf748a362012-03-07 12:01:20 -0800699 EXPECT_CALL(rtnl_handler_, SendMessage(_))
700 .WillOnce(Invoke(this, &RoutingTableTest::SetSequenceForMessage));
Darin Petkovabf6d282012-05-08 15:49:05 +0200701 EXPECT_TRUE(
702 routing_table_->RequestRouteToHost(destination_address,
703 kTestDeviceIndex0,
704 kTestRouteTag,
Prabhu Kaliamoorthi762bfb82015-02-06 13:17:08 +0100705 target.mocked_callback(),
706 kTestTableId));
Paul Stewarte93b0382012-04-24 13:11:28 -0700707 EXPECT_FALSE(GetQueries()->empty());
Paul Stewartf748a362012-03-07 12:01:20 -0800708
709 RoutingTableEntry entry(destination_address,
710 destination_address,
711 destination_address,
712 0,
713 RT_SCOPE_UNIVERSE,
714 true);
715
716 // Try a sequence arriving before the one RoutingTable is looking for.
717 // This should be a no-op.
718 SendRouteEntryWithSeqAndProto(RTNLMessage::kModeAdd,
719 kTestDeviceIndex0,
720 entry,
Darin Petkovabf6d282012-05-08 15:49:05 +0200721 kTestRequestSeq - 1,
Paul Stewartf748a362012-03-07 12:01:20 -0800722 RTPROT_UNSPEC);
Paul Stewarte93b0382012-04-24 13:11:28 -0700723 EXPECT_FALSE(GetQueries()->empty());
Paul Stewartf748a362012-03-07 12:01:20 -0800724
725 // Try a sequence arriving after the one RoutingTable is looking for.
726 // This should cause the request to be purged.
727 SendRouteEntryWithSeqAndProto(RTNLMessage::kModeAdd,
728 kTestDeviceIndex0,
729 entry,
Darin Petkovabf6d282012-05-08 15:49:05 +0200730 kTestRequestSeq + 1,
Paul Stewartf748a362012-03-07 12:01:20 -0800731 RTPROT_UNSPEC);
Paul Stewarte93b0382012-04-24 13:11:28 -0700732 EXPECT_TRUE(GetQueries()->empty());
Paul Stewart75e89d22011-08-01 10:00:02 -0700733}
734
Darin Petkovabf6d282012-05-08 15:49:05 +0200735TEST_F(RoutingTableTest, RequestHostRouteWithCallback) {
736 IPAddress destination_address(IPAddress::kFamilyIPv4);
737
738 EXPECT_CALL(rtnl_handler_, SendMessage(_))
739 .WillOnce(Invoke(this, &RoutingTableTest::SetSequenceForMessage));
740 QueryCallbackTarget target;
741 EXPECT_TRUE(
Prabhu Kaliamoorthi762bfb82015-02-06 13:17:08 +0100742 routing_table_->RequestRouteToHost(destination_address,
743 -1,
744 kTestRouteTag,
745 target.mocked_callback(),
746 kTestTableId));
Darin Petkovabf6d282012-05-08 15:49:05 +0200747
748 IPAddress gateway_address(IPAddress::kFamilyIPv4);
749 gateway_address.SetAddressFromString(kTestGatewayAddress4);
Darin Petkovabf6d282012-05-08 15:49:05 +0200750
751 const int kMetric = 10;
752 RoutingTableEntry entry(destination_address,
Darin Petkov13e6d552012-05-09 14:22:23 +0200753 IPAddress(IPAddress::kFamilyIPv4),
Darin Petkovabf6d282012-05-08 15:49:05 +0200754 gateway_address,
755 kMetric,
756 RT_SCOPE_UNIVERSE,
757 true);
758
759 EXPECT_CALL(rtnl_handler_, SendMessage(_));
760 EXPECT_CALL(target,
Darin Petkov13e6d552012-05-09 14:22:23 +0200761 MockedTarget(kTestDeviceIndex0,
762 Field(&RoutingTableEntry::tag, kTestRouteTag)));
Darin Petkovabf6d282012-05-08 15:49:05 +0200763 SendRouteEntryWithSeqAndProto(RTNLMessage::kModeAdd,
764 kTestDeviceIndex0,
765 entry,
766 kTestRequestSeq,
767 RTPROT_UNSPEC);
768}
769
770TEST_F(RoutingTableTest, RequestHostRouteWithoutGatewayWithCallback) {
771 IPAddress destination_address(IPAddress::kFamilyIPv4);
772
773 EXPECT_CALL(rtnl_handler_, SendMessage(_))
774 .WillOnce(Invoke(this, &RoutingTableTest::SetSequenceForMessage));
775 QueryCallbackTarget target;
776 EXPECT_TRUE(
Prabhu Kaliamoorthi762bfb82015-02-06 13:17:08 +0100777 routing_table_->RequestRouteToHost(destination_address,
778 -1,
779 kTestRouteTag,
780 target.mocked_callback(),
781 kTestTableId));
Darin Petkovabf6d282012-05-08 15:49:05 +0200782
783 const int kMetric = 10;
784 RoutingTableEntry entry(destination_address,
Darin Petkov13e6d552012-05-09 14:22:23 +0200785 IPAddress(IPAddress::kFamilyIPv4),
786 IPAddress(IPAddress::kFamilyIPv4),
Darin Petkovabf6d282012-05-08 15:49:05 +0200787 kMetric,
788 RT_SCOPE_UNIVERSE,
789 true);
790
791 EXPECT_CALL(target,
Darin Petkov13e6d552012-05-09 14:22:23 +0200792 MockedTarget(kTestDeviceIndex0,
793 Field(&RoutingTableEntry::tag, kTestRouteTag)));
Darin Petkovabf6d282012-05-08 15:49:05 +0200794 SendRouteEntryWithSeqAndProto(RTNLMessage::kModeAdd,
795 kTestDeviceIndex0,
796 entry,
797 kTestRequestSeq,
798 RTPROT_UNSPEC);
799}
800
801TEST_F(RoutingTableTest, CancelQueryCallback) {
802 IPAddress destination_address(IPAddress::kFamilyIPv4);
803 destination_address.SetAddressFromString(kTestRemoteAddress4);
Ben Chancd477322014-10-17 14:19:30 -0700804 std::unique_ptr<QueryCallbackTarget> target(new QueryCallbackTarget());
Darin Petkov13e6d552012-05-09 14:22:23 +0200805 EXPECT_CALL(rtnl_handler_, SendMessage(_))
806 .WillOnce(Invoke(this, &RoutingTableTest::SetSequenceForMessage));
Darin Petkovabf6d282012-05-08 15:49:05 +0200807 EXPECT_TRUE(
808 routing_table_->RequestRouteToHost(destination_address,
809 kTestDeviceIndex0,
810 kTestRouteTag,
Prabhu Kaliamoorthi762bfb82015-02-06 13:17:08 +0100811 target->unreached_callback(),
812 kTestTableId));
Darin Petkov13e6d552012-05-09 14:22:23 +0200813 ASSERT_EQ(1, GetQueries()->size());
814 // Cancels the callback by destroying the owner object.
815 target.reset();
816 const int kMetric = 10;
817 RoutingTableEntry entry(IPAddress(IPAddress::kFamilyIPv4),
818 IPAddress(IPAddress::kFamilyIPv4),
819 IPAddress(IPAddress::kFamilyIPv4),
820 kMetric,
821 RT_SCOPE_UNIVERSE,
822 true);
823 SendRouteEntryWithSeqAndProto(RTNLMessage::kModeAdd,
824 kTestDeviceIndex0,
825 entry,
826 kTestRequestSeq,
827 RTPROT_UNSPEC);
Darin Petkovabf6d282012-05-08 15:49:05 +0200828}
829
Ben Chana0163122012-09-25 15:10:52 -0700830TEST_F(RoutingTableTest, CreateBlackholeRoute) {
Ben Chan7fab8972014-08-10 17:14:46 -0700831 const uint32_t kMetric = 2;
Ben Chana0163122012-09-25 15:10:52 -0700832 EXPECT_CALL(rtnl_handler_,
833 SendMessage(IsBlackholeRoutingPacket(kTestDeviceIndex0,
834 IPAddress::kFamilyIPv6,
835 kMetric)))
836 .Times(1);
837 EXPECT_TRUE(routing_table_->CreateBlackholeRoute(kTestDeviceIndex0,
838 IPAddress::kFamilyIPv6,
Prabhu Kaliamoorthi762bfb82015-02-06 13:17:08 +0100839 kMetric,
840 kTestTableId));
Ben Chana0163122012-09-25 15:10:52 -0700841}
842
Paul Stewart4a6748d2012-07-17 14:31:36 -0700843TEST_F(RoutingTableTest, CreateLinkRoute) {
844 IPAddress local_address(IPAddress::kFamilyIPv4);
845 ASSERT_TRUE(local_address.SetAddressFromString(kTestNetAddress0));
846 local_address.set_prefix(kTestRemotePrefix4);
847 IPAddress remote_address(IPAddress::kFamilyIPv4);
848 ASSERT_TRUE(remote_address.SetAddressFromString(kTestNetAddress1));
849 IPAddress default_address(IPAddress::kFamilyIPv4);
850 IPAddress remote_address_with_prefix(remote_address);
851 remote_address_with_prefix.set_prefix(
852 IPAddress::GetMaxPrefixLength(remote_address_with_prefix.family()));
853 RoutingTableEntry entry(remote_address_with_prefix,
854 local_address,
855 default_address,
856 0,
857 RT_SCOPE_LINK,
Prabhu Kaliamoorthi762bfb82015-02-06 13:17:08 +0100858 false,
859 kTestTableId,
860 RoutingTableEntry::kDefaultTag);
Paul Stewart4a6748d2012-07-17 14:31:36 -0700861 EXPECT_CALL(rtnl_handler_,
862 SendMessage(IsRoutingPacket(RTNLMessage::kModeAdd,
863 kTestDeviceIndex0,
864 entry,
865 NLM_F_CREATE | NLM_F_EXCL)))
866 .Times(1);
867 EXPECT_TRUE(routing_table_->CreateLinkRoute(kTestDeviceIndex0,
868 local_address,
Prabhu Kaliamoorthi762bfb82015-02-06 13:17:08 +0100869 remote_address,
870 kTestTableId));
Paul Stewart4a6748d2012-07-17 14:31:36 -0700871
872 ASSERT_TRUE(remote_address.SetAddressFromString(kTestRemoteAddress4));
873 EXPECT_FALSE(routing_table_->CreateLinkRoute(kTestDeviceIndex0,
874 local_address,
Prabhu Kaliamoorthi762bfb82015-02-06 13:17:08 +0100875 remote_address,
876 kTestTableId));
Paul Stewart4a6748d2012-07-17 14:31:36 -0700877}
878
Paul Stewart75e89d22011-08-01 10:00:02 -0700879} // namespace shill