-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
mptcp: Associate MPTCP context with TCP socket
Use ULP to associate a subflow_context structure with each TCP subflow socket. Creating these sockets requires new bind and connect functions to make sure ULP is set up immediately when the subflow sockets are created. Co-developed-by: Florian Westphal <fw@strlen.de> Signed-off-by: Florian Westphal <fw@strlen.de> Co-developed-by: Matthieu Baerts <matthieu.baerts@tessares.net> Signed-off-by: Matthieu Baerts <matthieu.baerts@tessares.net> Co-developed-by: Davide Caratti <dcaratti@redhat.com> Signed-off-by: Davide Caratti <dcaratti@redhat.com> Co-developed-by: Paolo Abeni <pabeni@redhat.com> Signed-off-by: Paolo Abeni <pabeni@redhat.com> Signed-off-by: Peter Krystad <peter.krystad@linux.intel.com> Signed-off-by: Christoph Paasch <cpaasch@apple.com> Signed-off-by: David S. Miller <davem@davemloft.net>
- Loading branch information
Peter Krystad
authored and
David S. Miller
committed
Jan 24, 2020
1 parent
eda7acd
commit 2303f99
Showing
5 changed files
with
275 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
# SPDX-License-Identifier: GPL-2.0 | ||
obj-$(CONFIG_MPTCP) += mptcp.o | ||
|
||
mptcp-y := protocol.o options.o | ||
mptcp-y := protocol.o subflow.o options.o |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
// SPDX-License-Identifier: GPL-2.0 | ||
/* Multipath TCP | ||
* | ||
* Copyright (c) 2017 - 2019, Intel Corporation. | ||
*/ | ||
|
||
#include <linux/kernel.h> | ||
#include <linux/module.h> | ||
#include <linux/netdevice.h> | ||
#include <net/sock.h> | ||
#include <net/inet_common.h> | ||
#include <net/inet_hashtables.h> | ||
#include <net/protocol.h> | ||
#include <net/tcp.h> | ||
#include <net/mptcp.h> | ||
#include "protocol.h" | ||
|
||
int mptcp_subflow_create_socket(struct sock *sk, struct socket **new_sock) | ||
{ | ||
struct mptcp_subflow_context *subflow; | ||
struct net *net = sock_net(sk); | ||
struct socket *sf; | ||
int err; | ||
|
||
err = sock_create_kern(net, PF_INET, SOCK_STREAM, IPPROTO_TCP, &sf); | ||
if (err) | ||
return err; | ||
|
||
lock_sock(sf->sk); | ||
|
||
/* kernel sockets do not by default acquire net ref, but TCP timer | ||
* needs it. | ||
*/ | ||
sf->sk->sk_net_refcnt = 1; | ||
get_net(net); | ||
this_cpu_add(*net->core.sock_inuse, 1); | ||
err = tcp_set_ulp(sf->sk, "mptcp"); | ||
release_sock(sf->sk); | ||
|
||
if (err) | ||
return err; | ||
|
||
subflow = mptcp_subflow_ctx(sf->sk); | ||
pr_debug("subflow=%p", subflow); | ||
|
||
*new_sock = sf; | ||
subflow->conn = sk; | ||
|
||
return 0; | ||
} | ||
|
||
static struct mptcp_subflow_context *subflow_create_ctx(struct sock *sk, | ||
gfp_t priority) | ||
{ | ||
struct inet_connection_sock *icsk = inet_csk(sk); | ||
struct mptcp_subflow_context *ctx; | ||
|
||
ctx = kzalloc(sizeof(*ctx), priority); | ||
if (!ctx) | ||
return NULL; | ||
|
||
rcu_assign_pointer(icsk->icsk_ulp_data, ctx); | ||
|
||
pr_debug("subflow=%p", ctx); | ||
|
||
ctx->tcp_sock = sk; | ||
|
||
return ctx; | ||
} | ||
|
||
static int subflow_ulp_init(struct sock *sk) | ||
{ | ||
struct mptcp_subflow_context *ctx; | ||
struct tcp_sock *tp = tcp_sk(sk); | ||
int err = 0; | ||
|
||
/* disallow attaching ULP to a socket unless it has been | ||
* created with sock_create_kern() | ||
*/ | ||
if (!sk->sk_kern_sock) { | ||
err = -EOPNOTSUPP; | ||
goto out; | ||
} | ||
|
||
ctx = subflow_create_ctx(sk, GFP_KERNEL); | ||
if (!ctx) { | ||
err = -ENOMEM; | ||
goto out; | ||
} | ||
|
||
pr_debug("subflow=%p, family=%d", ctx, sk->sk_family); | ||
|
||
tp->is_mptcp = 1; | ||
out: | ||
return err; | ||
} | ||
|
||
static void subflow_ulp_release(struct sock *sk) | ||
{ | ||
struct mptcp_subflow_context *ctx = mptcp_subflow_ctx(sk); | ||
|
||
if (!ctx) | ||
return; | ||
|
||
kfree_rcu(ctx, rcu); | ||
} | ||
|
||
static struct tcp_ulp_ops subflow_ulp_ops __read_mostly = { | ||
.name = "mptcp", | ||
.owner = THIS_MODULE, | ||
.init = subflow_ulp_init, | ||
.release = subflow_ulp_release, | ||
}; | ||
|
||
void mptcp_subflow_init(void) | ||
{ | ||
if (tcp_register_ulp(&subflow_ulp_ops) != 0) | ||
panic("MPTCP: failed to register subflows to ULP\n"); | ||
} |