blob: 3acc8660c80073a7d47af3fa645b9d4b895fb471 [file] [log] [blame]
Thieu Le3426c8f2012-01-11 17:35:11 -08001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
Paul Stewartdd60e452011-08-08 11:38:36 -07002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Paul Stewart9a908082011-08-31 12:18:48 -07005#include <arpa/inet.h>
6#include <linux/rtnetlink.h>
7
Paul Stewartc8f4bef2011-12-13 09:45:51 -08008#include <string>
Paul Stewart9a908082011-08-31 12:18:48 -07009#include <vector>
10
11#include <base/memory/scoped_ptr.h>
Paul Stewartdd60e452011-08-08 11:38:36 -070012#include <gtest/gtest.h>
13#include <gmock/gmock.h>
14
15#include "shill/connection.h"
Paul Stewartdd60e452011-08-08 11:38:36 -070016#include "shill/ipconfig.h"
17#include "shill/mock_control.h"
Paul Stewartc8f4bef2011-12-13 09:45:51 -080018#include "shill/mock_device.h"
Paul Stewart9a908082011-08-31 12:18:48 -070019#include "shill/mock_device_info.h"
Paul Stewartdd60e452011-08-08 11:38:36 -070020#include "shill/mock_resolver.h"
21#include "shill/mock_routing_table.h"
22#include "shill/mock_rtnl_handler.h"
23#include "shill/routing_table_entry.h"
24
Paul Stewartc8f4bef2011-12-13 09:45:51 -080025using std::string;
Paul Stewart9a908082011-08-31 12:18:48 -070026using std::vector;
Paul Stewartdd60e452011-08-08 11:38:36 -070027using testing::_;
28using testing::NiceMock;
29using testing::Return;
30using testing::StrictMock;
31using testing::Test;
32
33namespace shill {
34
35namespace {
36const char kTestDeviceName0[] = "netdev0";
37const int kTestDeviceInterfaceIndex0 = 123;
38const char kTestDeviceName1[] = "netdev1";
39const int kTestDeviceInterfaceIndex1 = 321;
40const char kIPAddress0[] = "192.168.1.1";
41const char kGatewayAddress0[] = "192.168.1.254";
Paul Stewart5b7ba8c2012-04-18 09:08:00 -070042const char kGatewayAddress1[] = "192.168.2.254";
Paul Stewart9a908082011-08-31 12:18:48 -070043const char kBroadcastAddress0[] = "192.168.1.255";
Paul Stewartdd60e452011-08-08 11:38:36 -070044const char kNameServer0[] = "8.8.8.8";
45const char kNameServer1[] = "8.8.9.9";
Paul Stewart5b7ba8c2012-04-18 09:08:00 -070046const int32 kPrefix0 = 24;
47const int32 kPrefix1 = 31;
Paul Stewartdd60e452011-08-08 11:38:36 -070048const char kSearchDomain0[] = "chromium.org";
49const char kSearchDomain1[] = "google.com";
50} // namespace {}
51
52class ConnectionTest : public Test {
53 public:
54 ConnectionTest()
Paul Stewart9a908082011-08-31 12:18:48 -070055 : device_info_(new StrictMock<MockDeviceInfo>(
56 &control_,
57 static_cast<EventDispatcher*>(NULL),
Thieu Le3426c8f2012-01-11 17:35:11 -080058 static_cast<Metrics*>(NULL),
Paul Stewart9a908082011-08-31 12:18:48 -070059 static_cast<Manager*>(NULL))),
60 connection_(new Connection(
61 kTestDeviceInterfaceIndex0,
62 kTestDeviceName0,
Paul Stewarte00600e2012-03-16 07:08:00 -070063 Technology::kUnknown,
Paul Stewart9a908082011-08-31 12:18:48 -070064 device_info_.get())),
Paul Stewart5b7ba8c2012-04-18 09:08:00 -070065 ipconfig_(new IPConfig(&control_, kTestDeviceName0)),
66 local_address_(IPAddress::kFamilyIPv4),
67 broadcast_address_(IPAddress::kFamilyIPv4),
68 gateway_address_(IPAddress::kFamilyIPv4),
69 default_address_(IPAddress::kFamilyIPv4) {}
Paul Stewartdd60e452011-08-08 11:38:36 -070070
71 virtual void SetUp() {
Paul Stewartc8f4bef2011-12-13 09:45:51 -080072 ReplaceSingletons(connection_);
Paul Stewart5b7ba8c2012-04-18 09:08:00 -070073 properties_.address = kIPAddress0;
74 properties_.subnet_prefix = kPrefix0;
75 properties_.gateway = kGatewayAddress0;
76 properties_.broadcast_address = kBroadcastAddress0;
77 properties_.dns_servers.push_back(kNameServer0);
78 properties_.dns_servers.push_back(kNameServer1);
79 properties_.domain_search.push_back(kSearchDomain0);
80 properties_.domain_search.push_back(kSearchDomain1);
81 properties_.address_family = IPAddress::kFamilyIPv4;
82 UpdateProperties();
83 EXPECT_TRUE(local_address_.SetAddressFromString(kIPAddress0));
84 EXPECT_TRUE(broadcast_address_.SetAddressFromString(kBroadcastAddress0));
85 EXPECT_TRUE(gateway_address_.SetAddressFromString(kGatewayAddress0));
Paul Stewartdd60e452011-08-08 11:38:36 -070086 }
87
Paul Stewart9a908082011-08-31 12:18:48 -070088 virtual void TearDown() {
89 EXPECT_CALL(*device_info_, FlushAddresses(kTestDeviceInterfaceIndex0));
90 }
91
Paul Stewartc8f4bef2011-12-13 09:45:51 -080092 void ReplaceSingletons(ConnectionRefPtr connection) {
93 connection->resolver_ = &resolver_;
94 connection->routing_table_ = &routing_table_;
95 connection->rtnl_handler_ = &rtnl_handler_;
96 }
97
Paul Stewart5b7ba8c2012-04-18 09:08:00 -070098 void UpdateProperties() {
99 ipconfig_->UpdateProperties(properties_, true);
100 }
101
Paul Stewartdd60e452011-08-08 11:38:36 -0700102 protected:
Paul Stewart9a908082011-08-31 12:18:48 -0700103 scoped_ptr<StrictMock<MockDeviceInfo> > device_info_;
Paul Stewartdd60e452011-08-08 11:38:36 -0700104 ConnectionRefPtr connection_;
105 MockControl control_;
106 IPConfigRefPtr ipconfig_;
Paul Stewart5b7ba8c2012-04-18 09:08:00 -0700107 IPConfig::Properties properties_;
108 IPAddress local_address_;
109 IPAddress broadcast_address_;
110 IPAddress gateway_address_;
111 IPAddress default_address_;
Paul Stewartdd60e452011-08-08 11:38:36 -0700112 StrictMock<MockResolver> resolver_;
113 StrictMock<MockRoutingTable> routing_table_;
114 StrictMock<MockRTNLHandler> rtnl_handler_;
115};
116
117TEST_F(ConnectionTest, InitState) {
118 EXPECT_EQ(kTestDeviceInterfaceIndex0, connection_->interface_index_);
119 EXPECT_EQ(kTestDeviceName0, connection_->interface_name_);
120 EXPECT_FALSE(connection_->is_default());
Paul Stewartc8f4bef2011-12-13 09:45:51 -0800121 EXPECT_FALSE(connection_->routing_request_count_);
Paul Stewartdd60e452011-08-08 11:38:36 -0700122}
123
Paul Stewart5b7ba8c2012-04-18 09:08:00 -0700124MATCHER_P2(IsIPAddress, address, prefix, "") {
125 IPAddress match_address(address);
126 match_address.set_prefix(prefix);
127 return match_address.Equals(arg);
128}
129
Paul Stewartdd60e452011-08-08 11:38:36 -0700130TEST_F(ConnectionTest, AddConfig) {
131 EXPECT_CALL(rtnl_handler_,
Paul Stewart5b7ba8c2012-04-18 09:08:00 -0700132 AddInterfaceAddress(kTestDeviceInterfaceIndex0,
133 IsIPAddress(local_address_, kPrefix0),
134 IsIPAddress(broadcast_address_, 0),
135 IsIPAddress(default_address_, 0)));
Paul Stewart7cfca042011-12-08 14:18:17 -0800136 EXPECT_CALL(routing_table_,
137 SetDefaultRoute(kTestDeviceInterfaceIndex0,
Paul Stewart5b7ba8c2012-04-18 09:08:00 -0700138 IsIPAddress(gateway_address_, 0),
Paul Stewart7cfca042011-12-08 14:18:17 -0800139 Connection::kNonDefaultMetricBase +
140 kTestDeviceInterfaceIndex0));
Paul Stewart3f68bb12012-03-15 13:33:10 -0700141 EXPECT_CALL(routing_table_,
142 ConfigureRoutes(kTestDeviceInterfaceIndex0,
143 ipconfig_,
144 Connection::kDefaultMetric));
Paul Stewartdd60e452011-08-08 11:38:36 -0700145 connection_->UpdateFromIPConfig(ipconfig_);
146
147 EXPECT_CALL(routing_table_, SetDefaultMetric(kTestDeviceInterfaceIndex0,
148 Connection::kDefaultMetric));
149 EXPECT_CALL(resolver_, SetDNSFromLists(
150 ipconfig_->properties().dns_servers,
151 ipconfig_->properties().domain_search));
152
Paul Stewartc681fa02012-03-02 19:40:04 -0800153 scoped_refptr<MockDevice> device(new StrictMock<MockDevice>(
154 &control_,
155 reinterpret_cast<EventDispatcher *>(NULL),
156 reinterpret_cast<Metrics *>(NULL),
157 reinterpret_cast<Manager *>(NULL),
158 kTestDeviceName0,
159 string(),
160 kTestDeviceInterfaceIndex0));
161 EXPECT_CALL(*device_info_, GetDevice(kTestDeviceInterfaceIndex0))
162 .WillOnce(Return(device));
163 EXPECT_CALL(*device.get(), RequestPortalDetection())
164 .WillOnce(Return(true));
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800165 connection_->SetIsDefault(true);
Paul Stewartdd60e452011-08-08 11:38:36 -0700166 EXPECT_TRUE(connection_->is_default());
167
Paul Stewart7cfca042011-12-08 14:18:17 -0800168 EXPECT_CALL(routing_table_,
169 SetDefaultMetric(kTestDeviceInterfaceIndex0,
170 Connection::kNonDefaultMetricBase +
171 kTestDeviceInterfaceIndex0));
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800172 connection_->SetIsDefault(false);
Paul Stewartdd60e452011-08-08 11:38:36 -0700173 EXPECT_FALSE(connection_->is_default());
174}
175
Paul Stewart5b7ba8c2012-04-18 09:08:00 -0700176TEST_F(ConnectionTest, AddConfigWithPeer) {
177 const string kPeerAddress("192.168.1.222");
178 IPAddress peer_address(IPAddress::kFamilyIPv4);
179 EXPECT_TRUE(peer_address.SetAddressFromString(kPeerAddress));
180 properties_.peer_address = kPeerAddress;
181 properties_.gateway = string();
182 UpdateProperties();
183 EXPECT_CALL(rtnl_handler_,
184 AddInterfaceAddress(kTestDeviceInterfaceIndex0,
185 IsIPAddress(local_address_, kPrefix0),
186 IsIPAddress(broadcast_address_, 0),
187 IsIPAddress(peer_address, 0)));
188 EXPECT_CALL(routing_table_, SetDefaultRoute(_, _, _)).Times(0);
189 EXPECT_CALL(routing_table_,
190 ConfigureRoutes(kTestDeviceInterfaceIndex0,
191 ipconfig_,
192 Connection::kDefaultMetric));
193 connection_->UpdateFromIPConfig(ipconfig_);
194}
195
196TEST_F(ConnectionTest, AddConfigWithBrokenNetmask) {
197 // Assign a prefix that makes the gateway unreachable.
198 properties_.subnet_prefix = kPrefix1;
199 UpdateProperties();
200
201 // Connection should override with a prefix which will allow the
202 // gateway to be reachable.
203 EXPECT_CALL(rtnl_handler_,
204 AddInterfaceAddress(kTestDeviceInterfaceIndex0,
205 IsIPAddress(local_address_, kPrefix0),
206 IsIPAddress(broadcast_address_, 0),
207 IsIPAddress(default_address_, 0)));
208 EXPECT_CALL(routing_table_,
209 SetDefaultRoute(kTestDeviceInterfaceIndex0,
210 IsIPAddress(gateway_address_, 0),
211 Connection::kNonDefaultMetricBase +
212 kTestDeviceInterfaceIndex0));
213 EXPECT_CALL(routing_table_,
214 ConfigureRoutes(kTestDeviceInterfaceIndex0,
215 ipconfig_,
216 Connection::kDefaultMetric));
217 connection_->UpdateFromIPConfig(ipconfig_);
218
219 // Assign a gateway address that violates the minimum plausible prefix
220 // the Connection can assign.
221 properties_.gateway = kGatewayAddress1;
222 UpdateProperties();
223
224 // Connection cannot override this prefix, so it will revert to the
225 // configured prefix, expecting the default route to fail.
226 EXPECT_CALL(rtnl_handler_,
227 AddInterfaceAddress(kTestDeviceInterfaceIndex0,
228 IsIPAddress(local_address_, kPrefix1),
229 IsIPAddress(broadcast_address_, 0),
230 IsIPAddress(default_address_, 0)));
231 EXPECT_CALL(routing_table_,
232 SetDefaultRoute(kTestDeviceInterfaceIndex0, _, _));
233 EXPECT_CALL(routing_table_,
234 ConfigureRoutes(kTestDeviceInterfaceIndex0, _, _));
235 connection_->UpdateFromIPConfig(ipconfig_);
236}
237
Paul Stewartdd60e452011-08-08 11:38:36 -0700238TEST_F(ConnectionTest, AddConfigReverse) {
239 EXPECT_CALL(routing_table_, SetDefaultMetric(kTestDeviceInterfaceIndex0,
240 Connection::kDefaultMetric));
Paul Stewartc8f4bef2011-12-13 09:45:51 -0800241 vector<string> empty_list;
Paul Stewartdd60e452011-08-08 11:38:36 -0700242 EXPECT_CALL(resolver_, SetDNSFromLists(empty_list, empty_list));
Paul Stewartc681fa02012-03-02 19:40:04 -0800243 scoped_refptr<MockDevice> device(new StrictMock<MockDevice>(
244 &control_,
245 reinterpret_cast<EventDispatcher *>(NULL),
246 reinterpret_cast<Metrics *>(NULL),
247 reinterpret_cast<Manager *>(NULL),
248 kTestDeviceName0,
249 string(),
250 kTestDeviceInterfaceIndex0));
251 EXPECT_CALL(*device_info_, GetDevice(kTestDeviceInterfaceIndex0))
252 .WillOnce(Return(device));
253 EXPECT_CALL(*device.get(), RequestPortalDetection())
254 .WillOnce(Return(true));
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800255 connection_->SetIsDefault(true);
Paul Stewartdd60e452011-08-08 11:38:36 -0700256
257 EXPECT_CALL(rtnl_handler_,
Paul Stewart5b7ba8c2012-04-18 09:08:00 -0700258 AddInterfaceAddress(kTestDeviceInterfaceIndex0,
259 IsIPAddress(local_address_, kPrefix0),
260 IsIPAddress(broadcast_address_, 0),
261 IsIPAddress(default_address_, 0)));
Paul Stewartdd60e452011-08-08 11:38:36 -0700262 EXPECT_CALL(routing_table_, SetDefaultRoute(kTestDeviceInterfaceIndex0,
Paul Stewart5b7ba8c2012-04-18 09:08:00 -0700263 IsIPAddress(gateway_address_, 0),
264 Connection::kDefaultMetric));
Paul Stewart3f68bb12012-03-15 13:33:10 -0700265 EXPECT_CALL(routing_table_,
266 ConfigureRoutes(kTestDeviceInterfaceIndex0,
267 ipconfig_,
268 Connection::kDefaultMetric));
Paul Stewartdd60e452011-08-08 11:38:36 -0700269 EXPECT_CALL(resolver_, SetDNSFromIPConfig(ipconfig_));
270
271 connection_->UpdateFromIPConfig(ipconfig_);
272}
273
Paul Stewartc8f4bef2011-12-13 09:45:51 -0800274TEST_F(ConnectionTest, RouteRequest) {
Paul Stewartf748a362012-03-07 12:01:20 -0800275 ConnectionRefPtr connection(new Connection(kTestDeviceInterfaceIndex0,
276 kTestDeviceName0,
Paul Stewarte00600e2012-03-16 07:08:00 -0700277 Technology::kUnknown,
Paul Stewartf748a362012-03-07 12:01:20 -0800278 device_info_.get()));
279 ReplaceSingletons(connection);
280 scoped_refptr<MockDevice> device(new StrictMock<MockDevice>(
281 &control_,
282 reinterpret_cast<EventDispatcher *>(NULL),
283 reinterpret_cast<Metrics *>(NULL),
284 reinterpret_cast<Manager *>(NULL),
285 kTestDeviceName0,
286 string(),
287 kTestDeviceInterfaceIndex0));
288 EXPECT_CALL(*device_info_, GetDevice(kTestDeviceInterfaceIndex0))
289 .WillRepeatedly(Return(device));
290 EXPECT_CALL(*device.get(), DisableReversePathFilter()).Times(1);
291 connection->RequestRouting();
292 connection->RequestRouting();
Paul Stewartc8f4bef2011-12-13 09:45:51 -0800293
Paul Stewartf748a362012-03-07 12:01:20 -0800294 // The first release should only decrement the reference counter.
295 connection->ReleaseRouting();
Paul Stewartc8f4bef2011-12-13 09:45:51 -0800296
Paul Stewartf748a362012-03-07 12:01:20 -0800297 // Another release will re-enable reverse-path filter.
298 EXPECT_CALL(*device.get(), EnableReversePathFilter());
299 EXPECT_CALL(routing_table_, FlushCache());
300 connection->ReleaseRouting();
Paul Stewartc8f4bef2011-12-13 09:45:51 -0800301
Paul Stewartf748a362012-03-07 12:01:20 -0800302 // The destructor will remove the routes and addresses.
303 EXPECT_CALL(routing_table_, FlushRoutes(kTestDeviceInterfaceIndex0));
304 EXPECT_CALL(*device_info_.get(),
305 FlushAddresses(kTestDeviceInterfaceIndex0));
Paul Stewartc8f4bef2011-12-13 09:45:51 -0800306}
307
Paul Stewartdd60e452011-08-08 11:38:36 -0700308TEST_F(ConnectionTest, Destructor) {
Thieu Lefb46caf2012-03-08 11:57:15 -0800309 EXPECT_CALL(routing_table_, FlushRoutes(kTestDeviceInterfaceIndex1));
Paul Stewart9a908082011-08-31 12:18:48 -0700310 EXPECT_CALL(*device_info_, FlushAddresses(kTestDeviceInterfaceIndex1));
Paul Stewartdd60e452011-08-08 11:38:36 -0700311 {
312 ConnectionRefPtr connection(new Connection(kTestDeviceInterfaceIndex1,
Paul Stewart9a908082011-08-31 12:18:48 -0700313 kTestDeviceName1,
Paul Stewarte00600e2012-03-16 07:08:00 -0700314 Technology::kUnknown,
Paul Stewart9a908082011-08-31 12:18:48 -0700315 device_info_.get()));
Paul Stewartdd60e452011-08-08 11:38:36 -0700316 connection->resolver_ = &resolver_;
317 connection->routing_table_ = &routing_table_;
318 connection->rtnl_handler_ = &rtnl_handler_;
319 }
320}
321
Paul Stewartf748a362012-03-07 12:01:20 -0800322TEST_F(ConnectionTest, RequestHostRoute) {
323 ConnectionRefPtr connection(new Connection(kTestDeviceInterfaceIndex0,
324 kTestDeviceName0,
Paul Stewarte00600e2012-03-16 07:08:00 -0700325 Technology::kUnknown,
Paul Stewartf748a362012-03-07 12:01:20 -0800326 device_info_.get()));
327 ReplaceSingletons(connection);
328 IPAddress address(IPAddress::kFamilyIPv4);
329 ASSERT_TRUE(address.SetAddressFromString(kIPAddress0));
330 size_t prefix_len = address.GetLength() * 8;
331 EXPECT_CALL(routing_table_, RequestRouteToHost(
Paul Stewart536820d2012-03-19 16:05:59 -0700332 IsIPAddress(address, prefix_len), -1))
Paul Stewartf748a362012-03-07 12:01:20 -0800333 .WillOnce(Return(true));
334 EXPECT_TRUE(connection->RequestHostRoute(address));
335
336 // The destructor will remove the routes and addresses.
337 EXPECT_CALL(routing_table_, FlushRoutes(kTestDeviceInterfaceIndex0));
338 EXPECT_CALL(*device_info_.get(),
339 FlushAddresses(kTestDeviceInterfaceIndex0));
340}
341
Paul Stewartdd60e452011-08-08 11:38:36 -0700342} // namespace shill