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
next prev parent 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).