From: "Sven F." Subject: Re: Pflow and Rdomain To: tech@openbsd.org Date: Wed, 11 Mar 2026 11:25:08 -0400 On Tue, Mar 10, 2026 at 11:13 AM Sven F. wrote: > > > > On Tue, Mar 10, 2026 at 9:49 AM Sven F. wrote: >> >> Hello OpenBSD team, >> >> I was poking around pflow and rdomains , and i was trying to >> "misuse" flowsrc, interesting part after, So i got flowd to log the rdomain , in network order because engine is 8 bit here and 16 bit on the other side ( v5 ) 2 solutions: keep a flow mbuf / domain ( more mem less network ) or flush ( smaller diff , no mem usage ) reader in csv (2816 is 11) : 1773241924,528780838,218000,10.0.0.1,21,1764,186000,206000,10752,2816,10.0.0.11,10.0.0.1,0.0.0.0,5,5,54321,8,1,0,0,0,0,0,0 1773241924,528780838,218000,10.0.0.1,21,1764,186000,206000,10752,2816,10.0.0.1,10.0.0.11,0.0.0.0,5,5,8,54321,1,0,0,0,0,0,0 patch (probably mangled): Index: ./sys/net/if_pflow.c =================================================================== RCS file: /cvs/src/sys/net/if_pflow.c,v diff -u -p -r1.111 if_pflow.c --- ./sys/net/if_pflow.c 7 Jul 2025 02:28:50 -0000 1.111 +++ ./sys/net/if_pflow.c 11 Mar 2026 15:22:37 -0000 @@ -86,7 +86,7 @@ void pflow_setmtu(struct pflow_softc *, int pflowvalidsockaddr(const struct sockaddr *, int); int pflowioctl(struct ifnet *, u_long, caddr_t); -struct mbuf *pflow_get_mbuf(struct pflow_softc *, u_int16_t); +struct mbuf *pflow_get_mbuf(struct pflow_softc *, u_int16_t, u_int16_t); void pflow_flush(struct pflow_softc *); int pflow_sendout_v5(struct pflow_softc *); int pflow_sendout_ipfix(struct pflow_softc *, sa_family_t); @@ -109,9 +109,9 @@ int pflow_pack_flow_ipfix(struct pf_stat struct pflow_softc *); int export_pflow_if(struct pf_state*, struct pf_state_key *, struct pflow_softc *); -int copy_flow_to_m(struct pflow_flow *flow, struct pflow_softc *sc); +int copy_flow_to_m(struct pflow_flow *flow, struct pflow_softc *sc, u_int16_t); int copy_flow_ipfix_4_to_m(struct pflow_ipfix_flow4 *flow, - struct pflow_softc *sc); + struct pflow_softc *sc, u_int16_t rdomain); int copy_flow_ipfix_6_to_m(struct pflow_ipfix_flow6 *flow, struct pflow_softc *sc); @@ -657,7 +657,7 @@ pflow_setmtu(struct pflow_softc *sc, int } struct mbuf * -pflow_get_mbuf(struct pflow_softc *sc, u_int16_t set_id) +pflow_get_mbuf(struct pflow_softc *sc, u_int16_t set_id, u_int16_t rdomain) { struct pflow_set_header set_hdr; struct pflow_header h; @@ -693,7 +693,7 @@ pflow_get_mbuf(struct pflow_softc *sc, u h.version = htons(PFLOW_PROTO_5); h.flow_sequence = htonl(sc->sc_gcounter); h.engine_type = PFLOW_ENGINE_TYPE; - h.engine_id = PFLOW_ENGINE_ID; + h.engine_id = (uint8_t)(rdomain & 0xff); m_copyback(m, 0, PFLOW_HDRLEN, &h, M_NOWAIT); sc->sc_count = 0; @@ -905,16 +905,24 @@ export_pflow_if(struct pf_state *st, str } int -copy_flow_to_m(struct pflow_flow *flow, struct pflow_softc *sc) +copy_flow_to_m(struct pflow_flow *flow, struct pflow_softc *sc, + u_int16_t rdomain) { int ret = 0; MUTEX_ASSERT_LOCKED(&sc->sc_mtx); if (sc->sc_mbuf == NULL) { - if ((sc->sc_mbuf = pflow_get_mbuf(sc, 0)) == NULL) + if ((sc->sc_mbuf = pflow_get_mbuf(sc, 0, rdomain)) == NULL) return (ENOBUFS); - } + } else { + struct pflow_header *h = mtod(sc->sc_mbuf, struct pflow_header *); + if ( h->engine_id != (uint8_t)(rdomain & 0xff) ) { + ret = pflow_sendout_v5(sc); + if ((sc->sc_mbuf = pflow_get_mbuf(sc, 0, rdomain)) == NULL) + return (ENOBUFS); + } + } m_copyback(sc->sc_mbuf, PFLOW_HDRLEN + (sc->sc_count * sizeof(struct pflow_flow)), sizeof(struct pflow_flow), flow, M_NOWAIT); @@ -930,7 +938,8 @@ copy_flow_to_m(struct pflow_flow *flow, } int -copy_flow_ipfix_4_to_m(struct pflow_ipfix_flow4 *flow, struct pflow_softc *sc) +copy_flow_ipfix_4_to_m(struct pflow_ipfix_flow4 *flow, + struct pflow_softc *sc, u_int16_t rdomain) { int ret = 0; @@ -938,12 +947,13 @@ copy_flow_ipfix_4_to_m(struct pflow_ipfi if (sc->sc_mbuf == NULL) { if ((sc->sc_mbuf = - pflow_get_mbuf(sc, PFLOW_IPFIX_TMPL_IPV4_ID)) == NULL) { + pflow_get_mbuf(sc, PFLOW_IPFIX_TMPL_IPV4_ID, rdomain)) == NULL) { return (ENOBUFS); } sc->sc_count4 = 0; timeout_add_sec(&sc->sc_tmo, PFLOW_TIMEOUT); } + // sc->engine_id = rdomain; // cant do that and v10 is crewed m_copyback(sc->sc_mbuf, PFLOW_SET_HDRLEN + (sc->sc_count4 * sizeof(struct pflow_ipfix_flow4)), sizeof(struct pflow_ipfix_flow4), flow, M_NOWAIT); @@ -966,7 +976,7 @@ copy_flow_ipfix_6_to_m(struct pflow_ipfi if (sc->sc_mbuf6 == NULL) { if ((sc->sc_mbuf6 = - pflow_get_mbuf(sc, PFLOW_IPFIX_TMPL_IPV6_ID)) == NULL) { + pflow_get_mbuf(sc, PFLOW_IPFIX_TMPL_IPV6_ID, 0)) == NULL) { return (ENOBUFS); } sc->sc_count6 = 0; @@ -1001,12 +1011,17 @@ pflow_pack_flow(struct pf_state *st, str copy_flow_data(&flow1, &flow2, st, sk, 1, 0); else copy_flow_data(&flow1, &flow2, st, sk, 0, 1); +/* + u_int16_t x = st->rtableid[0]; // st->sc_domain; + u_int16_t y = st->rtableid[1]; // st->sc_domain; + printf("PFLOW DEB table %d : %d sk rdomain %d\n", x, y, sk->rdomain); +*/ if (st->bytes[0] != 0) /* first flow from state */ - ret = copy_flow_to_m(&flow1, sc); + ret = copy_flow_to_m(&flow1, sc, sk->rdomain); if (st->bytes[1] != 0) /* second flow from state */ - ret = copy_flow_to_m(&flow2, sc); + ret = copy_flow_to_m(&flow2, sc, sk->rdomain); return (ret); } @@ -1030,10 +1045,10 @@ pflow_pack_flow_ipfix(struct pf_state *s 0, 1); if (st->bytes[0] != 0) /* first flow from state */ - ret = copy_flow_ipfix_4_to_m(&flow4_1, sc); + ret = copy_flow_ipfix_4_to_m(&flow4_1, sc, sk->rdomain); if (st->bytes[1] != 0) /* second flow from state */ - ret = copy_flow_ipfix_4_to_m(&flow4_2, sc); + ret = copy_flow_ipfix_4_to_m(&flow4_2, sc, sk->rdomain); } else if (sk->af == AF_INET6) { bzero(&flow6_1, sizeof(flow6_1)); bzero(&flow6_2, sizeof(flow6_2)); @@ -1225,7 +1240,7 @@ pflow_sendout_ipfix_tmpl(struct pflow_so if (!(ifp->if_flags & IFF_RUNNING)) { return (0); } - m = pflow_get_mbuf(sc, 0); + m = pflow_get_mbuf(sc, 0, 0); if (m == NULL) return (0); if (m_copyback(m, 0, sizeof(struct pflow_ipfix_tmpl),