blob: e1104ce0371a798333a8a9a459bd5a727e4c6b07 [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
5#include <sys/socket.h>
6#include <linux/rtnetlink.h>
7
Paul Stewart3f68bb12012-03-15 13:33:10 -07008#include <vector>
9
Darin Petkov13e6d552012-05-09 14:22:23 +020010#include <base/memory/weak_ptr.h>
Eric Shienbrood3e20a232012-02-16 11:35:56 -050011#include <base/stl_util.h>
Paul Stewart75e89d22011-08-01 10:00:02 -070012#include <gtest/gtest.h>
13#include <gmock/gmock.h>
14
15#include "shill/byte_string.h"
Christopher Wileyb691efd2012-08-09 13:51:51 -070016#include "shill/logging.h"
Paul Stewart75e89d22011-08-01 10:00:02 -070017#include "shill/mock_control.h"
Paul Stewartf748a362012-03-07 12:01:20 -080018#include "shill/mock_rtnl_handler.h"
Paul Stewart75e89d22011-08-01 10:00:02 -070019#include "shill/routing_table.h"
20#include "shill/routing_table_entry.h"
21#include "shill/rtnl_handler.h"
22#include "shill/rtnl_message.h"
23
Darin Petkovabf6d282012-05-08 15:49:05 +020024using base::Bind;
Eric Shienbrood3e20a232012-02-16 11:35:56 -050025using base::Callback;
Darin Petkovabf6d282012-05-08 15:49:05 +020026using base::Unretained;
Paul Stewarte93b0382012-04-24 13:11:28 -070027using base::hash_map;
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*/,
Eric Shienbrood3e20a232012-02-16 11:35:56 -050043 const Callback<void(InputData*)> &/*callback*/) {
Paul Stewart75e89d22011-08-01 10:00:02 -070044 return NULL;
45 }
46};
47
48class RoutingTableTest : public Test {
49 public:
Paul Stewarte93b0382012-04-24 13:11:28 -070050 RoutingTableTest() : routing_table_(new RoutingTable()) {}
Paul Stewart75e89d22011-08-01 10:00:02 -070051
Paul Stewartf748a362012-03-07 12:01:20 -080052 virtual void SetUp() {
53 routing_table_->rtnl_handler_ = &rtnl_handler_;
54 ON_CALL(rtnl_handler_, SendMessage(_)).WillByDefault(Return(true));
Paul Stewart75e89d22011-08-01 10:00:02 -070055 }
56
Paul Stewart65c40f52011-08-08 07:27:46 -070057 virtual void TearDown() {
58 RTNLHandler::GetInstance()->Stop();
59 }
60
Paul Stewarte93b0382012-04-24 13:11:28 -070061 hash_map<int, vector<RoutingTableEntry> > *GetRoutingTables() {
Paul Stewartf748a362012-03-07 12:01:20 -080062 return &routing_table_->tables_;
63 }
64
Darin Petkovabf6d282012-05-08 15:49:05 +020065 deque<RoutingTable::Query> *GetQueries() {
Paul Stewarte93b0382012-04-24 13:11:28 -070066 return &routing_table_->route_queries_;
Paul Stewartf748a362012-03-07 12:01:20 -080067 }
68
69 void SendRouteEntry(RTNLMessage::Mode mode,
70 uint32 interface_index,
71 const RoutingTableEntry &entry);
72
73 void SendRouteEntryWithSeqAndProto(RTNLMessage::Mode mode,
74 uint32 interface_index,
75 const RoutingTableEntry &entry,
76 uint32 seq,
77 unsigned char proto);
78
79 void SendRouteMessage(const RTNLMessage &msg);
80
81 bool SetSequenceForMessage(RTNLMessage *message) {
82 message->set_seq(RoutingTableTest::kTestRequestSeq);
83 return true;
84 }
85
Paul Stewart75e89d22011-08-01 10:00:02 -070086 protected:
Paul Stewart75e89d22011-08-01 10:00:02 -070087 static const uint32 kTestDeviceIndex0;
88 static const uint32 kTestDeviceIndex1;
89 static const char kTestDeviceName0[];
Thieu Lecaef8932012-02-28 16:06:59 -080090 static const char kTestDeviceNetAddress4[];
91 static const char kTestForeignNetAddress4[];
92 static const char kTestForeignNetGateway4[];
93 static const char kTestForeignNetAddress6[];
94 static const char kTestForeignNetGateway6[];
Paul Stewartf748a362012-03-07 12:01:20 -080095 static const char kTestGatewayAddress4[];
Paul Stewart75e89d22011-08-01 10:00:02 -070096 static const char kTestNetAddress0[];
97 static const char kTestNetAddress1[];
Paul Stewartf748a362012-03-07 12:01:20 -080098 static const char kTestRemoteAddress4[];
Paul Stewart3f68bb12012-03-15 13:33:10 -070099 static const char kTestRemoteNetmask4[];
100 static const char kTestRemoteNetwork4[];
101 static const int kTestRemotePrefix4;
Paul Stewartf748a362012-03-07 12:01:20 -0800102 static const uint32 kTestRequestSeq;
Paul Stewarte93b0382012-04-24 13:11:28 -0700103 static const int kTestRouteTag;
Paul Stewart75e89d22011-08-01 10:00:02 -0700104
Darin Petkovabf6d282012-05-08 15:49:05 +0200105 class QueryCallbackTarget {
106 public:
107 QueryCallbackTarget()
Darin Petkov13e6d552012-05-09 14:22:23 +0200108 : weak_ptr_factory_(this),
109 mocked_callback_(
110 Bind(&QueryCallbackTarget::MockedTarget, Unretained(this))),
111 unreached_callback_(Bind(&QueryCallbackTarget::UnreachedTarget,
112 weak_ptr_factory_.GetWeakPtr())) {}
Darin Petkovabf6d282012-05-08 15:49:05 +0200113
Darin Petkov13e6d552012-05-09 14:22:23 +0200114 MOCK_METHOD2(MockedTarget,
Darin Petkovabf6d282012-05-08 15:49:05 +0200115 void(int interface_index, const RoutingTableEntry &entry));
Darin Petkov13e6d552012-05-09 14:22:23 +0200116
117 void UnreachedTarget(int interface_index, const RoutingTableEntry &entry) {
118 CHECK(false);
119 }
120
121 const RoutingTable::Query::Callback &mocked_callback() const {
122 return mocked_callback_;
123 }
124
125 const RoutingTable::Query::Callback &unreached_callback() const {
126 return unreached_callback_;
127 }
Darin Petkovabf6d282012-05-08 15:49:05 +0200128
129 private:
Darin Petkov13e6d552012-05-09 14:22:23 +0200130 base::WeakPtrFactory<QueryCallbackTarget> weak_ptr_factory_;
131 const RoutingTable::Query::Callback mocked_callback_;
132 const RoutingTable::Query::Callback unreached_callback_;
Darin Petkovabf6d282012-05-08 15:49:05 +0200133 };
134
Paul Stewart75e89d22011-08-01 10:00:02 -0700135 RoutingTable *routing_table_;
136 TestEventDispatcher dispatcher_;
Paul Stewartf748a362012-03-07 12:01:20 -0800137 StrictMock<MockRTNLHandler> rtnl_handler_;
Paul Stewart75e89d22011-08-01 10:00:02 -0700138};
139
Paul Stewart75e89d22011-08-01 10:00:02 -0700140const uint32 RoutingTableTest::kTestDeviceIndex0 = 12345;
141const uint32 RoutingTableTest::kTestDeviceIndex1 = 67890;
142const char RoutingTableTest::kTestDeviceName0[] = "test-device0";
Thieu Lecaef8932012-02-28 16:06:59 -0800143const char RoutingTableTest::kTestDeviceNetAddress4[] = "192.168.2.0/24";
144const char RoutingTableTest::kTestForeignNetAddress4[] = "192.168.2.2";
145const char RoutingTableTest::kTestForeignNetGateway4[] = "192.168.2.1";
146const char RoutingTableTest::kTestForeignNetAddress6[] = "2000::/3";
147const char RoutingTableTest::kTestForeignNetGateway6[] = "fe80:::::1";
Paul Stewartf748a362012-03-07 12:01:20 -0800148const char RoutingTableTest::kTestGatewayAddress4[] = "192.168.2.254";
Paul Stewart75e89d22011-08-01 10:00:02 -0700149const char RoutingTableTest::kTestNetAddress0[] = "192.168.1.1";
150const char RoutingTableTest::kTestNetAddress1[] = "192.168.1.2";
Paul Stewartf748a362012-03-07 12:01:20 -0800151const char RoutingTableTest::kTestRemoteAddress4[] = "192.168.2.254";
Paul Stewart3f68bb12012-03-15 13:33:10 -0700152const char RoutingTableTest::kTestRemoteNetmask4[] = "255.255.255.0";
153const char RoutingTableTest::kTestRemoteNetwork4[] = "192.168.100.0";
154const int RoutingTableTest::kTestRemotePrefix4 = 24;
Paul Stewartf748a362012-03-07 12:01:20 -0800155const uint32 RoutingTableTest::kTestRequestSeq = 456;
Paul Stewarte93b0382012-04-24 13:11:28 -0700156const int RoutingTableTest::kTestRouteTag = 789;
Paul Stewart75e89d22011-08-01 10:00:02 -0700157
Darin Petkovabf6d282012-05-08 15:49:05 +0200158namespace {
159
Ben Chana0163122012-09-25 15:10:52 -0700160MATCHER_P3(IsBlackholeRoutingPacket, index, family, metric, "") {
161 const RTNLMessage::RouteStatus &status = arg->route_status();
162
163 uint32 oif;
164 uint32 priority;
165
166 return
167 arg->type() == RTNLMessage::kTypeRoute &&
168 arg->family() == family &&
169 arg->flags() == (NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL) &&
170 status.table == RT_TABLE_MAIN &&
171 status.protocol == RTPROT_BOOT &&
172 status.scope == RT_SCOPE_UNIVERSE &&
173 status.type == RTN_BLACKHOLE &&
174 !arg->HasAttribute(RTA_DST) &&
175 !arg->HasAttribute(RTA_SRC) &&
176 !arg->HasAttribute(RTA_GATEWAY) &&
177 arg->GetAttribute(RTA_OIF).ConvertToCPUUInt32(&oif) &&
178 oif == index &&
179 arg->GetAttribute(RTA_PRIORITY).ConvertToCPUUInt32(&priority) &&
180 priority == metric;
181}
182
Paul Stewart75e89d22011-08-01 10:00:02 -0700183MATCHER_P4(IsRoutingPacket, mode, index, entry, flags, "") {
Paul Stewartf748a362012-03-07 12:01:20 -0800184 const RTNLMessage::RouteStatus &status = arg->route_status();
Paul Stewart75e89d22011-08-01 10:00:02 -0700185
186 uint32 oif;
187 uint32 priority;
188
189 return
Paul Stewartf748a362012-03-07 12:01:20 -0800190 arg->type() == RTNLMessage::kTypeRoute &&
191 arg->family() == entry.gateway.family() &&
192 arg->flags() == (NLM_F_REQUEST | flags) &&
193 status.table == RT_TABLE_MAIN &&
194 status.protocol == RTPROT_BOOT &&
195 status.scope == entry.scope &&
196 status.type == RTN_UNICAST &&
197 arg->HasAttribute(RTA_DST) &&
198 IPAddress(arg->family(),
199 arg->GetAttribute(RTA_DST),
200 status.dst_prefix).Equals(entry.dst) &&
Paul Stewart4a6748d2012-07-17 14:31:36 -0700201 ((!arg->HasAttribute(RTA_SRC) && entry.src.IsDefault()) ||
202 (arg->HasAttribute(RTA_SRC) && IPAddress(arg->family(),
203 arg->GetAttribute(RTA_SRC),
204 status.src_prefix).Equals(entry.src))) &&
205 ((!arg->HasAttribute(RTA_GATEWAY) && entry.gateway.IsDefault()) ||
206 (arg->HasAttribute(RTA_GATEWAY) && IPAddress(arg->family(),
207 arg->GetAttribute(RTA_GATEWAY)).Equals(entry.gateway))) &&
Paul Stewartf748a362012-03-07 12:01:20 -0800208 arg->GetAttribute(RTA_OIF).ConvertToCPUUInt32(&oif) &&
209 oif == index &&
210 arg->GetAttribute(RTA_PRIORITY).ConvertToCPUUInt32(&priority) &&
211 priority == entry.metric;
Paul Stewart75e89d22011-08-01 10:00:02 -0700212}
213
Darin Petkovabf6d282012-05-08 15:49:05 +0200214} // namespace
215
Paul Stewartf748a362012-03-07 12:01:20 -0800216void RoutingTableTest::SendRouteEntry(RTNLMessage::Mode mode,
217 uint32 interface_index,
218 const RoutingTableEntry &entry) {
219 SendRouteEntryWithSeqAndProto(mode, interface_index, entry, 0, RTPROT_BOOT);
220}
221
222void RoutingTableTest::SendRouteEntryWithSeqAndProto(
223 RTNLMessage::Mode mode,
224 uint32 interface_index,
225 const RoutingTableEntry &entry,
226 uint32 seq,
227 unsigned char proto) {
Paul Stewart75e89d22011-08-01 10:00:02 -0700228 RTNLMessage msg(
Paul Stewart9a908082011-08-31 12:18:48 -0700229 RTNLMessage::kTypeRoute,
Paul Stewart75e89d22011-08-01 10:00:02 -0700230 mode,
231 0,
Paul Stewartf748a362012-03-07 12:01:20 -0800232 seq,
Paul Stewart75e89d22011-08-01 10:00:02 -0700233 0,
234 0,
235 entry.dst.family());
236
237 msg.set_route_status(RTNLMessage::RouteStatus(
Paul Stewart9e3fcd72011-08-26 15:46:16 -0700238 entry.dst.prefix(),
239 entry.src.prefix(),
Paul Stewart75e89d22011-08-01 10:00:02 -0700240 RT_TABLE_MAIN,
Paul Stewartf748a362012-03-07 12:01:20 -0800241 proto,
Paul Stewart75e89d22011-08-01 10:00:02 -0700242 entry.scope,
243 RTN_UNICAST,
244 0));
245
246 msg.SetAttribute(RTA_DST, entry.dst.address());
247 if (!entry.src.IsDefault()) {
248 msg.SetAttribute(RTA_SRC, entry.src.address());
249 }
250 if (!entry.gateway.IsDefault()) {
251 msg.SetAttribute(RTA_GATEWAY, entry.gateway.address());
252 }
253 msg.SetAttribute(RTA_PRIORITY, ByteString::CreateFromCPUUInt32(entry.metric));
254 msg.SetAttribute(RTA_OIF, ByteString::CreateFromCPUUInt32(interface_index));
255
Paul Stewartf748a362012-03-07 12:01:20 -0800256 routing_table_->RouteMsgHandler(msg);
Paul Stewart75e89d22011-08-01 10:00:02 -0700257}
258
Paul Stewartf748a362012-03-07 12:01:20 -0800259void RoutingTableTest::SendRouteMessage(const RTNLMessage &msg) {
260 routing_table_->RouteMsgHandler(msg);
Paul Stewart75e89d22011-08-01 10:00:02 -0700261}
262
Paul Stewartf748a362012-03-07 12:01:20 -0800263TEST_F(RoutingTableTest, Start) {
264 EXPECT_CALL(rtnl_handler_, RequestDump(RTNLHandler::kRequestRoute));
265 routing_table_->Start();
Paul Stewart75e89d22011-08-01 10:00:02 -0700266}
267
268TEST_F(RoutingTableTest, RouteAddDelete) {
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800269 // Expect the tables to be empty by default.
Paul Stewart75e89d22011-08-01 10:00:02 -0700270 EXPECT_EQ(0, GetRoutingTables()->size());
271
Paul Stewart7355ce12011-09-02 10:47:01 -0700272 IPAddress default_address(IPAddress::kFamilyIPv4);
Paul Stewart75e89d22011-08-01 10:00:02 -0700273 default_address.SetAddressToDefault();
274
Paul Stewart7355ce12011-09-02 10:47:01 -0700275 IPAddress gateway_address0(IPAddress::kFamilyIPv4);
Paul Stewart75e89d22011-08-01 10:00:02 -0700276 gateway_address0.SetAddressFromString(kTestNetAddress0);
277
278 int metric = 10;
279
280 RoutingTableEntry entry0(default_address,
Paul Stewart75e89d22011-08-01 10:00:02 -0700281 default_address,
Paul Stewart75e89d22011-08-01 10:00:02 -0700282 gateway_address0,
283 metric,
284 RT_SCOPE_UNIVERSE,
285 true);
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800286 // Add a single entry.
Paul Stewartf748a362012-03-07 12:01:20 -0800287 SendRouteEntry(RTNLMessage::kModeAdd,
288 kTestDeviceIndex0,
289 entry0);
Paul Stewart75e89d22011-08-01 10:00:02 -0700290
Paul Stewarte93b0382012-04-24 13:11:28 -0700291 hash_map<int, vector<RoutingTableEntry> > *tables =
Paul Stewart75e89d22011-08-01 10:00:02 -0700292 GetRoutingTables();
293
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800294 // We should have a single table, which should in turn have a single entry.
Paul Stewart75e89d22011-08-01 10:00:02 -0700295 EXPECT_EQ(1, tables->size());
296 EXPECT_TRUE(ContainsKey(*tables, kTestDeviceIndex0));
297 EXPECT_EQ(1, (*tables)[kTestDeviceIndex0].size());
298
299 RoutingTableEntry test_entry = (*tables)[kTestDeviceIndex0][0];
300 EXPECT_TRUE(entry0.Equals(test_entry));
301
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800302 // Add a second entry for a different interface.
Paul Stewartf748a362012-03-07 12:01:20 -0800303 SendRouteEntry(RTNLMessage::kModeAdd,
304 kTestDeviceIndex1,
305 entry0);
Paul Stewart75e89d22011-08-01 10:00:02 -0700306
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800307 // We should have two tables, which should have a single entry each.
Paul Stewart75e89d22011-08-01 10:00:02 -0700308 EXPECT_EQ(2, tables->size());
309 EXPECT_TRUE(ContainsKey(*tables, kTestDeviceIndex1));
310 EXPECT_EQ(1, (*tables)[kTestDeviceIndex0].size());
311 EXPECT_EQ(1, (*tables)[kTestDeviceIndex1].size());
312
313 test_entry = (*tables)[kTestDeviceIndex1][0];
314 EXPECT_TRUE(entry0.Equals(test_entry));
315
Paul Stewart7355ce12011-09-02 10:47:01 -0700316 IPAddress gateway_address1(IPAddress::kFamilyIPv4);
Paul Stewart75e89d22011-08-01 10:00:02 -0700317 gateway_address1.SetAddressFromString(kTestNetAddress1);
318
319 RoutingTableEntry entry1(default_address,
Paul Stewart75e89d22011-08-01 10:00:02 -0700320 default_address,
Paul Stewart75e89d22011-08-01 10:00:02 -0700321 gateway_address1,
322 metric,
323 RT_SCOPE_UNIVERSE,
324 true);
325
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800326 // Add a second gateway route to the second interface.
Paul Stewartf748a362012-03-07 12:01:20 -0800327 SendRouteEntry(RTNLMessage::kModeAdd,
328 kTestDeviceIndex1,
329 entry1);
Paul Stewart75e89d22011-08-01 10:00:02 -0700330
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800331 // We should have two tables, one of which has a single entry, the other has
332 // two.
Paul Stewart75e89d22011-08-01 10:00:02 -0700333 EXPECT_EQ(2, tables->size());
334 EXPECT_EQ(1, (*tables)[kTestDeviceIndex0].size());
335 EXPECT_EQ(2, (*tables)[kTestDeviceIndex1].size());
336
337 test_entry = (*tables)[kTestDeviceIndex1][1];
338 EXPECT_TRUE(entry1.Equals(test_entry));
339
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800340 // Remove the first gateway route from the second interface.
Paul Stewartf748a362012-03-07 12:01:20 -0800341 SendRouteEntry(RTNLMessage::kModeDelete,
342 kTestDeviceIndex1,
343 entry0);
Paul Stewart75e89d22011-08-01 10:00:02 -0700344
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800345 // We should be back to having one route per table.
Paul Stewart75e89d22011-08-01 10:00:02 -0700346 EXPECT_EQ(2, tables->size());
347 EXPECT_EQ(1, (*tables)[kTestDeviceIndex0].size());
348 EXPECT_EQ(1, (*tables)[kTestDeviceIndex1].size());
349
350 test_entry = (*tables)[kTestDeviceIndex1][0];
351 EXPECT_TRUE(entry1.Equals(test_entry));
352
Paul Stewart5b7ba8c2012-04-18 09:08:00 -0700353 // Send a duplicate of the second gateway route message, changing the metric.
Paul Stewart75e89d22011-08-01 10:00:02 -0700354 RoutingTableEntry entry2(entry1);
355 entry2.metric++;
Paul Stewartf748a362012-03-07 12:01:20 -0800356 SendRouteEntry(RTNLMessage::kModeAdd,
357 kTestDeviceIndex1,
358 entry2);
Paul Stewart75e89d22011-08-01 10:00:02 -0700359
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800360 // Routing table size shouldn't change, but the new metric should match.
Paul Stewart75e89d22011-08-01 10:00:02 -0700361 EXPECT_EQ(1, (*tables)[kTestDeviceIndex1].size());
362 test_entry = (*tables)[kTestDeviceIndex1][0];
363 EXPECT_TRUE(entry2.Equals(test_entry));
364
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800365 // Find a matching entry.
Paul Stewart75e89d22011-08-01 10:00:02 -0700366 EXPECT_TRUE(routing_table_->GetDefaultRoute(kTestDeviceIndex1,
Paul Stewart7355ce12011-09-02 10:47:01 -0700367 IPAddress::kFamilyIPv4,
Paul Stewart75e89d22011-08-01 10:00:02 -0700368 &test_entry));
369 EXPECT_TRUE(entry2.Equals(test_entry));
370
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800371 // Test that a search for a non-matching family fails.
Paul Stewart75e89d22011-08-01 10:00:02 -0700372 EXPECT_FALSE(routing_table_->GetDefaultRoute(kTestDeviceIndex1,
Paul Stewart7355ce12011-09-02 10:47:01 -0700373 IPAddress::kFamilyIPv6,
Paul Stewart75e89d22011-08-01 10:00:02 -0700374 &test_entry));
375
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800376 // Remove last entry from an existing interface and test that we now fail.
Paul Stewartf748a362012-03-07 12:01:20 -0800377 SendRouteEntry(RTNLMessage::kModeDelete,
378 kTestDeviceIndex1,
379 entry2);
Paul Stewart75e89d22011-08-01 10:00:02 -0700380
381 EXPECT_FALSE(routing_table_->GetDefaultRoute(kTestDeviceIndex1,
Paul Stewart7355ce12011-09-02 10:47:01 -0700382 IPAddress::kFamilyIPv4,
Paul Stewart75e89d22011-08-01 10:00:02 -0700383 &test_entry));
384
Ben Chana6bfe872012-09-26 09:48:34 -0700385 // Add a route to a gateway address.
Paul Stewart5b7ba8c2012-04-18 09:08:00 -0700386 IPAddress gateway_address(IPAddress::kFamilyIPv4);
387 EXPECT_TRUE(gateway_address.SetAddressFromString(kTestNetAddress0));
Paul Stewart75e89d22011-08-01 10:00:02 -0700388
Paul Stewartf748a362012-03-07 12:01:20 -0800389 EXPECT_CALL(rtnl_handler_,
390 SendMessage(IsRoutingPacket(RTNLMessage::kModeAdd,
391 kTestDeviceIndex1,
392 entry0,
393 NLM_F_CREATE | NLM_F_EXCL)));
Paul Stewart75e89d22011-08-01 10:00:02 -0700394 EXPECT_TRUE(routing_table_->SetDefaultRoute(kTestDeviceIndex1,
Paul Stewart5b7ba8c2012-04-18 09:08:00 -0700395 gateway_address,
Paul Stewart75e89d22011-08-01 10:00:02 -0700396 metric));
397
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800398 // The table entry should look much like entry0, except with
399 // from_rtnl = false.
Paul Stewart75e89d22011-08-01 10:00:02 -0700400 RoutingTableEntry entry3(entry0);
401 entry3.from_rtnl = false;
402 EXPECT_TRUE(routing_table_->GetDefaultRoute(kTestDeviceIndex1,
Paul Stewart7355ce12011-09-02 10:47:01 -0700403 IPAddress::kFamilyIPv4,
Paul Stewart75e89d22011-08-01 10:00:02 -0700404 &test_entry));
405 EXPECT_TRUE(entry3.Equals(test_entry));
406
407 // Setting the same route on the interface with a different metric should
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800408 // push the route with different flags to indicate we are replacing it,
409 // then it should delete the old entry.
Paul Stewart75e89d22011-08-01 10:00:02 -0700410 RoutingTableEntry entry4(entry3);
411 entry4.metric += 10;
Paul Stewartf748a362012-03-07 12:01:20 -0800412 EXPECT_CALL(rtnl_handler_,
413 SendMessage(IsRoutingPacket(RTNLMessage::kModeAdd,
414 kTestDeviceIndex1,
415 entry4,
416 NLM_F_CREATE | NLM_F_REPLACE)));
417 EXPECT_CALL(rtnl_handler_,
418 SendMessage(IsRoutingPacket(RTNLMessage::kModeDelete,
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800419 kTestDeviceIndex1,
420 entry3,
Paul Stewartf748a362012-03-07 12:01:20 -0800421 0)));
Paul Stewart75e89d22011-08-01 10:00:02 -0700422 EXPECT_TRUE(routing_table_->SetDefaultRoute(kTestDeviceIndex1,
Paul Stewart5b7ba8c2012-04-18 09:08:00 -0700423 gateway_address,
Paul Stewart75e89d22011-08-01 10:00:02 -0700424 entry4.metric));
425
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800426 // Test that removing the table causes the route to disappear.
Paul Stewart75e89d22011-08-01 10:00:02 -0700427 routing_table_->ResetTable(kTestDeviceIndex1);
428 EXPECT_FALSE(ContainsKey(*tables, kTestDeviceIndex1));
429 EXPECT_FALSE(routing_table_->GetDefaultRoute(kTestDeviceIndex1,
Paul Stewart7355ce12011-09-02 10:47:01 -0700430 IPAddress::kFamilyIPv4,
Paul Stewart75e89d22011-08-01 10:00:02 -0700431 &test_entry));
432 EXPECT_EQ(1, GetRoutingTables()->size());
433
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800434 // When we set the metric on an existing route, a new add and delete
435 // operation should occur.
Paul Stewart75e89d22011-08-01 10:00:02 -0700436 RoutingTableEntry entry5(entry4);
437 entry5.metric += 10;
Paul Stewartf748a362012-03-07 12:01:20 -0800438 EXPECT_CALL(rtnl_handler_,
439 SendMessage(IsRoutingPacket(RTNLMessage::kModeAdd,
440 kTestDeviceIndex0,
441 entry5,
442 NLM_F_CREATE | NLM_F_REPLACE)));
443 EXPECT_CALL(rtnl_handler_,
444 SendMessage(IsRoutingPacket(RTNLMessage::kModeDelete,
445 kTestDeviceIndex0,
446 entry0,
447 0)));
Paul Stewart75e89d22011-08-01 10:00:02 -0700448 routing_table_->SetDefaultMetric(kTestDeviceIndex0, entry5.metric);
mukesh agrawald4ef6772012-02-21 16:28:04 -0800449 // Furthermore, the routing table should reflect the change in the metric
450 // for the default route for the interface.
451 RoutingTableEntry default_route;
452 EXPECT_TRUE(routing_table_->GetDefaultRoute(kTestDeviceIndex0,
453 IPAddress::kFamilyIPv4,
454 &default_route));
455 EXPECT_EQ(entry5.metric, default_route.metric);
Paul Stewart75e89d22011-08-01 10:00:02 -0700456
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800457 // Ask to flush table0. We should see a delete message sent.
Paul Stewartf748a362012-03-07 12:01:20 -0800458 EXPECT_CALL(rtnl_handler_,
459 SendMessage(IsRoutingPacket(RTNLMessage::kModeDelete,
460 kTestDeviceIndex0,
461 entry5,
462 0)));
Thieu Lefb46caf2012-03-08 11:57:15 -0800463 routing_table_->FlushRoutes(kTestDeviceIndex0);
464 EXPECT_EQ(0, (*tables)[kTestDeviceIndex0].size());
Paul Stewart75e89d22011-08-01 10:00:02 -0700465
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800466 // Test that the routing table size returns to zero.
Paul Stewartf748a362012-03-07 12:01:20 -0800467 SendRouteEntry(RTNLMessage::kModeAdd,
468 kTestDeviceIndex0,
469 entry5);
Paul Stewart75e89d22011-08-01 10:00:02 -0700470 EXPECT_EQ(1, GetRoutingTables()->size());
471 routing_table_->ResetTable(kTestDeviceIndex0);
472 EXPECT_EQ(0, GetRoutingTables()->size());
473
474 routing_table_->Stop();
Paul Stewartf748a362012-03-07 12:01:20 -0800475}
476
Paul Stewart3f68bb12012-03-15 13:33:10 -0700477TEST_F(RoutingTableTest, ConfigureRoutes) {
478 MockControl control;
479 IPConfigRefPtr ipconfig(new IPConfig(&control, kTestDeviceName0));
480 IPConfig::Properties properties;
481 properties.address_family = IPAddress::kFamilyIPv4;
482 vector<IPConfig::Route> &routes = properties.routes;
483 ipconfig->UpdateProperties(properties, true);
484
485 const int kMetric = 10;
486 EXPECT_TRUE(routing_table_->ConfigureRoutes(kTestDeviceIndex0,
487 ipconfig,
488 kMetric));
489
490 IPConfig::Route route;
491 route.host = kTestRemoteNetwork4;
492 route.netmask = kTestRemoteNetmask4;
493 route.gateway = kTestGatewayAddress4;
494 routes.push_back(route);
495 ipconfig->UpdateProperties(properties, true);
496
497 IPAddress destination_address(IPAddress::kFamilyIPv4);
498 IPAddress source_address(IPAddress::kFamilyIPv4);
499 IPAddress gateway_address(IPAddress::kFamilyIPv4);
500 ASSERT_TRUE(destination_address.SetAddressFromString(kTestRemoteNetwork4));
501 destination_address.set_prefix(kTestRemotePrefix4);
502 ASSERT_TRUE(gateway_address.SetAddressFromString(kTestGatewayAddress4));
503
504 RoutingTableEntry entry(destination_address,
505 source_address,
506 gateway_address,
507 kMetric,
508 RT_SCOPE_UNIVERSE,
509 false);
510
511 EXPECT_CALL(rtnl_handler_,
512 SendMessage(IsRoutingPacket(RTNLMessage::kModeAdd,
513 kTestDeviceIndex0,
514 entry,
515 NLM_F_CREATE | NLM_F_EXCL)));
516 EXPECT_TRUE(routing_table_->ConfigureRoutes(kTestDeviceIndex0,
517 ipconfig,
518 kMetric));
519
520 routes.clear();
521 route.gateway = "xxx"; // Invalid gateway entry -- should be skipped
522 routes.push_back(route);
523 route.host = "xxx"; // Invalid host entry -- should be skipped
524 route.gateway = kTestGatewayAddress4;
525 routes.push_back(route);
526 route.host = kTestRemoteNetwork4;
527 routes.push_back(route);
528 ipconfig->UpdateProperties(properties, true);
529
530 EXPECT_CALL(rtnl_handler_,
531 SendMessage(IsRoutingPacket(RTNLMessage::kModeAdd,
532 kTestDeviceIndex0,
533 entry,
534 NLM_F_CREATE | NLM_F_EXCL)))
535 .Times(1);
536 EXPECT_FALSE(routing_table_->ConfigureRoutes(kTestDeviceIndex0,
537 ipconfig,
538 kMetric));
539}
540
Paul Stewartf748a362012-03-07 12:01:20 -0800541MATCHER_P2(IsRoutingQuery, destination, index, "") {
542 const RTNLMessage::RouteStatus &status = arg->route_status();
543
544 uint32 oif;
545
546 return
547 arg->type() == RTNLMessage::kTypeRoute &&
548 arg->family() == destination.family() &&
549 arg->flags() == NLM_F_REQUEST &&
550 status.table == 0 &&
551 status.protocol == 0 &&
552 status.scope == 0 &&
553 status.type == 0 &&
554 arg->HasAttribute(RTA_DST) &&
555 IPAddress(arg->family(),
556 arg->GetAttribute(RTA_DST),
557 status.dst_prefix).Equals(destination) &&
558 !arg->HasAttribute(RTA_SRC) &&
559 !arg->HasAttribute(RTA_GATEWAY) &&
560 arg->GetAttribute(RTA_OIF).ConvertToCPUUInt32(&oif) &&
561 oif == index &&
562 !arg->HasAttribute(RTA_PRIORITY);
563
564 return false;
565}
566
567TEST_F(RoutingTableTest, RequestHostRoute) {
568 IPAddress destination_address(IPAddress::kFamilyIPv4);
569 destination_address.SetAddressFromString(kTestRemoteAddress4);
570 destination_address.set_prefix(24);
571
572 EXPECT_CALL(rtnl_handler_,
573 SendMessage(IsRoutingQuery(destination_address,
574 kTestDeviceIndex0)))
575 .WillOnce(Invoke(this, &RoutingTableTest::SetSequenceForMessage));
Darin Petkovabf6d282012-05-08 15:49:05 +0200576 EXPECT_TRUE(
577 routing_table_->RequestRouteToHost(destination_address,
578 kTestDeviceIndex0,
579 kTestRouteTag,
580 RoutingTable::Query::Callback()));
Paul Stewartf748a362012-03-07 12:01:20 -0800581
582 IPAddress gateway_address(IPAddress::kFamilyIPv4);
583 gateway_address.SetAddressFromString(kTestGatewayAddress4);
584
585 IPAddress local_address(IPAddress::kFamilyIPv4);
586 local_address.SetAddressFromString(kTestDeviceNetAddress4);
587
588 const int kMetric = 10;
589 RoutingTableEntry entry(destination_address,
590 local_address,
591 gateway_address,
592 kMetric,
593 RT_SCOPE_UNIVERSE,
594 true);
595
596 EXPECT_CALL(rtnl_handler_,
597 SendMessage(IsRoutingPacket(RTNLMessage::kModeAdd,
598 kTestDeviceIndex0,
599 entry,
600 NLM_F_CREATE | NLM_F_EXCL)));
601 SendRouteEntryWithSeqAndProto(RTNLMessage::kModeAdd,
602 kTestDeviceIndex0,
603 entry,
604 kTestRequestSeq,
605 RTPROT_UNSPEC);
Paul Stewarte93b0382012-04-24 13:11:28 -0700606
Darin Petkovabf6d282012-05-08 15:49:05 +0200607 hash_map<int, vector<RoutingTableEntry> > *tables = GetRoutingTables();
Paul Stewarte93b0382012-04-24 13:11:28 -0700608
609 // We should have a single table, which should in turn have a single entry.
610 EXPECT_EQ(1, tables->size());
611 EXPECT_TRUE(ContainsKey(*tables, kTestDeviceIndex0));
612 EXPECT_EQ(1, (*tables)[kTestDeviceIndex0].size());
613
614 // This entry's tag should match the tag we requested.
615 EXPECT_EQ(kTestRouteTag, (*tables)[kTestDeviceIndex0][0].tag);
616
Darin Petkovabf6d282012-05-08 15:49:05 +0200617 EXPECT_TRUE(GetQueries()->empty());
618
Paul Stewarte93b0382012-04-24 13:11:28 -0700619 // Ask to flush routes with our tag. We should see a delete message sent.
620 EXPECT_CALL(rtnl_handler_,
621 SendMessage(IsRoutingPacket(RTNLMessage::kModeDelete,
622 kTestDeviceIndex0,
623 entry,
624 0)));
625
626 routing_table_->FlushRoutesWithTag(kTestRouteTag);
627
628 // After flushing routes for this tag, we should end up with no routes.
629 EXPECT_EQ(0, (*tables)[kTestDeviceIndex0].size());
Paul Stewartf748a362012-03-07 12:01:20 -0800630}
631
Paul Stewartbbed76d2012-04-27 20:02:13 -0700632TEST_F(RoutingTableTest, RequestHostRouteWithoutGateway) {
633 IPAddress destination_address(IPAddress::kFamilyIPv4);
634 destination_address.SetAddressFromString(kTestRemoteAddress4);
635 destination_address.set_prefix(24);
636
637 EXPECT_CALL(rtnl_handler_,
638 SendMessage(IsRoutingQuery(destination_address,
639 kTestDeviceIndex0)))
640 .WillOnce(Invoke(this, &RoutingTableTest::SetSequenceForMessage));
Darin Petkovabf6d282012-05-08 15:49:05 +0200641 EXPECT_TRUE(
642 routing_table_->RequestRouteToHost(destination_address,
643 kTestDeviceIndex0,
644 kTestRouteTag,
645 RoutingTable::Query::Callback()));
Paul Stewartbbed76d2012-04-27 20:02:13 -0700646
647 // Don't specify a gateway address.
648 IPAddress gateway_address(IPAddress::kFamilyIPv4);
649
650 IPAddress local_address(IPAddress::kFamilyIPv4);
651 local_address.SetAddressFromString(kTestDeviceNetAddress4);
652
653 const int kMetric = 10;
654 RoutingTableEntry entry(destination_address,
655 local_address,
656 gateway_address,
657 kMetric,
658 RT_SCOPE_UNIVERSE,
659 true);
660
661 // Ensure that without a gateway entry, we don't create a route.
662 EXPECT_CALL(rtnl_handler_, SendMessage(_)).Times(0);
663 SendRouteEntryWithSeqAndProto(RTNLMessage::kModeAdd,
664 kTestDeviceIndex0,
665 entry,
666 kTestRequestSeq,
667 RTPROT_UNSPEC);
Darin Petkovabf6d282012-05-08 15:49:05 +0200668 EXPECT_TRUE(GetQueries()->empty());
Paul Stewartbbed76d2012-04-27 20:02:13 -0700669}
670
Paul Stewartf748a362012-03-07 12:01:20 -0800671TEST_F(RoutingTableTest, RequestHostRouteBadSequence) {
672 IPAddress destination_address(IPAddress::kFamilyIPv4);
673 destination_address.SetAddressFromString(kTestRemoteAddress4);
Darin Petkovabf6d282012-05-08 15:49:05 +0200674 QueryCallbackTarget target;
Darin Petkov13e6d552012-05-09 14:22:23 +0200675 EXPECT_CALL(target, MockedTarget(_, _)).Times(0);
Paul Stewartf748a362012-03-07 12:01:20 -0800676 EXPECT_CALL(rtnl_handler_, SendMessage(_))
677 .WillOnce(Invoke(this, &RoutingTableTest::SetSequenceForMessage));
Darin Petkovabf6d282012-05-08 15:49:05 +0200678 EXPECT_TRUE(
679 routing_table_->RequestRouteToHost(destination_address,
680 kTestDeviceIndex0,
681 kTestRouteTag,
Darin Petkov13e6d552012-05-09 14:22:23 +0200682 target.mocked_callback()));
Paul Stewarte93b0382012-04-24 13:11:28 -0700683 EXPECT_FALSE(GetQueries()->empty());
Paul Stewartf748a362012-03-07 12:01:20 -0800684
685 RoutingTableEntry entry(destination_address,
686 destination_address,
687 destination_address,
688 0,
689 RT_SCOPE_UNIVERSE,
690 true);
691
692 // Try a sequence arriving before the one RoutingTable is looking for.
693 // This should be a no-op.
694 SendRouteEntryWithSeqAndProto(RTNLMessage::kModeAdd,
695 kTestDeviceIndex0,
696 entry,
Darin Petkovabf6d282012-05-08 15:49:05 +0200697 kTestRequestSeq - 1,
Paul Stewartf748a362012-03-07 12:01:20 -0800698 RTPROT_UNSPEC);
Paul Stewarte93b0382012-04-24 13:11:28 -0700699 EXPECT_FALSE(GetQueries()->empty());
Paul Stewartf748a362012-03-07 12:01:20 -0800700
701 // Try a sequence arriving after the one RoutingTable is looking for.
702 // This should cause the request to be purged.
703 SendRouteEntryWithSeqAndProto(RTNLMessage::kModeAdd,
704 kTestDeviceIndex0,
705 entry,
Darin Petkovabf6d282012-05-08 15:49:05 +0200706 kTestRequestSeq + 1,
Paul Stewartf748a362012-03-07 12:01:20 -0800707 RTPROT_UNSPEC);
Paul Stewarte93b0382012-04-24 13:11:28 -0700708 EXPECT_TRUE(GetQueries()->empty());
Paul Stewart75e89d22011-08-01 10:00:02 -0700709}
710
Darin Petkovabf6d282012-05-08 15:49:05 +0200711TEST_F(RoutingTableTest, RequestHostRouteWithCallback) {
712 IPAddress destination_address(IPAddress::kFamilyIPv4);
713
714 EXPECT_CALL(rtnl_handler_, SendMessage(_))
715 .WillOnce(Invoke(this, &RoutingTableTest::SetSequenceForMessage));
716 QueryCallbackTarget target;
717 EXPECT_TRUE(
718 routing_table_->RequestRouteToHost(
Darin Petkov13e6d552012-05-09 14:22:23 +0200719 destination_address, -1, kTestRouteTag, target.mocked_callback()));
Darin Petkovabf6d282012-05-08 15:49:05 +0200720
721 IPAddress gateway_address(IPAddress::kFamilyIPv4);
722 gateway_address.SetAddressFromString(kTestGatewayAddress4);
Darin Petkovabf6d282012-05-08 15:49:05 +0200723
724 const int kMetric = 10;
725 RoutingTableEntry entry(destination_address,
Darin Petkov13e6d552012-05-09 14:22:23 +0200726 IPAddress(IPAddress::kFamilyIPv4),
Darin Petkovabf6d282012-05-08 15:49:05 +0200727 gateway_address,
728 kMetric,
729 RT_SCOPE_UNIVERSE,
730 true);
731
732 EXPECT_CALL(rtnl_handler_, SendMessage(_));
733 EXPECT_CALL(target,
Darin Petkov13e6d552012-05-09 14:22:23 +0200734 MockedTarget(kTestDeviceIndex0,
735 Field(&RoutingTableEntry::tag, kTestRouteTag)));
Darin Petkovabf6d282012-05-08 15:49:05 +0200736 SendRouteEntryWithSeqAndProto(RTNLMessage::kModeAdd,
737 kTestDeviceIndex0,
738 entry,
739 kTestRequestSeq,
740 RTPROT_UNSPEC);
741}
742
743TEST_F(RoutingTableTest, RequestHostRouteWithoutGatewayWithCallback) {
744 IPAddress destination_address(IPAddress::kFamilyIPv4);
745
746 EXPECT_CALL(rtnl_handler_, SendMessage(_))
747 .WillOnce(Invoke(this, &RoutingTableTest::SetSequenceForMessage));
748 QueryCallbackTarget target;
749 EXPECT_TRUE(
750 routing_table_->RequestRouteToHost(
Darin Petkov13e6d552012-05-09 14:22:23 +0200751 destination_address, -1, kTestRouteTag, target.mocked_callback()));
Darin Petkovabf6d282012-05-08 15:49:05 +0200752
753 const int kMetric = 10;
754 RoutingTableEntry entry(destination_address,
Darin Petkov13e6d552012-05-09 14:22:23 +0200755 IPAddress(IPAddress::kFamilyIPv4),
756 IPAddress(IPAddress::kFamilyIPv4),
Darin Petkovabf6d282012-05-08 15:49:05 +0200757 kMetric,
758 RT_SCOPE_UNIVERSE,
759 true);
760
761 EXPECT_CALL(target,
Darin Petkov13e6d552012-05-09 14:22:23 +0200762 MockedTarget(kTestDeviceIndex0,
763 Field(&RoutingTableEntry::tag, kTestRouteTag)));
Darin Petkovabf6d282012-05-08 15:49:05 +0200764 SendRouteEntryWithSeqAndProto(RTNLMessage::kModeAdd,
765 kTestDeviceIndex0,
766 entry,
767 kTestRequestSeq,
768 RTPROT_UNSPEC);
769}
770
771TEST_F(RoutingTableTest, CancelQueryCallback) {
772 IPAddress destination_address(IPAddress::kFamilyIPv4);
773 destination_address.SetAddressFromString(kTestRemoteAddress4);
Darin Petkov13e6d552012-05-09 14:22:23 +0200774 scoped_ptr<QueryCallbackTarget> target(new QueryCallbackTarget());
775 EXPECT_CALL(rtnl_handler_, SendMessage(_))
776 .WillOnce(Invoke(this, &RoutingTableTest::SetSequenceForMessage));
Darin Petkovabf6d282012-05-08 15:49:05 +0200777 EXPECT_TRUE(
778 routing_table_->RequestRouteToHost(destination_address,
779 kTestDeviceIndex0,
780 kTestRouteTag,
Darin Petkov13e6d552012-05-09 14:22:23 +0200781 target->unreached_callback()));
782 ASSERT_EQ(1, GetQueries()->size());
783 // Cancels the callback by destroying the owner object.
784 target.reset();
785 const int kMetric = 10;
786 RoutingTableEntry entry(IPAddress(IPAddress::kFamilyIPv4),
787 IPAddress(IPAddress::kFamilyIPv4),
788 IPAddress(IPAddress::kFamilyIPv4),
789 kMetric,
790 RT_SCOPE_UNIVERSE,
791 true);
792 SendRouteEntryWithSeqAndProto(RTNLMessage::kModeAdd,
793 kTestDeviceIndex0,
794 entry,
795 kTestRequestSeq,
796 RTPROT_UNSPEC);
Darin Petkovabf6d282012-05-08 15:49:05 +0200797}
798
Ben Chana0163122012-09-25 15:10:52 -0700799TEST_F(RoutingTableTest, CreateBlackholeRoute) {
800 const uint32 kMetric = 2;
801 EXPECT_CALL(rtnl_handler_,
802 SendMessage(IsBlackholeRoutingPacket(kTestDeviceIndex0,
803 IPAddress::kFamilyIPv6,
804 kMetric)))
805 .Times(1);
806 EXPECT_TRUE(routing_table_->CreateBlackholeRoute(kTestDeviceIndex0,
807 IPAddress::kFamilyIPv6,
808 kMetric));
809}
810
Paul Stewart4a6748d2012-07-17 14:31:36 -0700811TEST_F(RoutingTableTest, CreateLinkRoute) {
812 IPAddress local_address(IPAddress::kFamilyIPv4);
813 ASSERT_TRUE(local_address.SetAddressFromString(kTestNetAddress0));
814 local_address.set_prefix(kTestRemotePrefix4);
815 IPAddress remote_address(IPAddress::kFamilyIPv4);
816 ASSERT_TRUE(remote_address.SetAddressFromString(kTestNetAddress1));
817 IPAddress default_address(IPAddress::kFamilyIPv4);
818 IPAddress remote_address_with_prefix(remote_address);
819 remote_address_with_prefix.set_prefix(
820 IPAddress::GetMaxPrefixLength(remote_address_with_prefix.family()));
821 RoutingTableEntry entry(remote_address_with_prefix,
822 local_address,
823 default_address,
824 0,
825 RT_SCOPE_LINK,
826 false);
827 EXPECT_CALL(rtnl_handler_,
828 SendMessage(IsRoutingPacket(RTNLMessage::kModeAdd,
829 kTestDeviceIndex0,
830 entry,
831 NLM_F_CREATE | NLM_F_EXCL)))
832 .Times(1);
833 EXPECT_TRUE(routing_table_->CreateLinkRoute(kTestDeviceIndex0,
834 local_address,
835 remote_address));
836
837 ASSERT_TRUE(remote_address.SetAddressFromString(kTestRemoteAddress4));
838 EXPECT_FALSE(routing_table_->CreateLinkRoute(kTestDeviceIndex0,
839 local_address,
840 remote_address));
841}
842
Paul Stewart75e89d22011-08-01 10:00:02 -0700843} // namespace shill