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