aboutgitcodebugslistschat
diff options
context:
space:
mode:
-rw-r--r--conf.c74
-rw-r--r--port_fwd.h12
-rw-r--r--tcp.c42
-rw-r--r--tcp.h15
-rw-r--r--tcp_splice.c4
-rw-r--r--udp.c30
-rw-r--r--udp.h27
7 files changed, 106 insertions, 98 deletions
diff --git a/conf.c b/conf.c
index 8b1437d..8940ec4 100644
--- a/conf.c
+++ b/conf.c
@@ -52,15 +52,15 @@ void get_bound_ports(struct ctx *c, int ns, uint8_t proto)
uint8_t *udp_map, *udp_excl, *tcp_map, *tcp_excl;
if (ns) {
- udp_map = c->udp.port_to_tap;
- udp_excl = c->udp.port_to_init;
- tcp_map = c->tcp.port_to_tap;
- tcp_excl = c->tcp.port_to_init;
+ udp_map = c->udp.fwd_in.f.map;
+ udp_excl = c->udp.fwd_out.f.map;
+ tcp_map = c->tcp.fwd_in.map;
+ tcp_excl = c->tcp.fwd_out.map;
} else {
- udp_map = c->udp.port_to_init;
- udp_excl = c->udp.port_to_tap;
- tcp_map = c->tcp.port_to_init;
- tcp_excl = c->tcp.port_to_tap;
+ udp_map = c->udp.fwd_out.f.map;
+ udp_excl = c->udp.fwd_in.f.map;
+ tcp_map = c->tcp.fwd_out.map;
+ tcp_excl = c->tcp.fwd_in.map;
}
if (proto == IPPROTO_UDP) {
@@ -120,23 +120,23 @@ static int conf_ports(struct ctx *c, char optname, const char *optarg,
{
int start_src, end_src, start_dst, end_dst, exclude_only = 1, i, port;
char addr_buf[sizeof(struct in6_addr)] = { 0 }, *addr = addr_buf;
- void (*remap)(in_port_t port, in_port_t delta);
+ void (*remap)(struct ctx *c, in_port_t port, in_port_t delta);
uint8_t exclude[PORT_BITMAP_SIZE] = { 0 };
char buf[BUFSIZ], *sep, *spec, *p;
sa_family_t af = AF_UNSPEC;
uint8_t *map;
if (optname == 't') {
- map = c->tcp.port_to_tap;
+ map = c->tcp.fwd_in.map;
remap = tcp_remap_to_tap;
} else if (optname == 'T') {
- map = c->tcp.port_to_init;
+ map = c->tcp.fwd_out.map;
remap = tcp_remap_to_init;
} else if (optname == 'u') {
- map = c->udp.port_to_tap;
+ map = c->udp.fwd_in.f.map;
remap = udp_remap_to_tap;
} else if (optname == 'U') {
- map = c->udp.port_to_init;
+ map = c->udp.fwd_out.f.map;
remap = udp_remap_to_init;
} else { /* For gcc -O3 */
return 0;
@@ -365,8 +365,8 @@ static int conf_ports(struct ctx *c, char optname, const char *optarg,
if (start_dst != -1) {
/* 80:8080 or 22-80:8080:8080 */
- remap(i, (in_port_t)(start_dst -
- start_src));
+ remap(c, i, (in_port_t)(start_dst -
+ start_src));
}
if (optname == 't')
@@ -1095,8 +1095,8 @@ void conf(struct ctx *c, int argc, char **argv)
if (c->mode == MODE_PASTA)
c->no_dhcp_dns = c->no_dhcp_dns_search = 1;
- c->tcp.fwd_mode_in = c->tcp.fwd_mode_out = 0;
- c->udp.fwd_mode_in = c->udp.fwd_mode_out = 0;
+ c->tcp.fwd_in.mode = c->tcp.fwd_out.mode = 0;
+ c->udp.fwd_in.f.mode = c->udp.fwd_out.f.mode = 0;
do {
const char *optstring;
@@ -1563,13 +1563,13 @@ void conf(struct ctx *c, int argc, char **argv)
case 'T':
case 'U':
if (name == 't')
- fwd = &c->tcp.fwd_mode_in;
+ fwd = &c->tcp.fwd_in.mode;
else if (name == 'T')
- fwd = &c->tcp.fwd_mode_out;
+ fwd = &c->tcp.fwd_out.mode;
else if (name == 'u')
- fwd = &c->udp.fwd_mode_in;
+ fwd = &c->udp.fwd_in.f.mode;
else if (name == 'U')
- fwd = &c->udp.fwd_mode_out;
+ fwd = &c->udp.fwd_out.f.mode;
if (!optarg || conf_ports(c, name, optarg, fwd))
usage(argv[0]);
@@ -1606,33 +1606,33 @@ void conf(struct ctx *c, int argc, char **argv)
c->proc_net_udp[V4][0] = c->proc_net_udp[V4][1] = -1;
c->proc_net_udp[V6][0] = c->proc_net_udp[V6][1] = -1;
- if (!c->tcp.fwd_mode_in || c->tcp.fwd_mode_in == FWD_AUTO) {
- c->tcp.fwd_mode_in = FWD_AUTO;
+ if (!c->tcp.fwd_in.mode || c->tcp.fwd_in.mode == FWD_AUTO) {
+ c->tcp.fwd_in.mode = FWD_AUTO;
ns_ports_arg.proto = IPPROTO_TCP;
NS_CALL(get_bound_ports_ns, &ns_ports_arg);
}
- if (!c->udp.fwd_mode_in || c->udp.fwd_mode_in == FWD_AUTO) {
- c->udp.fwd_mode_in = FWD_AUTO;
+ if (!c->udp.fwd_in.f.mode || c->udp.fwd_in.f.mode == FWD_AUTO) {
+ c->udp.fwd_in.f.mode = FWD_AUTO;
ns_ports_arg.proto = IPPROTO_UDP;
NS_CALL(get_bound_ports_ns, &ns_ports_arg);
}
- if (!c->tcp.fwd_mode_out || c->tcp.fwd_mode_out == FWD_AUTO) {
- c->tcp.fwd_mode_out = FWD_AUTO;
+ if (!c->tcp.fwd_out.mode || c->tcp.fwd_out.mode == FWD_AUTO) {
+ c->tcp.fwd_out.mode = FWD_AUTO;
get_bound_ports(c, 0, IPPROTO_TCP);
}
- if (!c->udp.fwd_mode_out || c->udp.fwd_mode_out == FWD_AUTO) {
- c->udp.fwd_mode_out = FWD_AUTO;
+ if (!c->udp.fwd_out.f.mode || c->udp.fwd_out.f.mode == FWD_AUTO) {
+ c->udp.fwd_out.f.mode = FWD_AUTO;
get_bound_ports(c, 0, IPPROTO_UDP);
}
} else {
- if (!c->tcp.fwd_mode_in)
- c->tcp.fwd_mode_in = FWD_NONE;
- if (!c->tcp.fwd_mode_out)
- c->tcp.fwd_mode_out= FWD_NONE;
- if (!c->udp.fwd_mode_in)
- c->udp.fwd_mode_in = FWD_NONE;
- if (!c->udp.fwd_mode_out)
- c->udp.fwd_mode_out = FWD_NONE;
+ if (!c->tcp.fwd_in.mode)
+ c->tcp.fwd_in.mode = FWD_NONE;
+ if (!c->tcp.fwd_out.mode)
+ c->tcp.fwd_out.mode = FWD_NONE;
+ if (!c->udp.fwd_in.f.mode)
+ c->udp.fwd_in.f.mode = FWD_NONE;
+ if (!c->udp.fwd_out.f.mode)
+ c->udp.fwd_out.f.mode = FWD_NONE;
}
if (!c->quiet)
diff --git a/port_fwd.h b/port_fwd.h
index b938022..7e6a7d7 100644
--- a/port_fwd.h
+++ b/port_fwd.h
@@ -16,4 +16,16 @@ enum port_fwd_mode {
#define PORT_BITMAP_SIZE DIV_ROUND_UP(USHRT_MAX, 8)
+/**
+ * port_fwd - Describes port forwarding for one protocol and direction
+ * @mode: Overall forwarding mode (all, none, auto, specific ports)
+ * @map: Bitmap describing which ports are forwarded
+ * @delta: Offset between the original destination and mapped port number
+ */
+struct port_fwd {
+ enum port_fwd_mode mode;
+ uint8_t map[PORT_BITMAP_SIZE];
+ in_port_t delta[USHRT_MAX];
+};
+
#endif /* PORT_FWD_H */
diff --git a/tcp.c b/tcp.c
index 0bdef7f..e44177f 100644
--- a/tcp.c
+++ b/tcp.c
@@ -546,10 +546,6 @@ static const char *tcp_flag_str[] __attribute((__unused__)) = {
"ACK_TO_TAP_DUE", "ACK_FROM_TAP_DUE",
};
-/* Port re-mappings as delta, indexed by original destination port */
-static in_port_t tcp_port_delta_to_tap [USHRT_MAX];
-static in_port_t tcp_port_delta_to_init [USHRT_MAX];
-
/* Listening sockets, used for automatic port forwarding in pasta mode only */
static int tcp_sock_init_lo [USHRT_MAX][IP_VERSIONS];
static int tcp_sock_init_ext [USHRT_MAX][IP_VERSIONS];
@@ -954,22 +950,24 @@ static void conn_event_do(const struct ctx *c, struct tcp_conn *conn,
/**
* tcp_remap_to_tap() - Set delta for port translation toward guest/tap
+ * @c: Execution context
* @port: Original destination port, host order
* @delta: Delta to be added to original destination port
*/
-void tcp_remap_to_tap(in_port_t port, in_port_t delta)
+void tcp_remap_to_tap(struct ctx *c, in_port_t port, in_port_t delta)
{
- tcp_port_delta_to_tap[port] = delta;
+ c->tcp.fwd_in.delta[port] = delta;
}
/**
* tcp_remap_to_tap() - Set delta for port translation toward init namespace
+ * @c: Execution context
* @port: Original destination port, host order
* @delta: Delta to be added to original destination port
*/
-void tcp_remap_to_init(in_port_t port, in_port_t delta)
+void tcp_remap_to_init(struct ctx *c, in_port_t port, in_port_t delta)
{
- tcp_port_delta_to_init[port] = delta;
+ c->tcp.fwd_out.delta[port] = delta;
}
/**
@@ -3109,11 +3107,9 @@ void tcp_sock_init(const struct ctx *c, int ns, sa_family_t af,
int s;
if (ns) {
- tref.tcp.index = (in_port_t)(port +
- tcp_port_delta_to_init[port]);
+ tref.tcp.index = (in_port_t)(port + c->tcp.fwd_out.delta[port]);
} else {
- tref.tcp.index = (in_port_t)(port +
- tcp_port_delta_to_tap[port]);
+ tref.tcp.index = (in_port_t)(port + c->tcp.fwd_in.delta[port]);
}
if (af == AF_INET || af == AF_UNSPEC) {
@@ -3133,7 +3129,7 @@ void tcp_sock_init(const struct ctx *c, int ns, sa_family_t af,
else
s = -1;
- if (c->tcp.fwd_mode_in == FWD_AUTO)
+ if (c->tcp.fwd_in.mode == FWD_AUTO)
tcp_sock_init_ext[port][V4] = s;
}
@@ -3148,7 +3144,7 @@ void tcp_sock_init(const struct ctx *c, int ns, sa_family_t af,
else
s = -1;
- if (c->tcp.fwd_mode_out == FWD_AUTO) {
+ if (c->tcp.fwd_out.mode == FWD_AUTO) {
if (ns)
tcp_sock_ns[port][V4] = s;
else
@@ -3174,7 +3170,7 @@ void tcp_sock_init(const struct ctx *c, int ns, sa_family_t af,
else
s = -1;
- if (c->tcp.fwd_mode_in == FWD_AUTO)
+ if (c->tcp.fwd_in.mode == FWD_AUTO)
tcp_sock_init_ext[port][V6] = s;
}
@@ -3189,7 +3185,7 @@ void tcp_sock_init(const struct ctx *c, int ns, sa_family_t af,
else
s = -1;
- if (c->tcp.fwd_mode_out == FWD_AUTO) {
+ if (c->tcp.fwd_out.mode == FWD_AUTO) {
if (ns)
tcp_sock_ns[port][V6] = s;
else
@@ -3213,7 +3209,7 @@ static int tcp_sock_init_ns(void *arg)
ns_enter(c);
for (port = 0; port < USHRT_MAX; port++) {
- if (!bitmap_isset(c->tcp.port_to_init, port))
+ if (!bitmap_isset(c->tcp.fwd_out.map, port))
continue;
tcp_sock_init(c, 1, AF_UNSPEC, NULL, port);
@@ -3413,7 +3409,7 @@ static int tcp_port_rebind(void *arg)
ns_enter(a->c);
for (port = 0; port < USHRT_MAX; port++) {
- if (!bitmap_isset(a->c->tcp.port_to_init, port)) {
+ if (!bitmap_isset(a->c->tcp.fwd_out.map, port)) {
if (tcp_sock_ns[port][V4] >= 0) {
close(tcp_sock_ns[port][V4]);
tcp_sock_ns[port][V4] = -1;
@@ -3428,7 +3424,7 @@ static int tcp_port_rebind(void *arg)
}
/* Don't loop back our own ports */
- if (bitmap_isset(a->c->tcp.port_to_tap, port))
+ if (bitmap_isset(a->c->tcp.fwd_in.map, port))
continue;
if ((a->c->ifi4 && tcp_sock_ns[port][V4] == -1) ||
@@ -3437,7 +3433,7 @@ static int tcp_port_rebind(void *arg)
}
} else {
for (port = 0; port < USHRT_MAX; port++) {
- if (!bitmap_isset(a->c->tcp.port_to_tap, port)) {
+ if (!bitmap_isset(a->c->tcp.fwd_in.map, port)) {
if (tcp_sock_init_ext[port][V4] >= 0) {
close(tcp_sock_init_ext[port][V4]);
tcp_sock_init_ext[port][V4] = -1;
@@ -3461,7 +3457,7 @@ static int tcp_port_rebind(void *arg)
}
/* Don't loop back our own ports */
- if (bitmap_isset(a->c->tcp.port_to_init, port))
+ if (bitmap_isset(a->c->tcp.fwd_out.map, port))
continue;
if ((a->c->ifi4 && tcp_sock_init_ext[port][V4] == -1) ||
@@ -3489,14 +3485,14 @@ void tcp_timer(struct ctx *c, const struct timespec *ts)
struct tcp_port_detect_arg detect_arg = { c, 0 };
struct tcp_port_rebind_arg rebind_arg = { c, 0 };
- if (c->tcp.fwd_mode_in == FWD_AUTO) {
+ if (c->tcp.fwd_in.mode == FWD_AUTO) {
detect_arg.detect_in_ns = 0;
tcp_port_detect(&detect_arg);
rebind_arg.bind_in_ns = 1;
NS_CALL(tcp_port_rebind, &rebind_arg);
}
- if (c->tcp.fwd_mode_out == FWD_AUTO) {
+ if (c->tcp.fwd_out.mode == FWD_AUTO) {
detect_arg.detect_in_ns = 1;
NS_CALL(tcp_port_detect, &detect_arg);
rebind_arg.bind_in_ns = 0;
diff --git a/tcp.h b/tcp.h
index ed797d9..502b096 100644
--- a/tcp.h
+++ b/tcp.h
@@ -29,8 +29,8 @@ void tcp_defer_handler(struct ctx *c);
void tcp_sock_set_bufsize(const struct ctx *c, int s);
void tcp_update_l2_buf(const unsigned char *eth_d, const unsigned char *eth_s,
const uint32_t *ip_da);
-void tcp_remap_to_tap(in_port_t port, in_port_t delta);
-void tcp_remap_to_init(in_port_t port, in_port_t delta);
+void tcp_remap_to_tap(struct ctx *c, in_port_t port, in_port_t delta);
+void tcp_remap_to_init(struct ctx *c, in_port_t port, in_port_t delta);
/**
* union tcp_epoll_ref - epoll reference portion for TCP connections
@@ -58,9 +58,8 @@ union tcp_epoll_ref {
* @conn_count: Count of connections (not spliced) in connection table
* @splice_conn_count: Count of spliced connections in connection table
* @port_to_tap: Ports bound host-side, packets to tap or spliced
- * @fwd_mode_in: Port forwarding mode for inbound packets
- * @port_to_init: Ports bound namespace-side, spliced to init
- * @fwd_mode_out: Port forwarding mode for outbound packets
+ * @fwd_in: Port forwarding configuration for inbound packets
+ * @fwd_out: Port forwarding configuration for outbound packets
* @timer_run: Timestamp of most recent timer run
* @kernel_snd_wnd: Kernel reports sending window (with commit 8f7baad7f035)
* @pipe_size: Size of pipes for spliced connections
@@ -69,10 +68,8 @@ struct tcp_ctx {
uint64_t hash_secret[2];
int conn_count;
int splice_conn_count;
- uint8_t port_to_tap [PORT_BITMAP_SIZE];
- enum port_fwd_mode fwd_mode_in;
- uint8_t port_to_init [PORT_BITMAP_SIZE];
- enum port_fwd_mode fwd_mode_out;
+ struct port_fwd fwd_in;
+ struct port_fwd fwd_out;
struct timespec timer_run;
#ifdef HAS_SND_WND
int kernel_snd_wnd;
diff --git a/tcp_splice.c b/tcp_splice.c
index 61e9b23..edbcfd4 100644
--- a/tcp_splice.c
+++ b/tcp_splice.c
@@ -514,7 +514,7 @@ static int tcp_splice_new(const struct ctx *c, struct tcp_splice_conn *conn,
struct tcp_splice_connect_ns_arg ns_arg = { c, conn, port, 0 };
int *p, i, s = -1;
- if (bitmap_isset(c->tcp.port_to_tap, port))
+ if (bitmap_isset(c->tcp.fwd_in.map, port))
p = CONN_V6(conn) ? ns_sock_pool6 : ns_sock_pool4;
else
p = CONN_V6(conn) ? init_sock_pool6 : init_sock_pool4;
@@ -525,7 +525,7 @@ static int tcp_splice_new(const struct ctx *c, struct tcp_splice_conn *conn,
break;
}
- if (s < 0 && bitmap_isset(c->tcp.port_to_tap, port)) {
+ if (s < 0 && bitmap_isset(c->tcp.fwd_in.map, port)) {
NS_CALL(tcp_splice_connect_ns, &ns_arg);
return ns_arg.ret;
}
diff --git a/udp.c b/udp.c
index 0b4e134..38bb8d8 100644
--- a/udp.c
+++ b/udp.c
@@ -166,12 +166,6 @@ struct udp_splice_port {
static struct udp_tap_port udp_tap_map [IP_VERSIONS][USHRT_MAX];
static struct udp_splice_port udp_splice_map [IP_VERSIONS][USHRT_MAX];
-/* Port re-mappings as delta, indexed by original destination port */
-static in_port_t udp_port_delta_to_tap [USHRT_MAX];
-static in_port_t udp_port_delta_from_tap [USHRT_MAX];
-static in_port_t udp_port_delta_to_init [USHRT_MAX];
-static in_port_t udp_port_delta_from_init[USHRT_MAX];
-
enum udp_act_type {
UDP_ACT_TAP,
UDP_ACT_NS_CONN,
@@ -265,24 +259,26 @@ static struct mmsghdr udp_mmh_sendto [UDP_SPLICE_FRAMES];
/**
* udp_remap_to_tap() - Set delta for port translation to/from guest/tap
+ * @c: Execution context
* @port: Original destination port, host order
* @delta: Delta to be added to original destination port
*/
-void udp_remap_to_tap(in_port_t port, in_port_t delta)
+void udp_remap_to_tap(struct ctx *c, in_port_t port, in_port_t delta)
{
- udp_port_delta_to_tap[port] = delta;
- udp_port_delta_from_tap[port + delta] = USHRT_MAX - delta;
+ c->udp.fwd_in.f.delta[port] = delta;
+ c->udp.fwd_in.rdelta[port + delta] = USHRT_MAX - delta;
}
/**
* udp_remap_to_init() - Set delta for port translation to/from init namespace
+ * @c: Execution context
* @port: Original destination port, host order
* @delta: Delta to be added to original destination port
*/
-void udp_remap_to_init(in_port_t port, in_port_t delta)
+void udp_remap_to_init(struct ctx *c, in_port_t port, in_port_t delta)
{
- udp_port_delta_to_init[port] = delta;
- udp_port_delta_from_init[port + delta] = USHRT_MAX - delta;
+ c->udp.fwd_out.f.delta[port] = delta;
+ c->udp.fwd_out.rdelta[port + delta] = USHRT_MAX - delta;
}
/**
@@ -583,7 +579,7 @@ static void udp_sock_handler_splice(const struct ctx *c, union epoll_ref ref,
switch (ref.r.p.udp.udp.splice) {
case UDP_TO_NS:
- src += udp_port_delta_from_init[src];
+ src += c->udp.fwd_out.rdelta[src];
if (!(s = udp_splice_map[v6][src].ns_conn_sock)) {
struct udp_splice_connect_ns_arg arg = {
@@ -603,7 +599,7 @@ static void udp_sock_handler_splice(const struct ctx *c, union epoll_ref ref,
send_dst = udp_splice_map[v6][dst].init_dst_port;
break;
case UDP_TO_INIT:
- src += udp_port_delta_from_tap[src];
+ src += c->udp.fwd_in.rdelta[src];
if (!(s = udp_splice_map[v6][src].init_conn_sock)) {
s = udp_splice_connect(c, v6, ref.r.s, src, dst,
@@ -1121,10 +1117,10 @@ void udp_sock_init(const struct ctx *c, int ns, sa_family_t af,
if (ns) {
uref.udp.port = (in_port_t)(port +
- udp_port_delta_to_init[port]);
+ c->udp.fwd_out.f.delta[port]);
} else {
uref.udp.port = (in_port_t)(port +
- udp_port_delta_to_tap[port]);
+ c->udp.fwd_in.f.delta[port]);
}
if (af == AF_INET || af == AF_UNSPEC) {
@@ -1209,7 +1205,7 @@ int udp_sock_init_ns(void *arg)
return 0;
for (dst = 0; dst < USHRT_MAX; dst++) {
- if (!bitmap_isset(c->udp.port_to_init, dst))
+ if (!bitmap_isset(c->udp.fwd_out.f.map, dst))
continue;
udp_sock_init(c, 1, AF_UNSPEC, NULL, dst);
diff --git a/udp.h b/udp.h
index 706306c..cfd1a97 100644
--- a/udp.h
+++ b/udp.h
@@ -18,8 +18,8 @@ int udp_init(const struct ctx *c);
void udp_timer(struct ctx *c, const struct timespec *ts);
void udp_update_l2_buf(const unsigned char *eth_d, const unsigned char *eth_s,
const uint32_t *ip_da);
-void udp_remap_to_tap(in_port_t port, in_port_t delta);
-void udp_remap_to_init(in_port_t port, in_port_t delta);
+void udp_remap_to_tap(struct ctx *c, in_port_t port, in_port_t delta);
+void udp_remap_to_init(struct ctx *c, in_port_t port, in_port_t delta);
/**
* union udp_epoll_ref - epoll reference portion for TCP connections
@@ -44,19 +44,26 @@ union udp_epoll_ref {
uint32_t u32;
};
+
+/**
+ * udp_port_fwd - UDP specific port forwarding configuration
+ * @f: Generic forwarding configuration
+ * @rdelta: Reversed delta map to translate source ports on return packets
+ */
+struct udp_port_fwd {
+ struct port_fwd f;
+ in_port_t rdelta[USHRT_MAX];
+};
+
/**
* struct udp_ctx - Execution context for UDP
- * @port_to_tap: Ports bound host-side, data to tap or ns L4 socket
- * @fwd_mode_in: Port forwarding mode for inbound packets
- * @port_to_init: Ports bound namespace-side, data to init L4 socket
- * @fwd_mode_out: Port forwarding mode for outbound packets
+ * @fwd_in: Port forwarding configuration for inbound packets
+ * @fwd_out: Port forwarding configuration for outbound packets
* @timer_run: Timestamp of most recent timer run
*/
struct udp_ctx {
- uint8_t port_to_tap [PORT_BITMAP_SIZE];
- enum port_fwd_mode fwd_mode_in;
- uint8_t port_to_init [PORT_BITMAP_SIZE];
- enum port_fwd_mode fwd_mode_out;
+ struct udp_port_fwd fwd_in;
+ struct udp_port_fwd fwd_out;
struct timespec timer_run;
};