summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ovpn/io.c7
-rwxr-xr-xtools/testing/selftests/net/ovpn/test.sh4
2 files changed, 9 insertions, 2 deletions
diff --git a/drivers/net/ovpn/io.c b/drivers/net/ovpn/io.c
index db43a1f8a07a..22c555dd962e 100644
--- a/drivers/net/ovpn/io.c
+++ b/drivers/net/ovpn/io.c
@@ -85,17 +85,24 @@ static void ovpn_netdev_write(struct ovpn_peer *peer, struct sk_buff *skb)
skb_scrub_packet(skb, true);
/* network header reset in ovpn_decrypt_post() */
+ skb_reset_mac_header(skb);
skb_reset_transport_header(skb);
skb_reset_inner_headers(skb);
/* cause packet to be "received" by the interface */
pkt_len = skb->len;
+ /* we may get here in process context in case of TCP connections,
+ * therefore we have to disable BHs to ensure gro_cells_receive()
+ * and dev_dstats_rx_add() do not get corrupted or enter deadlock
+ */
+ local_bh_disable();
ret = gro_cells_receive(&peer->ovpn->gro_cells, skb);
if (likely(ret == NET_RX_SUCCESS)) {
/* update RX stats with the size of decrypted packet */
ovpn_peer_stats_increment_rx(&peer->vpn_stats, pkt_len);
dev_dstats_rx_add(peer->ovpn->dev, pkt_len);
}
+ local_bh_enable();
}
void ovpn_decrypt_post(void *data, int ret)
diff --git a/tools/testing/selftests/net/ovpn/test.sh b/tools/testing/selftests/net/ovpn/test.sh
index b50dbe45a4d0..c06e3135fbef 100755
--- a/tools/testing/selftests/net/ovpn/test.sh
+++ b/tools/testing/selftests/net/ovpn/test.sh
@@ -98,10 +98,10 @@ ovpn_run_basic_traffic() {
sleep 0.3
ovpn_cmd_ok "send baseline traffic to peer ${p}" \
ip netns exec ovpn_peer0 \
- ping -qfc 500 -w 3 5.5.5.$((p + 1))
+ ping -qfc 100 -w 3 5.5.5.$((p + 1))
ovpn_cmd_ok "send large-payload traffic to peer ${p}" \
ip netns exec ovpn_peer0 \
- ping -qfc 500 -s 3000 -w 3 5.5.5.$((p + 1))
+ ping -qfc 100 -s 3000 -w 3 5.5.5.$((p + 1))
wait "${tcpdump_pid1}" || return 1
wait "${tcpdump_pid2}" || return 1