blob: ed6cae3484ef0764dab40059f55aeb97ee2ce2d8 [file] [log] [blame]
Garrick Evansf0ab7132019-06-18 14:50:42 +09001// Copyright 2019 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_DATAPATH_H_
6#define PATCHPANEL_DATAPATH_H_
Garrick Evansf0ab7132019-06-18 14:50:42 +09007
Hugo Benichie8758b52020-04-03 14:49:01 +09008#include <net/route.h>
9
Garrick Evansf0ab7132019-06-18 14:50:42 +090010#include <string>
11
12#include <base/macros.h>
13
Garrick Evans3388a032020-03-24 11:25:55 +090014#include "patchpanel/mac_address_generator.h"
15#include "patchpanel/minijailed_process_runner.h"
16#include "patchpanel/subnet.h"
Garrick Evansf0ab7132019-06-18 14:50:42 +090017
Garrick Evans3388a032020-03-24 11:25:55 +090018namespace patchpanel {
Garrick Evansf0ab7132019-06-18 14:50:42 +090019
Taoyu Li90c13912019-11-26 17:56:54 +090020// cros lint will yell to force using int16/int64 instead of long here, however
21// note that unsigned long IS the correct signature for ioctl in Linux kernel -
22// it's 32 bits on 32-bit platform and 64 bits on 64-bit one.
23using ioctl_req_t = unsigned long;
24typedef int (*ioctl_t)(int, ioctl_req_t, ...);
Garrick Evansc7ae82c2019-09-04 16:25:10 +090025
Garrick Evans54861622019-07-19 09:05:09 +090026// Returns for given interface name the host name of a ARC veth pair.
27std::string ArcVethHostName(std::string ifname);
28
29// Returns for given interface name the peer name of a ARC veth pair.
30std::string ArcVethPeerName(std::string ifname);
31
Garrick Evansf0ab7132019-06-18 14:50:42 +090032// ARC networking data path configuration utility.
Garrick Evans54861622019-07-19 09:05:09 +090033// IPV4 addresses are always specified in singular dotted-form (a.b.c.d)
34// (not in CIDR representation
Garrick Evansf0ab7132019-06-18 14:50:42 +090035class Datapath {
36 public:
37 // |process_runner| must not be null; it is not owned.
38 explicit Datapath(MinijailedProcessRunner* process_runner);
Garrick Evansc7ae82c2019-09-04 16:25:10 +090039 // Provided for testing only.
40 Datapath(MinijailedProcessRunner* process_runner, ioctl_t ioctl_hook);
Garrick Evansf0ab7132019-06-18 14:50:42 +090041 virtual ~Datapath() = default;
42
Garrick Evans8a949dc2019-07-18 16:17:53 +090043 virtual bool AddBridge(const std::string& ifname,
Garrick Evans7a1a9ee2020-01-28 11:03:57 +090044 uint32_t ipv4_addr,
45 uint32_t ipv4_prefix_len);
Garrick Evans8a949dc2019-07-18 16:17:53 +090046 virtual void RemoveBridge(const std::string& ifname);
47
Garrick Evans621ed262019-11-13 12:28:43 +090048 virtual bool AddToBridge(const std::string& br_ifname,
49 const std::string& ifname);
50
Garrick Evansc7ae82c2019-09-04 16:25:10 +090051 // Adds a new TAP device.
52 // |name| may be empty, in which case a default device name will be used;
53 // it may be a template (e.g. vmtap%d), in which case the kernel will
54 // generate the name; or it may be fully defined. In all cases, upon success,
55 // the function returns the actual name of the interface.
Garrick Evans621ed262019-11-13 12:28:43 +090056 // |mac_addr| and |ipv4_addr| should be null if this interface will be later
57 // bridged.
Garrick Evans4f9f5572019-11-26 10:25:16 +090058 // If |user| is empty, no owner will be set
Garrick Evansc7ae82c2019-09-04 16:25:10 +090059 virtual std::string AddTAP(const std::string& name,
Garrick Evans621ed262019-11-13 12:28:43 +090060 const MacAddress* mac_addr,
61 const SubnetAddress* ipv4_addr,
Garrick Evans4f9f5572019-11-26 10:25:16 +090062 const std::string& user);
Garrick Evansc7ae82c2019-09-04 16:25:10 +090063
64 // |ifname| must be the actual name of the interface.
65 virtual void RemoveTAP(const std::string& ifname);
66
67 // The following are iptables methods.
68 // When specified, |ipv4_addr| is always singlar dotted-form (a.b.c.d)
69 // IPv4 address (not a CIDR representation).
70
Hugo Benichi76675592020-04-08 14:29:57 +090071 // Creates a virtual interface pair split across the current namespace and the
72 // namespace corresponding to |pid|, and set up the remote interface
73 // |peer_ifname| according // to the given parameters.
74 virtual bool ConnectVethPair(pid_t pid,
75 const std::string& veth_ifname,
76 const std::string& peer_ifname,
77 const MacAddress& remote_mac_addr,
78 uint32_t remote_ipv4_addr,
79 uint32_t remote_ipv4_prefix_len,
80 bool remote_multicast_flag);
81
Garrick Evans2470caa2020-03-04 14:15:41 +090082 // Creates a virtual interface pair.
83 virtual bool AddVirtualInterfacePair(const std::string& veth_ifname,
84 const std::string& peer_ifname);
85
86 // Sets the link status.
87 virtual bool ToggleInterface(const std::string& ifname, bool up);
88
89 // Sets the configuration of an interface.
90 virtual bool ConfigureInterface(const std::string& ifname,
91 const MacAddress& mac_addr,
92 uint32_t ipv4_addr,
93 uint32_t ipv4_prefix_len,
94 bool up,
95 bool enable_multicast);
96
Garrick Evans54861622019-07-19 09:05:09 +090097 virtual void RemoveInterface(const std::string& ifname);
98
Garrick Evansf0ab7132019-06-18 14:50:42 +090099 // Create (or flush and delete) pre-routing rules supporting legacy (ARC N)
100 // single networking DNAT configuration.
101 virtual bool AddLegacyIPv4DNAT(const std::string& ipv4_addr);
102 virtual void RemoveLegacyIPv4DNAT();
103
Garrick Evans54861622019-07-19 09:05:09 +0900104 // Enable ingress traffic from a specific physical device to the legacy
105 // single networkng DNAT configuration.
106 virtual bool AddLegacyIPv4InboundDNAT(const std::string& ifname);
107 virtual void RemoveLegacyIPv4InboundDNAT();
108
Garrick Evansf0ab7132019-06-18 14:50:42 +0900109 // Create (or delete) pre-routing rules allowing direct ingress on |ifname|
110 // to guest desintation |ipv4_addr|.
111 virtual bool AddInboundIPv4DNAT(const std::string& ifname,
112 const std::string& ipv4_addr);
113 virtual void RemoveInboundIPv4DNAT(const std::string& ifname,
114 const std::string& ipv4_addr);
115
116 // Create (or delete) a forwarding rule for |ifname|.
117 virtual bool AddOutboundIPv4(const std::string& ifname);
118 virtual void RemoveOutboundIPv4(const std::string& ifname);
119
Hugo Benichie8758b52020-04-03 14:49:01 +0900120 // Create (or delete) a mangle PREROUTING rule for marking IPv4 traffic
121 // outgoing of |ifname| with the SNAT fwmark value 0x1.
122 // TODO(hugobenichi) Refer to RoutingService to obtain the fwmark value and
123 // add a fwmark mask in the generated rule.
124 virtual bool AddOutboundIPv4SNATMark(const std::string& ifname);
125 virtual void RemoveOutboundIPv4SNATMark(const std::string& ifname);
126
Taoyu Li90c13912019-11-26 17:56:54 +0900127 // Methods supporting IPv6 configuration for ARC.
Garrick Evans664a82f2019-12-17 12:18:05 +0900128 virtual bool MaskInterfaceFlags(const std::string& ifname,
129 uint16_t on,
130 uint16_t off = 0);
Garrick Evans260ff302019-07-25 11:22:50 +0900131
Taoyu Li90c13912019-11-26 17:56:54 +0900132 virtual bool AddIPv6Forwarding(const std::string& ifname1,
133 const std::string& ifname2);
134 virtual void RemoveIPv6Forwarding(const std::string& ifname1,
135 const std::string& ifname2);
136
Garrick Evans260ff302019-07-25 11:22:50 +0900137 virtual bool AddIPv6HostRoute(const std::string& ifname,
138 const std::string& ipv6_addr,
139 int ipv6_prefix_len);
140 virtual void RemoveIPv6HostRoute(const std::string& ifname,
141 const std::string& ipv6_addr,
142 int ipv6_prefix_len);
143
144 virtual bool AddIPv6Neighbor(const std::string& ifname,
145 const std::string& ipv6_addr);
146 virtual void RemoveIPv6Neighbor(const std::string& ifname,
147 const std::string& ipv6_addr);
148
Hugo Benichie8758b52020-04-03 14:49:01 +0900149 // Adds (or deletes) a route to direct to |gateway_addr| the traffic destined
150 // to the subnet defined by |addr| and |netmask|.
Garrick Evans3d97a392020-02-21 15:24:37 +0900151 virtual bool AddIPv4Route(uint32_t gateway_addr,
152 uint32_t addr,
153 uint32_t netmask);
Hugo Benichie8758b52020-04-03 14:49:01 +0900154 virtual bool DeleteIPv4Route(uint32_t gateway_addr,
155 uint32_t addr,
156 uint32_t netmask);
157 // Adds (or deletes) a route to direct to |ifname| the traffic destined to the
158 // subnet defined by |addr| and |netmask|.
159 virtual bool AddIPv4Route(const std::string& ifname,
160 uint32_t addr,
161 uint32_t netmask);
162 virtual bool DeleteIPv4Route(const std::string& ifname,
163 uint32_t addr,
164 uint32_t netmask);
Garrick Evans3d97a392020-02-21 15:24:37 +0900165
Garrick Evans260ff302019-07-25 11:22:50 +0900166 MinijailedProcessRunner& runner() const;
167
Garrick Evansf0ab7132019-06-18 14:50:42 +0900168 private:
169 MinijailedProcessRunner* process_runner_;
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900170 ioctl_t ioctl_;
Garrick Evansf0ab7132019-06-18 14:50:42 +0900171
Hugo Benichie8758b52020-04-03 14:49:01 +0900172 bool ModifyRtentry(unsigned long op, struct rtentry* route);
173
Garrick Evansf0ab7132019-06-18 14:50:42 +0900174 DISALLOW_COPY_AND_ASSIGN(Datapath);
175};
176
Garrick Evans3388a032020-03-24 11:25:55 +0900177} // namespace patchpanel
Garrick Evansf0ab7132019-06-18 14:50:42 +0900178
Garrick Evans3388a032020-03-24 11:25:55 +0900179#endif // PATCHPANEL_DATAPATH_H_