port_fwd: Don't NS_CALL get_bound_ports()

When we want to scan for bound ports in the namespace we use NS_CALL() to
run get_bound_ports() in the namespace.  However, the only thing it
actually needed to be in the namespace for was to open the /proc/net file
it was scanning.  Since we now always pre-open those, we no longer need
to switch to the namespace for the actual get_bound_ports() calls.

That in turn means that tcp_port_detect() doesn't need to run in the ns
either, and we can just replace it with inline calls to get_bound_ports().

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
This commit is contained in:
David Gibson 2023-11-03 13:23:00 +11:00 committed by Stefano Brivio
parent 5a0485425b
commit 180dbc957a
2 changed files with 4 additions and 71 deletions

View file

@ -109,43 +109,12 @@ void get_bound_ports(struct ctx *c, int ns, uint8_t proto)
} }
} }
/**
* struct get_bound_ports_ns_arg - Arguments for get_bound_ports_ns()
* @c: Execution context
* @proto: Protocol number (IPPROTO_TCP or IPPROTO_UDP)
*/
struct get_bound_ports_ns_arg {
struct ctx *c;
uint8_t proto;
};
/**
* get_bound_ports_ns() - Get maps of ports in namespace with bound sockets
* @arg: See struct get_bound_ports_ns_arg
*
* Return: 0
*/
static int get_bound_ports_ns(void *arg)
{
struct get_bound_ports_ns_arg *a = (struct get_bound_ports_ns_arg *)arg;
struct ctx *c = a->c;
if (!c->pasta_netns_fd)
return 0;
ns_enter(c);
get_bound_ports(c, 1, a->proto);
return 0;
}
/** /**
* port_fwd_init() - Initial setup for port forwarding * port_fwd_init() - Initial setup for port forwarding
* @c: Execution context * @c: Execution context
*/ */
void port_fwd_init(struct ctx *c) void port_fwd_init(struct ctx *c)
{ {
struct get_bound_ports_ns_arg ns_ports_arg = { .c = c };
const int flags = O_RDONLY | O_CLOEXEC; const int flags = O_RDONLY | O_CLOEXEC;
c->proc_net_tcp[V4][0] = c->proc_net_tcp[V4][1] = -1; c->proc_net_tcp[V4][0] = c->proc_net_tcp[V4][1] = -1;
@ -156,14 +125,12 @@ void port_fwd_init(struct ctx *c)
if (c->tcp.fwd_in.mode == FWD_AUTO) { if (c->tcp.fwd_in.mode == FWD_AUTO) {
c->proc_net_tcp[V4][1] = open_in_ns(c, "/proc/net/tcp", flags); c->proc_net_tcp[V4][1] = open_in_ns(c, "/proc/net/tcp", flags);
c->proc_net_tcp[V6][1] = open_in_ns(c, "/proc/net/tcp6", flags); c->proc_net_tcp[V6][1] = open_in_ns(c, "/proc/net/tcp6", flags);
ns_ports_arg.proto = IPPROTO_TCP; get_bound_ports(c, 1, IPPROTO_TCP);
NS_CALL(get_bound_ports_ns, &ns_ports_arg);
} }
if (c->udp.fwd_in.f.mode == FWD_AUTO) { if (c->udp.fwd_in.f.mode == FWD_AUTO) {
c->proc_net_udp[V4][1] = open_in_ns(c, "/proc/net/udp", flags); c->proc_net_udp[V4][1] = open_in_ns(c, "/proc/net/udp", flags);
c->proc_net_udp[V6][1] = open_in_ns(c, "/proc/net/udp6", flags); c->proc_net_udp[V6][1] = open_in_ns(c, "/proc/net/udp6", flags);
ns_ports_arg.proto = IPPROTO_UDP; get_bound_ports(c, 1, IPPROTO_UDP);
NS_CALL(get_bound_ports_ns, &ns_ports_arg);
} }
if (c->tcp.fwd_out.mode == FWD_AUTO) { if (c->tcp.fwd_out.mode == FWD_AUTO) {
c->proc_net_tcp[V4][0] = open("/proc/net/tcp", flags); c->proc_net_tcp[V4][0] = open("/proc/net/tcp", flags);

38
tcp.c
View file

@ -3196,37 +3196,6 @@ int tcp_init(struct ctx *c)
return 0; return 0;
} }
/**
* struct tcp_port_detect_arg - Arguments for tcp_port_detect()
* @c: Execution context
* @detect_in_ns: Detect ports bound in namespace, not in init
*/
struct tcp_port_detect_arg {
struct ctx *c;
int detect_in_ns;
};
/**
* tcp_port_detect() - Detect ports bound in namespace or init
* @arg: See struct tcp_port_detect_arg
*
* Return: 0
*/
static int tcp_port_detect(void *arg)
{
struct tcp_port_detect_arg *a = (struct tcp_port_detect_arg *)arg;
if (a->detect_in_ns) {
ns_enter(a->c);
get_bound_ports(a->c, 1, IPPROTO_TCP);
} else {
get_bound_ports(a->c, 0, IPPROTO_TCP);
}
return 0;
}
/** /**
* struct tcp_port_rebind_arg - Arguments for tcp_port_rebind() * struct tcp_port_rebind_arg - Arguments for tcp_port_rebind()
* @c: Execution context * @c: Execution context
@ -3315,19 +3284,16 @@ void tcp_timer(struct ctx *c, const struct timespec *ts)
(void)ts; (void)ts;
if (c->mode == MODE_PASTA) { if (c->mode == MODE_PASTA) {
struct tcp_port_detect_arg detect_arg = { c, 0 };
struct tcp_port_rebind_arg rebind_arg = { c, 0 }; struct tcp_port_rebind_arg rebind_arg = { c, 0 };
if (c->tcp.fwd_out.mode == FWD_AUTO) { if (c->tcp.fwd_out.mode == FWD_AUTO) {
detect_arg.detect_in_ns = 0; get_bound_ports(c, 0, IPPROTO_TCP);
tcp_port_detect(&detect_arg);
rebind_arg.bind_in_ns = 1; rebind_arg.bind_in_ns = 1;
NS_CALL(tcp_port_rebind, &rebind_arg); NS_CALL(tcp_port_rebind, &rebind_arg);
} }
if (c->tcp.fwd_in.mode == FWD_AUTO) { if (c->tcp.fwd_in.mode == FWD_AUTO) {
detect_arg.detect_in_ns = 1; get_bound_ports(c, 1, IPPROTO_TCP);
NS_CALL(tcp_port_detect, &detect_arg);
rebind_arg.bind_in_ns = 0; rebind_arg.bind_in_ns = 0;
tcp_port_rebind(&rebind_arg); tcp_port_rebind(&rebind_arg);
} }