blob: d5e8cc533658c0f0c0de2af9b350dd85e597327a [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
Garrick Evans3388a032020-03-24 11:25:55 +09005#ifndef PATCHPANEL_DEVICE_H_
6#define PATCHPANEL_DEVICE_H_
Garrick Evans49879532018-12-03 13:15:36 +09007
Garrick Evans260ff302019-07-25 11:22:50 +09008#include <linux/in6.h>
Garrick Evans49879532018-12-03 13:15:36 +09009#include <netinet/in.h>
10#include <sys/socket.h>
11#include <unistd.h>
12
Taoyu Lice7caa62019-10-01 15:43:33 +090013#include <map>
Garrick Evans49879532018-12-03 13:15:36 +090014#include <memory>
15#include <string>
16
Garrick Evans428e4762018-12-11 15:18:42 +090017#include <base/bind.h>
Garrick Evans49879532018-12-03 13:15:36 +090018#include <base/memory/weak_ptr.h>
Garrick Evansf4a93292019-03-13 14:19:43 +090019#include <gtest/gtest_prod.h> // for FRIEND_TEST
Garrick Evans49879532018-12-03 13:15:36 +090020
Garrick Evans3388a032020-03-24 11:25:55 +090021#include "patchpanel/ipc.pb.h"
22#include "patchpanel/mac_address_generator.h"
23#include "patchpanel/subnet.h"
Garrick Evans49879532018-12-03 13:15:36 +090024
Garrick Evans3388a032020-03-24 11:25:55 +090025namespace patchpanel {
Garrick Evans49879532018-12-03 13:15:36 +090026
Garrick Evans49879532018-12-03 13:15:36 +090027// Encapsulates a physical (e.g. eth0) or proxy (e.g. arc) network device and
28// its configuration spec (interfaces, addresses) on the host and in the
29// container. It manages additional services such as router detection, address
30// assignment, and MDNS and SSDP forwarding. This class is the authoritative
31// source for configuration events.
32class Device {
33 public:
Garrick Evans209a80a2020-11-30 14:42:40 +090034 enum class ChangeEvent {
35 ADDED,
36 REMOVED,
37 };
38 using ChangeEventHandler = base::RepeatingCallback<void(
39 const Device&, ChangeEvent, GuestMessage::GuestType)>;
40
Garrick Evansf4a93292019-03-13 14:19:43 +090041 class Config {
42 public:
Garrick Evans6c7dcb82020-03-16 15:21:05 +090043 Config(const MacAddress& mac_addr,
Garrick Evansf4a93292019-03-13 14:19:43 +090044 std::unique_ptr<Subnet> ipv4_subnet,
45 std::unique_ptr<SubnetAddress> host_ipv4_addr,
Garrick Evans47c19272019-11-21 10:58:21 +090046 std::unique_ptr<SubnetAddress> guest_ipv4_addr,
47 std::unique_ptr<Subnet> lxd_ipv4_subnet = nullptr);
Qijiang Fan6bc59e12020-11-11 02:51:06 +090048 Config(const Config&) = delete;
49 Config& operator=(const Config&) = delete;
50
Garrick Evansf4a93292019-03-13 14:19:43 +090051 ~Config() = default;
Garrick Evans49879532018-12-03 13:15:36 +090052
Garrick Evans6c7dcb82020-03-16 15:21:05 +090053 MacAddress mac_addr() const { return mac_addr_; }
Garrick Evansf4a93292019-03-13 14:19:43 +090054 uint32_t host_ipv4_addr() const { return host_ipv4_addr_->Address(); }
55 uint32_t guest_ipv4_addr() const { return guest_ipv4_addr_->Address(); }
56
Garrick Evans47c19272019-11-21 10:58:21 +090057 const SubnetAddress* const host_ipv4_subnet_addr() const {
58 return host_ipv4_addr_.get();
59 }
60 const SubnetAddress* const guest_ipv4_subnet_addr() const {
61 return guest_ipv4_addr_.get();
62 }
63
64 const Subnet* const ipv4_subnet() const { return ipv4_subnet_.get(); }
65
66 const Subnet* const lxd_ipv4_subnet() const {
67 return lxd_ipv4_subnet_.get();
68 }
69
Garrick Evans2961c7c2020-04-03 11:34:40 +090070 void set_tap_ifname(const std::string& tap);
71 const std::string& tap_ifname() const;
72
Hugo Benichiee787ff2019-05-20 16:42:42 +090073 friend std::ostream& operator<<(std::ostream& stream, const Device& device);
74
Garrick Evansf4a93292019-03-13 14:19:43 +090075 private:
Garrick Evans47c19272019-11-21 10:58:21 +090076 // A random MAC address assigned to the device.
Garrick Evans6c7dcb82020-03-16 15:21:05 +090077 MacAddress mac_addr_;
Garrick Evans47c19272019-11-21 10:58:21 +090078 // The IPV4 subnet allocated for this device.
Garrick Evansf4a93292019-03-13 14:19:43 +090079 std::unique_ptr<Subnet> ipv4_subnet_;
Garrick Evans47c19272019-11-21 10:58:21 +090080 // The address allocated from |ipv4_subnet| for use by the CrOS-side
81 // interface associated with this device.
Garrick Evansf4a93292019-03-13 14:19:43 +090082 std::unique_ptr<SubnetAddress> host_ipv4_addr_;
Garrick Evans47c19272019-11-21 10:58:21 +090083 // The address allocated from |ipv4_subnet| for use by the guest-side
84 // interface associated with this device, if applicable.
Garrick Evansf4a93292019-03-13 14:19:43 +090085 std::unique_ptr<SubnetAddress> guest_ipv4_addr_;
Garrick Evans47c19272019-11-21 10:58:21 +090086 // If applicable, an additional subnet allocated for this device for guests
87 // like Crostini to use for assigning addresses to containers running within
88 // the VM.
89 std::unique_ptr<Subnet> lxd_ipv4_subnet_;
Garrick Evans2961c7c2020-04-03 11:34:40 +090090 // TAP devices currently associated with the configuration.
91 std::string tap_;
Garrick Evansf4a93292019-03-13 14:19:43 +090092 };
93
Garrick Evans6c7dcb82020-03-16 15:21:05 +090094 // |phys_ifname| corresponds either to the physical interface provided by
95 // shill or a placeholder for a guest-specific control interface (e.g. arc0).
96 // |host_ifname| identifies the name of the virtual (bridge) interface.
97 // |guest_ifname|, if specified, identifies the name of the interface used
98 // inside the guest.
99 Device(const std::string& phys_ifname,
100 const std::string& host_ifname,
101 const std::string& guest_ifname,
Hugo Benichi6f118a32021-03-01 12:28:14 +0900102 std::unique_ptr<Config> config);
Qijiang Fan6bc59e12020-11-11 02:51:06 +0900103 Device(const Device&) = delete;
104 Device& operator=(const Device&) = delete;
105
Garrick Evans260ff302019-07-25 11:22:50 +0900106 ~Device() = default;
Garrick Evansf4a93292019-03-13 14:19:43 +0900107
Garrick Evans6c7dcb82020-03-16 15:21:05 +0900108 const std::string& phys_ifname() const { return phys_ifname_; }
109 const std::string& host_ifname() const { return host_ifname_; }
110 const std::string& guest_ifname() const { return guest_ifname_; }
Garrick Evans894abc22019-06-07 10:49:02 +0900111 Config& config() const;
Garrick Evans86c7d9c2020-03-17 09:25:48 +0900112 std::unique_ptr<Config> release_config();
Garrick Evans49879532018-12-03 13:15:36 +0900113
Hugo Benichiee787ff2019-05-20 16:42:42 +0900114 friend std::ostream& operator<<(std::ostream& stream, const Device& device);
115
Garrick Evans49879532018-12-03 13:15:36 +0900116 private:
Garrick Evans6c7dcb82020-03-16 15:21:05 +0900117 std::string phys_ifname_;
118 std::string host_ifname_;
119 std::string guest_ifname_;
Garrick Evansf4a93292019-03-13 14:19:43 +0900120 std::unique_ptr<Config> config_;
Garrick Evans49879532018-12-03 13:15:36 +0900121
Garrick Evansf4a93292019-03-13 14:19:43 +0900122 FRIEND_TEST(DeviceTest, DisableLegacyAndroidDeviceSendsTwoMessages);
Garrick Evansbcce09e2020-03-10 15:08:04 +0900123
124 base::WeakPtrFactory<Device> weak_factory_{this};
Garrick Evans49879532018-12-03 13:15:36 +0900125};
126
Garrick Evans3388a032020-03-24 11:25:55 +0900127} // namespace patchpanel
Garrick Evans49879532018-12-03 13:15:36 +0900128
Garrick Evans3388a032020-03-24 11:25:55 +0900129#endif // PATCHPANEL_DEVICE_H_