xref: /openbsd-src/sys/net/if_pflow.c (revision f6aab3d83b51b91c24247ad2c2573574de475a82)
1 /*	$OpenBSD: if_pflow.c,v 1.100 2023/11/09 08:53:20 mvs 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 
33 #include <net/if.h>
34 #include <net/if_types.h>
35 #include <net/bpf.h>
36 #include <net/route.h>
37 #include <netinet/in.h>
38 #include <netinet/if_ether.h>
39 #include <netinet/tcp.h>
40 
41 #include <netinet/ip.h>
42 #include <netinet/ip_icmp.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/pfvar_priv.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 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 	rw_enter_read(&sc->sc_lock);
136 	while ((m = ml_dequeue(&ml)) != NULL) {
137 		pflow_sendout_mbuf(sc, m);
138 	}
139 	rw_exit_read(&sc->sc_lock);
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 	pflowif = malloc(sizeof(*pflowif), M_DEVBUF, M_WAITOK|M_ZERO);
149 	rw_init(&pflowif->sc_lock, "pflowlk");
150 	MGET(pflowif->send_nam, M_WAIT, MT_SONAME);
151 	pflowif->sc_version = PFLOW_PROTO_DEFAULT;
152 
153 	/* ipfix template init */
154 	bzero(&pflowif->sc_tmpl_ipfix,sizeof(pflowif->sc_tmpl_ipfix));
155 	pflowif->sc_tmpl_ipfix.set_header.set_id =
156 	    htons(PFLOW_IPFIX_TMPL_SET_ID);
157 	pflowif->sc_tmpl_ipfix.set_header.set_length =
158 	    htons(sizeof(struct pflow_ipfix_tmpl));
159 
160 	/* ipfix IPv4 template */
161 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.h.tmpl_id =
162 	    htons(PFLOW_IPFIX_TMPL_IPV4_ID);
163 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.h.field_count
164 	    = htons(PFLOW_IPFIX_TMPL_IPV4_FIELD_COUNT);
165 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.src_ip.field_id =
166 	    htons(PFIX_IE_sourceIPv4Address);
167 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.src_ip.len = htons(4);
168 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.dest_ip.field_id =
169 	    htons(PFIX_IE_destinationIPv4Address);
170 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.dest_ip.len = htons(4);
171 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.if_index_in.field_id =
172 	    htons(PFIX_IE_ingressInterface);
173 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.if_index_in.len = htons(4);
174 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.if_index_out.field_id =
175 	    htons(PFIX_IE_egressInterface);
176 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.if_index_out.len = htons(4);
177 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.packets.field_id =
178 	    htons(PFIX_IE_packetDeltaCount);
179 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.packets.len = htons(8);
180 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.octets.field_id =
181 	    htons(PFIX_IE_octetDeltaCount);
182 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.octets.len = htons(8);
183 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.start.field_id =
184 	    htons(PFIX_IE_flowStartMilliseconds);
185 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.start.len = htons(8);
186 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.finish.field_id =
187 	    htons(PFIX_IE_flowEndMilliseconds);
188 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.finish.len = htons(8);
189 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.src_port.field_id =
190 	    htons(PFIX_IE_sourceTransportPort);
191 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.src_port.len = htons(2);
192 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.dest_port.field_id =
193 	    htons(PFIX_IE_destinationTransportPort);
194 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.dest_port.len = htons(2);
195 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.tos.field_id =
196 	    htons(PFIX_IE_ipClassOfService);
197 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.tos.len = htons(1);
198 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.protocol.field_id =
199 	    htons(PFIX_IE_protocolIdentifier);
200 	pflowif->sc_tmpl_ipfix.ipv4_tmpl.protocol.len = htons(1);
201 
202 	/* ipfix IPv6 template */
203 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.h.tmpl_id =
204 	    htons(PFLOW_IPFIX_TMPL_IPV6_ID);
205 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.h.field_count =
206 	    htons(PFLOW_IPFIX_TMPL_IPV6_FIELD_COUNT);
207 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.src_ip.field_id =
208 	    htons(PFIX_IE_sourceIPv6Address);
209 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.src_ip.len = htons(16);
210 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.dest_ip.field_id =
211 	    htons(PFIX_IE_destinationIPv6Address);
212 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.dest_ip.len = htons(16);
213 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.if_index_in.field_id =
214 	    htons(PFIX_IE_ingressInterface);
215 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.if_index_in.len = htons(4);
216 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.if_index_out.field_id =
217 	    htons(PFIX_IE_egressInterface);
218 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.if_index_out.len = htons(4);
219 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.packets.field_id =
220 	    htons(PFIX_IE_packetDeltaCount);
221 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.packets.len = htons(8);
222 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.octets.field_id =
223 	    htons(PFIX_IE_octetDeltaCount);
224 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.octets.len = htons(8);
225 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.start.field_id =
226 	    htons(PFIX_IE_flowStartMilliseconds);
227 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.start.len = htons(8);
228 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.finish.field_id =
229 	    htons(PFIX_IE_flowEndMilliseconds);
230 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.finish.len = htons(8);
231 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.src_port.field_id =
232 	    htons(PFIX_IE_sourceTransportPort);
233 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.src_port.len = htons(2);
234 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.dest_port.field_id =
235 	    htons(PFIX_IE_destinationTransportPort);
236 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.dest_port.len = htons(2);
237 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.tos.field_id =
238 	    htons(PFIX_IE_ipClassOfService);
239 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.tos.len = htons(1);
240 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.protocol.field_id =
241 	    htons(PFIX_IE_protocolIdentifier);
242 	pflowif->sc_tmpl_ipfix.ipv6_tmpl.protocol.len = htons(1);
243 
244 	ifp = &pflowif->sc_if;
245 	snprintf(ifp->if_xname, sizeof ifp->if_xname, "pflow%d", unit);
246 	ifp->if_softc = pflowif;
247 	ifp->if_ioctl = pflowioctl;
248 	ifp->if_output = pflow_output;
249 	ifp->if_start = NULL;
250 	ifp->if_xflags = IFXF_CLONED;
251 	ifp->if_type = IFT_PFLOW;
252 	ifp->if_hdrlen = PFLOW_HDRLEN;
253 	ifp->if_flags = IFF_UP;
254 	ifp->if_flags &= ~IFF_RUNNING;	/* not running, need receiver */
255 	mq_init(&pflowif->sc_outputqueue, 8192, IPL_SOFTNET);
256 	pflow_setmtu(pflowif, ETHERMTU);
257 
258 	timeout_set_proc(&pflowif->sc_tmo, pflow_timeout, pflowif);
259 	timeout_set_proc(&pflowif->sc_tmo6, pflow_timeout6, pflowif);
260 	timeout_set_proc(&pflowif->sc_tmo_tmpl, pflow_timeout_tmpl, pflowif);
261 
262 	if_counters_alloc(ifp);
263 	if_attach(ifp);
264 	if_alloc_sadl(ifp);
265 
266 	task_set(&pflowif->sc_outputtask, pflow_output_process, pflowif);
267 
268 	/* Insert into list of pflows */
269 	NET_LOCK();
270 	SLIST_INSERT_HEAD(&pflowif_list, pflowif, sc_next);
271 	NET_UNLOCK();
272 	return (0);
273 }
274 
275 int
276 pflow_clone_destroy(struct ifnet *ifp)
277 {
278 	struct pflow_softc	*sc = ifp->if_softc;
279 	int			 error;
280 
281 	error = 0;
282 
283 	NET_LOCK();
284 	sc->sc_dying = 1;
285 	SLIST_REMOVE(&pflowif_list, sc, pflow_softc, sc_next);
286 	NET_UNLOCK();
287 
288 	timeout_del(&sc->sc_tmo);
289 	timeout_del(&sc->sc_tmo6);
290 	timeout_del(&sc->sc_tmo_tmpl);
291 
292 	pflow_flush(sc);
293 	task_del(net_tq(ifp->if_index), &sc->sc_outputtask);
294 	taskq_barrier(net_tq(ifp->if_index));
295 	mq_purge(&sc->sc_outputqueue);
296 	m_freem(sc->send_nam);
297 	if (sc->so != NULL) {
298 		error = soclose(sc->so, MSG_DONTWAIT);
299 		sc->so = NULL;
300 	}
301 	if (sc->sc_flowdst != NULL)
302 		free(sc->sc_flowdst, M_DEVBUF, sc->sc_flowdst->sa_len);
303 	if (sc->sc_flowsrc != NULL)
304 		free(sc->sc_flowsrc, M_DEVBUF, sc->sc_flowsrc->sa_len);
305 	if_detach(ifp);
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, MSG_DONTWAIT);
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, MSG_DONTWAIT);
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 				solock(so);
449 				error = sobind(so, m, p);
450 				sounlock(so);
451 				m_freem(m);
452 				if (error) {
453 					soclose(so, MSG_DONTWAIT);
454 					return (error);
455 				}
456 			}
457 			sc->so = so;
458 		}
459 	} else if (!pflowvalidsockaddr(sc->sc_flowdst, 0)) {
460 		soclose(sc->so, MSG_DONTWAIT);
461 		sc->so = NULL;
462 	}
463 
464 	/* error check is above */
465 	if (pflowr->addrmask & PFLOW_MASK_VERSION)
466 		sc->sc_version = pflowr->version;
467 
468 	pflow_setmtu(sc, ETHERMTU);
469 
470 	switch (sc->sc_version) {
471 	case PFLOW_PROTO_5:
472 		timeout_del(&sc->sc_tmo6);
473 		timeout_del(&sc->sc_tmo_tmpl);
474 		break;
475 	case PFLOW_PROTO_10:
476 		timeout_add_sec(&sc->sc_tmo_tmpl, PFLOW_TMPL_TIMEOUT);
477 		break;
478 	default: /* NOTREACHED */
479 		break;
480 	}
481 
482 	return (0);
483 }
484 
485 int
486 pflowioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
487 {
488 	struct proc		*p = curproc;
489 	struct pflow_softc	*sc = ifp->if_softc;
490 	struct ifreq		*ifr = (struct ifreq *)data;
491 	struct pflowreq		 pflowr;
492 	int			 error;
493 
494 	if (sc->sc_dying)
495 		return ENXIO;
496 
497 	switch (cmd) {
498 	case SIOCSIFADDR:
499 	case SIOCSIFDSTADDR:
500 	case SIOCSIFFLAGS:
501 		/* XXXSMP: enforce lock order */
502 		NET_UNLOCK();
503 		rw_enter_read(&sc->sc_lock);
504 		NET_LOCK();
505 		if ((ifp->if_flags & IFF_UP) && sc->so != NULL) {
506 			ifp->if_flags |= IFF_RUNNING;
507 			sc->sc_gcounter=pflowstats.pflow_flows;
508 			/* send templates on startup */
509 			if (sc->sc_version == PFLOW_PROTO_10)
510 				pflow_sendout_ipfix_tmpl(sc);
511 		} else
512 			ifp->if_flags &= ~IFF_RUNNING;
513 		rw_exit_read(&sc->sc_lock);
514 		break;
515 	case SIOCSIFMTU:
516 		if (ifr->ifr_mtu < PFLOW_MINMTU)
517 			return (EINVAL);
518 		if (ifr->ifr_mtu > MCLBYTES)
519 			ifr->ifr_mtu = MCLBYTES;
520 		if (ifr->ifr_mtu < ifp->if_mtu)
521 			pflow_flush(sc);
522 		pflow_setmtu(sc, ifr->ifr_mtu);
523 		break;
524 
525 	case SIOCGETPFLOW:
526 		bzero(&pflowr, sizeof(pflowr));
527 
528 		if (sc->sc_flowsrc != NULL)
529 			memcpy(&pflowr.flowsrc, sc->sc_flowsrc,
530 			    sc->sc_flowsrc->sa_len);
531 		if (sc->sc_flowdst != NULL)
532 			memcpy(&pflowr.flowdst, sc->sc_flowdst,
533 			    sc->sc_flowdst->sa_len);
534 		pflowr.version = sc->sc_version;
535 
536 		if ((error = copyout(&pflowr, ifr->ifr_data,
537 		    sizeof(pflowr))))
538 			return (error);
539 		break;
540 
541 	case SIOCSETPFLOW:
542 		if ((error = suser(p)) != 0)
543 			return (error);
544 		if ((error = copyin(ifr->ifr_data, &pflowr,
545 		    sizeof(pflowr))))
546 			return (error);
547 
548 		/* XXXSMP breaks atomicity */
549 		NET_UNLOCK();
550 		rw_enter_write(&sc->sc_lock);
551 		error = pflow_set(sc, &pflowr);
552 		NET_LOCK();
553 		if (error != 0) {
554 			rw_exit_write(&sc->sc_lock);
555 			return (error);
556 		}
557 
558 		if ((ifp->if_flags & IFF_UP) && sc->so != NULL) {
559 			ifp->if_flags |= IFF_RUNNING;
560 			sc->sc_gcounter=pflowstats.pflow_flows;
561 			if (sc->sc_version == PFLOW_PROTO_10)
562 				pflow_sendout_ipfix_tmpl(sc);
563 		} else
564 			ifp->if_flags &= ~IFF_RUNNING;
565 		rw_exit_write(&sc->sc_lock);
566 
567 		break;
568 
569 	default:
570 		return (ENOTTY);
571 	}
572 	return (0);
573 }
574 
575 int
576 pflow_calc_mtu(struct pflow_softc *sc, int mtu, int hdrsz)
577 {
578 
579 	sc->sc_maxcount4 = (mtu - hdrsz -
580 	    sizeof(struct udpiphdr)) / sizeof(struct pflow_ipfix_flow4);
581 	sc->sc_maxcount6 = (mtu - hdrsz -
582 	    sizeof(struct udpiphdr)) / sizeof(struct pflow_ipfix_flow6);
583 	if (sc->sc_maxcount4 > PFLOW_MAXFLOWS)
584 		sc->sc_maxcount4 = PFLOW_MAXFLOWS;
585 	if (sc->sc_maxcount6 > PFLOW_MAXFLOWS)
586 		sc->sc_maxcount6 = PFLOW_MAXFLOWS;
587 	return (hdrsz + sizeof(struct udpiphdr) +
588 	    MIN(sc->sc_maxcount4 * sizeof(struct pflow_ipfix_flow4),
589 	    sc->sc_maxcount6 * sizeof(struct pflow_ipfix_flow6)));
590 }
591 
592 void
593 pflow_setmtu(struct pflow_softc *sc, int mtu_req)
594 {
595 	int	mtu;
596 
597 	mtu = mtu_req;
598 
599 	switch (sc->sc_version) {
600 	case PFLOW_PROTO_5:
601 		sc->sc_maxcount = (mtu - sizeof(struct pflow_header) -
602 		    sizeof(struct udpiphdr)) / sizeof(struct pflow_flow);
603 		if (sc->sc_maxcount > PFLOW_MAXFLOWS)
604 		    sc->sc_maxcount = PFLOW_MAXFLOWS;
605 		sc->sc_if.if_mtu = sizeof(struct pflow_header) +
606 		    sizeof(struct udpiphdr) +
607 		    sc->sc_maxcount * sizeof(struct pflow_flow);
608 		break;
609 	case PFLOW_PROTO_10:
610 		sc->sc_if.if_mtu =
611 		    pflow_calc_mtu(sc, mtu, sizeof(struct pflow_v10_header));
612 		break;
613 	default: /* NOTREACHED */
614 		break;
615 	}
616 }
617 
618 struct mbuf *
619 pflow_get_mbuf(struct pflow_softc *sc, u_int16_t set_id)
620 {
621 	struct pflow_set_header	 set_hdr;
622 	struct pflow_header	 h;
623 	struct mbuf		*m;
624 
625 	MGETHDR(m, M_DONTWAIT, MT_DATA);
626 	if (m == NULL) {
627 		pflowstats.pflow_onomem++;
628 		return (NULL);
629 	}
630 
631 	MCLGET(m, M_DONTWAIT);
632 	if ((m->m_flags & M_EXT) == 0) {
633 		m_free(m);
634 		pflowstats.pflow_onomem++;
635 		return (NULL);
636 	}
637 
638 	m->m_len = m->m_pkthdr.len = 0;
639 	m->m_pkthdr.ph_ifidx = 0;
640 
641 	if (sc == NULL)		/* get only a new empty mbuf */
642 		return (m);
643 
644 	switch (sc->sc_version) {
645 	case PFLOW_PROTO_5:
646 		/* populate pflow_header */
647 		h.reserved1 = 0;
648 		h.reserved2 = 0;
649 		h.count = 0;
650 		h.version = htons(PFLOW_PROTO_5);
651 		h.flow_sequence = htonl(sc->sc_gcounter);
652 		h.engine_type = PFLOW_ENGINE_TYPE;
653 		h.engine_id = PFLOW_ENGINE_ID;
654 		m_copyback(m, 0, PFLOW_HDRLEN, &h, M_NOWAIT);
655 
656 		sc->sc_count = 0;
657 		timeout_add_sec(&sc->sc_tmo, PFLOW_TIMEOUT);
658 		break;
659 	case PFLOW_PROTO_10:
660 		/* populate pflow_set_header */
661 		set_hdr.set_length = 0;
662 		set_hdr.set_id = htons(set_id);
663 		m_copyback(m, 0, PFLOW_SET_HDRLEN, &set_hdr, M_NOWAIT);
664 		break;
665 	default: /* NOTREACHED */
666 		break;
667 	}
668 
669 	return (m);
670 }
671 
672 void
673 copy_flow_data(struct pflow_flow *flow1, struct pflow_flow *flow2,
674     struct pf_state *st, struct pf_state_key *sk, int src, int dst)
675 {
676 	flow1->src_ip = flow2->dest_ip = sk->addr[src].v4.s_addr;
677 	flow1->src_port = flow2->dest_port = sk->port[src];
678 	flow1->dest_ip = flow2->src_ip = sk->addr[dst].v4.s_addr;
679 	flow1->dest_port = flow2->src_port = sk->port[dst];
680 
681 	flow1->dest_as = flow2->src_as =
682 	    flow1->src_as = flow2->dest_as = 0;
683 	flow1->if_index_in = htons(st->if_index_in);
684 	flow1->if_index_out = htons(st->if_index_out);
685 	flow2->if_index_in = htons(st->if_index_out);
686 	flow2->if_index_out = htons(st->if_index_in);
687 	flow1->dest_mask = flow2->src_mask =
688 	    flow1->src_mask = flow2->dest_mask = 0;
689 
690 	flow1->flow_packets = htonl(st->packets[0]);
691 	flow2->flow_packets = htonl(st->packets[1]);
692 	flow1->flow_octets = htonl(st->bytes[0]);
693 	flow2->flow_octets = htonl(st->bytes[1]);
694 
695 	/*
696 	 * Pretend the flow was created or expired when the machine came up
697 	 * when creation is in the future of the last time a package was seen
698 	 * or was created / expired before this machine came up due to pfsync.
699 	 */
700 	flow1->flow_start = flow2->flow_start = st->creation < 0 ||
701 	    st->creation > st->expire ? htonl(0) : htonl(st->creation * 1000);
702 	flow1->flow_finish = flow2->flow_finish = st->expire < 0 ? htonl(0) :
703 	    htonl(st->expire * 1000);
704 	flow1->tcp_flags = flow2->tcp_flags = 0;
705 	flow1->protocol = flow2->protocol = sk->proto;
706 	flow1->tos = flow2->tos = st->rule.ptr->tos;
707 }
708 
709 void
710 copy_flow_ipfix_4_data(struct pflow_ipfix_flow4 *flow1,
711     struct pflow_ipfix_flow4 *flow2, struct pf_state *st,
712     struct pf_state_key *sk, struct pflow_softc *sc, int src, int dst)
713 {
714 	flow1->src_ip = flow2->dest_ip = sk->addr[src].v4.s_addr;
715 	flow1->src_port = flow2->dest_port = sk->port[src];
716 	flow1->dest_ip = flow2->src_ip = sk->addr[dst].v4.s_addr;
717 	flow1->dest_port = flow2->src_port = sk->port[dst];
718 
719 	flow1->if_index_in = htonl(st->if_index_in);
720 	flow1->if_index_out = htonl(st->if_index_out);
721 	flow2->if_index_in = htonl(st->if_index_out);
722 	flow2->if_index_out = htonl(st->if_index_in);
723 
724 	flow1->flow_packets = htobe64(st->packets[0]);
725 	flow2->flow_packets = htobe64(st->packets[1]);
726 	flow1->flow_octets = htobe64(st->bytes[0]);
727 	flow2->flow_octets = htobe64(st->bytes[1]);
728 
729 	/*
730 	 * Pretend the flow was created when the machine came up when creation
731 	 * is in the future of the last time a package was seen due to pfsync.
732 	 */
733 	if (st->creation > st->expire)
734 		flow1->flow_start = flow2->flow_start = htobe64((gettime() -
735 		    getuptime())*1000);
736 	else
737 		flow1->flow_start = flow2->flow_start = htobe64((gettime() -
738 		    (getuptime() - st->creation))*1000);
739 	flow1->flow_finish = flow2->flow_finish = htobe64((gettime() -
740 	    (getuptime() - st->expire))*1000);
741 
742 	flow1->protocol = flow2->protocol = sk->proto;
743 	flow1->tos = flow2->tos = st->rule.ptr->tos;
744 }
745 
746 void
747 copy_flow_ipfix_6_data(struct pflow_ipfix_flow6 *flow1,
748     struct pflow_ipfix_flow6 *flow2, struct pf_state *st,
749     struct pf_state_key *sk, struct pflow_softc *sc, int src, int dst)
750 {
751 	bcopy(&sk->addr[src].v6, &flow1->src_ip, sizeof(flow1->src_ip));
752 	bcopy(&sk->addr[src].v6, &flow2->dest_ip, sizeof(flow2->dest_ip));
753 	flow1->src_port = flow2->dest_port = sk->port[src];
754 	bcopy(&sk->addr[dst].v6, &flow1->dest_ip, sizeof(flow1->dest_ip));
755 	bcopy(&sk->addr[dst].v6, &flow2->src_ip, sizeof(flow2->src_ip));
756 	flow1->dest_port = flow2->src_port = sk->port[dst];
757 
758 	flow1->if_index_in = htonl(st->if_index_in);
759 	flow1->if_index_out = htonl(st->if_index_out);
760 	flow2->if_index_in = htonl(st->if_index_out);
761 	flow2->if_index_out = htonl(st->if_index_in);
762 
763 	flow1->flow_packets = htobe64(st->packets[0]);
764 	flow2->flow_packets = htobe64(st->packets[1]);
765 	flow1->flow_octets = htobe64(st->bytes[0]);
766 	flow2->flow_octets = htobe64(st->bytes[1]);
767 
768 	/*
769 	 * Pretend the flow was created when the machine came up when creation
770 	 * is in the future of the last time a package was seen due to pfsync.
771 	 */
772 	if (st->creation > st->expire)
773 		flow1->flow_start = flow2->flow_start = htobe64((gettime() -
774 		    getuptime())*1000);
775 	else
776 		flow1->flow_start = flow2->flow_start = htobe64((gettime() -
777 		    (getuptime() - st->creation))*1000);
778 	flow1->flow_finish = flow2->flow_finish = htobe64((gettime() -
779 	    (getuptime() - st->expire))*1000);
780 
781 	flow1->protocol = flow2->protocol = sk->proto;
782 	flow1->tos = flow2->tos = st->rule.ptr->tos;
783 }
784 
785 int
786 export_pflow(struct pf_state *st)
787 {
788 	struct pflow_softc	*sc = NULL;
789 	struct pf_state_key	*sk;
790 
791 	sk = st->key[st->direction == PF_IN ? PF_SK_WIRE : PF_SK_STACK];
792 
793 	SLIST_FOREACH(sc, &pflowif_list, sc_next) {
794 		switch (sc->sc_version) {
795 		case PFLOW_PROTO_5:
796 			if( sk->af == AF_INET )
797 				export_pflow_if(st, sk, sc);
798 			break;
799 		case PFLOW_PROTO_10:
800 			if( sk->af == AF_INET || sk->af == AF_INET6 )
801 				export_pflow_if(st, sk, sc);
802 			break;
803 		default: /* NOTREACHED */
804 			break;
805 		}
806 	}
807 
808 	return (0);
809 }
810 
811 int
812 export_pflow_if(struct pf_state *st, struct pf_state_key *sk,
813     struct pflow_softc *sc)
814 {
815 	struct pf_state		 pfs_copy;
816 	struct ifnet		*ifp = &sc->sc_if;
817 	u_int64_t		 bytes[2];
818 	int			 ret = 0;
819 
820 	if (!(ifp->if_flags & IFF_RUNNING))
821 		return (0);
822 
823 	if (sc->sc_version == PFLOW_PROTO_10)
824 		return (pflow_pack_flow_ipfix(st, sk, sc));
825 
826 	/* PFLOW_PROTO_5 */
827 	if ((st->bytes[0] < (u_int64_t)PFLOW_MAXBYTES)
828 	    && (st->bytes[1] < (u_int64_t)PFLOW_MAXBYTES))
829 		return (pflow_pack_flow(st, sk, sc));
830 
831 	/* flow > PFLOW_MAXBYTES need special handling */
832 	bcopy(st, &pfs_copy, sizeof(pfs_copy));
833 	bytes[0] = pfs_copy.bytes[0];
834 	bytes[1] = pfs_copy.bytes[1];
835 
836 	while (bytes[0] > PFLOW_MAXBYTES) {
837 		pfs_copy.bytes[0] = PFLOW_MAXBYTES;
838 		pfs_copy.bytes[1] = 0;
839 
840 		if ((ret = pflow_pack_flow(&pfs_copy, sk, sc)) != 0)
841 			return (ret);
842 		if ((bytes[0] - PFLOW_MAXBYTES) > 0)
843 			bytes[0] -= PFLOW_MAXBYTES;
844 	}
845 
846 	while (bytes[1] > (u_int64_t)PFLOW_MAXBYTES) {
847 		pfs_copy.bytes[1] = PFLOW_MAXBYTES;
848 		pfs_copy.bytes[0] = 0;
849 
850 		if ((ret = pflow_pack_flow(&pfs_copy, sk, sc)) != 0)
851 			return (ret);
852 		if ((bytes[1] - PFLOW_MAXBYTES) > 0)
853 			bytes[1] -= PFLOW_MAXBYTES;
854 	}
855 
856 	pfs_copy.bytes[0] = bytes[0];
857 	pfs_copy.bytes[1] = bytes[1];
858 
859 	return (pflow_pack_flow(&pfs_copy, sk, sc));
860 }
861 
862 int
863 copy_flow_to_m(struct pflow_flow *flow, struct pflow_softc *sc)
864 {
865 	int		ret = 0;
866 
867 	if (sc->sc_mbuf == NULL) {
868 		if ((sc->sc_mbuf = pflow_get_mbuf(sc, 0)) == NULL)
869 			return (ENOBUFS);
870 	}
871 	m_copyback(sc->sc_mbuf, PFLOW_HDRLEN +
872 	    (sc->sc_count * sizeof(struct pflow_flow)),
873 	    sizeof(struct pflow_flow), flow, M_NOWAIT);
874 
875 	if (pflowstats.pflow_flows == sc->sc_gcounter)
876 		pflowstats.pflow_flows++;
877 	sc->sc_gcounter++;
878 	sc->sc_count++;
879 
880 	if (sc->sc_count >= sc->sc_maxcount)
881 		ret = pflow_sendout_v5(sc);
882 
883 	return(ret);
884 }
885 
886 int
887 copy_flow_ipfix_4_to_m(struct pflow_ipfix_flow4 *flow, struct pflow_softc *sc)
888 {
889 	int		ret = 0;
890 
891 	if (sc->sc_mbuf == NULL) {
892 		if ((sc->sc_mbuf =
893 		    pflow_get_mbuf(sc, PFLOW_IPFIX_TMPL_IPV4_ID)) == NULL) {
894 			return (ENOBUFS);
895 		}
896 		sc->sc_count4 = 0;
897 		timeout_add_sec(&sc->sc_tmo, PFLOW_TIMEOUT);
898 	}
899 	m_copyback(sc->sc_mbuf, PFLOW_SET_HDRLEN +
900 	    (sc->sc_count4 * sizeof(struct pflow_ipfix_flow4)),
901 	    sizeof(struct pflow_ipfix_flow4), flow, M_NOWAIT);
902 
903 	if (pflowstats.pflow_flows == sc->sc_gcounter)
904 		pflowstats.pflow_flows++;
905 	sc->sc_gcounter++;
906 	sc->sc_count4++;
907 
908 	if (sc->sc_count4 >= sc->sc_maxcount4)
909 		ret = pflow_sendout_ipfix(sc, AF_INET);
910 	return(ret);
911 }
912 
913 int
914 copy_flow_ipfix_6_to_m(struct pflow_ipfix_flow6 *flow, struct pflow_softc *sc)
915 {
916 	int		ret = 0;
917 
918 	if (sc->sc_mbuf6 == NULL) {
919 		if ((sc->sc_mbuf6 =
920 		    pflow_get_mbuf(sc, PFLOW_IPFIX_TMPL_IPV6_ID)) == NULL) {
921 			return (ENOBUFS);
922 		}
923 		sc->sc_count6 = 0;
924 		timeout_add_sec(&sc->sc_tmo6, PFLOW_TIMEOUT);
925 	}
926 	m_copyback(sc->sc_mbuf6, PFLOW_SET_HDRLEN +
927 	    (sc->sc_count6 * sizeof(struct pflow_ipfix_flow6)),
928 	    sizeof(struct pflow_ipfix_flow6), flow, M_NOWAIT);
929 
930 	if (pflowstats.pflow_flows == sc->sc_gcounter)
931 		pflowstats.pflow_flows++;
932 	sc->sc_gcounter++;
933 	sc->sc_count6++;
934 
935 	if (sc->sc_count6 >= sc->sc_maxcount6)
936 		ret = pflow_sendout_ipfix(sc, AF_INET6);
937 
938 	return(ret);
939 }
940 
941 int
942 pflow_pack_flow(struct pf_state *st, struct pf_state_key *sk,
943     struct pflow_softc *sc)
944 {
945 	struct pflow_flow	 flow1;
946 	struct pflow_flow	 flow2;
947 	int			 ret = 0;
948 
949 	bzero(&flow1, sizeof(flow1));
950 	bzero(&flow2, sizeof(flow2));
951 
952 	if (st->direction == PF_OUT)
953 		copy_flow_data(&flow1, &flow2, st, sk, 1, 0);
954 	else
955 		copy_flow_data(&flow1, &flow2, st, sk, 0, 1);
956 
957 	if (st->bytes[0] != 0) /* first flow from state */
958 		ret = copy_flow_to_m(&flow1, sc);
959 
960 	if (st->bytes[1] != 0) /* second flow from state */
961 		ret = copy_flow_to_m(&flow2, sc);
962 
963 	return (ret);
964 }
965 
966 int
967 pflow_pack_flow_ipfix(struct pf_state *st, struct pf_state_key *sk,
968     struct pflow_softc *sc)
969 {
970 	struct pflow_ipfix_flow4	 flow4_1, flow4_2;
971 	struct pflow_ipfix_flow6	 flow6_1, flow6_2;
972 	int				 ret = 0;
973 	if (sk->af == AF_INET) {
974 		bzero(&flow4_1, sizeof(flow4_1));
975 		bzero(&flow4_2, sizeof(flow4_2));
976 
977 		if (st->direction == PF_OUT)
978 			copy_flow_ipfix_4_data(&flow4_1, &flow4_2, st, sk, sc,
979 			    1, 0);
980 		else
981 			copy_flow_ipfix_4_data(&flow4_1, &flow4_2, st, sk, sc,
982 			    0, 1);
983 
984 		if (st->bytes[0] != 0) /* first flow from state */
985 			ret = copy_flow_ipfix_4_to_m(&flow4_1, sc);
986 
987 		if (st->bytes[1] != 0) /* second flow from state */
988 			ret = copy_flow_ipfix_4_to_m(&flow4_2, sc);
989 	} else if (sk->af == AF_INET6) {
990 		bzero(&flow6_1, sizeof(flow6_1));
991 		bzero(&flow6_2, sizeof(flow6_2));
992 
993 		if (st->direction == PF_OUT)
994 			copy_flow_ipfix_6_data(&flow6_1, &flow6_2, st, sk, sc,
995 			    1, 0);
996 		else
997 			copy_flow_ipfix_6_data(&flow6_1, &flow6_2, st, sk, sc,
998 			    0, 1);
999 
1000 		if (st->bytes[0] != 0) /* first flow from state */
1001 			ret = copy_flow_ipfix_6_to_m(&flow6_1, sc);
1002 
1003 		if (st->bytes[1] != 0) /* second flow from state */
1004 			ret = copy_flow_ipfix_6_to_m(&flow6_2, sc);
1005 	}
1006 	return (ret);
1007 }
1008 
1009 void
1010 pflow_timeout(void *v)
1011 {
1012 	struct pflow_softc	*sc = v;
1013 
1014 	switch (sc->sc_version) {
1015 	case PFLOW_PROTO_5:
1016 		pflow_sendout_v5(sc);
1017 		break;
1018 	case PFLOW_PROTO_10:
1019 		pflow_sendout_ipfix(sc, AF_INET);
1020 		break;
1021 	default: /* NOTREACHED */
1022 		break;
1023 	}
1024 }
1025 
1026 void
1027 pflow_timeout6(void *v)
1028 {
1029 	struct pflow_softc	*sc = v;
1030 
1031 	pflow_sendout_ipfix(sc, AF_INET6);
1032 }
1033 
1034 void
1035 pflow_timeout_tmpl(void *v)
1036 {
1037 	struct pflow_softc	*sc = v;
1038 
1039 	pflow_sendout_ipfix_tmpl(sc);
1040 }
1041 
1042 void
1043 pflow_flush(struct pflow_softc *sc)
1044 {
1045 	switch (sc->sc_version) {
1046 	case PFLOW_PROTO_5:
1047 		pflow_sendout_v5(sc);
1048 		break;
1049 	case PFLOW_PROTO_10:
1050 		pflow_sendout_ipfix(sc, AF_INET);
1051 		pflow_sendout_ipfix(sc, AF_INET6);
1052 		break;
1053 	default: /* NOTREACHED */
1054 		break;
1055 	}
1056 }
1057 
1058 int
1059 pflow_sendout_v5(struct pflow_softc *sc)
1060 {
1061 	struct mbuf		*m = sc->sc_mbuf;
1062 	struct pflow_header	*h;
1063 	struct ifnet		*ifp = &sc->sc_if;
1064 	struct timespec		tv;
1065 
1066 	timeout_del(&sc->sc_tmo);
1067 
1068 	if (m == NULL)
1069 		return (0);
1070 
1071 	sc->sc_mbuf = NULL;
1072 	if (!(ifp->if_flags & IFF_RUNNING)) {
1073 		m_freem(m);
1074 		return (0);
1075 	}
1076 
1077 	pflowstats.pflow_packets++;
1078 	h = mtod(m, struct pflow_header *);
1079 	h->count = htons(sc->sc_count);
1080 
1081 	/* populate pflow_header */
1082 	h->uptime_ms = htonl(getuptime() * 1000);
1083 
1084 	getnanotime(&tv);
1085 	h->time_sec = htonl(tv.tv_sec);			/* XXX 2038 */
1086 	h->time_nanosec = htonl(tv.tv_nsec);
1087 	if (mq_enqueue(&sc->sc_outputqueue, m) == 0)
1088 		task_add(net_tq(ifp->if_index), &sc->sc_outputtask);
1089 	return (0);
1090 }
1091 
1092 int
1093 pflow_sendout_ipfix(struct pflow_softc *sc, sa_family_t af)
1094 {
1095 	struct mbuf			*m;
1096 	struct pflow_v10_header		*h10;
1097 	struct pflow_set_header		*set_hdr;
1098 	struct ifnet			*ifp = &sc->sc_if;
1099 	u_int32_t			 count;
1100 	int				 set_length;
1101 
1102 	switch (af) {
1103 	case AF_INET:
1104 		m = sc->sc_mbuf;
1105 		timeout_del(&sc->sc_tmo);
1106 		if (m == NULL)
1107 			return (0);
1108 		sc->sc_mbuf = NULL;
1109 		count = sc->sc_count4;
1110 		set_length = sizeof(struct pflow_set_header)
1111 		    + sc->sc_count4 * sizeof(struct pflow_ipfix_flow4);
1112 		break;
1113 	case AF_INET6:
1114 		m = sc->sc_mbuf6;
1115 		timeout_del(&sc->sc_tmo6);
1116 		if (m == NULL)
1117 			return (0);
1118 		sc->sc_mbuf6 = NULL;
1119 		count = sc->sc_count6;
1120 		set_length = sizeof(struct pflow_set_header)
1121 		    + sc->sc_count6 * sizeof(struct pflow_ipfix_flow6);
1122 		break;
1123 	default:
1124 		unhandled_af(af);
1125 	}
1126 
1127 	if (!(ifp->if_flags & IFF_RUNNING)) {
1128 		m_freem(m);
1129 		return (0);
1130 	}
1131 
1132 	pflowstats.pflow_packets++;
1133 	set_hdr = mtod(m, struct pflow_set_header *);
1134 	set_hdr->set_length = htons(set_length);
1135 
1136 	/* populate pflow_header */
1137 	M_PREPEND(m, sizeof(struct pflow_v10_header), M_DONTWAIT);
1138 	if (m == NULL) {
1139 		pflowstats.pflow_onomem++;
1140 		return (ENOBUFS);
1141 	}
1142 	h10 = mtod(m, struct pflow_v10_header *);
1143 	h10->version = htons(PFLOW_PROTO_10);
1144 	h10->length = htons(PFLOW_IPFIX_HDRLEN + set_length);
1145 	h10->time_sec = htonl(gettime());		/* XXX 2038 */
1146 	h10->flow_sequence = htonl(sc->sc_sequence);
1147 	sc->sc_sequence += count;
1148 	h10->observation_dom = htonl(PFLOW_ENGINE_TYPE);
1149 	if (mq_enqueue(&sc->sc_outputqueue, m) == 0)
1150 		task_add(net_tq(ifp->if_index), &sc->sc_outputtask);
1151 	return (0);
1152 }
1153 
1154 int
1155 pflow_sendout_ipfix_tmpl(struct pflow_softc *sc)
1156 {
1157 	struct mbuf			*m;
1158 	struct pflow_v10_header		*h10;
1159 	struct ifnet			*ifp = &sc->sc_if;
1160 
1161 	timeout_del(&sc->sc_tmo_tmpl);
1162 
1163 	if (!(ifp->if_flags & IFF_RUNNING)) {
1164 		return (0);
1165 	}
1166 	m = pflow_get_mbuf(NULL, 0);
1167 	if (m == NULL)
1168 		return (0);
1169 	if (m_copyback(m, 0, sizeof(struct pflow_ipfix_tmpl),
1170 	    &sc->sc_tmpl_ipfix, M_NOWAIT)) {
1171 		m_freem(m);
1172 		return (0);
1173 	}
1174 	pflowstats.pflow_packets++;
1175 
1176 	/* populate pflow_header */
1177 	M_PREPEND(m, sizeof(struct pflow_v10_header), M_DONTWAIT);
1178 	if (m == NULL) {
1179 		pflowstats.pflow_onomem++;
1180 		return (ENOBUFS);
1181 	}
1182 	h10 = mtod(m, struct pflow_v10_header *);
1183 	h10->version = htons(PFLOW_PROTO_10);
1184 	h10->length = htons(PFLOW_IPFIX_HDRLEN + sizeof(struct
1185 	    pflow_ipfix_tmpl));
1186 	h10->time_sec = htonl(gettime());		/* XXX 2038 */
1187 	h10->flow_sequence = htonl(sc->sc_sequence);
1188 	h10->observation_dom = htonl(PFLOW_ENGINE_TYPE);
1189 
1190 	timeout_add_sec(&sc->sc_tmo_tmpl, PFLOW_TMPL_TIMEOUT);
1191 	if (mq_enqueue(&sc->sc_outputqueue, m) == 0)
1192 		task_add(net_tq(ifp->if_index), &sc->sc_outputtask);
1193 	return (0);
1194 }
1195 
1196 int
1197 pflow_sendout_mbuf(struct pflow_softc *sc, struct mbuf *m)
1198 {
1199 	counters_pkt(sc->sc_if.if_counters,
1200 	            ifc_opackets, ifc_obytes, m->m_pkthdr.len);
1201 
1202 	if (sc->so == NULL) {
1203 		m_freem(m);
1204 		return (EINVAL);
1205 	}
1206 	return (sosend(sc->so, sc->send_nam, NULL, m, NULL, 0));
1207 }
1208 
1209 int
1210 pflow_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp,
1211     void *newp, size_t newlen)
1212 {
1213 	if (namelen != 1)
1214 		return (ENOTDIR);
1215 
1216 	switch (name[0]) {
1217 	case NET_PFLOW_STATS:
1218 		if (newp != NULL)
1219 			return (EPERM);
1220 		return (sysctl_struct(oldp, oldlenp, newp, newlen,
1221 		    &pflowstats, sizeof(pflowstats)));
1222 	default:
1223 		return (EOPNOTSUPP);
1224 	}
1225 	return (0);
1226 }
1227