public inbox for passt-dev@passt.top
 help / color / mirror / code / Atom feed
From: David Gibson <david@gibson.dropbear.id.au>
To: Stefano Brivio <sbrivio@redhat.com>, passt-dev@passt.top
Cc: David Gibson <david@gibson.dropbear.id.au>
Subject: [PATCH 3/9] port_fwd: Better parameterise procfs_scan_listen()
Date: Thu,  5 Oct 2023 14:44:39 +1100	[thread overview]
Message-ID: <20231005034445.2015303-4-david@gibson.dropbear.id.au> (raw)
In-Reply-To: <20231005034445.2015303-1-david@gibson.dropbear.id.au>

procfs_scan_listen() does some slightly clunky logic to deduce the fd it
wants to use, the path it wants to open and the state it's looking for
based on parameters for protocol, IP version and whether we're in the
namespace.

However, the caller already has to make choices based on similar parameters
so it can just pass in the things that procfs_scan_listen() needs directly.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 port_fwd.c | 53 +++++++++++++++++++++++------------------------------
 1 file changed, 23 insertions(+), 30 deletions(-)

diff --git a/port_fwd.c b/port_fwd.c
index 136a450..4b54877 100644
--- a/port_fwd.c
+++ b/port_fwd.c
@@ -23,39 +23,27 @@
 #include "passt.h"
 #include "lineread.h"
 
+#define UDP_LISTEN	0x07
+#define TCP_LISTEN	0x0a
+
 /**
  * procfs_scan_listen() - Set bits for listening TCP or UDP sockets from procfs
- * @proto:	IPPROTO_TCP or IPPROTO_UDP
- * @ip_version:	IP version, V4 or V6
- * @ns:		Use saved file descriptors for namespace if set
+ * @fd:		Pointer to fd for relevant /proc/net file
+ * @path:	Path to /proc/net file to open (if fd is -1)
+ * @lstate:	Code for listening state to scan for
  * @map:	Bitmap where numbers of ports in listening state will be set
  * @exclude:	Bitmap of ports to exclude from setting (and clear)
  *
  * #syscalls:pasta lseek
  * #syscalls:pasta ppc64le:_llseek ppc64:_llseek armv6l:_llseek armv7l:_llseek
  */
-static void procfs_scan_listen(struct ctx *c, uint8_t proto, int ip_version,
-			       int ns, uint8_t *map, const uint8_t *exclude)
+static void procfs_scan_listen(int *fd, const char *path, unsigned int lstate,
+			       uint8_t *map, const uint8_t *exclude)
 {
-	char *path, *line;
 	struct lineread lr;
 	unsigned long port;
 	unsigned int state;
-	int *fd;
-
-	if (proto == IPPROTO_TCP) {
-		fd = &c->proc_net_tcp[ip_version][ns];
-		if (ip_version == V4)
-			path = "/proc/net/tcp";
-		else
-			path = "/proc/net/tcp6";
-	} else {
-		fd = &c->proc_net_udp[ip_version][ns];
-		if (ip_version == V4)
-			path = "/proc/net/udp";
-		else
-			path = "/proc/net/udp6";
-	}
+	char *line;
 
 	if (*fd != -1) {
 		if (lseek(*fd, 0, SEEK_SET)) {
@@ -74,8 +62,7 @@ static void procfs_scan_listen(struct ctx *c, uint8_t proto, int ip_version,
 			continue;
 
 		/* See enum in kernel's include/net/tcp_states.h */
-		if ((proto == IPPROTO_TCP && state != 0x0a) ||
-		    (proto == IPPROTO_UDP && state != 0x07))
+		if (state != lstate)
 			continue;
 
 		if (bitmap_isset(exclude, port))
@@ -109,15 +96,21 @@ void get_bound_ports(struct ctx *c, int ns, uint8_t proto)
 
 	if (proto == IPPROTO_UDP) {
 		memset(udp_map, 0, PORT_BITMAP_SIZE);
-		procfs_scan_listen(c, IPPROTO_UDP, V4, ns, udp_map, udp_excl);
-		procfs_scan_listen(c, IPPROTO_UDP, V6, ns, udp_map, udp_excl);
-
-		procfs_scan_listen(c, IPPROTO_TCP, V4, ns, udp_map, udp_excl);
-		procfs_scan_listen(c, IPPROTO_TCP, V6, ns, udp_map, udp_excl);
+		procfs_scan_listen(&c->proc_net_udp[V4][ns], "/proc/net/udp",
+				   UDP_LISTEN, udp_map, udp_excl);
+		procfs_scan_listen(&c->proc_net_udp[V6][ns], "/proc/net/udp6",
+				   UDP_LISTEN, udp_map, udp_excl);
+
+		procfs_scan_listen(&c->proc_net_tcp[V4][ns], "/proc/net/tcp",
+				   TCP_LISTEN, udp_map, udp_excl);
+		procfs_scan_listen(&c->proc_net_tcp[V6][ns], "/proc/net/tcp6",
+				   TCP_LISTEN, udp_map, udp_excl);
 	} else if (proto == IPPROTO_TCP) {
 		memset(tcp_map, 0, PORT_BITMAP_SIZE);
-		procfs_scan_listen(c, IPPROTO_TCP, V4, ns, tcp_map, tcp_excl);
-		procfs_scan_listen(c, IPPROTO_TCP, V6, ns, tcp_map, tcp_excl);
+		procfs_scan_listen(&c->proc_net_tcp[V4][ns], "/proc/net/tcp",
+				   TCP_LISTEN, tcp_map, tcp_excl);
+		procfs_scan_listen(&c->proc_net_tcp[V6][ns], "/proc/net/tcp6",
+				   TCP_LISTEN, tcp_map, tcp_excl);
 	}
 }
 
-- 
@@ -23,39 +23,27 @@
 #include "passt.h"
 #include "lineread.h"
 
+#define UDP_LISTEN	0x07
+#define TCP_LISTEN	0x0a
+
 /**
  * procfs_scan_listen() - Set bits for listening TCP or UDP sockets from procfs
- * @proto:	IPPROTO_TCP or IPPROTO_UDP
- * @ip_version:	IP version, V4 or V6
- * @ns:		Use saved file descriptors for namespace if set
+ * @fd:		Pointer to fd for relevant /proc/net file
+ * @path:	Path to /proc/net file to open (if fd is -1)
+ * @lstate:	Code for listening state to scan for
  * @map:	Bitmap where numbers of ports in listening state will be set
  * @exclude:	Bitmap of ports to exclude from setting (and clear)
  *
  * #syscalls:pasta lseek
  * #syscalls:pasta ppc64le:_llseek ppc64:_llseek armv6l:_llseek armv7l:_llseek
  */
-static void procfs_scan_listen(struct ctx *c, uint8_t proto, int ip_version,
-			       int ns, uint8_t *map, const uint8_t *exclude)
+static void procfs_scan_listen(int *fd, const char *path, unsigned int lstate,
+			       uint8_t *map, const uint8_t *exclude)
 {
-	char *path, *line;
 	struct lineread lr;
 	unsigned long port;
 	unsigned int state;
-	int *fd;
-
-	if (proto == IPPROTO_TCP) {
-		fd = &c->proc_net_tcp[ip_version][ns];
-		if (ip_version == V4)
-			path = "/proc/net/tcp";
-		else
-			path = "/proc/net/tcp6";
-	} else {
-		fd = &c->proc_net_udp[ip_version][ns];
-		if (ip_version == V4)
-			path = "/proc/net/udp";
-		else
-			path = "/proc/net/udp6";
-	}
+	char *line;
 
 	if (*fd != -1) {
 		if (lseek(*fd, 0, SEEK_SET)) {
@@ -74,8 +62,7 @@ static void procfs_scan_listen(struct ctx *c, uint8_t proto, int ip_version,
 			continue;
 
 		/* See enum in kernel's include/net/tcp_states.h */
-		if ((proto == IPPROTO_TCP && state != 0x0a) ||
-		    (proto == IPPROTO_UDP && state != 0x07))
+		if (state != lstate)
 			continue;
 
 		if (bitmap_isset(exclude, port))
@@ -109,15 +96,21 @@ void get_bound_ports(struct ctx *c, int ns, uint8_t proto)
 
 	if (proto == IPPROTO_UDP) {
 		memset(udp_map, 0, PORT_BITMAP_SIZE);
-		procfs_scan_listen(c, IPPROTO_UDP, V4, ns, udp_map, udp_excl);
-		procfs_scan_listen(c, IPPROTO_UDP, V6, ns, udp_map, udp_excl);
-
-		procfs_scan_listen(c, IPPROTO_TCP, V4, ns, udp_map, udp_excl);
-		procfs_scan_listen(c, IPPROTO_TCP, V6, ns, udp_map, udp_excl);
+		procfs_scan_listen(&c->proc_net_udp[V4][ns], "/proc/net/udp",
+				   UDP_LISTEN, udp_map, udp_excl);
+		procfs_scan_listen(&c->proc_net_udp[V6][ns], "/proc/net/udp6",
+				   UDP_LISTEN, udp_map, udp_excl);
+
+		procfs_scan_listen(&c->proc_net_tcp[V4][ns], "/proc/net/tcp",
+				   TCP_LISTEN, udp_map, udp_excl);
+		procfs_scan_listen(&c->proc_net_tcp[V6][ns], "/proc/net/tcp6",
+				   TCP_LISTEN, udp_map, udp_excl);
 	} else if (proto == IPPROTO_TCP) {
 		memset(tcp_map, 0, PORT_BITMAP_SIZE);
-		procfs_scan_listen(c, IPPROTO_TCP, V4, ns, tcp_map, tcp_excl);
-		procfs_scan_listen(c, IPPROTO_TCP, V6, ns, tcp_map, tcp_excl);
+		procfs_scan_listen(&c->proc_net_tcp[V4][ns], "/proc/net/tcp",
+				   TCP_LISTEN, tcp_map, tcp_excl);
+		procfs_scan_listen(&c->proc_net_tcp[V6][ns], "/proc/net/tcp6",
+				   TCP_LISTEN, tcp_map, tcp_excl);
 	}
 }
 
-- 
2.41.0


  parent reply	other threads:[~2023-10-05  3:44 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-10-05  3:44 [PATCH 0/9] Clean ups to automatic port forwarding David Gibson
2023-10-05  3:44 ` [PATCH 1/9] conf: Cleaner initialisation of default forwarding modes David Gibson
2023-10-05  3:44 ` [PATCH 2/9] port_fwd: Move automatic port forwarding code to port_fwd.[ch] David Gibson
2023-10-05  3:44 ` David Gibson [this message]
2023-11-02 18:07   ` [PATCH 3/9] port_fwd: Better parameterise procfs_scan_listen() Stefano Brivio
2023-11-03  0:16     ` David Gibson
2023-10-05  3:44 ` [PATCH 4/9] util: Add open_in_ns() helper David Gibson
2023-11-02 18:07   ` Stefano Brivio
2023-11-03  0:20     ` David Gibson
2023-10-05  3:44 ` [PATCH 5/9] port_fwd: Pre-open /proc/net/* files rather than on-demand David Gibson
2023-10-05  3:44 ` [PATCH 6/9] port_fwd: Don't NS_CALL get_bound_ports() David Gibson
2023-10-05  3:44 ` [PATCH 7/9] port_fwd: Split TCP and UDP cases for get_bound_ports() David Gibson
2023-10-05  3:44 ` [PATCH 8/9] port_fwd: Move port scanning /proc fds into struct port_fwd David Gibson
2023-10-05  3:44 ` [PATCH 9/9] port_fwd: Simplify get_bound_ports_*() to port_fwd_scan_*() David Gibson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20231005034445.2015303-4-david@gibson.dropbear.id.au \
    --to=david@gibson.dropbear.id.au \
    --cc=passt-dev@passt.top \
    --cc=sbrivio@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://passt.top/passt

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for IMAP folder(s).