Skip to content

Commit

Permalink
Merge git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf
Browse files Browse the repository at this point in the history
Alexei Starovoitov says:

====================
pull-request: bpf 2019-07-25

The following pull-request contains BPF updates for your *net* tree.

The main changes are:

1) fix segfault in libbpf, from Andrii.

2) fix gso_segs access, from Eric.

3) tls/sockmap fixes, from Jakub and John.
====================

Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
davem330 committed Jul 26, 2019
2 parents 47d858d + cb8ffde commit 28ba934
Show file tree
Hide file tree
Showing 18 changed files with 480 additions and 94 deletions.
6 changes: 6 additions & 0 deletions Documentation/networking/tls-offload.rst
Original file line number Diff line number Diff line change
Expand Up @@ -513,3 +513,9 @@ Redirects leak clear text

In the RX direction, if segment has already been decrypted by the device
and it gets redirected or mirrored - clear text will be transmitted out.

shutdown() doesn't clear TLS state
----------------------------------

shutdown() system call allows for a TLS socket to be reused as a different
connection. Offload doesn't currently handle that.
13 changes: 13 additions & 0 deletions include/linux/filter.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

#include <net/sch_generic.h>

#include <asm/byteorder.h>
#include <uapi/linux/filter.h>
#include <uapi/linux/bpf.h>

Expand Down Expand Up @@ -747,6 +748,18 @@ bpf_ctx_narrow_access_ok(u32 off, u32 size, u32 size_default)
return size <= size_default && (size & (size - 1)) == 0;
}

static inline u8
bpf_ctx_narrow_load_shift(u32 off, u32 size, u32 size_default)
{
u8 load_off = off & (size_default - 1);

#ifdef __LITTLE_ENDIAN
return load_off * 8;
#else
return (size_default - (load_off + size)) * 8;
#endif
}

#define bpf_ctx_wide_access_ok(off, size, type, field) \
(size == sizeof(__u64) && \
off >= offsetof(type, field) && \
Expand Down
8 changes: 7 additions & 1 deletion include/linux/skmsg.h
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,13 @@ static inline void sk_psock_restore_proto(struct sock *sk,
sk->sk_write_space = psock->saved_write_space;

if (psock->sk_proto) {
sk->sk_prot = psock->sk_proto;
struct inet_connection_sock *icsk = inet_csk(sk);
bool has_ulp = !!icsk->icsk_ulp_data;

if (has_ulp)
tcp_update_ulp(sk, psock->sk_proto);
else
sk->sk_prot = psock->sk_proto;
psock->sk_proto = NULL;
}
}
Expand Down
3 changes: 3 additions & 0 deletions include/net/tcp.h
Original file line number Diff line number Diff line change
Expand Up @@ -2108,6 +2108,8 @@ struct tcp_ulp_ops {

/* initialize ulp */
int (*init)(struct sock *sk);
/* update ulp */
void (*update)(struct sock *sk, struct proto *p);
/* cleanup ulp */
void (*release)(struct sock *sk);

Expand All @@ -2119,6 +2121,7 @@ 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);
void tcp_update_ulp(struct sock *sk, struct proto *p);

#define MODULE_ALIAS_TCP_ULP(name) \
__MODULE_INFO(alias, alias_userspace, name); \
Expand Down
15 changes: 11 additions & 4 deletions include/net/tls.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,9 +107,7 @@ struct tls_device {
enum {
TLS_BASE,
TLS_SW,
#ifdef CONFIG_TLS_DEVICE
TLS_HW,
#endif
TLS_HW_RECORD,
TLS_NUM_CONFIG,
};
Expand Down Expand Up @@ -162,6 +160,7 @@ struct tls_sw_context_tx {
int async_capable;

#define BIT_TX_SCHEDULED 0
#define BIT_TX_CLOSING 1
unsigned long tx_bitmask;
};

Expand Down Expand Up @@ -272,6 +271,8 @@ struct tls_context {
unsigned long flags;

/* cache cold stuff */
struct proto *sk_proto;

void (*sk_destruct)(struct sock *sk);
void (*sk_proto_close)(struct sock *sk, long timeout);

Expand All @@ -289,6 +290,8 @@ struct tls_context {

struct list_head list;
refcount_t refcount;

struct work_struct gc;
};

enum tls_offload_ctx_dir {
Expand Down Expand Up @@ -355,13 +358,17 @@ int tls_sk_attach(struct sock *sk, int optname, char __user *optval,
unsigned int optlen);

int tls_set_sw_offload(struct sock *sk, struct tls_context *ctx, int tx);
void tls_sw_strparser_arm(struct sock *sk, struct tls_context *ctx);
void tls_sw_strparser_done(struct tls_context *tls_ctx);
int tls_sw_sendmsg(struct sock *sk, struct msghdr *msg, size_t size);
int tls_sw_sendpage(struct sock *sk, struct page *page,
int offset, size_t size, int flags);
void tls_sw_close(struct sock *sk, long timeout);
void tls_sw_free_resources_tx(struct sock *sk);
void tls_sw_cancel_work_tx(struct tls_context *tls_ctx);
void tls_sw_release_resources_tx(struct sock *sk);
void tls_sw_free_ctx_tx(struct tls_context *tls_ctx);
void tls_sw_free_resources_rx(struct sock *sk);
void tls_sw_release_resources_rx(struct sock *sk);
void tls_sw_free_ctx_rx(struct tls_context *tls_ctx);
int tls_sw_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
int nonblock, int flags, int *addr_len);
bool tls_sw_stream_read(const struct sock *sk);
Expand Down
4 changes: 2 additions & 2 deletions kernel/bpf/verifier.c
Original file line number Diff line number Diff line change
Expand Up @@ -8616,8 +8616,8 @@ static int convert_ctx_accesses(struct bpf_verifier_env *env)
}

if (is_narrower_load && size < target_size) {
u8 shift = (off & (size_default - 1)) * 8;

u8 shift = bpf_ctx_narrow_load_shift(off, size,
size_default);
if (ctx_field_size <= 4) {
if (shift)
insn_buf[cnt++] = BPF_ALU32_IMM(BPF_RSH,
Expand Down
6 changes: 3 additions & 3 deletions net/core/filter.c
Original file line number Diff line number Diff line change
Expand Up @@ -7455,12 +7455,12 @@ static u32 bpf_convert_ctx_access(enum bpf_access_type type,
case offsetof(struct __sk_buff, gso_segs):
/* si->dst_reg = skb_shinfo(SKB); */
#ifdef NET_SKBUFF_DATA_USES_OFFSET
*insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(struct sk_buff, head),
si->dst_reg, si->src_reg,
offsetof(struct sk_buff, head));
*insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(struct sk_buff, end),
BPF_REG_AX, si->src_reg,
offsetof(struct sk_buff, end));
*insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(struct sk_buff, head),
si->dst_reg, si->src_reg,
offsetof(struct sk_buff, head));
*insn++ = BPF_ALU64_REG(BPF_ADD, si->dst_reg, BPF_REG_AX);
#else
*insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(struct sk_buff, end),
Expand Down
4 changes: 2 additions & 2 deletions net/core/skmsg.c
Original file line number Diff line number Diff line change
Expand Up @@ -585,12 +585,12 @@ EXPORT_SYMBOL_GPL(sk_psock_destroy);

void sk_psock_drop(struct sock *sk, struct sk_psock *psock)
{
rcu_assign_sk_user_data(sk, NULL);
sk_psock_cork_free(psock);
sk_psock_zap_ingress(psock);
sk_psock_restore_proto(sk, psock);

write_lock_bh(&sk->sk_callback_lock);
sk_psock_restore_proto(sk, psock);
rcu_assign_sk_user_data(sk, NULL);
if (psock->progs.skb_parser)
sk_psock_stop_strp(sk, psock);
write_unlock_bh(&sk->sk_callback_lock);
Expand Down
19 changes: 14 additions & 5 deletions net/core/sock_map.c
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,8 @@ static void sock_map_free(struct bpf_map *map)
raw_spin_unlock_bh(&stab->lock);
rcu_read_unlock();

synchronize_rcu();

bpf_map_area_free(stab->sks);
kfree(stab);
}
Expand Down Expand Up @@ -276,16 +278,20 @@ static int __sock_map_delete(struct bpf_stab *stab, struct sock *sk_test,
struct sock **psk)
{
struct sock *sk;
int err = 0;

raw_spin_lock_bh(&stab->lock);
sk = *psk;
if (!sk_test || sk_test == sk)
*psk = NULL;
sk = xchg(psk, NULL);

if (likely(sk))
sock_map_unref(sk, psk);
else
err = -EINVAL;

raw_spin_unlock_bh(&stab->lock);
if (unlikely(!sk))
return -EINVAL;
sock_map_unref(sk, psk);
return 0;
return err;
}

static void sock_map_delete_from_link(struct bpf_map *map, struct sock *sk,
Expand Down Expand Up @@ -328,6 +334,7 @@ static int sock_map_update_common(struct bpf_map *map, u32 idx,
struct sock *sk, u64 flags)
{
struct bpf_stab *stab = container_of(map, struct bpf_stab, map);
struct inet_connection_sock *icsk = inet_csk(sk);
struct sk_psock_link *link;
struct sk_psock *psock;
struct sock *osk;
Expand All @@ -338,6 +345,8 @@ static int sock_map_update_common(struct bpf_map *map, u32 idx,
return -EINVAL;
if (unlikely(idx >= map->max_entries))
return -E2BIG;
if (unlikely(icsk->icsk_ulp_data))
return -EINVAL;

link = sk_psock_init_link();
if (!link)
Expand Down
13 changes: 13 additions & 0 deletions net/ipv4/tcp_ulp.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,19 @@ void tcp_get_available_ulp(char *buf, size_t maxlen)
rcu_read_unlock();
}

void tcp_update_ulp(struct sock *sk, struct proto *proto)
{
struct inet_connection_sock *icsk = inet_csk(sk);

if (!icsk->icsk_ulp_ops) {
sk->sk_prot = proto;
return;
}

if (icsk->icsk_ulp_ops->update)
icsk->icsk_ulp_ops->update(sk, proto);
}

void tcp_cleanup_ulp(struct sock *sk)
{
struct inet_connection_sock *icsk = inet_csk(sk);
Expand Down
Loading

0 comments on commit 28ba934

Please sign in to comment.