When fragmenting ipv4, we do not preserve DiffServ/ToS field.
Here is how to observe this :
[obsd1](vlan10) ---- (vlan10)[obsd2](vlan20) --mtu600-- (vlan20)[obsd3]
root@obsd2 # sysctl net.inet.ip.forwarding=1
root@obsd2 # tcpdump -ni $VLAN20DEV
user@obsd3 $ nc -4ul 6666
root@obsd1 $ echo "pass set prio 1" | pfctl -f -
user@obsd1 $ perl -e 'print "a"x800' | nc -4u $OBSD3VLAN20 6666
tcpdump: listening on vio0, link-type EN10MB
11:34.26.588937 802.1Q vid 10 pri 0 10.10.0.10.45095 > 10.20.0.20.6666: udp 800
11:34.26.589121 802.1Q vid 20 pri 0 10.10.0.10.45095 > 10.20.0.20.6666: udp 800
(frag 26935:576@0+)
11:34.26.589152 802.1Q vid 20 pri 3 10.10.0.10 > 10.20.0.20: (frag
26935:232@576)
Diff below ensures the fragmented packets have the same priority.
Ok ?
diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c
index d0b15f8..5921566 100644
--- a/sys/netinet/ip_output.c
+++ b/sys/netinet/ip_output.c
@@ -678,9 +678,10 @@ ip_fragment(struct mbuf *m, struct ifnet *ifp,
u_long mtu)
m->m_data += max_linkhdr;
mhip = mtod(m, struct ip *);
*mhip = *ip;
- /* we must inherit MCAST and BCAST flags and routing table */
+ /* we must inherit MCAST/BCAST flags, routing table and prio */
m->m_flags |= m0->m_flags & (M_MCAST|M_BCAST);
m->m_pkthdr.ph_rtableid = m0->m_pkthdr.ph_rtableid;
+ m->m_pkthdr.pf.prio = m0->m_pkthdr.pf.prio;
if (hlen > sizeof (struct ip)) {
mhlen = ip_optcopy(ip, mhip) + sizeof (struct ip);
mhip->ip_hl = mhlen >> 2;