xref: /freebsd/sys/netpfil/pf/pflow.c (revision 221d459f)
1 /*	$OpenBSD: if_pflow.c,v 1.100 2023/11/09 08:53:20 mvs Exp $	*/
2 
3 /*
4  * Copyright (c) 2023 Rubicon Communications, LLC (Netgate)
5  * Copyright (c) 2011 Florian Obser <florian@narrans.de>
6  * Copyright (c) 2011 Sebastian Benoit <benoit-lists@fb12.de>
7  * Copyright (c) 2008 Henning Brauer <henning@openbsd.org>
8  * Copyright (c) 2008 Joerg Goltermann <jg@osn.de>
9  *
10  * Permission to use, copy, modify, and distribute this software for any
11  * purpose with or without fee is hereby granted, provided that the above
12  * copyright notice and this permission notice appear in all copies.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
15  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
16  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
17  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
18  * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
19  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
20  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21  */
22 
23 #include <sys/cdefs.h>
24 #include <sys/param.h>
25 #include <sys/bus.h>
26 #include <sys/callout.h>
27 #include <sys/endian.h>
28 #include <sys/interrupt.h>
29 #include <sys/kernel.h>
30 #include <sys/malloc.h>
31 #include <sys/module.h>
32 #include <sys/mbuf.h>
33 #include <sys/socket.h>
34 #include <sys/socketvar.h>
35 #include <sys/sockio.h>
36 #include <sys/sysctl.h>
37 #include <sys/systm.h>
38 #include <sys/priv.h>
39 
40 #include <net/if.h>
41 #include <net/if_types.h>
42 #include <net/bpf.h>
43 #include <net/route.h>
44 #include <netinet/in.h>
45 #include <netinet/if_ether.h>
46 #include <netinet/tcp.h>
47 
48 #include <netinet/ip.h>
49 #include <netinet/ip_icmp.h>
50 #include <netinet/ip_var.h>
51 #include <netinet/udp.h>
52 #include <netinet/udp_var.h>
53 #include <netinet/in_pcb.h>
54 
55 #include <netlink/netlink.h>
56 #include <netlink/netlink_ctl.h>
57 #include <netlink/netlink_generic.h>
58 #include <netlink/netlink_message_writer.h>
59 
60 #include <net/pfvar.h>
61 #include <net/pflow.h>
62 #include "net/if_var.h"
63 
64 #define PFLOW_MINMTU	\
65     (sizeof(struct pflow_header) + sizeof(struct pflow_flow))
66 
67 #ifdef PFLOWDEBUG
68 #define DPRINTF(x)	do { printf x ; } while (0)
69 #else
70 #define DPRINTF(x)
71 #endif
72 
73 enum pflow_family_t {
74 	PFLOW_INET,
75 	PFLOW_INET6,
76 	PFLOW_NAT4,
77 };
78 
79 static void	pflow_output_process(void *);
80 static int	pflow_create(int);
81 static int	pflow_destroy(int, bool);
82 static int	pflow_calc_mtu(struct pflow_softc *, int, int);
83 static void	pflow_setmtu(struct pflow_softc *, int);
84 static int	pflowvalidsockaddr(const struct sockaddr *, int);
85 
86 static struct mbuf	*pflow_get_mbuf(struct pflow_softc *, u_int16_t);
87 static void	pflow_flush(struct pflow_softc *);
88 static int	pflow_sendout_v5(struct pflow_softc *);
89 static int	pflow_sendout_ipfix(struct pflow_softc *, enum pflow_family_t);
90 static int	pflow_sendout_ipfix_tmpl(struct pflow_softc *);
91 static int	pflow_sendout_mbuf(struct pflow_softc *, struct mbuf *);
92 static int	sysctl_pflowstats(SYSCTL_HANDLER_ARGS);
93 static void	pflow_timeout(void *);
94 static void	pflow_timeout6(void *);
95 static void	pflow_timeout_tmpl(void *);
96 static void	pflow_timeout_nat4(void *);
97 static void	copy_flow_data(struct pflow_flow *, struct pflow_flow *,
98 	const struct pf_kstate *, struct pf_state_key *, int, int);
99 static void	copy_flow_ipfix_4_data(struct pflow_ipfix_flow4 *,
100 	struct pflow_ipfix_flow4 *, const struct pf_kstate *, struct pf_state_key *,
101 	struct pflow_softc *, int, int);
102 static void	copy_flow_ipfix_6_data(struct pflow_ipfix_flow6 *,
103 	struct pflow_ipfix_flow6 *, const struct pf_kstate *, struct pf_state_key *,
104 	struct pflow_softc *, int, int);
105 static int	pflow_pack_flow(const struct pf_kstate *, struct pf_state_key *,
106 	struct pflow_softc *);
107 static int	pflow_pack_flow_ipfix(const struct pf_kstate *, struct pf_state_key *,
108 	struct pflow_softc *);
109 static void	export_pflow(const struct pf_kstate *);
110 static int	export_pflow_if(const struct pf_kstate*, struct pf_state_key *,
111 	struct pflow_softc *);
112 static int	copy_flow_to_m(struct pflow_flow *flow, struct pflow_softc *sc);
113 static int	copy_flow_ipfix_4_to_m(struct pflow_ipfix_flow4 *flow,
114 	struct pflow_softc *sc);
115 static int	copy_flow_ipfix_6_to_m(struct pflow_ipfix_flow6 *flow,
116 	struct pflow_softc *sc);
117 static int	copy_nat_ipfix_4_to_m(struct pflow_ipfix_nat4 *,
118 	const struct pf_kstate *, struct pflow_softc *,
119 	uint8_t, uint64_t);
120 
121 static const char pflowname[] = "pflow";
122 
123 enum pflowstat_counters {
124 	pflow_flows,
125 	pflow_packets,
126 	pflow_onomem,
127 	pflow_oerrors,
128 	pflow_ncounters,
129 };
130 struct pflowstats_ctr {
131 	counter_u64_t	c[pflow_ncounters];
132 };
133 
134 /**
135  * Locking concept
136  *
137  * The list of pflow devices (V_pflowif_list) is managed through epoch.
138  * It is safe to read the list without locking (while in NET_EPOCH).
139  * There may only be one simultaneous modifier, hence we need V_pflow_list_mtx
140  * on every add/delete.
141  *
142  * Each pflow interface protects its own data with the sc_lock mutex.
143  *
144  * We do not require any pf locks, and in fact expect to be called without
145  * hashrow locks held.
146  **/
147 
148 VNET_DEFINE(struct unrhdr *,	pflow_unr);
149 #define	V_pflow_unr	VNET(pflow_unr)
150 VNET_DEFINE(CK_LIST_HEAD(, pflow_softc), pflowif_list);
151 #define	V_pflowif_list	VNET(pflowif_list)
152 VNET_DEFINE(struct mtx, pflowif_list_mtx);
153 #define	V_pflowif_list_mtx	VNET(pflowif_list_mtx)
154 VNET_DEFINE(struct pflowstats_ctr,	 pflowstat);
155 #define	V_pflowstats	VNET(pflowstat)
156 
157 #define	PFLOW_LOCK(_sc)		mtx_lock(&(_sc)->sc_lock)
158 #define	PFLOW_UNLOCK(_sc)	mtx_unlock(&(_sc)->sc_lock)
159 #define	PFLOW_ASSERT(_sc)	mtx_assert(&(_sc)->sc_lock, MA_OWNED)
160 
161 SYSCTL_NODE(_net, OID_AUTO, pflow, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
162     "PFLOW");
163 SYSCTL_PROC(_net_pflow, OID_AUTO, stats, CTLTYPE_OPAQUE | CTLFLAG_RD | CTLFLAG_MPSAFE,
164     0, 0, sysctl_pflowstats, "S,pflowstats",
165     "PFLOW statistics (struct pflowstats, net/if_pflow.h)");
166 
167 static inline void
pflowstat_inc(enum pflowstat_counters c)168 pflowstat_inc(enum pflowstat_counters c)
169 {
170 	counter_u64_add(V_pflowstats.c[c], 1);
171 }
172 
173 static void
vnet_pflowattach(void)174 vnet_pflowattach(void)
175 {
176 	CK_LIST_INIT(&V_pflowif_list);
177 	mtx_init(&V_pflowif_list_mtx, "pflow interface list mtx", NULL, MTX_DEF);
178 
179 	V_pflow_unr = new_unrhdr(0, PFLOW_MAX_ENTRIES - 1, &V_pflowif_list_mtx);
180 
181 	for (int i = 0; i < pflow_ncounters; i++)
182 		V_pflowstats.c[i] = counter_u64_alloc(M_WAITOK);
183 }
184 VNET_SYSINIT(vnet_pflowattach, SI_SUB_PROTO_FIREWALL, SI_ORDER_ANY,
185     vnet_pflowattach, NULL);
186 
187 static void
vnet_pflowdetach(void)188 vnet_pflowdetach(void)
189 {
190 	struct pflow_softc	*sc;
191 
192 	CK_LIST_FOREACH(sc, &V_pflowif_list, sc_next) {
193 		pflow_destroy(sc->sc_id, false);
194 	}
195 
196 	MPASS(CK_LIST_EMPTY(&V_pflowif_list));
197 	delete_unrhdr(V_pflow_unr);
198 	mtx_destroy(&V_pflowif_list_mtx);
199 
200 	for (int i = 0; i < pflow_ncounters; i++)
201 		counter_u64_free(V_pflowstats.c[i]);
202 }
203 VNET_SYSUNINIT(vnet_pflowdetach, SI_SUB_PROTO_FIREWALL, SI_ORDER_FOURTH,
204     vnet_pflowdetach, NULL);
205 
206 static void
vnet_pflow_finalise(void)207 vnet_pflow_finalise(void)
208 {
209 	/*
210 	 * Ensure we've freed all interfaces, and do not have pending
211 	 * epoch cleanup calls.
212 	 */
213 	NET_EPOCH_DRAIN_CALLBACKS();
214 }
215 VNET_SYSUNINIT(vnet_pflow_finalise, SI_SUB_PROTO_FIREWALL, SI_ORDER_THIRD,
216     vnet_pflow_finalise, NULL);
217 
218 static void
pflow_output_process(void * arg)219 pflow_output_process(void *arg)
220 {
221 	struct mbufq ml;
222 	struct pflow_softc *sc = arg;
223 	struct mbuf *m;
224 
225 	mbufq_init(&ml, 0);
226 
227 	PFLOW_LOCK(sc);
228 	mbufq_concat(&ml, &sc->sc_outputqueue);
229 	PFLOW_UNLOCK(sc);
230 
231 	CURVNET_SET(sc->sc_vnet);
232 	while ((m = mbufq_dequeue(&ml)) != NULL) {
233 		pflow_sendout_mbuf(sc, m);
234 	}
235 	CURVNET_RESTORE();
236 }
237 
238 static int
pflow_create(int unit)239 pflow_create(int unit)
240 {
241 	struct pflow_softc	*pflowif;
242 	int			 error;
243 
244 	pflowif = malloc(sizeof(*pflowif), M_DEVBUF, M_WAITOK|M_ZERO);
245 	mtx_init(&pflowif->sc_lock, "pflowlk", NULL, MTX_DEF);
246 	pflowif->sc_version = PFLOW_PROTO_DEFAULT;
247 	pflowif->sc_observation_dom = PFLOW_ENGINE_TYPE;
248 
249 	/* ipfix template init */
250 	bzero(&pflowif->sc_tmpl_ipfix,sizeof(pflowif->sc_tmpl_ipfix));
251 	pflowif->sc_tmpl_ipfix.set_header.set_id =
252 	    htons(PFLOW_IPFIX_TMPL_SET_ID);
253 	pflowif->sc_tmpl_ipfix.set_header.set_length =
254 	    htons(sizeof(struct pflow_ipfix_tmpl));
255 
256 	/* ipfix IPv4 template */
257 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.h.tmpl_id =
258 	    htons(PFLOW_IPFIX_TMPL_IPV4_ID);
259 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.h.field_count
260 	    = htons(PFLOW_IPFIX_TMPL_IPV4_FIELD_COUNT);
261 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.src_ip.field_id =
262 	    htons(PFIX_IE_sourceIPv4Address);
263 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.src_ip.len = htons(4);
264 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.dest_ip.field_id =
265 	    htons(PFIX_IE_destinationIPv4Address);
266 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.dest_ip.len = htons(4);
267 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.if_index_in.field_id =
268 	    htons(PFIX_IE_ingressInterface);
269 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.if_index_in.len = htons(4);
270 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.if_index_out.field_id =
271 	    htons(PFIX_IE_egressInterface);
272 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.if_index_out.len = htons(4);
273 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.packets.field_id =
274 	    htons(PFIX_IE_packetDeltaCount);
275 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.packets.len = htons(8);
276 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.octets.field_id =
277 	    htons(PFIX_IE_octetDeltaCount);
278 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.octets.len = htons(8);
279 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.start.field_id =
280 	    htons(PFIX_IE_flowStartMilliseconds);
281 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.start.len = htons(8);
282 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.finish.field_id =
283 	    htons(PFIX_IE_flowEndMilliseconds);
284 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.finish.len = htons(8);
285 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.src_port.field_id =
286 	    htons(PFIX_IE_sourceTransportPort);
287 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.src_port.len = htons(2);
288 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.dest_port.field_id =
289 	    htons(PFIX_IE_destinationTransportPort);
290 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.dest_port.len = htons(2);
291 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.tos.field_id =
292 	    htons(PFIX_IE_ipClassOfService);
293 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.tos.len = htons(1);
294 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.protocol.field_id =
295 	    htons(PFIX_IE_protocolIdentifier);
296 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.protocol.len = htons(1);
297 
298 	/* ipfix IPv6 template */
299 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.h.tmpl_id =
300 	    htons(PFLOW_IPFIX_TMPL_IPV6_ID);
301 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.h.field_count =
302 	    htons(PFLOW_IPFIX_TMPL_IPV6_FIELD_COUNT);
303 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.src_ip.field_id =
304 	    htons(PFIX_IE_sourceIPv6Address);
305 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.src_ip.len = htons(16);
306 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.dest_ip.field_id =
307 	    htons(PFIX_IE_destinationIPv6Address);
308 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.dest_ip.len = htons(16);
309 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.if_index_in.field_id =
310 	    htons(PFIX_IE_ingressInterface);
311 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.if_index_in.len = htons(4);
312 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.if_index_out.field_id =
313 	    htons(PFIX_IE_egressInterface);
314 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.if_index_out.len = htons(4);
315 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.packets.field_id =
316 	    htons(PFIX_IE_packetDeltaCount);
317 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.packets.len = htons(8);
318 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.octets.field_id =
319 	    htons(PFIX_IE_octetDeltaCount);
320 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.octets.len = htons(8);
321 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.start.field_id =
322 	    htons(PFIX_IE_flowStartMilliseconds);
323 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.start.len = htons(8);
324 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.finish.field_id =
325 	    htons(PFIX_IE_flowEndMilliseconds);
326 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.finish.len = htons(8);
327 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.src_port.field_id =
328 	    htons(PFIX_IE_sourceTransportPort);
329 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.src_port.len = htons(2);
330 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.dest_port.field_id =
331 	    htons(PFIX_IE_destinationTransportPort);
332 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.dest_port.len = htons(2);
333 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.tos.field_id =
334 	    htons(PFIX_IE_ipClassOfService);
335 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.tos.len = htons(1);
336 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.protocol.field_id =
337 	    htons(PFIX_IE_protocolIdentifier);
338 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.protocol.len = htons(1);
339 
340 	/* NAT44 create template */
341 	pflowif->sc_tmpl_ipfix.nat44_tmpl.h.tmpl_id =
342 	    htons(PFLOW_IPFIX_TMPL_NAT44_ID);
343 	pflowif->sc_tmpl_ipfix.nat44_tmpl.h.field_count =
344 	    htons(PFLOW_IPFIX_TMPL_NAT44_FIELD_COUNT);
345 	pflowif->sc_tmpl_ipfix.nat44_tmpl.timestamp.field_id =
346 	    htons(PFIX_IE_timeStamp);
347 	pflowif->sc_tmpl_ipfix.nat44_tmpl.timestamp.len =
348 	    htons(8);
349 	pflowif->sc_tmpl_ipfix.nat44_tmpl.nat_event.field_id =
350 	    htons(PFIX_IE_natEvent);
351 	pflowif->sc_tmpl_ipfix.nat44_tmpl.nat_event.len =
352 	    htons(1);
353 	pflowif->sc_tmpl_ipfix.nat44_tmpl.protocol.field_id =
354 	    htons(PFIX_IE_protocolIdentifier);
355 	pflowif->sc_tmpl_ipfix.nat44_tmpl.protocol.len = htons(1);
356 	pflowif->sc_tmpl_ipfix.nat44_tmpl.src_ip.field_id =
357 	    htons(PFIX_IE_sourceIPv4Address);
358 	pflowif->sc_tmpl_ipfix.nat44_tmpl.src_ip.len =
359 	    htons(4);
360 	pflowif->sc_tmpl_ipfix.nat44_tmpl.src_port.field_id =
361 	    htons(PFIX_IE_sourceTransportPort);
362 	pflowif->sc_tmpl_ipfix.nat44_tmpl.src_port.len = htons(2);
363 	pflowif->sc_tmpl_ipfix.nat44_tmpl.postnat_src_ip.field_id =
364 	    htons(PFIX_IE_postNATSourceIPv4Address);
365 	pflowif->sc_tmpl_ipfix.nat44_tmpl.postnat_src_ip.len =
366 	    htons(4);
367 	pflowif->sc_tmpl_ipfix.nat44_tmpl.postnat_src_port.field_id =
368 	    htons(PFIX_IE_postNAPTSourceTransportPort);
369 	pflowif->sc_tmpl_ipfix.nat44_tmpl.postnat_src_port.len =
370 	    htons(2);
371 	pflowif->sc_tmpl_ipfix.nat44_tmpl.dst_ip.field_id =
372 	    htons(PFIX_IE_destinationIPv4Address);
373 	pflowif->sc_tmpl_ipfix.nat44_tmpl.dst_ip.len =
374 	    htons(4);
375 	pflowif->sc_tmpl_ipfix.nat44_tmpl.dst_port.field_id =
376 	    htons(PFIX_IE_destinationTransportPort);
377 	pflowif->sc_tmpl_ipfix.nat44_tmpl.dst_port.len = htons(2);
378 	pflowif->sc_tmpl_ipfix.nat44_tmpl.postnat_dst_ip.field_id =
379 	    htons(PFIX_IE_postNATDestinationIPv4Address);
380 	pflowif->sc_tmpl_ipfix.nat44_tmpl.postnat_dst_ip.len =
381 	    htons(4);
382 	pflowif->sc_tmpl_ipfix.nat44_tmpl.postnat_dst_port.field_id =
383 	    htons(PFIX_IE_postNAPTDestinationTransportPort);
384 	pflowif->sc_tmpl_ipfix.nat44_tmpl.postnat_dst_port.len =
385 	    htons(2);
386 
387 	pflowif->sc_id = unit;
388 	pflowif->sc_vnet = curvnet;
389 
390 	mbufq_init(&pflowif->sc_outputqueue, 8192);
391 	pflow_setmtu(pflowif, ETHERMTU);
392 
393 	callout_init_mtx(&pflowif->sc_tmo, &pflowif->sc_lock, 0);
394 	callout_init_mtx(&pflowif->sc_tmo6, &pflowif->sc_lock, 0);
395 	callout_init_mtx(&pflowif->sc_tmo_nat4, &pflowif->sc_lock, 0);
396 	callout_init_mtx(&pflowif->sc_tmo_tmpl, &pflowif->sc_lock, 0);
397 
398 	error = swi_add(&pflowif->sc_swi_ie, pflowname, pflow_output_process,
399 	    pflowif, SWI_NET, INTR_MPSAFE, &pflowif->sc_swi_cookie);
400 	if (error) {
401 		free(pflowif, M_DEVBUF);
402 		return (error);
403 	}
404 
405 	/* Insert into list of pflows */
406 	mtx_lock(&V_pflowif_list_mtx);
407 	CK_LIST_INSERT_HEAD(&V_pflowif_list, pflowif, sc_next);
408 	mtx_unlock(&V_pflowif_list_mtx);
409 
410 	V_pflow_export_state_ptr = export_pflow;
411 
412 	return (0);
413 }
414 
415 static void
pflow_free_cb(struct epoch_context * ctx)416 pflow_free_cb(struct epoch_context *ctx)
417 {
418 	struct pflow_softc *sc;
419 
420 	sc = __containerof(ctx, struct pflow_softc, sc_epoch_ctx);
421 
422 	free(sc, M_DEVBUF);
423 }
424 
425 static int
pflow_destroy(int unit,bool drain)426 pflow_destroy(int unit, bool drain)
427 {
428 	struct pflow_softc	*sc;
429 	int			 error __diagused;
430 
431 	mtx_lock(&V_pflowif_list_mtx);
432 	CK_LIST_FOREACH(sc, &V_pflowif_list, sc_next) {
433 		if (sc->sc_id == unit)
434 			break;
435 	}
436 	if (sc == NULL) {
437 		mtx_unlock(&V_pflowif_list_mtx);
438 		return (ENOENT);
439 	}
440 	CK_LIST_REMOVE(sc, sc_next);
441 	if (CK_LIST_EMPTY(&V_pflowif_list))
442 		V_pflow_export_state_ptr = NULL;
443 	mtx_unlock(&V_pflowif_list_mtx);
444 
445 	sc->sc_dying = 1;
446 
447 	if (drain) {
448 		/* Let's be sure no one is using this interface any more. */
449 		NET_EPOCH_DRAIN_CALLBACKS();
450 	}
451 
452 	error = swi_remove(sc->sc_swi_cookie);
453 	MPASS(error == 0);
454 	error = intr_event_destroy(sc->sc_swi_ie);
455 	MPASS(error == 0);
456 
457 	callout_drain(&sc->sc_tmo);
458 	callout_drain(&sc->sc_tmo6);
459 	callout_drain(&sc->sc_tmo_nat4);
460 	callout_drain(&sc->sc_tmo_tmpl);
461 
462 	m_freem(sc->sc_mbuf);
463 	m_freem(sc->sc_mbuf6);
464 	m_freem(sc->sc_mbuf_nat4);
465 
466 	PFLOW_LOCK(sc);
467 	mbufq_drain(&sc->sc_outputqueue);
468 	if (sc->so != NULL) {
469 		soclose(sc->so);
470 		sc->so = NULL;
471 	}
472 	if (sc->sc_flowdst != NULL)
473 		free(sc->sc_flowdst, M_DEVBUF);
474 	if (sc->sc_flowsrc != NULL)
475 		free(sc->sc_flowsrc, M_DEVBUF);
476 	PFLOW_UNLOCK(sc);
477 
478 	mtx_destroy(&sc->sc_lock);
479 
480 	free_unr(V_pflow_unr, unit);
481 
482 	NET_EPOCH_CALL(pflow_free_cb, &sc->sc_epoch_ctx);
483 
484 	return (0);
485 }
486 
487 static int
pflowvalidsockaddr(const struct sockaddr * sa,int ignore_port)488 pflowvalidsockaddr(const struct sockaddr *sa, int ignore_port)
489 {
490 	const struct sockaddr_in6	*sin6;
491 	const struct sockaddr_in	*sin;
492 
493 	if (sa == NULL)
494 		return (0);
495 	switch(sa->sa_family) {
496 	case AF_INET:
497 		sin = (const struct sockaddr_in *)sa;
498 		return (sin->sin_addr.s_addr != INADDR_ANY &&
499 		    (ignore_port || sin->sin_port != 0));
500 	case AF_INET6:
501 		sin6 = (const struct sockaddr_in6 *)sa;
502 		return (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr) &&
503 		    (ignore_port || sin6->sin6_port != 0));
504 	default:
505 		return (0);
506 	}
507 }
508 
509 int
pflow_calc_mtu(struct pflow_softc * sc,int mtu,int hdrsz)510 pflow_calc_mtu(struct pflow_softc *sc, int mtu, int hdrsz)
511 {
512 	size_t min;
513 
514 	sc->sc_maxcount4 = (mtu - hdrsz -
515 	    sizeof(struct udpiphdr)) / sizeof(struct pflow_ipfix_flow4);
516 	sc->sc_maxcount6 = (mtu - hdrsz -
517 	    sizeof(struct udpiphdr)) / sizeof(struct pflow_ipfix_flow6);
518 	sc->sc_maxcount_nat4 = (mtu - hdrsz -
519 	    sizeof(struct udpiphdr)) / sizeof(struct pflow_ipfix_nat4);
520 	if (sc->sc_maxcount4 > PFLOW_MAXFLOWS)
521 		sc->sc_maxcount4 = PFLOW_MAXFLOWS;
522 	if (sc->sc_maxcount6 > PFLOW_MAXFLOWS)
523 		sc->sc_maxcount6 = PFLOW_MAXFLOWS;
524 	if (sc->sc_maxcount_nat4 > PFLOW_MAXFLOWS)
525 		sc->sc_maxcount_nat4 = PFLOW_MAXFLOWS;
526 
527 	min = MIN(sc->sc_maxcount4 * sizeof(struct pflow_ipfix_flow4),
528 	    sc->sc_maxcount6 * sizeof(struct pflow_ipfix_flow6));
529 	min = MIN(min, sc->sc_maxcount_nat4 * sizeof(struct pflow_ipfix_nat4));
530 
531 	return (hdrsz + sizeof(struct udpiphdr) + min);
532 }
533 
534 static void
pflow_setmtu(struct pflow_softc * sc,int mtu_req)535 pflow_setmtu(struct pflow_softc *sc, int mtu_req)
536 {
537 	int	mtu;
538 
539 	mtu = mtu_req;
540 
541 	switch (sc->sc_version) {
542 	case PFLOW_PROTO_5:
543 		sc->sc_maxcount = (mtu - sizeof(struct pflow_header) -
544 		    sizeof(struct udpiphdr)) / sizeof(struct pflow_flow);
545 		if (sc->sc_maxcount > PFLOW_MAXFLOWS)
546 		    sc->sc_maxcount = PFLOW_MAXFLOWS;
547 		break;
548 	case PFLOW_PROTO_10:
549 		pflow_calc_mtu(sc, mtu, sizeof(struct pflow_v10_header));
550 		break;
551 	default: /* NOTREACHED */
552 		break;
553 	}
554 }
555 
556 static struct mbuf *
pflow_get_mbuf(struct pflow_softc * sc,u_int16_t set_id)557 pflow_get_mbuf(struct pflow_softc *sc, u_int16_t set_id)
558 {
559 	struct pflow_set_header	 set_hdr;
560 	struct pflow_header	 h;
561 	struct mbuf		*m;
562 
563 	MGETHDR(m, M_NOWAIT, MT_DATA);
564 	if (m == NULL) {
565 		pflowstat_inc(pflow_onomem);
566 		return (NULL);
567 	}
568 
569 	MCLGET(m, M_NOWAIT);
570 	if ((m->m_flags & M_EXT) == 0) {
571 		m_free(m);
572 		pflowstat_inc(pflow_onomem);
573 		return (NULL);
574 	}
575 
576 	m->m_len = m->m_pkthdr.len = 0;
577 
578 	if (sc == NULL)		/* get only a new empty mbuf */
579 		return (m);
580 
581 	switch (sc->sc_version) {
582 	case PFLOW_PROTO_5:
583 		/* populate pflow_header */
584 		h.reserved1 = 0;
585 		h.reserved2 = 0;
586 		h.count = 0;
587 		h.version = htons(PFLOW_PROTO_5);
588 		h.flow_sequence = htonl(sc->sc_gcounter);
589 		h.engine_type = PFLOW_ENGINE_TYPE;
590 		h.engine_id = PFLOW_ENGINE_ID;
591 		m_copyback(m, 0, PFLOW_HDRLEN, (caddr_t)&h);
592 
593 		sc->sc_count = 0;
594 		callout_reset(&sc->sc_tmo, PFLOW_TIMEOUT * hz,
595 		    pflow_timeout, sc);
596 		break;
597 	case PFLOW_PROTO_10:
598 		/* populate pflow_set_header */
599 		set_hdr.set_length = 0;
600 		set_hdr.set_id = htons(set_id);
601 		m_copyback(m, 0, PFLOW_SET_HDRLEN, (caddr_t)&set_hdr);
602 		break;
603 	default: /* NOTREACHED */
604 		break;
605 	}
606 
607 	return (m);
608 }
609 
610 static void
copy_flow_data(struct pflow_flow * flow1,struct pflow_flow * flow2,const struct pf_kstate * st,struct pf_state_key * sk,int src,int dst)611 copy_flow_data(struct pflow_flow *flow1, struct pflow_flow *flow2,
612     const struct pf_kstate *st, struct pf_state_key *sk, int src, int dst)
613 {
614 	flow1->src_ip = flow2->dest_ip = sk->addr[src].v4.s_addr;
615 	flow1->src_port = flow2->dest_port = sk->port[src];
616 	flow1->dest_ip = flow2->src_ip = sk->addr[dst].v4.s_addr;
617 	flow1->dest_port = flow2->src_port = sk->port[dst];
618 
619 	flow1->dest_as = flow2->src_as =
620 	    flow1->src_as = flow2->dest_as = 0;
621 	flow1->if_index_in = htons(st->if_index_in);
622 	flow1->if_index_out = htons(st->if_index_out);
623 	flow2->if_index_in = htons(st->if_index_out);
624 	flow2->if_index_out = htons(st->if_index_in);
625 	flow1->dest_mask = flow2->src_mask =
626 	    flow1->src_mask = flow2->dest_mask = 0;
627 
628 	flow1->flow_packets = htonl(st->packets[0]);
629 	flow2->flow_packets = htonl(st->packets[1]);
630 	flow1->flow_octets = htonl(st->bytes[0]);
631 	flow2->flow_octets = htonl(st->bytes[1]);
632 
633 	/*
634 	 * Pretend the flow was created or expired when the machine came up
635 	 * when creation is in the future of the last time a package was seen
636 	 * or was created / expired before this machine came up due to pfsync.
637 	 */
638 	flow1->flow_start = flow2->flow_start = st->creation < 0 ||
639 	    st->creation > st->expire ? htonl(0) : htonl(st->creation);
640 	flow1->flow_finish = flow2->flow_finish = st->expire < 0 ? htonl(0) :
641 	    htonl(st->expire);
642 	flow1->tcp_flags = flow2->tcp_flags = 0;
643 	flow1->protocol = flow2->protocol = sk->proto;
644 	flow1->tos = flow2->tos = st->rule.ptr->tos;
645 }
646 
647 static void
copy_flow_ipfix_4_data(struct pflow_ipfix_flow4 * flow1,struct pflow_ipfix_flow4 * flow2,const struct pf_kstate * st,struct pf_state_key * sk,struct pflow_softc * sc,int src,int dst)648 copy_flow_ipfix_4_data(struct pflow_ipfix_flow4 *flow1,
649     struct pflow_ipfix_flow4 *flow2, const struct pf_kstate *st,
650     struct pf_state_key *sk, struct pflow_softc *sc, int src, int dst)
651 {
652 	flow1->src_ip = flow2->dest_ip = sk->addr[src].v4.s_addr;
653 	flow1->src_port = flow2->dest_port = sk->port[src];
654 	flow1->dest_ip = flow2->src_ip = sk->addr[dst].v4.s_addr;
655 	flow1->dest_port = flow2->src_port = sk->port[dst];
656 
657 	flow1->if_index_in = htonl(st->if_index_in);
658 	flow1->if_index_out = htonl(st->if_index_out);
659 	flow2->if_index_in = htonl(st->if_index_out);
660 	flow2->if_index_out = htonl(st->if_index_in);
661 
662 	flow1->flow_packets = htobe64(st->packets[0]);
663 	flow2->flow_packets = htobe64(st->packets[1]);
664 	flow1->flow_octets = htobe64(st->bytes[0]);
665 	flow2->flow_octets = htobe64(st->bytes[1]);
666 
667 	/*
668 	 * Pretend the flow was created when the machine came up when creation
669 	 * is in the future of the last time a package was seen due to pfsync.
670 	 */
671 	if (st->creation > st->expire)
672 		flow1->flow_start = flow2->flow_start = htobe64((time_second -
673 		    time_uptime)*1000);
674 	else
675 		flow1->flow_start = flow2->flow_start = htobe64((pf_get_time() -
676 		    (pf_get_uptime() - st->creation)));
677 	flow1->flow_finish = flow2->flow_finish = htobe64((pf_get_time() -
678 	    (pf_get_uptime() - st->expire)));
679 
680 	flow1->protocol = flow2->protocol = sk->proto;
681 	flow1->tos = flow2->tos = st->rule.ptr->tos;
682 }
683 
684 static void
copy_flow_ipfix_6_data(struct pflow_ipfix_flow6 * flow1,struct pflow_ipfix_flow6 * flow2,const struct pf_kstate * st,struct pf_state_key * sk,struct pflow_softc * sc,int src,int dst)685 copy_flow_ipfix_6_data(struct pflow_ipfix_flow6 *flow1,
686     struct pflow_ipfix_flow6 *flow2, const struct pf_kstate *st,
687     struct pf_state_key *sk, struct pflow_softc *sc, int src, int dst)
688 {
689 	bcopy(&sk->addr[src].v6, &flow1->src_ip, sizeof(flow1->src_ip));
690 	bcopy(&sk->addr[src].v6, &flow2->dest_ip, sizeof(flow2->dest_ip));
691 	flow1->src_port = flow2->dest_port = sk->port[src];
692 	bcopy(&sk->addr[dst].v6, &flow1->dest_ip, sizeof(flow1->dest_ip));
693 	bcopy(&sk->addr[dst].v6, &flow2->src_ip, sizeof(flow2->src_ip));
694 	flow1->dest_port = flow2->src_port = sk->port[dst];
695 
696 	flow1->if_index_in = htonl(st->if_index_in);
697 	flow1->if_index_out = htonl(st->if_index_out);
698 	flow2->if_index_in = htonl(st->if_index_out);
699 	flow2->if_index_out = htonl(st->if_index_in);
700 
701 	flow1->flow_packets = htobe64(st->packets[0]);
702 	flow2->flow_packets = htobe64(st->packets[1]);
703 	flow1->flow_octets = htobe64(st->bytes[0]);
704 	flow2->flow_octets = htobe64(st->bytes[1]);
705 
706 	/*
707 	 * Pretend the flow was created when the machine came up when creation
708 	 * is in the future of the last time a package was seen due to pfsync.
709 	 */
710 	if (st->creation > st->expire)
711 		flow1->flow_start = flow2->flow_start = htobe64((time_second -
712 		    time_uptime)*1000);
713 	else
714 		flow1->flow_start = flow2->flow_start = htobe64((pf_get_time() -
715 		    (pf_get_uptime() - st->creation)));
716 	flow1->flow_finish = flow2->flow_finish = htobe64((pf_get_time() -
717 	    (pf_get_uptime() - st->expire)));
718 
719 	flow1->protocol = flow2->protocol = sk->proto;
720 	flow1->tos = flow2->tos = st->rule.ptr->tos;
721 }
722 
723 static void
copy_nat_ipfix_4_data(struct pflow_ipfix_nat4 * nat1,struct pflow_ipfix_nat4 * nat2,const struct pf_kstate * st,struct pf_state_key * sk,struct pflow_softc * sc,int src,int dst)724 copy_nat_ipfix_4_data(struct pflow_ipfix_nat4 *nat1,
725     struct pflow_ipfix_nat4 *nat2, const struct pf_kstate *st,
726     struct pf_state_key *sk, struct pflow_softc *sc, int src, int dst)
727 {
728 	nat1->src_ip = nat2->dest_ip = st->key[PF_SK_STACK]->addr[src].v4.s_addr;
729 	nat1->src_port = nat2->dest_port = st->key[PF_SK_STACK]->port[src];
730 	nat1->dest_ip = nat2->src_ip = st->key[PF_SK_STACK]->addr[dst].v4.s_addr;
731 	nat1->dest_port = nat2->src_port = st->key[PF_SK_STACK]->port[dst];
732 	nat1->postnat_src_ip = nat2->postnat_dest_ip = st->key[PF_SK_WIRE]->addr[src].v4.s_addr;
733 	nat1->postnat_src_port = nat2->postnat_dest_port = st->key[PF_SK_WIRE]->port[src];
734 	nat1->postnat_dest_ip = nat2->postnat_src_ip = st->key[PF_SK_WIRE]->addr[dst].v4.s_addr;
735 	nat1->postnat_dest_port = nat2->postnat_src_port = st->key[PF_SK_WIRE]->port[dst];
736 	nat1->protocol = nat2->protocol = sk->proto;
737 
738 	/*
739 	 * Because we have to generate a create and delete event we'll fill out the
740 	 * timestamp and nat_event fields when we transmit. As opposed to doing this
741 	 * work a second time.
742 	*/
743 }
744 
745 static void
export_pflow(const struct pf_kstate * st)746 export_pflow(const struct pf_kstate *st)
747 {
748 	struct pflow_softc	*sc = NULL;
749 	struct pf_state_key	*sk;
750 
751 	NET_EPOCH_ASSERT();
752 
753 	/* e.g. if pf_state_key_attach() fails. */
754 	if (st->key[PF_SK_STACK] == NULL || st->key[PF_SK_WIRE] == NULL)
755 		return;
756 
757 	sk = st->key[st->direction == PF_IN ? PF_SK_WIRE : PF_SK_STACK];
758 
759 	CK_LIST_FOREACH(sc, &V_pflowif_list, sc_next) {
760 		PFLOW_LOCK(sc);
761 		switch (sc->sc_version) {
762 		case PFLOW_PROTO_5:
763 			if (sk->af == AF_INET)
764 				export_pflow_if(st, sk, sc);
765 			break;
766 		case PFLOW_PROTO_10:
767 			if (sk->af == AF_INET || sk->af == AF_INET6)
768 				export_pflow_if(st, sk, sc);
769 			break;
770 		default: /* NOTREACHED */
771 			break;
772 		}
773 		PFLOW_UNLOCK(sc);
774 	}
775 }
776 
777 static int
export_pflow_if(const struct pf_kstate * st,struct pf_state_key * sk,struct pflow_softc * sc)778 export_pflow_if(const struct pf_kstate *st, struct pf_state_key *sk,
779     struct pflow_softc *sc)
780 {
781 	struct pf_kstate	 pfs_copy;
782 	u_int64_t		 bytes[2];
783 	int			 ret = 0;
784 
785 	if (sc->sc_version == PFLOW_PROTO_10)
786 		return (pflow_pack_flow_ipfix(st, sk, sc));
787 
788 	/* PFLOW_PROTO_5 */
789 	if ((st->bytes[0] < (u_int64_t)PFLOW_MAXBYTES)
790 	    && (st->bytes[1] < (u_int64_t)PFLOW_MAXBYTES))
791 		return (pflow_pack_flow(st, sk, sc));
792 
793 	/* flow > PFLOW_MAXBYTES need special handling */
794 	bcopy(st, &pfs_copy, sizeof(pfs_copy));
795 	bytes[0] = pfs_copy.bytes[0];
796 	bytes[1] = pfs_copy.bytes[1];
797 
798 	while (bytes[0] > PFLOW_MAXBYTES) {
799 		pfs_copy.bytes[0] = PFLOW_MAXBYTES;
800 		pfs_copy.bytes[1] = 0;
801 
802 		if ((ret = pflow_pack_flow(&pfs_copy, sk, sc)) != 0)
803 			return (ret);
804 		if ((bytes[0] - PFLOW_MAXBYTES) > 0)
805 			bytes[0] -= PFLOW_MAXBYTES;
806 	}
807 
808 	while (bytes[1] > (u_int64_t)PFLOW_MAXBYTES) {
809 		pfs_copy.bytes[1] = PFLOW_MAXBYTES;
810 		pfs_copy.bytes[0] = 0;
811 
812 		if ((ret = pflow_pack_flow(&pfs_copy, sk, sc)) != 0)
813 			return (ret);
814 		if ((bytes[1] - PFLOW_MAXBYTES) > 0)
815 			bytes[1] -= PFLOW_MAXBYTES;
816 	}
817 
818 	pfs_copy.bytes[0] = bytes[0];
819 	pfs_copy.bytes[1] = bytes[1];
820 
821 	return (pflow_pack_flow(&pfs_copy, sk, sc));
822 }
823 
824 static int
copy_flow_to_m(struct pflow_flow * flow,struct pflow_softc * sc)825 copy_flow_to_m(struct pflow_flow *flow, struct pflow_softc *sc)
826 {
827 	int		ret = 0;
828 
829 	PFLOW_ASSERT(sc);
830 
831 	if (sc->sc_mbuf == NULL) {
832 		if ((sc->sc_mbuf = pflow_get_mbuf(sc, 0)) == NULL)
833 			return (ENOBUFS);
834 	}
835 	m_copyback(sc->sc_mbuf, PFLOW_HDRLEN +
836 	    (sc->sc_count * sizeof(struct pflow_flow)),
837 	    sizeof(struct pflow_flow), (caddr_t)flow);
838 
839 	pflowstat_inc(pflow_flows);
840 	sc->sc_gcounter++;
841 	sc->sc_count++;
842 
843 	if (sc->sc_count >= sc->sc_maxcount)
844 		ret = pflow_sendout_v5(sc);
845 
846 	return(ret);
847 }
848 
849 static int
copy_flow_ipfix_4_to_m(struct pflow_ipfix_flow4 * flow,struct pflow_softc * sc)850 copy_flow_ipfix_4_to_m(struct pflow_ipfix_flow4 *flow, struct pflow_softc *sc)
851 {
852 	int		ret = 0;
853 
854 	PFLOW_ASSERT(sc);
855 
856 	if (sc->sc_mbuf == NULL) {
857 		if ((sc->sc_mbuf =
858 		    pflow_get_mbuf(sc, PFLOW_IPFIX_TMPL_IPV4_ID)) == NULL) {
859 			return (ENOBUFS);
860 		}
861 		sc->sc_count4 = 0;
862 		callout_reset(&sc->sc_tmo, PFLOW_TIMEOUT * hz,
863 		    pflow_timeout, sc);
864 	}
865 	m_copyback(sc->sc_mbuf, PFLOW_SET_HDRLEN +
866 	    (sc->sc_count4 * sizeof(struct pflow_ipfix_flow4)),
867 	    sizeof(struct pflow_ipfix_flow4), (caddr_t)flow);
868 
869 	pflowstat_inc(pflow_flows);
870 	sc->sc_gcounter++;
871 	sc->sc_count4++;
872 
873 	if (sc->sc_count4 >= sc->sc_maxcount4)
874 		ret = pflow_sendout_ipfix(sc, PFLOW_INET);
875 	return(ret);
876 }
877 
878 static int
copy_flow_ipfix_6_to_m(struct pflow_ipfix_flow6 * flow,struct pflow_softc * sc)879 copy_flow_ipfix_6_to_m(struct pflow_ipfix_flow6 *flow, struct pflow_softc *sc)
880 {
881 	int		ret = 0;
882 
883 	PFLOW_ASSERT(sc);
884 
885 	if (sc->sc_mbuf6 == NULL) {
886 		if ((sc->sc_mbuf6 =
887 		    pflow_get_mbuf(sc, PFLOW_IPFIX_TMPL_IPV6_ID)) == NULL) {
888 			return (ENOBUFS);
889 		}
890 		sc->sc_count6 = 0;
891 		callout_reset(&sc->sc_tmo6, PFLOW_TIMEOUT * hz,
892 		    pflow_timeout6, sc);
893 	}
894 	m_copyback(sc->sc_mbuf6, PFLOW_SET_HDRLEN +
895 	    (sc->sc_count6 * sizeof(struct pflow_ipfix_flow6)),
896 	    sizeof(struct pflow_ipfix_flow6), (caddr_t)flow);
897 
898 	pflowstat_inc(pflow_flows);
899 	sc->sc_gcounter++;
900 	sc->sc_count6++;
901 
902 	if (sc->sc_count6 >= sc->sc_maxcount6)
903 		ret = pflow_sendout_ipfix(sc, PFLOW_INET6);
904 
905 	return(ret);
906 }
907 
908 int
copy_nat_ipfix_4_to_m(struct pflow_ipfix_nat4 * nat,const struct pf_kstate * st,struct pflow_softc * sc,uint8_t event,uint64_t timestamp)909 copy_nat_ipfix_4_to_m(struct pflow_ipfix_nat4 *nat, const struct pf_kstate *st,
910     struct pflow_softc *sc, uint8_t event, uint64_t timestamp)
911 {
912 	int		ret = 0;
913 
914 	PFLOW_ASSERT(sc);
915 
916 	if (sc->sc_mbuf_nat4 == NULL) {
917 		if ((sc->sc_mbuf_nat4 =
918 		    pflow_get_mbuf(sc, PFLOW_IPFIX_TMPL_NAT44_ID)) == NULL) {
919 			return (ENOBUFS);
920 		}
921 		sc->sc_count_nat4 = 0;
922 		callout_reset(&sc->sc_tmo, PFLOW_TIMEOUT * hz,
923 		    pflow_timeout_nat4, sc);
924 	}
925 
926 	nat->nat_event = event;
927 	nat->timestamp = htobe64(pf_get_time() - (pf_get_uptime() - timestamp));
928 	m_copyback(sc->sc_mbuf_nat4, PFLOW_SET_HDRLEN +
929 	    (sc->sc_count_nat4 * sizeof(struct pflow_ipfix_nat4)),
930 	    sizeof(struct pflow_ipfix_nat4), (caddr_t)nat);
931 	sc->sc_count_nat4++;
932 
933 	pflowstat_inc(pflow_flows);
934 	sc->sc_gcounter++;
935 
936 	if (sc->sc_count_nat4 >= sc->sc_maxcount_nat4)
937 		ret = pflow_sendout_ipfix(sc, PFLOW_NAT4);
938 
939 	return (ret);
940 }
941 
942 static int
pflow_pack_flow(const struct pf_kstate * st,struct pf_state_key * sk,struct pflow_softc * sc)943 pflow_pack_flow(const struct pf_kstate *st, struct pf_state_key *sk,
944     struct pflow_softc *sc)
945 {
946 	struct pflow_flow	 flow1;
947 	struct pflow_flow	 flow2;
948 	int			 ret = 0;
949 
950 	bzero(&flow1, sizeof(flow1));
951 	bzero(&flow2, sizeof(flow2));
952 
953 	if (st->direction == PF_OUT)
954 		copy_flow_data(&flow1, &flow2, st, sk, 1, 0);
955 	else
956 		copy_flow_data(&flow1, &flow2, st, sk, 0, 1);
957 
958 	if (st->bytes[0] != 0) /* first flow from state */
959 		ret = copy_flow_to_m(&flow1, sc);
960 
961 	if (st->bytes[1] != 0) /* second flow from state */
962 		ret = copy_flow_to_m(&flow2, sc);
963 
964 	return (ret);
965 }
966 
967 static bool
pflow_is_natd(const struct pf_kstate * st)968 pflow_is_natd(const struct pf_kstate *st)
969 {
970 	/* If ports or addresses are different we've been NAT-ed. */
971 	return (memcmp(st->key[PF_SK_WIRE], st->key[PF_SK_STACK],
972 	    sizeof(struct pf_addr) * 2 + sizeof(uint16_t) * 2) != 0);
973 }
974 
975 static int
pflow_pack_flow_ipfix(const struct pf_kstate * st,struct pf_state_key * sk,struct pflow_softc * sc)976 pflow_pack_flow_ipfix(const struct pf_kstate *st, struct pf_state_key *sk,
977     struct pflow_softc *sc)
978 {
979 	struct pflow_ipfix_flow4	 flow4_1, flow4_2;
980 	struct pflow_ipfix_nat4		 nat4_1, nat4_2;
981 	struct pflow_ipfix_flow6	 flow6_1, flow6_2;
982 	int				 ret = 0;
983 	bool				 nat = false;
984 
985 	if (sk->af == AF_INET) {
986 		bzero(&flow4_1, sizeof(flow4_1));
987 		bzero(&flow4_2, sizeof(flow4_2));
988 
989 		nat = pflow_is_natd(st);
990 
991 		if (st->direction == PF_OUT)
992 			copy_flow_ipfix_4_data(&flow4_1, &flow4_2, st, sk, sc,
993 			    1, 0);
994 		else
995 			copy_flow_ipfix_4_data(&flow4_1, &flow4_2, st, sk, sc,
996 			    0, 1);
997 
998 		if (nat)
999 			copy_nat_ipfix_4_data(&nat4_1, &nat4_2, st, sk, sc, 1, 0);
1000 
1001 		if (st->bytes[0] != 0) /* first flow from state */ {
1002 			ret = copy_flow_ipfix_4_to_m(&flow4_1, sc);
1003 
1004 			if (ret == 0 && nat) {
1005 				ret = copy_nat_ipfix_4_to_m(&nat4_1, st, sc,
1006 				    PFIX_NAT_EVENT_SESSION_CREATE, st->creation);
1007 				ret |= copy_nat_ipfix_4_to_m(&nat4_1, st, sc,
1008 				    PFIX_NAT_EVENT_SESSION_DELETE, st->expire);
1009 			}
1010 		}
1011 
1012 		if (st->bytes[1] != 0) /* second flow from state */ {
1013 			ret = copy_flow_ipfix_4_to_m(&flow4_2, sc);
1014 
1015 			if (ret == 0 && nat) {
1016 				ret = copy_nat_ipfix_4_to_m(&nat4_2, st, sc,
1017 				    PFIX_NAT_EVENT_SESSION_CREATE, st->creation);
1018 				ret |= copy_nat_ipfix_4_to_m(&nat4_2, st, sc,
1019 				    PFIX_NAT_EVENT_SESSION_DELETE, st->expire);
1020 			}
1021 		}
1022 	} else if (sk->af == AF_INET6) {
1023 		bzero(&flow6_1, sizeof(flow6_1));
1024 		bzero(&flow6_2, sizeof(flow6_2));
1025 
1026 		if (st->direction == PF_OUT)
1027 			copy_flow_ipfix_6_data(&flow6_1, &flow6_2, st, sk, sc,
1028 			    1, 0);
1029 		else
1030 			copy_flow_ipfix_6_data(&flow6_1, &flow6_2, st, sk, sc,
1031 			    0, 1);
1032 
1033 		if (st->bytes[0] != 0) /* first flow from state */
1034 			ret = copy_flow_ipfix_6_to_m(&flow6_1, sc);
1035 
1036 		if (st->bytes[1] != 0) /* second flow from state */
1037 			ret = copy_flow_ipfix_6_to_m(&flow6_2, sc);
1038 	}
1039 	return (ret);
1040 }
1041 
1042 static void
pflow_timeout(void * v)1043 pflow_timeout(void *v)
1044 {
1045 	struct pflow_softc	*sc = v;
1046 
1047 	PFLOW_ASSERT(sc);
1048 	CURVNET_SET(sc->sc_vnet);
1049 
1050 	switch (sc->sc_version) {
1051 	case PFLOW_PROTO_5:
1052 		pflow_sendout_v5(sc);
1053 		break;
1054 	case PFLOW_PROTO_10:
1055 		pflow_sendout_ipfix(sc, PFLOW_INET);
1056 		break;
1057 	default: /* NOTREACHED */
1058 		panic("Unsupported version %d", sc->sc_version);
1059 		break;
1060 	}
1061 
1062 	CURVNET_RESTORE();
1063 }
1064 
1065 static void
pflow_timeout6(void * v)1066 pflow_timeout6(void *v)
1067 {
1068 	struct pflow_softc	*sc = v;
1069 
1070 	PFLOW_ASSERT(sc);
1071 
1072 	if (sc->sc_version != PFLOW_PROTO_10)
1073 		return;
1074 
1075 	CURVNET_SET(sc->sc_vnet);
1076 	pflow_sendout_ipfix(sc, PFLOW_INET6);
1077 	CURVNET_RESTORE();
1078 }
1079 
1080 static void
pflow_timeout_tmpl(void * v)1081 pflow_timeout_tmpl(void *v)
1082 {
1083 	struct pflow_softc	*sc = v;
1084 
1085 	PFLOW_ASSERT(sc);
1086 
1087 	if (sc->sc_version != PFLOW_PROTO_10)
1088 		return;
1089 
1090 	CURVNET_SET(sc->sc_vnet);
1091 	pflow_sendout_ipfix_tmpl(sc);
1092 	CURVNET_RESTORE();
1093 }
1094 
1095 static void
pflow_timeout_nat4(void * v)1096 pflow_timeout_nat4(void *v)
1097 {
1098 	struct pflow_softc	*sc = v;
1099 
1100 	PFLOW_ASSERT(sc);
1101 
1102 	if (sc->sc_version != PFLOW_PROTO_10)
1103 		return;
1104 
1105 	CURVNET_SET(sc->sc_vnet);
1106 	pflow_sendout_ipfix(sc, PFLOW_NAT4);
1107 	CURVNET_RESTORE();
1108 }
1109 
1110 static void
pflow_flush(struct pflow_softc * sc)1111 pflow_flush(struct pflow_softc *sc)
1112 {
1113 	PFLOW_ASSERT(sc);
1114 
1115 	switch (sc->sc_version) {
1116 	case PFLOW_PROTO_5:
1117 		pflow_sendout_v5(sc);
1118 		break;
1119 	case PFLOW_PROTO_10:
1120 		pflow_sendout_ipfix(sc, PFLOW_INET);
1121 		pflow_sendout_ipfix(sc, PFLOW_INET6);
1122 		pflow_sendout_ipfix(sc, PFLOW_NAT4);
1123 		break;
1124 	default: /* NOTREACHED */
1125 		break;
1126 	}
1127 }
1128 
1129 static int
pflow_sendout_v5(struct pflow_softc * sc)1130 pflow_sendout_v5(struct pflow_softc *sc)
1131 {
1132 	struct mbuf		*m = sc->sc_mbuf;
1133 	struct pflow_header	*h;
1134 	struct timespec		tv;
1135 
1136 	PFLOW_ASSERT(sc);
1137 
1138 	if (m == NULL)
1139 		return (0);
1140 
1141 	sc->sc_mbuf = NULL;
1142 
1143 	pflowstat_inc(pflow_packets);
1144 	h = mtod(m, struct pflow_header *);
1145 	h->count = htons(sc->sc_count);
1146 
1147 	/* populate pflow_header */
1148 	h->uptime_ms = htonl(time_uptime * 1000);
1149 
1150 	getnanotime(&tv);
1151 	h->time_sec = htonl(tv.tv_sec);			/* XXX 2038 */
1152 	h->time_nanosec = htonl(tv.tv_nsec);
1153 	if (mbufq_enqueue(&sc->sc_outputqueue, m) == 0)
1154 		swi_sched(sc->sc_swi_cookie, 0);
1155 
1156 	return (0);
1157 }
1158 
1159 static int
pflow_sendout_ipfix(struct pflow_softc * sc,enum pflow_family_t af)1160 pflow_sendout_ipfix(struct pflow_softc *sc, enum pflow_family_t af)
1161 {
1162 	struct mbuf			*m;
1163 	struct pflow_v10_header		*h10;
1164 	struct pflow_set_header		*set_hdr;
1165 	u_int32_t			 count;
1166 	int				 set_length;
1167 
1168 	PFLOW_ASSERT(sc);
1169 
1170 	switch (af) {
1171 	case PFLOW_INET:
1172 		m = sc->sc_mbuf;
1173 		callout_stop(&sc->sc_tmo);
1174 		if (m == NULL)
1175 			return (0);
1176 		sc->sc_mbuf = NULL;
1177 		count = sc->sc_count4;
1178 		set_length = sizeof(struct pflow_set_header)
1179 		    + sc->sc_count4 * sizeof(struct pflow_ipfix_flow4);
1180 		break;
1181 	case PFLOW_INET6:
1182 		m = sc->sc_mbuf6;
1183 		callout_stop(&sc->sc_tmo6);
1184 		if (m == NULL)
1185 			return (0);
1186 		sc->sc_mbuf6 = NULL;
1187 		count = sc->sc_count6;
1188 		set_length = sizeof(struct pflow_set_header)
1189 		    + sc->sc_count6 * sizeof(struct pflow_ipfix_flow6);
1190 		break;
1191 	case PFLOW_NAT4:
1192 		m = sc->sc_mbuf_nat4;
1193 		callout_stop(&sc->sc_tmo_nat4);
1194 		if (m == NULL)
1195 			return (0);
1196 		sc->sc_mbuf_nat4 = NULL;
1197 		count = sc->sc_count_nat4;
1198 		set_length = sizeof(struct pflow_set_header)
1199 		    + sc->sc_count_nat4 * sizeof(struct pflow_ipfix_nat4);
1200 		break;
1201 	default:
1202 		panic("Unsupported AF %d", af);
1203 	}
1204 
1205 	pflowstat_inc(pflow_packets);
1206 
1207 	set_hdr = mtod(m, struct pflow_set_header *);
1208 	set_hdr->set_length = htons(set_length);
1209 
1210 	/* populate pflow_header */
1211 	M_PREPEND(m, sizeof(struct pflow_v10_header), M_NOWAIT);
1212 	if (m == NULL) {
1213 		pflowstat_inc(pflow_onomem);
1214 		return (ENOBUFS);
1215 	}
1216 	h10 = mtod(m, struct pflow_v10_header *);
1217 	h10->version = htons(PFLOW_PROTO_10);
1218 	h10->length = htons(PFLOW_IPFIX_HDRLEN + set_length);
1219 	h10->time_sec = htonl(time_second);		/* XXX 2038 */
1220 	h10->flow_sequence = htonl(sc->sc_sequence);
1221 	sc->sc_sequence += count;
1222 	h10->observation_dom = htonl(sc->sc_observation_dom);
1223 	if (mbufq_enqueue(&sc->sc_outputqueue, m) == 0)
1224 		swi_sched(sc->sc_swi_cookie, 0);
1225 
1226 	return (0);
1227 }
1228 
1229 static int
pflow_sendout_ipfix_tmpl(struct pflow_softc * sc)1230 pflow_sendout_ipfix_tmpl(struct pflow_softc *sc)
1231 {
1232 	struct mbuf			*m;
1233 	struct pflow_v10_header		*h10;
1234 
1235 	PFLOW_ASSERT(sc);
1236 
1237 	m = pflow_get_mbuf(sc, 0);
1238 	if (m == NULL)
1239 		return (0);
1240 	m_copyback(m, 0, sizeof(struct pflow_ipfix_tmpl),
1241 	    (caddr_t)&sc->sc_tmpl_ipfix);
1242 
1243 	pflowstat_inc(pflow_packets);
1244 
1245 	/* populate pflow_header */
1246 	M_PREPEND(m, sizeof(struct pflow_v10_header), M_NOWAIT);
1247 	if (m == NULL) {
1248 		pflowstat_inc(pflow_onomem);
1249 		return (ENOBUFS);
1250 	}
1251 	h10 = mtod(m, struct pflow_v10_header *);
1252 	h10->version = htons(PFLOW_PROTO_10);
1253 	h10->length = htons(PFLOW_IPFIX_HDRLEN + sizeof(struct
1254 	    pflow_ipfix_tmpl));
1255 	h10->time_sec = htonl(time_second);		/* XXX 2038 */
1256 	h10->flow_sequence = htonl(sc->sc_sequence);
1257 	h10->observation_dom = htonl(sc->sc_observation_dom);
1258 
1259 	callout_reset(&sc->sc_tmo_tmpl, PFLOW_TMPL_TIMEOUT * hz,
1260 	    pflow_timeout_tmpl, sc);
1261 	if (mbufq_enqueue(&sc->sc_outputqueue, m) == 0)
1262 		swi_sched(sc->sc_swi_cookie, 0);
1263 
1264 	return (0);
1265 }
1266 
1267 static int
pflow_sendout_mbuf(struct pflow_softc * sc,struct mbuf * m)1268 pflow_sendout_mbuf(struct pflow_softc *sc, struct mbuf *m)
1269 {
1270 	if (sc->so == NULL) {
1271 		m_freem(m);
1272 		return (EINVAL);
1273 	}
1274 	return (sosend(sc->so, sc->sc_flowdst, NULL, m, NULL, 0, curthread));
1275 }
1276 
1277 static int
sysctl_pflowstats(SYSCTL_HANDLER_ARGS)1278 sysctl_pflowstats(SYSCTL_HANDLER_ARGS)
1279 {
1280 	struct pflowstats pflowstats;
1281 
1282 	pflowstats.pflow_flows =
1283 	    counter_u64_fetch(V_pflowstats.c[pflow_flows]);
1284 	pflowstats.pflow_packets =
1285 	    counter_u64_fetch(V_pflowstats.c[pflow_packets]);
1286 	pflowstats.pflow_onomem =
1287 	    counter_u64_fetch(V_pflowstats.c[pflow_onomem]);
1288 	pflowstats.pflow_oerrors =
1289 	    counter_u64_fetch(V_pflowstats.c[pflow_oerrors]);
1290 
1291 	return (sysctl_handle_opaque(oidp, &pflowstats, sizeof(pflowstats), req));
1292 }
1293 
1294 static int
pflow_nl_list(struct nlmsghdr * hdr,struct nl_pstate * npt)1295 pflow_nl_list(struct nlmsghdr *hdr, struct nl_pstate *npt)
1296 {
1297 	struct epoch_tracker	 et;
1298 	struct pflow_softc	*sc = NULL;
1299 	struct nl_writer	 *nw = npt->nw;
1300 	int			 error = 0;
1301 
1302 	hdr->nlmsg_flags |= NLM_F_MULTI;
1303 
1304 	NET_EPOCH_ENTER(et);
1305 	CK_LIST_FOREACH(sc, &V_pflowif_list, sc_next) {
1306 		if (!nlmsg_reply(nw, hdr, sizeof(struct genlmsghdr))) {
1307 			error = ENOMEM;
1308 			goto out;
1309 		}
1310 
1311 		struct genlmsghdr *ghdr_new = nlmsg_reserve_object(nw, struct genlmsghdr);
1312 		ghdr_new->cmd = PFLOWNL_CMD_LIST;
1313 		ghdr_new->version = 0;
1314 		ghdr_new->reserved = 0;
1315 
1316 		nlattr_add_u32(nw, PFLOWNL_L_ID, sc->sc_id);
1317 
1318 		if (! nlmsg_end(nw)) {
1319 			error = ENOMEM;
1320 			goto out;
1321 		}
1322 	}
1323 
1324 out:
1325 	NET_EPOCH_EXIT(et);
1326 
1327 	if (error != 0)
1328 		nlmsg_abort(nw);
1329 
1330 	return (error);
1331 }
1332 
1333 static int
pflow_nl_create(struct nlmsghdr * hdr,struct nl_pstate * npt)1334 pflow_nl_create(struct nlmsghdr *hdr, struct nl_pstate *npt)
1335 {
1336 	struct nl_writer	 *nw = npt->nw;
1337 	int			 error = 0;
1338 	int			 unit;
1339 
1340 	if (! nlmsg_reply(nw, hdr, sizeof(struct genlmsghdr))) {
1341 		return (ENOMEM);
1342 	}
1343 
1344 	struct genlmsghdr *ghdr_new = nlmsg_reserve_object(nw, struct genlmsghdr);
1345 	ghdr_new->cmd = PFLOWNL_CMD_CREATE;
1346 	ghdr_new->version = 0;
1347 	ghdr_new->reserved = 0;
1348 
1349 	unit = alloc_unr(V_pflow_unr);
1350 	if (unit == -1) {
1351 		nlmsg_abort(nw);
1352 		return (ENOMEM);
1353 	}
1354 
1355 	error = pflow_create(unit);
1356 	if (error != 0) {
1357 		free_unr(V_pflow_unr, unit);
1358 		nlmsg_abort(nw);
1359 		return (error);
1360 	}
1361 
1362 	nlattr_add_s32(nw, PFLOWNL_CREATE_ID, unit);
1363 
1364 	if (! nlmsg_end(nw)) {
1365 		pflow_destroy(unit, true);
1366 		return (ENOMEM);
1367 	}
1368 
1369 	return (0);
1370 }
1371 
1372 struct pflow_parsed_del {
1373 	int id;
1374 };
1375 #define	_IN(_field)	offsetof(struct genlmsghdr, _field)
1376 #define	_OUT(_field)	offsetof(struct pflow_parsed_del, _field)
1377 static const struct nlattr_parser nla_p_del[] = {
1378 	{ .type = PFLOWNL_DEL_ID, .off = _OUT(id), .cb = nlattr_get_uint32 },
1379 };
1380 static const struct nlfield_parser nlf_p_del[] = {};
1381 #undef _IN
1382 #undef _OUT
1383 NL_DECLARE_PARSER(del_parser, struct genlmsghdr, nlf_p_del, nla_p_del);
1384 
1385 static int
pflow_nl_del(struct nlmsghdr * hdr,struct nl_pstate * npt)1386 pflow_nl_del(struct nlmsghdr *hdr, struct nl_pstate *npt)
1387 {
1388 	struct pflow_parsed_del d = {};
1389 	int error;
1390 
1391 	error = nl_parse_nlmsg(hdr, &del_parser, npt, &d);
1392 	if (error != 0)
1393 		return (error);
1394 
1395 	error = pflow_destroy(d.id, true);
1396 
1397 	return (error);
1398 }
1399 
1400 struct pflow_parsed_get {
1401 	int id;
1402 };
1403 #define	_IN(_field)	offsetof(struct genlmsghdr, _field)
1404 #define	_OUT(_field)	offsetof(struct pflow_parsed_get, _field)
1405 static const struct nlattr_parser nla_p_get[] = {
1406 	{ .type = PFLOWNL_GET_ID, .off = _OUT(id), .cb = nlattr_get_uint32 },
1407 };
1408 static const struct nlfield_parser nlf_p_get[] = {};
1409 #undef _IN
1410 #undef _OUT
1411 NL_DECLARE_PARSER(get_parser, struct genlmsghdr, nlf_p_get, nla_p_get);
1412 
1413 static bool
nlattr_add_sockaddr(struct nl_writer * nw,int attr,const struct sockaddr * s)1414 nlattr_add_sockaddr(struct nl_writer *nw, int attr, const struct sockaddr *s)
1415 {
1416 	int off = nlattr_add_nested(nw, attr);
1417 	if (off == 0)
1418 		return (false);
1419 
1420 	nlattr_add_u8(nw, PFLOWNL_ADDR_FAMILY, s->sa_family);
1421 
1422 	switch (s->sa_family) {
1423 	case AF_INET: {
1424 		const struct sockaddr_in *in = (const struct sockaddr_in *)s;
1425 		nlattr_add_u16(nw, PFLOWNL_ADDR_PORT, in->sin_port);
1426 		nlattr_add_in_addr(nw, PFLOWNL_ADDR_IP, &in->sin_addr);
1427 		break;
1428 	}
1429 	case AF_INET6: {
1430 		const struct sockaddr_in6 *in6 = (const struct sockaddr_in6 *)s;
1431 		nlattr_add_u16(nw, PFLOWNL_ADDR_PORT, in6->sin6_port);
1432 		nlattr_add_in6_addr(nw, PFLOWNL_ADDR_IP6, &in6->sin6_addr);
1433 		break;
1434 	}
1435 	default:
1436 		panic("Unknown address family %d", s->sa_family);
1437 	}
1438 
1439 	nlattr_set_len(nw, off);
1440 	return (true);
1441 }
1442 
1443 static int
pflow_nl_get(struct nlmsghdr * hdr,struct nl_pstate * npt)1444 pflow_nl_get(struct nlmsghdr *hdr, struct nl_pstate *npt)
1445 {
1446 	struct epoch_tracker et;
1447 	struct pflow_parsed_get g = {};
1448 	struct pflow_softc *sc = NULL;
1449 	struct nl_writer *nw = npt->nw;
1450 	struct genlmsghdr *ghdr_new;
1451 	int error;
1452 
1453 	error = nl_parse_nlmsg(hdr, &get_parser, npt, &g);
1454 	if (error != 0)
1455 		return (error);
1456 
1457 	NET_EPOCH_ENTER(et);
1458 	CK_LIST_FOREACH(sc, &V_pflowif_list, sc_next) {
1459 		if (sc->sc_id == g.id)
1460 			break;
1461 	}
1462 	if (sc == NULL) {
1463 		error = ENOENT;
1464 		goto out;
1465 	}
1466 
1467 	if (! nlmsg_reply(nw, hdr, sizeof(struct genlmsghdr))) {
1468 		nlmsg_abort(nw);
1469 		error = ENOMEM;
1470 		goto out;
1471 	}
1472 
1473 	ghdr_new = nlmsg_reserve_object(nw, struct genlmsghdr);
1474 	if (ghdr_new == NULL) {
1475 		nlmsg_abort(nw);
1476 		error = ENOMEM;
1477 		goto out;
1478 	}
1479 
1480 	ghdr_new->cmd = PFLOWNL_CMD_GET;
1481 	ghdr_new->version = 0;
1482 	ghdr_new->reserved = 0;
1483 
1484 	nlattr_add_u32(nw, PFLOWNL_GET_ID, sc->sc_id);
1485 	nlattr_add_u16(nw, PFLOWNL_GET_VERSION, sc->sc_version);
1486 	if (sc->sc_flowsrc)
1487 		nlattr_add_sockaddr(nw, PFLOWNL_GET_SRC, sc->sc_flowsrc);
1488 	if (sc->sc_flowdst)
1489 		nlattr_add_sockaddr(nw, PFLOWNL_GET_DST, sc->sc_flowdst);
1490 	nlattr_add_u32(nw, PFLOWNL_GET_OBSERVATION_DOMAIN,
1491 	    sc->sc_observation_dom);
1492 	nlattr_add_u8(nw, PFLOWNL_GET_SOCKET_STATUS, sc->so != NULL);
1493 
1494 	if (! nlmsg_end(nw)) {
1495 		nlmsg_abort(nw);
1496 		error = ENOMEM;
1497 	}
1498 
1499 out:
1500 	NET_EPOCH_EXIT(et);
1501 
1502 	return (error);
1503 }
1504 
1505 struct pflow_sockaddr {
1506 	union {
1507 		struct sockaddr_in in;
1508 		struct sockaddr_in6 in6;
1509 		struct sockaddr_storage storage;
1510 	};
1511 };
1512 static bool
pflow_postparse_sockaddr(void * parsed_args,struct nl_pstate * npt __unused)1513 pflow_postparse_sockaddr(void *parsed_args, struct nl_pstate *npt __unused)
1514 {
1515 	struct pflow_sockaddr *s = (struct pflow_sockaddr *)parsed_args;
1516 
1517 	if (s->storage.ss_family == AF_INET)
1518 		s->storage.ss_len = sizeof(struct sockaddr_in);
1519 	else if (s->storage.ss_family == AF_INET6)
1520 		s->storage.ss_len = sizeof(struct sockaddr_in6);
1521 	else
1522 		return (false);
1523 
1524 	return (true);
1525 }
1526 
1527 #define	_OUT(_field)	offsetof(struct pflow_sockaddr, _field)
1528 static struct nlattr_parser nla_p_sockaddr[] = {
1529 	{ .type = PFLOWNL_ADDR_FAMILY, .off = _OUT(in.sin_family), .cb = nlattr_get_uint8 },
1530 	{ .type = PFLOWNL_ADDR_PORT, .off = _OUT(in.sin_port), .cb = nlattr_get_uint16 },
1531 	{ .type = PFLOWNL_ADDR_IP, .off = _OUT(in.sin_addr), .cb = nlattr_get_in_addr },
1532 	{ .type = PFLOWNL_ADDR_IP6, .off = _OUT(in6.sin6_addr), .cb = nlattr_get_in6_addr },
1533 };
1534 NL_DECLARE_ATTR_PARSER_EXT(addr_parser, nla_p_sockaddr, pflow_postparse_sockaddr);
1535 #undef _OUT
1536 
1537 struct pflow_parsed_set {
1538 	int id;
1539 	uint16_t version;
1540 	struct sockaddr_storage src;
1541 	struct sockaddr_storage dst;
1542 	uint32_t observation_dom;
1543 };
1544 #define	_IN(_field)	offsetof(struct genlmsghdr, _field)
1545 #define	_OUT(_field)	offsetof(struct pflow_parsed_set, _field)
1546 static const struct nlattr_parser nla_p_set[] = {
1547 	{ .type = PFLOWNL_SET_ID, .off = _OUT(id), .cb = nlattr_get_uint32 },
1548 	{ .type = PFLOWNL_SET_VERSION, .off = _OUT(version), .cb = nlattr_get_uint16 },
1549 	{ .type = PFLOWNL_SET_SRC, .off = _OUT(src), .arg = &addr_parser, .cb = nlattr_get_nested },
1550 	{ .type = PFLOWNL_SET_DST, .off = _OUT(dst), .arg = &addr_parser, .cb = nlattr_get_nested },
1551 	{ .type = PFLOWNL_SET_OBSERVATION_DOMAIN, .off = _OUT(observation_dom), .cb = nlattr_get_uint32 },
1552 };
1553 static const struct nlfield_parser nlf_p_set[] = {};
1554 #undef _IN
1555 #undef _OUT
1556 NL_DECLARE_PARSER(set_parser, struct genlmsghdr, nlf_p_set, nla_p_set);
1557 
1558 static int
pflow_set(struct pflow_softc * sc,const struct pflow_parsed_set * pflowr,struct ucred * cred)1559 pflow_set(struct pflow_softc *sc, const struct pflow_parsed_set *pflowr, struct ucred *cred)
1560 {
1561 	struct thread		*td;
1562 	struct socket		*so;
1563 	int			 error = 0;
1564 
1565 	td = curthread;
1566 
1567 	PFLOW_ASSERT(sc);
1568 
1569 	if (pflowr->version != 0) {
1570 		switch(pflowr->version) {
1571 		case PFLOW_PROTO_5:
1572 		case PFLOW_PROTO_10:
1573 			break;
1574 		default:
1575 			return(EINVAL);
1576 		}
1577 	}
1578 
1579 	pflow_flush(sc);
1580 
1581 	if (pflowr->dst.ss_len != 0) {
1582 		if (sc->sc_flowdst != NULL &&
1583 		    sc->sc_flowdst->sa_family != pflowr->dst.ss_family) {
1584 			free(sc->sc_flowdst, M_DEVBUF);
1585 			sc->sc_flowdst = NULL;
1586 			if (sc->so != NULL) {
1587 				soclose(sc->so);
1588 				sc->so = NULL;
1589 			}
1590 		}
1591 
1592 		switch (pflowr->dst.ss_family) {
1593 		case AF_INET:
1594 			if (sc->sc_flowdst == NULL) {
1595 				if ((sc->sc_flowdst = malloc(
1596 				    sizeof(struct sockaddr_in),
1597 				    M_DEVBUF,  M_NOWAIT)) == NULL)
1598 					return (ENOMEM);
1599 			}
1600 			memcpy(sc->sc_flowdst, &pflowr->dst,
1601 			    sizeof(struct sockaddr_in));
1602 			sc->sc_flowdst->sa_len = sizeof(struct
1603 			    sockaddr_in);
1604 			break;
1605 		case AF_INET6:
1606 			if (sc->sc_flowdst == NULL) {
1607 				if ((sc->sc_flowdst = malloc(
1608 				    sizeof(struct sockaddr_in6),
1609 				    M_DEVBUF, M_NOWAIT)) == NULL)
1610 					return (ENOMEM);
1611 			}
1612 			memcpy(sc->sc_flowdst, &pflowr->dst,
1613 			    sizeof(struct sockaddr_in6));
1614 			sc->sc_flowdst->sa_len = sizeof(struct
1615 			    sockaddr_in6);
1616 			break;
1617 		default:
1618 			break;
1619 		}
1620 	}
1621 
1622 	if (pflowr->src.ss_len != 0) {
1623 		if (sc->sc_flowsrc != NULL)
1624 			free(sc->sc_flowsrc, M_DEVBUF);
1625 		sc->sc_flowsrc = NULL;
1626 		if (sc->so != NULL) {
1627 			soclose(sc->so);
1628 			sc->so = NULL;
1629 		}
1630 		switch(pflowr->src.ss_family) {
1631 		case AF_INET:
1632 			if ((sc->sc_flowsrc = malloc(
1633 			    sizeof(struct sockaddr_in),
1634 			    M_DEVBUF, M_NOWAIT)) == NULL)
1635 				return (ENOMEM);
1636 			memcpy(sc->sc_flowsrc, &pflowr->src,
1637 			    sizeof(struct sockaddr_in));
1638 			sc->sc_flowsrc->sa_len = sizeof(struct
1639 			    sockaddr_in);
1640 			break;
1641 		case AF_INET6:
1642 			if ((sc->sc_flowsrc = malloc(
1643 			    sizeof(struct sockaddr_in6),
1644 			    M_DEVBUF, M_NOWAIT)) == NULL)
1645 				return (ENOMEM);
1646 			memcpy(sc->sc_flowsrc, &pflowr->src,
1647 			    sizeof(struct sockaddr_in6));
1648 			sc->sc_flowsrc->sa_len = sizeof(struct
1649 			    sockaddr_in6);
1650 			break;
1651 		default:
1652 			break;
1653 		}
1654 	}
1655 
1656 	if (sc->so == NULL) {
1657 		if (pflowvalidsockaddr(sc->sc_flowdst, 0)) {
1658 			error = socreate(sc->sc_flowdst->sa_family,
1659 			    &so, SOCK_DGRAM, IPPROTO_UDP, cred, td);
1660 			if (error)
1661 				return (error);
1662 			if (pflowvalidsockaddr(sc->sc_flowsrc, 1)) {
1663 				error = sobind(so, sc->sc_flowsrc, td);
1664 				if (error) {
1665 					soclose(so);
1666 					return (error);
1667 				}
1668 			}
1669 			sc->so = so;
1670 		}
1671 	} else if (!pflowvalidsockaddr(sc->sc_flowdst, 0)) {
1672 		soclose(sc->so);
1673 		sc->so = NULL;
1674 	}
1675 
1676 	if (pflowr->observation_dom != 0)
1677 		sc->sc_observation_dom = pflowr->observation_dom;
1678 
1679 	/* error check is above */
1680 	if (pflowr->version != 0)
1681 		sc->sc_version = pflowr->version;
1682 
1683 	pflow_setmtu(sc, ETHERMTU);
1684 
1685 	switch (sc->sc_version) {
1686 	case PFLOW_PROTO_5:
1687 		callout_stop(&sc->sc_tmo6);
1688 		callout_stop(&sc->sc_tmo_tmpl);
1689 		break;
1690 	case PFLOW_PROTO_10:
1691 		callout_reset(&sc->sc_tmo_tmpl, PFLOW_TMPL_TIMEOUT * hz,
1692 		    pflow_timeout_tmpl, sc);
1693 		break;
1694 	default: /* NOTREACHED */
1695 		break;
1696 	}
1697 
1698 	return (0);
1699 }
1700 
1701 static int
pflow_nl_set(struct nlmsghdr * hdr,struct nl_pstate * npt)1702 pflow_nl_set(struct nlmsghdr *hdr, struct nl_pstate *npt)
1703 {
1704 	struct epoch_tracker et;
1705 	struct pflow_parsed_set s = {};
1706 	struct pflow_softc *sc = NULL;
1707 	int error;
1708 
1709 	error = nl_parse_nlmsg(hdr, &set_parser, npt, &s);
1710 	if (error != 0)
1711 		return (error);
1712 
1713 	NET_EPOCH_ENTER(et);
1714 	CK_LIST_FOREACH(sc, &V_pflowif_list, sc_next) {
1715 		if (sc->sc_id == s.id)
1716 			break;
1717 	}
1718 	if (sc == NULL) {
1719 		error = ENOENT;
1720 		goto out;
1721 	}
1722 
1723 	PFLOW_LOCK(sc);
1724 	error = pflow_set(sc, &s, nlp_get_cred(npt->nlp));
1725 	PFLOW_UNLOCK(sc);
1726 
1727 out:
1728 	NET_EPOCH_EXIT(et);
1729 	return (error);
1730 }
1731 
1732 static const struct genl_cmd pflow_cmds[] = {
1733 	{
1734 		.cmd_num = PFLOWNL_CMD_LIST,
1735 		.cmd_name = "LIST",
1736 		.cmd_cb = pflow_nl_list,
1737 		.cmd_flags = GENL_CMD_CAP_DO | GENL_CMD_CAP_DUMP | GENL_CMD_CAP_HASPOL,
1738 		.cmd_priv = PRIV_NETINET_PF,
1739 	},
1740 	{
1741 		.cmd_num = PFLOWNL_CMD_CREATE,
1742 		.cmd_name = "CREATE",
1743 		.cmd_cb = pflow_nl_create,
1744 		.cmd_flags = GENL_CMD_CAP_DO | GENL_CMD_CAP_DUMP | GENL_CMD_CAP_HASPOL,
1745 		.cmd_priv = PRIV_NETINET_PF,
1746 	},
1747 	{
1748 		.cmd_num = PFLOWNL_CMD_DEL,
1749 		.cmd_name = "DEL",
1750 		.cmd_cb = pflow_nl_del,
1751 		.cmd_flags = GENL_CMD_CAP_DO | GENL_CMD_CAP_DUMP | GENL_CMD_CAP_HASPOL,
1752 		.cmd_priv = PRIV_NETINET_PF,
1753 	},
1754 	{
1755 		.cmd_num = PFLOWNL_CMD_GET,
1756 		.cmd_name = "GET",
1757 		.cmd_cb = pflow_nl_get,
1758 		.cmd_flags = GENL_CMD_CAP_DUMP | GENL_CMD_CAP_HASPOL,
1759 		.cmd_priv = PRIV_NETINET_PF,
1760 	},
1761 	{
1762 		.cmd_num = PFLOWNL_CMD_SET,
1763 		.cmd_name = "SET",
1764 		.cmd_cb = pflow_nl_set,
1765 		.cmd_flags = GENL_CMD_CAP_DO | GENL_CMD_CAP_DUMP | GENL_CMD_CAP_HASPOL,
1766 		.cmd_priv = PRIV_NETINET_PF,
1767 	},
1768 };
1769 
1770 static const struct nlhdr_parser *all_parsers[] = {
1771 	&del_parser,
1772 	&get_parser,
1773 	&set_parser,
1774 };
1775 
1776 static int
pflow_init(void)1777 pflow_init(void)
1778 {
1779 	bool ret;
1780 	int family_id __diagused;
1781 
1782 	NL_VERIFY_PARSERS(all_parsers);
1783 
1784 	family_id = genl_register_family(PFLOWNL_FAMILY_NAME, 0, 2, PFLOWNL_CMD_MAX);
1785 	MPASS(family_id != 0);
1786 	ret = genl_register_cmds(PFLOWNL_FAMILY_NAME, pflow_cmds, NL_ARRAY_LEN(pflow_cmds));
1787 
1788 	return (ret ? 0 : ENODEV);
1789 }
1790 
1791 static void
pflow_uninit(void)1792 pflow_uninit(void)
1793 {
1794 	genl_unregister_family(PFLOWNL_FAMILY_NAME);
1795 }
1796 
1797 static int
pflow_modevent(module_t mod,int type,void * data)1798 pflow_modevent(module_t mod, int type, void *data)
1799 {
1800 	int error = 0;
1801 
1802 	switch (type) {
1803 	case MOD_LOAD:
1804 		error = pflow_init();
1805 		break;
1806 	case MOD_UNLOAD:
1807 		pflow_uninit();
1808 		break;
1809 	default:
1810 		error = EINVAL;
1811 		break;
1812 	}
1813 
1814 	return (error);
1815 }
1816 
1817 static moduledata_t pflow_mod = {
1818 	pflowname,
1819 	pflow_modevent,
1820 	0
1821 };
1822 
1823 DECLARE_MODULE(pflow, pflow_mod, SI_SUB_PROTO_FIREWALL, SI_ORDER_ANY);
1824 MODULE_VERSION(pflow, 1);
1825 MODULE_DEPEND(pflow, pf, PF_MODVER, PF_MODVER, PF_MODVER);
1826