blob: fd63668b0bd25d515b5b1ec0c5d0a17d18ec0cc9 [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 Evansf4a93292019-03-13 14:19:43 +090034 class Config {
35 public:
Garrick Evans6c7dcb82020-03-16 15:21:05 +090036 Config(const MacAddress& mac_addr,
Garrick Evansf4a93292019-03-13 14:19:43 +090037 std::unique_ptr<Subnet> ipv4_subnet,
38 std::unique_ptr<SubnetAddress> host_ipv4_addr,
Garrick Evans47c19272019-11-21 10:58:21 +090039 std::unique_ptr<SubnetAddress> guest_ipv4_addr,
40 std::unique_ptr<Subnet> lxd_ipv4_subnet = nullptr);
Qijiang Fan6bc59e12020-11-11 02:51:06 +090041 Config(const Config&) = delete;
42 Config& operator=(const Config&) = delete;
43
Garrick Evansf4a93292019-03-13 14:19:43 +090044 ~Config() = default;
Garrick Evans49879532018-12-03 13:15:36 +090045
Garrick Evans6c7dcb82020-03-16 15:21:05 +090046 MacAddress mac_addr() const { return mac_addr_; }
Garrick Evansf4a93292019-03-13 14:19:43 +090047 uint32_t host_ipv4_addr() const { return host_ipv4_addr_->Address(); }
48 uint32_t guest_ipv4_addr() const { return guest_ipv4_addr_->Address(); }
49
Garrick Evans47c19272019-11-21 10:58:21 +090050 const SubnetAddress* const host_ipv4_subnet_addr() const {
51 return host_ipv4_addr_.get();
52 }
53 const SubnetAddress* const guest_ipv4_subnet_addr() const {
54 return guest_ipv4_addr_.get();
55 }
56
57 const Subnet* const ipv4_subnet() const { return ipv4_subnet_.get(); }
58
59 const Subnet* const lxd_ipv4_subnet() const {
60 return lxd_ipv4_subnet_.get();
61 }
62
Garrick Evans2961c7c2020-04-03 11:34:40 +090063 void set_tap_ifname(const std::string& tap);
64 const std::string& tap_ifname() const;
65
Hugo Benichiee787ff2019-05-20 16:42:42 +090066 friend std::ostream& operator<<(std::ostream& stream, const Device& device);
67
Garrick Evansf4a93292019-03-13 14:19:43 +090068 private:
Garrick Evans47c19272019-11-21 10:58:21 +090069 // A random MAC address assigned to the device.
Garrick Evans6c7dcb82020-03-16 15:21:05 +090070 MacAddress mac_addr_;
Garrick Evans47c19272019-11-21 10:58:21 +090071 // The IPV4 subnet allocated for this device.
Garrick Evansf4a93292019-03-13 14:19:43 +090072 std::unique_ptr<Subnet> ipv4_subnet_;
Garrick Evans47c19272019-11-21 10:58:21 +090073 // The address allocated from |ipv4_subnet| for use by the CrOS-side
74 // interface associated with this device.
Garrick Evansf4a93292019-03-13 14:19:43 +090075 std::unique_ptr<SubnetAddress> host_ipv4_addr_;
Garrick Evans47c19272019-11-21 10:58:21 +090076 // The address allocated from |ipv4_subnet| for use by the guest-side
77 // interface associated with this device, if applicable.
Garrick Evansf4a93292019-03-13 14:19:43 +090078 std::unique_ptr<SubnetAddress> guest_ipv4_addr_;
Garrick Evans47c19272019-11-21 10:58:21 +090079 // If applicable, an additional subnet allocated for this device for guests
80 // like Crostini to use for assigning addresses to containers running within
81 // the VM.
82 std::unique_ptr<Subnet> lxd_ipv4_subnet_;
Garrick Evans2961c7c2020-04-03 11:34:40 +090083 // TAP devices currently associated with the configuration.
84 std::string tap_;
Garrick Evansf4a93292019-03-13 14:19:43 +090085
Garrick Evansf4a93292019-03-13 14:19:43 +090086 };
87
88 struct Options {
89 bool fwd_multicast;
Taoyu Lice7caa62019-10-01 15:43:33 +090090 bool ipv6_enabled;
Jason Jeremy Iman3081d0e2020-03-04 15:52:06 +090091 bool adb_allowed;
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,
Garrick Evansf4a93292019-03-13 14:19:43 +0900102 std::unique_ptr<Config> config,
Garrick Evansbcce09e2020-03-10 15:08:04 +0900103 const Options& options);
Qijiang Fan6bc59e12020-11-11 02:51:06 +0900104 Device(const Device&) = delete;
105 Device& operator=(const Device&) = delete;
106
Garrick Evans260ff302019-07-25 11:22:50 +0900107 ~Device() = default;
Garrick Evansf4a93292019-03-13 14:19:43 +0900108
Garrick Evans6c7dcb82020-03-16 15:21:05 +0900109 const std::string& phys_ifname() const { return phys_ifname_; }
110 const std::string& host_ifname() const { return host_ifname_; }
111 const std::string& guest_ifname() const { return guest_ifname_; }
Garrick Evans894abc22019-06-07 10:49:02 +0900112 Config& config() const;
Garrick Evans86c7d9c2020-03-17 09:25:48 +0900113 std::unique_ptr<Config> release_config();
Garrick Evans54861622019-07-19 09:05:09 +0900114 const Options& options() const;
Garrick Evans49879532018-12-03 13:15:36 +0900115
Hugo Benichiee787ff2019-05-20 16:42:42 +0900116 friend std::ostream& operator<<(std::ostream& stream, const Device& device);
117
Garrick Evans49879532018-12-03 13:15:36 +0900118 private:
Garrick Evans6c7dcb82020-03-16 15:21:05 +0900119 std::string phys_ifname_;
120 std::string host_ifname_;
121 std::string guest_ifname_;
Garrick Evansf4a93292019-03-13 14:19:43 +0900122 std::unique_ptr<Config> config_;
123 const Options options_;
Garrick Evans49879532018-12-03 13:15:36 +0900124
Garrick Evansf4a93292019-03-13 14:19:43 +0900125 FRIEND_TEST(DeviceTest, DisableLegacyAndroidDeviceSendsTwoMessages);
Garrick Evansbcce09e2020-03-10 15:08:04 +0900126
127 base::WeakPtrFactory<Device> weak_factory_{this};
Garrick Evans49879532018-12-03 13:15:36 +0900128};
129
Garrick Evans3388a032020-03-24 11:25:55 +0900130} // namespace patchpanel
Garrick Evans49879532018-12-03 13:15:36 +0900131
Garrick Evans3388a032020-03-24 11:25:55 +0900132#endif // PATCHPANEL_DEVICE_H_