blob: 02f5194652ac4280ac1687fbf8e090bf40351dfb [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 {
54 // Device technology name in shill.
55 std::string type;
56 std::string ifname;
57 IPConfig ipconfig;
58 };
59
Garrick Evans1b1f67c2020-02-04 16:21:25 +090060 using DefaultInterfaceChangeHandler = base::Callback<void(
61 const std::string& new_ifname, const std::string& prev_ifname)>;
Garrick Evans139708f2020-02-06 14:38:59 +090062 using DevicesChangeHandler =
63 base::Callback<void(const std::set<std::string>& added,
64 const std::set<std::string>& removed)>;
Jie Jiang850a4712020-04-08 21:06:36 +090065 using IPConfigsChangeHandler =
66 base::Callback<void(const std::string& device, const IPConfig& ipconfig)>;
Garrick Evans1b1f67c2020-02-04 16:21:25 +090067
Garrick Evans08843932019-09-17 14:41:08 +090068 explicit ShillClient(const scoped_refptr<dbus::Bus>& bus);
Ben Chan4f386502019-09-20 16:17:59 -070069 virtual ~ShillClient() = default;
Kevin Cernekee95d4ae92016-06-19 10:26:29 -070070
71 void RegisterDefaultInterfaceChangedHandler(
Garrick Evans139708f2020-02-06 14:38:59 +090072 const DefaultInterfaceChangeHandler& handler);
Garrick Evans49879532018-12-03 13:15:36 +090073
Garrick Evans139708f2020-02-06 14:38:59 +090074 void RegisterDevicesChangedHandler(const DevicesChangeHandler& handler);
Garrick Evans49879532018-12-03 13:15:36 +090075
Jie Jiang850a4712020-04-08 21:06:36 +090076 void RegisterIPConfigsChangedHandler(const IPConfigsChangeHandler& handler);
77
Jie Jiang84c76a12020-04-17 16:45:20 +090078 void ScanDevices();
Kevin Cernekee95d4ae92016-06-19 10:26:29 -070079
Jie Jiang01c1a2e2020-04-08 20:58:30 +090080 // Fetches device properties via dbus. Returns false if an error occurs. Notes
81 // that this method will block the current thread.
82 virtual bool GetDeviceProperties(const std::string& device, Device* output);
83
Garrick Evansbbdf4b42020-03-05 12:59:06 +090084 // Returns the cached interface name; does not initiate a property fetch.
85 virtual const std::string& default_interface() const;
Hugo Benichicc6850f2020-01-17 13:26:06 +090086 // Returns interface names of all known shill Devices.
87 const std::set<std::string> get_devices() const;
88 // Returns true if |ifname| is a known shill Device.
89 bool has_device(const std::string& ifname) const;
Garrick Evans1b1f67c2020-02-04 16:21:25 +090090
Kevin Cernekee95d4ae92016-06-19 10:26:29 -070091 protected:
92 void OnManagerPropertyChangeRegistration(const std::string& interface,
93 const std::string& signal_name,
94 bool success);
95 void OnManagerPropertyChange(const std::string& property_name,
96 const brillo::Any& property_value);
97
Jie Jiang850a4712020-04-08 21:06:36 +090098 void OnDevicePropertyChangeRegistration(const std::string& interface,
99 const std::string& signal_name,
100 bool success);
101 void OnDevicePropertyChange(const std::string& device,
102 const std::string& property_name,
103 const brillo::Any& property_value);
104
Hugo Benichiddee2812019-05-10 16:03:43 +0900105 // Returns the name of the default interface for the system, or an empty
106 // string when the system has no default interface.
107 virtual std::string GetDefaultInterface();
Kevin Cernekee95d4ae92016-06-19 10:26:29 -0700108
Hugo Benichiddee2812019-05-10 16:03:43 +0900109 private:
Garrick Evans139708f2020-02-06 14:38:59 +0900110 void UpdateDevices(const brillo::Any& property_value);
111
Hugo Benichiddee2812019-05-10 16:03:43 +0900112 // Sets the internal variable tracking the system default interface and calls
113 // the default interface handler if the default interface changed. When the
114 // default interface is lost and a fallback exists, the fallback is used
Garrick Evans1b1f67c2020-02-04 16:21:25 +0900115 // instead. Returns the previous default interface.
116 std::string SetDefaultInterface(std::string new_default);
Hugo Benichiddee2812019-05-10 16:03:43 +0900117
Jie Jiang850a4712020-04-08 21:06:36 +0900118 // Parses the |property_value| as the IPConfigs property of |device|, which
119 // should be a list of object paths of IPConfigs.
120 IPConfig ParseIPConfigsProperty(const std::string& device,
121 const brillo::Any& property_value);
122
Hugo Benichiddee2812019-05-10 16:03:43 +0900123 // Tracks the name of the system default interface chosen by shill.
Kevin Cernekee95d4ae92016-06-19 10:26:29 -0700124 std::string default_interface_;
Hugo Benichiddee2812019-05-10 16:03:43 +0900125 // Another network interface on the system to use as a possible fallback if
126 // no system default interface exists.
127 std::string fallback_default_interface_;
128 // Tracks all network interfaces managed by shill.
129 std::set<std::string> devices_;
Jie Jiang850a4712020-04-08 21:06:36 +0900130 // Stores the map from interface to its object path in shill for all the
131 // devices we have seen. Unlike |devices_|, entries in this map will never
132 // be removed during the lifetime of this class. We maintain this map mainly
133 // for keeping track of the device object proxies we have created, to avoid
134 // registering the handler on the same object twice.
135 std::map<std::string, dbus::ObjectPath> known_device_paths_;
136
Hugo Benichiddee2812019-05-10 16:03:43 +0900137 // Called when the interface used as the default interface changes.
Garrick Evans139708f2020-02-06 14:38:59 +0900138 std::vector<DefaultInterfaceChangeHandler> default_interface_handlers_;
Hugo Benichiddee2812019-05-10 16:03:43 +0900139 // Called when the list of network interfaces managed by shill changes.
Garrick Evans139708f2020-02-06 14:38:59 +0900140 std::vector<DevicesChangeHandler> device_handlers_;
Jie Jiang850a4712020-04-08 21:06:36 +0900141 // Called when the IPConfigs of any device changes.
142 std::vector<IPConfigsChangeHandler> ipconfigs_handlers_;
Kevin Cernekee95d4ae92016-06-19 10:26:29 -0700143
144 scoped_refptr<dbus::Bus> bus_;
145 std::unique_ptr<org::chromium::flimflam::ManagerProxy> manager_proxy_;
146
147 base::WeakPtrFactory<ShillClient> weak_factory_{this};
148
Kevin Cernekee95d4ae92016-06-19 10:26:29 -0700149 DISALLOW_COPY_AND_ASSIGN(ShillClient);
150};
151
Garrick Evans3388a032020-03-24 11:25:55 +0900152} // namespace patchpanel
Kevin Cernekee95d4ae92016-06-19 10:26:29 -0700153
Garrick Evans3388a032020-03-24 11:25:55 +0900154#endif // PATCHPANEL_SHILL_CLIENT_H_