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: |
Garrick Evans | 428e476 | 2018-12-11 15:18:42 +0900 | [diff] [blame] | 40 | using MessageSink = base::Callback<void(const IpHelperMessage&)>; |
| 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, |
| 78 | const Options& options, |
| 79 | const MessageSink& msg_sink); |
| 80 | ~Device(); |
| 81 | |
| 82 | void FillProto(DeviceConfig* msg); |
Garrick Evans | 4987953 | 2018-12-03 13:15:36 +0900 | [diff] [blame] | 83 | |
| 84 | // |ifname| should always be empty for devices that represent physical host |
| 85 | // interfaces. For others, like the ARC device 'android' that represents the |
| 86 | // arcbr0 and arc0 interfaces, this function enables traffic to flow from a |
| 87 | // real interfaces (e.g. eth0) to the container. |
| 88 | void Enable(const std::string& ifname); |
| 89 | void Disable(); |
| 90 | |
Hugo Benichi | ee787ff | 2019-05-20 16:42:42 +0900 | [diff] [blame^] | 91 | friend std::ostream& operator<<(std::ostream& stream, const Device& device); |
| 92 | |
Garrick Evans | 4987953 | 2018-12-03 13:15:36 +0900 | [diff] [blame] | 93 | private: |
| 94 | // Callback from RouterFinder. May be triggered multiple times, e.g. |
| 95 | // if the route disappears or changes. |
| 96 | void OnRouteFound(const struct in6_addr& prefix, |
| 97 | int prefix_len, |
| 98 | const struct in6_addr& router); |
| 99 | |
| 100 | // Callback from NeighborFinder to indicate whether an IPv6 address |
| 101 | // collision was found or not found. |
| 102 | void OnNeighborCheckResult(bool found); |
| 103 | |
| 104 | const std::string ifname_; |
Garrick Evans | f4a9329 | 2019-03-13 14:19:43 +0900 | [diff] [blame] | 105 | std::unique_ptr<Config> config_; |
| 106 | const Options options_; |
Garrick Evans | 428e476 | 2018-12-11 15:18:42 +0900 | [diff] [blame] | 107 | const MessageSink msg_sink_; |
| 108 | |
Garrick Evans | d2bb850 | 2019-02-20 15:59:35 +0900 | [diff] [blame] | 109 | // Only used for the legacy Android device; points to the interface currently |
Garrick Evans | 4987953 | 2018-12-03 13:15:36 +0900 | [diff] [blame] | 110 | // used by the container. |
| 111 | std::string legacy_lan_ifname_; |
| 112 | |
| 113 | struct in6_addr random_address_; |
| 114 | int random_address_prefix_len_; |
| 115 | int random_address_tries_; |
| 116 | |
| 117 | std::unique_ptr<MulticastForwarder> mdns_forwarder_; |
| 118 | std::unique_ptr<MulticastForwarder> ssdp_forwarder_; |
| 119 | std::unique_ptr<RouterFinder> router_finder_; |
| 120 | std::unique_ptr<NeighborFinder> neighbor_finder_; |
| 121 | |
Garrick Evans | 4987953 | 2018-12-03 13:15:36 +0900 | [diff] [blame] | 122 | base::WeakPtrFactory<Device> weak_factory_{this}; |
| 123 | |
Garrick Evans | f4a9329 | 2019-03-13 14:19:43 +0900 | [diff] [blame] | 124 | FRIEND_TEST(DeviceTest, DisableLegacyAndroidDeviceSendsTwoMessages); |
Garrick Evans | 4987953 | 2018-12-03 13:15:36 +0900 | [diff] [blame] | 125 | DISALLOW_COPY_AND_ASSIGN(Device); |
| 126 | }; |
| 127 | |
| 128 | } // namespace arc_networkd |
| 129 | |
| 130 | #endif // ARC_NETWORK_DEVICE_H_ |