Index | Thread | Search

From:
"Sven F." <sven.falempin@gmail.com>
Subject:
Re: Pflow and Rdomain
To:
tech@openbsd.org
Date:
Wed, 11 Mar 2026 11:25:08 -0400

Download raw body.

Thread
On Tue, Mar 10, 2026 at 11:13 AM Sven F. <sven.falempin@gmail.com> wrote:
>
>
>
> On Tue, Mar 10, 2026 at 9:49 AM Sven F. <sven.falempin@gmail.com> 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),