blob: 83de5ba66145e138a6275d65a3021ab829b750b4 [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
Garrick Evans1b1f67c2020-02-04 16:21:25 +090047 using DefaultInterfaceChangeHandler = base::Callback<void(
48 const std::string& new_ifname, const std::string& prev_ifname)>;
Garrick Evans139708f2020-02-06 14:38:59 +090049 using DevicesChangeHandler =
50 base::Callback<void(const std::set<std::string>& added,
51 const std::set<std::string>& removed)>;
Jie Jiang850a4712020-04-08 21:06:36 +090052 using IPConfigsChangeHandler =
53 base::Callback<void(const std::string& device, const IPConfig& ipconfig)>;
Garrick Evans1b1f67c2020-02-04 16:21:25 +090054
Garrick Evans08843932019-09-17 14:41:08 +090055 explicit ShillClient(const scoped_refptr<dbus::Bus>& bus);
Ben Chan4f386502019-09-20 16:17:59 -070056 virtual ~ShillClient() = default;
Kevin Cernekee95d4ae92016-06-19 10:26:29 -070057
58 void RegisterDefaultInterfaceChangedHandler(
Garrick Evans139708f2020-02-06 14:38:59 +090059 const DefaultInterfaceChangeHandler& handler);
Garrick Evans49879532018-12-03 13:15:36 +090060
Garrick Evans139708f2020-02-06 14:38:59 +090061 void RegisterDevicesChangedHandler(const DevicesChangeHandler& handler);
Garrick Evans49879532018-12-03 13:15:36 +090062
Jie Jiang850a4712020-04-08 21:06:36 +090063 void RegisterIPConfigsChangedHandler(const IPConfigsChangeHandler& handler);
64
Jie Jiang84c76a12020-04-17 16:45:20 +090065 void ScanDevices();
Kevin Cernekee95d4ae92016-06-19 10:26:29 -070066
Garrick Evansbbdf4b42020-03-05 12:59:06 +090067 // Returns the cached interface name; does not initiate a property fetch.
68 virtual const std::string& default_interface() const;
Hugo Benichicc6850f2020-01-17 13:26:06 +090069 // Returns interface names of all known shill Devices.
70 const std::set<std::string> get_devices() const;
71 // Returns true if |ifname| is a known shill Device.
72 bool has_device(const std::string& ifname) const;
Garrick Evans1b1f67c2020-02-04 16:21:25 +090073
Kevin Cernekee95d4ae92016-06-19 10:26:29 -070074 protected:
75 void OnManagerPropertyChangeRegistration(const std::string& interface,
76 const std::string& signal_name,
77 bool success);
78 void OnManagerPropertyChange(const std::string& property_name,
79 const brillo::Any& property_value);
80
Jie Jiang850a4712020-04-08 21:06:36 +090081 void OnDevicePropertyChangeRegistration(const std::string& interface,
82 const std::string& signal_name,
83 bool success);
84 void OnDevicePropertyChange(const std::string& device,
85 const std::string& property_name,
86 const brillo::Any& property_value);
87
Hugo Benichiddee2812019-05-10 16:03:43 +090088 // Returns the name of the default interface for the system, or an empty
89 // string when the system has no default interface.
90 virtual std::string GetDefaultInterface();
Kevin Cernekee95d4ae92016-06-19 10:26:29 -070091
Hugo Benichiddee2812019-05-10 16:03:43 +090092 private:
Garrick Evans139708f2020-02-06 14:38:59 +090093 void UpdateDevices(const brillo::Any& property_value);
94
Hugo Benichiddee2812019-05-10 16:03:43 +090095 // Sets the internal variable tracking the system default interface and calls
96 // the default interface handler if the default interface changed. When the
97 // default interface is lost and a fallback exists, the fallback is used
Garrick Evans1b1f67c2020-02-04 16:21:25 +090098 // instead. Returns the previous default interface.
99 std::string SetDefaultInterface(std::string new_default);
Hugo Benichiddee2812019-05-10 16:03:43 +0900100
Jie Jiang850a4712020-04-08 21:06:36 +0900101 // Parses the |property_value| as the IPConfigs property of |device|, which
102 // should be a list of object paths of IPConfigs.
103 IPConfig ParseIPConfigsProperty(const std::string& device,
104 const brillo::Any& property_value);
105
Hugo Benichiddee2812019-05-10 16:03:43 +0900106 // Tracks the name of the system default interface chosen by shill.
Kevin Cernekee95d4ae92016-06-19 10:26:29 -0700107 std::string default_interface_;
Hugo Benichiddee2812019-05-10 16:03:43 +0900108 // Another network interface on the system to use as a possible fallback if
109 // no system default interface exists.
110 std::string fallback_default_interface_;
111 // Tracks all network interfaces managed by shill.
112 std::set<std::string> devices_;
Jie Jiang850a4712020-04-08 21:06:36 +0900113 // Stores the map from interface to its object path in shill for all the
114 // devices we have seen. Unlike |devices_|, entries in this map will never
115 // be removed during the lifetime of this class. We maintain this map mainly
116 // for keeping track of the device object proxies we have created, to avoid
117 // registering the handler on the same object twice.
118 std::map<std::string, dbus::ObjectPath> known_device_paths_;
119
Hugo Benichiddee2812019-05-10 16:03:43 +0900120 // Called when the interface used as the default interface changes.
Garrick Evans139708f2020-02-06 14:38:59 +0900121 std::vector<DefaultInterfaceChangeHandler> default_interface_handlers_;
Hugo Benichiddee2812019-05-10 16:03:43 +0900122 // Called when the list of network interfaces managed by shill changes.
Garrick Evans139708f2020-02-06 14:38:59 +0900123 std::vector<DevicesChangeHandler> device_handlers_;
Jie Jiang850a4712020-04-08 21:06:36 +0900124 // Called when the IPConfigs of any device changes.
125 std::vector<IPConfigsChangeHandler> ipconfigs_handlers_;
Kevin Cernekee95d4ae92016-06-19 10:26:29 -0700126
127 scoped_refptr<dbus::Bus> bus_;
128 std::unique_ptr<org::chromium::flimflam::ManagerProxy> manager_proxy_;
129
130 base::WeakPtrFactory<ShillClient> weak_factory_{this};
131
Kevin Cernekee95d4ae92016-06-19 10:26:29 -0700132 DISALLOW_COPY_AND_ASSIGN(ShillClient);
133};
134
Garrick Evans3388a032020-03-24 11:25:55 +0900135} // namespace patchpanel
Kevin Cernekee95d4ae92016-06-19 10:26:29 -0700136
Garrick Evans3388a032020-03-24 11:25:55 +0900137#endif // PATCHPANEL_SHILL_CLIENT_H_