Commit Graph

35 Commits

Author SHA1 Message Date
Kristof Provost
57fcf46dee if_ovpn: ovpn_find_peer_by_ip() is unused without INET
Don't define ovpn_find_peer_by_ip() if INET is not set, and do the same
for ovpn_find_peer_by_ip6() and INET6.

Reported by:	mjg
Sponsored by:	Rubicon Communications, LLC ("Netgate")
2023-02-23 05:56:56 +01:00
Justin Hibbits
2c2b37ad25 ifnet/API: Move struct ifnet definition to a <net/if_private.h>
Hide the ifnet structure definition, no user serviceable parts inside,
it's a netstack implementation detail.  Include it temporarily in
<net/if_var.h> until all drivers are updated to use the accessors
exclusively.

Reviewed by:	glebius
Sponsored by:	Juniper Networks, Inc.
Differential Revision: https://reviews.freebsd.org/D38046
2023-01-24 14:36:30 -05:00
Kristof Provost
b079ca8593 Revert "if_ovpn: allow peer lookup by vpn4/vpn6 address"
This reverts commit 92f0cf77db.

This change was incorrect, at least because it uses ovpn_kpeer's tree
for multipbe RB_TREEs.

This is a performance change, not a functional one, so we can revert
this until it can be fixed.

Reported by:	Gert Doering <gert@greenie.muc.de>
Sponsored by:	Rubicon Communications, LLC ("Netgate")
2022-12-26 22:38:10 +01:00
Kristof Provost
1596d28026 if_ovpn: fix LINT-NOIP build
Reported by:	mjg
Sponsored by:	Rubicon Communications, LLC ("Netgate")
2022-12-14 10:53:03 +01:00
Kristof Provost
a002c839ec if_ovpn: cleanup offsetof() use
Move the use of the `offsetof(struct ovpn_counters, fieldname) /
sizeof(uint64_t)` construct into a macro.
This removes a fair bit of code duplication and should make things a
little easier to read.

Reviewed by:	zlei
Sponsored by:	Rubicon Communications, LLC ("Netgate")
Differential Revision:	https://reviews.freebsd.org/D37607
2022-12-14 06:48:59 +01:00
Kristof Provost
c357bf397f if_ovpn: include peer counters in a OVPN_NOTIF_DEL_PEER message
When we remove a peer userspace can no longer retrieve its counters. To
ensure that userspace can get a full count of the entire session we now
include the counters in the deletion message.

Sponsored by:	Rubicon Communications, LLC ("Netgate")
Differential Revision:	https://reviews.freebsd.org/D37606
2022-12-14 06:48:59 +01:00
Kristof Provost
92f0cf77db if_ovpn: allow peer lookup by vpn4/vpn6 address
Introduce two more RB_TREEs so that we can look up peers by their peer
id (already present) or vpn4 or vpn6 address.
This removes the last linear scan of the peer list.

Sponsored by:	Rubicon Communications, LLC ("Netgate")
Differential Revision:	https://reviews.freebsd.org/D37605
2022-12-14 06:48:59 +01:00
Kristof Provost
8b630fa9ef if_ovpn: implement OVPN_GET_PEER_STATS
Allow userspace to retrieve per-peer traffic stats.

Sponsored by:	Rubicon Communications, LLC ("Netgate")
Differential Revision:	https://reviews.freebsd.org/D37604
2022-12-14 06:48:58 +01:00
Kristof Provost
18a30fd39b if_ovpn: start tracking per-peer packets/bytes in/out
OpenVPN will introduce a mechanism to retrieve per-peer statistics.
Start tracking those so we can return them to userspace when queried.

Sponsored by:	Rubicon Communications, LLC ("Netgate")
Differential Revision:	https://reviews.freebsd.org/D37603
2022-12-14 06:48:58 +01:00
Kristof Provost
66de89d4c2 if_ovpn: remove OVPN_SEND_PKT
OpenVPN userspace no longer uses the ioctl interface to send control
packets. It instead uses the socket directly.
The use of OVPN_SEND_PKT was never released, so we can remove this
without worrying about compatibility.

Sponsored by:	Rubicon Communications, LLC ("Netgate")
Differential Revision:	https://reviews.freebsd.org/D37602
2022-12-14 06:48:58 +01:00
Kristof Provost
da69782bf0 if_ovpn: extend notifications with a reason
Extend peer deleted notifications (which are the only type right now) to
include the reason the peer was deleted. This can be either because
userspace requested it, or because the peer timed out.

Reviewed by:	zlei
Sponsored by:	Rubicon Communications, LLC ("Netgate")
Differential Revision:	https://reviews.freebsd.org/D37583
2022-12-05 11:09:34 +01:00
Kristof Provost
97c802923e if_ovpn: remove peer limit
Replace the fixed-sized array by an RB_TREE. This should both speed up
lookups and remove the 128 peer limit.

Reviewed by:	zlei
Sponsored by:	Rubicon Communications, LLC ("Netgate")
Differential Revision:	https://reviews.freebsd.org/D37524
2022-12-01 17:42:57 +01:00
Kristof Provost
5246f8fade if_ovpn: pass control packets through the socket
Rather than passing control packets through the ioctl interface allow
them to pass through the normal UDP socket flow.
This simplifies both kernel and userspace, and matches the approach
taken (or the one that will be taken) on the Linux side of things.

Sponsored by:	Rubicon Communications, LLC ("Netgate")
Differential Revision:	https://reviews.freebsd.org/D37317
2022-11-15 10:01:18 +01:00
Kristof Provost
6905fd01cb if_ovpn: ensure we're in vnet context when calling sorele()
We reference count to ensure we don't release the socket while we still
have data in flight. That means that we can end up releasing the socket
from ovpn_encrypt_tx_cb().

We must have a vnet context set when calling sorele() (which asserts
this from within sofree()), so move the CURVNET_SET()/CURVNET_RESTORE()
to ensure this is the case.

While here also add a couple of assertions to make this more obvious,
and to ease future debugging.

Sponsored by:	Rubicon Communications, LLC ("Netgate")
Differential Revision:	https://reviews.freebsd.org/D37326
2022-11-14 09:36:44 +01:00
Kristof Provost
2c58d0cb3b if_ovpn: fix AES-128-GCM support
We need to explicitly list AES-128-GCM as an allowed cipher for that
mode to work. While here also add AES-192-GCM. That brings our supported
cipher list in line with other openvpn/dco platforms.

Sponsored by:	Rubicon Communications, LLC ("Netgate")
2022-11-11 11:17:39 +01:00
Kristof Provost
13b1d6f0c9 if_ovpn: avoid netisr_queue name conflicts
Rename the netisr_queue variable in if_ovpn.c to avoid naming conflicts.

Sponsored by:	Rubicon Communications, LLC ("Netgate")
2022-10-24 20:45:39 +02:00
Kristof Provost
dc12ee39b7 if_ovpn: add sysctls for netisr_queue() and crypto_dispatch_async()
Allow the choice between asynchronous and synchronous netisr and crypto
calls. These have performance implications, but depend on the specific
setup and OCF back-end.

Sponsored by:	Rubicon Communications, LLC ("Netgate")
Differential Revision:	https://reviews.freebsd.org/D37017
2022-10-24 10:08:35 +02:00
Gert Doering
2e797555f7 if_ovpn(4): implement ioctl() to set if_flags
Fully working openvpn(8) --iroute support needs real subnet config
on ovpn(4) interfaces (IFF_BROADCAST), while client-side/p2p
configs need IFF_POINTOPOINT setting.  So make this configurable.

Reviewed by:	kp
2022-10-17 15:33:45 +02:00
Kristof Provost
b136983a8a if_ovpn: fix use-after-free
ovpn_encrypt_tx_cb() calls ovpn_encap() to transmit a packet, then adds
the length of the packet to the "tunnel_bytes_sent" counter.  However,
after ovpn_encap() returns 0, the mbuf chain may have been freed, so the
load of m->m_pkthdr.len may be a use-after-free.

Reported by:	markj
Sponsored by:	Rubicon Communications, LLC ("Netgate")
2022-10-17 09:24:41 +02:00
Kristof Provost
61ab88d873 if_ovpn: remove an incorrect assertion
netisr_dispatch() can fail, especially when under high traffic loads.
This isn't a fatal error, so simply don't check the return value.

Sponsored by:	Rubicon Communications, LLC ("Netgate")
2022-10-07 19:10:01 +02:00
Kristof Provost
4f756295e0 if_ovpn: ensure we're in net_epoch when calling ovpn_encap()
If the crypto callback is asynchronous we're no longer in net_epoch,
which ovpn_encap() (and ip_output() it calls) expect.

Ensure we've entered the epoch.

Do the same thing for the rx path.

Sponsored by:	Rubicon Communications, LLC ("Netgate")
2022-10-06 17:42:12 +02:00
Kristof Provost
76e1c9c671 if_ovpn: fix address family check when traffic class bits are set
When the tunneled (IPv6) traffic had traffic class bits set (but only >=
16) the packet got lost on the receive side.

This happened because the address family check in ovpn_get_af() failed
to mask correctly, so the version check didn't match, causing us to drop
the packet.

While here also extend the existing 6-in-6 test case to trigger this
issue.

PR:		266598
Sponsored by:	Rubicon Communications, LLC ("Netgate")
2022-09-26 13:54:20 +02:00
Alexander V. Chernikov
91ebcbe02a if_clone: migrate some consumers to the new KPI.
Convert most of the cloner customers who require custom params
 to the new if_clone KPI.

Reviewed by:	kp
Differential Revision:	https://reviews.freebsd.org/D36636
MFC after:	2 weeks
2022-09-22 12:30:09 +00:00
Kristof Provost
d99d59a79f if_ovpn: fix memory leak on unload
When we're unloading the if_ovpn module we sometimes end up only freeing
the softc after the module is unloaded and the M_OVPN malloc type no
longer exists.

Don't return from ovpn_clone_destroy() until the epoch callbacks have
been called, which ensures that we've freed the softc before we destroy
M_OVPN.

Sponsored by:	Rubicon Communications, LLC ("Netgate")
2022-09-21 21:44:59 +02:00
Kristof Provost
9dfbbc919f if_ovpn: remove incorrect rounding up of packet sizes
The ciphers used by OpenVPN (DCO) do not require data to be block-sized.
Do not round up to AES_BLOCK_LEN, as this can lead to issues with
fragmented packets.

Reported by:	Gert Doering <gert@greenie.muc.de>
Sponsored by:	Rubicon Communications, LLC ("Netgate")
2022-09-21 21:44:59 +02:00
Mateusz Guzik
3212ad15ab Add getsock
All but one consumers of getsock_cap only pass 4 arguments.
Take advantage of it.
2022-09-10 19:47:47 +00:00
Gleb Smirnoff
e7d02be19d protosw: refactor protosw and domain static declaration and load
o Assert that every protosw has pr_attach.  Now this structure is
  only for socket protocols declarations and nothing else.
o Merge struct pr_usrreqs into struct protosw.  This was suggested
  in 1996 by wollman@ (see 7b187005d1), and later reiterated
  in 2006 by rwatson@ (see 6fbb9cf860).
o Make struct domain hold a variable sized array of protosw pointers.
  For most protocols these pointers are initialized statically.
  Those domains that may have loadable protocols have spacers. IPv4
  and IPv6 have 8 spacers each (andre@ dff3237ee5).
o For inetsw and inet6sw leave a comment noting that many protosw
  entries very likely are dead code.
o Refactor pf_proto_[un]register() into protosw_[un]register().
o Isolate pr_*_notsupp() methods into uipc_domain.c

Reviewed by:		melifaro
Differential revision:	https://reviews.freebsd.org/D36232
2022-08-17 11:50:32 -07:00
Kristof Provost
fd6b3bede5 if_ovpn: reject non-UDP sockets
We must ensure that the fd provided by userspace is really for a UDP
socket. If it's not we'll panic in udp_set_kernel_tunneling().

Reported by:	Gert Doering <gert@greenie.muc.de>
Sponsored by:	Rubicon Communications, LLC ("Netgate")
2022-08-11 10:40:03 +02:00
Kristof Provost
8449762738 if_ovpn: fix unused functions with NOINET / NOINET6
ovpn_find_peer_by_ip() is not used if INET is not defined. Do not
define the function in that case. Same for ovpn_find_peer_by_ip6().

Fix these warnings:

	/usr/src/sys/net/if_ovpn.c:1580:1: warning: unused function 'ovpn_find_peer_by_ip' [-Wunused-function]
	ovpn_find_peer_by_ip(struct ovpn_softc *sc, const struct in_addr addr)
	^
	/usr/src/sys/net/if_ovpn.c:1599:1: warning: unused function 'ovpn_find_peer_by_ip6' [-Wunused-function]
	ovpn_find_peer_by_ip6(struct ovpn_softc *sc, const struct in6_addr *addr)
	^

Reported by:	mjg
Sponsored by:	Rubicon Communications, LLC ("Netgate")
2022-08-04 14:00:32 +02:00
Kristof Provost
59219dde9a if_ovpn: fix mbuf leak
If the link is down or we can't find a peer we do not transmit the
packet, but also don't fee it.

Remember to m_freem() mbufs we can't transmit.

Sponsored by:	Rubicon Communications, LLC ("Netgate")
2022-07-12 14:19:25 +02:00
Kristof Provost
6ba6c05cb2 if_ovpn: deal with short packets
If we receive a UDP packet (directed towards an active OpenVPN socket)
which is too short to contain an OpenVPN header ('struct
ovpn_wire_header') we wound up making m_copydata() read outside the
mbuf, and panicking the machine.

Explicitly check that the packet is long enough to copy the data we're
interested in. If it's not we will pass the packet to userspace, just
like we'd do for an unknown peer.

Extend a test case to provoke this situation.

Sponsored by:	Rubicon Communications, LLC ("Netgate")
2022-07-05 19:27:00 +02:00
Kristof Provost
6c77f8f0e0 if_ovpn: handle m_pullup() failure
Ensure we correctly handle m_pullup() failing in ovpn_finish_rx().

Reported by:	Coverity (CID 1490340)
Sponsored by:	Rubicon Communications, LLC ("Netgate")
2022-07-01 10:02:32 +02:00
Kristof Provost
9f7c81eb33 if_ovpn: deal with v4 mapped IPv6 addresses
Openvpn defaults to binding to IPv6 sockets (with
setsockopt(IPV6_V6ONLY=0)), which we didn't deal with.
That resulted in us trying to in6_selectsrc_addr() on a v4 mapped v6
address, which does not work.

Instead we translate the mapped address to v4 and treat it as an IPv4
address.

Sponsored by:	Rubicon Communications, LLC ("Netgate")
2022-07-01 10:02:32 +02:00
Kristof Provost
b33308db39 if_ovpn: static probe points
Sprinkle a few SDTs around if_ovpn to ease debugging.

Sponsored by:	Rubicon Communications, LLC ("Netgate")
2022-06-28 13:50:54 +02:00
Kristof Provost
ab91feabcc ovpn: Introduce OpenVPN DCO support
OpenVPN Data Channel Offload (DCO) moves OpenVPN data plane processing
(i.e. tunneling and cryptography) into the kernel, rather than using tap
devices.
This avoids significant copying and context switching overhead between
kernel and user space and improves OpenVPN throughput.

In my test setup throughput improved from around 660Mbit/s to around
2Gbit/s.

Sponsored by:	Rubicon Communications, LLC ("Netgate")
Differential Revision:	https://reviews.freebsd.org/D34340
2022-06-28 11:33:10 +02:00