Вот выдержка из man pf.conf(5)flags <a>/<b> | /<b>
This rule only applies to TCP packets that have the flags <a> set
out of set <b>. Flags not specified in <b> are ignored. The flags
are: (F)IN, (S)YN, (R)ST, (P)USH, (A)CK, (U)RG, (E)CE, and C(W)R.
flags S/S Flag SYN is set. The other flags are ignored.
flags S/SA Out of SYN and ACK, exactly SYN may be set. SYN,
SYN+PSH and SYN+RST match, but SYN+ACK, ACK and ACK+RST
do not. This is more restrictive than the previous
example.
flags /SFRA
If the first set is not specified, it defaults to none.
All of SYN, FIN, RST and ACK must be unset.
Из этого документа следует, что маска S/SA означает, то, что я и описал в "учебнике": Выставлен из влагов SYN и ACK выставлен только SYN. Маске соответствует пакет с флагом SYN, SYN+PSH и SYN+RST, но не соответсвует пакет c сочетаниями флагов SYN+ACK, ACK и ACK+RST.
Поэтому, если верить документации, прав я а не вы.
Причина разночтений, на мой взгляд, может заключаться в:
1) Некорректном эксперименте с hping. Например: пакету с флагами SYN+ACK предшествовал пакет SYN, и он прошёл благодаря опции keep state. Или пакет прошёл благодаря другим правилам фильтра.
2) Устаревшая версия пакетного фильтра. Пакетный фильтр бурно развивается, и возможно его поведение в этой области драматически изменилось со времени вашего эксперимента.
Я не проводил своего эксперимента на эту тему. У меня нет причин не доверять документации. Но если я проведу эксперимент и, паче чаяния, увижу, что правы вы, а не авторы OpenBSD, то это будет откровенный баг, о котором надо заявить им в список рассылки, прежде всего.