blob: edebd7a595d004b2d3941ecc08b00b6680eb3979 [file] [log] [blame]
Kevin Cernekee95d4ae92016-06-19 10:26:29 -07001// Copyright 2016 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Garrick Evans3388a032020-03-24 11:25:55 +09005#ifndef PATCHPANEL_SHILL_CLIENT_H_
6#define PATCHPANEL_SHILL_CLIENT_H_
Kevin Cernekee95d4ae92016-06-19 10:26:29 -07007
Jie Jiang850a4712020-04-08 21:06:36 +09008#include <map>
Kevin Cernekee95d4ae92016-06-19 10:26:29 -07009#include <memory>
Garrick Evans49879532018-12-03 13:15:36 +090010#include <set>
Kevin Cernekee95d4ae92016-06-19 10:26:29 -070011#include <string>
Garrick Evansc7fea0a2020-02-04 10:46:42 +090012#include <vector>
Kevin Cernekee95d4ae92016-06-19 10:26:29 -070013
14#include <base/macros.h>
15#include <base/memory/weak_ptr.h>
16#include <shill/dbus-proxies.h>
17
Garrick Evans3388a032020-03-24 11:25:55 +090018namespace patchpanel {
Kevin Cernekee95d4ae92016-06-19 10:26:29 -070019
Jie Jiang850a4712020-04-08 21:06:36 +090020// Listens for shill signals over dbus in order to:
21// - Figure out which network interface (if any) is being used as the default
22// service.
23// - Invoke callbacks when the IPConfigs of a device has changed.
Kevin Cernekee95d4ae92016-06-19 10:26:29 -070024class ShillClient {
25 public:
Jie Jiang850a4712020-04-08 21:06:36 +090026 // IPConfig for a device. If the device does not have a valid ipv4/ipv6
27 // config, the corresponding fields will be empty or 0.
28 // TODO(jiejiang): add the following fields into this struct:
29 // - IPv4 search domains
30 // - IPv6 search domains
31 // - MTU (one only per network)
32 struct IPConfig {
33 int ipv4_prefix_length;
34 std::string ipv4_address;
35 std::string ipv4_gateway;
36 std::vector<std::string> ipv4_dns_addresses;
37
38 int ipv6_prefix_length;
39 // Note due to the limitation of shill, we will only get one IPv6 address
40 // from it. This address should be the privacy address for device with type
41 // of ethernet or wifi.
42 std::string ipv6_address;
43 std::string ipv6_gateway;
44 std::vector<std::string> ipv6_dns_addresses;
45 };
46
Jie Jiang01c1a2e2020-04-08 20:58:30 +090047 // Represents the properties of an object of org.chromium.flimflam.Device.
48 // Only contains the properties we care about.
49 // TODO(jiejiang): add the following fields into this struct:
50 // - the DBus path of the Service associated to this Device if any
51 // - the connection state of the Service, if possible by translating back to
52 // the enum shill::Service::ConnectState
53 struct Device {
Jie Jiang48c99ce2020-06-08 15:18:23 +090054 // A subset of shill::Technology::Type.
55 enum class Type {
56 kUnknown,
57 kCellular,
58 kEthernet,
59 kEthernetEap,
60 kGuestInterface,
61 kLoopback,
62 kPPP,
63 kPPPoE,
64 kTunnel,
65 kVPN,
66 kWifi,
67 };
68
69 Type type;
Jie Jiang01c1a2e2020-04-08 20:58:30 +090070 std::string ifname;
71 IPConfig ipconfig;
72 };
73
Garrick Evans1b1f67c2020-02-04 16:21:25 +090074 using DefaultInterfaceChangeHandler = base::Callback<void(
75 const std::string& new_ifname, const std::string& prev_ifname)>;
Garrick Evans139708f2020-02-06 14:38:59 +090076 using DevicesChangeHandler =
77 base::Callback<void(const std::set<std::string>& added,
78 const std::set<std::string>& removed)>;
Jie Jiang850a4712020-04-08 21:06:36 +090079 using IPConfigsChangeHandler =
80 base::Callback<void(const std::string& device, const IPConfig& ipconfig)>;
Garrick Evans1b1f67c2020-02-04 16:21:25 +090081
Garrick Evans08843932019-09-17 14:41:08 +090082 explicit ShillClient(const scoped_refptr<dbus::Bus>& bus);
Qijiang Fan6bc59e12020-11-11 02:51:06 +090083 ShillClient(const ShillClient&) = delete;
84 ShillClient& operator=(const ShillClient&) = delete;
85
Ben Chan4f386502019-09-20 16:17:59 -070086 virtual ~ShillClient() = default;
Kevin Cernekee95d4ae92016-06-19 10:26:29 -070087
88 void RegisterDefaultInterfaceChangedHandler(
Garrick Evans139708f2020-02-06 14:38:59 +090089 const DefaultInterfaceChangeHandler& handler);
Garrick Evans49879532018-12-03 13:15:36 +090090
Garrick Evans139708f2020-02-06 14:38:59 +090091 void RegisterDevicesChangedHandler(const DevicesChangeHandler& handler);
Garrick Evans49879532018-12-03 13:15:36 +090092
Jie Jiang850a4712020-04-08 21:06:36 +090093 void RegisterIPConfigsChangedHandler(const IPConfigsChangeHandler& handler);
94
Jie Jiang84c76a12020-04-17 16:45:20 +090095 void ScanDevices();
Kevin Cernekee95d4ae92016-06-19 10:26:29 -070096
Jie Jiang01c1a2e2020-04-08 20:58:30 +090097 // Fetches device properties via dbus. Returns false if an error occurs. Notes
98 // that this method will block the current thread.
99 virtual bool GetDeviceProperties(const std::string& device, Device* output);
100
Garrick Evansbbdf4b42020-03-05 12:59:06 +0900101 // Returns the cached interface name; does not initiate a property fetch.
102 virtual const std::string& default_interface() const;
Hugo Benichicc6850f2020-01-17 13:26:06 +0900103 // Returns interface names of all known shill Devices.
104 const std::set<std::string> get_devices() const;
105 // Returns true if |ifname| is a known shill Device.
106 bool has_device(const std::string& ifname) const;
Garrick Evans1b1f67c2020-02-04 16:21:25 +0900107
Kevin Cernekee95d4ae92016-06-19 10:26:29 -0700108 protected:
109 void OnManagerPropertyChangeRegistration(const std::string& interface,
110 const std::string& signal_name,
111 bool success);
112 void OnManagerPropertyChange(const std::string& property_name,
113 const brillo::Any& property_value);
114
Jie Jiang850a4712020-04-08 21:06:36 +0900115 void OnDevicePropertyChangeRegistration(const std::string& interface,
116 const std::string& signal_name,
117 bool success);
118 void OnDevicePropertyChange(const std::string& device,
119 const std::string& property_name,
120 const brillo::Any& property_value);
121
Hugo Benichiddee2812019-05-10 16:03:43 +0900122 // Returns the name of the default interface for the system, or an empty
123 // string when the system has no default interface.
124 virtual std::string GetDefaultInterface();
Kevin Cernekee95d4ae92016-06-19 10:26:29 -0700125
Hugo Benichiddee2812019-05-10 16:03:43 +0900126 private:
Garrick Evans139708f2020-02-06 14:38:59 +0900127 void UpdateDevices(const brillo::Any& property_value);
128
Hugo Benichiddee2812019-05-10 16:03:43 +0900129 // Sets the internal variable tracking the system default interface and calls
130 // the default interface handler if the default interface changed. When the
131 // default interface is lost and a fallback exists, the fallback is used
Garrick Evans1b1f67c2020-02-04 16:21:25 +0900132 // instead. Returns the previous default interface.
133 std::string SetDefaultInterface(std::string new_default);
Hugo Benichiddee2812019-05-10 16:03:43 +0900134
Jie Jiang850a4712020-04-08 21:06:36 +0900135 // Parses the |property_value| as the IPConfigs property of |device|, which
136 // should be a list of object paths of IPConfigs.
137 IPConfig ParseIPConfigsProperty(const std::string& device,
138 const brillo::Any& property_value);
139
Hugo Benichiddee2812019-05-10 16:03:43 +0900140 // Tracks the name of the system default interface chosen by shill.
Kevin Cernekee95d4ae92016-06-19 10:26:29 -0700141 std::string default_interface_;
Hugo Benichiddee2812019-05-10 16:03:43 +0900142 // Another network interface on the system to use as a possible fallback if
143 // no system default interface exists.
144 std::string fallback_default_interface_;
145 // Tracks all network interfaces managed by shill.
146 std::set<std::string> devices_;
Jie Jiang850a4712020-04-08 21:06:36 +0900147 // Stores the map from interface to its object path in shill for all the
148 // devices we have seen. Unlike |devices_|, entries in this map will never
149 // be removed during the lifetime of this class. We maintain this map mainly
150 // for keeping track of the device object proxies we have created, to avoid
151 // registering the handler on the same object twice.
152 std::map<std::string, dbus::ObjectPath> known_device_paths_;
153
Hugo Benichiddee2812019-05-10 16:03:43 +0900154 // Called when the interface used as the default interface changes.
Garrick Evans139708f2020-02-06 14:38:59 +0900155 std::vector<DefaultInterfaceChangeHandler> default_interface_handlers_;
Hugo Benichiddee2812019-05-10 16:03:43 +0900156 // Called when the list of network interfaces managed by shill changes.
Garrick Evans139708f2020-02-06 14:38:59 +0900157 std::vector<DevicesChangeHandler> device_handlers_;
Jie Jiang850a4712020-04-08 21:06:36 +0900158 // Called when the IPConfigs of any device changes.
159 std::vector<IPConfigsChangeHandler> ipconfigs_handlers_;
Kevin Cernekee95d4ae92016-06-19 10:26:29 -0700160
161 scoped_refptr<dbus::Bus> bus_;
162 std::unique_ptr<org::chromium::flimflam::ManagerProxy> manager_proxy_;
163
164 base::WeakPtrFactory<ShillClient> weak_factory_{this};
Kevin Cernekee95d4ae92016-06-19 10:26:29 -0700165};
166
Garrick Evans3388a032020-03-24 11:25:55 +0900167} // namespace patchpanel
Kevin Cernekee95d4ae92016-06-19 10:26:29 -0700168
Garrick Evans3388a032020-03-24 11:25:55 +0900169#endif // PATCHPANEL_SHILL_CLIENT_H_