Index | Thread | Search

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

Download raw body.

Thread
  • Sven F.:

    Pflow and Rdomain

    • Sven F.:

      Pflow and Rdomain

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,
>
> When I run:
>
> sh /etc/netstart pflow2
>
> I receive the following errors:
>
> ifconfig: pflow2: SIOCSETPFLOW: Can't assign requested address
> ifconfig: pflow2: SIOCSETPFLOW: Can't assign requested address
>
> The lo2 interface in rdomain 2 is configured as:
>
> lo2: flags=2008049<UP,LOOPBACK,RUNNING,MULTICAST,LRO> rdomain 2 mtu
> 32768
>      [...]
>      inet 2.3.0.6 netmask 0xffffffff
>
> And my /etc/hostname.pflow2 contains:
>
> rdomain 2
> flowsrc 2.3.0.6 flowdst 2.3.0.6:12345
> pflowproto 10
>
> My question is whether this behavior is expected. ( i guess so )  In
> this setup, the flow destination is in rdomain 0, and I'm trying to mark
> flows based on their originating rdomain.
>
> More seriously, I was also wondering whether using the engine_id field
> might be a
> suitable way to store or represent the rdomain value, which is probably
> a better way but would require a kernel update, something like :
>
> ```diff
> 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        10 Mar 2026 13:22:22 -0000
> @@ -111,7 +111,7 @@ int export_pflow_if(struct pf_state*, st
>          struct pflow_softc *);
>   int    copy_flow_to_m(struct pflow_flow *flow, struct pflow_softc *sc);
>   int    copy_flow_ipfix_4_to_m(struct pflow_ipfix_flow4 *flow,
> -       struct pflow_softc *sc);
> +       struct pflow_softc *sc, uint16_t rdomain);
>   int    copy_flow_ipfix_6_to_m(struct pflow_ipfix_flow6 *flow,
>          struct pflow_softc *sc);
>
> @@ -930,7 +930,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, uint16_t rdomain)
>   {
>          int             ret = 0;
>
> @@ -944,6 +945,7 @@ copy_flow_ipfix_4_to_m(struct pflow_ipfi
>                  sc->sc_count4 = 0;
>                  timeout_add_sec(&sc->sc_tmo, PFLOW_TIMEOUT);
>          }
> +       sc->engine_id = rdomain;
>          m_copyback(sc->sc_mbuf, PFLOW_SET_HDRLEN +
>              (sc->sc_count4 * sizeof(struct pflow_ipfix_flow4)),
>              sizeof(struct pflow_ipfix_flow4), flow, M_NOWAIT);
> @@ -1030,10 +1032,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));
> ```
>
>
> It's incomplete and not completely suitable. ( Tabs / spaces. Even
> my terminal does not copy tabs now, ignoring ipv6 ...  ), but
> certainly illustrate the feature better !
>
> I'd appreciate any clarification on whether the errors above are
> expected and whether the idea of using engine_id for rdomain tagging
> makes sense, and could be included in future release
>
>
> Happy Spring and thank you for reading that far.
>

NB:

Meanwhile i'm downgrading to netflow5 and will test this :


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 10 Mar 2026 15:10:07 -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 = htons(rdomain); m_copyback(m, 0, PFLOW_HDRLEN, &h, M_NOWAIT);
sc->sc_count = 0; @@ -905,14 +905,15 @@ 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); } m_copyback(sc->sc_mbuf, PFLOW_HDRLEN + @@ -930,7 +931,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 +940,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 +969,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; @@ -1003,10 +1006,10 @@ pflow_pack_flow(struct pf_state *st, str
copy_flow_data(&flow1, &flow2, st, sk, 0, 1); 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
+1033,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 +1228,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),