Overview ------- While pfctl lets you set-tos for ipv6, it doesn't appear to be implemented on kernel side. Steps to Reproduce ----------- 1. pf.conf: scrub in on em0 inet6 proto {tcp, udp, 58} all set-tos lowdelay fragment reassemble pass log (all) all 2. ping6 the target with traffic class specified: ping6 -n -Q 0x20 -c2 fe80::a00:27ff:feb8:57c0%wlp2s0 Expected result --------------- tcpdump: listening on pflog0, link-type PFLOG (OpenBSD pflog file), capture size 262144 bytes 09:14:53.083938 rule 0/0(match): pass in on em0: (class 0x10... Actual Result ------------- # tcpdump -vvv -ee -i pflog0 -l -n tcpdump: listening on pflog0, link-type PFLOG (OpenBSD pflog file), capture size 262144 bytes 09:14:53.083938 rule 0/0(match): pass in on em0: (class 0x20... Build Date & Hardware --------------------- FreeBSD bsd-vbox 13.0-CURRENT FreeBSD 13.0-CURRENT #0 r368820: Tue Jan 5 17:30:19 EST 2021 jcaplan@bsd-vbox:/usr/obj/usr/src-head/amd64.amd64/sys/GENERIC amd64 Additional Information ---------------------- pf_scrub_ip6, unlike pf_scrub_ip doesn't check the PFRULE_SET_TOS flag and doesn't update the traffic class in the ip6_hdr.
I have a diff for this, I will dig it out and tag a review this weekend.
Created attachment 223003 [details] proposed patch Here is a patch that worked for me. I found I needed to scrub on the fragments as well for the expected result.
Created attachment 226053 [details] updated patch
That patch looks a lot like its missing something. It changes the prototype for pf_scrub_ip6() but not the implementation. It's also slightly stale, because pf_scrub_ip6() has been extended to implement set-tos (and we explicitly test this already). However, it does appear to be the case that we should also scrub reassembled IPv6 packets. I'd expect your example to already work on main (but not stable/13). It will likely not work on fragmented (but reassembled) packets. The following patch should help, but I want to build a test case for it before I commit: diff --git a/sys/netpfil/pf/pf_norm.c b/sys/netpfil/pf/pf_norm.c index 5827fb0b093b..31dcbe9c83a0 100644 --- a/sys/netpfil/pf/pf_norm.c +++ b/sys/netpfil/pf/pf_norm.c @@ -1302,6 +1302,8 @@ pf_normalize_ip6(struct mbuf **m0, int dir, struct pfi_kkif *kif, if (m == NULL) return (PF_DROP); + pf_scrub_ip6(&m, r->rule_flag, r->min_ttl, r->set_tos); + pd->flags |= PFDESC_IP_REAS; return (PF_PASS);