Hi, While writing my own patches to the OpenBSD kernel and the pf subsystem, I noticed that random-id packets scrub twice. I noticed this by copying random-id's code and modifying it a little. From that grew a little patch for scrub and random-id and I'd like OpenBSD to consider it. I sent a mail to misc@ before asking "why scrub twice?" and didn't find an answer. I did the work for myself and put it up for you in a small HTML file on my website. It is here:
http://centroid.eu/private/steg-patch.html The end result is here. I add 2 arguments to pf_scrub() for rule/state direction that is desired and direction that the packet is taking. Then in random-id the logic does not scrub when we had an "outbound scrub" and the packets direction is inbound. Happy Easter! May your pf get a little faster! -peter Index: sys/net/pf.c =================================================================== RCS file: /cvs/src/sys/net/pf.c,v retrieving revision 1.1063 diff -u -p -u -r1.1063 pf.c --- sys/net/pf.c 6 Mar 2018 17:35:53 -0000 1.1063 +++ sys/net/pf.c 29 Mar 2018 19:44:28 -0000 @@ -7018,7 +7018,7 @@ done: } pf_scrub(pd.m, s->state_flags, pd.af, s->min_ttl, - s->set_tos); + s->set_tos, s->direction, dir); pf_tag_packet(pd.m, s->tag, s->rtableid[pd.didx]); if (pqid || (pd.tos & IPTOS_LOWDELAY)) { qid = s->pqid; @@ -7031,7 +7031,7 @@ done: } } else { pf_scrub(pd.m, r->scrub_flags, pd.af, r->min_ttl, - r->set_tos); + r->set_tos, r->direction, dir); if (pqid || (pd.tos & IPTOS_LOWDELAY)) { qid = r->pqid; if (r->scrub_flags & PFSTATE_SETPRIO) Index: sys/net/pf_norm.c =================================================================== RCS file: /cvs/src/sys/net/pf_norm.c,v retrieving revision 1.209 diff -u -p -u -r1.209 pf_norm.c --- sys/net/pf_norm.c 6 Feb 2018 09:16:11 -0000 1.209 +++ sys/net/pf_norm.c 29 Mar 2018 19:44:28 -0000 @@ -1540,7 +1540,7 @@ pf_normalize_mss(struct pf_pdesc *pd, u_ void pf_scrub(struct mbuf *m, u_int16_t flags, sa_family_t af, u_int8_t min_ttl, - u_int8_t tos) + u_int8_t tos, u_int8_t ruledir, u_int8_t dir) { struct ip *h = mtod(m, struct ip *); #ifdef INET6 @@ -1574,6 +1574,7 @@ pf_scrub(struct mbuf *m, u_int16_t flags /* random-id, but not for fragments */ if (flags & PFSTATE_RANDOMID && af == AF_INET && - !(h->ip_off & ~htons(IP_DF))) + !(h->ip_off & ~htons(IP_DF)) && + (ruledir == PF_INOUT || ruledir == PF_FWD || ruledir == dir)) h->ip_id = htons(ip_randomid()); } Index: sys/net/pfvar.h =================================================================== RCS file: /cvs/src/sys/net/pfvar.h,v retrieving revision 1.476 diff -u -p -u -r1.476 pfvar.h --- sys/net/pfvar.h 9 Feb 2018 09:35:03 -0000 1.476 +++ sys/net/pfvar.h 29 Mar 2018 19:44:28 -0000 @@ -1764,7 +1764,7 @@ int pf_normalize_tcp_stateful(struct pf_ struct pf_state *, struct pf_state_peer *, struct pf_state_peer *, int *); int pf_normalize_mss(struct pf_pdesc *, u_int16_t); -void pf_scrub(struct mbuf *, u_int16_t, sa_family_t, u_int8_t, u_int8_t); +void pf_scrub(struct mbuf *, u_int16_t, sa_family_t, u_int8_t, u_int8_t, u_int8_t, u_int8_t); int32_t pf_state_expires(const struct pf_state *); void pf_purge_expired_fragments(void); int pf_routable(struct pf_addr *addr, sa_family_t af, struct pfi_kif *,