aboutsummaryrefslogtreecommitdiff
path: root/sys/netpfil/pf/pf.c
Commit message (Collapse)AuthorAgeFilesLines
* pf: fix reply-to after rdr and dummynetKristof Provost2024-03-281-0/+12
| | | | | | | | | | | | | | If we redirect a packet to localhost and it gets dummynet'd it may be re-injected later (e.g. when delayed) which means it will be passed through ip_input() again. ip_input() will then reject the packet because it's directed to the loopback address, but did not arrive on a loopback interface. Fix this by having pf set the rcvif to V_iflo if we redirect to loopback. See also: https://redmine.pfsense.org/issues/15363 Sponsored by: Rubicon Communications, LLC ("Netgate")
* pf: fix use-after-freeKristof Provost2024-03-251-0/+1
| | | | | | | | | | If we fragment the packet in pf_route() the first transmitted packet will free the pf_mtag we have stored in pf_pdesc (pd). Ensure we update that pointer for every packet to avoid using a freed pointer in pf_dummynet_route(). Reported by: CI KASAN, markj MFC after: 1 week
* pf: fix dummynet + route-toKristof Provost2024-03-191-5/+21
| | | | | | | | | | | | | Ensure that we pick the correct dummynet pipe (i.e. forward vs. reverse direction) when applying route-to. We mark the processing as outbound so that dummynet will re-inject in the correct phase of processing after it's done with the packet, but that will cause us to pick the wrong pipe number. Reverse them so that the incorrect decision ends up picking the correct pipe. Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D44366
* pf: avoid passing through dummynet multiple timesKristof Provost2024-03-191-0/+4
| | | | | | | | | | | | In some setups we end up with multiple states created for a single packet, which in turn can mean we run the packet through dummynet multiple times. That's not expected or intended. Mark each packet when it goes through dummynet, and do not pass packet through dummynet if they're marked as having already passed through. See also: https://redmine.pfsense.org/issues/14854 Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D44365
* pf: support if-bound with reply-toKristof Provost2024-03-011-1/+32
| | | | | | | | | On reply-to we don't know what interface to bind to when we create the state. Create any reply-to state as floating, but bind to the appropriate interface once we're handling the reply. See also: https://redmine.pfsense.org/issues/15220 Sponsored by: Rubicon Communications, LLC ("Netgate")
* pf: fix packet-to-big for route-to as wellKristof Provost2024-02-271-2/+2
| | | | | | | | | | | | | | | When we handle a packet via route-to (i.e. pf_route6()) we still need to verify the MTU. However, we only run that check in the forwarding case. Set the PFIL_FWD tag when running the pf_test6(PF_OUT) check from pf_route6(). We are in fact forwarding, so should call the test function as such. This will cause us to run the MTU check, and generate an ICMP6 packet-too-big error when required. See also: 54c62e3e5d8cd90c5571a1d4c8c5f062d580480e See also: f1c0030bb05cfa01bdd500e50befbb425fecc4c4 See also: https://redmine.pfsense.org/issues/14290 Sponsored by: Rubicon Communications, LLC ("Netgate")
* pf: add a probe point to BOUND_IFACEKristof Provost2024-02-061-0/+4
| | | | | | It's been useful at least once, so we may as well keep it. Sponsored by: Rubicon Communications, LLC ("Netgate")
* pf: Ensure that st->kif is obtained in a way which respects the ↵Kajetan Staszkiewicz2024-02-061-10/+7
| | | | | | | | | | | | | | | | | | r->rpool->mtx mutex The redirection pool stored in r->rpool.cur is used for loadbalancing and cur can change whenever loadbalancing happens, which is for every new connection. Therefore it can't be trusted outside of pf_map_addr() and the r->rpool->mtx mutex. After evaluating the ruleset, loadbalancing decission is made in pf_map_addr() called from within pf_create_state() and stored in the state itself. This patch modifies BOUND_IFACE() so that it only uses the information already stored in the state which has been obtained in a way which respects the r->rpool->mtx mutex. Reviewed by: kp Differential Revision: https://reviews.freebsd.org/D43741
* Revert "pf: Ensure that st->kif is obtained in a way which respects the ↵Kristof Provost2024-02-061-7/+10
| | | | | | | | | r->rpool->mtx mutex" This commit is correct, but was misattributed. Revert so we can re-apply with the correct author set. This reverts commit 6d4a140acfdf637bb559d371c583e4db478e1549.
* pf: Ensure that st->kif is obtained in a way which respects the ↵Igor Ostapenko2024-02-051-10/+7
| | | | | | | | | | | | | | | | | | r->rpool->mtx mutex The redirection pool stored in r->rpool.cur is used for loadbalancing and cur can change whenever loadbalancing happens, which is for every new connection. Therefore it can't be trusted outside of pf_map_addr() and the r->rpool->mtx mutex. After evaluating the ruleset, loadbalancing decission is made in pf_map_addr() called from within pf_create_state() and stored in the state itself. This patch modifies BOUND_IFACE() so that it only uses the information already stored in the state which has been obtained in a way which respects the r->rpool->mtx mutex. Reviewed by: kp Differential Revision: https://reviews.freebsd.org/D43741
* sys/netpfil/pf/pf.c: remove an extra semicolonrilysh2024-02-031-1/+1
| | | | | | Signed-off-by: rilysh <nightquick@proton.me> Reviewed by: imp Pull Request: https://github.com/freebsd/freebsd-src/pull/959
* sys/netpfil/pf/pf.c: remove an extra semicolonrilysh2024-02-031-1/+1
| | | | | | Signed-off-by: rilysh <nightquick@proton.me> Reviewed by: imp Pull Request: https://github.com/freebsd/freebsd-src/pull/959
* pf: ensure dummynet gets the correct direction after route-toKristof Provost2024-02-021-0/+6
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | If we apply a route-to to an inbound packet pf_route() may hand that packet over to dummynet. Dummynet may then delay the packet, and later re-inject it. This re-injection (in dummynet_send()) needs to know if the packet was inbound or outbound, to call the correct path for continued processing. That's done based on the pf_pdesc we pass along (through pf_dummynet_route() and pf_pdesc_to_dnflow()). In the case of pf_route() on inbound packets that may be wrong, because we're called in the input path, and didn't update pf_pdesc->dir. This can manifest in issues with fragmented packets. For example, a fragmented packet will be re-fragmented in pf_route(), and if dummynet makes different decisions for some of the fragments (that is, it delays some and allows others to pass through directly) this will break. The packets that pass through dummynet without delay will be transmitted correctly (through the ifp->if_output() call in pf_route()), but the delayed packets will be re-injected in the input path (and not the output path, as they should be). These packets will pass through pf_test(PF_IN) as they're tagged PF_MTAG_FLAG_DUMMYNET. However, this tag is then removed and the packet will be routed and enter pf_test(PF_OUT) where pf_reassemble() will hold them indefinitely (as some fragments have been transmitted directly, and will never hit pf_test(PF_OUT)). The fix is simple: we must update pf_pfdesc->dir to PF_OUT before we pass the packet to dummynet. See also: https://redmine.pfsense.org/issues/15156 Reviewed by: rcm Sponsored by: Rubicon Communications, LLC ("Netgate")
* pf: bind route-to states to their route-to interfaceKristof Provost2024-01-291-4/+23
| | | | | | | | | | | | | | | | When we route-to the state should be bound to the route-to interface, not the default route interface. However, we should only do so for outbound traffic, because inbound traffic should bind on the arriving interface, not the one we eventually transmit on. Explicitly check for this in BOUND_IFACE(). We must also extend pf_find_state(), because subsequent packets within the established state will attempt to match the original interface, not the route-to interface. Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D43589
* pf: only check MTU for IPv6 packets when forwardingKristof Provost2024-01-241-1/+1
| | | | | | | | | | | When the packets are generated locally (i.e. PFIL_FWD is not set) we might generate overly large packets and rely on the NIC to fragment it for us. In that case we'd reject a valid packet. Reported by: Herbert J. Skuhra <herbert@gojira.at> Tested by: Herbert J. Skuhra <herbert@gojira.at> Fixes: 54c62e3e5d8cd90c5571a1d4c8c5f062d580480e Sponsored by: Rubicon Communications, LLC ("Netgate")
* pf: work around icmp6 packet-too-big not being sent when binat-ingKristof Provost2024-01-221-0/+12
| | | | | | | | | | | | | | | | | | | | 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
* pflow: add RFC8158 NAT supportKristof Provost2024-01-161-1/+2
| | | | | | | | | Extend pflow(4) to send NAT44 Session Create and Delete events. This applies only to IPFIX (i.e. proto version 10), and requires no user configuration. Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D43114
* pf: store state creation/expiration timestamps with milisecond precisionKristof Provost2024-01-161-10/+9
| | | | | | | | 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
* pf: allow pflow to be activated per ruleKristof Provost2024-01-161-0/+5
| | | | | | | | | | Only generate ipfix/netflow reports (through pflow) for the rules where this is enabled. Reports can also be enabled globally through 'set state-default pflow'. Obtained from: OpenBSD Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D43108
* pflow: import from OpenBSDKristof Provost2024-01-161-0/+24
| | | | | | | | | | | | | pflow is a pseudo device to export flow accounting data over UDP. It's compatible with netflow version 5 and IPFIX (10). The data is extracted from the pf state table. States are exported once they are removed. Reviewed by: melifaro Obtained from: OpenBSD Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D43106
* pflog: pass the action to pflog directlyKristof Provost2024-01-041-11/+11
| | | | | | | | | | | | 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")
* pf: don't clobber log flagKristof Provost2024-01-041-0/+4
| | | | | | | | | | If we decide to discard a packet due to unexpected IP options or unsupported headers we set pd.act.log. However, this can later get overwritten when we copy the state's saved actions over. Merge the two log fields to ensure we log as expected. Sponsored by: Rubicon Communications, LLC ("Netgate")
* pf: remove incorrect fragmentation checkKristof Provost2023-12-051-2/+1
| | | | | | | | | | We do not need to check PFDESC_IP_REAS while tracking TCP state. Moreover, this check incorrectly considers no-data packets (e.g. RST) to be in-window when this flag is not set. Sponsored by: Rubicon Communications, LLC ("Netgate") Approved by: so Security: FreeBSD-SA-23:17.pf
* pf: sctp heartbeats confirm a connectionKristof Provost2023-11-171-1/+1
| | | | | | | | | | | | | 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: skip urpf check for sctp multihomed statesKristof Provost2023-11-171-0/+3
| | | | | | | | | | | When we create a new state for multihomed sctp connections (i.e. based on INIT/INIT_ACK or ASCONF parameters) we cannot know what interfaces we'll be seeing that traffic on. These states are floating states, i.e. on "all" interfaces. We cannot do reverse path filtering for these states, so do not do so. MFC after: 1 week Sponsored by: Orange Business Services
* pf: always create multihomed states as floatingKristof Provost2023-11-171-2/+6
| | | | | | | | | | When we create a new state for multihomed sctp connections (i.e. based on INIT/INIT_ACK or ASCONF parameters) we cannot know what interfaces we'll be seeing that traffic on. Make those states floating, irrespective of state policy. MFC after: 1 week Sponsored by: Orange Business Services
* pf: fix dummynet + ipdivert use caseIgor Ostapenko2023-11-171-5/+22
| | | | | | | | | | | | | | | | | | | Dummynet re-injects an mbuf with MTAG_IPFW_RULE added, and the same mtag is used by divert(4) as parameters for packet diversion. If according to pf rule set a packet should go through dummynet first and through ipdivert after then mentioned mtag must be removed after dummynet not to make ipdivert think that this is its input parameters. At the very beginning ipfw consumes this mtag what means the same behavior with tag clearing after dummynet. And after fabf705f4b5a pf passes parameters to ipdivert using its personal MTAG_PF_DIVERT mtag. PR: 274850 Reviewed by: kp Differential Revision: https://reviews.freebsd.org/D42609
* pf_purge_expired_states(): fix build without SDT probesKonstantin Belousov2023-11-091-1/+1
| | | | Sponsored by: The FreeBSD Foundation
* pf: add hashtable row count SDTKristof Provost2023-11-091-0/+6
| | | | | | | | | | | | | | | | | | | | | This allows us to figure out how many states each hashrow contains. That can be important to know when debugging performance issues. A simple probe could be: dtrace -n 'pf:purge:state:rowcount { @counts["states per row"] = quantize(arg1); }' dtrace: description 'pf:purge:state:rowcount ' matched 1 probe ^C states per row value ------------- Distribution ------------- count -1 | 0 0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 8257624 1 | 14321 2 | 0 MFC after: 1 week Sponsored by: Modirum MDPay
* pf: support SCTP-specific timeoutsKristof Provost2023-10-311-5/+9
| | | | | | | | | | Allow SCTP state timeouts to be configured independently from TCP state timeouts. Reviewed by: tuexen MFC after: 1 week Sponsored by: Orange Business Services Differential Revision: https://reviews.freebsd.org/D42393
* pf: fix missing SCTP multihomed statesKristof Provost2023-10-311-15/+238
| | | | | | | | | | | | | | | | 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: use an enum for packet direction in divert tagKristof Provost2023-10-201-1/+1
| | | | | | | | | | | The benefit is that in the debugger you will see PF_DIVERT_MTAG_DIR_IN instead of 1 when looking at a structure. And compilation time failure if anybody sets it to a wrong value. Using "port" instead of "ndir" when assigning a port improves readability of code. Suggested by: glebius MFC after: 3 weeks X-MFC-With: fabf705f4b
* pf: fix pf divert-to loopIgor Ostapenko2023-10-191-11/+21
| | | | | | | | | | | | | | | | Resolved conflict between ipfw and pf if both are used and pf wants to do divert(4) by having separate mtags for pf and ipfw. Also fix the incorrect 'rulenum' check, which caused the reported loop. While here add a few test cases to ensure that divert-to works as expected, even if ipfw is loaded. divert(4) PR: 272770 MFC after: 3 weeks Reviewed by: kp Differential Revision: https://reviews.freebsd.org/D42142
* pf: Free pf_rule_items when state is not createdKajetan Staszkiewicz2023-10-121-0/+11
| | | | | | | | | | | This addresses the issues of pf_rule_times leaking in case of stateless rules and in case of state creation failures, like hitting the state limit. Reviewed by: kp MFC after: 1 week Sponsored by: InnoGames GmbH Differential Revision: https://reviews.freebsd.org/D42169
* pf: fix SCTP SDT probeKristof Provost2023-10-051-1/+1
| | | | | | | | | We want the return value of pf_test_rule(), i.e. the result of the evaluation of the new state, not the result of the evaluation of the original packet/state. MFC after: 1 week Sponsored by: Orange Business Services
* pf: cope with missing rpool.curKristof Provost2023-10-041-4/+5
| | | | | | | | | | | | | | If we're evaluating a pfsync'd state (and have different rules on both ends) our state may point to the default rule, which does not have rpool.cur set. As a result we can end up dereferencing a NULL pointer. Explicitly check for this when we try to re-construct the route-to interface. Also add a test case which can trigger this issue. MFC after: 3 days See also: https://redmine.pfsense.org/issues/14804 Sponsored by: Rubicon Communications, LLC ("Netgate")
* pf: only create sctp multihome states if we pass the packetKristof Provost2023-09-291-6/+10
| | | | | | | | If we've decided to drop the packet we shouldn't create additional states based off it. MFC after: 3 days Sponsored by: Orange Business Services
* pf: ensure 'off' is always set before useKristof Provost2023-09-291-1/+7
| | | | | | | | | If we bail out early from pf_test(6)() we still need to clean up/finish SCTP multihome work, which requires the 'off' value to be set. Set it early enough. MFC after: 3 days Sponsored by: Orange Business Services
* pf: fix state leakKristof Provost2023-09-101-17/+9
| | | | | | | | | | If we hit the csfailed case in pf_create_state() we may have allocated a state, so we must also free it. While here reduce the amount of duplicated cleanup code. MFC after: 2 weeks Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D41772
* netpfil/pf/pf.c: fix build without dtraceKonstantin Belousov2023-09-091-1/+1
| | | | Sponsored by: The FreeBSD Foundation
* pf: mark removed connections within a multihome association as shutting downKristof Provost2023-09-071-15/+72
| | | | | | | | | | Parse IP removal in ASCONF chunks, find the affected state(s) and mark them as shutting down. This will cause them to time out according to PFTM_TCP_CLOSING timeouts, rather than waiting for the established session timeout. MFC after: 3 weeks Sponsored by: Orange Business Services
* pf: inherit v_tag values to multihomed connectionsKristof Provost2023-09-071-1/+5
| | | | | | | | When we create a new state for an existing SCTP association inherit the v_tag values from the original connection. MFC after: 3 weeks Sponsored by: Orange Business Services
* pf: improve SCTP state validationKristof Provost2023-09-071-10/+22
| | | | | | | | | | 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-2/+184
| | | | | | | | | | | 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
* pf: Access r->rpool.cur->kif under mutex protectionKajetan Staszkiewicz2023-08-241-14/+17
| | | | | | | | | | | | | | | | | pf_route() sends traffic to a specified next hop over a specific interface. The next hop is obtained in pf_map_addr() but the interface is obtained directly via r->rpool.cur->kif` outside of the lock held in pf_map_addr() in multiple places around pf. The chosen interface is not stored in source node. Move the interface selection into pf_map_addr(), have the function return it together with the chosen IP address and ensure its stored in struct pf_ksrc_node, store it in the source node and use the stored value when needed. Sponsored by: InnoGames GmbH MFC after: 2 weeks Differential Revision: https://reviews.freebsd.org/D41570
* pf: enable the syncookie feature for IPv6Kajetan Staszkiewicz2023-08-211-3/+48
| | | | | | | | | | When syncookie support was added to pf the relevant work was only done in pf_test(), not pf_test6(). Do this now. MFC after: 1 week Reviewed by: kp Sponsored by: InnoGames GmbH Differential Revision: https://reviews.freebsd.org/D41502
* pf: reduce indentationKajetan Staszkiewicz2023-08-211-25/+19
| | | | | | | | | | | Early-return to reduce syncookie-related indentation. No functional change. MFC after: 1 week Reviewed by: kp Sponsored by: InnoGames GmbH Differential Revision: https://reviews.freebsd.org/D41502
* sys: Remove $FreeBSD$: one-line .c patternWarner Losh2023-08-161-2/+0
| | | | Remove /^[\s*]*__FBSDID\("\$FreeBSD\$"\);?\s*\n/
* pf: add SCTP NAT supportKristof Provost2023-07-211-0/+56
| | | | | | | | | | | | | | | | | | | Support NAT-ing SCTP connections. This is mostly similar to UDP and TCP, but we refuse to change ports for SCTP, to avoid interfering with multihomed connections. As a result we also never copy the SCTP header back or recalculate checksums as we'd do for TCP or UDP (because we don't modify the header for SCTP). We do use the existing pf_change_ap() function to modify the packet, because we may still need to update the IPv4 header checksum. Reviewed by: tuexen MFC after: 3 weeks Sponsored by: Orange Business Services Differential Revision: https://reviews.freebsd.org/D40866
* pf: support 'return' for SCTPKristof Provost2023-07-211-0/+117
| | | | | | | | | Send an SCTP Abort message if we're refusing a connection, just like we send a RST for TCP. MFC after: 3 weeks Sponsored by: Orange Business Services Differential Revision: https://reviews.freebsd.org/D40864