Bug Summary

File:net/if_pflow.c
Warning:line 431, column 26
Result of 'malloc' is converted to a pointer of type 'struct sockaddr', which is incompatible with sizeof operand type 'struct sockaddr_in'

Annotated Source Code

Press '?' to see keyboard shortcuts

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