Commit a8ae8a0e authored by David S. Miller's avatar David S. Miller
Browse files

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: default avatarDavid 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
parents b8fa067c 40d48527
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -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
+12 −6
Original line number Diff line number Diff line
@@ -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);
+15 −3
Original line number Diff line number Diff line
@@ -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;
}

/**
+5 −0
Original line number Diff line number Diff line
@@ -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;
+2 −3
Original line number Diff line number Diff line
@@ -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);
Loading