Commit d04fb13c authored by Alexei Starovoitov's avatar Alexei Starovoitov

Merge branch 'sockmap_and_ktls'

Daniel Borkmann says:

====================
This work adds a generic sk_msg layer and converts both sockmap
and later ktls over to make use of it as a common data structure
for application data (similarly as sk_buff for network packets).
With that in place the sk_msg framework spans accross ULP layer
in the kernel and allows for introspection or filtering of L7
data with the help of BPF programs operating on a common input
context.

In a second step, we enable the latter for ktls which was previously
not possible, meaning, ktls and sk_msg verdict programs were
mutually exclusive in the ULP layer which created challenges for
the orchestrator when trying to apply TCP based policy, for
example. Leveraging the prior consolidation we can finally overcome
this limitation.

Note, there's no change in behavior when ktls is not used in
combination with BPF, and also no change in behavior for stand
alone sockmap. The kselftest suites for ktls, sockmap and ktls
with sockmap combined also runs through successfully. For further
details please see individual patches.

Thanks!

v1 -> v2:
  - Removed leftover comment spotted by Alexei
  - Improved commit messages, rebase
====================
Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
parents 67e89ac3 eea0d2ad
...@@ -8188,6 +8188,16 @@ S: Maintained ...@@ -8188,6 +8188,16 @@ S: Maintained
F: net/l3mdev F: net/l3mdev
F: include/net/l3mdev.h F: include/net/l3mdev.h
L7 BPF FRAMEWORK
M: John Fastabend <john.fastabend@gmail.com>
M: Daniel Borkmann <daniel@iogearbox.net>
L: netdev@vger.kernel.org
S: Maintained
F: include/linux/skmsg.h
F: net/core/skmsg.c
F: net/core/sock_map.c
F: net/ipv4/tcp_bpf.c
LANTIQ / INTEL Ethernet drivers LANTIQ / INTEL Ethernet drivers
M: Hauke Mehrtens <hauke@hauke-m.de> M: Hauke Mehrtens <hauke@hauke-m.de>
L: netdev@vger.kernel.org L: netdev@vger.kernel.org
......
...@@ -737,32 +737,17 @@ static inline void bpf_map_offload_map_free(struct bpf_map *map) ...@@ -737,32 +737,17 @@ static inline void bpf_map_offload_map_free(struct bpf_map *map)
} }
#endif /* CONFIG_NET && CONFIG_BPF_SYSCALL */ #endif /* CONFIG_NET && CONFIG_BPF_SYSCALL */
#if defined(CONFIG_STREAM_PARSER) && defined(CONFIG_BPF_SYSCALL) && defined(CONFIG_INET) #if defined(CONFIG_BPF_STREAM_PARSER)
struct sock *__sock_map_lookup_elem(struct bpf_map *map, u32 key); int sock_map_prog_update(struct bpf_map *map, struct bpf_prog *prog, u32 which);
struct sock *__sock_hash_lookup_elem(struct bpf_map *map, void *key); int sock_map_get_from_fd(const union bpf_attr *attr, struct bpf_prog *prog);
int sock_map_prog(struct bpf_map *map, struct bpf_prog *prog, u32 type);
int sockmap_get_from_fd(const union bpf_attr *attr, int type,
struct bpf_prog *prog);
#else #else
static inline struct sock *__sock_map_lookup_elem(struct bpf_map *map, u32 key) static inline int sock_map_prog_update(struct bpf_map *map,
{ struct bpf_prog *prog, u32 which)
return NULL;
}
static inline struct sock *__sock_hash_lookup_elem(struct bpf_map *map,
void *key)
{
return NULL;
}
static inline int sock_map_prog(struct bpf_map *map,
struct bpf_prog *prog,
u32 type)
{ {
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
static inline int sockmap_get_from_fd(const union bpf_attr *attr, int type, static inline int sock_map_get_from_fd(const union bpf_attr *attr,
struct bpf_prog *prog) struct bpf_prog *prog)
{ {
return -EINVAL; return -EINVAL;
...@@ -839,6 +824,10 @@ extern const struct bpf_func_proto bpf_get_stack_proto; ...@@ -839,6 +824,10 @@ extern const struct bpf_func_proto bpf_get_stack_proto;
extern const struct bpf_func_proto bpf_sock_map_update_proto; extern const struct bpf_func_proto bpf_sock_map_update_proto;
extern const struct bpf_func_proto bpf_sock_hash_update_proto; extern const struct bpf_func_proto bpf_sock_hash_update_proto;
extern const struct bpf_func_proto bpf_get_current_cgroup_id_proto; extern const struct bpf_func_proto bpf_get_current_cgroup_id_proto;
extern const struct bpf_func_proto bpf_msg_redirect_hash_proto;
extern const struct bpf_func_proto bpf_msg_redirect_map_proto;
extern const struct bpf_func_proto bpf_sk_redirect_hash_proto;
extern const struct bpf_func_proto bpf_sk_redirect_map_proto;
extern const struct bpf_func_proto bpf_get_local_storage_proto; extern const struct bpf_func_proto bpf_get_local_storage_proto;
......
...@@ -57,7 +57,7 @@ BPF_MAP_TYPE(BPF_MAP_TYPE_ARRAY_OF_MAPS, array_of_maps_map_ops) ...@@ -57,7 +57,7 @@ BPF_MAP_TYPE(BPF_MAP_TYPE_ARRAY_OF_MAPS, array_of_maps_map_ops)
BPF_MAP_TYPE(BPF_MAP_TYPE_HASH_OF_MAPS, htab_of_maps_map_ops) BPF_MAP_TYPE(BPF_MAP_TYPE_HASH_OF_MAPS, htab_of_maps_map_ops)
#ifdef CONFIG_NET #ifdef CONFIG_NET
BPF_MAP_TYPE(BPF_MAP_TYPE_DEVMAP, dev_map_ops) BPF_MAP_TYPE(BPF_MAP_TYPE_DEVMAP, dev_map_ops)
#if defined(CONFIG_STREAM_PARSER) && defined(CONFIG_INET) #if defined(CONFIG_BPF_STREAM_PARSER)
BPF_MAP_TYPE(BPF_MAP_TYPE_SOCKMAP, sock_map_ops) BPF_MAP_TYPE(BPF_MAP_TYPE_SOCKMAP, sock_map_ops)
BPF_MAP_TYPE(BPF_MAP_TYPE_SOCKHASH, sock_hash_ops) BPF_MAP_TYPE(BPF_MAP_TYPE_SOCKHASH, sock_hash_ops)
#endif #endif
......
...@@ -520,24 +520,6 @@ struct bpf_skb_data_end { ...@@ -520,24 +520,6 @@ struct bpf_skb_data_end {
void *data_end; void *data_end;
}; };
struct sk_msg_buff {
void *data;
void *data_end;
__u32 apply_bytes;
__u32 cork_bytes;
int sg_copybreak;
int sg_start;
int sg_curr;
int sg_end;
struct scatterlist sg_data[MAX_SKB_FRAGS];
bool sg_copy[MAX_SKB_FRAGS];
__u32 flags;
struct sock *sk_redir;
struct sock *sk;
struct sk_buff *skb;
struct list_head list;
};
struct bpf_redirect_info { struct bpf_redirect_info {
u32 ifindex; u32 ifindex;
u32 flags; u32 flags;
...@@ -833,9 +815,6 @@ void xdp_do_flush_map(void); ...@@ -833,9 +815,6 @@ void xdp_do_flush_map(void);
void bpf_warn_invalid_xdp_action(u32 act); void bpf_warn_invalid_xdp_action(u32 act);
struct sock *do_sk_redirect_map(struct sk_buff *skb);
struct sock *do_msg_redirect_map(struct sk_msg_buff *md);
#ifdef CONFIG_INET #ifdef CONFIG_INET
struct sock *bpf_run_sk_reuseport(struct sock_reuseport *reuse, struct sock *sk, struct sock *bpf_run_sk_reuseport(struct sock_reuseport *reuse, struct sock *sk,
struct bpf_prog *prog, struct sk_buff *skb, struct bpf_prog *prog, struct sk_buff *skb,
......
This diff is collapsed.
...@@ -2214,10 +2214,6 @@ static inline struct page_frag *sk_page_frag(struct sock *sk) ...@@ -2214,10 +2214,6 @@ static inline struct page_frag *sk_page_frag(struct sock *sk)
bool sk_page_frag_refill(struct sock *sk, struct page_frag *pfrag); bool sk_page_frag_refill(struct sock *sk, struct page_frag *pfrag);
int sk_alloc_sg(struct sock *sk, int len, struct scatterlist *sg,
int sg_start, int *sg_curr, unsigned int *sg_size,
int first_coalesce);
/* /*
* Default write policy as shown to user space via poll/select/SIGIO * Default write policy as shown to user space via poll/select/SIGIO
*/ */
......
...@@ -858,6 +858,21 @@ static inline void bpf_compute_data_end_sk_skb(struct sk_buff *skb) ...@@ -858,6 +858,21 @@ static inline void bpf_compute_data_end_sk_skb(struct sk_buff *skb)
TCP_SKB_CB(skb)->bpf.data_end = skb->data + skb_headlen(skb); TCP_SKB_CB(skb)->bpf.data_end = skb->data + skb_headlen(skb);
} }
static inline bool tcp_skb_bpf_ingress(const struct sk_buff *skb)
{
return TCP_SKB_CB(skb)->bpf.flags & BPF_F_INGRESS;
}
static inline struct sock *tcp_skb_bpf_redirect_fetch(struct sk_buff *skb)
{
return TCP_SKB_CB(skb)->bpf.sk_redir;
}
static inline void tcp_skb_bpf_redirect_clear(struct sk_buff *skb)
{
TCP_SKB_CB(skb)->bpf.sk_redir = NULL;
}
#if IS_ENABLED(CONFIG_IPV6) #if IS_ENABLED(CONFIG_IPV6)
/* This is the variant of inet6_iif() that must be used by TCP, /* This is the variant of inet6_iif() that must be used by TCP,
* as TCP moves IP6CB into a different location in skb->cb[] * as TCP moves IP6CB into a different location in skb->cb[]
...@@ -2057,7 +2072,6 @@ struct tcp_ulp_ops { ...@@ -2057,7 +2072,6 @@ struct tcp_ulp_ops {
int tcp_register_ulp(struct tcp_ulp_ops *type); int tcp_register_ulp(struct tcp_ulp_ops *type);
void tcp_unregister_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); int tcp_set_ulp(struct sock *sk, const char *name);
int tcp_set_ulp_id(struct sock *sk, const int ulp);
void tcp_get_available_ulp(char *buf, size_t len); void tcp_get_available_ulp(char *buf, size_t len);
void tcp_cleanup_ulp(struct sock *sk); void tcp_cleanup_ulp(struct sock *sk);
...@@ -2065,6 +2079,18 @@ void tcp_cleanup_ulp(struct sock *sk); ...@@ -2065,6 +2079,18 @@ void tcp_cleanup_ulp(struct sock *sk);
__MODULE_INFO(alias, alias_userspace, name); \ __MODULE_INFO(alias, alias_userspace, name); \
__MODULE_INFO(alias, alias_tcp_ulp, "tcp-ulp-" name) __MODULE_INFO(alias, alias_tcp_ulp, "tcp-ulp-" name)
struct sk_msg;
struct sk_psock;
int tcp_bpf_init(struct sock *sk);
void tcp_bpf_reinit(struct sock *sk);
int tcp_bpf_sendmsg_redir(struct sock *sk, struct sk_msg *msg, u32 bytes,
int flags);
int tcp_bpf_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
int nonblock, int flags, int *addr_len);
int __tcp_bpf_recvmsg(struct sock *sk, struct sk_psock *psock,
struct msghdr *msg, int len);
/* Call BPF_SOCK_OPS program that returns an int. If the return value /* Call BPF_SOCK_OPS program that returns an int. If the return value
* is < 0, then the BPF op failed (for example if the loaded BPF * is < 0, then the BPF op failed (for example if the loaded BPF
* program does not support the chosen operation or there is no BPF * program does not support the chosen operation or there is no BPF
......
...@@ -39,6 +39,8 @@ ...@@ -39,6 +39,8 @@
#include <linux/crypto.h> #include <linux/crypto.h>
#include <linux/socket.h> #include <linux/socket.h>
#include <linux/tcp.h> #include <linux/tcp.h>
#include <linux/skmsg.h>
#include <net/tcp.h> #include <net/tcp.h>
#include <net/strparser.h> #include <net/strparser.h>
#include <crypto/aead.h> #include <crypto/aead.h>
...@@ -103,15 +105,13 @@ struct tls_rec { ...@@ -103,15 +105,13 @@ struct tls_rec {
int tx_flags; int tx_flags;
int inplace_crypto; int inplace_crypto;
/* AAD | sg_plaintext_data | sg_tag */ struct sk_msg msg_plaintext;
struct scatterlist sg_plaintext_data[MAX_SKB_FRAGS + 1]; struct sk_msg msg_encrypted;
/* AAD | sg_encrypted_data (data contain overhead for hdr&iv&tag) */
struct scatterlist sg_encrypted_data[MAX_SKB_FRAGS + 1];
unsigned int sg_plaintext_size; /* AAD | msg_plaintext.sg.data | sg_tag */
unsigned int sg_encrypted_size; struct scatterlist sg_aead_in[2];
int sg_plaintext_num_elem; /* AAD | msg_encrypted.sg.data (data contains overhead for hdr & iv & tag) */
int sg_encrypted_num_elem; struct scatterlist sg_aead_out[2];
char aad_space[TLS_AAD_SPACE_SIZE]; char aad_space[TLS_AAD_SPACE_SIZE];
struct aead_request aead_req; struct aead_request aead_req;
...@@ -142,8 +142,7 @@ struct tls_sw_context_rx { ...@@ -142,8 +142,7 @@ struct tls_sw_context_rx {
struct strparser strp; struct strparser strp;
void (*saved_data_ready)(struct sock *sk); void (*saved_data_ready)(struct sock *sk);
unsigned int (*sk_poll)(struct file *file, struct socket *sock,
struct poll_table_struct *wait);
struct sk_buff *recv_pkt; struct sk_buff *recv_pkt;
u8 control; u8 control;
bool decrypted; bool decrypted;
...@@ -223,8 +222,8 @@ struct tls_context { ...@@ -223,8 +222,8 @@ struct tls_context {
unsigned long flags; unsigned long flags;
bool in_tcp_sendpages; bool in_tcp_sendpages;
bool pending_open_record_frags;
u16 pending_open_record_frags;
int (*push_pending_record)(struct sock *sk, int flags); int (*push_pending_record)(struct sock *sk, int flags);
void (*sk_write_space)(struct sock *sk); void (*sk_write_space)(struct sock *sk);
...@@ -272,8 +271,7 @@ void tls_sw_free_resources_rx(struct sock *sk); ...@@ -272,8 +271,7 @@ void tls_sw_free_resources_rx(struct sock *sk);
void tls_sw_release_resources_rx(struct sock *sk); void tls_sw_release_resources_rx(struct sock *sk);
int tls_sw_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int tls_sw_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
int nonblock, int flags, int *addr_len); int nonblock, int flags, int *addr_len);
unsigned int tls_sw_poll(struct file *file, struct socket *sock, bool tls_sw_stream_read(const struct sock *sk);
struct poll_table_struct *wait);
ssize_t tls_sw_splice_read(struct socket *sock, loff_t *ppos, ssize_t tls_sw_splice_read(struct socket *sock, loff_t *ppos,
struct pipe_inode_info *pipe, struct pipe_inode_info *pipe,
size_t len, unsigned int flags); size_t len, unsigned int flags);
......
...@@ -13,11 +13,6 @@ ifeq ($(CONFIG_XDP_SOCKETS),y) ...@@ -13,11 +13,6 @@ ifeq ($(CONFIG_XDP_SOCKETS),y)
obj-$(CONFIG_BPF_SYSCALL) += xskmap.o obj-$(CONFIG_BPF_SYSCALL) += xskmap.o
endif endif
obj-$(CONFIG_BPF_SYSCALL) += offload.o obj-$(CONFIG_BPF_SYSCALL) += offload.o
ifeq ($(CONFIG_STREAM_PARSER),y)
ifeq ($(CONFIG_INET),y)
obj-$(CONFIG_BPF_SYSCALL) += sockmap.o
endif
endif
endif endif
ifeq ($(CONFIG_PERF_EVENTS),y) ifeq ($(CONFIG_PERF_EVENTS),y)
obj-$(CONFIG_BPF_SYSCALL) += stackmap.o obj-$(CONFIG_BPF_SYSCALL) += stackmap.o
......
...@@ -1792,8 +1792,6 @@ const struct bpf_func_proto bpf_ktime_get_ns_proto __weak; ...@@ -1792,8 +1792,6 @@ const struct bpf_func_proto bpf_ktime_get_ns_proto __weak;
const struct bpf_func_proto bpf_get_current_pid_tgid_proto __weak; const struct bpf_func_proto bpf_get_current_pid_tgid_proto __weak;
const struct bpf_func_proto bpf_get_current_uid_gid_proto __weak; const struct bpf_func_proto bpf_get_current_uid_gid_proto __weak;
const struct bpf_func_proto bpf_get_current_comm_proto __weak; const struct bpf_func_proto bpf_get_current_comm_proto __weak;
const struct bpf_func_proto bpf_sock_map_update_proto __weak;
const struct bpf_func_proto bpf_sock_hash_update_proto __weak;
const struct bpf_func_proto bpf_get_current_cgroup_id_proto __weak; const struct bpf_func_proto bpf_get_current_cgroup_id_proto __weak;
const struct bpf_func_proto bpf_get_local_storage_proto __weak; const struct bpf_func_proto bpf_get_local_storage_proto __weak;
......
This diff is collapsed.
...@@ -1664,7 +1664,7 @@ static int bpf_prog_attach(const union bpf_attr *attr) ...@@ -1664,7 +1664,7 @@ static int bpf_prog_attach(const union bpf_attr *attr)
switch (ptype) { switch (ptype) {
case BPF_PROG_TYPE_SK_SKB: case BPF_PROG_TYPE_SK_SKB:
case BPF_PROG_TYPE_SK_MSG: case BPF_PROG_TYPE_SK_MSG:
ret = sockmap_get_from_fd(attr, ptype, prog); ret = sock_map_get_from_fd(attr, prog);
break; break;
case BPF_PROG_TYPE_LIRC_MODE2: case BPF_PROG_TYPE_LIRC_MODE2:
ret = lirc_prog_attach(attr, prog); ret = lirc_prog_attach(attr, prog);
...@@ -1718,10 +1718,10 @@ static int bpf_prog_detach(const union bpf_attr *attr) ...@@ -1718,10 +1718,10 @@ static int bpf_prog_detach(const union bpf_attr *attr)
ptype = BPF_PROG_TYPE_CGROUP_DEVICE; ptype = BPF_PROG_TYPE_CGROUP_DEVICE;
break; break;
case BPF_SK_MSG_VERDICT: case BPF_SK_MSG_VERDICT:
return sockmap_get_from_fd(attr, BPF_PROG_TYPE_SK_MSG, NULL); return sock_map_get_from_fd(attr, NULL);
case BPF_SK_SKB_STREAM_PARSER: case BPF_SK_SKB_STREAM_PARSER:
case BPF_SK_SKB_STREAM_VERDICT: case BPF_SK_SKB_STREAM_VERDICT:
return sockmap_get_from_fd(attr, BPF_PROG_TYPE_SK_SKB, NULL); return sock_map_get_from_fd(attr, NULL);
case BPF_LIRC_MODE2: case BPF_LIRC_MODE2:
return lirc_prog_detach(attr); return lirc_prog_detach(attr);
case BPF_FLOW_DISSECTOR: case BPF_FLOW_DISSECTOR:
......
...@@ -300,8 +300,11 @@ config BPF_JIT ...@@ -300,8 +300,11 @@ config BPF_JIT
config BPF_STREAM_PARSER config BPF_STREAM_PARSER
bool "enable BPF STREAM_PARSER" bool "enable BPF STREAM_PARSER"
depends on INET
depends on BPF_SYSCALL depends on BPF_SYSCALL
depends on CGROUP_BPF
select STREAM_PARSER select STREAM_PARSER
select NET_SOCK_MSG
---help--- ---help---
Enabling this allows a stream parser to be used with Enabling this allows a stream parser to be used with
BPF_MAP_TYPE_SOCKMAP. BPF_MAP_TYPE_SOCKMAP.
...@@ -413,6 +416,14 @@ config GRO_CELLS ...@@ -413,6 +416,14 @@ config GRO_CELLS
config SOCK_VALIDATE_XMIT config SOCK_VALIDATE_XMIT
bool bool
config NET_SOCK_MSG
bool
default n
help
The NET_SOCK_MSG provides a framework for plain sockets (e.g. TCP) or
ULPs (upper layer modules, e.g. TLS) to process L7 application data
with the help of BPF programs.
config NET_DEVLINK config NET_DEVLINK
tristate "Network physical/parent device Netlink interface" tristate "Network physical/parent device Netlink interface"
help help
......
...@@ -16,6 +16,7 @@ obj-y += dev.o ethtool.o dev_addr_lists.o dst.o netevent.o \ ...@@ -16,6 +16,7 @@ obj-y += dev.o ethtool.o dev_addr_lists.o dst.o netevent.o \
obj-y += net-sysfs.o obj-y += net-sysfs.o
obj-$(CONFIG_PAGE_POOL) += page_pool.o obj-$(CONFIG_PAGE_POOL) += page_pool.o
obj-$(CONFIG_PROC_FS) += net-procfs.o obj-$(CONFIG_PROC_FS) += net-procfs.o
obj-$(CONFIG_NET_SOCK_MSG) += skmsg.o
obj-$(CONFIG_NET_PKTGEN) += pktgen.o obj-$(CONFIG_NET_PKTGEN) += pktgen.o
obj-$(CONFIG_NETPOLL) += netpoll.o obj-$(CONFIG_NETPOLL) += netpoll.o
obj-$(CONFIG_FIB_RULES) += fib_rules.o obj-$(CONFIG_FIB_RULES) += fib_rules.o
...@@ -27,6 +28,7 @@ obj-$(CONFIG_CGROUP_NET_PRIO) += netprio_cgroup.o ...@@ -27,6 +28,7 @@ obj-$(CONFIG_CGROUP_NET_PRIO) += netprio_cgroup.o
obj-$(CONFIG_CGROUP_NET_CLASSID) += netclassid_cgroup.o obj-$(CONFIG_CGROUP_NET_CLASSID) += netclassid_cgroup.o
obj-$(CONFIG_LWTUNNEL) += lwtunnel.o obj-$(CONFIG_LWTUNNEL) += lwtunnel.o
obj-$(CONFIG_LWTUNNEL_BPF) += lwt_bpf.o obj-$(CONFIG_LWTUNNEL_BPF) += lwt_bpf.o
obj-$(CONFIG_BPF_STREAM_PARSER) += sock_map.o
obj-$(CONFIG_DST_CACHE) += dst_cache.o obj-$(CONFIG_DST_CACHE) += dst_cache.o
obj-$(CONFIG_HWBM) += hwbm.o obj-$(CONFIG_HWBM) += hwbm.o
obj-$(CONFIG_NET_DEVLINK) += devlink.o obj-$(CONFIG_NET_DEVLINK) += devlink.o
......
This diff is collapsed.
This diff is collapsed.
...@@ -2238,67 +2238,6 @@ bool sk_page_frag_refill(struct sock *sk, struct page_frag *pfrag) ...@@ -2238,67 +2238,6 @@ bool sk_page_frag_refill(struct sock *sk, struct page_frag *pfrag)
} }
EXPORT_SYMBOL(sk_page_frag_refill); EXPORT_SYMBOL(sk_page_frag_refill);
int sk_alloc_sg(struct sock *sk, int len, struct scatterlist *sg,
int sg_start, int *sg_curr_index, unsigned int *sg_curr_size,
int first_coalesce)
{
int sg_curr = *sg_curr_index, use = 0, rc = 0;
unsigned int size = *sg_curr_size;
struct page_frag *pfrag;
struct scatterlist *sge;
len -= size;
pfrag = sk_page_frag(sk);
while (len > 0) {
unsigned int orig_offset;
if (!sk_page_frag_refill(sk, pfrag)) {
rc = -ENOMEM;
goto out;
}
use = min_t(int, len, pfrag->size - pfrag->offset);
if (!sk_wmem_schedule(sk, use)) {
rc = -ENOMEM;
goto out;
}
sk_mem_charge(sk, use);
size += use;
orig_offset = pfrag->offset;
pfrag->offset += use;
sge = sg + sg_curr - 1;
if (sg_curr > first_coalesce && sg_page(sge) == pfrag->page &&
sge->offset + sge->length == orig_offset) {
sge->length += use;
} else {
sge = sg + sg_curr;
sg_unmark_end(sge);
sg_set_page(sge, pfrag->page, use, orig_offset);
get_page(pfrag->page);
sg_curr++;
if (sg_curr == MAX_SKB_FRAGS)
sg_curr = 0;
if (sg_curr == sg_start) {
rc = -ENOSPC;
break;
}
}
len -= use;
}
out:
*sg_curr_size = size;
*sg_curr_index = sg_curr;
return rc;
}
EXPORT_SYMBOL(sk_alloc_sg);
static void __lock_sock(struct sock *sk) static void __lock_sock(struct sock *sk)
__releases(&sk->sk_lock.slock) __releases(&sk->sk_lock.slock)
__acquires(&sk->sk_lock.slock) __acquires(&sk->sk_lock.slock)
......
This diff is collapsed.
...@@ -63,6 +63,7 @@ obj-$(CONFIG_TCP_CONG_SCALABLE) += tcp_scalable.o ...@@ -63,6 +63,7 @@ obj-$(CONFIG_TCP_CONG_SCALABLE) += tcp_scalable.o
obj-$(CONFIG_TCP_CONG_LP) += tcp_lp.o obj-$(CONFIG_TCP_CONG_LP) += tcp_lp.o
obj-$(CONFIG_TCP_CONG_YEAH) += tcp_yeah.o obj-$(CONFIG_TCP_CONG_YEAH) += tcp_yeah.o
obj-$(CONFIG_TCP_CONG_ILLINOIS) += tcp_illinois.o obj-$(CONFIG_TCP_CONG_ILLINOIS) += tcp_illinois.o
obj-$(CONFIG_NET_SOCK_MSG) += tcp_bpf.o
obj-$(CONFIG_NETLABEL) += cipso_ipv4.o obj-$(CONFIG_NETLABEL) += cipso_ipv4.o
obj-$(CONFIG_XFRM) += xfrm4_policy.o xfrm4_state.o xfrm4_input.o \ obj-$(CONFIG_XFRM) += xfrm4_policy.o xfrm4_state.o xfrm4_input.o \
......
This diff is collapsed.
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* *
*/ */
#include<linux/module.h> #include <linux/module.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/list.h> #include <linux/list.h>
...@@ -29,18 +29,6 @@ static struct tcp_ulp_ops *tcp_ulp_find(const char *name) ...@@ -29,18 +29,6 @@ static struct tcp_ulp_ops *tcp_ulp_find(const char *name)
return NULL; return NULL;
} }
static struct tcp_ulp_ops *tcp_ulp_find_id(const int ulp)
{
struct tcp_ulp_ops *e;
list_for_each_entry_rcu(e, &tcp_ulp_list, list) {
if (e->uid == ulp)
return e;
}
return NULL;
}
static const struct tcp_ulp_ops *__tcp_ulp_find_autoload(const char *name) static const struct tcp_ulp_ops *__tcp_ulp_find_autoload(const char *name)
{ {
const struct tcp_ulp_ops *ulp = NULL; const struct tcp_ulp_ops *ulp = NULL;
...@@ -63,18 +51,6 @@ static const struct tcp_ulp_ops *__tcp_ulp_find_autoload(const char *name) ...@@ -63,18 +51,6 @@ static const struct tcp_ulp_ops *__tcp_ulp_find_autoload(const char *name)
return ulp; return ulp;
} }
static const struct tcp_ulp_ops *__tcp_ulp_lookup(const int uid)
{
const struct tcp_ulp_ops *ulp;
rcu_read_lock();
ulp = tcp_ulp_find_id(uid);
if (!ulp || !try_module_get(ulp->owner))
ulp = NULL;
rcu_read_unlock();
return ulp;
}
/* Attach new upper layer protocol to the list /* Attach new upper layer protocol to the list
* of available protocols. * of available protocols.
*/ */
...@@ -123,6 +99,8 @@ void tcp_cleanup_ulp(struct sock *sk) ...@@ -123,6 +99,8 @@ void tcp_cleanup_ulp(struct sock *sk)
{ {
struct inet_connection_sock *icsk = inet_csk(sk); struct inet_connection_sock *icsk = inet_csk(sk);
sock_owned_by_me(sk);
if (!icsk->icsk_ulp_ops) if (!icsk->icsk_ulp_ops)
return; return;
...@@ -133,54 +111,35 @@ void tcp_cleanup_ulp(struct sock *sk) ...@@ -133,54 +111,35 @@ void tcp_cleanup_ulp(struct sock *sk)
icsk->icsk_ulp_ops = NULL; icsk->icsk_ulp_ops = NULL;
} }
/* Change upper layer protocol for socket */ static int __tcp_set_ulp(struct sock *sk, const struct tcp_ulp_ops *ulp_ops)
int tcp_set_ulp(struct sock *sk, const char *name)
{ {
struct inet_connection_sock *icsk = inet_csk(sk); struct inet_connection_sock *icsk = inet_csk(sk);
const struct tcp_ulp_ops *ulp_ops; int err;
int err = 0;
err = -EEXIST;
if (icsk->icsk_ulp_ops) if (icsk->icsk_ulp_ops)
return -EEXIST; goto out_err;
ulp_ops = __tcp_ulp_find_autoload(name);
if (!ulp_ops)
return -ENOENT;
if (!ulp_ops->user_visible) {
module_put(ulp_ops->owner);
return -ENOENT;
}
err = ulp_ops->init(sk); err = ulp_ops->init(sk);
if (err) { if (err)
module_put(ulp_ops->owner); goto out_err;
return err;
}
icsk->icsk_ulp_ops = ulp_ops; icsk->icsk_ulp_ops = ulp_ops;
return 0; return 0;
out_err:
module_put(ulp_ops->owner);
return err;
} }
int tcp_set_ulp_id(struct sock *sk, int ulp) int tcp_set_ulp(struct sock *sk, const char *name)
{ {
struct inet_connection_sock *icsk = inet_csk(sk);
const struct tcp_ulp_ops *ulp_ops; const struct tcp_ulp_ops *ulp_ops;
int err;
if (icsk->icsk_ulp_ops) sock_owned_by_me(sk);
return -EEXIST;
ulp_ops = __tcp_ulp_lookup(ulp); ulp_ops = __tcp_ulp_find_autoload(name);
if (!ulp_ops) if (!ulp_ops)
return -ENOENT; return -ENOENT;
err = ulp_ops->init(sk); return __tcp_set_ulp(sk, ulp_ops);
if (err) {
module_put(ulp_ops->owner);
return err;
}
icsk->icsk_ulp_ops = ulp_ops;
return 0;
} }
config STREAM_PARSER config STREAM_PARSER
tristate def_bool n
default n
...@@ -8,6 +8,7 @@ config TLS ...@@ -8,6 +8,7 @@ config TLS
select CRYPTO_AES select CRYPTO_AES
select CRYPTO_GCM select CRYPTO_GCM
select STREAM_PARSER select STREAM_PARSER
select NET_SOCK_MSG
default n default n
---help--- ---help---
Enable kernel support for TLS protocol. This allows symmetric Enable kernel support for TLS protocol. This allows symmetric
......
...@@ -421,7 +421,7 @@ static int tls_push_data(struct sock *sk, ...@@ -421,7 +421,7 @@ static int tls_push_data(struct sock *sk,
tls_push_record_flags = flags; tls_push_record_flags = flags;
if (more) { if (more) {
tls_ctx->pending_open_record_frags = tls_ctx->pending_open_record_frags =
record->num_frags; !!record->num_frags;
break; break;
} }
......
...@@ -621,10 +621,12 @@ static void build_protos(struct proto prot[TLS_NUM_CONFIG][TLS_NUM_CONFIG], ...@@ -621,10 +621,12 @@ static void build_protos(struct proto prot[TLS_NUM_CONFIG][TLS_NUM_CONFIG],
prot[TLS_BASE][TLS_SW] = prot[TLS_BASE][TLS_BASE]; prot[TLS_BASE][TLS_SW] = prot[TLS_BASE][TLS_BASE];
prot[TLS_BASE][TLS_SW].recvmsg = tls_sw_recvmsg; prot[TLS_BASE][TLS_SW].recvmsg = tls_sw_recvmsg;
prot[TLS_BASE][TLS_SW].stream_memory_read = tls_sw_stream_read;
prot[TLS_BASE][TLS_SW].close = tls_sk_proto_close; prot[TLS_BASE][TLS_SW].close = tls_sk_proto_close;
prot[TLS_SW][TLS_SW] = prot[TLS_SW][TLS_BASE]; prot[TLS_SW][TLS_SW] = prot[TLS_SW][TLS_BASE];
prot[TLS_SW][TLS_SW].recvmsg = tls_sw_recvmsg; prot[TLS_SW][TLS_SW].recvmsg = tls_sw_recvmsg;
prot[TLS_SW][TLS_SW].stream_memory_read = tls_sw_stream_read;
prot[TLS_SW][TLS_SW].close = tls_sk_proto_close; prot[TLS_SW][TLS_SW].close = tls_sk_proto_close;
#ifdef CONFIG_TLS_DEVICE #ifdef CONFIG_TLS_DEVICE
...@@ -724,7 +726,6 @@ static int __init tls_register(void) ...@@ -724,7 +726,6 @@ static int __init tls_register(void)
build_protos(tls_prots[TLSV4], &tcp_prot); build_protos(tls_prots[TLSV4], &tcp_prot);
tls_sw_proto_ops = inet_stream_ops; tls_sw_proto_ops = inet_stream_ops;
tls_sw_proto_ops.poll = tls_sw_poll;
tls_sw_proto_ops.splice_read = tls_sw_splice_read; tls_sw_proto_ops.splice_read = tls_sw_splice_read;
#ifdef CONFIG_TLS_DEVICE #ifdef CONFIG_TLS_DEVICE
......
This diff is collapsed.
...@@ -71,6 +71,7 @@ int txmsg_start; ...@@ -71,6 +71,7 @@ int txmsg_start;
int txmsg_end; int txmsg_end;
int txmsg_ingress; int txmsg_ingress;
int txmsg_skb; int txmsg_skb;
int ktls;
static const struct option long_options[] = { static const struct option long_options[] = {
{"help", no_argument, NULL, 'h' }, {"help", no_argument, NULL, 'h' },
...@@ -92,6 +93,7 @@ static const struct option long_options[] = { ...@@ -92,6 +93,7 @@ static const struct option long_options[] = {
{"txmsg_end", required_argument, NULL, 'e'}, {"txmsg_end", required_argument, NULL, 'e'},
{"txmsg_ingress", no_argument, &txmsg_ingress, 1 }, {"txmsg_ingress", no_argument, &txmsg_ingress, 1 },
{"txmsg_skb", no_argument, &txmsg_skb, 1 }, {"txmsg_skb", no_argument, &txmsg_skb, 1 },
{"ktls", no_argument, &ktls, 1 },
{0, 0, NULL, 0 } {0, 0, NULL, 0 }
}; };
...@@ -112,6 +114,76 @@ static void usage(char *argv[]) ...@@ -112,6 +114,76 @@ static void usage(char *argv[])
printf("\n"); printf("\n");
} }
#define TCP_ULP 31
#define TLS_TX 1
#define TLS_RX 2
#include <linux/tls.h>
char *sock_to_string(int s)
{
if (s == c1)
return "client1";
else if (s == c2)
return "client2";
else if (s == s1)
return "server1";
else if (s == s2)
return "server2";
else if (s == p1)
return "peer1";
else if (s == p2)
return "peer2";
else
return "unknown";
}
static int sockmap_init_ktls(int verbose, int s)
{
struct tls12_crypto_info_aes_gcm_128 tls_tx = {
.info = {
.version = TLS_1_2_VERSION,
.cipher_type = TLS_CIPHER_AES_GCM_128,
},
};
struct tls12_crypto_info_aes_gcm_128 tls_rx = {
.info = {
.version = TLS_1_2_VERSION,
.cipher_type = TLS_CIPHER_AES_GCM_128,
},
};
int so_buf = 6553500;
int err;
err = setsockopt(s, 6, TCP_ULP, "tls", sizeof("tls"));
if (err) {
fprintf(stderr, "setsockopt: TCP_ULP(%s) failed with error %i\n", sock_to_string(s), err);
return -EINVAL;
}
err = setsockopt(s, SOL_TLS, TLS_TX, (void *)&tls_tx, sizeof(tls_tx));
if (err) {
fprintf(stderr, "setsockopt: TLS_TX(%s) failed with error %i\n", sock_to_string(s), err);
return -EINVAL;
}
err = setsockopt(s, SOL_TLS, TLS_RX, (void *)&tls_rx, sizeof(tls_rx));
if (err) {
fprintf(stderr, "setsockopt: TLS_RX(%s) failed with error %i\n", sock_to_string(s), err);
return -EINVAL;
}
err = setsockopt(s, SOL_SOCKET, SO_SNDBUF, &so_buf, sizeof(so_buf));
if (err) {
fprintf(stderr, "setsockopt: (%s) failed sndbuf with error %i\n", sock_to_string(s), err);
return -EINVAL;
}
err = setsockopt(s, SOL_SOCKET, SO_RCVBUF, &so_buf, sizeof(so_buf));
if (err) {
fprintf(stderr, "setsockopt: (%s) failed rcvbuf with error %i\n", sock_to_string(s), err);
return -EINVAL;
}
if (verbose)
fprintf(stdout, "socket(%s) kTLS enabled\n", sock_to_string(s));
return 0;
}
static int sockmap_init_sockets(int verbose) static int sockmap_init_sockets(int verbose)
{ {
int i, err, one = 1; int i, err, one = 1;
...@@ -456,6 +528,21 @@ static int sendmsg_test(struct sockmap_options *opt) ...@@ -456,6 +528,21 @@ static int sendmsg_test(struct sockmap_options *opt)
else else
rx_fd = p2; rx_fd = p2;
if (ktls) {
/* Redirecting into non-TLS socket which sends into a TLS
* socket is not a valid test. So in this case lets not
* enable kTLS but still run the test.
*/
if (!txmsg_redir || (txmsg_redir && txmsg_ingress)) {
err = sockmap_init_ktls(opt->verbose, rx_fd);
if (err)
return err;
}
err = sockmap_init_ktls(opt->verbose, c1);
if (err)
return err;
}
rxpid = fork(); rxpid = fork();
if (rxpid == 0) { if (rxpid == 0) {
if (opt->drop_expected) if (opt->drop_expected)
...@@ -907,6 +994,8 @@ static void test_options(char *options) ...@@ -907,6 +994,8 @@ static void test_options(char *options)
strncat(options, "ingress,", OPTSTRING); strncat(options, "ingress,", OPTSTRING);
if (txmsg_skb) if (txmsg_skb)
strncat(options, "skb,", OPTSTRING); strncat(options, "skb,", OPTSTRING);
if (ktls)
strncat(options, "ktls,", OPTSTRING);
} }
static int __test_exec(int cgrp, int test, struct sockmap_options *opt) static int __test_exec(int cgrp, int test, struct sockmap_options *opt)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment