netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Xin Long <lucien.xin@gmail.com>
To: David Howells <dhowells@redhat.com>
Cc: network dev <netdev@vger.kernel.org>, davem <davem@davemloft.net>,
	Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
	Willem de Bruijn <willemb@google.com>,
	Martin Varghese <martin.varghese@nokia.com>,
	Alexander Duyck <alexander.duyck@gmail.com>,
	vfedorenko@novek.ru
Subject: Re: [PATCHv4 net-next 0/2] net: enable udp v6 sockets receiving v4 packets with UDP GRO
Date: Wed, 3 Feb 2021 21:47:18 +0800	[thread overview]
Message-ID: <CADvbK_ePdoJRna81YwJUL5cqu1ST3W8J8kRqhbNVGdSse-3u1w@mail.gmail.com> (raw)
In-Reply-To: <655776.1612343656@warthog.procyon.org.uk>

[-- Attachment #1: Type: text/plain, Size: 2755 bytes --]

On Wed, Feb 3, 2021 at 5:14 PM David Howells <dhowells@redhat.com> wrote:
>
> Xin Long <lucien.xin@gmail.com> wrote:
>
> > BTW, I'm also thinking to use udp_sock_create(), the only problem I can
> > see is it may not do bind() in rxrpc_open_socket(), is that true? or we
> > can actually bind to some address when a local address is not supplied?
>
> If a local address isn't explicitly bound to the AF_RXRPC socket, binding the
> UDP socket to a random local port is fine.  In fact, sometimes I want to
> explicitly bind an rxrpc server socket to a random port.  See fs/afs/rxrpc.c
> function afs_open_socket():
>
>         /* bind the callback manager's address to make this a server socket */
>         memset(&srx, 0, sizeof(srx));
>         srx.srx_family                  = AF_RXRPC;
>         srx.srx_service                 = CM_SERVICE;
>         srx.transport_type              = SOCK_DGRAM;
>         srx.transport_len               = sizeof(srx.transport.sin6);
>         srx.transport.sin6.sin6_family  = AF_INET6;
>         srx.transport.sin6.sin6_port    = htons(AFS_CM_PORT);
>         ...
>         ret = kernel_bind(socket, (struct sockaddr *) &srx, sizeof(srx));
>         if (ret == -EADDRINUSE) {
>                 srx.transport.sin6.sin6_port = 0;
>
>                 ^^^ That's hoping to get a random port bound.
>
>                 ret = kernel_bind(socket, (struct sockaddr *) &srx, sizeof(srx));
>         }
>         if (ret < 0)
>                 goto error_2;
>
> The client cache manager server socket here is used to receive notifications
> back from the fileserver.  There's a standard port (7001) for the service, but
> if that's in use, we can use any other port.  The fileserver grabs the source
> port from incoming RPC requests - and then uses that when sending 3rd-party
> change notifications back.
>
> If you could arrange for a random port to be assigned in such a case (and
> indicated back to the caller), that would be awesome.  Possibly I just don't
> need to actually use bind in this case.
>
The patch is attached (based on this patch):

+       udp_conf.family = srx->transport.family;
+       if (udp_conf.family == AF_INET) {
+               udp_conf.local_ip = srx->transport.sin.sin_addr;
+               udp_conf.local_udp_port = srx->transport.sin.sin_port;
+       } else {
+               udp_conf.local_ip6 = srx->transport.sin6.sin6_addr;
+               udp_conf.local_udp_port = srx->transport.sin6.sin6_port;
+       }
+       ret = udp_sock_create(net, &udp_conf, &local->socket);

I think this will work well. When the socket is not bound,
srx->transport.sin.sin(6)_addr/sin(6)_port are zero. It'll
bind to a random port in udp_sock_create().

BTW: do you have any testing for this?

Thanks.

[-- Attachment #2: 0001-rxrpc-use-udp-tunnel-APIs-instead-of-open-code-in-rx.patch --]
[-- Type: application/octet-stream, Size: 4027 bytes --]

From 5748d6312ad8025f6e347a0b067b204320b1c770 Mon Sep 17 00:00:00 2001
Message-Id: <5748d6312ad8025f6e347a0b067b204320b1c770.1612359043.git.lucien.xin@gmail.com>
From: Xin Long <lucien.xin@gmail.com>
Date: Wed, 3 Feb 2021 08:25:28 -0500
Subject: [PATCH net-next] rxrpc: use udp tunnel APIs instead of open code in
 rxrpc_open_socket

Signed-off-by: Xin Long <lucien.xin@gmail.com>
---
 net/rxrpc/local_object.c | 69 ++++++++++++++--------------------------
 1 file changed, 24 insertions(+), 45 deletions(-)

diff --git a/net/rxrpc/local_object.c b/net/rxrpc/local_object.c
index 33b49367d575..546fd237a649 100644
--- a/net/rxrpc/local_object.c
+++ b/net/rxrpc/local_object.c
@@ -107,54 +107,42 @@ static struct rxrpc_local *rxrpc_alloc_local(struct rxrpc_net *rxnet,
  */
 static int rxrpc_open_socket(struct rxrpc_local *local, struct net *net)
 {
+	struct udp_tunnel_sock_cfg tuncfg = {NULL};
+	struct sockaddr_rxrpc *srx = &local->srx;
+	struct udp_port_cfg udp_conf = {0};
 	struct sock *usk;
 	int ret;
 
 	_enter("%p{%d,%d}",
-	       local, local->srx.transport_type, local->srx.transport.family);
-
-	/* create a socket to represent the local endpoint */
-	ret = sock_create_kern(net, local->srx.transport.family,
-			       local->srx.transport_type, 0, &local->socket);
+	       local, srx->transport_type, srx->transport.family);
+
+	udp_conf.family = srx->transport.family;
+	if (udp_conf.family == AF_INET) {
+		udp_conf.local_ip = srx->transport.sin.sin_addr;
+		udp_conf.local_udp_port = srx->transport.sin.sin_port;
+	} else {
+		udp_conf.local_ip6 = srx->transport.sin6.sin6_addr;
+		udp_conf.local_udp_port = srx->transport.sin6.sin6_port;
+	}
+	ret = udp_sock_create(net, &udp_conf, &local->socket);
 	if (ret < 0) {
 		_leave(" = %d [socket]", ret);
 		return ret;
 	}
 
+	tuncfg.encap_type = UDP_ENCAP_RXRPC;
+	tuncfg.encap_rcv = rxrpc_input_packet;
+	tuncfg.sk_user_data = local;
+	setup_udp_tunnel_sock(net, local->socket, &tuncfg);
+
 	/* set the socket up */
 	usk = local->socket->sk;
-	inet_sk(usk)->mc_loop = 0;
-
-	/* Enable CHECKSUM_UNNECESSARY to CHECKSUM_COMPLETE conversion */
-	inet_inc_convert_csum(usk);
-
-	rcu_assign_sk_user_data(usk, local);
-
-	udp_sk(usk)->encap_type = UDP_ENCAP_RXRPC;
-	udp_sk(usk)->encap_rcv = rxrpc_input_packet;
-	udp_sk(usk)->encap_destroy = NULL;
-	udp_sk(usk)->gro_receive = NULL;
-	udp_sk(usk)->gro_complete = NULL;
-
-	udp_tunnel_encap_enable(local->socket);
 	usk->sk_error_report = rxrpc_error_report;
 
-	/* if a local address was supplied then bind it */
-	if (local->srx.transport_len > sizeof(sa_family_t)) {
-		_debug("bind");
-		ret = kernel_bind(local->socket,
-				  (struct sockaddr *)&local->srx.transport,
-				  local->srx.transport_len);
-		if (ret < 0) {
-			_debug("bind failed %d", ret);
-			goto error;
-		}
-	}
-
-	switch (local->srx.transport.family) {
+	switch (srx->transport.family) {
 	case AF_INET6:
 		/* we want to receive ICMPv6 errors */
-		ip6_sock_set_recverr(local->socket->sk);
+		ip6_sock_set_recverr(usk);
 
 		/* Fall through and set IPv4 options too otherwise we don't get
 		 * errors from IPv4 packets sent through the IPv6 socket.
@@ -162,13 +150,13 @@ static int rxrpc_open_socket(struct rxrpc_local *local, struct net *net)
 		fallthrough;
 	case AF_INET:
 		/* we want to receive ICMP errors */
-		ip_sock_set_recverr(local->socket->sk);
+		ip_sock_set_recverr(usk);
 
 		/* we want to set the don't fragment bit */
-		ip_sock_set_mtu_discover(local->socket->sk, IP_PMTUDISC_DO);
+		ip_sock_set_mtu_discover(usk, IP_PMTUDISC_DO);
 
 		/* We want receive timestamps. */
-		sock_enable_timestamps(local->socket->sk);
+		sock_enable_timestamps(usk);
 		break;
 
 	default:
@@ -177,15 +165,6 @@ static int rxrpc_open_socket(struct rxrpc_local *local, struct net *net)
 
 	_leave(" = 0");
 	return 0;
-
-error:
-	kernel_sock_shutdown(local->socket, SHUT_RDWR);
-	local->socket->sk->sk_user_data = NULL;
-	sock_release(local->socket);
-	local->socket = NULL;
-
-	_leave(" = %d", ret);
-	return ret;
 }
 
 /*
-- 
2.18.1


  reply	other threads:[~2021-02-03 13:49 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-01-26  5:10 [PATCHv4 net-next 0/2] net: enable udp v6 sockets receiving v4 packets with UDP GRO Xin Long
2021-01-26  5:10 ` [PATCHv4 net-next 1/2] udp: call udp_encap_enable for v6 sockets when enabling encap Xin Long
2021-01-26  5:10   ` [PATCHv4 net-next 2/2] rxrpc: call udp_tunnel_encap_enable in rxrpc_open_socket Xin Long
2021-01-26  9:06   ` David Howells
2021-01-26 23:07   ` [PATCHv4 net-next 1/2] udp: call udp_encap_enable for v6 sockets when enabling encap Willem de Bruijn
2021-02-03  4:20 ` [PATCHv4 net-next 0/2] net: enable udp v6 sockets receiving v4 packets with UDP GRO Xin Long
2021-02-03  8:00 ` David Howells
2021-02-03  8:52   ` Xin Long
2021-02-03  9:14   ` David Howells
2021-02-03 13:47     ` Xin Long [this message]
2021-02-03 15:19     ` David Howells
2021-02-05  0:19     ` David Howells
2021-02-05  9:14     ` David Howells
2021-02-05  9:16       ` Xin Long

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=CADvbK_ePdoJRna81YwJUL5cqu1ST3W8J8kRqhbNVGdSse-3u1w@mail.gmail.com \
    --to=lucien.xin@gmail.com \
    --cc=alexander.duyck@gmail.com \
    --cc=davem@davemloft.net \
    --cc=dhowells@redhat.com \
    --cc=kuba@kernel.org \
    --cc=martin.varghese@nokia.com \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=vfedorenko@novek.ru \
    --cc=willemb@google.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.
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 NNTP newsgroup(s).