aboutsummaryrefslogtreecommitdiff
path: root/sys/netpfil/pf/pf_norm.c
Commit message (Collapse)AuthorAgeFilesLines
* pf: remove unused 'dir' argument in pf_reassemble()Kristof Provost5 days1-5/+5
| | | | | | pf_reassemble() only uses it to pass to pf_ip2key(), which also does not use it. Sponsored by: Rubicon Communications, LLC ("Netgate")
* pf: be more strict about IPv6 fragmentsKristof Provost2025-05-091-3/+6
| | | | | | | | | | | Follow RFC 5722 more strictly when handling overlapping fragments in pf. Drop the whole fragment state if IPv6 fragments appear which have invalid length or fragment-offset or more-fragment-bit. In IPv4 they are considered invalid and just dropped like before. Found by Antonios Atlasis; OK sashan@ sthen@ Obtained from: OpenBSD, bluhm <bluhm@openbsd.org>, f0f63321f2 Sponsored by: Rubicon Communications, LLC ("Netgate")
* pf: push 'field changed' guards into 'change field' functionsKristof Provost2025-04-231-4/+2
| | | | | | | | optimise pf_patch_32(); simplify pf_match_addr() OK mikeb@ Obtained from: OpenBSD, procter <procter@openbsd.org>, 7f3e6f164e Sponsored by: Rubicon Communications, LLC ("Netgate")
* pf: remove _unaligned from pf_patch_(16|32)_unaligned()Kristof Provost2025-04-161-3/+3
| | | | | | | This is the only variant of the function, appending _unaligned does not clarify anything. Sponsored by: Rubicon Communications, LLC ("Netgate")
* pf: simplify pf_patch* argumentsKristof Provost2025-04-161-12/+6
| | | | | | Pass struct pf_pdesc rather than separate arguments. Sponsored by: Rubicon Communications, LLC ("Netgate")
* pf: Don't convert arc4random() to host byte orderKristof Provost2025-04-161-1/+1
| | | | | | | | | | There's no need to convert values returned by arc4random to the network byte order. Spotted by Gleb Smirnoff (glebius@FreeBSD.org), thanks! ok tedu Obtained from: OpenBSD, mikeb <mikeb@openbsd.org>, 367b0410d3 Sponsored by: Rubicon Communications, LLC ("Netgate")
* pf: emit ICMPv6 packet too big for route-toKristof Provost2025-04-091-1/+8
| | | | | | | | Based on OpenBSD's ae08e5b41d6 (by sashan <sashan@openbsd.org>). We already implemented most of this (i.e. the refragmenting) but we did not send the packet-too-big error. Sponsored by: Rubicon Communications, LLC ("Netgate")
* pf: unused arguments at pf_normalize_tcp_init()Kristof Provost2025-04-091-1/+1
| | | | | | | OK deraadt. Obtained from: OpenBSD, sashan <sashan@openbsd.org>, eaed871b13 Sponsored by: Rubicon Communications, LLC ("Netgate")
* pf: INET/INET6 address family check should be unified in PFKristof Provost2025-04-091-6/+10
| | | | | | | | | | It also adds af_unhandled(), where it is currently missing. ok mcbride@ Obtained from: OpenBSD, sashan <sashan@openbsd.org>, 9b00340fee Obtained from: OpenBSD, sashan <sashan@openbsd.org>, 3f22add75d Sponsored by: Rubicon Communications, LLC ("Netgate")
* netinet: allow per protocol random IP id control, single out IPSECacazuc2025-03-041-1/+1
| | | | | | | | | | | | | | | | A globally enabled random IP id generation maybe useful in most IP contexts, but it may be unnecessary in the case of IPsec encapsulated packets because IPsec can be configured to use anti-replay windows. This commit adds a new net.inet.ipsec.random_id sysctl to control whether or not IPsec packets should use random IP id generation. Rest of the protocols/modules are still controlled by the global net.inet.ip.random_id, but can be easily augmented with a knob. Reviewed by: glebius Sponsored by: Stormshield Differential Revision: https://reviews.freebsd.org/D49164
* pf: micro-optimise padding checkKristof Provost2025-02-211-2/+4
| | | | | | | | | | | In most cases, IP fragments do not have an Ethernet padding. So add a condition to save a useless call to m_adj() and have a paranoid length check in the other cases. OK henning@ Obtained from: OpenBSD, bluhm <bluhm@openbsd.org>, fcf0d61153 Obtained from: OpenBSD, chris <chris@openbsd.org>, ebe64b684c Sponsored by: Rubicon Communications, LLC ("Netgate")
* pf: make log(matches) more usefulKristof Provost2025-02-211-3/+3
| | | | | | | | | | | | | | | | | change log(matches) semantics slightly to make it more useful. since it is a debug tool change of semantics not considered problematic. up until now, log(matches) forced logging on subsequent matching rules, the actual logging used the log settings from that matched rule. now, log(matches) causes subsequent matches to be logged with the log settings from the log(matches) rule. in particular (this was the driving point), log(matches, to pflog23) allows you to have the trace log going to a seperate pflog interface, not clobbering your regular pflogs, actually not affecting them at all. long conversation with bluhm about it, which didn't lead to a single bit changed in the diff but was very very helpful. ok bluhm as well. Obtained from: OpenBSD, henning <henning@openbsd.org>, f61b1efcce Sponsored by: Rubicon Communications, LLC ("Netgate")
* pf: do not reset the fragment timeout each time a fragment arrivesKristof Provost2025-02-131-2/+0
| | | | | | | | | | Start the expire counter when the queue is created by the first fragment and drop it if the packet could not be reassembled within 60 seconds. Reported by Antonios Atlasis; OK henning@ deraadt@ Obtained from: OpenBSD, bluhm <bluhm@openbsd.org>, 4697a20621 Sponsored by: Rubicon Communications, LLC ("Netgate")
* pf: make length overlow protection more obviousKristof Provost2025-02-121-2/+2
| | | | | | | | | | | Before pulling the TCP options from the mbuf onto the stack, do an additional length check in pf_modulate_sack() and pf_normalize_mss(). Overflow cannot happen due to the restricted values in the length calculation. As this is not obvious, be better safe than sorry. OK henning@ Obtained from: OpenBSD, henning <henning@openbsd.org>, a9e7ebb0d5 Sponsored by: Rubicon Communications, LLC ("Netgate")
* pf: fix fragment hole countKristof Provost2025-02-111-23/+10
| | | | | | | | | | | | | | | | Fragment reassembly finishes when no holes are left in the fragment queue. In certain overlap conditions, the hole counter was wrong and pf(4) created an incomplete IP packet. Before adjusting the length, remove the overlapping fragment from the queue and insert it again afterwards. pf_frent_remove() and pf_frent_insert() adjust the hole counter automatically. bug reported and fix tested by Lucas Aubard with Johan Mazel, Gilles Guette and Pierre Chifflier; OK claudio@ MFC after: 1 week Obtained from: OpenBSD, bluhm <bluhm@openbsd.org>, 9915416fe8 Sponsored by: Rubicon Communications, LLC ("Netgate")
* pf: remove unused functionKristof Provost2025-02-051-13/+0
| | | | | | No functional change. Sponsored by: Rubicon Communications, LLC ("Netgate")
* pf: clean up mbuf passing for reassemblyKristof Provost2025-01-171-12/+5
| | | | | | | | | | | | | When we call pf_normalize_ip() or pf_normalize_ip6() we passed the mbuf twice. Once as m0, and once inside the struct pf_pdesc. Remove the former to avoid confusion when we free *m0, but don't update pd->m. This could lead to use-after-free errors e.g. if reassembly failed. PR: 283705 Reported by: Yichen Chai <yichen.chai@gmail.com>, Zhuo Ying Jiang Li <zyj20@cl.cam.ac.uk> MFC after: 3 days Sponsored by: Rubicon Communications, LLC ("Netgate")
* pf: verify that ABORT chunks are not mixed with DATA chunksKristof Provost2025-01-171-0/+8
| | | | | | | RFC4960 3.3.7: DATA chunks MUST NOT be bundled with ABORT. MFC after: 2 weeks Sponsored by: Orange Business Services
* pf: do not keep state when dropping overlapping IPv6 fragmentsKristof Provost2025-01-141-22/+8
| | | | | | | ok sperreault@ Obtained from: OpenBSD, bluhm <bluhm@openbsd.org>, cd45765685 Sponsored by: Rubicon Communications, LLC ("Netgate")
* pf: drop IPv6 packets built from overlapping fragments in pf reassemblyKristof Provost2025-01-141-8/+38
| | | | | | | | | | | | | | | | | | | The reassembly state will be dropped after timeout, all related fragments are dropped until that. This is conforming to RFC 5722. - Sort pf_fragment fields while there. - If the fr_queue is empty, we had overlapping fragments, don't add new ones. - If we detect overlapping IPv6 fragments, flush the fr_queue and drop all fragments immediately. - Rearrange debug output, to make clear what happens. - An IPv4 fragment that is totaly overlapped does not inclease the bad fragment counter. - Put an KASSERT into pf_isfull_fragment() to make sure that the fr_queue is never emtpy there. discussed with Fernando Gont; ok henning@ Obtained from: OpenBSD, bluhm <bluhm@openbsd.org>, 8b45f36762 Sponsored by: Rubicon Communications, LLC ("Netgate")
* pf: remove pf_remove_fragment()Kristof Provost2025-01-141-11/+15
| | | | | | | | | | | Instead of having two functions pf_free_fragment() and pf_remove_fragment() doing more or less the same, merge them into one. Just remove fragment entries from the queue in pf_join_fragment() before they are freed. Then pf_remove_fragment() is not needed anymore. ok henning@ Obtained from: OpenBSD, bluhm <bluhm@openbsd.org>, dc8c96a470 Sponsored by: Rubicon Communications, LLC ("Netgate")
* pf: handle fragmentation for nat64Kristof Provost2024-12-171-7/+19
| | | | | | | | When we reassemble IPv4 packets tag them just like we tag the IPv6 reassembled packtes. Use this information as the basis for refragmenting the IPv6 packet. Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D47804
* pf: update pd->tot_len after reassemblyKristof Provost2024-12-171-0/+4
| | | | | | | | Ensure that the packet length we track in struct pf_pdesc matches the reassembled packet size. Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D47803
* tcp: extend the use of the th_flags accessor functionRichard Scheffenegger2024-11-291-6/+6
| | | | | | | | | | | Formally, there are 12 bits for TCP header flags. Use the accessor functions in more (kernel) places. No functional change. Reviewed By: cc, #transport, cy, glebius, #iflib, kbowling Sponsored by: NetApp, Inc. Differential Revision: https://reviews.freebsd.org/D47063
* pf: handle IPv6 fragmentation for route-toKristof Provost2024-11-261-10/+24
| | | | | | | | | | | | | | | | | If a fragmented IPv6 packet hits a route-to rule we have to first prevent the pf_test(PF_OUT) check in pf_route6() from refragmenting (and calling ip6_output()/ip6_forward()). We then have to refragment in pf_route6() and transmit the packets on the route-to interface. Split pf_refragment6() into two parts, the first to perform the refragmentation, the second to call ip6_output()/ip6_forward() and call the former from pf_route6(). Add a test case for route-to-ing fragmented IPv6 packets to verify this works as expected. Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D47684
* pf: fix build on kernels without "options INET"Lexi Winter2024-11-041-0/+2
| | | | | | | | | | | | - IN_LOOPBACK() cannot be used without INET, because it references a VNET symbol vnet_entry_in_loopback_mask. - ip_fillid() is not available without INET. since this codepath is only entered in the AF_INET case, guard it with #ifnet INET. Fixes: 27f54be50bbad ("pf: merge pf_test() and pf_test6()") Fixes: 4f9e688708f1b ("pf: merge pf_scrub_ip() and pf_scrub_ip6()") Reviewed by: kp
* pf: move the mbuf into struct pf_pdesc tooKristof Provost2024-10-101-55/+55
| | | | | | | | | | | As requested by henning, move the mbuf pointer into struct pf_pdesc. Also sort pd to the beginning of the functions' parameter lists for consistency. ok henning Obtained from: OpenBSD, bluhm <bluhm@openbsd.org>, 776f210a75 Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D46941
* pf: remove switch (af) default casesKristof Provost2024-10-101-2/+6
| | | | | | | | | | | | pf_setup_pdesc() panics if address family is neither AF_INET nor AF_INET6. So remove useless af switch defaults here and there. Always use "switch(af)" instead of "if (af) else" for af dependent code. Always use AF_ defines instead of PF_ when checking af values. ok claudio mpf henning Obtained from: OpenBSD, bluhm <bluhm@openbsd.org>, fb75e2fc14 Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D46940
* pf: put kif into struct pf_pdescKristof Provost2024-10-101-27/+25
| | | | | | | | | | | Put kif and dir into pdesc an use this instead of passing the values around. This is a mechanical change. Initialize pd2 and use it where appropriate. ok henning on an earlier version; ok mpf Obtained from: OpenBSD, bluhm <bluhm@openbsd.org>, 47de5c193e Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D46939
* pf: consolidate pf function parametersKristof Provost2024-10-101-20/+19
| | | | | | | | | | | | | | Move off and hdrlen into pdesc and change their type from int to u_int32_t. Do not pass struct tcphdr *th and sa_family_t af, it is in pd anyway. Do not use af and pd->af intermixed, the latter makes clear where it comes from. Do not calculate the packet length again if pd already has it. Use pd2.off instead of off2. go go go go don't stop henning@ mpf@ Obtained from: OpenBSD, bluhm <bluhm@openbsd.org>, 110e53770d Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D46937
* pf: remove the last hand-rolled IPv6 extension header loopKristof Provost2024-10-101-16/+2
| | | | | | | | | | | | | | | | | | Replace the IPv6 header walking loop in pf_test_state_icmp() with the common function pf_walk_header6(). For that, pf_walk_header6() can now extract both the information wether it is a fragment and the final protocol if it is the first fragment. This allows to match the icmp6 too big packet of a first fragment to the reassembled packet's state. This is neccesary if a refragmented fragment is to big for the Path-MTU. Note that pd.proto contains the real protocol number for the first fragment and IPPROTO_FRAGMENT for later fragments. pd.virtual_protocol is set to PF_VPROTO_FRAGMENT for all fragments. ok mcbride@ Obtained from: OpenBSD, bluhm <bluhm@openbsd.org>, 90b3c57e94 Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D46931
* pf: reduce IPv6 header parsing code duplicationKristof Provost2024-10-101-115/+30
| | | | | | | | | | | | | There were two loops in pf_setup_pdesc() and pf_normalize_ip6() walking over the IPv6 header chain. Merge them into one loop, adjust some length checks and fix IPv6 jumbo option handling. Also allow strange but legal IPv6 packets with plen=0 passing through pf. IPv6 jumbo packets still get dropped. testing dhill@; ok mcbride@ henning@ Obtained from: OpenBSD, bluhm <bluhm@openbsd.org>, d68283bbf0 Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D46925
* pf: replace union pf_krule_ptr with struct pf_krule in in-kernel structsKajetan Staszkiewicz2024-10-021-29/+29
| | | | | | | | | There is no need for the union pf_krule_ptr for kernel-only structs like pf_kstate and pf_ksrc_node. The rules are always accessed by pointer. The rule numbers are a leftover from using the same structure for pfctl(8) and pf(4). Reviewed by: kp Differential Revision: https://reviews.freebsd.org/D46868
* pf: remove ip(6) header argument from pf_reassemble(6)()Kristof Provost2024-09-271-6/+8
| | | | | | | | | | | Instead of passing the ip header and mbuf to pf_reassemble(), lookup the header address in the mbuf. ok henning@ Reviewed by: zlei Obtained from: OpenBSD, bluhm <bluhm@openbsd.org>, 074ee1f915 Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D46652
* pf: remove unused argument 'h' from various functionKristof Provost2024-09-251-2/+2
| | | | | | Reviewed by: zlei Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D46598
* pf: merge pf_scrub_ip() and pf_scrub_ip6()Kristof Provost2024-09-251-29/+31
| | | | | | | | | | | | Merge pf_scrub_ip() and pf_scrub_ip6() into a single function. Call pf_scrub with the right arugments in the rule case so that match rules will work as expected. OK henning@ Obtained from: OpenBSD, claudio <claudio@openbsd.org>, 48c45e6969 Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D46597
* pf: do not pass af to PFLOG_PACKETKristof Provost2024-09-191-5/+5
| | | | | | | | | | | | | Do not pass AF specific information to pf_test_rule() and PFLOG_PACKET() because either the info is already available in struct pd or easy to figure out. Makes pf_test() and pf_test6() even more similar (with the target to remove one of them in the near future). OK henning@ Reviewed by: zlei Obtained from: OpenBSD, claudio <claudio@openbsd.org>, 5480721ed1 Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D46596
* pf: remove unneeded double pointer to pf_scrub_ip(6)()Kristof Provost2024-09-191-4/+2
| | | | | | | | | | | pf_scrub_ip() does not modify the given mbuf pointer. So don't pass a pointer to a pointer to make the code in pf_test() clearer. ok henning@ Reviewed by: zlei Obtained from: OpenBSD, bluhm <bluhm@openbsd.org>, aac78b59b9 Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D46593
* pf: factor out pf_setup_pdesc()Kristof Provost2024-09-191-7/+2
| | | | | | | | | | | factor our the code to set up pf_pdesc, a central structure in pf carrying information about the packet we're currently dealing with, into its own function. ok ryan dlg and additional testing sthen Obtained from: OpenBSD, henning <henning@openbsd.org>, c4202972a3 Obtained from: OpenBSD, claudio <claudio@openbsd.org>, 78d25123ea Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D46586
* pf: work around icmp6 packet-too-big not being sent when binat-ingKristof Provost2024-01-221-0/+15
| | | | | | | | | | | | | | | | | | | | If we're applying NPTv6 we pass a packet with a modified source and/or destination address to the network stack. If that packet then turns out to be larger than the MTU of the sending interface the stack will attempt to generate an icmp6 packet-too-big error, but may fail to look up the appropriate source address for that error message. Even if it does, pf would still have to undo the binat operation inside the icmp6 packet so the sending host can make sense of the error. We can avoid both problems entirely by having pf also perform the MTU check (taking the potential refragmentation into account), and generating the icmp6 error directly in pf. See also: https://redmine.pfsense.org/issues/14290 Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D43499
* pf: store state creation/expiration timestamps with milisecond precisionKristof Provost2024-01-161-1/+1
| | | | | | | | The primary beneficiary is pflow(4), which expects milisecond precision in timestamps. Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D43112
* pflog: pass the action to pflog directlyKristof Provost2024-01-041-5/+5
| | | | | | | | | | | | If a packet is malformed, it is dropped by pf(4). The rule referenced in pflog(4) is the default rule. As the default rule is a pass rule, tcpdump printed "pass" although the packet was actually dropped. Use the actual action, rather than the rule's action, or an attempt at guessing the correct action. Inspired by OpenBSD's 'pflog(4) logs packet dropped by default rule with block.' commit. Sponsored by: Rubicon Communications, LLC ("Netgate")
* netpfil: Use accessor functions and named constants for all tcphdr flagsRichard Scheffenegger2023-12-251-5/+6
| | | | | | | | | | | | | Update all remaining references to the struct tcphdr th_x2 field. This completes the compatibilty of various aspects with AccECN (TH_AE), after the internal ipfw "re-checksum required" was moved to use the TH_RES1 flag. No functional change. Reviewed By: tuexen, #transport, glebius Sponsored by: NetApp, Inc. Differential Revision: https://reviews.freebsd.org/D43172
* pf: sctp heartbeats confirm a connectionKristof Provost2023-11-171-1/+9
| | | | | | | | | | | | | When we create a new state for multihomed sctp connections (i.e. based on INIT/INIT_ACK or ASCONF parameters) the new connection will never see a COOKIE/COOKIE_ACK exchange. We should consider HEARTBEAT_ACK to be a confirmation that the connection is established. This ensures that such connections do not time out earlier than expected. MFC after: 1 week Sponsored by: Orange Business Services
* pf: fix missing SCTP multihomed statesKristof Provost2023-10-311-0/+2
| | | | | | | | | | | | | | | | The existing code to create extra states when SCTP endpoints supplied extra addresses missed a case. As a result we failed to generate all of the required states. Briefly, if host A has address 1 and 2 and host B has addres 3 and 4 we generated 1 - 3 and 2 - 3, as well as 1 - 4, but not 2 - 4. Store the list of endpoints supplied by each host and use those to generate all of the connection permutations. MFC after: 1 week Sponsored by: Orange Business Services Differential Revision: https://reviews.freebsd.org/D42361
* pf: Fix packet reassemblyKajetan Staszkiewicz2023-10-261-20/+31
| | | | | | | | | | Don't drop fragmented packets when reassembly is disabled, they can be matched by rules with "fragment" keyword. Ensure that presence of scrub rules forces old behaviour. Reviewed by: kp Sponsored by: InnoGames GmbH Differential Revision: https://reviews.freebsd.org/D42355
* pf: improve SCTP state validationKristof Provost2023-09-071-0/+17
| | | | | | | | | | Only create new states for INIT chunks, or when we're creating a secondary state for a multihomed association. Store and verify verification tag. MFC after: 3 weeks Sponsored by: Orange Business Services
* pf: support SCTP multihomingKristof Provost2023-09-071-8/+26
| | | | | | | | | | | SCTP may announce additional IP addresses it'll use in the INIT/INIT_ACK chunks, or in ASCONF chunks at any time during the connection. Parse these parameters, evaluate the ruleset for the new connection and if allowed create the corresponding states. MFC after: 3 weeks Sponsored by: Orange Business Services Differential Revision: https://reviews.freebsd.org/D41637
* sys: Remove $FreeBSD$: one-line .c patternWarner Losh2023-08-161-2/+0
| | | | Remove /^[\s*]*__FBSDID\("\$FreeBSD\$"\);?\s*\n/
* pf: handle multiple IPv6 fragment headersKristof Provost2023-08-041-1/+5
| | | | | | | | | | | | | | | | | | | With 'scrub fragment reassemble' if a packet contains multiple IPv6 fragment headers we would reassemble the packet and immediately continue processing it. That is, we'd remove the first fragment header and expect the next header to be a final header (i.e. TCP, UDP, ICMPv6, ...). However, if it's another fragment header we'd not treat the packet correctly. That is, we'd fail to recognise the payload and treat it as if it were an IPv6 fragment rather than as its actual payload. Fix this by restarting the normalisation on the reassembled packet. If there are multiple fragment headers drop the packet. Reported by: Enrico Bassetti bassetti@di.uniroma1.it (NetSecurityLab @ Sapienza University of Rome) MFC after: instant Sponsored by: Rubicon Communications, LLC ("Netgate")