If we pass a packet to dummynet we should indicate we've passed it (but
keep m0 == NULL). Otherwise we'll indicate to the calling layers that
the packet has been rejected.
Sponsored by: Rubicon Communications, LLC ("Netgate")
If we don't have a pipe set we shouldn't feed packets into dummynet.
This could occur if we have a 'dnpipe (0, 100)' configuration, for
example. We do want to feed the packet to dummynet in the return
direction, but not in the forward direction. In that case
pf_pdesc_to_dnflow() should return false, rather than pass a pipe number
of 0 to dummynet.
Sponsored by: Rubicon Communications, LLC ("Netgate")
Due to a typo dnrpipe (i.e. the pipe for reverse direction traffic) was
nevern assigned, preventing it from working correctly.
Sponsored by: Rubicon Communications, LLC ("Netgate")
This fixed panic with interface being removed while packet
was sitting on a queue. This allows to pass all dummynet
tests including forthcoming dummynet:ipfw_interface_removal
and dummynet:pf_interface_removal and demonstrates use of
m_rcvif_serialize() and m_rcvif_restore().
Reviewed by: kp
Differential revision: https://reviews.freebsd.org/D33267
(cherry picked from commit 165746f4e4bf54c5902a103c2d4a3455e651c58f)
ip_dn_io_ptr() (i.e. dummynet_io()) can return the mbuf immediately (as
opposed to owning it and later passing it through dummynet_send(), which
returns it to pf_test()). In that case we must clear the PF_TAG_DUMMYNET
flag to ensure we don't skip any subsequent firewall passes.
This can happen if we process a packet in PFIL_IN, set PF_TAG_DUMMYNET
on it, pass it to ip_dn_io_ptr() but have it returned immediately. The
packet continues its normal path, eventually hitting
pf_test(dir=PFIL_OUT), where we'd skip when we're not supposed to.
Sponsored by: Rubicon Communications, LLC ("Netgate")
Similar to ipfw rule timestamps, these timestamps internally are
uint32_t snaps of the system time in seconds. The timestamp is CPU local
and updated each time a rule or a state associated with a rule or state
is matched.
Reviewed by: kp
Sponsored by: Rubicon Communications, LLC ("Netgate")
Differential Revision: https://reviews.freebsd.org/D34970
Coverity points out that if counter was NULL when passed to
pfr_pool_get() we could potentially end up dereferencing it.
Happily all users of the function pass a non-NULL pointer. Enforce this
by assertion and remove the pointless NULL check.
Reported by: Coverity (CID 273309)
MFC after: 1 week
Sponsored by: Rubicon Communications, LLC ("Netgate")
Move the use of 'sc' to after the NULL check.
It's very unlikely that we'd actually hit this, but Coverity is correct
that it's not a good idea to dereference the pointer and only then NULL
check it.
Reported by: Coverity (CID 1398362)
MFC after: 1 week
Sponsored by: Rubicon Communications, LLC ("Netgate")
Allow tables to be used for the l3 source/destination matching.
This requires taking the PF_RULES read lock.
Sponsored by: Rubicon Communications, LLC ("Netgate")
Differential Revision: https://reviews.freebsd.org/D34917
Inactive Ethernet rules get cleaned by a net_epoch callback. This
callback may still be pending when we try to start a new (pf rules)
transaction, causing it to fail.
This is especially likely to occur in scripted scenarios, such as the
regression tests.
Drain the epoch callbacks before starting a new transaction, ensuring
we've had the opportunity to clean up the inactive rules.
Sponsored by: Rubicon Communications, LLC ("Netgate")
Differential Revision: https://reviews.freebsd.org/D34846
Matching for DSCP codes has used incorrect bits. Use IPV6_DSCP()
macro for matching opcodes to fix this. Also this leads to always
use value from a mbuf instead of cached value.
Previously different opcodes have used both cached in f_id value
and stored in the mbuf, and it did not always work after setdscp
action, since cached value was not updated.
Update IPv6 flowid value cached in the f_id.flow_id6 when we do
modification of DSCP value in O_SETDSCP opcode, it may be used by
external modules.
Also added logging support for O_SETDSCP opcode.
Reviewed by: kp
MFC after: 1 week
Differential Revision: https://reviews.freebsd.org/D34807
The RB_NEXT macro does not use its middle argument since commit
5fce408cc44c737267aaaf0dcecd3454ba9089cd in 2004 (which ironically
fixed an "unused parameter" warning by introducing this warning in all
consumers). RB_PREV has also copied this unfortunate behavior of an
unused argument.
This results in 'parent' not being used. To workaround, inline the
value of 'parent' as the second argument to RB_NEXT.
Reviewed by: kp
Differential Revision: https://reviews.freebsd.org/D34833
We forgot to free the nvlist (and packed nvlist) on success.
While here start using the ERROUT macro to clean up error handling, and
to add SDTs for better debugging.
Reported by: Coverity
CID: 1473150
The nvlist is allocated in pf_keth_rule_to_nveth_rule(). There's no need
to allocate one in the calling function. Especially not as we overwrite
the pointer to the new nvlist with the one allocated by
pf_keth_rule_to_nveth_rule(), leaking memory.
Reported by: Coverity
CID: 1476128
Sponsored by: Rubicon Communications, LLC ("Netgate")
Use ERROUT_IOCTL() rather than hand-rolling the macro. This adds DTrace
SDTs in the error path, making debugging ioctl errors easier.
MFC after: 1 week
Sponsored by: Rubicon Communications, LLC ("Netgate")
When trying to avoid a CARP demotion during a pfsync service restart, I
noticed that a non-default value for the net.pfsync.carp_demotion_factor
sysctl was not being applied during the demotion. The CARP was always
demoted by 240.
After investigating, I realized that the sysctl was using VNET_NAME()
without the CTLFLAG_VNET.
PR: 262983
Reviewed by: kp
MFC after: 1 week
Differential Revision: https://reviews.freebsd.org/D34737
The limit may later be updated by the "set limit" directive in pf.conf.
UMA does not permit a limit to be set on a zone after any items have
been allocated from a zone.
Other UMA zones used by pf do not appear to be susceptible to this
problem: they either set a limit at zone creation time or never set one
at all.
PR: 260406
Reviewed by: kp
MFC after: 3 days
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D34713
Possibility to do it was always a bug, but it runs into crashes
since recent introduction of a per-ruleset RB tree.
Reviewed by: kp
Sponsored by: Rubicon Communications, LLC ("Netgate")
Reported by: syzbot+665b700afc6f69f1766a@syzkaller.appspotmail.com
with md5 sum used as key.
This gets rid of the quadratic rule traversal when "keep_counters" is
set.
Reviewed by: kp
Sponsored by: Rubicon Communications, LLC ("Netgate")
Makes it cheaper to compare rules when "keep_counters" is set.
This also sets up keeping them in a RB tree.
Reviewed by: kp
Sponsored by: Rubicon Communications, LLC ("Netgate")
For now only protects rule creation/destruction, but will allow
gradually reducing the scope of rules lock when changing the
rules.
Reviewed by: kp
Sponsored by: Rubicon Communications, LLC ("Netgate")
Otherwise all anchors hash to the same value.
Note this can result in checksum mismatches between pfsynced hosts,
but it has to be sorted out as the previously computed checksum
would fail to indicate changed anchors.
Reviewed by: kp
Sponsored by: Rubicon Communications, LLC ("Netgate")
Disallow the use of tables in ethernet rules. Using tables requires
taking the PF_RULES lock. Moreover, the current table code isn't ready
to deal with ethernet rules.
Disallow their use for now.
Sponsored by: Rubicon Communications, LLC ("Netgate")
Allow filtering based on the source or destination IP/IPv6 address in
the Ethernet layer rules.
Reviewed by: pauamma_gundo.com (man), debdrup (man)
Sponsored by: Rubicon Communications, LLC ("Netgate")
Differential Revision: https://reviews.freebsd.org/D34482
Newly allocated counters are guaranteed to be 0.
This removes 5 IPIs for each loaded rule.
Reviewed by: kp
Sponsored by: Rubicon Communications, LLC ("Netgate")
When filtering Ethernet packets allow rules to specify a mac address
with a mask. This indicates which bits of the specified address are
significant. This allows users to do things like filter based on device
manufacturer.
Sponsored by: Rubicon Communications, LLC ("Netgate")
Allow packets to be tagged with dummynet information. Note that we do
not apply dummynet shaping on the L2 traffic, but instead mark it for
dummynet processing in the L3 code. This is the same approach as we take
for ALTQ.
Sponsored by: Rubicon Communications, LLC ("Netgate")
Differential Revision: https://reviews.freebsd.org/D32222
Allow the evaluations/packets/bytes counters on Ethernet rules to be
cleared.
Sponsored by: Rubicon Communications, LLC ("Netgate")
Differential Revision: https://reviews.freebsd.org/D31748
Avoid the overhead of the Ethernet pfil hooks if we don't have any
Ethernet rules.
Sponsored by: Rubicon Communications, LLC ("Netgate")
Differential Revision: https://reviews.freebsd.org/D31742
Avoid the overhead of acquiring a (read) RULES lock when processing the
Ethernet rules.
We can get away with that because when rules are modified they're staged
in V_pf_keth_inactive. We take care to ensure the swap to V_pf_keth is
atomic, so that pf_test_eth_rule() always sees either the old rules, or
the new ruleset.
We need to take care not to delete the old ruleset until we're sure no
pf_test_eth_rule() is still running with those. We accomplish that by
using NET_EPOCH_CALL() to actually free the old rules.
Sponsored by: Rubicon Communications, LLC ("Netgate")
Differential Revision: https://reviews.freebsd.org/D31739
This is the kernel side of stateless Ethernel level filtering for pf.
The primary use case for this is to enable captive portal functionality
to allow/deny access by MAC address, rather than per IP address.
Sponsored by: Rubicon Communications, LLC ("Netgate")
Differential Revision: https://reviews.freebsd.org/D31737
The ref_count counter is global (i.e. not per-vnet) so we can't use a
per-vnet lock to protect it. Moreover, in callouts curvnet is not set,
so we'd end up panicing when trying to use DN_BH_WLOCK().
Instead we use the global sched_lock, which is already used when
evaluating ref_count (in unload_dn_aqm()).
Sponsored by: Rubicon Communications, LLC ("Netgate")
Differential Revision: https://reviews.freebsd.org/D34059
When we create a table without counters, add an entry and later
re-define the table to have counters we wound up trying to read
non-existent counters.
We now cope with this by attempting to add them if needed, removing them
when they're no longer needed and not trying to read from counters that
are not present.
MFC after: 2 weeks
Sponsored by: Rubicon Communications, LLC ("Netgate")
Differential Revision: https://reviews.freebsd.org/D34131