Garrick Evans | 4987953 | 2018-12-03 13:15:36 +0900 | [diff] [blame] | 1 | // Copyright 2018 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 | |
| 5 | #ifndef ARC_NETWORK_DEVICE_H_ |
| 6 | #define ARC_NETWORK_DEVICE_H_ |
| 7 | |
| 8 | #include <netinet/in.h> |
| 9 | #include <sys/socket.h> |
| 10 | #include <unistd.h> |
| 11 | |
| 12 | #include <memory> |
| 13 | #include <string> |
| 14 | |
Garrick Evans | 428e476 | 2018-12-11 15:18:42 +0900 | [diff] [blame] | 15 | #include <base/bind.h> |
Garrick Evans | 4987953 | 2018-12-03 13:15:36 +0900 | [diff] [blame] | 16 | #include <base/memory/weak_ptr.h> |
Garrick Evans | f4a9329 | 2019-03-13 14:19:43 +0900 | [diff] [blame] | 17 | #include <gtest/gtest_prod.h> // for FRIEND_TEST |
Garrick Evans | 4987953 | 2018-12-03 13:15:36 +0900 | [diff] [blame] | 18 | |
| 19 | #include "arc/network/ipc.pb.h" |
Garrick Evans | f4a9329 | 2019-03-13 14:19:43 +0900 | [diff] [blame] | 20 | #include "arc/network/mac_address_generator.h" |
Garrick Evans | 4987953 | 2018-12-03 13:15:36 +0900 | [diff] [blame] | 21 | #include "arc/network/multicast_forwarder.h" |
| 22 | #include "arc/network/neighbor_finder.h" |
| 23 | #include "arc/network/router_finder.h" |
Garrick Evans | f4a9329 | 2019-03-13 14:19:43 +0900 | [diff] [blame] | 24 | #include "arc/network/subnet.h" |
Garrick Evans | 4987953 | 2018-12-03 13:15:36 +0900 | [diff] [blame] | 25 | |
| 26 | namespace arc_networkd { |
| 27 | |
Garrick Evans | d2bb850 | 2019-02-20 15:59:35 +0900 | [diff] [blame] | 28 | // Reserved name for the Android device. |
Garrick Evans | 4987953 | 2018-12-03 13:15:36 +0900 | [diff] [blame] | 29 | extern const char kAndroidDevice[]; |
Garrick Evans | d2bb850 | 2019-02-20 15:59:35 +0900 | [diff] [blame] | 30 | // Reserved name for the Android device for legacy single network configs. |
| 31 | extern const char kAndroidLegacyDevice[]; |
Garrick Evans | 4987953 | 2018-12-03 13:15:36 +0900 | [diff] [blame] | 32 | |
| 33 | // Encapsulates a physical (e.g. eth0) or proxy (e.g. arc) network device and |
| 34 | // its configuration spec (interfaces, addresses) on the host and in the |
| 35 | // container. It manages additional services such as router detection, address |
| 36 | // assignment, and MDNS and SSDP forwarding. This class is the authoritative |
| 37 | // source for configuration events. |
| 38 | class Device { |
| 39 | public: |
Long Cheng | 994dfd3 | 2019-09-24 18:50:27 +0000 | [diff] [blame] | 40 | using MessageSink = base::Callback<void(const DeviceMessage&)>; |
Garrick Evans | 428e476 | 2018-12-11 15:18:42 +0900 | [diff] [blame] | 41 | |
Garrick Evans | f4a9329 | 2019-03-13 14:19:43 +0900 | [diff] [blame] | 42 | class Config { |
| 43 | public: |
| 44 | Config(const std::string& host_ifname, |
| 45 | const std::string& guest_ifname, |
| 46 | const MacAddress& guest_mac_addr, |
| 47 | std::unique_ptr<Subnet> ipv4_subnet, |
| 48 | std::unique_ptr<SubnetAddress> host_ipv4_addr, |
| 49 | std::unique_ptr<SubnetAddress> guest_ipv4_addr); |
| 50 | ~Config() = default; |
Garrick Evans | 4987953 | 2018-12-03 13:15:36 +0900 | [diff] [blame] | 51 | |
Garrick Evans | f4a9329 | 2019-03-13 14:19:43 +0900 | [diff] [blame] | 52 | std::string host_ifname() const { return host_ifname_; } |
| 53 | std::string guest_ifname() const { return guest_ifname_; } |
| 54 | MacAddress guest_mac_addr() const { return guest_mac_addr_; } |
| 55 | uint32_t host_ipv4_addr() const { return host_ipv4_addr_->Address(); } |
| 56 | uint32_t guest_ipv4_addr() const { return guest_ipv4_addr_->Address(); } |
| 57 | |
Hugo Benichi | ee787ff | 2019-05-20 16:42:42 +0900 | [diff] [blame] | 58 | friend std::ostream& operator<<(std::ostream& stream, const Device& device); |
| 59 | |
Garrick Evans | f4a9329 | 2019-03-13 14:19:43 +0900 | [diff] [blame] | 60 | private: |
| 61 | std::string host_ifname_; |
| 62 | std::string guest_ifname_; |
| 63 | MacAddress guest_mac_addr_; |
| 64 | std::unique_ptr<Subnet> ipv4_subnet_; |
| 65 | std::unique_ptr<SubnetAddress> host_ipv4_addr_; |
| 66 | std::unique_ptr<SubnetAddress> guest_ipv4_addr_; |
| 67 | |
| 68 | DISALLOW_COPY_AND_ASSIGN(Config); |
| 69 | }; |
| 70 | |
| 71 | struct Options { |
| 72 | bool fwd_multicast; |
| 73 | bool find_ipv6_routes; |
| 74 | }; |
| 75 | |
| 76 | Device(const std::string& ifname, |
| 77 | std::unique_ptr<Config> config, |
Long Cheng | 994dfd3 | 2019-09-24 18:50:27 +0000 | [diff] [blame] | 78 | const Options& options, |
| 79 | const MessageSink& msg_sink); |
Long Cheng | e4c8676 | 2019-09-24 18:52:40 +0000 | [diff] [blame] | 80 | ~Device(); |
Garrick Evans | f4a9329 | 2019-03-13 14:19:43 +0900 | [diff] [blame] | 81 | |
Long Cheng | 994dfd3 | 2019-09-24 18:50:27 +0000 | [diff] [blame] | 82 | void FillProto(DeviceConfig* msg) const; |
Garrick Evans | 5486162 | 2019-07-19 09:05:09 +0900 | [diff] [blame^] | 83 | const std::string& ifname() const; |
Garrick Evans | 894abc2 | 2019-06-07 10:49:02 +0900 | [diff] [blame] | 84 | Config& config() const; |
Garrick Evans | 5486162 | 2019-07-19 09:05:09 +0900 | [diff] [blame^] | 85 | const Options& options() const; |
Garrick Evans | 4987953 | 2018-12-03 13:15:36 +0900 | [diff] [blame] | 86 | |
Garrick Evans | 5486162 | 2019-07-19 09:05:09 +0900 | [diff] [blame^] | 87 | bool IsAndroid() const; |
| 88 | bool IsLegacyAndroid() const; |
| 89 | |
Garrick Evans | 4987953 | 2018-12-03 13:15:36 +0900 | [diff] [blame] | 90 | void Enable(const std::string& ifname); |
| 91 | void Disable(); |
| 92 | |
Garrick Evans | 5486162 | 2019-07-19 09:05:09 +0900 | [diff] [blame^] | 93 | void OnGuestStart(GuestMessage::GuestType guest); |
| 94 | void OnGuestStop(GuestMessage::GuestType guest); |
| 95 | |
| 96 | // Updates the link status and returns whether the status was changed. |
| 97 | // ifname must match either host_ifname or guest_ifname in the config. |
| 98 | bool LinkUp(const std::string& ifname, bool up); |
| 99 | |
Hugo Benichi | ee787ff | 2019-05-20 16:42:42 +0900 | [diff] [blame] | 100 | friend std::ostream& operator<<(std::ostream& stream, const Device& device); |
| 101 | |
Garrick Evans | 4987953 | 2018-12-03 13:15:36 +0900 | [diff] [blame] | 102 | private: |
| 103 | // Callback from RouterFinder. May be triggered multiple times, e.g. |
| 104 | // if the route disappears or changes. |
| 105 | void OnRouteFound(const struct in6_addr& prefix, |
| 106 | int prefix_len, |
| 107 | const struct in6_addr& router); |
| 108 | |
| 109 | // Callback from NeighborFinder to indicate whether an IPv6 address |
| 110 | // collision was found or not found. |
| 111 | void OnNeighborCheckResult(bool found); |
| 112 | |
| 113 | const std::string ifname_; |
Garrick Evans | f4a9329 | 2019-03-13 14:19:43 +0900 | [diff] [blame] | 114 | std::unique_ptr<Config> config_; |
| 115 | const Options options_; |
Long Cheng | 994dfd3 | 2019-09-24 18:50:27 +0000 | [diff] [blame] | 116 | const MessageSink msg_sink_; |
Garrick Evans | 428e476 | 2018-12-11 15:18:42 +0900 | [diff] [blame] | 117 | |
Long Cheng | e4c8676 | 2019-09-24 18:52:40 +0000 | [diff] [blame] | 118 | // Only used for the legacy Android device; points to the interface currently |
| 119 | // used by the container. |
| 120 | std::string legacy_lan_ifname_; |
| 121 | |
Garrick Evans | 5486162 | 2019-07-19 09:05:09 +0900 | [diff] [blame^] | 122 | // Link status. |
| 123 | // TODO(garrick): Scope by guest. |
| 124 | bool host_link_up_; |
| 125 | bool guest_link_up_; |
| 126 | |
Long Cheng | e4c8676 | 2019-09-24 18:52:40 +0000 | [diff] [blame] | 127 | struct in6_addr random_address_; |
| 128 | int random_address_prefix_len_; |
| 129 | int random_address_tries_; |
Garrick Evans | 4987953 | 2018-12-03 13:15:36 +0900 | [diff] [blame] | 130 | |
| 131 | std::unique_ptr<MulticastForwarder> mdns_forwarder_; |
| 132 | std::unique_ptr<MulticastForwarder> ssdp_forwarder_; |
| 133 | std::unique_ptr<RouterFinder> router_finder_; |
| 134 | std::unique_ptr<NeighborFinder> neighbor_finder_; |
| 135 | |
Garrick Evans | 4987953 | 2018-12-03 13:15:36 +0900 | [diff] [blame] | 136 | base::WeakPtrFactory<Device> weak_factory_{this}; |
| 137 | |
Garrick Evans | f4a9329 | 2019-03-13 14:19:43 +0900 | [diff] [blame] | 138 | FRIEND_TEST(DeviceTest, DisableLegacyAndroidDeviceSendsTwoMessages); |
Garrick Evans | 4987953 | 2018-12-03 13:15:36 +0900 | [diff] [blame] | 139 | DISALLOW_COPY_AND_ASSIGN(Device); |
| 140 | }; |
| 141 | |
| 142 | } // namespace arc_networkd |
| 143 | |
| 144 | #endif // ARC_NETWORK_DEVICE_H_ |