1/*	$OpenBSD: if_pflow.c,v 1.109 2023/12/23 10:52:54 bluhm Exp $	*/
2
3/*
4 * Copyright (c) 2011 Florian Obser <florian@narrans.de>
5 * Copyright (c) 2011 Sebastian Benoit <benoit-lists@fb12.de>
6 * Copyright (c) 2008 Henning Brauer <henning@openbsd.org>
7 * Copyright (c) 2008 Joerg Goltermann <jg@osn.de>
8 *
9 * Permission to use, copy, modify, and distribute this software for any
10 * purpose with or without fee is hereby granted, provided that the above
11 * copyright notice and this permission notice appear in all copies.
12 *
13 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
14 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
16 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
18 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
19 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 */
21
22#include <sys/param.h>
23#include <sys/malloc.h>
24#include <sys/systm.h>
25#include <sys/mbuf.h>
26#include <sys/socket.h>
27#include <sys/timeout.h>
28#include <sys/ioctl.h>
29#include <sys/kernel.h>
30#include <sys/socketvar.h>
31#include <sys/sysctl.h>
32#include <sys/mutex.h>
33
34#include <net/if.h>
35#include <net/if_types.h>
36#include <net/bpf.h>
37#include <net/route.h>
38#include <netinet/in.h>
39#include <netinet/if_ether.h>
40#include <netinet/tcp.h>
41
42#include <netinet/ip.h>
43#include <netinet/ip_icmp.h>
44#include <netinet/ip_var.h>
45#include <netinet/udp.h>
46#include <netinet/udp_var.h>
47#include <netinet/in_pcb.h>
48
49#include <net/pfvar.h>
50#include <net/pfvar_priv.h>
51#include <net/if_pflow.h>
52
53#include "bpfilter.h"
54#include "pflow.h"
55
56#define PFLOW_MINMTU	\
57    (sizeof(struct pflow_header) + sizeof(struct pflow_flow))
58
59#ifdef PFLOWDEBUG
60#define DPRINTF(x)	do { printf x ; } while (0)
61#else
62#define DPRINTF(x)
63#endif
64
65SMR_SLIST_HEAD(, pflow_softc) pflowif_list;
66
67enum pflowstat_counters {
68	pflow_flows,
69	pflow_packets,
70	pflow_onomem,
71	pflow_oerrors,
72	pflow_ncounters,
73};
74
75struct cpumem *pflow_counters;
76
77static inline void
78pflowstat_inc(enum pflowstat_counters c)
79{
80	counters_inc(pflow_counters, c);
81}
82
83void	pflowattach(int);
84int	pflow_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
85	struct rtentry *rt);
86void	pflow_output_process(void *);
87int	pflow_clone_create(struct if_clone *, int);
88int	pflow_clone_destroy(struct ifnet *);
89int	pflow_set(struct pflow_softc *, struct pflowreq *);
90int	pflow_calc_mtu(struct pflow_softc *, int, int);
91void	pflow_setmtu(struct pflow_softc *, int);
92int	pflowvalidsockaddr(const struct sockaddr *, int);
93int	pflowioctl(struct ifnet *, u_long, caddr_t);
94
95struct mbuf	*pflow_get_mbuf(struct pflow_softc *, u_int16_t);
96void	pflow_flush(struct pflow_softc *);
97int	pflow_sendout_v5(struct pflow_softc *);
98int	pflow_sendout_ipfix(struct pflow_softc *, sa_family_t);
99int	pflow_sendout_ipfix_tmpl(struct pflow_softc *);
100int	pflow_sendout_mbuf(struct pflow_softc *, struct mbuf *);
101void	pflow_timeout(void *);
102void	pflow_timeout6(void *);
103void	pflow_timeout_tmpl(void *);
104void	copy_flow_data(struct pflow_flow *, struct pflow_flow *,
105	struct pf_state *, struct pf_state_key *, int, int);
106void	copy_flow_ipfix_4_data(struct pflow_ipfix_flow4 *,
107	struct pflow_ipfix_flow4 *, struct pf_state *, struct pf_state_key *,
108	struct pflow_softc *, int, int);
109void	copy_flow_ipfix_6_data(struct pflow_ipfix_flow6 *,
110	struct pflow_ipfix_flow6 *, struct pf_state *, struct pf_state_key *,
111	struct pflow_softc *, int, int);
112int	pflow_pack_flow(struct pf_state *, struct pf_state_key *,
113	struct pflow_softc *);
114int	pflow_pack_flow_ipfix(struct pf_state *, struct pf_state_key *,
115	struct pflow_softc *);
116int	export_pflow_if(struct pf_state*, struct pf_state_key *,
117	struct pflow_softc *);
118int	copy_flow_to_m(struct pflow_flow *flow, struct pflow_softc *sc);
119int	copy_flow_ipfix_4_to_m(struct pflow_ipfix_flow4 *flow,
120	struct pflow_softc *sc);
121int	copy_flow_ipfix_6_to_m(struct pflow_ipfix_flow6 *flow,
122	struct pflow_softc *sc);
123
124struct if_clone	pflow_cloner =
125    IF_CLONE_INITIALIZER("pflow", pflow_clone_create,
126    pflow_clone_destroy);
127
128void
129pflowattach(int npflow)
130{
131	SMR_SLIST_INIT(&pflowif_list);
132	pflow_counters = counters_alloc(pflow_ncounters);
133	if_clone_attach(&pflow_cloner);
134}
135
136int
137pflow_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
138	struct rtentry *rt)
139{
140	m_freem(m);	/* drop packet */
141	return (EAFNOSUPPORT);
142}
143
144void
145pflow_output_process(void *arg)
146{
147	struct mbuf_list ml;
148	struct pflow_softc *sc = arg;
149	struct mbuf *m;
150
151	mq_delist(&sc->sc_outputqueue, &ml);
152	rw_enter_read(&sc->sc_lock);
153	while ((m = ml_dequeue(&ml)) != NULL) {
154		pflow_sendout_mbuf(sc, m);
155	}
156	rw_exit_read(&sc->sc_lock);
157}
158
159int
160pflow_clone_create(struct if_clone *ifc, int unit)
161{
162	struct ifnet		*ifp;
163	struct pflow_softc	*pflowif;
164
165	pflowif = malloc(sizeof(*pflowif), M_DEVBUF, M_WAITOK|M_ZERO);
166	rw_init(&pflowif->sc_lock, "pflowlk");
167	mtx_init(&pflowif->sc_mtx, IPL_MPFLOOR);
168	MGET(pflowif->send_nam, M_WAIT, MT_SONAME);
169	pflowif->sc_version = PFLOW_PROTO_DEFAULT;
170
171	/* ipfix template init */
172	bzero(&pflowif->sc_tmpl_ipfix,sizeof(pflowif->sc_tmpl_ipfix));
173	pflowif->sc_tmpl_ipfix.set_header.set_id =
174	    htons(PFLOW_IPFIX_TMPL_SET_ID);
175	pflowif->sc_tmpl_ipfix.set_header.set_length =
176	    htons(sizeof(struct pflow_ipfix_tmpl));
177
178	/* ipfix IPv4 template */
179	pflowif->sc_tmpl_ipfix.ipv4_tmpl.h.tmpl_id =
180	    htons(PFLOW_IPFIX_TMPL_IPV4_ID);
181	pflowif->sc_tmpl_ipfix.ipv4_tmpl.h.field_count
182	    = htons(PFLOW_IPFIX_TMPL_IPV4_FIELD_COUNT);
183	pflowif->sc_tmpl_ipfix.ipv4_tmpl.src_ip.field_id =
184	    htons(PFIX_IE_sourceIPv4Address);
185	pflowif->sc_tmpl_ipfix.ipv4_tmpl.src_ip.len = htons(4);
186	pflowif->sc_tmpl_ipfix.ipv4_tmpl.dest_ip.field_id =
187	    htons(PFIX_IE_destinationIPv4Address);
188	pflowif->sc_tmpl_ipfix.ipv4_tmpl.dest_ip.len = htons(4);
189	pflowif->sc_tmpl_ipfix.ipv4_tmpl.if_index_in.field_id =
190	    htons(PFIX_IE_ingressInterface);
191	pflowif->sc_tmpl_ipfix.ipv4_tmpl.if_index_in.len = htons(4);
192	pflowif->sc_tmpl_ipfix.ipv4_tmpl.if_index_out.field_id =
193	    htons(PFIX_IE_egressInterface);
194	pflowif->sc_tmpl_ipfix.ipv4_tmpl.if_index_out.len = htons(4);
195	pflowif->sc_tmpl_ipfix.ipv4_tmpl.packets.field_id =
196	    htons(PFIX_IE_packetDeltaCount);
197	pflowif->sc_tmpl_ipfix.ipv4_tmpl.packets.len = htons(8);
198	pflowif->sc_tmpl_ipfix.ipv4_tmpl.octets.field_id =
199	    htons(PFIX_IE_octetDeltaCount);
200	pflowif->sc_tmpl_ipfix.ipv4_tmpl.octets.len = htons(8);
201	pflowif->sc_tmpl_ipfix.ipv4_tmpl.start.field_id =
202	    htons(PFIX_IE_flowStartMilliseconds);
203	pflowif->sc_tmpl_ipfix.ipv4_tmpl.start.len = htons(8);
204	pflowif->sc_tmpl_ipfix.ipv4_tmpl.finish.field_id =
205	    htons(PFIX_IE_flowEndMilliseconds);
206	pflowif->sc_tmpl_ipfix.ipv4_tmpl.finish.len = htons(8);
207	pflowif->sc_tmpl_ipfix.ipv4_tmpl.src_port.field_id =
208	    htons(PFIX_IE_sourceTransportPort);
209	pflowif->sc_tmpl_ipfix.ipv4_tmpl.src_port.len = htons(2);
210	pflowif->sc_tmpl_ipfix.ipv4_tmpl.dest_port.field_id =
211	    htons(PFIX_IE_destinationTransportPort);
212	pflowif->sc_tmpl_ipfix.ipv4_tmpl.dest_port.len = htons(2);
213	pflowif->sc_tmpl_ipfix.ipv4_tmpl.tos.field_id =
214	    htons(PFIX_IE_ipClassOfService);
215	pflowif->sc_tmpl_ipfix.ipv4_tmpl.tos.len = htons(1);
216	pflowif->sc_tmpl_ipfix.ipv4_tmpl.protocol.field_id =
217	    htons(PFIX_IE_protocolIdentifier);
218	pflowif->sc_tmpl_ipfix.ipv4_tmpl.protocol.len = htons(1);
219
220	/* ipfix IPv6 template */
221	pflowif->sc_tmpl_ipfix.ipv6_tmpl.h.tmpl_id =
222	    htons(PFLOW_IPFIX_TMPL_IPV6_ID);
223	pflowif->sc_tmpl_ipfix.ipv6_tmpl.h.field_count =
224	    htons(PFLOW_IPFIX_TMPL_IPV6_FIELD_COUNT);
225	pflowif->sc_tmpl_ipfix.ipv6_tmpl.src_ip.field_id =
226	    htons(PFIX_IE_sourceIPv6Address);
227	pflowif->sc_tmpl_ipfix.ipv6_tmpl.src_ip.len = htons(16);
228	pflowif->sc_tmpl_ipfix.ipv6_tmpl.dest_ip.field_id =
229	    htons(PFIX_IE_destinationIPv6Address);
230	pflowif->sc_tmpl_ipfix.ipv6_tmpl.dest_ip.len = htons(16);
231	pflowif->sc_tmpl_ipfix.ipv6_tmpl.if_index_in.field_id =
232	    htons(PFIX_IE_ingressInterface);
233	pflowif->sc_tmpl_ipfix.ipv6_tmpl.if_index_in.len = htons(4);
234	pflowif->sc_tmpl_ipfix.ipv6_tmpl.if_index_out.field_id =
235	    htons(PFIX_IE_egressInterface);
236	pflowif->sc_tmpl_ipfix.ipv6_tmpl.if_index_out.len = htons(4);
237	pflowif->sc_tmpl_ipfix.ipv6_tmpl.packets.field_id =
238	    htons(PFIX_IE_packetDeltaCount);
239	pflowif->sc_tmpl_ipfix.ipv6_tmpl.packets.len = htons(8);
240	pflowif->sc_tmpl_ipfix.ipv6_tmpl.octets.field_id =
241	    htons(PFIX_IE_octetDeltaCount);
242	pflowif->sc_tmpl_ipfix.ipv6_tmpl.octets.len = htons(8);
243	pflowif->sc_tmpl_ipfix.ipv6_tmpl.start.field_id =
244	    htons(PFIX_IE_flowStartMilliseconds);
245	pflowif->sc_tmpl_ipfix.ipv6_tmpl.start.len = htons(8);
246	pflowif->sc_tmpl_ipfix.ipv6_tmpl.finish.field_id =
247	    htons(PFIX_IE_flowEndMilliseconds);
248	pflowif->sc_tmpl_ipfix.ipv6_tmpl.finish.len = htons(8);
249	pflowif->sc_tmpl_ipfix.ipv6_tmpl.src_port.field_id =
250	    htons(PFIX_IE_sourceTransportPort);
251	pflowif->sc_tmpl_ipfix.ipv6_tmpl.src_port.len = htons(2);
252	pflowif->sc_tmpl_ipfix.ipv6_tmpl.dest_port.field_id =
253	    htons(PFIX_IE_destinationTransportPort);
254	pflowif->sc_tmpl_ipfix.ipv6_tmpl.dest_port.len = htons(2);
255	pflowif->sc_tmpl_ipfix.ipv6_tmpl.tos.field_id =
256	    htons(PFIX_IE_ipClassOfService);
257	pflowif->sc_tmpl_ipfix.ipv6_tmpl.tos.len = htons(1);
258	pflowif->sc_tmpl_ipfix.ipv6_tmpl.protocol.field_id =
259	    htons(PFIX_IE_protocolIdentifier);
260	pflowif->sc_tmpl_ipfix.ipv6_tmpl.protocol.len = htons(1);
261
262	ifp = &pflowif->sc_if;
263	snprintf(ifp->if_xname, sizeof ifp->if_xname, "pflow%d", unit);
264	ifp->if_softc = pflowif;
265	ifp->if_ioctl = pflowioctl;
266	ifp->if_output = pflow_output;
267	ifp->if_start = NULL;
268	ifp->if_xflags = IFXF_CLONED;
269	ifp->if_type = IFT_PFLOW;
270	ifp->if_hdrlen = PFLOW_HDRLEN;
271	ifp->if_flags = IFF_UP;
272	ifp->if_flags &= ~IFF_RUNNING;	/* not running, need receiver */
273	mq_init(&pflowif->sc_outputqueue, 8192, IPL_SOFTNET);
274	pflow_setmtu(pflowif, ETHERMTU);
275
276	timeout_set_proc(&pflowif->sc_tmo, pflow_timeout, pflowif);
277	timeout_set_proc(&pflowif->sc_tmo6, pflow_timeout6, pflowif);
278	timeout_set_proc(&pflowif->sc_tmo_tmpl, pflow_timeout_tmpl, pflowif);
279
280	task_set(&pflowif->sc_outputtask, pflow_output_process, pflowif);
281
282	if_counters_alloc(ifp);
283	if_attach(ifp);
284	if_alloc_sadl(ifp);
285
286	/* Insert into list of pflows */
287	KERNEL_ASSERT_LOCKED();
288	SMR_SLIST_INSERT_HEAD_LOCKED(&pflowif_list, pflowif, sc_next);
289	return (0);
290}
291
292int
293pflow_clone_destroy(struct ifnet *ifp)
294{
295	struct pflow_softc	*sc = ifp->if_softc;
296	int			 error;
297
298	error = 0;
299
300	rw_enter_write(&sc->sc_lock);
301	sc->sc_dying = 1;
302	rw_exit_write(&sc->sc_lock);
303
304	KERNEL_ASSERT_LOCKED();
305	SMR_SLIST_REMOVE_LOCKED(&pflowif_list, sc, pflow_softc, sc_next);
306	smr_barrier();
307
308	timeout_del(&sc->sc_tmo);
309	timeout_del(&sc->sc_tmo6);
310	timeout_del(&sc->sc_tmo_tmpl);
311
312	pflow_flush(sc);
313	task_del(net_tq(ifp->if_index), &sc->sc_outputtask);
314	taskq_barrier(net_tq(ifp->if_index));
315	mq_purge(&sc->sc_outputqueue);
316	m_freem(sc->send_nam);
317	if (sc->so != NULL) {
318		error = soclose(sc->so, MSG_DONTWAIT);
319		sc->so = NULL;
320	}
321	if (sc->sc_flowdst != NULL)
322		free(sc->sc_flowdst, M_DEVBUF, sc->sc_flowdst->sa_len);
323	if (sc->sc_flowsrc != NULL)
324		free(sc->sc_flowsrc, M_DEVBUF, sc->sc_flowsrc->sa_len);
325	if_detach(ifp);
326	free(sc, M_DEVBUF, sizeof(*sc));
327	return (error);
328}
329
330int
331pflowvalidsockaddr(const struct sockaddr *sa, int ignore_port)
332{
333	struct sockaddr_in6	*sin6;
334	struct sockaddr_in	*sin;
335
336	if (sa == NULL)
337		return (0);
338	switch(sa->sa_family) {
339	case AF_INET:
340		sin = (struct sockaddr_in*) sa;
341		return (sin->sin_addr.s_addr != INADDR_ANY &&
342		    (ignore_port || sin->sin_port != 0));
343	case AF_INET6:
344		sin6 = (struct sockaddr_in6*) sa;
345		return (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr) &&
346		    (ignore_port || sin6->sin6_port != 0));
347	default:
348		return (0);
349	}
350}
351
352int
353pflow_set(struct pflow_softc *sc, struct pflowreq *pflowr)
354{
355	struct proc		*p = curproc;
356	struct socket		*so;
357	struct sockaddr		*sa;
358	int			 error = 0;
359
360	if (pflowr->addrmask & PFLOW_MASK_VERSION) {
361		switch(pflowr->version) {
362		case PFLOW_PROTO_5:
363		case PFLOW_PROTO_10:
364			break;
365		default:
366			return(EINVAL);
367		}
368	}
369
370	rw_assert_wrlock(&sc->sc_lock);
371
372	pflow_flush(sc);
373
374	if (pflowr->addrmask & PFLOW_MASK_DSTIP) {
375		if (sc->sc_flowdst != NULL &&
376		    sc->sc_flowdst->sa_family != pflowr->flowdst.ss_family) {
377			free(sc->sc_flowdst, M_DEVBUF, sc->sc_flowdst->sa_len);
378			sc->sc_flowdst = NULL;
379			if (sc->so != NULL) {
380				soclose(sc->so, MSG_DONTWAIT);
381				sc->so = NULL;
382			}
383		}
384
385		switch (pflowr->flowdst.ss_family) {
386		case AF_INET:
387			if (sc->sc_flowdst == NULL) {
388				if ((sc->sc_flowdst = malloc(
389				    sizeof(struct sockaddr_in),
390				    M_DEVBUF,  M_NOWAIT)) == NULL)
391					return (ENOMEM);
392			}
393			memcpy(sc->sc_flowdst, &pflowr->flowdst,
394			    sizeof(struct sockaddr_in));
395			sc->sc_flowdst->sa_len = sizeof(struct
396			    sockaddr_in);
397			break;
398		case AF_INET6:
399			if (sc->sc_flowdst == NULL) {
400				if ((sc->sc_flowdst = malloc(
401				    sizeof(struct sockaddr_in6),
402				    M_DEVBUF, M_NOWAIT)) == NULL)
403					return (ENOMEM);
404			}
405			memcpy(sc->sc_flowdst, &pflowr->flowdst,
406			    sizeof(struct sockaddr_in6));
407			sc->sc_flowdst->sa_len = sizeof(struct
408			    sockaddr_in6);
409			break;
410		default:
411			break;
412		}
413
414		if (sc->sc_flowdst != NULL) {
415			sc->send_nam->m_len = sc->sc_flowdst->sa_len;
416			sa = mtod(sc->send_nam, struct sockaddr *);
417			memcpy(sa, sc->sc_flowdst, sc->sc_flowdst->sa_len);
418		}
419	}
420
421	if (pflowr->addrmask & PFLOW_MASK_SRCIP) {
422		if (sc->sc_flowsrc != NULL)
423			free(sc->sc_flowsrc, M_DEVBUF, sc->sc_flowsrc->sa_len);
424		sc->sc_flowsrc = NULL;
425		if (sc->so != NULL) {
426			soclose(sc->so, MSG_DONTWAIT);
427			sc->so = NULL;
428		}
429		switch(pflowr->flowsrc.ss_family) {
430		case AF_INET:
431			if ((sc->sc_flowsrc = malloc(
432			    sizeof(struct sockaddr_in),
433			    M_DEVBUF, M_NOWAIT)) == NULL)
434				return (ENOMEM);
435			memcpy(sc->sc_flowsrc, &pflowr->flowsrc,
436			    sizeof(struct sockaddr_in));
437			sc->sc_flowsrc->sa_len = sizeof(struct
438			    sockaddr_in);
439			break;
440		case AF_INET6:
441			if ((sc->sc_flowsrc = malloc(
442			    sizeof(struct sockaddr_in6),
443			    M_DEVBUF, M_NOWAIT)) == NULL)
444				return (ENOMEM);
445			memcpy(sc->sc_flowsrc, &pflowr->flowsrc,
446			    sizeof(struct sockaddr_in6));
447			sc->sc_flowsrc->sa_len = sizeof(struct
448			    sockaddr_in6);
449			break;
450		default:
451			break;
452		}
453	}
454
455	if (sc->so == NULL) {
456		if (pflowvalidsockaddr(sc->sc_flowdst, 0)) {
457			error = socreate(sc->sc_flowdst->sa_family,
458			    &so, SOCK_DGRAM, 0);
459			if (error)
460				return (error);
461			if (pflowvalidsockaddr(sc->sc_flowsrc, 1)) {
462				struct mbuf *m;
463
464				MGET(m, M_WAIT, MT_SONAME);
465				m->m_len = sc->sc_flowsrc->sa_len;
466				sa = mtod(m, struct sockaddr *);
467				memcpy(sa, sc->sc_flowsrc,
468				    sc->sc_flowsrc->sa_len);
469
470				solock(so);
471				error = sobind(so, m, p);
472				sounlock(so);
473				m_freem(m);
474				if (error) {
475					soclose(so, MSG_DONTWAIT);
476					return (error);
477				}
478			}
479			sc->so = so;
480		}
481	} else if (!pflowvalidsockaddr(sc->sc_flowdst, 0)) {
482		soclose(sc->so, MSG_DONTWAIT);
483		sc->so = NULL;
484	}
485
486	NET_LOCK();
487	mtx_enter(&sc->sc_mtx);
488
489	/* error check is above */
490	if (pflowr->addrmask & PFLOW_MASK_VERSION)
491		sc->sc_version = pflowr->version;
492
493	pflow_setmtu(sc, ETHERMTU);
494
495	switch (sc->sc_version) {
496	case PFLOW_PROTO_5:
497		timeout_del(&sc->sc_tmo6);
498		timeout_del(&sc->sc_tmo_tmpl);
499		break;
500	case PFLOW_PROTO_10:
501		timeout_add_sec(&sc->sc_tmo_tmpl, PFLOW_TMPL_TIMEOUT);
502		break;
503	default: /* NOTREACHED */
504		break;
505	}
506
507	mtx_leave(&sc->sc_mtx);
508	NET_UNLOCK();
509
510	return (0);
511}
512
513int
514pflowioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
515{
516	struct proc		*p = curproc;
517	struct pflow_softc	*sc = ifp->if_softc;
518	struct ifreq		*ifr = (struct ifreq *)data;
519	struct pflowreq		 pflowr;
520	int			 error = 0;
521
522	switch (cmd) {
523	case SIOCSIFADDR:
524	case SIOCSIFDSTADDR:
525	case SIOCSIFFLAGS:
526	case SIOCSIFMTU:
527	case SIOCGETPFLOW:
528	case SIOCSETPFLOW:
529		break;
530	default:
531		return (ENOTTY);
532	}
533
534	/* XXXSMP: enforce lock order */
535	NET_UNLOCK();
536	rw_enter_write(&sc->sc_lock);
537
538	if (sc->sc_dying) {
539		error = ENXIO;
540		goto out;
541	}
542
543	switch (cmd) {
544	case SIOCSIFADDR:
545	case SIOCSIFDSTADDR:
546	case SIOCSIFFLAGS:
547		NET_LOCK();
548		if ((ifp->if_flags & IFF_UP) && sc->so != NULL) {
549			ifp->if_flags |= IFF_RUNNING;
550			mtx_enter(&sc->sc_mtx);
551			/* send templates on startup */
552			if (sc->sc_version == PFLOW_PROTO_10)
553				pflow_sendout_ipfix_tmpl(sc);
554			mtx_leave(&sc->sc_mtx);
555		} else
556			ifp->if_flags &= ~IFF_RUNNING;
557		NET_UNLOCK();
558		break;
559
560	case SIOCSIFMTU:
561		if (ifr->ifr_mtu < PFLOW_MINMTU) {
562			error = EINVAL;
563			goto out;
564		}
565		if (ifr->ifr_mtu > MCLBYTES)
566			ifr->ifr_mtu = MCLBYTES;
567		NET_LOCK();
568		if (ifr->ifr_mtu < ifp->if_mtu)
569			pflow_flush(sc);
570		mtx_enter(&sc->sc_mtx);
571		pflow_setmtu(sc, ifr->ifr_mtu);
572		mtx_leave(&sc->sc_mtx);
573		NET_UNLOCK();
574		break;
575
576	case SIOCGETPFLOW:
577		bzero(&pflowr, sizeof(pflowr));
578
579		if (sc->sc_flowsrc != NULL)
580			memcpy(&pflowr.flowsrc, sc->sc_flowsrc,
581			    sc->sc_flowsrc->sa_len);
582		if (sc->sc_flowdst != NULL)
583			memcpy(&pflowr.flowdst, sc->sc_flowdst,
584			    sc->sc_flowdst->sa_len);
585		mtx_enter(&sc->sc_mtx);
586		pflowr.version = sc->sc_version;
587		mtx_leave(&sc->sc_mtx);
588
589		if ((error = copyout(&pflowr, ifr->ifr_data, sizeof(pflowr))))
590			goto out;
591		break;
592
593	case SIOCSETPFLOW:
594		if ((error = suser(p)) != 0)
595			goto out;
596		if ((error = copyin(ifr->ifr_data, &pflowr, sizeof(pflowr))))
597			goto out;
598
599		error = pflow_set(sc, &pflowr);
600		if (error != 0)
601			goto out;
602
603		NET_LOCK();
604		if ((ifp->if_flags & IFF_UP) && sc->so != NULL) {
605			ifp->if_flags |= IFF_RUNNING;
606			mtx_enter(&sc->sc_mtx);
607			if (sc->sc_version == PFLOW_PROTO_10)
608				pflow_sendout_ipfix_tmpl(sc);
609			mtx_leave(&sc->sc_mtx);
610		} else
611			ifp->if_flags &= ~IFF_RUNNING;
612		NET_UNLOCK();
613
614		break;
615	}
616
617out:
618	rw_exit_write(&sc->sc_lock);
619	NET_LOCK();
620
621	return (error);
622}
623
624int
625pflow_calc_mtu(struct pflow_softc *sc, int mtu, int hdrsz)
626{
627	sc->sc_maxcount4 = (mtu - hdrsz -
628	    sizeof(struct udpiphdr)) / sizeof(struct pflow_ipfix_flow4);
629	sc->sc_maxcount6 = (mtu - hdrsz -
630	    sizeof(struct udpiphdr)) / sizeof(struct pflow_ipfix_flow6);
631	if (sc->sc_maxcount4 > PFLOW_MAXFLOWS)
632		sc->sc_maxcount4 = PFLOW_MAXFLOWS;
633	if (sc->sc_maxcount6 > PFLOW_MAXFLOWS)
634		sc->sc_maxcount6 = PFLOW_MAXFLOWS;
635	return (hdrsz + sizeof(struct udpiphdr) +
636	    MIN(sc->sc_maxcount4 * sizeof(struct pflow_ipfix_flow4),
637	    sc->sc_maxcount6 * sizeof(struct pflow_ipfix_flow6)));
638}
639
640void
641pflow_setmtu(struct pflow_softc *sc, int mtu_req)
642{
643	int	mtu;
644
645	mtu = mtu_req;
646
647	switch (sc->sc_version) {
648	case PFLOW_PROTO_5:
649		sc->sc_maxcount = (mtu - sizeof(struct pflow_header) -
650		    sizeof(struct udpiphdr)) / sizeof(struct pflow_flow);
651		if (sc->sc_maxcount > PFLOW_MAXFLOWS)
652		    sc->sc_maxcount = PFLOW_MAXFLOWS;
653		sc->sc_if.if_mtu = sizeof(struct pflow_header) +
654		    sizeof(struct udpiphdr) +
655		    sc->sc_maxcount * sizeof(struct pflow_flow);
656		break;
657	case PFLOW_PROTO_10:
658		sc->sc_if.if_mtu =
659		    pflow_calc_mtu(sc, mtu, sizeof(struct pflow_v10_header));
660		break;
661	default: /* NOTREACHED */
662		break;
663	}
664}
665
666struct mbuf *
667pflow_get_mbuf(struct pflow_softc *sc, u_int16_t set_id)
668{
669	struct pflow_set_header	 set_hdr;
670	struct pflow_header	 h;
671	struct mbuf		*m;
672
673	MUTEX_ASSERT_LOCKED(&sc->sc_mtx);
674
675	MGETHDR(m, M_DONTWAIT, MT_DATA);
676	if (m == NULL) {
677		pflowstat_inc(pflow_onomem);
678		return (NULL);
679	}
680
681	MCLGET(m, M_DONTWAIT);
682	if ((m->m_flags & M_EXT) == 0) {
683		m_free(m);
684		pflowstat_inc(pflow_onomem);
685		return (NULL);
686	}
687
688	m->m_len = m->m_pkthdr.len = 0;
689	m->m_pkthdr.ph_ifidx = 0;
690
691	if (sc == NULL)		/* get only a new empty mbuf */
692		return (m);
693
694	switch (sc->sc_version) {
695	case PFLOW_PROTO_5:
696		/* populate pflow_header */
697		h.reserved1 = 0;
698		h.reserved2 = 0;
699		h.count = 0;
700		h.version = htons(PFLOW_PROTO_5);
701		h.flow_sequence = htonl(sc->sc_gcounter);
702		h.engine_type = PFLOW_ENGINE_TYPE;
703		h.engine_id = PFLOW_ENGINE_ID;
704		m_copyback(m, 0, PFLOW_HDRLEN, &h, M_NOWAIT);
705
706		sc->sc_count = 0;
707		timeout_add_sec(&sc->sc_tmo, PFLOW_TIMEOUT);
708		break;
709	case PFLOW_PROTO_10:
710		/* populate pflow_set_header */
711		set_hdr.set_length = 0;
712		set_hdr.set_id = htons(set_id);
713		m_copyback(m, 0, PFLOW_SET_HDRLEN, &set_hdr, M_NOWAIT);
714		break;
715	default: /* NOTREACHED */
716		break;
717	}
718
719	return (m);
720}
721
722void
723copy_flow_data(struct pflow_flow *flow1, struct pflow_flow *flow2,
724    struct pf_state *st, struct pf_state_key *sk, int src, int dst)
725{
726	flow1->src_ip = flow2->dest_ip = sk->addr[src].v4.s_addr;
727	flow1->src_port = flow2->dest_port = sk->port[src];
728	flow1->dest_ip = flow2->src_ip = sk->addr[dst].v4.s_addr;
729	flow1->dest_port = flow2->src_port = sk->port[dst];
730
731	flow1->dest_as = flow2->src_as =
732	    flow1->src_as = flow2->dest_as = 0;
733	flow1->if_index_in = htons(st->if_index_in);
734	flow1->if_index_out = htons(st->if_index_out);
735	flow2->if_index_in = htons(st->if_index_out);
736	flow2->if_index_out = htons(st->if_index_in);
737	flow1->dest_mask = flow2->src_mask =
738	    flow1->src_mask = flow2->dest_mask = 0;
739
740	flow1->flow_packets = htonl(st->packets[0]);
741	flow2->flow_packets = htonl(st->packets[1]);
742	flow1->flow_octets = htonl(st->bytes[0]);
743	flow2->flow_octets = htonl(st->bytes[1]);
744
745	/*
746	 * Pretend the flow was created or expired when the machine came up
747	 * when creation is in the future of the last time a package was seen
748	 * or was created / expired before this machine came up due to pfsync.
749	 */
750	flow1->flow_start = flow2->flow_start = st->creation < 0 ||
751	    st->creation > st->expire ? htonl(0) : htonl(st->creation * 1000);
752	flow1->flow_finish = flow2->flow_finish = st->expire < 0 ? htonl(0) :
753	    htonl(st->expire * 1000);
754	flow1->tcp_flags = flow2->tcp_flags = 0;
755	flow1->protocol = flow2->protocol = sk->proto;
756	flow1->tos = flow2->tos = st->rule.ptr->tos;
757}
758
759void
760copy_flow_ipfix_4_data(struct pflow_ipfix_flow4 *flow1,
761    struct pflow_ipfix_flow4 *flow2, struct pf_state *st,
762    struct pf_state_key *sk, struct pflow_softc *sc, int src, int dst)
763{
764	flow1->src_ip = flow2->dest_ip = sk->addr[src].v4.s_addr;
765	flow1->src_port = flow2->dest_port = sk->port[src];
766	flow1->dest_ip = flow2->src_ip = sk->addr[dst].v4.s_addr;
767	flow1->dest_port = flow2->src_port = sk->port[dst];
768
769	flow1->if_index_in = htonl(st->if_index_in);
770	flow1->if_index_out = htonl(st->if_index_out);
771	flow2->if_index_in = htonl(st->if_index_out);
772	flow2->if_index_out = htonl(st->if_index_in);
773
774	flow1->flow_packets = htobe64(st->packets[0]);
775	flow2->flow_packets = htobe64(st->packets[1]);
776	flow1->flow_octets = htobe64(st->bytes[0]);
777	flow2->flow_octets = htobe64(st->bytes[1]);
778
779	/*
780	 * Pretend the flow was created when the machine came up when creation
781	 * is in the future of the last time a package was seen due to pfsync.
782	 */
783	if (st->creation > st->expire)
784		flow1->flow_start = flow2->flow_start = htobe64((gettime() -
785		    getuptime())*1000);
786	else
787		flow1->flow_start = flow2->flow_start = htobe64((gettime() -
788		    (getuptime() - st->creation))*1000);
789	flow1->flow_finish = flow2->flow_finish = htobe64((gettime() -
790	    (getuptime() - st->expire))*1000);
791
792	flow1->protocol = flow2->protocol = sk->proto;
793	flow1->tos = flow2->tos = st->rule.ptr->tos;
794}
795
796void
797copy_flow_ipfix_6_data(struct pflow_ipfix_flow6 *flow1,
798    struct pflow_ipfix_flow6 *flow2, struct pf_state *st,
799    struct pf_state_key *sk, struct pflow_softc *sc, int src, int dst)
800{
801	bcopy(&sk->addr[src].v6, &flow1->src_ip, sizeof(flow1->src_ip));
802	bcopy(&sk->addr[src].v6, &flow2->dest_ip, sizeof(flow2->dest_ip));
803	flow1->src_port = flow2->dest_port = sk->port[src];
804	bcopy(&sk->addr[dst].v6, &flow1->dest_ip, sizeof(flow1->dest_ip));
805	bcopy(&sk->addr[dst].v6, &flow2->src_ip, sizeof(flow2->src_ip));
806	flow1->dest_port = flow2->src_port = sk->port[dst];
807
808	flow1->if_index_in = htonl(st->if_index_in);
809	flow1->if_index_out = htonl(st->if_index_out);
810	flow2->if_index_in = htonl(st->if_index_out);
811	flow2->if_index_out = htonl(st->if_index_in);
812
813	flow1->flow_packets = htobe64(st->packets[0]);
814	flow2->flow_packets = htobe64(st->packets[1]);
815	flow1->flow_octets = htobe64(st->bytes[0]);
816	flow2->flow_octets = htobe64(st->bytes[1]);
817
818	/*
819	 * Pretend the flow was created when the machine came up when creation
820	 * is in the future of the last time a package was seen due to pfsync.
821	 */
822	if (st->creation > st->expire)
823		flow1->flow_start = flow2->flow_start = htobe64((gettime() -
824		    getuptime())*1000);
825	else
826		flow1->flow_start = flow2->flow_start = htobe64((gettime() -
827		    (getuptime() - st->creation))*1000);
828	flow1->flow_finish = flow2->flow_finish = htobe64((gettime() -
829	    (getuptime() - st->expire))*1000);
830
831	flow1->protocol = flow2->protocol = sk->proto;
832	flow1->tos = flow2->tos = st->rule.ptr->tos;
833}
834
835int
836export_pflow(struct pf_state *st)
837{
838	struct pflow_softc	*sc = NULL;
839	struct pf_state_key	*sk;
840
841	sk = st->key[st->direction == PF_IN ? PF_SK_WIRE : PF_SK_STACK];
842
843	SMR_SLIST_FOREACH(sc, &pflowif_list, sc_next) {
844		mtx_enter(&sc->sc_mtx);
845		switch (sc->sc_version) {
846		case PFLOW_PROTO_5:
847			if (sk->af == AF_INET)
848				export_pflow_if(st, sk, sc);
849			break;
850		case PFLOW_PROTO_10:
851			if (sk->af == AF_INET || sk->af == AF_INET6)
852				export_pflow_if(st, sk, sc);
853			break;
854		default: /* NOTREACHED */
855			break;
856		}
857		mtx_leave(&sc->sc_mtx);
858	}
859
860	return (0);
861}
862
863int
864export_pflow_if(struct pf_state *st, struct pf_state_key *sk,
865    struct pflow_softc *sc)
866{
867	struct pf_state		 pfs_copy;
868	struct ifnet		*ifp = &sc->sc_if;
869	u_int64_t		 bytes[2];
870	int			 ret = 0;
871
872	if (!(ifp->if_flags & IFF_RUNNING))
873		return (0);
874
875	if (sc->sc_version == PFLOW_PROTO_10)
876		return (pflow_pack_flow_ipfix(st, sk, sc));
877
878	/* PFLOW_PROTO_5 */
879	if ((st->bytes[0] < (u_int64_t)PFLOW_MAXBYTES)
880	    && (st->bytes[1] < (u_int64_t)PFLOW_MAXBYTES))
881		return (pflow_pack_flow(st, sk, sc));
882
883	/* flow > PFLOW_MAXBYTES need special handling */
884	bcopy(st, &pfs_copy, sizeof(pfs_copy));
885	bytes[0] = pfs_copy.bytes[0];
886	bytes[1] = pfs_copy.bytes[1];
887
888	while (bytes[0] > PFLOW_MAXBYTES) {
889		pfs_copy.bytes[0] = PFLOW_MAXBYTES;
890		pfs_copy.bytes[1] = 0;
891
892		if ((ret = pflow_pack_flow(&pfs_copy, sk, sc)) != 0)
893			return (ret);
894		if ((bytes[0] - PFLOW_MAXBYTES) > 0)
895			bytes[0] -= PFLOW_MAXBYTES;
896	}
897
898	while (bytes[1] > (u_int64_t)PFLOW_MAXBYTES) {
899		pfs_copy.bytes[1] = PFLOW_MAXBYTES;
900		pfs_copy.bytes[0] = 0;
901
902		if ((ret = pflow_pack_flow(&pfs_copy, sk, sc)) != 0)
903			return (ret);
904		if ((bytes[1] - PFLOW_MAXBYTES) > 0)
905			bytes[1] -= PFLOW_MAXBYTES;
906	}
907
908	pfs_copy.bytes[0] = bytes[0];
909	pfs_copy.bytes[1] = bytes[1];
910
911	return (pflow_pack_flow(&pfs_copy, sk, sc));
912}
913
914int
915copy_flow_to_m(struct pflow_flow *flow, struct pflow_softc *sc)
916{
917	int		ret = 0;
918
919	MUTEX_ASSERT_LOCKED(&sc->sc_mtx);
920
921	if (sc->sc_mbuf == NULL) {
922		if ((sc->sc_mbuf = pflow_get_mbuf(sc, 0)) == NULL)
923			return (ENOBUFS);
924	}
925	m_copyback(sc->sc_mbuf, PFLOW_HDRLEN +
926	    (sc->sc_count * sizeof(struct pflow_flow)),
927	    sizeof(struct pflow_flow), flow, M_NOWAIT);
928
929	pflowstat_inc(pflow_flows);
930	sc->sc_gcounter++;
931	sc->sc_count++;
932
933	if (sc->sc_count >= sc->sc_maxcount)
934		ret = pflow_sendout_v5(sc);
935
936	return(ret);
937}
938
939int
940copy_flow_ipfix_4_to_m(struct pflow_ipfix_flow4 *flow, struct pflow_softc *sc)
941{
942	int		ret = 0;
943
944	MUTEX_ASSERT_LOCKED(&sc->sc_mtx);
945
946	if (sc->sc_mbuf == NULL) {
947		if ((sc->sc_mbuf =
948		    pflow_get_mbuf(sc, PFLOW_IPFIX_TMPL_IPV4_ID)) == NULL) {
949			return (ENOBUFS);
950		}
951		sc->sc_count4 = 0;
952		timeout_add_sec(&sc->sc_tmo, PFLOW_TIMEOUT);
953	}
954	m_copyback(sc->sc_mbuf, PFLOW_SET_HDRLEN +
955	    (sc->sc_count4 * sizeof(struct pflow_ipfix_flow4)),
956	    sizeof(struct pflow_ipfix_flow4), flow, M_NOWAIT);
957
958	pflowstat_inc(pflow_flows);
959	sc->sc_gcounter++;
960	sc->sc_count4++;
961
962	if (sc->sc_count4 >= sc->sc_maxcount4)
963		ret = pflow_sendout_ipfix(sc, AF_INET);
964	return(ret);
965}
966
967int
968copy_flow_ipfix_6_to_m(struct pflow_ipfix_flow6 *flow, struct pflow_softc *sc)
969{
970	int		ret = 0;
971
972	MUTEX_ASSERT_LOCKED(&sc->sc_mtx);
973
974	if (sc->sc_mbuf6 == NULL) {
975		if ((sc->sc_mbuf6 =
976		    pflow_get_mbuf(sc, PFLOW_IPFIX_TMPL_IPV6_ID)) == NULL) {
977			return (ENOBUFS);
978		}
979		sc->sc_count6 = 0;
980		timeout_add_sec(&sc->sc_tmo6, PFLOW_TIMEOUT);
981	}
982	m_copyback(sc->sc_mbuf6, PFLOW_SET_HDRLEN +
983	    (sc->sc_count6 * sizeof(struct pflow_ipfix_flow6)),
984	    sizeof(struct pflow_ipfix_flow6), flow, M_NOWAIT);
985
986	pflowstat_inc(pflow_flows);
987	sc->sc_gcounter++;
988	sc->sc_count6++;
989
990	if (sc->sc_count6 >= sc->sc_maxcount6)
991		ret = pflow_sendout_ipfix(sc, AF_INET6);
992
993	return(ret);
994}
995
996int
997pflow_pack_flow(struct pf_state *st, struct pf_state_key *sk,
998    struct pflow_softc *sc)
999{
1000	struct pflow_flow	 flow1;
1001	struct pflow_flow	 flow2;
1002	int			 ret = 0;
1003
1004	bzero(&flow1, sizeof(flow1));
1005	bzero(&flow2, sizeof(flow2));
1006
1007	if (st->direction == PF_OUT)
1008		copy_flow_data(&flow1, &flow2, st, sk, 1, 0);
1009	else
1010		copy_flow_data(&flow1, &flow2, st, sk, 0, 1);
1011
1012	if (st->bytes[0] != 0) /* first flow from state */
1013		ret = copy_flow_to_m(&flow1, sc);
1014
1015	if (st->bytes[1] != 0) /* second flow from state */
1016		ret = copy_flow_to_m(&flow2, sc);
1017
1018	return (ret);
1019}
1020
1021int
1022pflow_pack_flow_ipfix(struct pf_state *st, struct pf_state_key *sk,
1023    struct pflow_softc *sc)
1024{
1025	struct pflow_ipfix_flow4	 flow4_1, flow4_2;
1026	struct pflow_ipfix_flow6	 flow6_1, flow6_2;
1027	int				 ret = 0;
1028	if (sk->af == AF_INET) {
1029		bzero(&flow4_1, sizeof(flow4_1));
1030		bzero(&flow4_2, sizeof(flow4_2));
1031
1032		if (st->direction == PF_OUT)
1033			copy_flow_ipfix_4_data(&flow4_1, &flow4_2, st, sk, sc,
1034			    1, 0);
1035		else
1036			copy_flow_ipfix_4_data(&flow4_1, &flow4_2, st, sk, sc,
1037			    0, 1);
1038
1039		if (st->bytes[0] != 0) /* first flow from state */
1040			ret = copy_flow_ipfix_4_to_m(&flow4_1, sc);
1041
1042		if (st->bytes[1] != 0) /* second flow from state */
1043			ret = copy_flow_ipfix_4_to_m(&flow4_2, sc);
1044	} else if (sk->af == AF_INET6) {
1045		bzero(&flow6_1, sizeof(flow6_1));
1046		bzero(&flow6_2, sizeof(flow6_2));
1047
1048		if (st->direction == PF_OUT)
1049			copy_flow_ipfix_6_data(&flow6_1, &flow6_2, st, sk, sc,
1050			    1, 0);
1051		else
1052			copy_flow_ipfix_6_data(&flow6_1, &flow6_2, st, sk, sc,
1053			    0, 1);
1054
1055		if (st->bytes[0] != 0) /* first flow from state */
1056			ret = copy_flow_ipfix_6_to_m(&flow6_1, sc);
1057
1058		if (st->bytes[1] != 0) /* second flow from state */
1059			ret = copy_flow_ipfix_6_to_m(&flow6_2, sc);
1060	}
1061	return (ret);
1062}
1063
1064void
1065pflow_timeout(void *v)
1066{
1067	struct pflow_softc	*sc = v;
1068
1069	mtx_enter(&sc->sc_mtx);
1070	switch (sc->sc_version) {
1071	case PFLOW_PROTO_5:
1072		pflow_sendout_v5(sc);
1073		break;
1074	case PFLOW_PROTO_10:
1075		pflow_sendout_ipfix(sc, AF_INET);
1076		break;
1077	default: /* NOTREACHED */
1078		break;
1079	}
1080	mtx_leave(&sc->sc_mtx);
1081}
1082
1083void
1084pflow_timeout6(void *v)
1085{
1086	struct pflow_softc	*sc = v;
1087
1088	mtx_enter(&sc->sc_mtx);
1089	pflow_sendout_ipfix(sc, AF_INET6);
1090	mtx_leave(&sc->sc_mtx);
1091}
1092
1093void
1094pflow_timeout_tmpl(void *v)
1095{
1096	struct pflow_softc	*sc = v;
1097
1098	mtx_enter(&sc->sc_mtx);
1099	pflow_sendout_ipfix_tmpl(sc);
1100	mtx_leave(&sc->sc_mtx);
1101}
1102
1103void
1104pflow_flush(struct pflow_softc *sc)
1105{
1106	mtx_enter(&sc->sc_mtx);
1107	switch (sc->sc_version) {
1108	case PFLOW_PROTO_5:
1109		pflow_sendout_v5(sc);
1110		break;
1111	case PFLOW_PROTO_10:
1112		pflow_sendout_ipfix(sc, AF_INET);
1113		pflow_sendout_ipfix(sc, AF_INET6);
1114		break;
1115	default: /* NOTREACHED */
1116		break;
1117	}
1118	mtx_leave(&sc->sc_mtx);
1119}
1120
1121int
1122pflow_sendout_v5(struct pflow_softc *sc)
1123{
1124	struct mbuf		*m = sc->sc_mbuf;
1125	struct pflow_header	*h;
1126	struct ifnet		*ifp = &sc->sc_if;
1127	struct timespec		tv;
1128
1129	MUTEX_ASSERT_LOCKED(&sc->sc_mtx);
1130
1131	timeout_del(&sc->sc_tmo);
1132
1133	if (m == NULL)
1134		return (0);
1135
1136	sc->sc_mbuf = NULL;
1137	if (!(ifp->if_flags & IFF_RUNNING)) {
1138		m_freem(m);
1139		return (0);
1140	}
1141
1142	pflowstat_inc(pflow_packets);
1143	h = mtod(m, struct pflow_header *);
1144	h->count = htons(sc->sc_count);
1145
1146	/* populate pflow_header */
1147	h->uptime_ms = htonl(getuptime() * 1000);
1148
1149	getnanotime(&tv);
1150	h->time_sec = htonl(tv.tv_sec);			/* XXX 2038 */
1151	h->time_nanosec = htonl(tv.tv_nsec);
1152	if (mq_enqueue(&sc->sc_outputqueue, m) == 0)
1153		task_add(net_tq(ifp->if_index), &sc->sc_outputtask);
1154	return (0);
1155}
1156
1157int
1158pflow_sendout_ipfix(struct pflow_softc *sc, sa_family_t af)
1159{
1160	struct mbuf			*m;
1161	struct pflow_v10_header		*h10;
1162	struct pflow_set_header		*set_hdr;
1163	struct ifnet			*ifp = &sc->sc_if;
1164	u_int32_t			 count;
1165	int				 set_length;
1166
1167	MUTEX_ASSERT_LOCKED(&sc->sc_mtx);
1168
1169	switch (af) {
1170	case AF_INET:
1171		m = sc->sc_mbuf;
1172		timeout_del(&sc->sc_tmo);
1173		if (m == NULL)
1174			return (0);
1175		sc->sc_mbuf = NULL;
1176		count = sc->sc_count4;
1177		set_length = sizeof(struct pflow_set_header)
1178		    + sc->sc_count4 * sizeof(struct pflow_ipfix_flow4);
1179		break;
1180	case AF_INET6:
1181		m = sc->sc_mbuf6;
1182		timeout_del(&sc->sc_tmo6);
1183		if (m == NULL)
1184			return (0);
1185		sc->sc_mbuf6 = NULL;
1186		count = sc->sc_count6;
1187		set_length = sizeof(struct pflow_set_header)
1188		    + sc->sc_count6 * sizeof(struct pflow_ipfix_flow6);
1189		break;
1190	default:
1191		unhandled_af(af);
1192	}
1193
1194	if (!(ifp->if_flags & IFF_RUNNING)) {
1195		m_freem(m);
1196		return (0);
1197	}
1198
1199	pflowstat_inc(pflow_packets);
1200	set_hdr = mtod(m, struct pflow_set_header *);
1201	set_hdr->set_length = htons(set_length);
1202
1203	/* populate pflow_header */
1204	M_PREPEND(m, sizeof(struct pflow_v10_header), M_DONTWAIT);
1205	if (m == NULL) {
1206		pflowstat_inc(pflow_onomem);
1207		return (ENOBUFS);
1208	}
1209	h10 = mtod(m, struct pflow_v10_header *);
1210	h10->version = htons(PFLOW_PROTO_10);
1211	h10->length = htons(PFLOW_IPFIX_HDRLEN + set_length);
1212	h10->time_sec = htonl(gettime());		/* XXX 2038 */
1213	h10->flow_sequence = htonl(sc->sc_sequence);
1214	sc->sc_sequence += count;
1215	h10->observation_dom = htonl(PFLOW_ENGINE_TYPE);
1216	if (mq_enqueue(&sc->sc_outputqueue, m) == 0)
1217		task_add(net_tq(ifp->if_index), &sc->sc_outputtask);
1218	return (0);
1219}
1220
1221int
1222pflow_sendout_ipfix_tmpl(struct pflow_softc *sc)
1223{
1224	struct mbuf			*m;
1225	struct pflow_v10_header		*h10;
1226	struct ifnet			*ifp = &sc->sc_if;
1227
1228	MUTEX_ASSERT_LOCKED(&sc->sc_mtx);
1229
1230	timeout_del(&sc->sc_tmo_tmpl);
1231
1232	if (!(ifp->if_flags & IFF_RUNNING)) {
1233		return (0);
1234	}
1235	m = pflow_get_mbuf(sc, 0);
1236	if (m == NULL)
1237		return (0);
1238	if (m_copyback(m, 0, sizeof(struct pflow_ipfix_tmpl),
1239	    &sc->sc_tmpl_ipfix, M_NOWAIT)) {
1240		m_freem(m);
1241		return (0);
1242	}
1243	pflowstat_inc(pflow_packets);
1244
1245	/* populate pflow_header */
1246	M_PREPEND(m, sizeof(struct pflow_v10_header), M_DONTWAIT);
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(gettime());		/* XXX 2038 */
1256	h10->flow_sequence = htonl(sc->sc_sequence);
1257	h10->observation_dom = htonl(PFLOW_ENGINE_TYPE);
1258
1259	timeout_add_sec(&sc->sc_tmo_tmpl, PFLOW_TMPL_TIMEOUT);
1260	if (mq_enqueue(&sc->sc_outputqueue, m) == 0)
1261		task_add(net_tq(ifp->if_index), &sc->sc_outputtask);
1262	return (0);
1263}
1264
1265int
1266pflow_sendout_mbuf(struct pflow_softc *sc, struct mbuf *m)
1267{
1268	rw_assert_anylock(&sc->sc_lock);
1269
1270	counters_pkt(sc->sc_if.if_counters,
1271	            ifc_opackets, ifc_obytes, m->m_pkthdr.len);
1272
1273	if (sc->so == NULL) {
1274		m_freem(m);
1275		return (EINVAL);
1276	}
1277	return (sosend(sc->so, sc->send_nam, NULL, m, NULL, 0));
1278}
1279
1280int
1281pflow_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp,
1282    void *newp, size_t newlen)
1283{
1284	if (namelen != 1)
1285		return (ENOTDIR);
1286
1287	switch (name[0]) {
1288	case NET_PFLOW_STATS: {
1289		uint64_t counters[pflow_ncounters];
1290		struct pflowstats pflowstats;
1291
1292		if (newp != NULL)
1293			return (EPERM);
1294
1295		counters_read(pflow_counters, counters, pflow_ncounters, NULL);
1296
1297		pflowstats.pflow_flows = counters[pflow_flows];
1298		pflowstats.pflow_packets = counters[pflow_packets];
1299		pflowstats.pflow_onomem = counters[pflow_onomem];
1300		pflowstats.pflow_oerrors = counters[pflow_oerrors];
1301
1302		return (sysctl_struct(oldp, oldlenp, newp, newlen,
1303		    &pflowstats, sizeof(pflowstats)));
1304	}
1305	default:
1306		return (EOPNOTSUPP);
1307	}
1308	return (0);
1309}
1310