blob: 2f4596624714cb70469b513d500df9c47884ac2f [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
Paul Stewart75e89d22011-08-01 10:00:02 -07005#include <linux/rtnetlink.h>
Alex Vakulenkoa41ab512014-07-23 14:24:23 -07006#include <sys/socket.h>
Paul Stewart75e89d22011-08-01 10:00:02 -07007
Paul Stewart3f68bb12012-03-15 13:33:10 -07008#include <vector>
9
Paul Stewart8d5e2162014-08-29 14:41:59 -070010#include <base/memory/scoped_ptr.h>
Darin Petkov13e6d552012-05-09 14:22:23 +020011#include <base/memory/weak_ptr.h>
Eric Shienbrood3e20a232012-02-16 11:35:56 -050012#include <base/stl_util.h>
Paul Stewart75e89d22011-08-01 10:00:02 -070013#include <gtest/gtest.h>
14#include <gmock/gmock.h>
15
16#include "shill/byte_string.h"
Christopher Wileyb691efd2012-08-09 13:51:51 -070017#include "shill/logging.h"
Paul Stewart75e89d22011-08-01 10:00:02 -070018#include "shill/mock_control.h"
Paul Stewartf748a362012-03-07 12:01:20 -080019#include "shill/mock_rtnl_handler.h"
Paul Stewart75e89d22011-08-01 10:00:02 -070020#include "shill/routing_table.h"
21#include "shill/routing_table_entry.h"
22#include "shill/rtnl_handler.h"
23#include "shill/rtnl_message.h"
24
Darin Petkovabf6d282012-05-08 15:49:05 +020025using base::Bind;
Eric Shienbrood3e20a232012-02-16 11:35:56 -050026using base::Callback;
Darin Petkovabf6d282012-05-08 15:49:05 +020027using base::Unretained;
Darin Petkovabf6d282012-05-08 15:49:05 +020028using std::deque;
Paul Stewart3f68bb12012-03-15 13:33:10 -070029using std::vector;
Paul Stewart75e89d22011-08-01 10:00:02 -070030using testing::_;
Darin Petkovabf6d282012-05-08 15:49:05 +020031using testing::Field;
Paul Stewartf748a362012-03-07 12:01:20 -080032using testing::Invoke;
Paul Stewart75e89d22011-08-01 10:00:02 -070033using testing::Return;
Paul Stewartf748a362012-03-07 12:01:20 -080034using testing::StrictMock;
Paul Stewart75e89d22011-08-01 10:00:02 -070035using testing::Test;
36
37namespace shill {
38
39class TestEventDispatcher : public EventDispatcher {
40 public:
Paul Stewart26b327e2011-10-19 11:38:09 -070041 virtual IOHandler *CreateInputHandler(
mukesh agrawal1830fa12011-09-26 14:31:40 -070042 int /*fd*/,
Paul Stewart5f06a0e2012-12-20 11:11:33 -080043 const IOHandler::InputCallback &/*input_callback*/,
44 const IOHandler::ErrorCallback &/*error_callback*/) {
Paul Stewart75e89d22011-08-01 10:00:02 -070045 return NULL;
46 }
47};
48
49class RoutingTableTest : public Test {
50 public:
Paul Stewarte93b0382012-04-24 13:11:28 -070051 RoutingTableTest() : routing_table_(new RoutingTable()) {}
Paul Stewart75e89d22011-08-01 10:00:02 -070052
Paul Stewartf748a362012-03-07 12:01:20 -080053 virtual void SetUp() {
54 routing_table_->rtnl_handler_ = &rtnl_handler_;
55 ON_CALL(rtnl_handler_, SendMessage(_)).WillByDefault(Return(true));
Paul Stewart75e89d22011-08-01 10:00:02 -070056 }
57
Paul Stewart65c40f52011-08-08 07:27:46 -070058 virtual void TearDown() {
59 RTNLHandler::GetInstance()->Stop();
60 }
61
Alex Vakulenko8a532292014-06-16 17:18:44 -070062 std::unordered_map<int, vector<RoutingTableEntry>> *GetRoutingTables() {
Paul Stewartf748a362012-03-07 12:01:20 -080063 return &routing_table_->tables_;
64 }
65
Darin Petkovabf6d282012-05-08 15:49:05 +020066 deque<RoutingTable::Query> *GetQueries() {
Paul Stewarte93b0382012-04-24 13:11:28 -070067 return &routing_table_->route_queries_;
Paul Stewartf748a362012-03-07 12:01:20 -080068 }
69
70 void SendRouteEntry(RTNLMessage::Mode mode,
Ben Chan7fab8972014-08-10 17:14:46 -070071 uint32_t interface_index,
Paul Stewartf748a362012-03-07 12:01:20 -080072 const RoutingTableEntry &entry);
73
74 void SendRouteEntryWithSeqAndProto(RTNLMessage::Mode mode,
Ben Chan7fab8972014-08-10 17:14:46 -070075 uint32_t interface_index,
Paul Stewartf748a362012-03-07 12:01:20 -080076 const RoutingTableEntry &entry,
Ben Chan7fab8972014-08-10 17:14:46 -070077 uint32_t seq,
Paul Stewartf748a362012-03-07 12:01:20 -080078 unsigned char proto);
79
80 void SendRouteMessage(const RTNLMessage &msg);
81
82 bool SetSequenceForMessage(RTNLMessage *message) {
83 message->set_seq(RoutingTableTest::kTestRequestSeq);
84 return true;
85 }
86
Paul Stewart75e89d22011-08-01 10:00:02 -070087 protected:
Ben Chan7fab8972014-08-10 17:14:46 -070088 static const uint32_t kTestDeviceIndex0;
89 static const uint32_t kTestDeviceIndex1;
Paul Stewart75e89d22011-08-01 10:00:02 -070090 static const char kTestDeviceName0[];
Thieu Lecaef8932012-02-28 16:06:59 -080091 static const char kTestDeviceNetAddress4[];
92 static const char kTestForeignNetAddress4[];
93 static const char kTestForeignNetGateway4[];
94 static const char kTestForeignNetAddress6[];
95 static const char kTestForeignNetGateway6[];
Paul Stewartf748a362012-03-07 12:01:20 -080096 static const char kTestGatewayAddress4[];
Paul Stewart75e89d22011-08-01 10:00:02 -070097 static const char kTestNetAddress0[];
98 static const char kTestNetAddress1[];
Paul Stewartf748a362012-03-07 12:01:20 -080099 static const char kTestRemoteAddress4[];
Paul Stewart3f68bb12012-03-15 13:33:10 -0700100 static const char kTestRemoteNetmask4[];
101 static const char kTestRemoteNetwork4[];
102 static const int kTestRemotePrefix4;
Ben Chan7fab8972014-08-10 17:14:46 -0700103 static const uint32_t kTestRequestSeq;
Paul Stewarte93b0382012-04-24 13:11:28 -0700104 static const int kTestRouteTag;
Paul Stewart75e89d22011-08-01 10:00:02 -0700105
Darin Petkovabf6d282012-05-08 15:49:05 +0200106 class QueryCallbackTarget {
107 public:
108 QueryCallbackTarget()
Darin Petkov13e6d552012-05-09 14:22:23 +0200109 : weak_ptr_factory_(this),
110 mocked_callback_(
111 Bind(&QueryCallbackTarget::MockedTarget, Unretained(this))),
112 unreached_callback_(Bind(&QueryCallbackTarget::UnreachedTarget,
113 weak_ptr_factory_.GetWeakPtr())) {}
Darin Petkovabf6d282012-05-08 15:49:05 +0200114
Darin Petkov13e6d552012-05-09 14:22:23 +0200115 MOCK_METHOD2(MockedTarget,
Darin Petkovabf6d282012-05-08 15:49:05 +0200116 void(int interface_index, const RoutingTableEntry &entry));
Darin Petkov13e6d552012-05-09 14:22:23 +0200117
118 void UnreachedTarget(int interface_index, const RoutingTableEntry &entry) {
119 CHECK(false);
120 }
121
122 const RoutingTable::Query::Callback &mocked_callback() const {
123 return mocked_callback_;
124 }
125
126 const RoutingTable::Query::Callback &unreached_callback() const {
127 return unreached_callback_;
128 }
Darin Petkovabf6d282012-05-08 15:49:05 +0200129
130 private:
Darin Petkov13e6d552012-05-09 14:22:23 +0200131 base::WeakPtrFactory<QueryCallbackTarget> weak_ptr_factory_;
132 const RoutingTable::Query::Callback mocked_callback_;
133 const RoutingTable::Query::Callback unreached_callback_;
Darin Petkovabf6d282012-05-08 15:49:05 +0200134 };
135
Paul Stewart8d5e2162014-08-29 14:41:59 -0700136 scoped_ptr<RoutingTable> routing_table_;
Paul Stewart75e89d22011-08-01 10:00:02 -0700137 TestEventDispatcher dispatcher_;
Paul Stewartf748a362012-03-07 12:01:20 -0800138 StrictMock<MockRTNLHandler> rtnl_handler_;
Paul Stewart75e89d22011-08-01 10:00:02 -0700139};
140
Ben Chan7fab8972014-08-10 17:14:46 -0700141const uint32_t RoutingTableTest::kTestDeviceIndex0 = 12345;
142const uint32_t RoutingTableTest::kTestDeviceIndex1 = 67890;
Paul Stewart75e89d22011-08-01 10:00:02 -0700143const char RoutingTableTest::kTestDeviceName0[] = "test-device0";
Thieu Lecaef8932012-02-28 16:06:59 -0800144const char RoutingTableTest::kTestDeviceNetAddress4[] = "192.168.2.0/24";
145const char RoutingTableTest::kTestForeignNetAddress4[] = "192.168.2.2";
146const char RoutingTableTest::kTestForeignNetGateway4[] = "192.168.2.1";
147const char RoutingTableTest::kTestForeignNetAddress6[] = "2000::/3";
148const char RoutingTableTest::kTestForeignNetGateway6[] = "fe80:::::1";
Paul Stewartf748a362012-03-07 12:01:20 -0800149const char RoutingTableTest::kTestGatewayAddress4[] = "192.168.2.254";
Paul Stewart75e89d22011-08-01 10:00:02 -0700150const char RoutingTableTest::kTestNetAddress0[] = "192.168.1.1";
151const char RoutingTableTest::kTestNetAddress1[] = "192.168.1.2";
Paul Stewartf748a362012-03-07 12:01:20 -0800152const char RoutingTableTest::kTestRemoteAddress4[] = "192.168.2.254";
Paul Stewart3f68bb12012-03-15 13:33:10 -0700153const char RoutingTableTest::kTestRemoteNetmask4[] = "255.255.255.0";
154const char RoutingTableTest::kTestRemoteNetwork4[] = "192.168.100.0";
155const int RoutingTableTest::kTestRemotePrefix4 = 24;
Ben Chan7fab8972014-08-10 17:14:46 -0700156const uint32_t RoutingTableTest::kTestRequestSeq = 456;
Paul Stewarte93b0382012-04-24 13:11:28 -0700157const int RoutingTableTest::kTestRouteTag = 789;
Paul Stewart75e89d22011-08-01 10:00:02 -0700158
Darin Petkovabf6d282012-05-08 15:49:05 +0200159namespace {
160
Ben Chana0163122012-09-25 15:10:52 -0700161MATCHER_P3(IsBlackholeRoutingPacket, index, family, metric, "") {
162 const RTNLMessage::RouteStatus &status = arg->route_status();
163
Ben Chan7fab8972014-08-10 17:14:46 -0700164 uint32_t oif;
165 uint32_t priority;
Ben Chana0163122012-09-25 15:10:52 -0700166
167 return
168 arg->type() == RTNLMessage::kTypeRoute &&
169 arg->family() == family &&
170 arg->flags() == (NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL) &&
171 status.table == RT_TABLE_MAIN &&
172 status.protocol == RTPROT_BOOT &&
173 status.scope == RT_SCOPE_UNIVERSE &&
174 status.type == RTN_BLACKHOLE &&
175 !arg->HasAttribute(RTA_DST) &&
176 !arg->HasAttribute(RTA_SRC) &&
177 !arg->HasAttribute(RTA_GATEWAY) &&
178 arg->GetAttribute(RTA_OIF).ConvertToCPUUInt32(&oif) &&
179 oif == index &&
180 arg->GetAttribute(RTA_PRIORITY).ConvertToCPUUInt32(&priority) &&
181 priority == metric;
182}
183
Paul Stewart75e89d22011-08-01 10:00:02 -0700184MATCHER_P4(IsRoutingPacket, mode, index, entry, flags, "") {
Paul Stewartf748a362012-03-07 12:01:20 -0800185 const RTNLMessage::RouteStatus &status = arg->route_status();
Paul Stewart75e89d22011-08-01 10:00:02 -0700186
Ben Chan7fab8972014-08-10 17:14:46 -0700187 uint32_t oif;
188 uint32_t priority;
Paul Stewart75e89d22011-08-01 10:00:02 -0700189
190 return
Paul Stewartf748a362012-03-07 12:01:20 -0800191 arg->type() == RTNLMessage::kTypeRoute &&
192 arg->family() == entry.gateway.family() &&
193 arg->flags() == (NLM_F_REQUEST | flags) &&
194 status.table == RT_TABLE_MAIN &&
195 status.protocol == RTPROT_BOOT &&
196 status.scope == entry.scope &&
197 status.type == RTN_UNICAST &&
198 arg->HasAttribute(RTA_DST) &&
199 IPAddress(arg->family(),
200 arg->GetAttribute(RTA_DST),
201 status.dst_prefix).Equals(entry.dst) &&
Paul Stewart4a6748d2012-07-17 14:31:36 -0700202 ((!arg->HasAttribute(RTA_SRC) && entry.src.IsDefault()) ||
203 (arg->HasAttribute(RTA_SRC) && IPAddress(arg->family(),
204 arg->GetAttribute(RTA_SRC),
205 status.src_prefix).Equals(entry.src))) &&
206 ((!arg->HasAttribute(RTA_GATEWAY) && entry.gateway.IsDefault()) ||
207 (arg->HasAttribute(RTA_GATEWAY) && IPAddress(arg->family(),
208 arg->GetAttribute(RTA_GATEWAY)).Equals(entry.gateway))) &&
Paul Stewartf748a362012-03-07 12:01:20 -0800209 arg->GetAttribute(RTA_OIF).ConvertToCPUUInt32(&oif) &&
210 oif == index &&
211 arg->GetAttribute(RTA_PRIORITY).ConvertToCPUUInt32(&priority) &&
212 priority == entry.metric;
Paul Stewart75e89d22011-08-01 10:00:02 -0700213}
214
Darin Petkovabf6d282012-05-08 15:49:05 +0200215} // namespace
216
Paul Stewartf748a362012-03-07 12:01:20 -0800217void RoutingTableTest::SendRouteEntry(RTNLMessage::Mode mode,
Ben Chan7fab8972014-08-10 17:14:46 -0700218 uint32_t interface_index,
Paul Stewartf748a362012-03-07 12:01:20 -0800219 const RoutingTableEntry &entry) {
220 SendRouteEntryWithSeqAndProto(mode, interface_index, entry, 0, RTPROT_BOOT);
221}
222
223void RoutingTableTest::SendRouteEntryWithSeqAndProto(
224 RTNLMessage::Mode mode,
Ben Chan7fab8972014-08-10 17:14:46 -0700225 uint32_t interface_index,
Paul Stewartf748a362012-03-07 12:01:20 -0800226 const RoutingTableEntry &entry,
Ben Chan7fab8972014-08-10 17:14:46 -0700227 uint32_t seq,
Paul Stewartf748a362012-03-07 12:01:20 -0800228 unsigned char proto) {
Paul Stewart75e89d22011-08-01 10:00:02 -0700229 RTNLMessage msg(
Paul Stewart9a908082011-08-31 12:18:48 -0700230 RTNLMessage::kTypeRoute,
Paul Stewart75e89d22011-08-01 10:00:02 -0700231 mode,
232 0,
Paul Stewartf748a362012-03-07 12:01:20 -0800233 seq,
Paul Stewart75e89d22011-08-01 10:00:02 -0700234 0,
235 0,
236 entry.dst.family());
237
238 msg.set_route_status(RTNLMessage::RouteStatus(
Paul Stewart9e3fcd72011-08-26 15:46:16 -0700239 entry.dst.prefix(),
240 entry.src.prefix(),
Paul Stewart75e89d22011-08-01 10:00:02 -0700241 RT_TABLE_MAIN,
Paul Stewartf748a362012-03-07 12:01:20 -0800242 proto,
Paul Stewart75e89d22011-08-01 10:00:02 -0700243 entry.scope,
244 RTN_UNICAST,
245 0));
246
247 msg.SetAttribute(RTA_DST, entry.dst.address());
248 if (!entry.src.IsDefault()) {
249 msg.SetAttribute(RTA_SRC, entry.src.address());
250 }
251 if (!entry.gateway.IsDefault()) {
252 msg.SetAttribute(RTA_GATEWAY, entry.gateway.address());
253 }
254 msg.SetAttribute(RTA_PRIORITY, ByteString::CreateFromCPUUInt32(entry.metric));
255 msg.SetAttribute(RTA_OIF, ByteString::CreateFromCPUUInt32(interface_index));
256
Paul Stewartf748a362012-03-07 12:01:20 -0800257 routing_table_->RouteMsgHandler(msg);
Paul Stewart75e89d22011-08-01 10:00:02 -0700258}
259
Paul Stewartf748a362012-03-07 12:01:20 -0800260void RoutingTableTest::SendRouteMessage(const RTNLMessage &msg) {
261 routing_table_->RouteMsgHandler(msg);
Paul Stewart75e89d22011-08-01 10:00:02 -0700262}
263
Paul Stewartf748a362012-03-07 12:01:20 -0800264TEST_F(RoutingTableTest, Start) {
265 EXPECT_CALL(rtnl_handler_, RequestDump(RTNLHandler::kRequestRoute));
266 routing_table_->Start();
Paul Stewart75e89d22011-08-01 10:00:02 -0700267}
268
269TEST_F(RoutingTableTest, RouteAddDelete) {
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800270 // Expect the tables to be empty by default.
Paul Stewart75e89d22011-08-01 10:00:02 -0700271 EXPECT_EQ(0, GetRoutingTables()->size());
272
Paul Stewart7355ce12011-09-02 10:47:01 -0700273 IPAddress default_address(IPAddress::kFamilyIPv4);
Paul Stewart75e89d22011-08-01 10:00:02 -0700274 default_address.SetAddressToDefault();
275
Paul Stewart7355ce12011-09-02 10:47:01 -0700276 IPAddress gateway_address0(IPAddress::kFamilyIPv4);
Paul Stewart75e89d22011-08-01 10:00:02 -0700277 gateway_address0.SetAddressFromString(kTestNetAddress0);
278
279 int metric = 10;
280
281 RoutingTableEntry entry0(default_address,
Paul Stewart75e89d22011-08-01 10:00:02 -0700282 default_address,
Paul Stewart75e89d22011-08-01 10:00:02 -0700283 gateway_address0,
284 metric,
285 RT_SCOPE_UNIVERSE,
286 true);
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800287 // Add a single entry.
Paul Stewartf748a362012-03-07 12:01:20 -0800288 SendRouteEntry(RTNLMessage::kModeAdd,
289 kTestDeviceIndex0,
290 entry0);
Paul Stewart75e89d22011-08-01 10:00:02 -0700291
Alex Vakulenko8a532292014-06-16 17:18:44 -0700292 std::unordered_map<int, vector<RoutingTableEntry>> *tables =
293 GetRoutingTables();
Paul Stewart75e89d22011-08-01 10:00:02 -0700294
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800295 // We should have a single table, which should in turn have a single entry.
Paul Stewart75e89d22011-08-01 10:00:02 -0700296 EXPECT_EQ(1, tables->size());
297 EXPECT_TRUE(ContainsKey(*tables, kTestDeviceIndex0));
298 EXPECT_EQ(1, (*tables)[kTestDeviceIndex0].size());
299
300 RoutingTableEntry test_entry = (*tables)[kTestDeviceIndex0][0];
301 EXPECT_TRUE(entry0.Equals(test_entry));
302
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800303 // Add a second entry for a different interface.
Paul Stewartf748a362012-03-07 12:01:20 -0800304 SendRouteEntry(RTNLMessage::kModeAdd,
305 kTestDeviceIndex1,
306 entry0);
Paul Stewart75e89d22011-08-01 10:00:02 -0700307
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800308 // We should have two tables, which should have a single entry each.
Paul Stewart75e89d22011-08-01 10:00:02 -0700309 EXPECT_EQ(2, tables->size());
310 EXPECT_TRUE(ContainsKey(*tables, kTestDeviceIndex1));
311 EXPECT_EQ(1, (*tables)[kTestDeviceIndex0].size());
312 EXPECT_EQ(1, (*tables)[kTestDeviceIndex1].size());
313
314 test_entry = (*tables)[kTestDeviceIndex1][0];
315 EXPECT_TRUE(entry0.Equals(test_entry));
316
Paul Stewart7355ce12011-09-02 10:47:01 -0700317 IPAddress gateway_address1(IPAddress::kFamilyIPv4);
Paul Stewart75e89d22011-08-01 10:00:02 -0700318 gateway_address1.SetAddressFromString(kTestNetAddress1);
319
320 RoutingTableEntry entry1(default_address,
Paul Stewart75e89d22011-08-01 10:00:02 -0700321 default_address,
Paul Stewart75e89d22011-08-01 10:00:02 -0700322 gateway_address1,
323 metric,
324 RT_SCOPE_UNIVERSE,
325 true);
326
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800327 // Add a second gateway route to the second interface.
Paul Stewartf748a362012-03-07 12:01:20 -0800328 SendRouteEntry(RTNLMessage::kModeAdd,
329 kTestDeviceIndex1,
330 entry1);
Paul Stewart75e89d22011-08-01 10:00:02 -0700331
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800332 // We should have two tables, one of which has a single entry, the other has
333 // two.
Paul Stewart75e89d22011-08-01 10:00:02 -0700334 EXPECT_EQ(2, tables->size());
335 EXPECT_EQ(1, (*tables)[kTestDeviceIndex0].size());
336 EXPECT_EQ(2, (*tables)[kTestDeviceIndex1].size());
337
338 test_entry = (*tables)[kTestDeviceIndex1][1];
339 EXPECT_TRUE(entry1.Equals(test_entry));
340
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800341 // Remove the first gateway route from the second interface.
Paul Stewartf748a362012-03-07 12:01:20 -0800342 SendRouteEntry(RTNLMessage::kModeDelete,
343 kTestDeviceIndex1,
344 entry0);
Paul Stewart75e89d22011-08-01 10:00:02 -0700345
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800346 // We should be back to having one route per table.
Paul Stewart75e89d22011-08-01 10:00:02 -0700347 EXPECT_EQ(2, tables->size());
348 EXPECT_EQ(1, (*tables)[kTestDeviceIndex0].size());
349 EXPECT_EQ(1, (*tables)[kTestDeviceIndex1].size());
350
351 test_entry = (*tables)[kTestDeviceIndex1][0];
352 EXPECT_TRUE(entry1.Equals(test_entry));
353
Paul Stewart5b7ba8c2012-04-18 09:08:00 -0700354 // Send a duplicate of the second gateway route message, changing the metric.
Paul Stewart75e89d22011-08-01 10:00:02 -0700355 RoutingTableEntry entry2(entry1);
356 entry2.metric++;
Paul Stewartf748a362012-03-07 12:01:20 -0800357 SendRouteEntry(RTNLMessage::kModeAdd,
358 kTestDeviceIndex1,
359 entry2);
Paul Stewart75e89d22011-08-01 10:00:02 -0700360
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800361 // Routing table size shouldn't change, but the new metric should match.
Paul Stewart75e89d22011-08-01 10:00:02 -0700362 EXPECT_EQ(1, (*tables)[kTestDeviceIndex1].size());
363 test_entry = (*tables)[kTestDeviceIndex1][0];
364 EXPECT_TRUE(entry2.Equals(test_entry));
365
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800366 // Find a matching entry.
Paul Stewart75e89d22011-08-01 10:00:02 -0700367 EXPECT_TRUE(routing_table_->GetDefaultRoute(kTestDeviceIndex1,
Paul Stewart7355ce12011-09-02 10:47:01 -0700368 IPAddress::kFamilyIPv4,
Paul Stewart75e89d22011-08-01 10:00:02 -0700369 &test_entry));
370 EXPECT_TRUE(entry2.Equals(test_entry));
371
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800372 // Test that a search for a non-matching family fails.
Paul Stewart75e89d22011-08-01 10:00:02 -0700373 EXPECT_FALSE(routing_table_->GetDefaultRoute(kTestDeviceIndex1,
Paul Stewart7355ce12011-09-02 10:47:01 -0700374 IPAddress::kFamilyIPv6,
Paul Stewart75e89d22011-08-01 10:00:02 -0700375 &test_entry));
376
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800377 // Remove last entry from an existing interface and test that we now fail.
Paul Stewartf748a362012-03-07 12:01:20 -0800378 SendRouteEntry(RTNLMessage::kModeDelete,
379 kTestDeviceIndex1,
380 entry2);
Paul Stewart75e89d22011-08-01 10:00:02 -0700381
382 EXPECT_FALSE(routing_table_->GetDefaultRoute(kTestDeviceIndex1,
Paul Stewart7355ce12011-09-02 10:47:01 -0700383 IPAddress::kFamilyIPv4,
Paul Stewart75e89d22011-08-01 10:00:02 -0700384 &test_entry));
385
Ben Chana6bfe872012-09-26 09:48:34 -0700386 // Add a route to a gateway address.
Paul Stewart5b7ba8c2012-04-18 09:08:00 -0700387 IPAddress gateway_address(IPAddress::kFamilyIPv4);
388 EXPECT_TRUE(gateway_address.SetAddressFromString(kTestNetAddress0));
Paul Stewart75e89d22011-08-01 10:00:02 -0700389
Paul Stewartf748a362012-03-07 12:01:20 -0800390 EXPECT_CALL(rtnl_handler_,
391 SendMessage(IsRoutingPacket(RTNLMessage::kModeAdd,
392 kTestDeviceIndex1,
393 entry0,
394 NLM_F_CREATE | NLM_F_EXCL)));
Paul Stewart75e89d22011-08-01 10:00:02 -0700395 EXPECT_TRUE(routing_table_->SetDefaultRoute(kTestDeviceIndex1,
Paul Stewart5b7ba8c2012-04-18 09:08:00 -0700396 gateway_address,
Paul Stewart75e89d22011-08-01 10:00:02 -0700397 metric));
398
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800399 // The table entry should look much like entry0, except with
400 // from_rtnl = false.
Paul Stewart75e89d22011-08-01 10:00:02 -0700401 RoutingTableEntry entry3(entry0);
402 entry3.from_rtnl = false;
403 EXPECT_TRUE(routing_table_->GetDefaultRoute(kTestDeviceIndex1,
Paul Stewart7355ce12011-09-02 10:47:01 -0700404 IPAddress::kFamilyIPv4,
Paul Stewart75e89d22011-08-01 10:00:02 -0700405 &test_entry));
406 EXPECT_TRUE(entry3.Equals(test_entry));
407
408 // Setting the same route on the interface with a different metric should
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800409 // push the route with different flags to indicate we are replacing it,
410 // then it should delete the old entry.
Paul Stewart75e89d22011-08-01 10:00:02 -0700411 RoutingTableEntry entry4(entry3);
412 entry4.metric += 10;
Paul Stewartf748a362012-03-07 12:01:20 -0800413 EXPECT_CALL(rtnl_handler_,
414 SendMessage(IsRoutingPacket(RTNLMessage::kModeAdd,
415 kTestDeviceIndex1,
416 entry4,
417 NLM_F_CREATE | NLM_F_REPLACE)));
418 EXPECT_CALL(rtnl_handler_,
419 SendMessage(IsRoutingPacket(RTNLMessage::kModeDelete,
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800420 kTestDeviceIndex1,
421 entry3,
Paul Stewartf748a362012-03-07 12:01:20 -0800422 0)));
Paul Stewart75e89d22011-08-01 10:00:02 -0700423 EXPECT_TRUE(routing_table_->SetDefaultRoute(kTestDeviceIndex1,
Paul Stewart5b7ba8c2012-04-18 09:08:00 -0700424 gateway_address,
Paul Stewart75e89d22011-08-01 10:00:02 -0700425 entry4.metric));
426
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800427 // Test that removing the table causes the route to disappear.
Paul Stewart75e89d22011-08-01 10:00:02 -0700428 routing_table_->ResetTable(kTestDeviceIndex1);
429 EXPECT_FALSE(ContainsKey(*tables, kTestDeviceIndex1));
430 EXPECT_FALSE(routing_table_->GetDefaultRoute(kTestDeviceIndex1,
Paul Stewart7355ce12011-09-02 10:47:01 -0700431 IPAddress::kFamilyIPv4,
Paul Stewart75e89d22011-08-01 10:00:02 -0700432 &test_entry));
433 EXPECT_EQ(1, GetRoutingTables()->size());
434
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800435 // When we set the metric on an existing route, a new add and delete
436 // operation should occur.
Paul Stewart75e89d22011-08-01 10:00:02 -0700437 RoutingTableEntry entry5(entry4);
438 entry5.metric += 10;
Paul Stewartf748a362012-03-07 12:01:20 -0800439 EXPECT_CALL(rtnl_handler_,
440 SendMessage(IsRoutingPacket(RTNLMessage::kModeAdd,
441 kTestDeviceIndex0,
442 entry5,
443 NLM_F_CREATE | NLM_F_REPLACE)));
444 EXPECT_CALL(rtnl_handler_,
445 SendMessage(IsRoutingPacket(RTNLMessage::kModeDelete,
446 kTestDeviceIndex0,
447 entry0,
448 0)));
Paul Stewart75e89d22011-08-01 10:00:02 -0700449 routing_table_->SetDefaultMetric(kTestDeviceIndex0, entry5.metric);
mukesh agrawald4ef6772012-02-21 16:28:04 -0800450 // Furthermore, the routing table should reflect the change in the metric
451 // for the default route for the interface.
452 RoutingTableEntry default_route;
453 EXPECT_TRUE(routing_table_->GetDefaultRoute(kTestDeviceIndex0,
454 IPAddress::kFamilyIPv4,
455 &default_route));
456 EXPECT_EQ(entry5.metric, default_route.metric);
Paul Stewart75e89d22011-08-01 10:00:02 -0700457
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800458 // Ask to flush table0. We should see a delete message sent.
Paul Stewartf748a362012-03-07 12:01:20 -0800459 EXPECT_CALL(rtnl_handler_,
460 SendMessage(IsRoutingPacket(RTNLMessage::kModeDelete,
461 kTestDeviceIndex0,
462 entry5,
463 0)));
Thieu Lefb46caf2012-03-08 11:57:15 -0800464 routing_table_->FlushRoutes(kTestDeviceIndex0);
465 EXPECT_EQ(0, (*tables)[kTestDeviceIndex0].size());
Paul Stewart75e89d22011-08-01 10:00:02 -0700466
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800467 // Test that the routing table size returns to zero.
Paul Stewartf748a362012-03-07 12:01:20 -0800468 SendRouteEntry(RTNLMessage::kModeAdd,
469 kTestDeviceIndex0,
470 entry5);
Paul Stewart75e89d22011-08-01 10:00:02 -0700471 EXPECT_EQ(1, GetRoutingTables()->size());
472 routing_table_->ResetTable(kTestDeviceIndex0);
473 EXPECT_EQ(0, GetRoutingTables()->size());
474
475 routing_table_->Stop();
Paul Stewartf748a362012-03-07 12:01:20 -0800476}
477
Paul Stewart3f68bb12012-03-15 13:33:10 -0700478TEST_F(RoutingTableTest, ConfigureRoutes) {
479 MockControl control;
480 IPConfigRefPtr ipconfig(new IPConfig(&control, kTestDeviceName0));
481 IPConfig::Properties properties;
482 properties.address_family = IPAddress::kFamilyIPv4;
483 vector<IPConfig::Route> &routes = properties.routes;
Paul Stewartc5099532013-12-12 07:53:15 -0800484 ipconfig->UpdateProperties(properties);
Paul Stewart3f68bb12012-03-15 13:33:10 -0700485
486 const int kMetric = 10;
487 EXPECT_TRUE(routing_table_->ConfigureRoutes(kTestDeviceIndex0,
488 ipconfig,
489 kMetric));
490
491 IPConfig::Route route;
492 route.host = kTestRemoteNetwork4;
493 route.netmask = kTestRemoteNetmask4;
494 route.gateway = kTestGatewayAddress4;
495 routes.push_back(route);
Paul Stewartc5099532013-12-12 07:53:15 -0800496 ipconfig->UpdateProperties(properties);
Paul Stewart3f68bb12012-03-15 13:33:10 -0700497
498 IPAddress destination_address(IPAddress::kFamilyIPv4);
499 IPAddress source_address(IPAddress::kFamilyIPv4);
500 IPAddress gateway_address(IPAddress::kFamilyIPv4);
501 ASSERT_TRUE(destination_address.SetAddressFromString(kTestRemoteNetwork4));
502 destination_address.set_prefix(kTestRemotePrefix4);
503 ASSERT_TRUE(gateway_address.SetAddressFromString(kTestGatewayAddress4));
504
505 RoutingTableEntry entry(destination_address,
506 source_address,
507 gateway_address,
508 kMetric,
509 RT_SCOPE_UNIVERSE,
510 false);
511
512 EXPECT_CALL(rtnl_handler_,
513 SendMessage(IsRoutingPacket(RTNLMessage::kModeAdd,
514 kTestDeviceIndex0,
515 entry,
516 NLM_F_CREATE | NLM_F_EXCL)));
517 EXPECT_TRUE(routing_table_->ConfigureRoutes(kTestDeviceIndex0,
518 ipconfig,
519 kMetric));
520
521 routes.clear();
522 route.gateway = "xxx"; // Invalid gateway entry -- should be skipped
523 routes.push_back(route);
524 route.host = "xxx"; // Invalid host entry -- should be skipped
525 route.gateway = kTestGatewayAddress4;
526 routes.push_back(route);
527 route.host = kTestRemoteNetwork4;
528 routes.push_back(route);
Paul Stewartc5099532013-12-12 07:53:15 -0800529 ipconfig->UpdateProperties(properties);
Paul Stewart3f68bb12012-03-15 13:33:10 -0700530
531 EXPECT_CALL(rtnl_handler_,
532 SendMessage(IsRoutingPacket(RTNLMessage::kModeAdd,
533 kTestDeviceIndex0,
534 entry,
535 NLM_F_CREATE | NLM_F_EXCL)))
536 .Times(1);
537 EXPECT_FALSE(routing_table_->ConfigureRoutes(kTestDeviceIndex0,
538 ipconfig,
539 kMetric));
540}
541
Paul Stewartf748a362012-03-07 12:01:20 -0800542MATCHER_P2(IsRoutingQuery, destination, index, "") {
543 const RTNLMessage::RouteStatus &status = arg->route_status();
544
Ben Chan7fab8972014-08-10 17:14:46 -0700545 uint32_t oif;
Paul Stewartf748a362012-03-07 12:01:20 -0800546
547 return
548 arg->type() == RTNLMessage::kTypeRoute &&
549 arg->family() == destination.family() &&
550 arg->flags() == NLM_F_REQUEST &&
551 status.table == 0 &&
552 status.protocol == 0 &&
553 status.scope == 0 &&
554 status.type == 0 &&
555 arg->HasAttribute(RTA_DST) &&
556 IPAddress(arg->family(),
557 arg->GetAttribute(RTA_DST),
558 status.dst_prefix).Equals(destination) &&
559 !arg->HasAttribute(RTA_SRC) &&
560 !arg->HasAttribute(RTA_GATEWAY) &&
561 arg->GetAttribute(RTA_OIF).ConvertToCPUUInt32(&oif) &&
562 oif == index &&
563 !arg->HasAttribute(RTA_PRIORITY);
564
565 return false;
566}
567
568TEST_F(RoutingTableTest, RequestHostRoute) {
569 IPAddress destination_address(IPAddress::kFamilyIPv4);
570 destination_address.SetAddressFromString(kTestRemoteAddress4);
571 destination_address.set_prefix(24);
572
573 EXPECT_CALL(rtnl_handler_,
574 SendMessage(IsRoutingQuery(destination_address,
575 kTestDeviceIndex0)))
576 .WillOnce(Invoke(this, &RoutingTableTest::SetSequenceForMessage));
Darin Petkovabf6d282012-05-08 15:49:05 +0200577 EXPECT_TRUE(
578 routing_table_->RequestRouteToHost(destination_address,
579 kTestDeviceIndex0,
580 kTestRouteTag,
581 RoutingTable::Query::Callback()));
Paul Stewartf748a362012-03-07 12:01:20 -0800582
583 IPAddress gateway_address(IPAddress::kFamilyIPv4);
584 gateway_address.SetAddressFromString(kTestGatewayAddress4);
585
586 IPAddress local_address(IPAddress::kFamilyIPv4);
587 local_address.SetAddressFromString(kTestDeviceNetAddress4);
588
589 const int kMetric = 10;
590 RoutingTableEntry entry(destination_address,
591 local_address,
592 gateway_address,
593 kMetric,
594 RT_SCOPE_UNIVERSE,
595 true);
596
597 EXPECT_CALL(rtnl_handler_,
598 SendMessage(IsRoutingPacket(RTNLMessage::kModeAdd,
599 kTestDeviceIndex0,
600 entry,
601 NLM_F_CREATE | NLM_F_EXCL)));
602 SendRouteEntryWithSeqAndProto(RTNLMessage::kModeAdd,
603 kTestDeviceIndex0,
604 entry,
605 kTestRequestSeq,
606 RTPROT_UNSPEC);
Paul Stewarte93b0382012-04-24 13:11:28 -0700607
Alex Vakulenko8a532292014-06-16 17:18:44 -0700608 std::unordered_map<int, vector<RoutingTableEntry>> *tables =
609 GetRoutingTables();
Paul Stewarte93b0382012-04-24 13:11:28 -0700610
611 // We should have a single table, which should in turn have a single entry.
612 EXPECT_EQ(1, tables->size());
613 EXPECT_TRUE(ContainsKey(*tables, kTestDeviceIndex0));
614 EXPECT_EQ(1, (*tables)[kTestDeviceIndex0].size());
615
616 // This entry's tag should match the tag we requested.
617 EXPECT_EQ(kTestRouteTag, (*tables)[kTestDeviceIndex0][0].tag);
618
Darin Petkovabf6d282012-05-08 15:49:05 +0200619 EXPECT_TRUE(GetQueries()->empty());
620
Paul Stewarte93b0382012-04-24 13:11:28 -0700621 // Ask to flush routes with our tag. We should see a delete message sent.
622 EXPECT_CALL(rtnl_handler_,
623 SendMessage(IsRoutingPacket(RTNLMessage::kModeDelete,
624 kTestDeviceIndex0,
625 entry,
626 0)));
627
628 routing_table_->FlushRoutesWithTag(kTestRouteTag);
629
630 // After flushing routes for this tag, we should end up with no routes.
631 EXPECT_EQ(0, (*tables)[kTestDeviceIndex0].size());
Paul Stewartf748a362012-03-07 12:01:20 -0800632}
633
Paul Stewartbbed76d2012-04-27 20:02:13 -0700634TEST_F(RoutingTableTest, RequestHostRouteWithoutGateway) {
635 IPAddress destination_address(IPAddress::kFamilyIPv4);
636 destination_address.SetAddressFromString(kTestRemoteAddress4);
637 destination_address.set_prefix(24);
638
639 EXPECT_CALL(rtnl_handler_,
640 SendMessage(IsRoutingQuery(destination_address,
641 kTestDeviceIndex0)))
642 .WillOnce(Invoke(this, &RoutingTableTest::SetSequenceForMessage));
Darin Petkovabf6d282012-05-08 15:49:05 +0200643 EXPECT_TRUE(
644 routing_table_->RequestRouteToHost(destination_address,
645 kTestDeviceIndex0,
646 kTestRouteTag,
647 RoutingTable::Query::Callback()));
Paul Stewartbbed76d2012-04-27 20:02:13 -0700648
649 // Don't specify a gateway address.
650 IPAddress gateway_address(IPAddress::kFamilyIPv4);
651
652 IPAddress local_address(IPAddress::kFamilyIPv4);
653 local_address.SetAddressFromString(kTestDeviceNetAddress4);
654
655 const int kMetric = 10;
656 RoutingTableEntry entry(destination_address,
657 local_address,
658 gateway_address,
659 kMetric,
660 RT_SCOPE_UNIVERSE,
661 true);
662
663 // Ensure that without a gateway entry, we don't create a route.
664 EXPECT_CALL(rtnl_handler_, SendMessage(_)).Times(0);
665 SendRouteEntryWithSeqAndProto(RTNLMessage::kModeAdd,
666 kTestDeviceIndex0,
667 entry,
668 kTestRequestSeq,
669 RTPROT_UNSPEC);
Darin Petkovabf6d282012-05-08 15:49:05 +0200670 EXPECT_TRUE(GetQueries()->empty());
Paul Stewartbbed76d2012-04-27 20:02:13 -0700671}
672
Paul Stewartf748a362012-03-07 12:01:20 -0800673TEST_F(RoutingTableTest, RequestHostRouteBadSequence) {
674 IPAddress destination_address(IPAddress::kFamilyIPv4);
675 destination_address.SetAddressFromString(kTestRemoteAddress4);
Darin Petkovabf6d282012-05-08 15:49:05 +0200676 QueryCallbackTarget target;
Darin Petkov13e6d552012-05-09 14:22:23 +0200677 EXPECT_CALL(target, MockedTarget(_, _)).Times(0);
Paul Stewartf748a362012-03-07 12:01:20 -0800678 EXPECT_CALL(rtnl_handler_, SendMessage(_))
679 .WillOnce(Invoke(this, &RoutingTableTest::SetSequenceForMessage));
Darin Petkovabf6d282012-05-08 15:49:05 +0200680 EXPECT_TRUE(
681 routing_table_->RequestRouteToHost(destination_address,
682 kTestDeviceIndex0,
683 kTestRouteTag,
Darin Petkov13e6d552012-05-09 14:22:23 +0200684 target.mocked_callback()));
Paul Stewarte93b0382012-04-24 13:11:28 -0700685 EXPECT_FALSE(GetQueries()->empty());
Paul Stewartf748a362012-03-07 12:01:20 -0800686
687 RoutingTableEntry entry(destination_address,
688 destination_address,
689 destination_address,
690 0,
691 RT_SCOPE_UNIVERSE,
692 true);
693
694 // Try a sequence arriving before the one RoutingTable is looking for.
695 // This should be a no-op.
696 SendRouteEntryWithSeqAndProto(RTNLMessage::kModeAdd,
697 kTestDeviceIndex0,
698 entry,
Darin Petkovabf6d282012-05-08 15:49:05 +0200699 kTestRequestSeq - 1,
Paul Stewartf748a362012-03-07 12:01:20 -0800700 RTPROT_UNSPEC);
Paul Stewarte93b0382012-04-24 13:11:28 -0700701 EXPECT_FALSE(GetQueries()->empty());
Paul Stewartf748a362012-03-07 12:01:20 -0800702
703 // Try a sequence arriving after the one RoutingTable is looking for.
704 // This should cause the request to be purged.
705 SendRouteEntryWithSeqAndProto(RTNLMessage::kModeAdd,
706 kTestDeviceIndex0,
707 entry,
Darin Petkovabf6d282012-05-08 15:49:05 +0200708 kTestRequestSeq + 1,
Paul Stewartf748a362012-03-07 12:01:20 -0800709 RTPROT_UNSPEC);
Paul Stewarte93b0382012-04-24 13:11:28 -0700710 EXPECT_TRUE(GetQueries()->empty());
Paul Stewart75e89d22011-08-01 10:00:02 -0700711}
712
Darin Petkovabf6d282012-05-08 15:49:05 +0200713TEST_F(RoutingTableTest, RequestHostRouteWithCallback) {
714 IPAddress destination_address(IPAddress::kFamilyIPv4);
715
716 EXPECT_CALL(rtnl_handler_, SendMessage(_))
717 .WillOnce(Invoke(this, &RoutingTableTest::SetSequenceForMessage));
718 QueryCallbackTarget target;
719 EXPECT_TRUE(
720 routing_table_->RequestRouteToHost(
Darin Petkov13e6d552012-05-09 14:22:23 +0200721 destination_address, -1, kTestRouteTag, target.mocked_callback()));
Darin Petkovabf6d282012-05-08 15:49:05 +0200722
723 IPAddress gateway_address(IPAddress::kFamilyIPv4);
724 gateway_address.SetAddressFromString(kTestGatewayAddress4);
Darin Petkovabf6d282012-05-08 15:49:05 +0200725
726 const int kMetric = 10;
727 RoutingTableEntry entry(destination_address,
Darin Petkov13e6d552012-05-09 14:22:23 +0200728 IPAddress(IPAddress::kFamilyIPv4),
Darin Petkovabf6d282012-05-08 15:49:05 +0200729 gateway_address,
730 kMetric,
731 RT_SCOPE_UNIVERSE,
732 true);
733
734 EXPECT_CALL(rtnl_handler_, SendMessage(_));
735 EXPECT_CALL(target,
Darin Petkov13e6d552012-05-09 14:22:23 +0200736 MockedTarget(kTestDeviceIndex0,
737 Field(&RoutingTableEntry::tag, kTestRouteTag)));
Darin Petkovabf6d282012-05-08 15:49:05 +0200738 SendRouteEntryWithSeqAndProto(RTNLMessage::kModeAdd,
739 kTestDeviceIndex0,
740 entry,
741 kTestRequestSeq,
742 RTPROT_UNSPEC);
743}
744
745TEST_F(RoutingTableTest, RequestHostRouteWithoutGatewayWithCallback) {
746 IPAddress destination_address(IPAddress::kFamilyIPv4);
747
748 EXPECT_CALL(rtnl_handler_, SendMessage(_))
749 .WillOnce(Invoke(this, &RoutingTableTest::SetSequenceForMessage));
750 QueryCallbackTarget target;
751 EXPECT_TRUE(
752 routing_table_->RequestRouteToHost(
Darin Petkov13e6d552012-05-09 14:22:23 +0200753 destination_address, -1, kTestRouteTag, target.mocked_callback()));
Darin Petkovabf6d282012-05-08 15:49:05 +0200754
755 const int kMetric = 10;
756 RoutingTableEntry entry(destination_address,
Darin Petkov13e6d552012-05-09 14:22:23 +0200757 IPAddress(IPAddress::kFamilyIPv4),
758 IPAddress(IPAddress::kFamilyIPv4),
Darin Petkovabf6d282012-05-08 15:49:05 +0200759 kMetric,
760 RT_SCOPE_UNIVERSE,
761 true);
762
763 EXPECT_CALL(target,
Darin Petkov13e6d552012-05-09 14:22:23 +0200764 MockedTarget(kTestDeviceIndex0,
765 Field(&RoutingTableEntry::tag, kTestRouteTag)));
Darin Petkovabf6d282012-05-08 15:49:05 +0200766 SendRouteEntryWithSeqAndProto(RTNLMessage::kModeAdd,
767 kTestDeviceIndex0,
768 entry,
769 kTestRequestSeq,
770 RTPROT_UNSPEC);
771}
772
773TEST_F(RoutingTableTest, CancelQueryCallback) {
774 IPAddress destination_address(IPAddress::kFamilyIPv4);
775 destination_address.SetAddressFromString(kTestRemoteAddress4);
Darin Petkov13e6d552012-05-09 14:22:23 +0200776 scoped_ptr<QueryCallbackTarget> target(new QueryCallbackTarget());
777 EXPECT_CALL(rtnl_handler_, SendMessage(_))
778 .WillOnce(Invoke(this, &RoutingTableTest::SetSequenceForMessage));
Darin Petkovabf6d282012-05-08 15:49:05 +0200779 EXPECT_TRUE(
780 routing_table_->RequestRouteToHost(destination_address,
781 kTestDeviceIndex0,
782 kTestRouteTag,
Darin Petkov13e6d552012-05-09 14:22:23 +0200783 target->unreached_callback()));
784 ASSERT_EQ(1, GetQueries()->size());
785 // Cancels the callback by destroying the owner object.
786 target.reset();
787 const int kMetric = 10;
788 RoutingTableEntry entry(IPAddress(IPAddress::kFamilyIPv4),
789 IPAddress(IPAddress::kFamilyIPv4),
790 IPAddress(IPAddress::kFamilyIPv4),
791 kMetric,
792 RT_SCOPE_UNIVERSE,
793 true);
794 SendRouteEntryWithSeqAndProto(RTNLMessage::kModeAdd,
795 kTestDeviceIndex0,
796 entry,
797 kTestRequestSeq,
798 RTPROT_UNSPEC);
Darin Petkovabf6d282012-05-08 15:49:05 +0200799}
800
Ben Chana0163122012-09-25 15:10:52 -0700801TEST_F(RoutingTableTest, CreateBlackholeRoute) {
Ben Chan7fab8972014-08-10 17:14:46 -0700802 const uint32_t kMetric = 2;
Ben Chana0163122012-09-25 15:10:52 -0700803 EXPECT_CALL(rtnl_handler_,
804 SendMessage(IsBlackholeRoutingPacket(kTestDeviceIndex0,
805 IPAddress::kFamilyIPv6,
806 kMetric)))
807 .Times(1);
808 EXPECT_TRUE(routing_table_->CreateBlackholeRoute(kTestDeviceIndex0,
809 IPAddress::kFamilyIPv6,
810 kMetric));
811}
812
Paul Stewart4a6748d2012-07-17 14:31:36 -0700813TEST_F(RoutingTableTest, CreateLinkRoute) {
814 IPAddress local_address(IPAddress::kFamilyIPv4);
815 ASSERT_TRUE(local_address.SetAddressFromString(kTestNetAddress0));
816 local_address.set_prefix(kTestRemotePrefix4);
817 IPAddress remote_address(IPAddress::kFamilyIPv4);
818 ASSERT_TRUE(remote_address.SetAddressFromString(kTestNetAddress1));
819 IPAddress default_address(IPAddress::kFamilyIPv4);
820 IPAddress remote_address_with_prefix(remote_address);
821 remote_address_with_prefix.set_prefix(
822 IPAddress::GetMaxPrefixLength(remote_address_with_prefix.family()));
823 RoutingTableEntry entry(remote_address_with_prefix,
824 local_address,
825 default_address,
826 0,
827 RT_SCOPE_LINK,
828 false);
829 EXPECT_CALL(rtnl_handler_,
830 SendMessage(IsRoutingPacket(RTNLMessage::kModeAdd,
831 kTestDeviceIndex0,
832 entry,
833 NLM_F_CREATE | NLM_F_EXCL)))
834 .Times(1);
835 EXPECT_TRUE(routing_table_->CreateLinkRoute(kTestDeviceIndex0,
836 local_address,
837 remote_address));
838
839 ASSERT_TRUE(remote_address.SetAddressFromString(kTestRemoteAddress4));
840 EXPECT_FALSE(routing_table_->CreateLinkRoute(kTestDeviceIndex0,
841 local_address,
842 remote_address));
843}
844
Paul Stewart75e89d22011-08-01 10:00:02 -0700845} // namespace shill