Bug 253872 - pf set-tos doesn't work for ipv6
Summary: pf set-tos doesn't work for ipv6
Status: New
Alias: None
Product: Base System
Classification: Unclassified
Component: kern (show other bugs)
Version: CURRENT
Hardware: Any Any
: --- Affects Only Me
Assignee: Tom Jones
Depends on:
Reported: 2021-02-26 15:07 UTC by jcaplan
Modified: 2022-01-19 10:39 UTC (History)
5 users (show)

See Also:

proposed patch (1.32 KB, patch)
2021-03-05 14:47 UTC, jcaplan
no flags Details | Diff
updated patch (988 bytes, patch)
2021-06-25 17:52 UTC, jcaplan
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description jcaplan 2021-02-26 15:07:02 UTC
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.
Comment 1 Tom Jones freebsd_committer 2021-02-26 15:10:35 UTC
I have a diff for this, I will dig it out and tag a review this weekend.
Comment 2 jcaplan 2021-03-05 14:47:44 UTC
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.
Comment 3 jcaplan 2021-06-25 17:52:38 UTC
Created attachment 226053 [details]
updated patch
Comment 4 Kristof Provost freebsd_committer 2022-01-19 10:39:34 UTC
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);