Commit 1b6ca07b authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'net-tls-add-socket-diag'



Davide Caratti says:

====================
net: tls: add socket diag

The current kernel does not provide any diagnostic tool, except
getsockopt(TCP_ULP), to know more about TCP sockets that have an upper
layer protocol (ULP) on top of them. This series extends the set of
information exported by INET_DIAG_INFO, to include data that are
specific to the ULP (and that might be meaningful for debug/testing
purposes).

patch 1/3 ensures that the control plane reads/updates ULP specific data
using RCU.

patch 2/3 extends INET_DIAG_INFO and allows knowing the ULP name for
each TCP socket that has done setsockopt(TCP_ULP) successfully.

patch 3/3 extends kTLS to let programs like 'ss' know the protocol
version and the cipher in use.

Changes since v2:
- remove unneeded #ifdef and fix reverse christmas tree in
  tls_get_info(), thanks to Jakub Kicinski

Changes since v1:
- don't worry about grace period when accessing ulp_ops, thanks to
  Jakub Kicinski and Eric Dumazet
- use rcu_dereference() to access ULP data in tls get_info(), and
  test against NULL value, thanks to Jakub Kicinski
- move RCU protected section inside tls get_info(), thanks to Jakub
  Kicinski

Changes since RFC:
- some coding style fixes, thanks to Jakub Kicinski
- add X_UNSPEC as lowest value of uAPI enums, thanks to Jakub Kicinski
- fix assignment of struct nlattr *start, thanks to Jakub Kicinski
- let tls dump RXCONF and TXCONF, suggested by Jakub Kicinski
- don't dump anything if TLS version or cipher are 0 (but still return a
  constant size in get_aux_size()), thanks to Boris Pismenny
- constify first argument of get_info() and get_size()
- use RCU to access access ulp_ops, like it's done for ca_ops
- add patch 1/3, from Jakub Kicinski
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents ed6e8103 26811cc9
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -97,7 +97,7 @@ struct inet_connection_sock {
	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;
	void __rcu		  *icsk_ulp_data;
	void (*icsk_clean_acked)(struct sock *sk, u32 acked_seq);
	struct hlist_node         icsk_listen_portaddr_node;
	unsigned int		  (*icsk_sync_mss)(struct sock *sk, u32 pmtu);
+3 −0
Original line number Diff line number Diff line
@@ -2122,6 +2122,9 @@ struct tcp_ulp_ops {
	void (*update)(struct sock *sk, struct proto *p);
	/* cleanup ulp */
	void (*release)(struct sock *sk);
	/* diagnostic */
	int (*get_info)(const struct sock *sk, struct sk_buff *skb);
	size_t (*get_info_size)(const struct sock *sk);

	char		name[TCP_ULP_NAME_MAX];
	struct module	*owner;
+24 −2
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@
#include <linux/tcp.h>
#include <linux/skmsg.h>
#include <linux/netdevice.h>
#include <linux/rcupdate.h>

#include <net/tcp.h>
#include <net/strparser.h>
@@ -290,6 +291,7 @@ struct tls_context {

	struct list_head list;
	refcount_t refcount;
	struct rcu_head rcu;
};

enum tls_offload_ctx_dir {
@@ -348,7 +350,7 @@ struct tls_offload_context_rx {
#define TLS_OFFLOAD_CONTEXT_SIZE_RX					\
	(sizeof(struct tls_offload_context_rx) + TLS_DRIVER_STATE_SIZE_RX)

void tls_ctx_free(struct tls_context *ctx);
void tls_ctx_free(struct sock *sk, struct tls_context *ctx);
int wait_on_pending_writer(struct sock *sk, long *timeo);
int tls_sk_query(struct sock *sk, int optname, char __user *optval,
		int __user *optlen);
@@ -429,6 +431,23 @@ static inline bool is_tx_ready(struct tls_sw_context_tx *ctx)
	return READ_ONCE(rec->tx_ready);
}

static inline u16 tls_user_config(struct tls_context *ctx, bool tx)
{
	u16 config = tx ? ctx->tx_conf : ctx->rx_conf;

	switch (config) {
	case TLS_BASE:
		return TLS_CONF_BASE;
	case TLS_SW:
		return TLS_CONF_SW;
	case TLS_HW:
		return TLS_CONF_HW;
	case TLS_HW_RECORD:
		return TLS_CONF_HW_RECORD;
	}
	return 0;
}

struct sk_buff *
tls_validate_xmit_skb(struct sock *sk, struct net_device *dev,
		      struct sk_buff *skb);
@@ -467,7 +486,10 @@ static inline struct tls_context *tls_get_ctx(const struct sock *sk)
{
	struct inet_connection_sock *icsk = inet_csk(sk);

	return icsk->icsk_ulp_data;
	/* Use RCU on icsk_ulp_data only for sock diag code,
	 * TLS data path doesn't need rcu_dereference().
	 */
	return (__force void *)icsk->icsk_ulp_data;
}

static inline void tls_advance_record_sn(struct sock *sk,
+9 −0
Original line number Diff line number Diff line
@@ -153,11 +153,20 @@ enum {
	INET_DIAG_BBRINFO,	/* request as INET_DIAG_VEGASINFO */
	INET_DIAG_CLASS_ID,	/* request as INET_DIAG_TCLASS */
	INET_DIAG_MD5SIG,
	INET_DIAG_ULP_INFO,
	__INET_DIAG_MAX,
};

#define INET_DIAG_MAX (__INET_DIAG_MAX - 1)

enum {
	INET_ULP_INFO_UNSPEC,
	INET_ULP_INFO_NAME,
	INET_ULP_INFO_TLS,
	__INET_ULP_INFO_MAX,
};
#define INET_ULP_INFO_MAX (__INET_ULP_INFO_MAX - 1)

/* INET_DIAG_MEM */

struct inet_diag_meminfo {
+15 −0
Original line number Diff line number Diff line
@@ -109,4 +109,19 @@ struct tls12_crypto_info_aes_ccm_128 {
	unsigned char rec_seq[TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE];
};

enum {
	TLS_INFO_UNSPEC,
	TLS_INFO_VERSION,
	TLS_INFO_CIPHER,
	TLS_INFO_TXCONF,
	TLS_INFO_RXCONF,
	__TLS_INFO_MAX,
};
#define TLS_INFO_MAX (__TLS_INFO_MAX - 1)

#define TLS_CONF_BASE 1
#define TLS_CONF_SW 2
#define TLS_CONF_HW 3
#define TLS_CONF_HW_RECORD 4

#endif /* _UAPI_LINUX_TLS_H */
Loading