pflow: allow observation domain to be configured

Sponsored by:	Rubicon Communications, LLC ("Netgate")
Differential Revision:	https://reviews.freebsd.org/D43113
This commit is contained in:
Kristof Provost 2023-12-08 11:00:30 +01:00
parent 0493260115
commit 85b71dcfc9
5 changed files with 36 additions and 4 deletions

View file

@ -68,6 +68,8 @@ set the source IP address (and optionally port).
set the destination IP address (and optionally port).
.It Cm proto
set the protocol version.
.It Cm domain
set the observation domain.
Valid values are 5 and 10.
.El
.Pp

View file

@ -252,6 +252,7 @@ struct pflowctl_get {
int version;
struct pflowctl_sockaddr src;
struct pflowctl_sockaddr dst;
uint32_t obs_dom;
};
#define _IN(_field) offsetof(struct genlmsghdr, _field)
#define _OUT(_field) offsetof(struct pflowctl_get, _field)
@ -260,6 +261,7 @@ static struct snl_attr_parser ap_get[] = {
{ .type = PFLOWNL_GET_VERSION, .off = _OUT(version), .cb = snl_attr_get_int16 },
{ .type = PFLOWNL_GET_SRC, .off = _OUT(src), .arg = &sockaddr_parser, .cb = snl_attr_get_nested },
{ .type = PFLOWNL_GET_DST, .off = _OUT(dst), .arg = &sockaddr_parser, .cb = snl_attr_get_nested },
{ .type = PFLOWNL_GET_OBSERVATION_DOMAIN, .off = _OUT(obs_dom), .cb = snl_attr_get_uint32 },
};
static struct snl_field_parser fp_get[] = {};
#undef _IN
@ -338,7 +340,7 @@ get(int id)
if (! snl_parse_nlmsg(&ss, hdr, &get_parser, &g))
continue;
printf("pflow%d: version %d", g.id, g.version);
printf("pflow%d: version %d domain %d", g.id, g.version, g.obs_dom);
print_sockaddr(" src ", &g.src.storage);
print_sockaddr(" dst ", &g.dst.storage);
printf("\n");
@ -355,6 +357,7 @@ struct pflowctl_set {
uint16_t version;
struct sockaddr_storage src;
struct sockaddr_storage dst;
uint32_t obs_dom;
};
static inline bool
snl_add_msg_attr_sockaddr(struct snl_writer *nw, int attrtype, struct sockaddr_storage *s)
@ -408,6 +411,8 @@ do_set(struct pflowctl_set *s)
snl_add_msg_attr_sockaddr(&nw, PFLOWNL_SET_SRC, &s->src);
if (s->dst.ss_len != 0)
snl_add_msg_attr_sockaddr(&nw, PFLOWNL_SET_DST, &s->dst);
if (s->obs_dom != 0)
snl_add_msg_attr_u32(&nw, PFLOWNL_SET_OBSERVATION_DOMAIN, s->obs_dom);
hdr = snl_finalize_msg(&nw);
if (hdr == NULL)
@ -505,6 +510,14 @@ set(char *idstr, int argc, char *argv[])
s.version = strtol(argv[1], NULL, 10);
argc -= 2;
argv += 2;
} else if (strcmp(argv[0], "domain") == 0) {
if (argc < 2)
usage();
s.obs_dom = strtol(argv[1], NULL, 10);
argc -= 2;
argv += 2;
} else {

View file

@ -216,6 +216,7 @@ struct pflow_softc {
struct sockaddr *sc_flowdst;
struct pflow_ipfix_tmpl sc_tmpl_ipfix;
u_int8_t sc_version;
u_int32_t sc_observation_dom;
struct mbuf *sc_mbuf; /* current cumulative mbuf */
struct mbuf *sc_mbuf6; /* current cumulative mbuf */
CK_LIST_ENTRY(pflow_softc) sc_next;
@ -315,6 +316,7 @@ enum pflow_get_type_t {
PFLOWNL_GET_VERSION = 2, /* u16 */
PFLOWNL_GET_SRC = 3, /* struct sockaddr_storage */
PFLOWNL_GET_DST = 4, /* struct sockaddr_storage */
PFLOWNL_GET_OBSERVATION_DOMAIN = 5, /* u32 */
};
enum pflow_set_type_t {
@ -323,6 +325,7 @@ enum pflow_set_type_t {
PFLOWNL_SET_VERSION = 2, /* u16 */
PFLOWNL_SET_SRC = 3, /* struct sockaddr_storage */
PFLOWNL_SET_DST = 4, /* struct sockaddr_storage */
PFLOWNL_SET_OBSERVATION_DOMAIN = 5, /* u32 */
};
#ifdef _KERNEL

View file

@ -210,6 +210,7 @@ pflow_create(int unit)
pflowif = malloc(sizeof(*pflowif), M_DEVBUF, M_WAITOK|M_ZERO);
mtx_init(&pflowif->sc_lock, "pflowlk", NULL, MTX_DEF);
pflowif->sc_version = PFLOW_PROTO_DEFAULT;
pflowif->sc_observation_dom = PFLOW_ENGINE_TYPE;
/* ipfix template init */
bzero(&pflowif->sc_tmpl_ipfix,sizeof(pflowif->sc_tmpl_ipfix));
@ -421,7 +422,7 @@ pflowvalidsockaddr(const struct sockaddr *sa, int ignore_port)
}
}
static int
int
pflow_calc_mtu(struct pflow_softc *sc, int mtu, int hdrsz)
{
@ -1010,7 +1011,7 @@ pflow_sendout_ipfix(struct pflow_softc *sc, sa_family_t af)
h10->time_sec = htonl(time_second); /* XXX 2038 */
h10->flow_sequence = htonl(sc->sc_sequence);
sc->sc_sequence += count;
h10->observation_dom = htonl(PFLOW_ENGINE_TYPE);
h10->observation_dom = htonl(sc->sc_observation_dom);
if (mbufq_enqueue(&sc->sc_outputqueue, m) == 0)
swi_sched(sc->sc_swi_cookie, 0);
@ -1045,7 +1046,7 @@ pflow_sendout_ipfix_tmpl(struct pflow_softc *sc)
pflow_ipfix_tmpl));
h10->time_sec = htonl(time_second); /* XXX 2038 */
h10->flow_sequence = htonl(sc->sc_sequence);
h10->observation_dom = htonl(PFLOW_ENGINE_TYPE);
h10->observation_dom = htonl(sc->sc_observation_dom);
callout_reset(&sc->sc_tmo_tmpl, PFLOW_TMPL_TIMEOUT * hz,
pflow_timeout_tmpl, sc);
@ -1257,6 +1258,8 @@ pflow_nl_get(struct nlmsghdr *hdr, struct nl_pstate *npt)
nlattr_add_sockaddr(nw, PFLOWNL_GET_SRC, sc->sc_flowsrc);
if (sc->sc_flowdst)
nlattr_add_sockaddr(nw, PFLOWNL_GET_DST, sc->sc_flowdst);
nlattr_add_u32(nw, PFLOWNL_GET_OBSERVATION_DOMAIN,
sc->sc_observation_dom);
if (! nlmsg_end(nw)) {
nlmsg_abort(nw);
@ -1306,6 +1309,7 @@ struct pflow_parsed_set {
uint16_t version;
struct sockaddr_storage src;
struct sockaddr_storage dst;
uint32_t observation_dom;
};
#define _IN(_field) offsetof(struct genlmsghdr, _field)
#define _OUT(_field) offsetof(struct pflow_parsed_set, _field)
@ -1314,6 +1318,7 @@ static const struct nlattr_parser nla_p_set[] = {
{ .type = PFLOWNL_SET_VERSION, .off = _OUT(version), .cb = nlattr_get_uint16 },
{ .type = PFLOWNL_SET_SRC, .off = _OUT(src), .arg = &addr_parser, .cb = nlattr_get_nested },
{ .type = PFLOWNL_SET_DST, .off = _OUT(dst), .arg = &addr_parser, .cb = nlattr_get_nested },
{ .type = PFLOWNL_SET_OBSERVATION_DOMAIN, .off = _OUT(observation_dom), .cb = nlattr_get_uint32 },
};
static const struct nlfield_parser nlf_p_set[] = {};
#undef _IN
@ -1438,6 +1443,9 @@ pflow_set(struct pflow_softc *sc, const struct pflow_parsed_set *pflowr, struct
sc->so = NULL;
}
if (pflowr->observation_dom != 0)
sc->sc_observation_dom = pflowr->observation_dom;
/* error check is above */
if (pflowr->version != 0)
sc->sc_version = pflowr->version;

View file

@ -67,6 +67,12 @@ basic_body()
jexec alcatraz pflowctl -s ${pflow} proto 5
atf_check -s exit:0 \
jexec alcatraz pflowctl -s ${pflow} proto 10
# We can change the observation domain
atf_check -s exit:0 \
jexec alcatraz pflowctl -s ${pflow} domain 13
atf_check -s exit:0 -o match:".*domain 13.*" \
jexec alcatraz pflowctl -l
}
basic_cleanup()