Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
Pull networking fixes from David Miller: 1) Fix several scatter gather list issues in kTLS code, from Jakub Kicinski. 2) macb driver device remove has to kill the hresp_err_tasklet. From Chuhong Yuan. 3) Several memory leak and reference count bug fixes in tipc, from Tung Nguyen. 4) Fix mlx5 build error w/o ipv6, from Yue Haibing. 5) Fix jumbo frame and other regressions in r8169, from Heiner Kallweit. 6) Undo some BUG_ON()'s and replace them with WARN_ON_ONCE and proper error propagation/handling. From Paolo Abeni. * git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (24 commits) openvswitch: remove another BUG_ON() openvswitch: drop unneeded BUG_ON() in ovs_flow_cmd_build_info() net: phy: realtek: fix using paged operations with RTL8105e / RTL8208 r8169: fix resume on cable plug-in r8169: fix jumbo configuration for RTL8168evl net: emulex: benet: indent a Kconfig depends continuation line selftests: forwarding: fix race between packet receive and tc check net: sched: fix `tc -s class show` no bstats on class with nolock subqueues net: ethernet: ti: ale: ensure vlan/mdb deleted when no members net/mlx5e: Fix build error without IPV6 selftests: pmtu: use -oneline for ip route list cache tipc: fix duplicate SYN messages under link congestion tipc: fix wrong timeout input for tipc_wait_for_cond() tipc: fix wrong socket reference counter after tipc_sk_timeout() returns tipc: fix potential memory leak in __tipc_sendmsg() net: macb: add missed tasklet_kill selftests: bpf: correct perror strings selftests: bpf: test_sockmap: handle file creation failures gracefully net/tls: use sg_next() to walk sg entries net/tls: remove the dead inplace_crypto code ...
This commit is contained in:
@@ -2299,7 +2299,7 @@ BPF_CALL_4(bpf_msg_pull_data, struct sk_msg *, msg, u32, start,
|
||||
WARN_ON_ONCE(last_sge == first_sge);
|
||||
shift = last_sge > first_sge ?
|
||||
last_sge - first_sge - 1 :
|
||||
MAX_SKB_FRAGS - first_sge + last_sge - 1;
|
||||
NR_MSG_FRAG_IDS - first_sge + last_sge - 1;
|
||||
if (!shift)
|
||||
goto out;
|
||||
|
||||
@@ -2308,8 +2308,8 @@ BPF_CALL_4(bpf_msg_pull_data, struct sk_msg *, msg, u32, start,
|
||||
do {
|
||||
u32 move_from;
|
||||
|
||||
if (i + shift >= MAX_MSG_FRAGS)
|
||||
move_from = i + shift - MAX_MSG_FRAGS;
|
||||
if (i + shift >= NR_MSG_FRAG_IDS)
|
||||
move_from = i + shift - NR_MSG_FRAG_IDS;
|
||||
else
|
||||
move_from = i + shift;
|
||||
if (move_from == msg->sg.end)
|
||||
@@ -2323,7 +2323,7 @@ BPF_CALL_4(bpf_msg_pull_data, struct sk_msg *, msg, u32, start,
|
||||
} while (1);
|
||||
|
||||
msg->sg.end = msg->sg.end - shift > msg->sg.end ?
|
||||
msg->sg.end - shift + MAX_MSG_FRAGS :
|
||||
msg->sg.end - shift + NR_MSG_FRAG_IDS :
|
||||
msg->sg.end - shift;
|
||||
out:
|
||||
msg->data = sg_virt(&msg->sg.data[first_sge]) + start - offset;
|
||||
|
@@ -421,7 +421,7 @@ static int sk_psock_skb_ingress(struct sk_psock *psock, struct sk_buff *skb)
|
||||
copied = skb->len;
|
||||
msg->sg.start = 0;
|
||||
msg->sg.size = copied;
|
||||
msg->sg.end = num_sge == MAX_MSG_FRAGS ? 0 : num_sge;
|
||||
msg->sg.end = num_sge;
|
||||
msg->skb = skb;
|
||||
|
||||
sk_psock_queue_msg(psock, msg);
|
||||
|
@@ -301,7 +301,7 @@ EXPORT_SYMBOL_GPL(tcp_bpf_sendmsg_redir);
|
||||
static int tcp_bpf_send_verdict(struct sock *sk, struct sk_psock *psock,
|
||||
struct sk_msg *msg, int *copied, int flags)
|
||||
{
|
||||
bool cork = false, enospc = msg->sg.start == msg->sg.end;
|
||||
bool cork = false, enospc = sk_msg_full(msg);
|
||||
struct sock *sk_redir;
|
||||
u32 tosend, delta = 0;
|
||||
int ret;
|
||||
|
@@ -905,7 +905,10 @@ static struct sk_buff *ovs_flow_cmd_build_info(const struct sw_flow *flow,
|
||||
retval = ovs_flow_cmd_fill_info(flow, dp_ifindex, skb,
|
||||
info->snd_portid, info->snd_seq, 0,
|
||||
cmd, ufid_flags);
|
||||
BUG_ON(retval < 0);
|
||||
if (WARN_ON_ONCE(retval < 0)) {
|
||||
kfree_skb(skb);
|
||||
skb = ERR_PTR(retval);
|
||||
}
|
||||
return skb;
|
||||
}
|
||||
|
||||
@@ -1369,7 +1372,10 @@ static int ovs_flow_cmd_del(struct sk_buff *skb, struct genl_info *info)
|
||||
OVS_FLOW_CMD_DEL,
|
||||
ufid_flags);
|
||||
rcu_read_unlock();
|
||||
BUG_ON(err < 0);
|
||||
if (WARN_ON_ONCE(err < 0)) {
|
||||
kfree_skb(reply);
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
ovs_notify(&dp_flow_genl_family, reply, info);
|
||||
} else {
|
||||
@@ -1377,6 +1383,7 @@ static int ovs_flow_cmd_del(struct sk_buff *skb, struct genl_info *info)
|
||||
}
|
||||
}
|
||||
|
||||
out_free:
|
||||
ovs_flow_free(flow, true);
|
||||
return 0;
|
||||
unlock:
|
||||
|
@@ -245,7 +245,8 @@ static int mq_dump_class_stats(struct Qdisc *sch, unsigned long cl,
|
||||
struct netdev_queue *dev_queue = mq_queue_get(sch, cl);
|
||||
|
||||
sch = dev_queue->qdisc_sleeping;
|
||||
if (gnet_stats_copy_basic(&sch->running, d, NULL, &sch->bstats) < 0 ||
|
||||
if (gnet_stats_copy_basic(&sch->running, d, sch->cpu_bstats,
|
||||
&sch->bstats) < 0 ||
|
||||
qdisc_qstats_copy(d, sch) < 0)
|
||||
return -1;
|
||||
return 0;
|
||||
|
@@ -557,8 +557,8 @@ static int mqprio_dump_class_stats(struct Qdisc *sch, unsigned long cl,
|
||||
struct netdev_queue *dev_queue = mqprio_queue_get(sch, cl);
|
||||
|
||||
sch = dev_queue->qdisc_sleeping;
|
||||
if (gnet_stats_copy_basic(qdisc_root_sleeping_running(sch),
|
||||
d, NULL, &sch->bstats) < 0 ||
|
||||
if (gnet_stats_copy_basic(qdisc_root_sleeping_running(sch), d,
|
||||
sch->cpu_bstats, &sch->bstats) < 0 ||
|
||||
qdisc_qstats_copy(d, sch) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
@@ -339,7 +339,7 @@ static int multiq_dump_class_stats(struct Qdisc *sch, unsigned long cl,
|
||||
|
||||
cl_q = q->queues[cl - 1];
|
||||
if (gnet_stats_copy_basic(qdisc_root_sleeping_running(sch),
|
||||
d, NULL, &cl_q->bstats) < 0 ||
|
||||
d, cl_q->cpu_bstats, &cl_q->bstats) < 0 ||
|
||||
qdisc_qstats_copy(d, cl_q) < 0)
|
||||
return -1;
|
||||
|
||||
|
@@ -356,7 +356,7 @@ static int prio_dump_class_stats(struct Qdisc *sch, unsigned long cl,
|
||||
|
||||
cl_q = q->queues[cl - 1];
|
||||
if (gnet_stats_copy_basic(qdisc_root_sleeping_running(sch),
|
||||
d, NULL, &cl_q->bstats) < 0 ||
|
||||
d, cl_q->cpu_bstats, &cl_q->bstats) < 0 ||
|
||||
qdisc_qstats_copy(d, cl_q) < 0)
|
||||
return -1;
|
||||
|
||||
|
@@ -532,7 +532,7 @@ static void __tipc_shutdown(struct socket *sock, int error)
|
||||
struct sock *sk = sock->sk;
|
||||
struct tipc_sock *tsk = tipc_sk(sk);
|
||||
struct net *net = sock_net(sk);
|
||||
long timeout = CONN_TIMEOUT_DEFAULT;
|
||||
long timeout = msecs_to_jiffies(CONN_TIMEOUT_DEFAULT);
|
||||
u32 dnode = tsk_peer_node(tsk);
|
||||
struct sk_buff *skb;
|
||||
|
||||
@@ -540,12 +540,10 @@ static void __tipc_shutdown(struct socket *sock, int error)
|
||||
tipc_wait_for_cond(sock, &timeout, (!tsk->cong_link_cnt &&
|
||||
!tsk_conn_cong(tsk)));
|
||||
|
||||
/* Push out unsent messages or remove if pending SYN */
|
||||
skb = skb_peek(&sk->sk_write_queue);
|
||||
if (skb && !msg_is_syn(buf_msg(skb)))
|
||||
tipc_sk_push_backlog(tsk);
|
||||
else
|
||||
__skb_queue_purge(&sk->sk_write_queue);
|
||||
/* Push out delayed messages if in Nagle mode */
|
||||
tipc_sk_push_backlog(tsk);
|
||||
/* Remove pending SYN */
|
||||
__skb_queue_purge(&sk->sk_write_queue);
|
||||
|
||||
/* Reject all unreceived messages, except on an active connection
|
||||
* (which disconnects locally & sends a 'FIN+' to peer).
|
||||
@@ -1248,9 +1246,14 @@ static void tipc_sk_push_backlog(struct tipc_sock *tsk)
|
||||
struct sk_buff_head *txq = &tsk->sk.sk_write_queue;
|
||||
struct net *net = sock_net(&tsk->sk);
|
||||
u32 dnode = tsk_peer_node(tsk);
|
||||
struct sk_buff *skb = skb_peek(txq);
|
||||
int rc;
|
||||
|
||||
if (skb_queue_empty(txq) || tsk->cong_link_cnt)
|
||||
if (!skb || tsk->cong_link_cnt)
|
||||
return;
|
||||
|
||||
/* Do not send SYN again after congestion */
|
||||
if (msg_is_syn(buf_msg(skb)))
|
||||
return;
|
||||
|
||||
tsk->snt_unacked += tsk->snd_backlog;
|
||||
@@ -1447,8 +1450,10 @@ static int __tipc_sendmsg(struct socket *sock, struct msghdr *m, size_t dlen)
|
||||
rc = tipc_msg_build(hdr, m, 0, dlen, mtu, &pkts);
|
||||
if (unlikely(rc != dlen))
|
||||
return rc;
|
||||
if (unlikely(syn && !tipc_msg_skb_clone(&pkts, &sk->sk_write_queue)))
|
||||
if (unlikely(syn && !tipc_msg_skb_clone(&pkts, &sk->sk_write_queue))) {
|
||||
__skb_queue_purge(&pkts);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
trace_tipc_sk_sendmsg(sk, skb_peek(&pkts), TIPC_DUMP_SK_SNDQ, " ");
|
||||
rc = tipc_node_xmit(net, &pkts, dnode, tsk->portid);
|
||||
@@ -2757,6 +2762,7 @@ static void tipc_sk_timeout(struct timer_list *t)
|
||||
if (sock_owned_by_user(sk)) {
|
||||
sk_reset_timer(sk, &sk->sk_timer, jiffies + HZ / 20);
|
||||
bh_unlock_sock(sk);
|
||||
sock_put(sk);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@@ -209,24 +209,15 @@ int tls_push_partial_record(struct sock *sk, struct tls_context *ctx,
|
||||
return tls_push_sg(sk, ctx, sg, offset, flags);
|
||||
}
|
||||
|
||||
bool tls_free_partial_record(struct sock *sk, struct tls_context *ctx)
|
||||
void tls_free_partial_record(struct sock *sk, struct tls_context *ctx)
|
||||
{
|
||||
struct scatterlist *sg;
|
||||
|
||||
sg = ctx->partially_sent_record;
|
||||
if (!sg)
|
||||
return false;
|
||||
|
||||
while (1) {
|
||||
for (sg = ctx->partially_sent_record; sg; sg = sg_next(sg)) {
|
||||
put_page(sg_page(sg));
|
||||
sk_mem_uncharge(sk, sg->length);
|
||||
|
||||
if (sg_is_last(sg))
|
||||
break;
|
||||
sg++;
|
||||
}
|
||||
ctx->partially_sent_record = NULL;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void tls_write_space(struct sock *sk)
|
||||
|
@@ -710,8 +710,7 @@ static int tls_push_record(struct sock *sk, int flags,
|
||||
}
|
||||
|
||||
i = msg_pl->sg.start;
|
||||
sg_chain(rec->sg_aead_in, 2, rec->inplace_crypto ?
|
||||
&msg_en->sg.data[i] : &msg_pl->sg.data[i]);
|
||||
sg_chain(rec->sg_aead_in, 2, &msg_pl->sg.data[i]);
|
||||
|
||||
i = msg_en->sg.end;
|
||||
sk_msg_iter_var_prev(i);
|
||||
@@ -771,8 +770,14 @@ static int bpf_exec_tx_verdict(struct sk_msg *msg, struct sock *sk,
|
||||
|
||||
policy = !(flags & MSG_SENDPAGE_NOPOLICY);
|
||||
psock = sk_psock_get(sk);
|
||||
if (!psock || !policy)
|
||||
return tls_push_record(sk, flags, record_type);
|
||||
if (!psock || !policy) {
|
||||
err = tls_push_record(sk, flags, record_type);
|
||||
if (err) {
|
||||
*copied -= sk_msg_free(sk, msg);
|
||||
tls_free_open_rec(sk);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
more_data:
|
||||
enospc = sk_msg_full(msg);
|
||||
if (psock->eval == __SK_NONE) {
|
||||
@@ -970,8 +975,6 @@ alloc_encrypted:
|
||||
if (ret)
|
||||
goto fallback_to_reg_send;
|
||||
|
||||
rec->inplace_crypto = 0;
|
||||
|
||||
num_zc++;
|
||||
copied += try_to_copy;
|
||||
|
||||
@@ -984,7 +987,7 @@ alloc_encrypted:
|
||||
num_async++;
|
||||
else if (ret == -ENOMEM)
|
||||
goto wait_for_memory;
|
||||
else if (ret == -ENOSPC)
|
||||
else if (ctx->open_rec && ret == -ENOSPC)
|
||||
goto rollback_iter;
|
||||
else if (ret != -EAGAIN)
|
||||
goto send_end;
|
||||
@@ -1053,11 +1056,12 @@ wait_for_memory:
|
||||
ret = sk_stream_wait_memory(sk, &timeo);
|
||||
if (ret) {
|
||||
trim_sgl:
|
||||
tls_trim_both_msgs(sk, orig_size);
|
||||
if (ctx->open_rec)
|
||||
tls_trim_both_msgs(sk, orig_size);
|
||||
goto send_end;
|
||||
}
|
||||
|
||||
if (msg_en->sg.size < required_size)
|
||||
if (ctx->open_rec && msg_en->sg.size < required_size)
|
||||
goto alloc_encrypted;
|
||||
}
|
||||
|
||||
@@ -1169,7 +1173,6 @@ alloc_payload:
|
||||
|
||||
tls_ctx->pending_open_record_frags = true;
|
||||
if (full_record || eor || sk_msg_full(msg_pl)) {
|
||||
rec->inplace_crypto = 0;
|
||||
ret = bpf_exec_tx_verdict(msg_pl, sk, full_record,
|
||||
record_type, &copied, flags);
|
||||
if (ret) {
|
||||
@@ -1190,11 +1193,13 @@ wait_for_sndbuf:
|
||||
wait_for_memory:
|
||||
ret = sk_stream_wait_memory(sk, &timeo);
|
||||
if (ret) {
|
||||
tls_trim_both_msgs(sk, msg_pl->sg.size);
|
||||
if (ctx->open_rec)
|
||||
tls_trim_both_msgs(sk, msg_pl->sg.size);
|
||||
goto sendpage_end;
|
||||
}
|
||||
|
||||
goto alloc_payload;
|
||||
if (ctx->open_rec)
|
||||
goto alloc_payload;
|
||||
}
|
||||
|
||||
if (num_async) {
|
||||
@@ -2084,7 +2089,8 @@ void tls_sw_release_resources_tx(struct sock *sk)
|
||||
/* Free up un-sent records in tx_list. First, free
|
||||
* the partially sent record if any at head of tx_list.
|
||||
*/
|
||||
if (tls_free_partial_record(sk, tls_ctx)) {
|
||||
if (tls_ctx->partially_sent_record) {
|
||||
tls_free_partial_record(sk, tls_ctx);
|
||||
rec = list_first_entry(&ctx->tx_list,
|
||||
struct tls_rec, list);
|
||||
list_del(&rec->list);
|
||||
|
Reference in New Issue
Block a user