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