blob: d3876e78c167ef4b03e7921f88be8be24d3cbd31 [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);
Garrick Evansf4a93292019-03-13 14:19:43 +090041 ~Config() = default;
Garrick Evans49879532018-12-03 13:15:36 +090042
Garrick Evans6c7dcb82020-03-16 15:21:05 +090043 MacAddress mac_addr() const { return mac_addr_; }
Garrick Evansf4a93292019-03-13 14:19:43 +090044 uint32_t host_ipv4_addr() const { return host_ipv4_addr_->Address(); }
45 uint32_t guest_ipv4_addr() const { return guest_ipv4_addr_->Address(); }
46
Garrick Evans47c19272019-11-21 10:58:21 +090047 const SubnetAddress* const host_ipv4_subnet_addr() const {
48 return host_ipv4_addr_.get();
49 }
50 const SubnetAddress* const guest_ipv4_subnet_addr() const {
51 return guest_ipv4_addr_.get();
52 }
53
54 const Subnet* const ipv4_subnet() const { return ipv4_subnet_.get(); }
55
56 const Subnet* const lxd_ipv4_subnet() const {
57 return lxd_ipv4_subnet_.get();
58 }
59
Garrick Evans2961c7c2020-04-03 11:34:40 +090060 void set_tap_ifname(const std::string& tap);
61 const std::string& tap_ifname() const;
62
Hugo Benichiee787ff2019-05-20 16:42:42 +090063 friend std::ostream& operator<<(std::ostream& stream, const Device& device);
64
Garrick Evansf4a93292019-03-13 14:19:43 +090065 private:
Garrick Evans47c19272019-11-21 10:58:21 +090066 // A random MAC address assigned to the device.
Garrick Evans6c7dcb82020-03-16 15:21:05 +090067 MacAddress mac_addr_;
Garrick Evans47c19272019-11-21 10:58:21 +090068 // The IPV4 subnet allocated for this device.
Garrick Evansf4a93292019-03-13 14:19:43 +090069 std::unique_ptr<Subnet> ipv4_subnet_;
Garrick Evans47c19272019-11-21 10:58:21 +090070 // The address allocated from |ipv4_subnet| for use by the CrOS-side
71 // interface associated with this device.
Garrick Evansf4a93292019-03-13 14:19:43 +090072 std::unique_ptr<SubnetAddress> host_ipv4_addr_;
Garrick Evans47c19272019-11-21 10:58:21 +090073 // The address allocated from |ipv4_subnet| for use by the guest-side
74 // interface associated with this device, if applicable.
Garrick Evansf4a93292019-03-13 14:19:43 +090075 std::unique_ptr<SubnetAddress> guest_ipv4_addr_;
Garrick Evans47c19272019-11-21 10:58:21 +090076 // If applicable, an additional subnet allocated for this device for guests
77 // like Crostini to use for assigning addresses to containers running within
78 // the VM.
79 std::unique_ptr<Subnet> lxd_ipv4_subnet_;
Garrick Evans2961c7c2020-04-03 11:34:40 +090080 // TAP devices currently associated with the configuration.
81 std::string tap_;
Garrick Evansf4a93292019-03-13 14:19:43 +090082
83 DISALLOW_COPY_AND_ASSIGN(Config);
84 };
85
86 struct Options {
87 bool fwd_multicast;
Taoyu Lice7caa62019-10-01 15:43:33 +090088 bool ipv6_enabled;
Jason Jeremy Iman3081d0e2020-03-04 15:52:06 +090089 bool adb_allowed;
Garrick Evansf4a93292019-03-13 14:19:43 +090090 };
91
Garrick Evans6c7dcb82020-03-16 15:21:05 +090092 // |phys_ifname| corresponds either to the physical interface provided by
93 // shill or a placeholder for a guest-specific control interface (e.g. arc0).
94 // |host_ifname| identifies the name of the virtual (bridge) interface.
95 // |guest_ifname|, if specified, identifies the name of the interface used
96 // inside the guest.
97 Device(const std::string& phys_ifname,
98 const std::string& host_ifname,
99 const std::string& guest_ifname,
Garrick Evansf4a93292019-03-13 14:19:43 +0900100 std::unique_ptr<Config> config,
Garrick Evansbcce09e2020-03-10 15:08:04 +0900101 const Options& options);
Garrick Evans260ff302019-07-25 11:22:50 +0900102 ~Device() = default;
Garrick Evansf4a93292019-03-13 14:19:43 +0900103
Garrick Evans6c7dcb82020-03-16 15:21:05 +0900104 const std::string& phys_ifname() const { return phys_ifname_; }
105 const std::string& host_ifname() const { return host_ifname_; }
106 const std::string& guest_ifname() const { return guest_ifname_; }
Garrick Evans894abc22019-06-07 10:49:02 +0900107 Config& config() const;
Garrick Evans86c7d9c2020-03-17 09:25:48 +0900108 std::unique_ptr<Config> release_config();
Garrick Evans54861622019-07-19 09:05:09 +0900109 const Options& options() const;
Garrick Evans49879532018-12-03 13:15:36 +0900110
Hugo Benichiee787ff2019-05-20 16:42:42 +0900111 friend std::ostream& operator<<(std::ostream& stream, const Device& device);
112
Garrick Evans49879532018-12-03 13:15:36 +0900113 private:
Garrick Evans6c7dcb82020-03-16 15:21:05 +0900114 std::string phys_ifname_;
115 std::string host_ifname_;
116 std::string guest_ifname_;
Garrick Evansf4a93292019-03-13 14:19:43 +0900117 std::unique_ptr<Config> config_;
118 const Options options_;
Garrick Evans49879532018-12-03 13:15:36 +0900119
Garrick Evansf4a93292019-03-13 14:19:43 +0900120 FRIEND_TEST(DeviceTest, DisableLegacyAndroidDeviceSendsTwoMessages);
Garrick Evansbcce09e2020-03-10 15:08:04 +0900121
122 base::WeakPtrFactory<Device> weak_factory_{this};
Garrick Evans49879532018-12-03 13:15:36 +0900123 DISALLOW_COPY_AND_ASSIGN(Device);
124};
125
Garrick Evans3388a032020-03-24 11:25:55 +0900126} // namespace patchpanel
Garrick Evans49879532018-12-03 13:15:36 +0900127
Garrick Evans3388a032020-03-24 11:25:55 +0900128#endif // PATCHPANEL_DEVICE_H_