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;

Reply via email to