Is this packet arriving or departing (in, out)?

The next required keyword that appears after
either the block (followed by optional
reset-icmp or reset-rst keywords) or the
pass keyword is the direction keyword. There are two
direction keywords you can use: in or out.
They are known to cause some confusion, especially when the firewall
is equipped with more than one network interface, and when NAT rules
are used along with filtering rules.

The key to understanding when a packet matches either the
in or the out rule is remembering that these
directions are relative to the firewall itself. Iif a packet is sent
from an external host to the firewall, it matches the in
rule on the firewall's external interface; when it is sent from the
firewall itself, it matches the out on the external
interface. Similarly, packets sent from internal hosts to the
firewall and destined to external host will match in
rules on the interface connecting your private network segment to the
firewall and out rules on the firewall's external
interface.

Do you want to log packets (log, log-all)?

To start packet logging, use the log or the
log-all keywords. The difference between them lies in
the way they work with rules that contain either keep
state or modulate state rules (more on these
later). log logs only the state-making packets, while
log-all logs all packets. If you use stateful filtering
and want to capture all packets that match the log rule,
use log-all, otherwise, use log.

If you want to log all traffic on all interfaces, add either the
log or log-all keywords to the rules that
cover most traffic. For example, to log all traffic entering and
leaving the firewall on the external interface, use these rules:

block in log on $ext_if
block out log on $ext_if

Similar rules should be added to sections describing packet
filtering policy for other interfaces on the firewall. If you would
rather log only incoming HTTP traffic, add the log
keyword to the rule that lets HTTP packets through.

Although I wrote
earlier that the firewall need not be the latest, fastest machine
you can get, the more traffic you log and the heavier the traffic that
passes through the firewall's interface, the faster the hardware you
use the better. This is especially true for the disks that must store
the data. As you will learn later in this article, when I discuss the
dup-to keyword, you can duplicate packets and send them
to a different interface, where a dedicated packet logging machine can
sit, listen, store, and analyze traffic. If you use
dup-to for logging, then log, and
log-all are redundant.

How can I influence the process of matching packets
(quick)?

Unlike NAT (nat, binat, rdr)
rules, which are processed in the "first matching rule wins" fashion,
packet filtering is done in the "last matching rule wins" way. While
it is possible to carefully structure your ruleset in a way that
avoids letting unwanted packets through, it is more convenient and
simpler to put rules that you want to process faster (like very
specific blocking rules) at the top of the packet filtering section of
the ruleset and add the quick keyword to such rules.
Whenever this keyword is used, pf(4)
will execute the matching rule and will not try to match the packet
against the rest of the ruleset. This saves some processing time,
which quickly adds up on a busy link, so I use this keyword
frequently.

The quick keyword is added after the log
or log-all keywords, or, in the absence of these
keywords, after the in or out direction
keywords:

pass in log-all quick on $ext_if proto tcp from any to $ext_ad port 80

Which network interface receives packets (on)?

While the packet filtering rules grammar allows us to write general
rules that apply to all interfaces, we can seldom write a good ruleset
without adding rules for specific interfaces. The name of the
interface is given after the on keyword that appears
after the quick keyword. The following examples show a
few possible variations of keywords that appear beforeon:

block in on $ext_if
block in log-all on $ext_if
block in log-all quick on $ext_if

Hint: If you forgot the name of the interface,
check the output of dmesg | less. If OpenBSD is not
recognizing your network interface, read this article for kernel
modification tips. Note that if you are using a device connected to
the serial interface (like a modem), such device may not be listed in
dmesg output, but should still be recognized by the
system. When you are not sure what name your network card falls under
in OpenBSD, check the list displayed by apropos
driver. Still no luck? Look at this list.