1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332
|
/* SPDX-License-Identifier: GPL-2.0-or-later
* Copyright (c) 2021 Red Hat GmbH
* Author: Stefano Brivio <sbrivio@redhat.com>
*/
#ifndef PASST_H
#define PASST_H
#define UNIX_SOCK_MAX 100
#define UNIX_SOCK_PATH "/tmp/passt_%i.socket"
union epoll_ref;
#include <stdbool.h>
#include <assert.h>
#include <sys/epoll.h>
#include "pif.h"
#include "packet.h"
#include "siphash.h"
#include "ip.h"
#include "inany.h"
#include "migrate.h"
#include "flow.h"
#include "icmp.h"
#include "fwd.h"
#include "tcp.h"
#include "udp.h"
#include "vhost_user.h"
/* Default address for our end on the tap interface. Bit 0 of byte 0 must be 0
* (unicast) and bit 1 of byte 1 must be 1 (locally administered). Otherwise
* it's arbitrary.
*/
#define MAC_OUR_LAA \
((uint8_t [ETH_ALEN]){0x9a, 0x55, 0x9a, 0x55, 0x9a, 0x55})
/**
* union epoll_ref - Breakdown of reference for epoll fd bookkeeping
* @type: Type of fd (tells us what to do with events)
* @fd: File descriptor number (implies < 2^24 total descriptors)
* @flow: Index of the flow this fd is linked to
* @tcp_listen: TCP-specific reference part for listening sockets
* @udp: UDP-specific reference part
* @icmp: ICMP-specific reference part
* @data: Data handled by protocol handlers
* @nsdir_fd: netns dirfd for fallback timer checking if namespace is gone
* @queue: vhost-user queue index for this fd
* @u64: Opaque reference for epoll_ctl() and epoll_wait()
*/
union epoll_ref {
struct {
enum epoll_type type:8;
#define FD_REF_BITS 24
#define FD_REF_MAX ((int)MAX_FROM_BITS(FD_REF_BITS))
int32_t fd:FD_REF_BITS;
union {
uint32_t flow;
flow_sidx_t flowside;
union tcp_listen_epoll_ref tcp_listen;
union udp_listen_epoll_ref udp;
uint32_t data;
int nsdir_fd;
int queue;
};
};
uint64_t u64;
};
static_assert(sizeof(union epoll_ref) <= sizeof(union epoll_data),
"epoll_ref must have same size as epoll_data");
/* Large enough for ~128 maximum size frames */
#define PKT_BUF_BYTES (8UL << 20)
extern char pkt_buf [PKT_BUF_BYTES];
extern char *epoll_type_str[];
#define EPOLL_TYPE_STR(n) \
(((uint8_t)(n) < EPOLL_NUM_TYPES && epoll_type_str[(n)]) ? \
epoll_type_str[(n)] : "?")
#include <resolv.h> /* For MAXNS below */
/**
* struct fqdn - Representation of fully-qualified domain name
* @n: Domain name string
*/
struct fqdn {
char n[NS_MAXDNAME];
};
#include <net/if.h>
#include <linux/un.h>
enum passt_modes {
MODE_PASST,
MODE_PASTA,
MODE_VU,
};
/**
* struct ip4_ctx - IPv4 execution context
* @addr: IPv4 address assigned to guest
* @addr_seen: Latest IPv4 address seen as source from tap
* @prefixlen: IPv4 prefix length (netmask)
* @guest_gw: IPv4 gateway as seen by the guest
* @map_host_loopback: Outbound connections to this address are NATted to the
* host's 127.0.0.1
* @map_guest_addr: Outbound connections to this address are NATted to the
* guest's assigned address
* @dns: DNS addresses for DHCP, zero-terminated
* @dns_match: Forward DNS query if sent to this address
* @our_tap_addr: IPv4 address for passt's use on tap
* @dns_host: Use this DNS on the host for forwarding
* @addr_out: Optional source address for outbound traffic
* @ifname_out: Optional interface name to bind outbound sockets to
* @no_copy_routes: Don't copy all routes when configuring target namespace
* @no_copy_addrs: Don't copy all addresses when configuring namespace
*/
struct ip4_ctx {
/* PIF_TAP addresses */
struct in_addr addr;
struct in_addr addr_seen;
int prefix_len;
struct in_addr guest_gw;
struct in_addr map_host_loopback;
struct in_addr map_guest_addr;
struct in_addr dns[MAXNS + 1];
struct in_addr dns_match;
struct in_addr our_tap_addr;
/* PIF_HOST addresses */
struct in_addr dns_host;
struct in_addr addr_out;
char ifname_out[IFNAMSIZ];
bool no_copy_routes;
bool no_copy_addrs;
};
/**
* struct ip6_ctx - IPv6 execution context
* @addr: IPv6 address assigned to guest
* @addr_seen: Latest IPv6 global/site address seen as source from tap
* @addr_ll_seen: Latest IPv6 link-local address seen as source from tap
* @guest_gw: IPv6 gateway as seen by the guest
* @map_host_loopback: Outbound connections to this address are NATted to the
* host's [::1]
* @map_guest_addr: Outbound connections to this address are NATted to the
* guest's assigned address
* @dns: DNS addresses for DHCPv6 and NDP, zero-terminated
* @dns_match: Forward DNS query if sent to this address
* @our_tap_ll: Link-local IPv6 address for passt's use on tap
* @dns_host: Use this DNS on the host for forwarding
* @addr_out: Optional source address for outbound traffic
* @ifname_out: Optional interface name to bind outbound sockets to
* @no_copy_routes: Don't copy all routes when configuring target namespace
* @no_copy_addrs: Don't copy all addresses when configuring namespace
*/
struct ip6_ctx {
/* PIF_TAP addresses */
struct in6_addr addr;
struct in6_addr addr_seen;
struct in6_addr addr_ll_seen;
struct in6_addr guest_gw;
struct in6_addr map_host_loopback;
struct in6_addr map_guest_addr;
struct in6_addr dns[MAXNS + 1];
struct in6_addr dns_match;
struct in6_addr our_tap_ll;
/* PIF_HOST addresses */
struct in6_addr dns_host;
struct in6_addr addr_out;
char ifname_out[IFNAMSIZ];
bool no_copy_routes;
bool no_copy_addrs;
};
#include <netinet/if_ether.h>
/**
* struct ctx - Execution context
* @mode: Operation mode, qemu/UNIX domain socket or namespace/tap
* @debug: Enable debug mode
* @trace: Enable tracing (extra debug) mode
* @stats: Events statistics delay (0 means disabled)
* @quiet: Don't print informational messages
* @foreground: Run in foreground, don't log to stderr by default
* @nofile: Maximum number of open files (ulimit -n)
* @sock_path: Path for UNIX domain socket
* @repair_path: TCP_REPAIR helper path, can be "none", empty for default
* @pcap: Path for packet capture file
* @pidfile: Path to PID file, empty string if not configured
* @pidfile_fd: File descriptor for PID file, -1 if none
* @pasta_netns_fd: File descriptor for network namespace in pasta mode
* @no_netns_quit: In pasta mode, don't exit if fs-bound namespace is gone
* @netns_base: Base name for fs-bound namespace, if any, in pasta mode
* @netns_dir: Directory of fs-bound namespace, if any, in pasta mode
* @epollfd: File descriptor for epoll instance
* @fd_tap_listen: File descriptor for listening AF_UNIX socket, if any
* @fd_tap: AF_UNIX socket, tuntap device, or pre-opened socket
* @fd_repair_listen: File descriptor for listening TCP_REPAIR socket, if any
* @fd_repair: Connected AF_UNIX socket for TCP_REPAIR helper
* @our_tap_mac: Pasta/passt's MAC on the tap link
* @guest_mac: MAC address of guest or namespace, seen or configured
* @hash_secret: 128-bit secret for siphash functions
* @ifi4: Template interface for IPv4, -1: none, 0: IPv4 disabled
* @ip4: IPv4 configuration
* @dns_search: DNS search list
* @hostname: Guest hostname
* @fqdn: Guest FQDN
* @ifi6: Template interface for IPv6, -1: none, 0: IPv6 disabled
* @ip6: IPv6 configuration
* @pasta_ifn: Name of namespace interface for pasta
* @pasta_ifi: Index of namespace interface for pasta
* @pasta_conf_ns: Configure namespace after creating it
* @no_tcp: Disable TCP operation
* @tcp: Context for TCP protocol handler
* @no_tcp: Disable UDP operation
* @udp: Context for UDP protocol handler
* @no_icmp: Disable ICMP operation
* @icmp: Context for ICMP protocol handler
* @mtu: MTU passed via DHCP/NDP
* @no_dns: Do not source/use DNS servers for any purpose
* @no_dns_search: Do not source/use domain search lists for any purpose
* @no_dhcp_dns: Do not assign any DNS server via DHCP/DHCPv6/NDP
* @no_dhcp_dns_search: Do not assign any DNS domain search via DHCP/DHCPv6/NDP
* @no_dhcp: Disable DHCP server
* @no_dhcpv6: Disable DHCPv6 server
* @no_ndp: Disable NDP handler altogether
* @no_ra: Disable router advertisements
* @no_splice: Disable socket splicing for inbound traffic
* @host_lo_to_ns_lo: Map host loopback addresses to ns loopback addresses
* @freebind: Allow binding of non-local addresses for forwarding
* @low_wmem: Low probed net.core.wmem_max
* @low_rmem: Low probed net.core.rmem_max
* @vdev: vhost-user device
* @device_state_fd: Device state migration channel
* @device_state_result: Device state migration result
* @migrate_target: Are we the target, on the next migration request?
* @migrate_no_linger: Close sockets as we migrate them
* @migrate_exit: Exit (on source) once migration is complete
*/
struct ctx {
enum passt_modes mode;
int debug;
int trace;
int stats;
int quiet;
int foreground;
int nofile;
char sock_path[UNIX_PATH_MAX];
char repair_path[UNIX_PATH_MAX];
char pcap[PATH_MAX];
char pidfile[PATH_MAX];
int pidfile_fd;
int one_off;
int pasta_netns_fd;
int no_netns_quit;
char netns_base[PATH_MAX];
char netns_dir[PATH_MAX];
int epollfd;
int fd_tap_listen;
int fd_tap;
int fd_repair_listen;
int fd_repair;
unsigned char our_tap_mac[ETH_ALEN];
unsigned char guest_mac[ETH_ALEN];
uint16_t mtu;
uint64_t hash_secret[2];
int ifi4;
struct ip4_ctx ip4;
struct fqdn dns_search[MAXDNSRCH];
char hostname[PASST_MAXDNAME];
char fqdn[PASST_MAXDNAME];
int ifi6;
struct ip6_ctx ip6;
char pasta_ifn[IF_NAMESIZE];
unsigned int pasta_ifi;
int pasta_conf_ns;
int no_tcp;
struct tcp_ctx tcp;
int no_udp;
struct udp_ctx udp;
int no_icmp;
struct icmp_ctx icmp;
int no_dns;
int no_dns_search;
int no_dhcp_dns;
int no_dhcp_dns_search;
int no_dhcp;
int no_dhcpv6;
int no_ndp;
int no_ra;
int no_splice;
int host_lo_to_ns_lo;
int freebind;
int low_wmem;
int low_rmem;
struct vu_dev *vdev;
/* Migration */
int device_state_fd;
int device_state_result;
bool migrate_target;
bool migrate_no_linger;
bool migrate_exit;
};
void proto_update_l2_buf(const unsigned char *eth_d,
const unsigned char *eth_s);
#endif /* PASST_H */
|