Commit Graph

591 Commits

Author SHA1 Message Date
Kristof Provost
bf206a1db2 pf: remove NULL check before uma_zfree()
uma_zfree() can be called on a NULL pointer. Simplify the pf code a
little by removing the redundant checks.

Sponsored by:	Rubicon Communications, LLC ("Netgate")
2023-05-04 18:22:54 +02:00
Kajetan Staszkiewicz
16303d2ba6 pf: improve source node error handling
Functions manipulating source nodes can fail due to various reasons like
memory allocation errors, hitting configured limits or lack of
redirection targets. Ensure those errors are properly caught and
propagated in the code. Increase the error counters not only when
parsing the main ruleset but the NAT ruleset too.

Cherry-picked from development of D39880

Reviewed by:	kp
Sponsored by:	InnoGames GmbH
Differential Revision:	https://reviews.freebsd.org/D39940
2023-05-03 10:31:05 +02:00
Kristof Provost
7b67669885 pf: simplify structs with anonymous unions
Rather than playing preprocessor hacks use actual anonymous unions.
No functional change.

Sponsored by:	Rubicon Communications, LLC ("Netgate")
2023-05-03 10:24:20 +02:00
Tom Hukins
7626863e19 pf: Fix a spelling mistake in a comment
Pull Request:	https://github.com/freebsd/freebsd-src/pull/704
2023-05-01 10:30:15 -04:00
Kajetan Staszkiewicz
db0a2bfd0c pf: reduce number of hashing operations when handling source nodes
Reduce number of hashing operations when handling source nodes by always
having a pointer to the hash row mutex in the source node. Provide
macros for handling and asserting the mutex. Calculate the hash only
once in pf_find_src_node() and then use this hash in subsequent
operations.

Cherry-picked from development of D39880

Reviewed by:	kp, mjg
Sponsored by:	InnoGames GmbH
Differential Revision:	https://reviews.freebsd.org/D39888
2023-05-01 16:15:30 +02:00
Kristof Provost
a81f5112a0 pf: clear PF_TAG_ROUTE_TO for dummynet fast path
Similar to the PF_TAG_DUMMYNET we must also clear the route tag if
dummynet didn't keep the packet. In that case we'd continue immediately
and there'd be no need for the route tag. Keeping it could lead to
unexpected routing of traffic.

See also:	27407a6adc
See also:	https://redmine.pfsense.org/issues/14055
Sponsored by:	Rubicon Communications, LLC ("Netgate")
2023-04-26 17:09:47 +02:00
Christian McDonald
ef661d4a5b pf: introduce ridentifier and labels to ether rules
Make Ethernet rules more similar to the usual layer 3 rules by also
allowing ridentifier and labels to be set on them.

Reviewed by:	kp
Sponsored by:	Rubicon Communications, LLC ("Netgate")
2023-04-26 11:14:41 +02:00
Kristof Provost
2e6cdfe293 pf: change pf_rules_lock and pf_ioctl_lock to per-vnet locks
Both pf_rules_lock and pf_ioctl_lock only ever affect one vnet, so
there's no point in having these locks affect other vnets.
(In fact, the only lock in pf that can affect multiple vnets is
pf_end_lock.)

That's especially important for the rules lock, because taking the write
lock suspends all network traffic until it's released. This will reduce
the impact a vnet running pf can have on other vnets, and improve
concurrency on machines running multiple pf-enabled vnets.

Reviewed by:	zlei
Sponsored by:	Rubicon Communications, LLC ("Netgate")
Differential Revision:	https://reviews.freebsd.org/D39658
2023-04-19 09:50:52 +02:00
Kajetan Staszkiewicz
39282ef356 pf: backport OpenBSD syntax of "scrub" option for "match" and "pass" rules
Introduce the OpenBSD syntax of "scrub" option for "match" and "pass"
rules and the "set reassemble" flag. The patch is backward-compatible,
pf.conf can be still written in FreeBSD-style.

Obtained from:	OpenBSD
MFC after:	never
Sponsored by:	InnoGames GmbH
Differential Revision:	https://reviews.freebsd.org/D38025
2023-04-14 09:04:06 +02:00
Kristof Provost
27b23cdec9 pf: remove pd_refs from pfsync
It only served to complicate cleanup, and added no value.

While here drop packets in pfsync_defer_tmo() if we don't have a syncif,
rather than just leaving them on the queue.

Reviewed by:	markj
Sponsored by:	Rubicon Communications, LLC ("Netgate")
Differential Revision:	https://reviews.freebsd.org/D39248
2023-03-28 01:18:07 +02:00
Kristof Provost
01194da28a pfsync: hold b_mtx for callout_stop(pd_tmo)
The pd_tmo callout has an associated mutex, which we must hold while
calling callout_stop().

Reported by:	markj
Reviewed by:	markj
MFC after:	3 days
Sponsored by:	Rubicon Communications, LLC ("Netgate")
Differential Revision:	https://reviews.freebsd.org/D39223
2023-03-28 01:17:55 +02:00
Kristof Provost
ad729f8d50 pf: ignore ip6_output() return value in pf_refragment6()
We can't do anything if ip6_output() fails, other than discard the
packet which ip6_output() already does for us.
Mark the return value as ignored.

Reported by:	emaste, Coverity
Sponsored by:	Rubicon Communications, LLC (Netgate)
2023-03-24 08:08:19 +01:00
Kristof Provost
53247cdf12 pfsync: fix pfsync_undefer_state() locking
pfsync_undefer_state() takes the bucket lock, but could get called from
places (e.g. from pfsync_update_state() or pfsync_delete_state()) where
we already held the lock.

As it can also be called from places where we don't yet hold the lock
create new locked variant for use when the lock is already held. Keep
using pfsync_undefer_state() where the lock must still be taken.

PR:		268246
MFC after:	1 week
Sponsored by:	Rubicon Communications, LLC (Netgate)
2023-03-20 16:39:14 +01:00
Kristof Provost
844ad2828a pfsync: add missing unlock in pfsync_defer_tmo()
The callout for pfsync_defer_tmo() is created with
CALLOUT_RETURNUNLOCKED, because while the callout framework takes care
of taking the lock we want to run a few operations outside of the lock,
so we unlock ourselves.

However, if `sc->sc_sync_if == NULL` we return without releasing the
lock, and leak the lock, causing later deadlocks.
Ensure we always release the bucket lock when we exit pfsync_defer_tmo()

PR:		268246
MFC after:	1 week
Sponsored by:	Rubicon Communications, LLC (Netgate)
2023-03-20 16:39:14 +01:00
Kristof Provost
80e76c61cc pf: set scope in pf_refragment6()
Link-local traffic needs to have a scope embedded before it's passed on
to ip6_output(). Do so in pf_refragment6(), because when we end up here
in the output path we may have passed through ip6_output() already
(before being reassembled), where the scope would have been removed.

Re-embed the scope so that link-local traffic is sent correctly.

Sponsored by:	Rubicon Communications, LLC ("Netgate")
Differential Revision:	https://reviews.freebsd.org/D39062
2023-03-16 10:59:04 +01:00
Kristof Provost
b52b61c0b6 pf: distinguish forwarding and output cases for pf_refragment6()
Re-introduce PFIL_FWD, because pf's pf_refragment6() needs to know if
we're ip6_forward()-ing or ip6_output()-ing.

ip6_forward() relies on m->m_pkthdr.rcvif, at least for link-local
traffic (for in6_get_unicast_scopeid()). rcvif is not set for locally
generated traffic (e.g. from icmp6_reflect()), so we need to call the
correct output function.

Sponsored by:	Rubicon Communications, LLC ("Netgate")
Differential Revisi:	https://reviews.freebsd.org/D39061
2023-03-16 10:59:04 +01:00
Kristof Provost
f52ca3dfd5 pfsync: ensure 'error' is always initialised
Reported by:	Herbert J. Skuhra <herbert@gojira.at>
MFC after:	2 weeks
2023-02-16 09:16:35 +01:00
Kristof Provost
9a1cab6d79 pfsync: support deferring IPv6 packets
When we send out a deferred packet we must make sure to call
ip6_output() for IPv6 packets. If not we might end up attempting to
ip_fragment() an IPv6 packet, which could lead to us reading outside of
the mbuf.

PR:		268246
Reviewed by:	melifaro, zlei
MFC after:	2 weeks
Differential Revision:	https://reviews.freebsd.org/D38586
2023-02-16 07:43:04 +01:00
Gleb Smirnoff
caf32b260a pfil: add pfil_mem_{in,out}() and retire pfil_run_hooks()
The 0b70e3e78b changed the original design of a single entry point
into pfil(9) chains providing separate functions for the filtering
points that always provide mbufs and know the direction of a flow.
The motivation was to reduce branching.  The logical continuation
would be to do the same for the filtering points that always provide
a memory pointer and retire the single entry point.

o Hooks now provide two functions: one for mbufs and optional for
  memory pointers.
o pfil_hook_args() has a new member and pfil_add_hook() has a
  requirement to zero out uninitialized data. Bump PFIL_VERSION.
o As it was before, a hook function for a memory pointer may realloc
  into an mbuf.  Such mbuf would be returned via a pointer that must
  be provided in argument.
o The only hook that supports memory pointers is ipfw:default-link.
  It is rewritten to provide two functions.
o All remaining uses of pfil_run_hooks() are converted to
  pfil_mem_in().
o Transparent union of pfil_packet_t and tricks to fix pointer
  alignment are retired. Internal pfil_realloc() reduces down to
  m_devget() and thus is retired, too.

Reviewed by:		mjg, ocochard
Differential revision:	https://reviews.freebsd.org/D37977
2023-02-14 10:02:49 -08:00
Kristof Provost
0ed5f66c5a pfsync: add missing bucket lock
pfsync_q_ins() expects us to hold the bucket lock, but when we enter it
from pfsync_state_import() we don't.

MFC after:	2 weeks
2023-02-03 09:39:09 +01:00
Justin Hibbits
3d0d5b21c9 IfAPI: Explicitly include <net/if_private.h> in netstack
Summary:
In preparation of making if_t completely opaque outside of the netstack,
explicitly include the header.  <net/if_var.h> will stop including the
header in the future.

Sponsored by:	Juniper Networks, Inc.
Reviewed by:	glebius, melifaro
Differential Revision: https://reviews.freebsd.org/D38200
2023-01-31 15:02:16 -05:00
Kristof Provost
fd02192c3a pf: fix panic on deferred packets
The pfsync_defer_tmo() callout needs to set the correct vnet before it
can transmit packets. It used the rcvif in the mbuf to get this vnet,
but that doesn't work for locally originated traffic. In that case the
rcvif pointer is NULL, and the dereference leads to a panic.

Instead use the sc_sync_if, which is always set (if pfsync is enabled,
at least).

PR:		268246
MFC after:	2 weeks
2023-01-13 20:41:25 +01:00
Kristof Provost
933be8d74b pf: default syncookies to adaptive mode
The cost of enabling syncookies in adaptive mode is very low (basically
a single atomic add when we create a new half-open state), and the
payoff when under SYN flood is huge.

So, enable adaptive mode by default.

Suggested by:   Eirik Øverby
2023-01-13 23:14:25 +01:00
Kristof Provost
9c041b450d pf: fix syncookies in conjunction with tcp fast port reuse
Basic scenario: we have a closed connection (In TCPS_FIN_WAIT_2), and
get a new connection (i.e. SYN) re-using the tuple.

Without syncookies we look at the SYN, and completely unlink the old,
closed state on the SYN.
With syncookies we send a generated SYN|ACK back, and drop the SYN,
never looking at the state table.

So when the ACK (i.e. the third step in the three way handshake for
connection setup) turns up, we’ve not actually removed the old state, so
we find it, and don’t do the syncookie dance, or allow the new
connection to get set up.

Explicitly check for this in pf_test_state_tcp(). If we find a state in
TCPS_FIN_WAIT_2 and the syncookie is valid we delete the existing state
so we can set up the new state.
Note that when we verify the syncookie in pf_test_state_tcp() we don't
decrement the number of half-open connections to avoid an incorrect
double decrement.

MFC after:      2 weeks
Differential Revision:  https://reviews.freebsd.org/D37919
2023-01-13 23:14:12 +01:00
Mark Johnston
57cc96f49e pf: Fix definitions of pf_pfil_*_hooked
This use of "volatile" in the vnet definitions doesn't have any effect.
VNET_DEFINE_STATE(volatile int, ...) should work, but let's avoid using
"volatile" altogether and convert to atomic_load/atomic_store.  Also
convert to bool while here.

Reviewed by:	kp, mjg
MFC after:	1 week
Sponsored by:	The FreeBSD Foundation
Differential Revision:	https://reviews.freebsd.org/D37684
2022-12-14 09:29:59 -05:00
Nick Reilly
bfeef0d32a pf: fix pfi_ifnet leak on interface removal
The detach of the interface and group were leaving pfi_ifnet memory
behind. Check if the kif still has references, and clean it up if it
doesn't

On interface detach, the group deletion was notified first and then a
change notification was sent. This would recreate the group in the kif
layer. Reorder the change to before the delete.

PR:		257218
MFC after:	2 weeks
Differential Revision:	https://reviews.freebsd.org/D37569
2022-12-14 10:19:01 +01:00
Gleb Smirnoff
e68b379244 tcp: embed inpcb into tcpcb
For the TCP protocol inpcb storage specify allocation size that would
provide space to most of the data a TCP connection needs, embedding
into struct tcpcb several structures, that previously were allocated
separately.

The most import one is the inpcb itself.  With embedding we can provide
strong guarantee that with a valid TCP inpcb the tcpcb is always valid
and vice versa.  Also we reduce number of allocs/frees per connection.
The embedded inpcb is placed in the beginning of the struct tcpcb,
since in_pcballoc() requires that.  However, later we may want to move
it around for cache line efficiency, and this can be done with a little
effort.  The new intotcpcb() macro is ready for such move.

The congestion algorithm data, the TCP timers and osd(9) data are
also embedded into tcpcb, and temprorary struct tcpcb_mem goes away.
There was no extra allocation here, but we went through extra pointer
every time we accessed this data.

One interesting side effect is that now TCP data is allocated from
SMR-protected zone.  Potentially this allows the TCP stacks or other
TCP related modules to utilize that for their own synchronization.

Large part of the change was done with sed script:

s/tp->ccv->/tp->t_ccv./g
s/tp->ccv/\&tp->t_ccv/g
s/tp->cc_algo/tp->t_cc/g
s/tp->t_timers->tt_/tp->tt_/g
s/CCV\(ccv, osd\)/\&CCV(ccv, t_osd)/g

Dependency side effect is that code that needs to know struct tcpcb
should also know struct inpcb, that added several <netinet/in_pcb.h>.

Differential revision:	https://reviews.freebsd.org/D37127
2022-12-07 09:00:48 -08:00
Kristof Provost
57e047e51c pf: allow scrub rules without fragment reassemble
scrub rules have defaulted to handling fragments for a long time, but
since we removed "fragment crop" and "fragment drop-ovl" in 64b3b4d611
this has become less obvious and more expensive ("reassemble" being the
more expensive option, even if it's the one the vast majority of users
should be using).

Extend the 'scrub' syntax to allow fragment reassembly to be disabled,
while retaining the other scrub behaviour (e.g. TTL changes, random-id,
..) using 'scrub fragment no reassemble'.

Sponsored by:	Rubicon Communications, LLC ("Netgate")
Differential Revision:	https://reviews.freebsd.org/D37459
2022-11-28 20:19:05 +01:00
Kristof Provost
48767d8734 pfsync: fix memory leak
The recent refactoring to prepare for pfsync over IPv6 introduced a
memory leak.
If we don't have a sync peer configured we return early (without sending
out a packet), but failed to free the newly allocated packet.

Sponsored by:	Rubicon Communications, LLC ("Netgate")
2022-11-15 12:13:11 +01:00
Luiz Amaral
813c5b75e6 pfsync: prepare code to accommodate AF_INET6 family
Work is ongoing to add support for pfsync over IPv6. This required some
changes to allow for differentiating between the two families in a more
generic way.

This patch converts the relevant ioctls to using nvlists, making future
extensions (such as supporting IPv6 addresses) easier.

Sponsored by:	InnoGames GmbH
Differential Revision:	https://reviews.freebsd.org/D36277
2022-11-09 21:06:07 +01:00
Kristof Provost
8a8af94240 pf: bridge-to
Allow pf (l2) to be used to redirect ethernet packets to a different
interface.

The intended use case is to send 802.1x challenges out to a side
interface, to enable AT&T links to function with pfSense as a gateway,
rather than the AT&T provided hardware.

Sponsored by:	Rubicon Communications, LLC ("Netgate")
Differential Revision:	https://reviews.freebsd.org/D37193
2022-11-02 15:45:23 +01:00
Kristof Provost
444a77ca85 pf: expose syncookie active/inactive status
When syncookies are in adaptive mode they may be active or inactive.
Expose this status to users.

Suggested by:	Guido van Rooij
Sponsored by:	Rubicon Communications, LLC ("Netgate")
2022-10-31 18:14:09 +01:00
Gordon Bergling
558ec54da3 netpfil: Fix two typos in source code comments
- s/missmatch/mismatch/

MFC after:	3 days
2022-10-25 04:32:59 +02:00
Kristof Provost
b37707bb39 pf: fix LINT-NOINET6 build 2022-10-15 10:02:35 +02:00
Kristof Provost
a974702e27 pf: apply the network stack's ICMP rate limiting to ICMP errors sent by pf
PR:		266477
Event:		Aberdeen Hackathon 2022
Differential Revision:	https://reviews.freebsd.org/D36903
2022-10-14 10:36:16 +02:00
Kristof Provost
133935d26f pf: atomically increment state ids
Rather than using a per-cpu state counter, and adding in the CPU id we
can atomically increment the number.
This has the advantage of removing the assumption that the CPU ID fits
in 8 bits.

Event:		Aberdeen Hackathon 2022
Reviewed by:	mjg
Differential Revision:	https://reviews.freebsd.org/D36915
2022-10-08 18:27:29 +02:00
Kristof Provost
1d090028d3 pf: use time_to for timestamps
Use time_t rather than uint32_t to represent the timestamps. That means
we have 64 bits rather than 32 on all platforms except i386, avoiding
the Y2K38 issues on most platforms.

Reviewed by:	Zhenlei Huang
Sponsored by:	Rubicon Communications, LLC ("Netgate")
Differential Revision:	https://reviews.freebsd.org/D36837
2022-10-05 17:52:27 +02:00
Kristof Provost
0044bd90f2 pf: fix memory leak retrieving Ethernet rules
Remember to free the nvlist we've added to our main nvlist.

Sponsored by:	Rubicon Communications, LLC ("Netgate")
2022-09-27 15:28:37 +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
Mateusz Guzik
e5d08f4729 pf: remove pf_bcmp_state_key
Clang 14 performs the optimisation on its own, thus the custom code is
no longer needed.

Sponsored by:	Rubicon Communications, LLC ("Netgate")
2022-09-09 17:16:58 +00:00
Mateusz Guzik
6b94546a7e pf: partially depessimize pf_match_translation
Reviewed by:	kp
Sponsored by:	Rubicon Communications, LLC ("Netgate")
2022-09-09 17:03:55 +00:00
Mateusz Guzik
69ce6ae21a pf: make pfsync_state_import appease an assert in pf_free_state
The newly created state failed to be inserted anywhere. This follows
other places.

Reviewed by:	kp
Sponsored by:	Rubicon Communications, LLC ("Netgate")
2022-09-06 15:00:46 +00:00
Mateusz Guzik
9503043f6e pf: stop using PFIL_FWD
It is only there to check if the packet was reassembled,
relevant if we are forwarding. But if the packet originated
locally it could not have been reassembled, thus the flag is
redundant.

Reviewed by:	kp
Sponsored by:	Rubicon Communications, LLC ("Netgate")
2022-09-05 13:06:12 +00:00
Kristof Provost
6ab80e7275 pf: do not block new Ethernet rules for in-progress transactions
Make Ethernet rule addition behave just like L3 rules, in that we now
allow ongoing transaction to be interrupted, rather than rejecting a new
one.

The result of that is that we can no longer end up in a state where a
transaction failed, but was not rolled back, blocking us from setting
new rules.

It's safe to assume there's no pending epoch callback for cleanup here,
because we've explicitly called it before hitting pf_begin_eth().

Sponsored by:	Rubicon Communications, LLC ("Netgate")
2022-08-27 22:25:01 +02:00
Luiz Amaral
485be9798a pfsync: replace struct pfsync_pkt with int flags
Get rid of struct pfsync_pkt. It was used to store data on the stack to
pass to all the submessage handlers, but only the flags part of it was
ever used. Just pass the flags directly instead.

Reviewed by:		kp
Obtained from:		OpenBSD
Sponsored by:		InnoGames GmbH
Differential Revision:	https://reviews.freebsd.org/D36294
2022-08-22 23:46:50 +02:00
Ed Maste
6b598e263b pf: Reduce diffs against OpenBSD in pf_if.c
Use memset instead of bzero, memcpy instead of bcopy, and add some
optional {}s.

Reviewed by:	kp
MFC after:	1 week
Sponsored by:	The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D36267
2022-08-20 11:52:05 -04:00
Kristof Provost
c780d3ad7b pf: clear ethernet rules prior to shutdown
Ethernet rule cleanup is postponed to an epoch callback. Ensure it's
been called before we remove the entire vnet, or we risk the rules still
getting hit after we've freed the uma zone, i.e. a use-after-free.

Sponsored by:	Rubicon Communications, LLC ("Netgate")
2022-08-19 14:53:09 +02:00
Gleb Smirnoff
78b1fc05b2 protosw: separate pr_input and pr_ctlinput out of protosw
The protosw KPI historically has implemented two quite orthogonal
things: protocols that implement a certain kind of socket, and
protocols that are IPv4/IPv6 protocol.  These two things do not
make one-to-one correspondence. The pr_input and pr_ctlinput methods
were utilized only in IP protocols.  This strange duality required
IP protocols that doesn't have a socket to declare protosw, e.g.
carp(4).  On the other hand developers of socket protocols thought
that they need to define pr_input/pr_ctlinput always, which lead to
strange dead code, e.g. div_input() or sdp_ctlinput().

With this change pr_input and pr_ctlinput as part of protosw disappear
and IPv4/IPv6 get their private single level protocol switch table
ip_protox[] and ip6_protox[] respectively, pointing at array of
ipproto_input_t functions.  The pr_ctlinput that was used for
control input coming from the network (ICMP, ICMPv6) is now represented
by ip_ctlprotox[] and ip6_ctlprotox[].

ipproto_register() becomes the only official way to register in the
table.  Those protocols that were always static and unlikely anybody
is interested in making them loadable, are now registered by ip_init(),
ip6_init().  An IP protocol that considers itself unloadable shall
register itself within its own private SYSINIT().

Reviewed by:		tuexen, melifaro
Differential revision:	https://reviews.freebsd.org/D36157
2022-08-17 11:50:31 -07:00
Gleb Smirnoff
8c77967ecc protosw: retire pr_output method
The only place to execute this method was raw_usend(). Only those
protocols that used raw socket were able to actually enter that method.
All pr_output assignments being deleted by this commit were a dead code
for many years.

Reviewed by:		melifaro
Differential revision:	https://reviews.freebsd.org/D36126
2022-08-11 09:19:37 -07:00
Zhenlei Huang
150486f6a9 Introduce and use the NET_EPOCH_DRAIN_CALLBACKS() macro
Reviewed by:	melifao, kp
Differential Revision:	https://reviews.freebsd.org/D35968
2022-07-29 21:21:10 +02:00