mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 17:47:41 +02:00
Patchset highlights:
- update MAINTAINERS entry for ovpn - extend selftest with more cases - avoid crash in selftest in case of getaddrinfo() failure - fix ndo_start_xmit return value on error - set ignore_df flag for IPv6 packets - drop useless reg_state check in keepalive worker - retain skb's dst when entering xmit function - fix check on skb_to_sgvec_nomark() return value -----BEGIN PGP SIGNATURE----- iQEzBAABCAAdFiEEmavcbPjUEuTeX8D8C3DlOqA41YcFAmgly3gACgkQC3DlOqA4 1Yce5QgAq0UK170Dk8yrq97PevhAc35OekOvZ2kC7rS/Mp7E7de6puVR0Xawh9rU xLJC9ldAXCFS8jKzW/9yd6hJqe03KXVULtHD0tdOCoxkp5jfQCx+RWG9BaHljs9T NWIqKP93Fe83qqWgnSjtG1lTPPNbx++JD61xvnl/eMEh/xU0kVeuhxuqhdyoj1NT 8IzSSFIJBnh4LtgCzGxhNkA8Ar+SShKdFkc+4nL3AoD9DTRx5NiFDfG6OKWTK75h GA0VB3Ip7Jt8PTFBdxXYcEEe7sYXGtjkiNUHYa+sv4VdU83BTfYgyBi+6PeIADjq N9BI418qfSkt2VBV1cYHZwe+O89fvw== =nC7o -----END PGP SIGNATURE----- Merge tag 'ovpn-net-next-20250515' of https://github.com/OpenVPN/ovpn-net-next Antonio Quartulli says: ==================== ovpn: pull request for net-next: ovpn 2025-05-15 this is a new version of the previous pull request. These time I have removed the fixes that we are still discussing, so that we don't hold the entire series back. There is a new fix though: it's about properly checking the return value of skb_to_sgvec_nomark(). I spotted the issue while testing pings larger than the iface's MTU on a TCP VPN connection. I have added various Closes and Link tags where applicable, so that we have references to GitHub tickets and other public discussions. Since I have resent the PR, I have also added Andrew's Reviewed-by to the first patch. Please pull or let me know if something should be changed! ==================== Signed-off-by: David S. Miller <davem@davemloft.net> Patchset highlights: - update MAINTAINERS entry for ovpn - extend selftest with more cases - avoid crash in selftest in case of getaddrinfo() failure - fix ndo_start_xmit return value on error - set ignore_df flag for IPv6 packets - drop useless reg_state check in keepalive worker - retain skb's dst when entering xmit function - fix check on skb_to_sgvec_nomark() return value
This commit is contained in:
commit
a8ae8a0e84
|
|
@ -18256,10 +18256,11 @@ F: drivers/irqchip/irq-or1k-*
|
|||
|
||||
OPENVPN DATA CHANNEL OFFLOAD
|
||||
M: Antonio Quartulli <antonio@openvpn.net>
|
||||
R: Sabrina Dubroca <sd@queasysnail.net>
|
||||
L: openvpn-devel@lists.sourceforge.net (subscribers-only)
|
||||
L: netdev@vger.kernel.org
|
||||
S: Supported
|
||||
T: git https://github.com/OpenVPN/linux-kernel-ovpn.git
|
||||
T: git https://github.com/OpenVPN/ovpn-net-next.git
|
||||
F: Documentation/netlink/specs/ovpn.yaml
|
||||
F: drivers/net/ovpn/
|
||||
F: include/uapi/linux/ovpn.h
|
||||
|
|
|
|||
|
|
@ -88,12 +88,15 @@ int ovpn_aead_encrypt(struct ovpn_peer *peer, struct ovpn_crypto_key_slot *ks,
|
|||
|
||||
/* build scatterlist to encrypt packet payload */
|
||||
ret = skb_to_sgvec_nomark(skb, sg + 1, 0, skb->len);
|
||||
if (unlikely(nfrags != ret))
|
||||
return -EINVAL;
|
||||
if (unlikely(ret < 0)) {
|
||||
netdev_err(peer->ovpn->dev,
|
||||
"encrypt: cannot map skb to sg: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* append auth_tag onto scatterlist */
|
||||
__skb_push(skb, tag_size);
|
||||
sg_set_buf(sg + nfrags + 1, skb->data, tag_size);
|
||||
sg_set_buf(sg + ret + 1, skb->data, tag_size);
|
||||
|
||||
/* obtain packet ID, which is used both as a first
|
||||
* 4 bytes of nonce and last 4 bytes of associated data.
|
||||
|
|
@ -201,11 +204,14 @@ int ovpn_aead_decrypt(struct ovpn_peer *peer, struct ovpn_crypto_key_slot *ks,
|
|||
|
||||
/* build scatterlist to decrypt packet payload */
|
||||
ret = skb_to_sgvec_nomark(skb, sg + 1, payload_offset, payload_len);
|
||||
if (unlikely(nfrags != ret))
|
||||
return -EINVAL;
|
||||
if (unlikely(ret < 0)) {
|
||||
netdev_err(peer->ovpn->dev,
|
||||
"decrypt: cannot map skb to sg: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* append auth_tag onto scatterlist */
|
||||
sg_set_buf(sg + nfrags + 1, skb->data + OVPN_AAD_SIZE, tag_size);
|
||||
sg_set_buf(sg + ret + 1, skb->data + OVPN_AAD_SIZE, tag_size);
|
||||
|
||||
/* iv may be required by async crypto */
|
||||
ovpn_skb_cb(skb)->iv = kmalloc(OVPN_NONCE_SIZE, GFP_ATOMIC);
|
||||
|
|
|
|||
|
|
@ -394,10 +394,22 @@ netdev_tx_t ovpn_net_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
/* retrieve peer serving the destination IP of this packet */
|
||||
peer = ovpn_peer_get_by_dst(ovpn, skb);
|
||||
if (unlikely(!peer)) {
|
||||
net_dbg_ratelimited("%s: no peer to send data to\n",
|
||||
netdev_name(ovpn->dev));
|
||||
switch (skb->protocol) {
|
||||
case htons(ETH_P_IP):
|
||||
net_dbg_ratelimited("%s: no peer to send data to dst=%pI4\n",
|
||||
netdev_name(ovpn->dev),
|
||||
&ip_hdr(skb)->daddr);
|
||||
break;
|
||||
case htons(ETH_P_IPV6):
|
||||
net_dbg_ratelimited("%s: no peer to send data to dst=%pI6c\n",
|
||||
netdev_name(ovpn->dev),
|
||||
&ipv6_hdr(skb)->daddr);
|
||||
break;
|
||||
}
|
||||
goto drop;
|
||||
}
|
||||
/* dst was needed for peer selection - it can now be dropped */
|
||||
skb_dst_drop(skb);
|
||||
|
||||
ovpn_peer_stats_increment_tx(&peer->vpn_stats, skb->len);
|
||||
ovpn_send(ovpn, skb_list.next, peer);
|
||||
|
|
@ -408,7 +420,7 @@ netdev_tx_t ovpn_net_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
dev_dstats_tx_dropped(ovpn->dev);
|
||||
skb_tx_error(skb);
|
||||
kfree_skb_list(skb);
|
||||
return NET_XMIT_DROP;
|
||||
return NETDEV_TX_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -157,6 +157,11 @@ static void ovpn_setup(struct net_device *dev)
|
|||
dev->type = ARPHRD_NONE;
|
||||
dev->flags = IFF_POINTOPOINT | IFF_NOARP;
|
||||
dev->priv_flags |= IFF_NO_QUEUE;
|
||||
/* when routing packets to a LAN behind a client, we rely on the
|
||||
* route entry that originally brought the packet into ovpn, so
|
||||
* don't release it
|
||||
*/
|
||||
netif_keep_dst(dev);
|
||||
|
||||
dev->lltx = true;
|
||||
dev->features |= feat;
|
||||
|
|
|
|||
|
|
@ -258,7 +258,7 @@ void ovpn_peer_endpoints_update(struct ovpn_peer *peer, struct sk_buff *skb)
|
|||
*/
|
||||
if (unlikely(!ipv6_addr_equal(&bind->local.ipv6,
|
||||
&ipv6_hdr(skb)->daddr))) {
|
||||
net_dbg_ratelimited("%s: learning local IPv6 for peer %d (%pI6c -> %pI6c\n",
|
||||
net_dbg_ratelimited("%s: learning local IPv6 for peer %d (%pI6c -> %pI6c)\n",
|
||||
netdev_name(peer->ovpn->dev),
|
||||
peer->id, &bind->local.ipv6,
|
||||
&ipv6_hdr(skb)->daddr);
|
||||
|
|
@ -1353,8 +1353,7 @@ void ovpn_peer_keepalive_work(struct work_struct *work)
|
|||
}
|
||||
|
||||
/* prevent rearming if the interface is being destroyed */
|
||||
if (next_run > 0 &&
|
||||
READ_ONCE(ovpn->dev->reg_state) == NETREG_REGISTERED) {
|
||||
if (next_run > 0) {
|
||||
netdev_dbg(ovpn->dev,
|
||||
"scheduling keepalive work: now=%llu next_run=%llu delta=%llu\n",
|
||||
next_run, now, next_run - now);
|
||||
|
|
|
|||
|
|
@ -262,6 +262,16 @@ static int ovpn_udp6_output(struct ovpn_peer *peer, struct ovpn_bind *bind,
|
|||
dst_cache_set_ip6(cache, dst, &fl.saddr);
|
||||
|
||||
transmit:
|
||||
/* user IPv6 packets may be larger than the transport interface
|
||||
* MTU (after encapsulation), however, since they are locally
|
||||
* generated we should ensure they get fragmented.
|
||||
* Setting the ignore_df flag to 1 will instruct ip6_fragment() to
|
||||
* fragment packets if needed.
|
||||
*
|
||||
* NOTE: this is not needed for IPv4 because we pass df=0 to
|
||||
* udp_tunnel_xmit_skb()
|
||||
*/
|
||||
skb->ignore_df = 1;
|
||||
udp_tunnel6_xmit_skb(dst, sk, skb, skb->dev, &fl.saddr, &fl.daddr, 0,
|
||||
ip6_dst_hoplimit(dst), 0, fl.fl6_sport,
|
||||
fl.fl6_dport, udp_get_no_check6_tx(sk));
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ LDLIBS += $(VAR_LDLIBS)
|
|||
TEST_FILES = common.sh
|
||||
|
||||
TEST_PROGS = test.sh \
|
||||
test-large-mtu.sh \
|
||||
test-chachapoly.sh \
|
||||
test-tcp.sh \
|
||||
test-float.sh \
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@ ALG=${ALG:-aes}
|
|||
PROTO=${PROTO:-UDP}
|
||||
FLOAT=${FLOAT:-0}
|
||||
|
||||
LAN_IP="11.11.11.11"
|
||||
|
||||
create_ns() {
|
||||
ip netns add peer${1}
|
||||
}
|
||||
|
|
@ -24,15 +26,25 @@ setup_ns() {
|
|||
ip link add veth${p} netns peer0 type veth peer name veth${p} netns peer${p}
|
||||
|
||||
ip -n peer0 addr add 10.10.${p}.1/24 dev veth${p}
|
||||
ip -n peer0 addr add fd00:0:0:${p}::1/64 dev veth${p}
|
||||
ip -n peer0 link set veth${p} up
|
||||
|
||||
ip -n peer${p} addr add 10.10.${p}.2/24 dev veth${p}
|
||||
ip -n peer${p} addr add fd00:0:0:${p}::2/64 dev veth${p}
|
||||
ip -n peer${p} link set veth${p} up
|
||||
done
|
||||
fi
|
||||
|
||||
ip netns exec peer${1} ${OVPN_CLI} new_iface tun${1} $MODE
|
||||
ip -n peer${1} addr add ${2} dev tun${1}
|
||||
# add a secondary IP to peer 1, to test a LAN behind a client
|
||||
if [ ${1} -eq 1 -a -n "${LAN_IP}" ]; then
|
||||
ip -n peer${1} addr add ${LAN_IP} dev tun${1}
|
||||
ip -n peer0 route add ${LAN_IP} via $(echo ${2} |sed -e s'!/.*!!') dev tun0
|
||||
fi
|
||||
if [ -n "${3}" ]; then
|
||||
ip -n peer${1} link set mtu ${3} dev tun${1}
|
||||
fi
|
||||
ip -n peer${1} link set tun${1} up
|
||||
}
|
||||
|
||||
|
|
@ -46,7 +58,11 @@ add_peer() {
|
|||
data64.key
|
||||
done
|
||||
else
|
||||
ip netns exec peer${1} ${OVPN_CLI} new_peer tun${1} ${1} 1 10.10.${1}.1 1
|
||||
RADDR=$(awk "NR == ${1} {print \$2}" ${UDP_PEERS_FILE})
|
||||
RPORT=$(awk "NR == ${1} {print \$3}" ${UDP_PEERS_FILE})
|
||||
LPORT=$(awk "NR == ${1} {print \$5}" ${UDP_PEERS_FILE})
|
||||
ip netns exec peer${1} ${OVPN_CLI} new_peer tun${1} ${1} ${LPORT} \
|
||||
${RADDR} ${RPORT}
|
||||
ip netns exec peer${1} ${OVPN_CLI} new_key tun${1} ${1} 1 0 ${ALG} 1 \
|
||||
data64.key
|
||||
fi
|
||||
|
|
|
|||
|
|
@ -1753,8 +1753,11 @@ static int ovpn_parse_remote(struct ovpn_ctx *ovpn, const char *host,
|
|||
|
||||
if (host) {
|
||||
ret = getaddrinfo(host, service, &hints, &result);
|
||||
if (ret == EAI_NONAME || ret == EAI_FAIL)
|
||||
if (ret) {
|
||||
fprintf(stderr, "getaddrinfo on remote error: %s\n",
|
||||
gai_strerror(ret));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!(result->ai_family == AF_INET &&
|
||||
result->ai_addrlen == sizeof(struct sockaddr_in)) &&
|
||||
|
|
@ -1769,8 +1772,11 @@ static int ovpn_parse_remote(struct ovpn_ctx *ovpn, const char *host,
|
|||
|
||||
if (vpnip) {
|
||||
ret = getaddrinfo(vpnip, NULL, &hints, &result);
|
||||
if (ret == EAI_NONAME || ret == EAI_FAIL)
|
||||
if (ret) {
|
||||
fprintf(stderr, "getaddrinfo on vpnip error: %s\n",
|
||||
gai_strerror(ret));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!(result->ai_family == AF_INET &&
|
||||
result->ai_addrlen == sizeof(struct sockaddr_in)) &&
|
||||
|
|
@ -1928,7 +1934,8 @@ static void ovpn_waitbg(void)
|
|||
|
||||
static int ovpn_run_cmd(struct ovpn_ctx *ovpn)
|
||||
{
|
||||
char peer_id[10], vpnip[INET6_ADDRSTRLEN], raddr[128], rport[10];
|
||||
char peer_id[10], vpnip[INET6_ADDRSTRLEN], laddr[128], lport[10];
|
||||
char raddr[128], rport[10];
|
||||
int n, ret;
|
||||
FILE *fp;
|
||||
|
||||
|
|
@ -2044,8 +2051,8 @@ static int ovpn_run_cmd(struct ovpn_ctx *ovpn)
|
|||
return -1;
|
||||
}
|
||||
|
||||
while ((n = fscanf(fp, "%s %s %s %s\n", peer_id, raddr, rport,
|
||||
vpnip)) == 4) {
|
||||
while ((n = fscanf(fp, "%s %s %s %s %s %s\n", peer_id, laddr,
|
||||
lport, raddr, rport, vpnip)) == 6) {
|
||||
struct ovpn_ctx peer_ctx = { 0 };
|
||||
|
||||
peer_ctx.ifindex = ovpn->ifindex;
|
||||
|
|
@ -2349,7 +2356,7 @@ int main(int argc, char *argv[])
|
|||
}
|
||||
|
||||
memset(&ovpn, 0, sizeof(ovpn));
|
||||
ovpn.sa_family = AF_INET;
|
||||
ovpn.sa_family = AF_UNSPEC;
|
||||
ovpn.cipher = OVPN_CIPHER_ALG_NONE;
|
||||
|
||||
ovpn.cmd = ovpn_parse_cmd(argv[1]);
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ for p in $(seq 0 ${NUM_PEERS}); do
|
|||
done
|
||||
|
||||
for p in $(seq 0 ${NUM_PEERS}); do
|
||||
setup_ns ${p} 5.5.5.$((${p} + 1))/24
|
||||
setup_ns ${p} 5.5.5.$((${p} + 1))/24 ${MTU}
|
||||
done
|
||||
|
||||
for p in $(seq 0 ${NUM_PEERS}); do
|
||||
|
|
@ -34,8 +34,12 @@ sleep 1
|
|||
|
||||
for p in $(seq 1 ${NUM_PEERS}); do
|
||||
ip netns exec peer0 ping -qfc 500 -w 3 5.5.5.$((${p} + 1))
|
||||
ip netns exec peer0 ping -qfc 500 -s 3000 -w 3 5.5.5.$((${p} + 1))
|
||||
done
|
||||
|
||||
# ping LAN behind client 1
|
||||
ip netns exec peer0 ping -qfc 500 -w 3 ${LAN_IP}
|
||||
|
||||
if [ "$FLOAT" == "1" ]; then
|
||||
# make clients float..
|
||||
for p in $(seq 1 ${NUM_PEERS}); do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
1 10.10.1.2 1 5.5.5.2
|
||||
2 10.10.2.2 1 5.5.5.3
|
||||
3 10.10.3.2 1 5.5.5.4
|
||||
4 10.10.4.2 1 5.5.5.5
|
||||
5 10.10.5.2 1 5.5.5.6
|
||||
1 10.10.1.1 1 10.10.1.2 1 5.5.5.2
|
||||
2 10.10.2.1 1 10.10.2.2 1 5.5.5.3
|
||||
3 10.10.3.1 1 10.10.3.2 1 5.5.5.4
|
||||
4 fd00:0:0:4::1 1 fd00:0:0:4::2 1 5.5.5.5
|
||||
5 fd00:0:0:5::1 1 fd00:0:0:5::2 1 5.5.5.6
|
||||
6 fd00:0:0:6::1 1 fd00:0:0:6::2 1 5.5.5.7
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user