/* SPDX-License-Identifier: GPL-2.0-or-later * Copyright Red Hat * Author: Stefano Brivio * Author: David Gibson */ #ifndef FWD_H #define FWD_H union inany_addr; struct flowside; /* Number of ports for both TCP and UDP */ #define NUM_PORTS (1U << 16) void fwd_probe_ephemeral(void); bool fwd_port_is_ephemeral(in_port_t port); /** * struct fwd_entry - One range of ports to forward * @addr: Address to forward from * @ifname: Interface to forward from * @first: First port number to forward * @last: Last port number to forward * @to: Port number to forward port @first to. * @flags: Flag mask * FWD_DUAL_STACK - forward both IPv4 and IPv6 (requires @addr be ::) * FWD_WEAK - Don't give an error if binds fail for some forwards * FWD_SCAN - Only forward if we scan a listener on the target * * FIXME: @addr and @ifname currently ignored for outbound tables */ struct fwd_entry { union inany_addr addr; char ifname[IFNAMSIZ]; in_port_t first, last, to; #define FWD_DUAL_STACK BIT(0) #define FWD_WEAK BIT(1) #define FWD_SCAN BIT(2) uint8_t flags; }; #define MAX_FWDS 1024 enum fwd_ports_mode { FWD_UNSET = 0, FWD_SPEC = 1, FWD_NONE, FWD_AUTO, FWD_ALL, }; #define PORT_BITMAP_SIZE DIV_ROUND_UP(NUM_PORTS, 8) /** * fwd_ports() - Describes port forwarding for one protocol and direction * @mode: Overall forwarding mode (all, none, auto, specific ports) * @scan4: /proc/net fd to scan for IPv4 ports when in AUTO mode * @scan6: /proc/net fd to scan for IPv6 ports when in AUTO mode * @map: Bitmap describing which ports are forwarded * @delta: Offset between the original destination and mapped port number */ struct fwd_ports { enum fwd_ports_mode mode; int scan4; int scan6; unsigned count; struct fwd_entry tab[MAX_FWDS]; uint8_t map[PORT_BITMAP_SIZE]; in_port_t delta[NUM_PORTS]; }; #define FWD_PORT_SCAN_INTERVAL 1000 /* ms */ void fwd_table_add(struct fwd_ports *tab, uint8_t flags, const union inany_addr *addr, const char *ifname, in_port_t first, in_port_t last, in_port_t to); void fwd_table_print(const struct fwd_ports *tab); void fwd_scan_ports_init(struct ctx *c); void fwd_scan_ports_timer(struct ctx *c, const struct timespec *now); bool nat_inbound(const struct ctx *c, const union inany_addr *addr, union inany_addr *translated); uint8_t fwd_nat_from_tap(const struct ctx *c, uint8_t proto, const struct flowside *ini, struct flowside *tgt); uint8_t fwd_nat_from_splice(const struct ctx *c, uint8_t proto, const struct flowside *ini, struct flowside *tgt); uint8_t fwd_nat_from_host(const struct ctx *c, uint8_t proto, const struct flowside *ini, struct flowside *tgt); void fwd_neigh_table_update(const struct ctx *c, const union inany_addr *addr, const uint8_t *mac, bool permanent); void fwd_neigh_table_free(const struct ctx *c, const union inany_addr *addr); void fwd_neigh_mac_get(const struct ctx *c, const union inany_addr *addr, uint8_t *mac); void fwd_neigh_table_init(const struct ctx *c); #endif /* FWD_H */