blob: 4f0c08d5c2ad3e738a2c0e35d6b97ab3dd6ba103 [file] [log] [blame]
Thieu Le3426c8f2012-01-11 17:35:11 -08001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
Paul Stewartb50f0b92011-05-16 16:31:42 -07002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Chris Masoneb2e326b2011-07-12 13:28:51 -07005#include "shill/ethernet.h"
6
Paul Stewartb50f0b92011-05-16 16:31:42 -07007#include <time.h>
8#include <stdio.h>
Paul Stewartf1ce5d22011-05-19 13:10:20 -07009#include <netinet/ether.h>
mukesh agrawal5c4dd0b2011-09-14 13:53:14 -070010#include <linux/if.h> // Needs definitions from netinet/ether.h
Paul Stewartb50f0b92011-05-16 16:31:42 -070011
12#include <string>
13
Eric Shienbrood9a245532012-03-07 14:20:39 -050014#include "shill/adaptor_interfaces.h"
Paul Stewartb50f0b92011-05-16 16:31:42 -070015#include "shill/control_interface.h"
16#include "shill/device.h"
Paul Stewartf1ce5d22011-05-19 13:10:20 -070017#include "shill/device_info.h"
Paul Stewartf1ce5d22011-05-19 13:10:20 -070018#include "shill/ethernet_service.h"
Paul Stewart26b327e2011-10-19 11:38:09 -070019#include "shill/event_dispatcher.h"
Christopher Wileyb691efd2012-08-09 13:51:51 -070020#include "shill/logging.h"
Paul Stewart26b327e2011-10-19 11:38:09 -070021#include "shill/manager.h"
Chris Masone7aa5f902011-07-11 11:13:35 -070022#include "shill/profile.h"
Paul Stewartf1ce5d22011-05-19 13:10:20 -070023#include "shill/rtnl_handler.h"
Paul Stewartb50f0b92011-05-16 16:31:42 -070024
Chris Masonea82b7112011-05-25 15:16:29 -070025using std::string;
26
Paul Stewartb50f0b92011-05-16 16:31:42 -070027namespace shill {
Darin Petkovafa6fc42011-06-21 16:21:08 -070028
Paul Stewartb50f0b92011-05-16 16:31:42 -070029Ethernet::Ethernet(ControlInterface *control_interface,
30 EventDispatcher *dispatcher,
Thieu Le3426c8f2012-01-11 17:35:11 -080031 Metrics *metrics,
Paul Stewartf1ce5d22011-05-19 13:10:20 -070032 Manager *manager,
Darin Petkovafa6fc42011-06-21 16:21:08 -070033 const string &link_name,
mukesh agrawal93a29ed2012-04-17 16:13:01 -070034 const string &address,
Paul Stewartb50f0b92011-05-16 16:31:42 -070035 int interface_index)
Chris Masonea82b7112011-05-25 15:16:29 -070036 : Device(control_interface,
37 dispatcher,
Thieu Le3426c8f2012-01-11 17:35:11 -080038 metrics,
Chris Masonea82b7112011-05-25 15:16:29 -070039 manager,
40 link_name,
Chris Masone626719f2011-08-18 16:58:48 -070041 address,
Gaurav Shah435de2c2011-11-17 19:01:07 -080042 interface_index,
43 Technology::kEthernet),
mukesh agrawalf60e4062011-05-27 13:13:41 -070044 link_up_(false) {
Ben Chanfad4a0b2012-04-18 15:49:59 -070045 SLOG(Ethernet, 2) << "Ethernet device " << link_name << " initialized.";
Paul Stewartb50f0b92011-05-16 16:31:42 -070046}
47
48Ethernet::~Ethernet() {
Eric Shienbrood9a245532012-03-07 14:20:39 -050049 Stop(NULL, EnabledStateChangedCallback());
Paul Stewartf1ce5d22011-05-19 13:10:20 -070050}
51
Eric Shienbrood9a245532012-03-07 14:20:39 -050052void Ethernet::Start(Error *error,
53 const EnabledStateChangedCallback &callback) {
Paul Stewart2713d6c2011-08-25 15:38:15 -070054 service_ = new EthernetService(control_interface(),
55 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -080056 metrics(),
Paul Stewart2713d6c2011-08-25 15:38:15 -070057 manager(),
58 this);
Paul Stewartac4ac002011-08-26 12:04:26 -070059 RTNLHandler::GetInstance()->SetInterfaceFlags(interface_index(), IFF_UP,
Paul Stewartf1ce5d22011-05-19 13:10:20 -070060 IFF_UP);
Eric Shienbrood9a245532012-03-07 14:20:39 -050061 OnEnabledStateChanged(EnabledStateChangedCallback(), Error());
62 if (error)
63 error->Reset(); // indicate immediate completion
Paul Stewartf1ce5d22011-05-19 13:10:20 -070064}
65
Eric Shienbrood9a245532012-03-07 14:20:39 -050066void Ethernet::Stop(Error *error, const EnabledStateChangedCallback &callback) {
Paul Stewartf2792e82011-12-12 10:23:11 -080067 if (service_) {
68 manager()->DeregisterService(service_);
69 service_ = NULL;
70 }
Eric Shienbrood9a245532012-03-07 14:20:39 -050071 OnEnabledStateChanged(EnabledStateChangedCallback(), Error());
72 if (error)
73 error->Reset(); // indicate immediate completion
Paul Stewartb50f0b92011-05-16 16:31:42 -070074}
75
Darin Petkovafa6fc42011-06-21 16:21:08 -070076void Ethernet::LinkEvent(unsigned int flags, unsigned int change) {
Paul Stewartf1ce5d22011-05-19 13:10:20 -070077 Device::LinkEvent(flags, change);
78 if ((flags & IFF_LOWER_UP) != 0 && !link_up_) {
Paul Stewartf1ce5d22011-05-19 13:10:20 -070079 link_up_ = true;
Eric Shienbrood9a245532012-03-07 14:20:39 -050080 if (service_) {
Christopher Wiley2f1bbf02012-10-25 15:31:13 -070081 LOG(INFO) << "Registering " << link_name() << " with manager.";
82 // Manager will bring up L3 for us.
Eric Shienbrood9a245532012-03-07 14:20:39 -050083 manager()->RegisterService(service_);
Darin Petkovafa6fc42011-06-21 16:21:08 -070084 }
Paul Stewartf1ce5d22011-05-19 13:10:20 -070085 } else if ((flags & IFF_LOWER_UP) == 0 && link_up_) {
86 link_up_ = false;
Paul Stewart63c93932012-01-06 11:24:12 -080087 DestroyIPConfig();
Thieu Le9c497072012-10-31 14:06:20 -070088 if (service_)
89 manager()->DeregisterService(service_);
Paul Stewart03dba0b2011-08-22 16:32:45 -070090 SelectService(NULL);
Paul Stewartf1ce5d22011-05-19 13:10:20 -070091 }
92}
93
Christopher Wiley2f1bbf02012-10-25 15:31:13 -070094void Ethernet::ConnectTo(EthernetService *service) {
95 CHECK(service == service_.get()) << "Ethernet was asked to connect the "
96 << "wrong service?";
97 if (AcquireIPConfigWithLeaseName(service->GetStorageIdentifier())) {
98 SelectService(service);
99 SetServiceState(Service::kStateConfiguring);
100 } else {
101 LOG(ERROR) << "Unable to acquire DHCP config.";
102 SetServiceState(Service::kStateFailure);
103 }
104}
105
106void Ethernet::DisconnectFrom(EthernetService *service) {
107 CHECK(service == service_.get()) << "Ethernet was asked to disconnect the "
108 << "wrong service?";
109 DropConnection();
110}
111
Paul Stewartb50f0b92011-05-16 16:31:42 -0700112} // namespace shill