1// 2// Copyright (C) 2012 The Android Open Source Project 3// 4// Licensed under the Apache License, Version 2.0 (the "License"); 5// you may not use this file except in compliance with the License. 6// You may obtain a copy of the License at 7// 8// http://www.apache.org/licenses/LICENSE-2.0 9// 10// Unless required by applicable law or agreed to in writing, software 11// distributed under the License is distributed on an "AS IS" BASIS, 12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13// See the License for the specific language governing permissions and 14// limitations under the License. 15// 16 17#include "shill/routing_table.h" 18 19#include <linux/rtnetlink.h> 20#include <sys/socket.h> 21 22#include <memory> 23#include <vector> 24 25#include <base/bind.h> 26#include <base/callback.h> 27#include <base/memory/weak_ptr.h> 28#include <base/stl_util.h> 29#include <gtest/gtest.h> 30#include <gmock/gmock.h> 31 32#include "shill/event_dispatcher.h" 33#include "shill/ipconfig.h" 34#include "shill/logging.h" 35#include "shill/mock_control.h" 36#include "shill/net/byte_string.h" 37#include "shill/net/mock_rtnl_handler.h" 38#include "shill/net/rtnl_message.h" 39#include "shill/routing_table_entry.h" 40 41using base::Bind; 42using base::Callback; 43using base::Unretained; 44using std::deque; 45using std::vector; 46using testing::_; 47using testing::Field; 48using testing::Invoke; 49using testing::Return; 50using testing::StrictMock; 51using testing::Test; 52 53namespace shill { 54 55class TestEventDispatcher : public EventDispatcher { 56 public: 57 virtual IOHandler* CreateInputHandler( 58 int /*fd*/, 59 const IOHandler::InputCallback& /*input_callback*/, 60 const IOHandler::ErrorCallback& /*error_callback*/) { 61 return nullptr; 62 } 63}; 64 65class RoutingTableTest : public Test { 66 public: 67 static const uint8_t kTestTableId; 68 69 RoutingTableTest() : routing_table_(new RoutingTable()) {} 70 71 virtual void SetUp() { 72 routing_table_->rtnl_handler_ = &rtnl_handler_; 73 ON_CALL(rtnl_handler_, SendMessage(_)).WillByDefault(Return(true)); 74 } 75 76 virtual void TearDown() { 77 RTNLHandler::GetInstance()->Stop(); 78 } 79 80 std::unordered_map<int, vector<RoutingTableEntry>>* GetRoutingTables() { 81 return &routing_table_->tables_; 82 } 83 84 deque<RoutingTable::Query>* GetQueries() { 85 return &routing_table_->route_queries_; 86 } 87 88 void SendRouteEntry(RTNLMessage::Mode mode, 89 uint32_t interface_index, 90 const RoutingTableEntry& entry); 91 92 void SendRouteEntryWithSeqAndProto(RTNLMessage::Mode mode, 93 uint32_t interface_index, 94 const RoutingTableEntry& entry, 95 uint32_t seq, 96 unsigned char proto); 97 98 void SendRouteMessage(const RTNLMessage& msg); 99 100 bool SetSequenceForMessage(RTNLMessage* message) { 101 message->set_seq(RoutingTableTest::kTestRequestSeq); 102 return true; 103 } 104 105 protected: 106 static const uint32_t kTestDeviceIndex0; 107 static const uint32_t kTestDeviceIndex1; 108 static const char kTestDeviceName0[]; 109 static const char kTestDeviceNetAddress4[]; 110 static const char kTestForeignNetAddress4[]; 111 static const char kTestForeignNetGateway4[]; 112 static const char kTestForeignNetAddress6[]; 113 static const char kTestForeignNetGateway6[]; 114 static const char kTestGatewayAddress4[]; 115 static const char kTestNetAddress0[]; 116 static const char kTestNetAddress1[]; 117 static const char kTestRemoteAddress4[]; 118 static const char kTestRemoteNetmask4[]; 119 static const char kTestRemoteNetwork4[]; 120 static const int kTestRemotePrefix4; 121 static const uint32_t kTestRequestSeq; 122 static const int kTestRouteTag; 123 124 class QueryCallbackTarget { 125 public: 126 QueryCallbackTarget() 127 : weak_ptr_factory_(this), 128 mocked_callback_( 129 Bind(&QueryCallbackTarget::MockedTarget, Unretained(this))), 130 unreached_callback_(Bind(&QueryCallbackTarget::UnreachedTarget, 131 weak_ptr_factory_.GetWeakPtr())) {} 132 133 MOCK_METHOD2(MockedTarget, 134 void(int interface_index, const RoutingTableEntry& entry)); 135 136 void UnreachedTarget(int interface_index, const RoutingTableEntry& entry) { 137 CHECK(false); 138 } 139 140 const RoutingTable::Query::Callback& mocked_callback() const { 141 return mocked_callback_; 142 } 143 144 const RoutingTable::Query::Callback& unreached_callback() const { 145 return unreached_callback_; 146 } 147 148 private: 149 base::WeakPtrFactory<QueryCallbackTarget> weak_ptr_factory_; 150 const RoutingTable::Query::Callback mocked_callback_; 151 const RoutingTable::Query::Callback unreached_callback_; 152 }; 153 154 std::unique_ptr<RoutingTable> routing_table_; 155 TestEventDispatcher dispatcher_; 156 StrictMock<MockRTNLHandler> rtnl_handler_; 157}; 158 159const uint32_t RoutingTableTest::kTestDeviceIndex0 = 12345; 160const uint32_t RoutingTableTest::kTestDeviceIndex1 = 67890; 161const char RoutingTableTest::kTestDeviceName0[] = "test-device0"; 162const char RoutingTableTest::kTestDeviceNetAddress4[] = "192.168.2.0/24"; 163const char RoutingTableTest::kTestForeignNetAddress4[] = "192.168.2.2"; 164const char RoutingTableTest::kTestForeignNetGateway4[] = "192.168.2.1"; 165const char RoutingTableTest::kTestForeignNetAddress6[] = "2000::/3"; 166const char RoutingTableTest::kTestForeignNetGateway6[] = "fe80:::::1"; 167const char RoutingTableTest::kTestGatewayAddress4[] = "192.168.2.254"; 168const char RoutingTableTest::kTestNetAddress0[] = "192.168.1.1"; 169const char RoutingTableTest::kTestNetAddress1[] = "192.168.1.2"; 170const char RoutingTableTest::kTestRemoteAddress4[] = "192.168.2.254"; 171const char RoutingTableTest::kTestRemoteNetmask4[] = "255.255.255.0"; 172const char RoutingTableTest::kTestRemoteNetwork4[] = "192.168.100.0"; 173const int RoutingTableTest::kTestRemotePrefix4 = 24; 174const uint32_t RoutingTableTest::kTestRequestSeq = 456; 175const int RoutingTableTest::kTestRouteTag = 789; 176const uint8_t RoutingTableTest::kTestTableId = 0xa5; 177 178namespace { 179 180MATCHER_P3(IsBlackholeRoutingPacket, index, family, metric, "") { 181 const RTNLMessage::RouteStatus& status = arg->route_status(); 182 183 uint32_t oif; 184 uint32_t priority; 185 186 return 187 arg->type() == RTNLMessage::kTypeRoute && 188 arg->family() == family && 189 arg->flags() == (NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL) && 190 status.table == RoutingTableTest::kTestTableId && 191 status.protocol == RTPROT_BOOT && 192 status.scope == RT_SCOPE_UNIVERSE && 193 status.type == RTN_BLACKHOLE && 194 !arg->HasAttribute(RTA_DST) && 195 !arg->HasAttribute(RTA_SRC) && 196 !arg->HasAttribute(RTA_GATEWAY) && 197 arg->GetAttribute(RTA_OIF).ConvertToCPUUInt32(&oif) && 198 oif == index && 199 arg->GetAttribute(RTA_PRIORITY).ConvertToCPUUInt32(&priority) && 200 priority == metric; 201} 202 203MATCHER_P4(IsRoutingPacket, mode, index, entry, flags, "") { 204 const RTNLMessage::RouteStatus& status = arg->route_status(); 205 206 uint32_t oif; 207 uint32_t priority; 208 209 return 210 arg->type() == RTNLMessage::kTypeRoute && 211 arg->family() == entry.gateway.family() && 212 arg->flags() == (NLM_F_REQUEST | flags) && 213 status.table == RoutingTableTest::kTestTableId && 214 entry.table == RoutingTableTest::kTestTableId && 215 status.protocol == RTPROT_BOOT && 216 status.scope == entry.scope && 217 status.type == RTN_UNICAST && 218 arg->HasAttribute(RTA_DST) && 219 IPAddress(arg->family(), 220 arg->GetAttribute(RTA_DST), 221 status.dst_prefix).Equals(entry.dst) && 222 ((!arg->HasAttribute(RTA_SRC) && entry.src.IsDefault()) || 223 (arg->HasAttribute(RTA_SRC) && IPAddress(arg->family(), 224 arg->GetAttribute(RTA_SRC), 225 status.src_prefix).Equals(entry.src))) && 226 ((!arg->HasAttribute(RTA_GATEWAY) && entry.gateway.IsDefault()) || 227 (arg->HasAttribute(RTA_GATEWAY) && IPAddress(arg->family(), 228 arg->GetAttribute(RTA_GATEWAY)).Equals(entry.gateway))) && 229 arg->GetAttribute(RTA_OIF).ConvertToCPUUInt32(&oif) && 230 oif == index && 231 arg->GetAttribute(RTA_PRIORITY).ConvertToCPUUInt32(&priority) && 232 priority == entry.metric; 233} 234 235} // namespace 236 237void RoutingTableTest::SendRouteEntry(RTNLMessage::Mode mode, 238 uint32_t interface_index, 239 const RoutingTableEntry& entry) { 240 SendRouteEntryWithSeqAndProto(mode, interface_index, entry, 0, RTPROT_BOOT); 241} 242 243void RoutingTableTest::SendRouteEntryWithSeqAndProto( 244 RTNLMessage::Mode mode, 245 uint32_t interface_index, 246 const RoutingTableEntry& entry, 247 uint32_t seq, 248 unsigned char proto) { 249 RTNLMessage msg( 250 RTNLMessage::kTypeRoute, 251 mode, 252 0, 253 seq, 254 0, 255 0, 256 entry.dst.family()); 257 258 msg.set_route_status(RTNLMessage::RouteStatus( 259 entry.dst.prefix(), 260 entry.src.prefix(), 261 entry.table, 262 proto, 263 entry.scope, 264 RTN_UNICAST, 265 0)); 266 267 msg.SetAttribute(RTA_DST, entry.dst.address()); 268 if (!entry.src.IsDefault()) { 269 msg.SetAttribute(RTA_SRC, entry.src.address()); 270 } 271 if (!entry.gateway.IsDefault()) { 272 msg.SetAttribute(RTA_GATEWAY, entry.gateway.address()); 273 } 274 msg.SetAttribute(RTA_PRIORITY, ByteString::CreateFromCPUUInt32(entry.metric)); 275 msg.SetAttribute(RTA_OIF, ByteString::CreateFromCPUUInt32(interface_index)); 276 277 routing_table_->RouteMsgHandler(msg); 278} 279 280void RoutingTableTest::SendRouteMessage(const RTNLMessage& msg) { 281 routing_table_->RouteMsgHandler(msg); 282} 283 284TEST_F(RoutingTableTest, Start) { 285 EXPECT_CALL(rtnl_handler_, RequestDump(RTNLHandler::kRequestRoute)); 286 routing_table_->Start(); 287} 288 289TEST_F(RoutingTableTest, RouteAddDelete) { 290 // Expect the tables to be empty by default. 291 EXPECT_EQ(0, GetRoutingTables()->size()); 292 293 IPAddress default_address(IPAddress::kFamilyIPv4); 294 default_address.SetAddressToDefault(); 295 296 IPAddress gateway_address0(IPAddress::kFamilyIPv4); 297 gateway_address0.SetAddressFromString(kTestNetAddress0); 298 299 int metric = 10; 300 301 RoutingTableEntry entry0(default_address, 302 default_address, 303 gateway_address0, 304 metric, 305 RT_SCOPE_UNIVERSE, 306 true, 307 kTestTableId, 308 RoutingTableEntry::kDefaultTag); 309 // Add a single entry. 310 SendRouteEntry(RTNLMessage::kModeAdd, 311 kTestDeviceIndex0, 312 entry0); 313 314 std::unordered_map<int, vector<RoutingTableEntry>>* tables = 315 GetRoutingTables(); 316 317 // We should have a single table, which should in turn have a single entry. 318 EXPECT_EQ(1, tables->size()); 319 EXPECT_TRUE(ContainsKey(*tables, kTestDeviceIndex0)); 320 EXPECT_EQ(1, (*tables)[kTestDeviceIndex0].size()); 321 322 RoutingTableEntry test_entry = (*tables)[kTestDeviceIndex0][0]; 323 EXPECT_TRUE(entry0.Equals(test_entry)); 324 325 // Add a second entry for a different interface. 326 SendRouteEntry(RTNLMessage::kModeAdd, 327 kTestDeviceIndex1, 328 entry0); 329 330 // We should have two tables, which should have a single entry each. 331 EXPECT_EQ(2, tables->size()); 332 EXPECT_TRUE(ContainsKey(*tables, kTestDeviceIndex1)); 333 EXPECT_EQ(1, (*tables)[kTestDeviceIndex0].size()); 334 EXPECT_EQ(1, (*tables)[kTestDeviceIndex1].size()); 335 336 test_entry = (*tables)[kTestDeviceIndex1][0]; 337 EXPECT_TRUE(entry0.Equals(test_entry)); 338 339 IPAddress gateway_address1(IPAddress::kFamilyIPv4); 340 gateway_address1.SetAddressFromString(kTestNetAddress1); 341 342 RoutingTableEntry entry1(default_address, 343 default_address, 344 gateway_address1, 345 metric, 346 RT_SCOPE_UNIVERSE, 347 true); 348 349 // Add a second gateway route to the second interface. 350 SendRouteEntry(RTNLMessage::kModeAdd, 351 kTestDeviceIndex1, 352 entry1); 353 354 // We should have two tables, one of which has a single entry, the other has 355 // two. 356 EXPECT_EQ(2, tables->size()); 357 EXPECT_EQ(1, (*tables)[kTestDeviceIndex0].size()); 358 EXPECT_EQ(2, (*tables)[kTestDeviceIndex1].size()); 359 360 test_entry = (*tables)[kTestDeviceIndex1][1]; 361 EXPECT_TRUE(entry1.Equals(test_entry)); 362 363 // Remove the first gateway route from the second interface. 364 SendRouteEntry(RTNLMessage::kModeDelete, 365 kTestDeviceIndex1, 366 entry0); 367 368 // We should be back to having one route per table. 369 EXPECT_EQ(2, tables->size()); 370 EXPECT_EQ(1, (*tables)[kTestDeviceIndex0].size()); 371 EXPECT_EQ(1, (*tables)[kTestDeviceIndex1].size()); 372 373 test_entry = (*tables)[kTestDeviceIndex1][0]; 374 EXPECT_TRUE(entry1.Equals(test_entry)); 375 376 // Send a duplicate of the second gateway route message, changing the metric. 377 RoutingTableEntry entry2(entry1); 378 entry2.metric++; 379 SendRouteEntry(RTNLMessage::kModeAdd, 380 kTestDeviceIndex1, 381 entry2); 382 383 // Routing table size shouldn't change, but the new metric should match. 384 EXPECT_EQ(1, (*tables)[kTestDeviceIndex1].size()); 385 test_entry = (*tables)[kTestDeviceIndex1][0]; 386 EXPECT_TRUE(entry2.Equals(test_entry)); 387 388 // Find a matching entry. 389 EXPECT_TRUE(routing_table_->GetDefaultRoute(kTestDeviceIndex1, 390 IPAddress::kFamilyIPv4, 391 &test_entry)); 392 EXPECT_TRUE(entry2.Equals(test_entry)); 393 394 // Test that a search for a non-matching family fails. 395 EXPECT_FALSE(routing_table_->GetDefaultRoute(kTestDeviceIndex1, 396 IPAddress::kFamilyIPv6, 397 &test_entry)); 398 399 // Remove last entry from an existing interface and test that we now fail. 400 SendRouteEntry(RTNLMessage::kModeDelete, 401 kTestDeviceIndex1, 402 entry2); 403 404 EXPECT_FALSE(routing_table_->GetDefaultRoute(kTestDeviceIndex1, 405 IPAddress::kFamilyIPv4, 406 &test_entry)); 407 408 // Add a route to a gateway address. 409 IPAddress gateway_address(IPAddress::kFamilyIPv4); 410 EXPECT_TRUE(gateway_address.SetAddressFromString(kTestNetAddress0)); 411 412 EXPECT_CALL(rtnl_handler_, 413 SendMessage(IsRoutingPacket(RTNLMessage::kModeAdd, 414 kTestDeviceIndex1, 415 entry0, 416 NLM_F_CREATE | NLM_F_EXCL))); 417 EXPECT_TRUE(routing_table_->SetDefaultRoute(kTestDeviceIndex1, 418 gateway_address, 419 metric, 420 kTestTableId)); 421 422 // The table entry should look much like entry0, except with 423 // from_rtnl = false. 424 RoutingTableEntry entry3(entry0); 425 entry3.from_rtnl = false; 426 EXPECT_TRUE(routing_table_->GetDefaultRoute(kTestDeviceIndex1, 427 IPAddress::kFamilyIPv4, 428 &test_entry)); 429 EXPECT_TRUE(entry3.Equals(test_entry)); 430 431 // Setting the same route on the interface with a different metric should 432 // push the route with different flags to indicate we are replacing it, 433 // then it should delete the old entry. 434 RoutingTableEntry entry4(entry3); 435 entry4.metric += 10; 436 EXPECT_CALL(rtnl_handler_, 437 SendMessage(IsRoutingPacket(RTNLMessage::kModeAdd, 438 kTestDeviceIndex1, 439 entry4, 440 NLM_F_CREATE | NLM_F_REPLACE))); 441 EXPECT_CALL(rtnl_handler_, 442 SendMessage(IsRoutingPacket(RTNLMessage::kModeDelete, 443 kTestDeviceIndex1, 444 entry3, 445 0))); 446 EXPECT_TRUE(routing_table_->SetDefaultRoute(kTestDeviceIndex1, 447 gateway_address, 448 entry4.metric, 449 kTestTableId)); 450 451 // Test that removing the table causes the route to disappear. 452 routing_table_->ResetTable(kTestDeviceIndex1); 453 EXPECT_FALSE(ContainsKey(*tables, kTestDeviceIndex1)); 454 EXPECT_FALSE(routing_table_->GetDefaultRoute(kTestDeviceIndex1, 455 IPAddress::kFamilyIPv4, 456 &test_entry)); 457 EXPECT_EQ(1, GetRoutingTables()->size()); 458 459 // When we set the metric on an existing route, a new add and delete 460 // operation should occur. 461 RoutingTableEntry entry5(entry4); 462 entry5.metric += 10; 463 EXPECT_CALL(rtnl_handler_, 464 SendMessage(IsRoutingPacket(RTNLMessage::kModeAdd, 465 kTestDeviceIndex0, 466 entry5, 467 NLM_F_CREATE | NLM_F_REPLACE))); 468 EXPECT_CALL(rtnl_handler_, 469 SendMessage(IsRoutingPacket(RTNLMessage::kModeDelete, 470 kTestDeviceIndex0, 471 entry0, 472 0))); 473 routing_table_->SetDefaultMetric(kTestDeviceIndex0, entry5.metric); 474 // Furthermore, the routing table should reflect the change in the metric 475 // for the default route for the interface. 476 RoutingTableEntry default_route; 477 EXPECT_TRUE(routing_table_->GetDefaultRoute(kTestDeviceIndex0, 478 IPAddress::kFamilyIPv4, 479 &default_route)); 480 EXPECT_EQ(entry5.metric, default_route.metric); 481 482 // Ask to flush table0. We should see a delete message sent. 483 EXPECT_CALL(rtnl_handler_, 484 SendMessage(IsRoutingPacket(RTNLMessage::kModeDelete, 485 kTestDeviceIndex0, 486 entry5, 487 0))); 488 routing_table_->FlushRoutes(kTestDeviceIndex0); 489 EXPECT_EQ(0, (*tables)[kTestDeviceIndex0].size()); 490 491 // Test that the routing table size returns to zero. 492 SendRouteEntry(RTNLMessage::kModeAdd, 493 kTestDeviceIndex0, 494 entry5); 495 EXPECT_EQ(1, GetRoutingTables()->size()); 496 routing_table_->ResetTable(kTestDeviceIndex0); 497 EXPECT_EQ(0, GetRoutingTables()->size()); 498 499 routing_table_->Stop(); 500} 501 502TEST_F(RoutingTableTest, ConfigureRoutes) { 503 MockControl control; 504 IPConfigRefPtr ipconfig(new IPConfig(&control, kTestDeviceName0)); 505 IPConfig::Properties properties; 506 properties.address_family = IPAddress::kFamilyIPv4; 507 vector<IPConfig::Route>& routes = properties.routes; 508 ipconfig->UpdateProperties(properties, true); 509 510 const int kMetric = 10; 511 EXPECT_TRUE(routing_table_->ConfigureRoutes(kTestDeviceIndex0, 512 ipconfig, 513 kMetric, 514 kTestTableId)); 515 516 IPConfig::Route route; 517 route.host = kTestRemoteNetwork4; 518 route.netmask = kTestRemoteNetmask4; 519 route.gateway = kTestGatewayAddress4; 520 routes.push_back(route); 521 ipconfig->UpdateProperties(properties, true); 522 523 IPAddress destination_address(IPAddress::kFamilyIPv4); 524 IPAddress source_address(IPAddress::kFamilyIPv4); 525 IPAddress gateway_address(IPAddress::kFamilyIPv4); 526 ASSERT_TRUE(destination_address.SetAddressFromString(kTestRemoteNetwork4)); 527 destination_address.set_prefix(kTestRemotePrefix4); 528 ASSERT_TRUE(gateway_address.SetAddressFromString(kTestGatewayAddress4)); 529 530 RoutingTableEntry entry(destination_address, 531 source_address, 532 gateway_address, 533 kMetric, 534 RT_SCOPE_UNIVERSE, 535 false, 536 kTestTableId, 537 RoutingTableEntry::kDefaultTag); 538 539 EXPECT_CALL(rtnl_handler_, 540 SendMessage(IsRoutingPacket(RTNLMessage::kModeAdd, 541 kTestDeviceIndex0, 542 entry, 543 NLM_F_CREATE | NLM_F_EXCL))); 544 EXPECT_TRUE(routing_table_->ConfigureRoutes(kTestDeviceIndex0, 545 ipconfig, 546 kMetric, 547 kTestTableId)); 548 549 routes.clear(); 550 route.gateway = "xxx"; // Invalid gateway entry -- should be skipped 551 routes.push_back(route); 552 route.host = "xxx"; // Invalid host entry -- should be skipped 553 route.gateway = kTestGatewayAddress4; 554 routes.push_back(route); 555 route.host = kTestRemoteNetwork4; 556 routes.push_back(route); 557 ipconfig->UpdateProperties(properties, true); 558 559 EXPECT_CALL(rtnl_handler_, 560 SendMessage(IsRoutingPacket(RTNLMessage::kModeAdd, 561 kTestDeviceIndex0, 562 entry, 563 NLM_F_CREATE | NLM_F_EXCL))) 564 .Times(1); 565 EXPECT_FALSE(routing_table_->ConfigureRoutes(kTestDeviceIndex0, 566 ipconfig, 567 kMetric, 568 kTestTableId)); 569} 570 571MATCHER_P2(IsRoutingQuery, destination, index, "") { 572 const RTNLMessage::RouteStatus& status = arg->route_status(); 573 574 uint32_t oif; 575 576 return 577 arg->type() == RTNLMessage::kTypeRoute && 578 arg->family() == destination.family() && 579 arg->flags() == NLM_F_REQUEST && 580 status.table == 0 && 581 status.protocol == 0 && 582 status.scope == 0 && 583 status.type == 0 && 584 arg->HasAttribute(RTA_DST) && 585 IPAddress(arg->family(), 586 arg->GetAttribute(RTA_DST), 587 status.dst_prefix).Equals(destination) && 588 !arg->HasAttribute(RTA_SRC) && 589 !arg->HasAttribute(RTA_GATEWAY) && 590 arg->GetAttribute(RTA_OIF).ConvertToCPUUInt32(&oif) && 591 oif == index && 592 !arg->HasAttribute(RTA_PRIORITY); 593 594 return false; 595} 596 597TEST_F(RoutingTableTest, RequestHostRoute) { 598 IPAddress destination_address(IPAddress::kFamilyIPv4); 599 destination_address.SetAddressFromString(kTestRemoteAddress4); 600 destination_address.set_prefix(24); 601 602 EXPECT_CALL(rtnl_handler_, 603 SendMessage(IsRoutingQuery(destination_address, 604 kTestDeviceIndex0))) 605 .WillOnce(Invoke(this, &RoutingTableTest::SetSequenceForMessage)); 606 EXPECT_TRUE( 607 routing_table_->RequestRouteToHost(destination_address, 608 kTestDeviceIndex0, 609 kTestRouteTag, 610 RoutingTable::Query::Callback(), 611 kTestTableId)); 612 613 IPAddress gateway_address(IPAddress::kFamilyIPv4); 614 gateway_address.SetAddressFromString(kTestGatewayAddress4); 615 616 IPAddress local_address(IPAddress::kFamilyIPv4); 617 local_address.SetAddressFromString(kTestDeviceNetAddress4); 618 619 const int kMetric = 10; 620 RoutingTableEntry entry(destination_address, 621 local_address, 622 gateway_address, 623 kMetric, 624 RT_SCOPE_UNIVERSE, 625 true, 626 kTestTableId, 627 RoutingTableEntry::kDefaultTag); 628 629 EXPECT_CALL(rtnl_handler_, 630 SendMessage(IsRoutingPacket(RTNLMessage::kModeAdd, 631 kTestDeviceIndex0, 632 entry, 633 NLM_F_CREATE | NLM_F_EXCL))); 634 SendRouteEntryWithSeqAndProto(RTNLMessage::kModeAdd, 635 kTestDeviceIndex0, 636 entry, 637 kTestRequestSeq, 638 RTPROT_UNSPEC); 639 640 std::unordered_map<int, vector<RoutingTableEntry>>* tables = 641 GetRoutingTables(); 642 643 // We should have a single table, which should in turn have a single entry. 644 EXPECT_EQ(1, tables->size()); 645 EXPECT_TRUE(ContainsKey(*tables, kTestDeviceIndex0)); 646 EXPECT_EQ(1, (*tables)[kTestDeviceIndex0].size()); 647 648 // This entry's tag should match the tag we requested. 649 EXPECT_EQ(kTestRouteTag, (*tables)[kTestDeviceIndex0][0].tag); 650 651 EXPECT_TRUE(GetQueries()->empty()); 652 653 // Ask to flush routes with our tag. We should see a delete message sent. 654 EXPECT_CALL(rtnl_handler_, 655 SendMessage(IsRoutingPacket(RTNLMessage::kModeDelete, 656 kTestDeviceIndex0, 657 entry, 658 0))); 659 660 routing_table_->FlushRoutesWithTag(kTestRouteTag); 661 662 // After flushing routes for this tag, we should end up with no routes. 663 EXPECT_EQ(0, (*tables)[kTestDeviceIndex0].size()); 664} 665 666TEST_F(RoutingTableTest, RequestHostRouteWithoutGateway) { 667 IPAddress destination_address(IPAddress::kFamilyIPv4); 668 destination_address.SetAddressFromString(kTestRemoteAddress4); 669 destination_address.set_prefix(24); 670 671 EXPECT_CALL(rtnl_handler_, 672 SendMessage(IsRoutingQuery(destination_address, 673 kTestDeviceIndex0))) 674 .WillOnce(Invoke(this, &RoutingTableTest::SetSequenceForMessage)); 675 EXPECT_TRUE( 676 routing_table_->RequestRouteToHost(destination_address, 677 kTestDeviceIndex0, 678 kTestRouteTag, 679 RoutingTable::Query::Callback(), 680 kTestTableId)); 681 682 // Don't specify a gateway address. 683 IPAddress gateway_address(IPAddress::kFamilyIPv4); 684 685 IPAddress local_address(IPAddress::kFamilyIPv4); 686 local_address.SetAddressFromString(kTestDeviceNetAddress4); 687 688 const int kMetric = 10; 689 RoutingTableEntry entry(destination_address, 690 local_address, 691 gateway_address, 692 kMetric, 693 RT_SCOPE_UNIVERSE, 694 true); 695 696 // Ensure that without a gateway entry, we don't create a route. 697 EXPECT_CALL(rtnl_handler_, SendMessage(_)).Times(0); 698 SendRouteEntryWithSeqAndProto(RTNLMessage::kModeAdd, 699 kTestDeviceIndex0, 700 entry, 701 kTestRequestSeq, 702 RTPROT_UNSPEC); 703 EXPECT_TRUE(GetQueries()->empty()); 704} 705 706TEST_F(RoutingTableTest, RequestHostRouteBadSequence) { 707 IPAddress destination_address(IPAddress::kFamilyIPv4); 708 destination_address.SetAddressFromString(kTestRemoteAddress4); 709 QueryCallbackTarget target; 710 EXPECT_CALL(target, MockedTarget(_, _)).Times(0); 711 EXPECT_CALL(rtnl_handler_, SendMessage(_)) 712 .WillOnce(Invoke(this, &RoutingTableTest::SetSequenceForMessage)); 713 EXPECT_TRUE( 714 routing_table_->RequestRouteToHost(destination_address, 715 kTestDeviceIndex0, 716 kTestRouteTag, 717 target.mocked_callback(), 718 kTestTableId)); 719 EXPECT_FALSE(GetQueries()->empty()); 720 721 RoutingTableEntry entry(destination_address, 722 destination_address, 723 destination_address, 724 0, 725 RT_SCOPE_UNIVERSE, 726 true); 727 728 // Try a sequence arriving before the one RoutingTable is looking for. 729 // This should be a no-op. 730 SendRouteEntryWithSeqAndProto(RTNLMessage::kModeAdd, 731 kTestDeviceIndex0, 732 entry, 733 kTestRequestSeq - 1, 734 RTPROT_UNSPEC); 735 EXPECT_FALSE(GetQueries()->empty()); 736 737 // Try a sequence arriving after the one RoutingTable is looking for. 738 // This should cause the request to be purged. 739 SendRouteEntryWithSeqAndProto(RTNLMessage::kModeAdd, 740 kTestDeviceIndex0, 741 entry, 742 kTestRequestSeq + 1, 743 RTPROT_UNSPEC); 744 EXPECT_TRUE(GetQueries()->empty()); 745} 746 747TEST_F(RoutingTableTest, RequestHostRouteWithCallback) { 748 IPAddress destination_address(IPAddress::kFamilyIPv4); 749 750 EXPECT_CALL(rtnl_handler_, SendMessage(_)) 751 .WillOnce(Invoke(this, &RoutingTableTest::SetSequenceForMessage)); 752 QueryCallbackTarget target; 753 EXPECT_TRUE( 754 routing_table_->RequestRouteToHost(destination_address, 755 -1, 756 kTestRouteTag, 757 target.mocked_callback(), 758 kTestTableId)); 759 760 IPAddress gateway_address(IPAddress::kFamilyIPv4); 761 gateway_address.SetAddressFromString(kTestGatewayAddress4); 762 763 const int kMetric = 10; 764 RoutingTableEntry entry(destination_address, 765 IPAddress(IPAddress::kFamilyIPv4), 766 gateway_address, 767 kMetric, 768 RT_SCOPE_UNIVERSE, 769 true); 770 771 EXPECT_CALL(rtnl_handler_, SendMessage(_)); 772 EXPECT_CALL(target, 773 MockedTarget(kTestDeviceIndex0, 774 Field(&RoutingTableEntry::tag, kTestRouteTag))); 775 SendRouteEntryWithSeqAndProto(RTNLMessage::kModeAdd, 776 kTestDeviceIndex0, 777 entry, 778 kTestRequestSeq, 779 RTPROT_UNSPEC); 780} 781 782TEST_F(RoutingTableTest, RequestHostRouteWithoutGatewayWithCallback) { 783 IPAddress destination_address(IPAddress::kFamilyIPv4); 784 785 EXPECT_CALL(rtnl_handler_, SendMessage(_)) 786 .WillOnce(Invoke(this, &RoutingTableTest::SetSequenceForMessage)); 787 QueryCallbackTarget target; 788 EXPECT_TRUE( 789 routing_table_->RequestRouteToHost(destination_address, 790 -1, 791 kTestRouteTag, 792 target.mocked_callback(), 793 kTestTableId)); 794 795 const int kMetric = 10; 796 RoutingTableEntry entry(destination_address, 797 IPAddress(IPAddress::kFamilyIPv4), 798 IPAddress(IPAddress::kFamilyIPv4), 799 kMetric, 800 RT_SCOPE_UNIVERSE, 801 true); 802 803 EXPECT_CALL(target, 804 MockedTarget(kTestDeviceIndex0, 805 Field(&RoutingTableEntry::tag, kTestRouteTag))); 806 SendRouteEntryWithSeqAndProto(RTNLMessage::kModeAdd, 807 kTestDeviceIndex0, 808 entry, 809 kTestRequestSeq, 810 RTPROT_UNSPEC); 811} 812 813TEST_F(RoutingTableTest, CancelQueryCallback) { 814 IPAddress destination_address(IPAddress::kFamilyIPv4); 815 destination_address.SetAddressFromString(kTestRemoteAddress4); 816 std::unique_ptr<QueryCallbackTarget> target(new QueryCallbackTarget()); 817 EXPECT_CALL(rtnl_handler_, SendMessage(_)) 818 .WillOnce(Invoke(this, &RoutingTableTest::SetSequenceForMessage)); 819 EXPECT_TRUE( 820 routing_table_->RequestRouteToHost(destination_address, 821 kTestDeviceIndex0, 822 kTestRouteTag, 823 target->unreached_callback(), 824 kTestTableId)); 825 ASSERT_EQ(1, GetQueries()->size()); 826 // Cancels the callback by destroying the owner object. 827 target.reset(); 828 const int kMetric = 10; 829 RoutingTableEntry entry(IPAddress(IPAddress::kFamilyIPv4), 830 IPAddress(IPAddress::kFamilyIPv4), 831 IPAddress(IPAddress::kFamilyIPv4), 832 kMetric, 833 RT_SCOPE_UNIVERSE, 834 true); 835 SendRouteEntryWithSeqAndProto(RTNLMessage::kModeAdd, 836 kTestDeviceIndex0, 837 entry, 838 kTestRequestSeq, 839 RTPROT_UNSPEC); 840} 841 842TEST_F(RoutingTableTest, CreateBlackholeRoute) { 843 const uint32_t kMetric = 2; 844 EXPECT_CALL(rtnl_handler_, 845 SendMessage(IsBlackholeRoutingPacket(kTestDeviceIndex0, 846 IPAddress::kFamilyIPv6, 847 kMetric))) 848 .Times(1); 849 EXPECT_TRUE(routing_table_->CreateBlackholeRoute(kTestDeviceIndex0, 850 IPAddress::kFamilyIPv6, 851 kMetric, 852 kTestTableId)); 853} 854 855TEST_F(RoutingTableTest, CreateLinkRoute) { 856 IPAddress local_address(IPAddress::kFamilyIPv4); 857 ASSERT_TRUE(local_address.SetAddressFromString(kTestNetAddress0)); 858 local_address.set_prefix(kTestRemotePrefix4); 859 IPAddress remote_address(IPAddress::kFamilyIPv4); 860 ASSERT_TRUE(remote_address.SetAddressFromString(kTestNetAddress1)); 861 IPAddress default_address(IPAddress::kFamilyIPv4); 862 IPAddress remote_address_with_prefix(remote_address); 863 remote_address_with_prefix.set_prefix( 864 IPAddress::GetMaxPrefixLength(remote_address_with_prefix.family())); 865 RoutingTableEntry entry(remote_address_with_prefix, 866 local_address, 867 default_address, 868 0, 869 RT_SCOPE_LINK, 870 false, 871 kTestTableId, 872 RoutingTableEntry::kDefaultTag); 873 EXPECT_CALL(rtnl_handler_, 874 SendMessage(IsRoutingPacket(RTNLMessage::kModeAdd, 875 kTestDeviceIndex0, 876 entry, 877 NLM_F_CREATE | NLM_F_EXCL))) 878 .Times(1); 879 EXPECT_TRUE(routing_table_->CreateLinkRoute(kTestDeviceIndex0, 880 local_address, 881 remote_address, 882 kTestTableId)); 883 884 ASSERT_TRUE(remote_address.SetAddressFromString(kTestRemoteAddress4)); 885 EXPECT_FALSE(routing_table_->CreateLinkRoute(kTestDeviceIndex0, 886 local_address, 887 remote_address, 888 kTestTableId)); 889} 890 891} // namespace shill 892