blob: 2454ac76e680b2510cc65a21855161fd80aa12d4 [file] [log] [blame]
Garrick Evans49879532018-12-03 13:15:36 +09001// 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 Evans428e4762018-12-11 15:18:42 +090015#include <base/bind.h>
Garrick Evans49879532018-12-03 13:15:36 +090016#include <base/memory/weak_ptr.h>
Garrick Evansf4a93292019-03-13 14:19:43 +090017#include <gtest/gtest_prod.h> // for FRIEND_TEST
Garrick Evans49879532018-12-03 13:15:36 +090018
19#include "arc/network/ipc.pb.h"
Garrick Evansf4a93292019-03-13 14:19:43 +090020#include "arc/network/mac_address_generator.h"
Garrick Evans49879532018-12-03 13:15:36 +090021#include "arc/network/multicast_forwarder.h"
22#include "arc/network/neighbor_finder.h"
23#include "arc/network/router_finder.h"
Garrick Evansf4a93292019-03-13 14:19:43 +090024#include "arc/network/subnet.h"
Garrick Evans49879532018-12-03 13:15:36 +090025
26namespace arc_networkd {
27
Garrick Evansd2bb8502019-02-20 15:59:35 +090028// Reserved name for the Android device.
Garrick Evans49879532018-12-03 13:15:36 +090029extern const char kAndroidDevice[];
Garrick Evansd2bb8502019-02-20 15:59:35 +090030// Reserved name for the Android device for legacy single network configs.
31extern const char kAndroidLegacyDevice[];
Garrick Evans49879532018-12-03 13:15:36 +090032
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.
38class Device {
39 public:
Long Cheng994dfd32019-09-24 18:50:27 +000040 using MessageSink = base::Callback<void(const DeviceMessage&)>;
Garrick Evans428e4762018-12-11 15:18:42 +090041
Garrick Evansf4a93292019-03-13 14:19:43 +090042 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 Evans49879532018-12-03 13:15:36 +090051
Garrick Evansf4a93292019-03-13 14:19:43 +090052 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 Benichiee787ff2019-05-20 16:42:42 +090058 friend std::ostream& operator<<(std::ostream& stream, const Device& device);
59
Garrick Evansf4a93292019-03-13 14:19:43 +090060 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 Cheng994dfd32019-09-24 18:50:27 +000078 const Options& options,
79 const MessageSink& msg_sink);
Long Chenge4c86762019-09-24 18:52:40 +000080 ~Device();
Garrick Evansf4a93292019-03-13 14:19:43 +090081
Long Cheng994dfd32019-09-24 18:50:27 +000082 void FillProto(DeviceConfig* msg) const;
Garrick Evans54861622019-07-19 09:05:09 +090083 const std::string& ifname() const;
Garrick Evans894abc22019-06-07 10:49:02 +090084 Config& config() const;
Garrick Evans54861622019-07-19 09:05:09 +090085 const Options& options() const;
Garrick Evans49879532018-12-03 13:15:36 +090086
Garrick Evans54861622019-07-19 09:05:09 +090087 bool IsAndroid() const;
88 bool IsLegacyAndroid() const;
89
Garrick Evans49879532018-12-03 13:15:36 +090090 void Enable(const std::string& ifname);
91 void Disable();
92
Garrick Evans54861622019-07-19 09:05:09 +090093 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 Benichiee787ff2019-05-20 16:42:42 +0900100 friend std::ostream& operator<<(std::ostream& stream, const Device& device);
101
Garrick Evans49879532018-12-03 13:15:36 +0900102 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 Evansf4a93292019-03-13 14:19:43 +0900114 std::unique_ptr<Config> config_;
115 const Options options_;
Long Cheng994dfd32019-09-24 18:50:27 +0000116 const MessageSink msg_sink_;
Garrick Evans428e4762018-12-11 15:18:42 +0900117
Long Chenge4c86762019-09-24 18:52:40 +0000118 // 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 Evans54861622019-07-19 09:05:09 +0900122 // Link status.
123 // TODO(garrick): Scope by guest.
124 bool host_link_up_;
125 bool guest_link_up_;
126
Long Chenge4c86762019-09-24 18:52:40 +0000127 struct in6_addr random_address_;
128 int random_address_prefix_len_;
129 int random_address_tries_;
Garrick Evans49879532018-12-03 13:15:36 +0900130
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 Evans49879532018-12-03 13:15:36 +0900136 base::WeakPtrFactory<Device> weak_factory_{this};
137
Garrick Evansf4a93292019-03-13 14:19:43 +0900138 FRIEND_TEST(DeviceTest, DisableLegacyAndroidDeviceSendsTwoMessages);
Garrick Evans49879532018-12-03 13:15:36 +0900139 DISALLOW_COPY_AND_ASSIGN(Device);
140};
141
142} // namespace arc_networkd
143
144#endif // ARC_NETWORK_DEVICE_H_