aboutsummaryrefslogtreecommitdiff
path: root/sys/net/if_ovpn.c
Commit message (Collapse)AuthorAgeFilesLines
* if_ovpn: support IPv6 link-local addressesKristof Provost5 days1-1/+20
| | | | | | MFC after: 3 weeks Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D51596
* if_ovpn: Destroy cloned interfaces via a prison removal callbackMark Johnston11 days1-8/+40
| | | | | | | | | | | | | | | | | | A if_ovpn interface carries a reference to a socket, which has a credential reference, which holds a reference on the containing prison and prevents SYSUNINITs from being invoked. So, register a PR_METHOD_REMOVE callback and destroy the cloner from there instead, since that mechanism doesn't require the prison refcount to drop to zero first. This fixes a bug where jails get left stuck in the DYING state after running if_ovpn regression tests. Reviewed by: kp MFC after: 2 weeks Sponsored by: Stormshield Sponsored by: Klara, Inc. Differential Revision: https://reviews.freebsd.org/D51526
* if_ovpn: support floating clientsKristof Provost11 days1-1/+192
| | | | | | | | | | | | | | | If a client changes its IP address notify userspace of this. The UDP filtering function supplies the remote IP address, so we check if the address changed there. If so, we tag the packet with the new address. Once the packet is decrypted (and as part of that, has had its signature checked) we can commit to the address change. Take the write lock and notify userspace of the change. Reviewed by: markj MFC after: 3 weeks Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D51468
* if_ovpn: Support multihomed server configurationsMark Johnston2025-07-251-7/+46
| | | | | | | | | | | | | | | | | | | | | | | In UDP server mode, openvpn implements the "multihome" option, which makes it avoid binding to an address. Instead, the server socket is bound to INADDR_ANY. Today, when configuring a new peer and setting the source address, sockaddr() returns the wildcard address, so the source address is implicitly determined by the output interface. This doesn't work as one would want if the WAN interface has multiple addresses and clients connect to non-primary addresses. Make multihome mode work properly: use the local address supplied by openvpn in preference to that of the socket. We still fetch the port number out of the socket. PR: 273664 Reviewed by: kp MFC after: 1 month Sponsored by: Stormshield Sponsored by: Klara, Inc. Differential Revision: https://reviews.freebsd.org/D51498
* if_ovpn: Remove a no-op functionMark Johnston2025-07-251-29/+0
| | | | | | | | | | | | | | | | ovpn used to maintain one socket ref per peer. This scheme was changed in commit 3acf7e0da487 ("if_ovpn: avoid LOR between ovpn and UDP locks"), which turned ovpn_rele_so() in a no-op. Just remove the whole function and a related helper, as the remaining assertion there isn't useful. No functional change intended. Reviewed by: kp MFC after: 2 weeks Sponsored by: Stormshield Sponsored by: Klara, Inc. Differential Revision: https://reviews.freebsd.org/D51497
* if_ovpn: Assert that udp_set_kernel_tunneling() succeedsMark Johnston2025-07-251-0/+1
| | | | | | | | | | We do this elsewhere, so copy the pattern here. Reviewed by: kp MFC after: 2 weeks Sponsored by: Stormshield Sponsored by: Klara, Inc. Differential Revision: https://reviews.freebsd.org/D51496
* if_ovpn: Destroy the datapath lock when destroying a cloneMark Johnston2025-07-251-0/+1
| | | | | | | | Reviewed by: kp MFC after: 2 weeks Sponsored by: Stormshield Sponsored by: Klara, Inc. Differential Revision: https://reviews.freebsd.org/D51495
* if_ovpn: Sprinkle const over some helper functionsMark Johnston2025-07-251-5/+6
| | | | | | | | | | No functional change intended. Reviewed by: kp MFC after: 2 weeks Sponsored by: Stormshield Sponsored by: Klara, Inc. Differential Revision: https://reviews.freebsd.org/D51494
* if_ovpn: Remove an unused field from struct ovpn_kkey_dirMark Johnston2025-07-251-1/+0
| | | | | | | | | | No functional change intended. Reviewed by: kp MFC after: 2 weeks Sponsored by: Stormshield Sponsored by: Klara, Inc. Differential Revision: https://reviews.freebsd.org/D51493
* if_ovpn: fill out sin_len/sin6_lenKristof Provost2025-07-231-0/+2
| | | | | | | | | When we parse an nvlist sockaddr we should set the sockaddr_in(6)'s length field. This isn't currently used by anything yet, but it's reasonable to expect a sockaddr to contain its length. MFC after: 3 weeks Sponsored by: Rubicon Communications, LLC ("Netgate")
* if_ovpn: fix use-after-free of mbufKristof Provost2025-04-011-6/+6
| | | | | | | | | | | | | | | m_unshare() can return a new mbuf pointer. We update the 'm' pointer in ovpn_udp_input(), but if we decide to pass on the packet (e.g. because it's for an unknown peer) the caller (udp_append()) continues with the old 'm' pointer, eventually resulting in a use-after-free. Re-order operations in ovpn_udp_input() so that we don't modify the 'm' pointer until we're committed to keeping the packet. PR: 283426 Test case by: takahiro.kurosawa@gmail.com MFC after: 2 weeks Sponsored by: Rubicon Communications, LLC ("Netgate")
* if_ovpn: fix module load in NOINET6 kernelsKristof Provost2025-01-301-1/+1
| | | | | | PR: 284459 MFC after: 2 weeks Sponsored by: Rubicon Communications, LLC ("Netgate")
* if_ovpn: improve reconnect handlingKristof Provost2024-12-181-2/+14
| | | | | | | | | | | | When a DCO client reconnects (e.g. on server restart) OpenVPN may create a new socket rather than reusing the existing one. This used to be rejected because we expect all peers to use the same socket. However, if there are no peers it's safe to release the previous socket and install the tunnel function on the new one. See also: https://redmine.pfsense.org/issues/15928 MFC after: 2 weeks Sponsored by: Rubicon Communications, LLC ("Netgate")
* if_ovpn: declare our dependency on the crypto moduleKristof Provost2024-09-121-0/+1
| | | | | | PR: 281460 MFC after: 1 week Sponsored by: Rubicon Communications, LLC ("Netgate")
* if_ovpn: only install tunnel callback onceKristof Provost2024-09-121-3/+7
| | | | | | | | | Rather than attempt to install the tunnel callback every time we add a peer only do so the first time. Reviewed by: zlei Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D46651
* if_ovpn: avoid LOR between ovpn and UDP locksKristof Provost2024-09-121-22/+24
| | | | | | | | | | | | | | | | | | | | | | | | | | | | When we install the tunneling function we had the ovpn lock, and then took the UDP lock. During normal data flow we are called with the UDP lock held and then take the ovpn lock. This naturally produces a lock order reversal warning. Avoid this by releasing the ovpn lock before installing the tunnel function. This is safe, in that installing the tunnel function does not fail (other than with EBUSY, which would mean another thread has already installed the function). On cleanup the problem is more difficult, in that we cannot reasonably release the ovpn lock before we can remove the tunneling function callback. Solve this by delaying the removal of the tunnel callback until the ovpn_softc is cleaned up. It's still safe for ovpn_udp_input() to be caled when all peers are removed. That will only increment counters (which are still allocated), discover there are no peers and then pass the message on to userspace, if any userspace users of the socket remain. We ensure that the socket object remains valid by holding a reference, which we release when we remove the ovpn_softc. This removes the need for per-peer reference counting on the socket, so remove that. Reviewed by: zlei Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision:: https://reviews.freebsd.org/D46616
* if_ovpn: remove unused argumentKristof Provost2024-09-101-2/+2
| | | | | | Reviewed by: zlei Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D46615
* if_ovpn: ensure it's safe to modify the mbufKristof Provost2024-09-051-0/+12
| | | | | | | | PR: 280036 Reviewed by: ae MFC after: 1 week Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D46529
* if_ovpn: cope with loopsKristof Provost2024-05-131-0/+9
| | | | | | | | | | | User misconfiguration may lead to routing loops where we try to send the tunnel packet into the tunnel. This eventually leads to stack overflows and panics. Avoid this using if_tunnel_check_nesting(), which will drop the packet if we're looping or we hit three layers of nested tunnels. MFC after: 1 week Sponsored by: Rubicon Communications, LLC ("Netgate")
* sockets: don't malloc/free sockaddr memory on getpeername/getsocknameGleb Smirnoff2023-11-301-8/+4
| | | | | | | | | | | | | Just like it was done for accept(2) in cfb1e92912b4, use same approach for two simplier syscalls that return socket addresses. Although, these two syscalls aren't performance critical, this change generalizes some code between 3 syscalls trimming code size. Following example of accept(2), provide VNET-aware and INVARIANT-checking wrappers sopeeraddr() and sosockaddr() around protosw methods. Reviewed by: tuexen Differential Revision: https://reviews.freebsd.org/D42694
* if_ovpn: clear mbuf flags on rxKristof Provost2023-08-221-0/+4
| | | | | | | | | | When we receive a packet and remove the encapsulating layer we should also clear out protocol flags and any mbuf tags. If we do not we risk confusing firewalls filtering the tunneled packet. See also: https://redmine.pfsense.org/issues/14682#change-69073 Sponsored by: Rubicon Communications, LLC ("Netgate")
* if_ovpn: atomic_set -> atomic_storeKristof Provost2023-05-241-1/+1
| | | | | | | | | The intent is to set the value to UINT32_MAX, not to |= UINT32_MAX. Happily the intent (ensure that we do not send further packets) is achieved either way. Reported by: markj Sponsored by: Rubicon Communications, LLC ("Netgate")
* if_ovpn: ensure we never re-use sequence numbersKristof Provost2023-05-231-4/+18
| | | | | | | | | | | | | if_ovpn already notified userpsace when there was a risk of sequence number re-use, but it trusted userspace to actually rotate the key. Convert the internal sequence number counter to 64 bits so we can detect overflows and then refuse to send packets. Event: BSDCan 2023 Reviewed by: Leon Dang <ldang@netgate.com> Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D40187
* spdx: The BSD-2-Clause-FreeBSD identifier is obsolete, drop -FreeBSDWarner Losh2023-05-121-1/+1
| | | | | | | | | The SPDX folks have obsoleted the BSD-2-Clause-FreeBSD identifier. Catch up to that fact and revert to their recommended match of BSD-2-Clause. Discussed with: pfg MFC After: 3 days Sponsored by: Netflix
* if_ovpn: notify userspace when we've used half of the sequence numbersKristof Provost2023-05-081-3/+30
| | | | | | | | | | | | | OpenVPN uses the sequence number (as well as a userspace supplied nonce) to build the IV. This means we should avoid re-using sequence numbers. However, userspace doesn't know how many packets we've sent (and thus what sequence number we're up to). Notify userspace when we've used half of the available sequence numbers to tell it that it's time for a key renegotiaton. Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D39570
* if_ovpn: ovpn_find_peer_by_ip() is unused without INETKristof Provost2023-02-231-0/+4
| | | | | | | | 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")
* ifnet/API: Move struct ifnet definition to a <net/if_private.h>Justin Hibbits2023-01-241-0/+1
| | | | | | | | | | | 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
* Revert "if_ovpn: allow peer lookup by vpn4/vpn6 address"Kristof Provost2022-12-261-63/+18
| | | | | | | | | | | | | This reverts commit 92f0cf77db18502cac9a731cd2f6e8f3cc8a9369. 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")
* if_ovpn: fix LINT-NOIP buildKristof Provost2022-12-141-4/+0
| | | | | Reported by: mjg Sponsored by: Rubicon Communications, LLC ("Netgate")
* if_ovpn: cleanup offsetof() useKristof Provost2022-12-141-21/+15
| | | | | | | | | | | 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
* if_ovpn: include peer counters in a OVPN_NOTIF_DEL_PEER messageKristof Provost2022-12-141-9/+53
| | | | | | | | | 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
* if_ovpn: allow peer lookup by vpn4/vpn6 addressKristof Provost2022-12-141-18/+63
| | | | | | | | | 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
* if_ovpn: implement OVPN_GET_PEER_STATSKristof Provost2022-12-141-0/+57
| | | | | | | Allow userspace to retrieve per-peer traffic stats. Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D37604
* if_ovpn: start tracking per-peer packets/bytes in/outKristof Provost2022-12-141-0/+20
| | | | | | | | 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
* if_ovpn: remove OVPN_SEND_PKTKristof Provost2022-12-141-52/+0
| | | | | | | | | | 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
* if_ovpn: extend notifications with a reasonKristof Provost2022-12-051-11/+24
| | | | | | | | | | 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
* if_ovpn: remove peer limitKristof Provost2022-12-011-88/+48
| | | | | | | | | 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
* if_ovpn: pass control packets through the socketKristof Provost2022-11-151-79/+23
| | | | | | | | | | 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
* if_ovpn: ensure we're in vnet context when calling sorele()Kristof Provost2022-11-141-6/+13
| | | | | | | | | | | | | | | | 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
* if_ovpn: fix AES-128-GCM supportKristof Provost2022-11-111-1/+3
| | | | | | | | 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")
* if_ovpn: avoid netisr_queue name conflictsKristof Provost2022-10-241-4/+4
| | | | | | Rename the netisr_queue variable in if_ovpn.c to avoid naming conflicts. Sponsored by: Rubicon Communications, LLC ("Netgate")
* if_ovpn: add sysctls for netisr_queue() and crypto_dispatch_async()Kristof Provost2022-10-241-3/+24
| | | | | | | | | 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
* if_ovpn(4): implement ioctl() to set if_flagsGert Doering2022-10-171-0/+42
| | | | | | | | 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
* if_ovpn: fix use-after-freeKristof Provost2022-10-171-2/+3
| | | | | | | | | | 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")
* if_ovpn: remove an incorrect assertionKristof Provost2022-10-071-4/+1
| | | | | | | 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")
* if_ovpn: ensure we're in net_epoch when calling ovpn_encap()Kristof Provost2022-10-061-0/+7
| | | | | | | | | | | 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")
* if_ovpn: fix address family check when traffic class bits are setKristof Provost2022-09-261-1/+1
| | | | | | | | | | | | | | | 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")
* if_clone: migrate some consumers to the new KPI.Alexander V. Chernikov2022-09-221-4/+10
| | | | | | | | | 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
* if_ovpn: fix memory leak on unloadKristof Provost2022-09-211-0/+2
| | | | | | | | | | | | 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")
* if_ovpn: remove incorrect rounding up of packet sizesKristof Provost2022-09-211-12/+3
| | | | | | | | | 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")