Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 734942cc authored by Dave Watson's avatar Dave Watson Committed by David S. Miller
Browse files

tcp: ULP infrastructure



Add the infrustructure for attaching Upper Layer Protocols (ULPs) over TCP
sockets. Based on a similar infrastructure in tcp_cong.  The idea is that any
ULP can add its own logic by changing the TCP proto_ops structure to its own
methods.

Example usage:

setsockopt(sock, SOL_TCP, TCP_ULP, "tls", sizeof("tls"));

modules will call:
tcp_register_ulp(&tcp_tls_ulp_ops);

to register/unregister their ulp, with an init function and name.

A list of registered ulps will be returned by tcp_get_available_ulp, which is
hooked up to /proc.  Example:

$ cat /proc/sys/net/ipv4/tcp_available_ulp
tls

There is currently no functionality to remove or chain ULPs, but
it should be possible to add these in the future if needed.

Signed-off-by: default avatarBoris Pismenny <borisp@mellanox.com>
Signed-off-by: default avatarDave Watson <davejwatson@fb.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 206f60e1
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -75,6 +75,8 @@ struct inet_connection_sock_af_ops {
 * @icsk_pmtu_cookie	   Last pmtu seen by socket
 * @icsk_ca_ops		   Pluggable congestion control hook
 * @icsk_af_ops		   Operations which are AF_INET{4,6} specific
 * @icsk_ulp_ops	   Pluggable ULP control hook
 * @icsk_ulp_data	   ULP private data
 * @icsk_ca_state:	   Congestion control state
 * @icsk_retransmits:	   Number of unrecovered [RTO] timeouts
 * @icsk_pending:	   Scheduled timer event
@@ -97,6 +99,8 @@ struct inet_connection_sock {
	__u32			  icsk_pmtu_cookie;
	const struct tcp_congestion_ops *icsk_ca_ops;
	const struct inet_connection_sock_af_ops *icsk_af_ops;
	const struct tcp_ulp_ops  *icsk_ulp_ops;
	void			  *icsk_ulp_data;
	unsigned int		  (*icsk_sync_mss)(struct sock *sk, u32 pmtu);
	__u8			  icsk_ca_state:6,
				  icsk_ca_setsockopt:1,
+25 −0
Original line number Diff line number Diff line
@@ -1991,4 +1991,29 @@ static inline void tcp_listendrop(const struct sock *sk)

enum hrtimer_restart tcp_pace_kick(struct hrtimer *timer);

/*
 * Interface for adding Upper Level Protocols over TCP
 */

#define TCP_ULP_NAME_MAX	16
#define TCP_ULP_MAX		128
#define TCP_ULP_BUF_MAX		(TCP_ULP_NAME_MAX*TCP_ULP_MAX)

struct tcp_ulp_ops {
	struct list_head	list;

	/* initialize ulp */
	int (*init)(struct sock *sk);
	/* cleanup ulp */
	void (*release)(struct sock *sk);

	char		name[TCP_ULP_NAME_MAX];
	struct module	*owner;
};
int tcp_register_ulp(struct tcp_ulp_ops *type);
void tcp_unregister_ulp(struct tcp_ulp_ops *type);
int tcp_set_ulp(struct sock *sk, const char *name);
void tcp_get_available_ulp(char *buf, size_t len);
void tcp_cleanup_ulp(struct sock *sk);

#endif	/* _TCP_H */
+1 −0
Original line number Diff line number Diff line
@@ -117,6 +117,7 @@ enum {
#define TCP_SAVED_SYN		28	/* Get SYN headers recorded for connection */
#define TCP_REPAIR_WINDOW	29	/* Get/set window parameters */
#define TCP_FASTOPEN_CONNECT	30	/* Attempt FastOpen with connect */
#define TCP_ULP		31	/* Attach a ULP to a TCP connection */

struct tcp_repair_opt {
	__u32	opt_code;
+1 −1
Original line number Diff line number Diff line
@@ -8,7 +8,7 @@ obj-y := route.o inetpeer.o protocol.o \
	     inet_timewait_sock.o inet_connection_sock.o \
	     tcp.o tcp_input.o tcp_output.o tcp_timer.o tcp_ipv4.o \
	     tcp_minisocks.o tcp_cong.o tcp_metrics.o tcp_fastopen.o \
	     tcp_rate.o tcp_recovery.o \
	     tcp_rate.o tcp_recovery.o tcp_ulp.o \
	     tcp_offload.o datagram.o raw.o udp.o udplite.o \
	     udp_offload.o arp.o icmp.o devinet.o af_inet.o igmp.o \
	     fib_frontend.o fib_semantics.o fib_trie.o fib_notifier.o \
+25 −0
Original line number Diff line number Diff line
@@ -360,6 +360,25 @@ static int proc_tfo_blackhole_detect_timeout(struct ctl_table *table,
	ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos);
	if (write && ret == 0)
		tcp_fastopen_active_timeout_reset();

	return ret;
}

static int proc_tcp_available_ulp(struct ctl_table *ctl,
				  int write,
				  void __user *buffer, size_t *lenp,
				  loff_t *ppos)
{
	struct ctl_table tbl = { .maxlen = TCP_ULP_BUF_MAX, };
	int ret;

	tbl.data = kmalloc(tbl.maxlen, GFP_USER);
	if (!tbl.data)
		return -ENOMEM;
	tcp_get_available_ulp(tbl.data, TCP_ULP_BUF_MAX);
	ret = proc_dostring(&tbl, write, buffer, lenp, ppos);
	kfree(tbl.data);

	return ret;
}

@@ -685,6 +704,12 @@ static struct ctl_table ipv4_table[] = {
		.mode		= 0644,
		.proc_handler	= proc_dointvec_ms_jiffies,
	},
	{
		.procname	= "tcp_available_ulp",
		.maxlen		= TCP_ULP_BUF_MAX,
		.mode		= 0444,
		.proc_handler   = proc_tcp_available_ulp,
	},
	{
		.procname	= "icmp_msgs_per_sec",
		.data		= &sysctl_icmp_msgs_per_sec,
Loading