Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/netpfil/pf/pflow.c
39563 views
1
/* $OpenBSD: if_pflow.c,v 1.100 2023/11/09 08:53:20 mvs Exp $ */
2
3
/*
4
* Copyright (c) 2023 Rubicon Communications, LLC (Netgate)
5
* Copyright (c) 2011 Florian Obser <[email protected]>
6
* Copyright (c) 2011 Sebastian Benoit <[email protected]>
7
* Copyright (c) 2008 Henning Brauer <[email protected]>
8
* Copyright (c) 2008 Joerg Goltermann <[email protected]>
9
*
10
* Permission to use, copy, modify, and distribute this software for any
11
* purpose with or without fee is hereby granted, provided that the above
12
* copyright notice and this permission notice appear in all copies.
13
*
14
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
15
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
16
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
17
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
18
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
19
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
20
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21
*/
22
23
#include <sys/cdefs.h>
24
#include <sys/param.h>
25
#include <sys/bus.h>
26
#include <sys/callout.h>
27
#include <sys/endian.h>
28
#include <sys/interrupt.h>
29
#include <sys/jail.h>
30
#include <sys/kernel.h>
31
#include <sys/malloc.h>
32
#include <sys/module.h>
33
#include <sys/mbuf.h>
34
#include <sys/socket.h>
35
#include <sys/socketvar.h>
36
#include <sys/sockio.h>
37
#include <sys/sysctl.h>
38
#include <sys/systm.h>
39
#include <sys/priv.h>
40
41
#include <net/if.h>
42
#include <net/if_types.h>
43
#include <net/bpf.h>
44
#include <net/route.h>
45
#include <netinet/in.h>
46
#include <netinet/if_ether.h>
47
#include <netinet/tcp.h>
48
49
#include <netinet/ip.h>
50
#include <netinet/ip_icmp.h>
51
#include <netinet/ip_var.h>
52
#include <netinet/udp.h>
53
#include <netinet/udp_var.h>
54
#include <netinet/in_pcb.h>
55
56
#include <netlink/netlink.h>
57
#include <netlink/netlink_ctl.h>
58
#include <netlink/netlink_generic.h>
59
#include <netlink/netlink_message_writer.h>
60
61
#include <net/pfvar.h>
62
#include <net/pflow.h>
63
#include "net/if_var.h"
64
65
#define PFLOW_MINMTU \
66
(sizeof(struct pflow_header) + sizeof(struct pflow_flow))
67
68
#ifdef PFLOWDEBUG
69
#define DPRINTF(x) do { printf x ; } while (0)
70
#else
71
#define DPRINTF(x)
72
#endif
73
74
enum pflow_family_t {
75
PFLOW_INET,
76
PFLOW_INET6,
77
PFLOW_NAT4,
78
};
79
80
static void pflow_output_process(void *);
81
static int pflow_create(int);
82
static int pflow_destroy(int, bool);
83
static int pflow_calc_mtu(struct pflow_softc *, int, int);
84
static void pflow_setmtu(struct pflow_softc *, int);
85
static int pflowvalidsockaddr(const struct sockaddr *, int);
86
87
static struct mbuf *pflow_get_mbuf(struct pflow_softc *, u_int16_t);
88
static void pflow_flush(struct pflow_softc *);
89
static int pflow_sendout_v5(struct pflow_softc *);
90
static int pflow_sendout_ipfix(struct pflow_softc *, enum pflow_family_t);
91
static int pflow_sendout_ipfix_tmpl(struct pflow_softc *);
92
static int pflow_sendout_mbuf(struct pflow_softc *, struct mbuf *);
93
static int sysctl_pflowstats(SYSCTL_HANDLER_ARGS);
94
static void pflow_timeout(void *);
95
static void pflow_timeout6(void *);
96
static void pflow_timeout_tmpl(void *);
97
static void pflow_timeout_nat4(void *);
98
static void copy_flow_data(struct pflow_flow *, struct pflow_flow *,
99
const struct pf_kstate *, struct pf_state_key *, int, int);
100
static void copy_flow_ipfix_4_data(struct pflow_ipfix_flow4 *,
101
struct pflow_ipfix_flow4 *, const struct pf_kstate *, struct pf_state_key *,
102
struct pflow_softc *, int, int);
103
static void copy_flow_ipfix_6_data(struct pflow_ipfix_flow6 *,
104
struct pflow_ipfix_flow6 *, const struct pf_kstate *, struct pf_state_key *,
105
struct pflow_softc *, int, int);
106
static int pflow_pack_flow(const struct pf_kstate *, struct pf_state_key *,
107
struct pflow_softc *);
108
static int pflow_pack_flow_ipfix(const struct pf_kstate *, struct pf_state_key *,
109
struct pflow_softc *);
110
static void export_pflow(const struct pf_kstate *);
111
static int export_pflow_if(const struct pf_kstate*, struct pf_state_key *,
112
struct pflow_softc *);
113
static int copy_flow_to_m(struct pflow_flow *flow, struct pflow_softc *sc);
114
static int copy_flow_ipfix_4_to_m(struct pflow_ipfix_flow4 *flow,
115
struct pflow_softc *sc);
116
static int copy_flow_ipfix_6_to_m(struct pflow_ipfix_flow6 *flow,
117
struct pflow_softc *sc);
118
static int copy_nat_ipfix_4_to_m(struct pflow_ipfix_nat4 *,
119
const struct pf_kstate *, struct pflow_softc *,
120
uint8_t, uint64_t);
121
122
static const char pflowname[] = "pflow";
123
124
enum pflowstat_counters {
125
pflow_flows,
126
pflow_packets,
127
pflow_onomem,
128
pflow_oerrors,
129
pflow_ncounters,
130
};
131
struct pflowstats_ctr {
132
counter_u64_t c[pflow_ncounters];
133
};
134
135
/**
136
* Locking concept
137
*
138
* The list of pflow devices (V_pflowif_list) is managed through epoch.
139
* It is safe to read the list without locking (while in NET_EPOCH).
140
* There may only be one simultaneous modifier, hence we need V_pflow_list_mtx
141
* on every add/delete.
142
*
143
* Each pflow interface protects its own data with the sc_lock mutex.
144
*
145
* We do not require any pf locks, and in fact expect to be called without
146
* hashrow locks held.
147
**/
148
149
VNET_DEFINE(struct unrhdr *, pflow_unr);
150
#define V_pflow_unr VNET(pflow_unr)
151
VNET_DEFINE(CK_LIST_HEAD(, pflow_softc), pflowif_list);
152
#define V_pflowif_list VNET(pflowif_list)
153
VNET_DEFINE(struct mtx, pflowif_list_mtx);
154
#define V_pflowif_list_mtx VNET(pflowif_list_mtx)
155
VNET_DEFINE(struct pflowstats_ctr, pflowstat);
156
#define V_pflowstats VNET(pflowstat)
157
158
#define PFLOW_LOCK(_sc) mtx_lock(&(_sc)->sc_lock)
159
#define PFLOW_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_lock)
160
#define PFLOW_ASSERT(_sc) mtx_assert(&(_sc)->sc_lock, MA_OWNED)
161
162
SYSCTL_NODE(_net, OID_AUTO, pflow, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
163
"PFLOW");
164
SYSCTL_PROC(_net_pflow, OID_AUTO, stats, CTLTYPE_OPAQUE | CTLFLAG_RD | CTLFLAG_MPSAFE,
165
0, 0, sysctl_pflowstats, "S,pflowstats",
166
"PFLOW statistics (struct pflowstats, net/if_pflow.h)");
167
168
static inline void
169
pflowstat_inc(enum pflowstat_counters c)
170
{
171
counter_u64_add(V_pflowstats.c[c], 1);
172
}
173
174
static void
175
vnet_pflowattach(void)
176
{
177
CK_LIST_INIT(&V_pflowif_list);
178
mtx_init(&V_pflowif_list_mtx, "pflow interface list mtx", NULL, MTX_DEF);
179
180
V_pflow_unr = new_unrhdr(0, PFLOW_MAX_ENTRIES - 1, &V_pflowif_list_mtx);
181
182
for (int i = 0; i < pflow_ncounters; i++)
183
V_pflowstats.c[i] = counter_u64_alloc(M_WAITOK);
184
}
185
VNET_SYSINIT(vnet_pflowattach, SI_SUB_PROTO_FIREWALL, SI_ORDER_ANY,
186
vnet_pflowattach, NULL);
187
188
static int
189
pflow_jail_remove(void *obj, void *data __unused)
190
{
191
#ifdef VIMAGE
192
const struct prison *pr = obj;
193
#endif
194
struct pflow_softc *sc, *tmp;
195
196
CURVNET_SET(pr->pr_vnet);
197
CK_LIST_FOREACH_SAFE(sc, &V_pflowif_list, sc_next, tmp) {
198
pflow_destroy(sc->sc_id, false);
199
}
200
CURVNET_RESTORE();
201
202
return (0);
203
}
204
205
static void
206
vnet_pflowdetach(void)
207
{
208
209
/* Should have been done by pflow_jail_remove() */
210
MPASS(CK_LIST_EMPTY(&V_pflowif_list));
211
delete_unrhdr(V_pflow_unr);
212
mtx_destroy(&V_pflowif_list_mtx);
213
214
for (int i = 0; i < pflow_ncounters; i++)
215
counter_u64_free(V_pflowstats.c[i]);
216
}
217
VNET_SYSUNINIT(vnet_pflowdetach, SI_SUB_PROTO_FIREWALL, SI_ORDER_FOURTH,
218
vnet_pflowdetach, NULL);
219
220
static void
221
vnet_pflow_finalise(void)
222
{
223
/*
224
* Ensure we've freed all interfaces, and do not have pending
225
* epoch cleanup calls.
226
*/
227
NET_EPOCH_DRAIN_CALLBACKS();
228
}
229
VNET_SYSUNINIT(vnet_pflow_finalise, SI_SUB_PROTO_FIREWALL, SI_ORDER_THIRD,
230
vnet_pflow_finalise, NULL);
231
232
static void
233
pflow_output_process(void *arg)
234
{
235
struct mbufq ml;
236
struct pflow_softc *sc = arg;
237
struct mbuf *m;
238
239
mbufq_init(&ml, 0);
240
241
PFLOW_LOCK(sc);
242
mbufq_concat(&ml, &sc->sc_outputqueue);
243
PFLOW_UNLOCK(sc);
244
245
CURVNET_SET(sc->sc_vnet);
246
while ((m = mbufq_dequeue(&ml)) != NULL) {
247
pflow_sendout_mbuf(sc, m);
248
}
249
CURVNET_RESTORE();
250
}
251
252
static int
253
pflow_create(int unit)
254
{
255
struct pflow_softc *pflowif;
256
int error;
257
258
pflowif = malloc(sizeof(*pflowif), M_DEVBUF, M_WAITOK|M_ZERO);
259
mtx_init(&pflowif->sc_lock, "pflowlk", NULL, MTX_DEF);
260
pflowif->sc_version = PFLOW_PROTO_DEFAULT;
261
pflowif->sc_observation_dom = PFLOW_ENGINE_TYPE;
262
263
/* ipfix template init */
264
bzero(&pflowif->sc_tmpl_ipfix,sizeof(pflowif->sc_tmpl_ipfix));
265
pflowif->sc_tmpl_ipfix.set_header.set_id =
266
htons(PFLOW_IPFIX_TMPL_SET_ID);
267
pflowif->sc_tmpl_ipfix.set_header.set_length =
268
htons(sizeof(struct pflow_ipfix_tmpl));
269
270
/* ipfix IPv4 template */
271
pflowif->sc_tmpl_ipfix.ipv4_tmpl.h.tmpl_id =
272
htons(PFLOW_IPFIX_TMPL_IPV4_ID);
273
pflowif->sc_tmpl_ipfix.ipv4_tmpl.h.field_count
274
= htons(PFLOW_IPFIX_TMPL_IPV4_FIELD_COUNT);
275
pflowif->sc_tmpl_ipfix.ipv4_tmpl.src_ip.field_id =
276
htons(PFIX_IE_sourceIPv4Address);
277
pflowif->sc_tmpl_ipfix.ipv4_tmpl.src_ip.len = htons(4);
278
pflowif->sc_tmpl_ipfix.ipv4_tmpl.dest_ip.field_id =
279
htons(PFIX_IE_destinationIPv4Address);
280
pflowif->sc_tmpl_ipfix.ipv4_tmpl.dest_ip.len = htons(4);
281
pflowif->sc_tmpl_ipfix.ipv4_tmpl.if_index_in.field_id =
282
htons(PFIX_IE_ingressInterface);
283
pflowif->sc_tmpl_ipfix.ipv4_tmpl.if_index_in.len = htons(4);
284
pflowif->sc_tmpl_ipfix.ipv4_tmpl.if_index_out.field_id =
285
htons(PFIX_IE_egressInterface);
286
pflowif->sc_tmpl_ipfix.ipv4_tmpl.if_index_out.len = htons(4);
287
pflowif->sc_tmpl_ipfix.ipv4_tmpl.packets.field_id =
288
htons(PFIX_IE_packetDeltaCount);
289
pflowif->sc_tmpl_ipfix.ipv4_tmpl.packets.len = htons(8);
290
pflowif->sc_tmpl_ipfix.ipv4_tmpl.octets.field_id =
291
htons(PFIX_IE_octetDeltaCount);
292
pflowif->sc_tmpl_ipfix.ipv4_tmpl.octets.len = htons(8);
293
pflowif->sc_tmpl_ipfix.ipv4_tmpl.start.field_id =
294
htons(PFIX_IE_flowStartMilliseconds);
295
pflowif->sc_tmpl_ipfix.ipv4_tmpl.start.len = htons(8);
296
pflowif->sc_tmpl_ipfix.ipv4_tmpl.finish.field_id =
297
htons(PFIX_IE_flowEndMilliseconds);
298
pflowif->sc_tmpl_ipfix.ipv4_tmpl.finish.len = htons(8);
299
pflowif->sc_tmpl_ipfix.ipv4_tmpl.src_port.field_id =
300
htons(PFIX_IE_sourceTransportPort);
301
pflowif->sc_tmpl_ipfix.ipv4_tmpl.src_port.len = htons(2);
302
pflowif->sc_tmpl_ipfix.ipv4_tmpl.dest_port.field_id =
303
htons(PFIX_IE_destinationTransportPort);
304
pflowif->sc_tmpl_ipfix.ipv4_tmpl.dest_port.len = htons(2);
305
pflowif->sc_tmpl_ipfix.ipv4_tmpl.tos.field_id =
306
htons(PFIX_IE_ipClassOfService);
307
pflowif->sc_tmpl_ipfix.ipv4_tmpl.tos.len = htons(1);
308
pflowif->sc_tmpl_ipfix.ipv4_tmpl.protocol.field_id =
309
htons(PFIX_IE_protocolIdentifier);
310
pflowif->sc_tmpl_ipfix.ipv4_tmpl.protocol.len = htons(1);
311
312
/* ipfix IPv6 template */
313
pflowif->sc_tmpl_ipfix.ipv6_tmpl.h.tmpl_id =
314
htons(PFLOW_IPFIX_TMPL_IPV6_ID);
315
pflowif->sc_tmpl_ipfix.ipv6_tmpl.h.field_count =
316
htons(PFLOW_IPFIX_TMPL_IPV6_FIELD_COUNT);
317
pflowif->sc_tmpl_ipfix.ipv6_tmpl.src_ip.field_id =
318
htons(PFIX_IE_sourceIPv6Address);
319
pflowif->sc_tmpl_ipfix.ipv6_tmpl.src_ip.len = htons(16);
320
pflowif->sc_tmpl_ipfix.ipv6_tmpl.dest_ip.field_id =
321
htons(PFIX_IE_destinationIPv6Address);
322
pflowif->sc_tmpl_ipfix.ipv6_tmpl.dest_ip.len = htons(16);
323
pflowif->sc_tmpl_ipfix.ipv6_tmpl.if_index_in.field_id =
324
htons(PFIX_IE_ingressInterface);
325
pflowif->sc_tmpl_ipfix.ipv6_tmpl.if_index_in.len = htons(4);
326
pflowif->sc_tmpl_ipfix.ipv6_tmpl.if_index_out.field_id =
327
htons(PFIX_IE_egressInterface);
328
pflowif->sc_tmpl_ipfix.ipv6_tmpl.if_index_out.len = htons(4);
329
pflowif->sc_tmpl_ipfix.ipv6_tmpl.packets.field_id =
330
htons(PFIX_IE_packetDeltaCount);
331
pflowif->sc_tmpl_ipfix.ipv6_tmpl.packets.len = htons(8);
332
pflowif->sc_tmpl_ipfix.ipv6_tmpl.octets.field_id =
333
htons(PFIX_IE_octetDeltaCount);
334
pflowif->sc_tmpl_ipfix.ipv6_tmpl.octets.len = htons(8);
335
pflowif->sc_tmpl_ipfix.ipv6_tmpl.start.field_id =
336
htons(PFIX_IE_flowStartMilliseconds);
337
pflowif->sc_tmpl_ipfix.ipv6_tmpl.start.len = htons(8);
338
pflowif->sc_tmpl_ipfix.ipv6_tmpl.finish.field_id =
339
htons(PFIX_IE_flowEndMilliseconds);
340
pflowif->sc_tmpl_ipfix.ipv6_tmpl.finish.len = htons(8);
341
pflowif->sc_tmpl_ipfix.ipv6_tmpl.src_port.field_id =
342
htons(PFIX_IE_sourceTransportPort);
343
pflowif->sc_tmpl_ipfix.ipv6_tmpl.src_port.len = htons(2);
344
pflowif->sc_tmpl_ipfix.ipv6_tmpl.dest_port.field_id =
345
htons(PFIX_IE_destinationTransportPort);
346
pflowif->sc_tmpl_ipfix.ipv6_tmpl.dest_port.len = htons(2);
347
pflowif->sc_tmpl_ipfix.ipv6_tmpl.tos.field_id =
348
htons(PFIX_IE_ipClassOfService);
349
pflowif->sc_tmpl_ipfix.ipv6_tmpl.tos.len = htons(1);
350
pflowif->sc_tmpl_ipfix.ipv6_tmpl.protocol.field_id =
351
htons(PFIX_IE_protocolIdentifier);
352
pflowif->sc_tmpl_ipfix.ipv6_tmpl.protocol.len = htons(1);
353
354
/* NAT44 create template */
355
pflowif->sc_tmpl_ipfix.nat44_tmpl.h.tmpl_id =
356
htons(PFLOW_IPFIX_TMPL_NAT44_ID);
357
pflowif->sc_tmpl_ipfix.nat44_tmpl.h.field_count =
358
htons(PFLOW_IPFIX_TMPL_NAT44_FIELD_COUNT);
359
pflowif->sc_tmpl_ipfix.nat44_tmpl.timestamp.field_id =
360
htons(PFIX_IE_timeStamp);
361
pflowif->sc_tmpl_ipfix.nat44_tmpl.timestamp.len =
362
htons(8);
363
pflowif->sc_tmpl_ipfix.nat44_tmpl.nat_event.field_id =
364
htons(PFIX_IE_natEvent);
365
pflowif->sc_tmpl_ipfix.nat44_tmpl.nat_event.len =
366
htons(1);
367
pflowif->sc_tmpl_ipfix.nat44_tmpl.protocol.field_id =
368
htons(PFIX_IE_protocolIdentifier);
369
pflowif->sc_tmpl_ipfix.nat44_tmpl.protocol.len = htons(1);
370
pflowif->sc_tmpl_ipfix.nat44_tmpl.src_ip.field_id =
371
htons(PFIX_IE_sourceIPv4Address);
372
pflowif->sc_tmpl_ipfix.nat44_tmpl.src_ip.len =
373
htons(4);
374
pflowif->sc_tmpl_ipfix.nat44_tmpl.src_port.field_id =
375
htons(PFIX_IE_sourceTransportPort);
376
pflowif->sc_tmpl_ipfix.nat44_tmpl.src_port.len = htons(2);
377
pflowif->sc_tmpl_ipfix.nat44_tmpl.postnat_src_ip.field_id =
378
htons(PFIX_IE_postNATSourceIPv4Address);
379
pflowif->sc_tmpl_ipfix.nat44_tmpl.postnat_src_ip.len =
380
htons(4);
381
pflowif->sc_tmpl_ipfix.nat44_tmpl.postnat_src_port.field_id =
382
htons(PFIX_IE_postNAPTSourceTransportPort);
383
pflowif->sc_tmpl_ipfix.nat44_tmpl.postnat_src_port.len =
384
htons(2);
385
pflowif->sc_tmpl_ipfix.nat44_tmpl.dst_ip.field_id =
386
htons(PFIX_IE_destinationIPv4Address);
387
pflowif->sc_tmpl_ipfix.nat44_tmpl.dst_ip.len =
388
htons(4);
389
pflowif->sc_tmpl_ipfix.nat44_tmpl.dst_port.field_id =
390
htons(PFIX_IE_destinationTransportPort);
391
pflowif->sc_tmpl_ipfix.nat44_tmpl.dst_port.len = htons(2);
392
pflowif->sc_tmpl_ipfix.nat44_tmpl.postnat_dst_ip.field_id =
393
htons(PFIX_IE_postNATDestinationIPv4Address);
394
pflowif->sc_tmpl_ipfix.nat44_tmpl.postnat_dst_ip.len =
395
htons(4);
396
pflowif->sc_tmpl_ipfix.nat44_tmpl.postnat_dst_port.field_id =
397
htons(PFIX_IE_postNAPTDestinationTransportPort);
398
pflowif->sc_tmpl_ipfix.nat44_tmpl.postnat_dst_port.len =
399
htons(2);
400
401
pflowif->sc_id = unit;
402
pflowif->sc_vnet = curvnet;
403
404
mbufq_init(&pflowif->sc_outputqueue, 8192);
405
pflow_setmtu(pflowif, ETHERMTU);
406
407
callout_init_mtx(&pflowif->sc_tmo, &pflowif->sc_lock, 0);
408
callout_init_mtx(&pflowif->sc_tmo6, &pflowif->sc_lock, 0);
409
callout_init_mtx(&pflowif->sc_tmo_nat4, &pflowif->sc_lock, 0);
410
callout_init_mtx(&pflowif->sc_tmo_tmpl, &pflowif->sc_lock, 0);
411
412
error = swi_add(&pflowif->sc_swi_ie, pflowname, pflow_output_process,
413
pflowif, SWI_NET, INTR_MPSAFE, &pflowif->sc_swi_cookie);
414
if (error) {
415
free(pflowif, M_DEVBUF);
416
return (error);
417
}
418
419
/* Insert into list of pflows */
420
mtx_lock(&V_pflowif_list_mtx);
421
CK_LIST_INSERT_HEAD(&V_pflowif_list, pflowif, sc_next);
422
mtx_unlock(&V_pflowif_list_mtx);
423
424
V_pflow_export_state_ptr = export_pflow;
425
426
return (0);
427
}
428
429
static void
430
pflow_free_cb(struct epoch_context *ctx)
431
{
432
struct pflow_softc *sc;
433
434
sc = __containerof(ctx, struct pflow_softc, sc_epoch_ctx);
435
436
free(sc, M_DEVBUF);
437
}
438
439
static int
440
pflow_destroy(int unit, bool drain)
441
{
442
struct pflow_softc *sc;
443
int error __diagused;
444
445
mtx_lock(&V_pflowif_list_mtx);
446
CK_LIST_FOREACH(sc, &V_pflowif_list, sc_next) {
447
if (sc->sc_id == unit)
448
break;
449
}
450
if (sc == NULL) {
451
mtx_unlock(&V_pflowif_list_mtx);
452
return (ENOENT);
453
}
454
CK_LIST_REMOVE(sc, sc_next);
455
if (CK_LIST_EMPTY(&V_pflowif_list))
456
V_pflow_export_state_ptr = NULL;
457
mtx_unlock(&V_pflowif_list_mtx);
458
459
sc->sc_dying = 1;
460
461
if (drain) {
462
/* Let's be sure no one is using this interface any more. */
463
NET_EPOCH_DRAIN_CALLBACKS();
464
}
465
466
error = swi_remove(sc->sc_swi_cookie);
467
MPASS(error == 0);
468
error = intr_event_destroy(sc->sc_swi_ie);
469
MPASS(error == 0);
470
471
callout_drain(&sc->sc_tmo);
472
callout_drain(&sc->sc_tmo6);
473
callout_drain(&sc->sc_tmo_nat4);
474
callout_drain(&sc->sc_tmo_tmpl);
475
476
m_freem(sc->sc_mbuf);
477
m_freem(sc->sc_mbuf6);
478
m_freem(sc->sc_mbuf_nat4);
479
480
PFLOW_LOCK(sc);
481
mbufq_drain(&sc->sc_outputqueue);
482
if (sc->so != NULL) {
483
soclose(sc->so);
484
sc->so = NULL;
485
}
486
if (sc->sc_flowdst != NULL)
487
free(sc->sc_flowdst, M_DEVBUF);
488
if (sc->sc_flowsrc != NULL)
489
free(sc->sc_flowsrc, M_DEVBUF);
490
PFLOW_UNLOCK(sc);
491
492
mtx_destroy(&sc->sc_lock);
493
494
free_unr(V_pflow_unr, unit);
495
496
NET_EPOCH_CALL(pflow_free_cb, &sc->sc_epoch_ctx);
497
498
return (0);
499
}
500
501
static int
502
pflowvalidsockaddr(const struct sockaddr *sa, int ignore_port)
503
{
504
const struct sockaddr_in6 *sin6;
505
const struct sockaddr_in *sin;
506
507
if (sa == NULL)
508
return (0);
509
switch(sa->sa_family) {
510
case AF_INET:
511
sin = (const struct sockaddr_in *)sa;
512
return (sin->sin_addr.s_addr != INADDR_ANY &&
513
(ignore_port || sin->sin_port != 0));
514
case AF_INET6:
515
sin6 = (const struct sockaddr_in6 *)sa;
516
return (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr) &&
517
(ignore_port || sin6->sin6_port != 0));
518
default:
519
return (0);
520
}
521
}
522
523
int
524
pflow_calc_mtu(struct pflow_softc *sc, int mtu, int hdrsz)
525
{
526
size_t min;
527
528
sc->sc_maxcount4 = (mtu - hdrsz -
529
sizeof(struct udpiphdr)) / sizeof(struct pflow_ipfix_flow4);
530
sc->sc_maxcount6 = (mtu - hdrsz -
531
sizeof(struct udpiphdr)) / sizeof(struct pflow_ipfix_flow6);
532
sc->sc_maxcount_nat4 = (mtu - hdrsz -
533
sizeof(struct udpiphdr)) / sizeof(struct pflow_ipfix_nat4);
534
if (sc->sc_maxcount4 > PFLOW_MAXFLOWS)
535
sc->sc_maxcount4 = PFLOW_MAXFLOWS;
536
if (sc->sc_maxcount6 > PFLOW_MAXFLOWS)
537
sc->sc_maxcount6 = PFLOW_MAXFLOWS;
538
if (sc->sc_maxcount_nat4 > PFLOW_MAXFLOWS)
539
sc->sc_maxcount_nat4 = PFLOW_MAXFLOWS;
540
541
min = MIN(sc->sc_maxcount4 * sizeof(struct pflow_ipfix_flow4),
542
sc->sc_maxcount6 * sizeof(struct pflow_ipfix_flow6));
543
min = MIN(min, sc->sc_maxcount_nat4 * sizeof(struct pflow_ipfix_nat4));
544
545
return (hdrsz + sizeof(struct udpiphdr) + min);
546
}
547
548
static void
549
pflow_setmtu(struct pflow_softc *sc, int mtu_req)
550
{
551
int mtu;
552
553
mtu = mtu_req;
554
555
switch (sc->sc_version) {
556
case PFLOW_PROTO_5:
557
sc->sc_maxcount = (mtu - sizeof(struct pflow_header) -
558
sizeof(struct udpiphdr)) / sizeof(struct pflow_flow);
559
if (sc->sc_maxcount > PFLOW_MAXFLOWS)
560
sc->sc_maxcount = PFLOW_MAXFLOWS;
561
break;
562
case PFLOW_PROTO_10:
563
pflow_calc_mtu(sc, mtu, sizeof(struct pflow_v10_header));
564
break;
565
default: /* NOTREACHED */
566
break;
567
}
568
}
569
570
static struct mbuf *
571
pflow_get_mbuf(struct pflow_softc *sc, u_int16_t set_id)
572
{
573
struct pflow_set_header set_hdr;
574
struct pflow_header h;
575
struct mbuf *m;
576
577
MGETHDR(m, M_NOWAIT, MT_DATA);
578
if (m == NULL) {
579
pflowstat_inc(pflow_onomem);
580
return (NULL);
581
}
582
583
MCLGET(m, M_NOWAIT);
584
if ((m->m_flags & M_EXT) == 0) {
585
m_free(m);
586
pflowstat_inc(pflow_onomem);
587
return (NULL);
588
}
589
590
m->m_len = m->m_pkthdr.len = 0;
591
592
if (sc == NULL) /* get only a new empty mbuf */
593
return (m);
594
595
switch (sc->sc_version) {
596
case PFLOW_PROTO_5:
597
/* populate pflow_header */
598
h.reserved1 = 0;
599
h.reserved2 = 0;
600
h.count = 0;
601
h.version = htons(PFLOW_PROTO_5);
602
h.flow_sequence = htonl(sc->sc_gcounter);
603
h.engine_type = PFLOW_ENGINE_TYPE;
604
h.engine_id = PFLOW_ENGINE_ID;
605
m_copyback(m, 0, PFLOW_HDRLEN, (caddr_t)&h);
606
607
sc->sc_count = 0;
608
callout_reset(&sc->sc_tmo, PFLOW_TIMEOUT * hz,
609
pflow_timeout, sc);
610
break;
611
case PFLOW_PROTO_10:
612
/* populate pflow_set_header */
613
set_hdr.set_length = 0;
614
set_hdr.set_id = htons(set_id);
615
m_copyback(m, 0, PFLOW_SET_HDRLEN, (caddr_t)&set_hdr);
616
break;
617
default: /* NOTREACHED */
618
break;
619
}
620
621
return (m);
622
}
623
624
static void
625
copy_flow_data(struct pflow_flow *flow1, struct pflow_flow *flow2,
626
const struct pf_kstate *st, struct pf_state_key *sk, int src, int dst)
627
{
628
flow1->src_ip = flow2->dest_ip = sk->addr[src].v4.s_addr;
629
flow1->src_port = flow2->dest_port = sk->port[src];
630
flow1->dest_ip = flow2->src_ip = sk->addr[dst].v4.s_addr;
631
flow1->dest_port = flow2->src_port = sk->port[dst];
632
633
flow1->dest_as = flow2->src_as =
634
flow1->src_as = flow2->dest_as = 0;
635
flow1->if_index_in = htons(st->if_index_in);
636
flow1->if_index_out = htons(st->if_index_out);
637
flow2->if_index_in = htons(st->if_index_out);
638
flow2->if_index_out = htons(st->if_index_in);
639
flow1->dest_mask = flow2->src_mask =
640
flow1->src_mask = flow2->dest_mask = 0;
641
642
flow1->flow_packets = htonl(st->packets[0]);
643
flow2->flow_packets = htonl(st->packets[1]);
644
flow1->flow_octets = htonl(st->bytes[0]);
645
flow2->flow_octets = htonl(st->bytes[1]);
646
647
/*
648
* Pretend the flow was created or expired when the machine came up
649
* when creation is in the future of the last time a package was seen
650
* or was created / expired before this machine came up due to pfsync.
651
*/
652
flow1->flow_start = flow2->flow_start = st->creation < 0 ||
653
st->creation > st->expire ? htonl(0) : htonl(st->creation);
654
flow1->flow_finish = flow2->flow_finish = st->expire < 0 ? htonl(0) :
655
htonl(st->expire);
656
flow1->tcp_flags = flow2->tcp_flags = 0;
657
flow1->protocol = flow2->protocol = sk->proto;
658
flow1->tos = flow2->tos = st->rule->tos;
659
}
660
661
static void
662
copy_flow_ipfix_4_data(struct pflow_ipfix_flow4 *flow1,
663
struct pflow_ipfix_flow4 *flow2, const struct pf_kstate *st,
664
struct pf_state_key *sk, struct pflow_softc *sc, int src, int dst)
665
{
666
flow1->src_ip = flow2->dest_ip = sk->addr[src].v4.s_addr;
667
flow1->src_port = flow2->dest_port = sk->port[src];
668
flow1->dest_ip = flow2->src_ip = sk->addr[dst].v4.s_addr;
669
flow1->dest_port = flow2->src_port = sk->port[dst];
670
671
flow1->if_index_in = htonl(st->if_index_in);
672
flow1->if_index_out = htonl(st->if_index_out);
673
flow2->if_index_in = htonl(st->if_index_out);
674
flow2->if_index_out = htonl(st->if_index_in);
675
676
flow1->flow_packets = htobe64(st->packets[0]);
677
flow2->flow_packets = htobe64(st->packets[1]);
678
flow1->flow_octets = htobe64(st->bytes[0]);
679
flow2->flow_octets = htobe64(st->bytes[1]);
680
681
/*
682
* Pretend the flow was created when the machine came up when creation
683
* is in the future of the last time a package was seen due to pfsync.
684
*/
685
if (st->creation > st->expire)
686
flow1->flow_start = flow2->flow_start = htobe64((time_second -
687
time_uptime)*1000);
688
else
689
flow1->flow_start = flow2->flow_start = htobe64((pf_get_time() -
690
(pf_get_uptime() - st->creation)));
691
flow1->flow_finish = flow2->flow_finish = htobe64((pf_get_time() -
692
(pf_get_uptime() - st->expire)));
693
694
flow1->protocol = flow2->protocol = sk->proto;
695
flow1->tos = flow2->tos = st->rule->tos;
696
}
697
698
static void
699
copy_flow_ipfix_6_data(struct pflow_ipfix_flow6 *flow1,
700
struct pflow_ipfix_flow6 *flow2, const struct pf_kstate *st,
701
struct pf_state_key *sk, struct pflow_softc *sc, int src, int dst)
702
{
703
bcopy(&sk->addr[src].v6, &flow1->src_ip, sizeof(flow1->src_ip));
704
bcopy(&sk->addr[src].v6, &flow2->dest_ip, sizeof(flow2->dest_ip));
705
flow1->src_port = flow2->dest_port = sk->port[src];
706
bcopy(&sk->addr[dst].v6, &flow1->dest_ip, sizeof(flow1->dest_ip));
707
bcopy(&sk->addr[dst].v6, &flow2->src_ip, sizeof(flow2->src_ip));
708
flow1->dest_port = flow2->src_port = sk->port[dst];
709
710
flow1->if_index_in = htonl(st->if_index_in);
711
flow1->if_index_out = htonl(st->if_index_out);
712
flow2->if_index_in = htonl(st->if_index_out);
713
flow2->if_index_out = htonl(st->if_index_in);
714
715
flow1->flow_packets = htobe64(st->packets[0]);
716
flow2->flow_packets = htobe64(st->packets[1]);
717
flow1->flow_octets = htobe64(st->bytes[0]);
718
flow2->flow_octets = htobe64(st->bytes[1]);
719
720
/*
721
* Pretend the flow was created when the machine came up when creation
722
* is in the future of the last time a package was seen due to pfsync.
723
*/
724
if (st->creation > st->expire)
725
flow1->flow_start = flow2->flow_start = htobe64((time_second -
726
time_uptime)*1000);
727
else
728
flow1->flow_start = flow2->flow_start = htobe64((pf_get_time() -
729
(pf_get_uptime() - st->creation)));
730
flow1->flow_finish = flow2->flow_finish = htobe64((pf_get_time() -
731
(pf_get_uptime() - st->expire)));
732
733
flow1->protocol = flow2->protocol = sk->proto;
734
flow1->tos = flow2->tos = st->rule->tos;
735
}
736
737
static void
738
copy_nat_ipfix_4_data(struct pflow_ipfix_nat4 *nat1,
739
struct pflow_ipfix_nat4 *nat2, const struct pf_kstate *st,
740
struct pf_state_key *sk, struct pflow_softc *sc, int src, int dst)
741
{
742
nat1->src_ip = nat2->dest_ip = st->key[PF_SK_STACK]->addr[src].v4.s_addr;
743
nat1->src_port = nat2->dest_port = st->key[PF_SK_STACK]->port[src];
744
nat1->dest_ip = nat2->src_ip = st->key[PF_SK_STACK]->addr[dst].v4.s_addr;
745
nat1->dest_port = nat2->src_port = st->key[PF_SK_STACK]->port[dst];
746
nat1->postnat_src_ip = nat2->postnat_dest_ip = st->key[PF_SK_WIRE]->addr[src].v4.s_addr;
747
nat1->postnat_src_port = nat2->postnat_dest_port = st->key[PF_SK_WIRE]->port[src];
748
nat1->postnat_dest_ip = nat2->postnat_src_ip = st->key[PF_SK_WIRE]->addr[dst].v4.s_addr;
749
nat1->postnat_dest_port = nat2->postnat_src_port = st->key[PF_SK_WIRE]->port[dst];
750
nat1->protocol = nat2->protocol = sk->proto;
751
752
/*
753
* Because we have to generate a create and delete event we'll fill out the
754
* timestamp and nat_event fields when we transmit. As opposed to doing this
755
* work a second time.
756
*/
757
}
758
759
static void
760
export_pflow(const struct pf_kstate *st)
761
{
762
struct pflow_softc *sc = NULL;
763
struct pf_state_key *sk;
764
765
NET_EPOCH_ASSERT();
766
767
/* e.g. if pf_state_key_attach() fails. */
768
if (st->key[PF_SK_STACK] == NULL || st->key[PF_SK_WIRE] == NULL)
769
return;
770
771
sk = st->key[st->direction == PF_IN ? PF_SK_WIRE : PF_SK_STACK];
772
773
CK_LIST_FOREACH(sc, &V_pflowif_list, sc_next) {
774
PFLOW_LOCK(sc);
775
switch (sc->sc_version) {
776
case PFLOW_PROTO_5:
777
if (sk->af == AF_INET)
778
export_pflow_if(st, sk, sc);
779
break;
780
case PFLOW_PROTO_10:
781
if (sk->af == AF_INET || sk->af == AF_INET6)
782
export_pflow_if(st, sk, sc);
783
break;
784
default: /* NOTREACHED */
785
break;
786
}
787
PFLOW_UNLOCK(sc);
788
}
789
}
790
791
static int
792
export_pflow_if(const struct pf_kstate *st, struct pf_state_key *sk,
793
struct pflow_softc *sc)
794
{
795
struct pf_kstate pfs_copy;
796
u_int64_t bytes[2];
797
int ret = 0;
798
799
if (sc->sc_version == PFLOW_PROTO_10)
800
return (pflow_pack_flow_ipfix(st, sk, sc));
801
802
/* PFLOW_PROTO_5 */
803
if ((st->bytes[0] < (u_int64_t)PFLOW_MAXBYTES)
804
&& (st->bytes[1] < (u_int64_t)PFLOW_MAXBYTES))
805
return (pflow_pack_flow(st, sk, sc));
806
807
/* flow > PFLOW_MAXBYTES need special handling */
808
bcopy(st, &pfs_copy, sizeof(pfs_copy));
809
bytes[0] = pfs_copy.bytes[0];
810
bytes[1] = pfs_copy.bytes[1];
811
812
while (bytes[0] > PFLOW_MAXBYTES) {
813
pfs_copy.bytes[0] = PFLOW_MAXBYTES;
814
pfs_copy.bytes[1] = 0;
815
816
if ((ret = pflow_pack_flow(&pfs_copy, sk, sc)) != 0)
817
return (ret);
818
if ((bytes[0] - PFLOW_MAXBYTES) > 0)
819
bytes[0] -= PFLOW_MAXBYTES;
820
}
821
822
while (bytes[1] > (u_int64_t)PFLOW_MAXBYTES) {
823
pfs_copy.bytes[1] = PFLOW_MAXBYTES;
824
pfs_copy.bytes[0] = 0;
825
826
if ((ret = pflow_pack_flow(&pfs_copy, sk, sc)) != 0)
827
return (ret);
828
if ((bytes[1] - PFLOW_MAXBYTES) > 0)
829
bytes[1] -= PFLOW_MAXBYTES;
830
}
831
832
pfs_copy.bytes[0] = bytes[0];
833
pfs_copy.bytes[1] = bytes[1];
834
835
return (pflow_pack_flow(&pfs_copy, sk, sc));
836
}
837
838
static int
839
copy_flow_to_m(struct pflow_flow *flow, struct pflow_softc *sc)
840
{
841
int ret = 0;
842
843
PFLOW_ASSERT(sc);
844
845
if (sc->sc_mbuf == NULL) {
846
if ((sc->sc_mbuf = pflow_get_mbuf(sc, 0)) == NULL)
847
return (ENOBUFS);
848
}
849
m_copyback(sc->sc_mbuf, PFLOW_HDRLEN +
850
(sc->sc_count * sizeof(struct pflow_flow)),
851
sizeof(struct pflow_flow), (caddr_t)flow);
852
853
pflowstat_inc(pflow_flows);
854
sc->sc_gcounter++;
855
sc->sc_count++;
856
857
if (sc->sc_count >= sc->sc_maxcount)
858
ret = pflow_sendout_v5(sc);
859
860
return(ret);
861
}
862
863
static int
864
copy_flow_ipfix_4_to_m(struct pflow_ipfix_flow4 *flow, struct pflow_softc *sc)
865
{
866
int ret = 0;
867
868
PFLOW_ASSERT(sc);
869
870
if (sc->sc_mbuf == NULL) {
871
if ((sc->sc_mbuf =
872
pflow_get_mbuf(sc, PFLOW_IPFIX_TMPL_IPV4_ID)) == NULL) {
873
return (ENOBUFS);
874
}
875
sc->sc_count4 = 0;
876
callout_reset(&sc->sc_tmo, PFLOW_TIMEOUT * hz,
877
pflow_timeout, sc);
878
}
879
m_copyback(sc->sc_mbuf, PFLOW_SET_HDRLEN +
880
(sc->sc_count4 * sizeof(struct pflow_ipfix_flow4)),
881
sizeof(struct pflow_ipfix_flow4), (caddr_t)flow);
882
883
pflowstat_inc(pflow_flows);
884
sc->sc_gcounter++;
885
sc->sc_count4++;
886
887
if (sc->sc_count4 >= sc->sc_maxcount4)
888
ret = pflow_sendout_ipfix(sc, PFLOW_INET);
889
return(ret);
890
}
891
892
static int
893
copy_flow_ipfix_6_to_m(struct pflow_ipfix_flow6 *flow, struct pflow_softc *sc)
894
{
895
int ret = 0;
896
897
PFLOW_ASSERT(sc);
898
899
if (sc->sc_mbuf6 == NULL) {
900
if ((sc->sc_mbuf6 =
901
pflow_get_mbuf(sc, PFLOW_IPFIX_TMPL_IPV6_ID)) == NULL) {
902
return (ENOBUFS);
903
}
904
sc->sc_count6 = 0;
905
callout_reset(&sc->sc_tmo6, PFLOW_TIMEOUT * hz,
906
pflow_timeout6, sc);
907
}
908
m_copyback(sc->sc_mbuf6, PFLOW_SET_HDRLEN +
909
(sc->sc_count6 * sizeof(struct pflow_ipfix_flow6)),
910
sizeof(struct pflow_ipfix_flow6), (caddr_t)flow);
911
912
pflowstat_inc(pflow_flows);
913
sc->sc_gcounter++;
914
sc->sc_count6++;
915
916
if (sc->sc_count6 >= sc->sc_maxcount6)
917
ret = pflow_sendout_ipfix(sc, PFLOW_INET6);
918
919
return(ret);
920
}
921
922
int
923
copy_nat_ipfix_4_to_m(struct pflow_ipfix_nat4 *nat, const struct pf_kstate *st,
924
struct pflow_softc *sc, uint8_t event, uint64_t timestamp)
925
{
926
int ret = 0;
927
928
PFLOW_ASSERT(sc);
929
930
if (sc->sc_mbuf_nat4 == NULL) {
931
if ((sc->sc_mbuf_nat4 =
932
pflow_get_mbuf(sc, PFLOW_IPFIX_TMPL_NAT44_ID)) == NULL) {
933
return (ENOBUFS);
934
}
935
sc->sc_count_nat4 = 0;
936
callout_reset(&sc->sc_tmo, PFLOW_TIMEOUT * hz,
937
pflow_timeout_nat4, sc);
938
}
939
940
nat->nat_event = event;
941
nat->timestamp = htobe64(pf_get_time() - (pf_get_uptime() - timestamp));
942
m_copyback(sc->sc_mbuf_nat4, PFLOW_SET_HDRLEN +
943
(sc->sc_count_nat4 * sizeof(struct pflow_ipfix_nat4)),
944
sizeof(struct pflow_ipfix_nat4), (caddr_t)nat);
945
sc->sc_count_nat4++;
946
947
pflowstat_inc(pflow_flows);
948
sc->sc_gcounter++;
949
950
if (sc->sc_count_nat4 >= sc->sc_maxcount_nat4)
951
ret = pflow_sendout_ipfix(sc, PFLOW_NAT4);
952
953
return (ret);
954
}
955
956
static int
957
pflow_pack_flow(const struct pf_kstate *st, struct pf_state_key *sk,
958
struct pflow_softc *sc)
959
{
960
struct pflow_flow flow1;
961
struct pflow_flow flow2;
962
int ret = 0;
963
964
bzero(&flow1, sizeof(flow1));
965
bzero(&flow2, sizeof(flow2));
966
967
if (st->direction == PF_OUT)
968
copy_flow_data(&flow1, &flow2, st, sk, 1, 0);
969
else
970
copy_flow_data(&flow1, &flow2, st, sk, 0, 1);
971
972
if (st->bytes[0] != 0) /* first flow from state */
973
ret = copy_flow_to_m(&flow1, sc);
974
975
if (st->bytes[1] != 0) /* second flow from state */
976
ret = copy_flow_to_m(&flow2, sc);
977
978
return (ret);
979
}
980
981
static bool
982
pflow_is_natd(const struct pf_kstate *st)
983
{
984
/* If ports or addresses are different we've been NAT-ed. */
985
return (memcmp(st->key[PF_SK_WIRE], st->key[PF_SK_STACK],
986
sizeof(struct pf_addr) * 2 + sizeof(uint16_t) * 2) != 0);
987
}
988
989
static int
990
pflow_pack_flow_ipfix(const struct pf_kstate *st, struct pf_state_key *sk,
991
struct pflow_softc *sc)
992
{
993
struct pflow_ipfix_flow4 flow4_1, flow4_2;
994
struct pflow_ipfix_nat4 nat4_1, nat4_2;
995
struct pflow_ipfix_flow6 flow6_1, flow6_2;
996
int ret = 0;
997
bool nat = false;
998
999
switch (sk->af) {
1000
case AF_INET:
1001
bzero(&flow4_1, sizeof(flow4_1));
1002
bzero(&flow4_2, sizeof(flow4_2));
1003
1004
nat = pflow_is_natd(st);
1005
1006
if (st->direction == PF_OUT)
1007
copy_flow_ipfix_4_data(&flow4_1, &flow4_2, st, sk, sc,
1008
1, 0);
1009
else
1010
copy_flow_ipfix_4_data(&flow4_1, &flow4_2, st, sk, sc,
1011
0, 1);
1012
1013
if (nat)
1014
copy_nat_ipfix_4_data(&nat4_1, &nat4_2, st, sk, sc, 1, 0);
1015
1016
if (st->bytes[0] != 0) /* first flow from state */ {
1017
ret = copy_flow_ipfix_4_to_m(&flow4_1, sc);
1018
1019
if (ret == 0 && nat) {
1020
ret = copy_nat_ipfix_4_to_m(&nat4_1, st, sc,
1021
PFIX_NAT_EVENT_SESSION_CREATE, st->creation);
1022
ret |= copy_nat_ipfix_4_to_m(&nat4_1, st, sc,
1023
PFIX_NAT_EVENT_SESSION_DELETE, st->expire);
1024
}
1025
}
1026
1027
if (st->bytes[1] != 0) /* second flow from state */ {
1028
ret = copy_flow_ipfix_4_to_m(&flow4_2, sc);
1029
1030
if (ret == 0 && nat) {
1031
ret = copy_nat_ipfix_4_to_m(&nat4_2, st, sc,
1032
PFIX_NAT_EVENT_SESSION_CREATE, st->creation);
1033
ret |= copy_nat_ipfix_4_to_m(&nat4_2, st, sc,
1034
PFIX_NAT_EVENT_SESSION_DELETE, st->expire);
1035
}
1036
}
1037
break;
1038
case AF_INET6:
1039
bzero(&flow6_1, sizeof(flow6_1));
1040
bzero(&flow6_2, sizeof(flow6_2));
1041
1042
if (st->direction == PF_OUT)
1043
copy_flow_ipfix_6_data(&flow6_1, &flow6_2, st, sk, sc,
1044
1, 0);
1045
else
1046
copy_flow_ipfix_6_data(&flow6_1, &flow6_2, st, sk, sc,
1047
0, 1);
1048
1049
if (st->bytes[0] != 0) /* first flow from state */
1050
ret = copy_flow_ipfix_6_to_m(&flow6_1, sc);
1051
1052
if (st->bytes[1] != 0) /* second flow from state */
1053
ret = copy_flow_ipfix_6_to_m(&flow6_2, sc);
1054
break;
1055
}
1056
return (ret);
1057
}
1058
1059
static void
1060
pflow_timeout(void *v)
1061
{
1062
struct pflow_softc *sc = v;
1063
1064
PFLOW_ASSERT(sc);
1065
CURVNET_SET(sc->sc_vnet);
1066
1067
switch (sc->sc_version) {
1068
case PFLOW_PROTO_5:
1069
pflow_sendout_v5(sc);
1070
break;
1071
case PFLOW_PROTO_10:
1072
pflow_sendout_ipfix(sc, PFLOW_INET);
1073
break;
1074
default: /* NOTREACHED */
1075
panic("Unsupported version %d", sc->sc_version);
1076
break;
1077
}
1078
1079
CURVNET_RESTORE();
1080
}
1081
1082
static void
1083
pflow_timeout6(void *v)
1084
{
1085
struct pflow_softc *sc = v;
1086
1087
PFLOW_ASSERT(sc);
1088
1089
if (sc->sc_version != PFLOW_PROTO_10)
1090
return;
1091
1092
CURVNET_SET(sc->sc_vnet);
1093
pflow_sendout_ipfix(sc, PFLOW_INET6);
1094
CURVNET_RESTORE();
1095
}
1096
1097
static void
1098
pflow_timeout_tmpl(void *v)
1099
{
1100
struct pflow_softc *sc = v;
1101
1102
PFLOW_ASSERT(sc);
1103
1104
if (sc->sc_version != PFLOW_PROTO_10)
1105
return;
1106
1107
CURVNET_SET(sc->sc_vnet);
1108
pflow_sendout_ipfix_tmpl(sc);
1109
CURVNET_RESTORE();
1110
}
1111
1112
static void
1113
pflow_timeout_nat4(void *v)
1114
{
1115
struct pflow_softc *sc = v;
1116
1117
PFLOW_ASSERT(sc);
1118
1119
if (sc->sc_version != PFLOW_PROTO_10)
1120
return;
1121
1122
CURVNET_SET(sc->sc_vnet);
1123
pflow_sendout_ipfix(sc, PFLOW_NAT4);
1124
CURVNET_RESTORE();
1125
}
1126
1127
static void
1128
pflow_flush(struct pflow_softc *sc)
1129
{
1130
PFLOW_ASSERT(sc);
1131
1132
switch (sc->sc_version) {
1133
case PFLOW_PROTO_5:
1134
pflow_sendout_v5(sc);
1135
break;
1136
case PFLOW_PROTO_10:
1137
pflow_sendout_ipfix(sc, PFLOW_INET);
1138
pflow_sendout_ipfix(sc, PFLOW_INET6);
1139
pflow_sendout_ipfix(sc, PFLOW_NAT4);
1140
break;
1141
default: /* NOTREACHED */
1142
break;
1143
}
1144
}
1145
1146
static int
1147
pflow_sendout_v5(struct pflow_softc *sc)
1148
{
1149
struct mbuf *m = sc->sc_mbuf;
1150
struct pflow_header *h;
1151
struct timespec tv;
1152
1153
PFLOW_ASSERT(sc);
1154
1155
if (m == NULL)
1156
return (0);
1157
1158
sc->sc_mbuf = NULL;
1159
1160
pflowstat_inc(pflow_packets);
1161
h = mtod(m, struct pflow_header *);
1162
h->count = htons(sc->sc_count);
1163
1164
/* populate pflow_header */
1165
h->uptime_ms = htonl(time_uptime * 1000);
1166
1167
getnanotime(&tv);
1168
h->time_sec = htonl(tv.tv_sec); /* XXX 2038 */
1169
h->time_nanosec = htonl(tv.tv_nsec);
1170
if (mbufq_enqueue(&sc->sc_outputqueue, m) == 0)
1171
swi_sched(sc->sc_swi_cookie, 0);
1172
1173
return (0);
1174
}
1175
1176
static int
1177
pflow_sendout_ipfix(struct pflow_softc *sc, enum pflow_family_t af)
1178
{
1179
struct mbuf *m;
1180
struct pflow_v10_header *h10;
1181
struct pflow_set_header *set_hdr;
1182
u_int32_t count;
1183
int set_length;
1184
1185
PFLOW_ASSERT(sc);
1186
1187
switch (af) {
1188
case PFLOW_INET:
1189
m = sc->sc_mbuf;
1190
callout_stop(&sc->sc_tmo);
1191
if (m == NULL)
1192
return (0);
1193
sc->sc_mbuf = NULL;
1194
count = sc->sc_count4;
1195
set_length = sizeof(struct pflow_set_header)
1196
+ sc->sc_count4 * sizeof(struct pflow_ipfix_flow4);
1197
break;
1198
case PFLOW_INET6:
1199
m = sc->sc_mbuf6;
1200
callout_stop(&sc->sc_tmo6);
1201
if (m == NULL)
1202
return (0);
1203
sc->sc_mbuf6 = NULL;
1204
count = sc->sc_count6;
1205
set_length = sizeof(struct pflow_set_header)
1206
+ sc->sc_count6 * sizeof(struct pflow_ipfix_flow6);
1207
break;
1208
case PFLOW_NAT4:
1209
m = sc->sc_mbuf_nat4;
1210
callout_stop(&sc->sc_tmo_nat4);
1211
if (m == NULL)
1212
return (0);
1213
sc->sc_mbuf_nat4 = NULL;
1214
count = sc->sc_count_nat4;
1215
set_length = sizeof(struct pflow_set_header)
1216
+ sc->sc_count_nat4 * sizeof(struct pflow_ipfix_nat4);
1217
break;
1218
default:
1219
unhandled_af(af);
1220
}
1221
1222
pflowstat_inc(pflow_packets);
1223
1224
set_hdr = mtod(m, struct pflow_set_header *);
1225
set_hdr->set_length = htons(set_length);
1226
1227
/* populate pflow_header */
1228
M_PREPEND(m, sizeof(struct pflow_v10_header), M_NOWAIT);
1229
if (m == NULL) {
1230
pflowstat_inc(pflow_onomem);
1231
return (ENOBUFS);
1232
}
1233
h10 = mtod(m, struct pflow_v10_header *);
1234
h10->version = htons(PFLOW_PROTO_10);
1235
h10->length = htons(PFLOW_IPFIX_HDRLEN + set_length);
1236
h10->time_sec = htonl(time_second); /* XXX 2038 */
1237
h10->flow_sequence = htonl(sc->sc_sequence);
1238
sc->sc_sequence += count;
1239
h10->observation_dom = htonl(sc->sc_observation_dom);
1240
if (mbufq_enqueue(&sc->sc_outputqueue, m) == 0)
1241
swi_sched(sc->sc_swi_cookie, 0);
1242
1243
return (0);
1244
}
1245
1246
static int
1247
pflow_sendout_ipfix_tmpl(struct pflow_softc *sc)
1248
{
1249
struct mbuf *m;
1250
struct pflow_v10_header *h10;
1251
1252
PFLOW_ASSERT(sc);
1253
1254
m = pflow_get_mbuf(sc, 0);
1255
if (m == NULL)
1256
return (0);
1257
m_copyback(m, 0, sizeof(struct pflow_ipfix_tmpl),
1258
(caddr_t)&sc->sc_tmpl_ipfix);
1259
1260
pflowstat_inc(pflow_packets);
1261
1262
/* populate pflow_header */
1263
M_PREPEND(m, sizeof(struct pflow_v10_header), M_NOWAIT);
1264
if (m == NULL) {
1265
pflowstat_inc(pflow_onomem);
1266
return (ENOBUFS);
1267
}
1268
h10 = mtod(m, struct pflow_v10_header *);
1269
h10->version = htons(PFLOW_PROTO_10);
1270
h10->length = htons(PFLOW_IPFIX_HDRLEN + sizeof(struct
1271
pflow_ipfix_tmpl));
1272
h10->time_sec = htonl(time_second); /* XXX 2038 */
1273
h10->flow_sequence = htonl(sc->sc_sequence);
1274
h10->observation_dom = htonl(sc->sc_observation_dom);
1275
1276
callout_reset(&sc->sc_tmo_tmpl, PFLOW_TMPL_TIMEOUT * hz,
1277
pflow_timeout_tmpl, sc);
1278
if (mbufq_enqueue(&sc->sc_outputqueue, m) == 0)
1279
swi_sched(sc->sc_swi_cookie, 0);
1280
1281
return (0);
1282
}
1283
1284
static int
1285
pflow_sendout_mbuf(struct pflow_softc *sc, struct mbuf *m)
1286
{
1287
if (sc->so == NULL) {
1288
m_freem(m);
1289
return (EINVAL);
1290
}
1291
return (sosend(sc->so, sc->sc_flowdst, NULL, m, NULL, 0, curthread));
1292
}
1293
1294
static int
1295
sysctl_pflowstats(SYSCTL_HANDLER_ARGS)
1296
{
1297
struct pflowstats pflowstats;
1298
1299
pflowstats.pflow_flows =
1300
counter_u64_fetch(V_pflowstats.c[pflow_flows]);
1301
pflowstats.pflow_packets =
1302
counter_u64_fetch(V_pflowstats.c[pflow_packets]);
1303
pflowstats.pflow_onomem =
1304
counter_u64_fetch(V_pflowstats.c[pflow_onomem]);
1305
pflowstats.pflow_oerrors =
1306
counter_u64_fetch(V_pflowstats.c[pflow_oerrors]);
1307
1308
return (sysctl_handle_opaque(oidp, &pflowstats, sizeof(pflowstats), req));
1309
}
1310
1311
static int
1312
pflow_nl_list(struct nlmsghdr *hdr, struct nl_pstate *npt)
1313
{
1314
struct epoch_tracker et;
1315
struct pflow_softc *sc = NULL;
1316
struct nl_writer *nw = npt->nw;
1317
int error = 0;
1318
1319
hdr->nlmsg_flags |= NLM_F_MULTI;
1320
1321
NET_EPOCH_ENTER(et);
1322
CK_LIST_FOREACH(sc, &V_pflowif_list, sc_next) {
1323
if (!nlmsg_reply(nw, hdr, sizeof(struct genlmsghdr))) {
1324
error = ENOMEM;
1325
goto out;
1326
}
1327
1328
struct genlmsghdr *ghdr_new = nlmsg_reserve_object(nw, struct genlmsghdr);
1329
ghdr_new->cmd = PFLOWNL_CMD_LIST;
1330
ghdr_new->version = 0;
1331
ghdr_new->reserved = 0;
1332
1333
nlattr_add_u32(nw, PFLOWNL_L_ID, sc->sc_id);
1334
1335
if (! nlmsg_end(nw)) {
1336
error = ENOMEM;
1337
goto out;
1338
}
1339
}
1340
1341
out:
1342
NET_EPOCH_EXIT(et);
1343
1344
if (error != 0)
1345
nlmsg_abort(nw);
1346
1347
return (error);
1348
}
1349
1350
static int
1351
pflow_nl_create(struct nlmsghdr *hdr, struct nl_pstate *npt)
1352
{
1353
struct nl_writer *nw = npt->nw;
1354
int error = 0;
1355
int unit;
1356
1357
if (! nlmsg_reply(nw, hdr, sizeof(struct genlmsghdr))) {
1358
return (ENOMEM);
1359
}
1360
1361
struct genlmsghdr *ghdr_new = nlmsg_reserve_object(nw, struct genlmsghdr);
1362
ghdr_new->cmd = PFLOWNL_CMD_CREATE;
1363
ghdr_new->version = 0;
1364
ghdr_new->reserved = 0;
1365
1366
unit = alloc_unr(V_pflow_unr);
1367
if (unit == -1) {
1368
nlmsg_abort(nw);
1369
return (ENOMEM);
1370
}
1371
1372
error = pflow_create(unit);
1373
if (error != 0) {
1374
free_unr(V_pflow_unr, unit);
1375
nlmsg_abort(nw);
1376
return (error);
1377
}
1378
1379
nlattr_add_s32(nw, PFLOWNL_CREATE_ID, unit);
1380
1381
if (! nlmsg_end(nw)) {
1382
pflow_destroy(unit, true);
1383
return (ENOMEM);
1384
}
1385
1386
return (0);
1387
}
1388
1389
struct pflow_parsed_del {
1390
int id;
1391
};
1392
#define _OUT(_field) offsetof(struct pflow_parsed_del, _field)
1393
static const struct nlattr_parser nla_p_del[] = {
1394
{ .type = PFLOWNL_DEL_ID, .off = _OUT(id), .cb = nlattr_get_uint32 },
1395
};
1396
#undef _OUT
1397
NL_DECLARE_PARSER(del_parser, struct genlmsghdr, nlf_p_empty, nla_p_del);
1398
1399
static int
1400
pflow_nl_del(struct nlmsghdr *hdr, struct nl_pstate *npt)
1401
{
1402
struct pflow_parsed_del d = {};
1403
int error;
1404
1405
error = nl_parse_nlmsg(hdr, &del_parser, npt, &d);
1406
if (error != 0)
1407
return (error);
1408
1409
error = pflow_destroy(d.id, true);
1410
1411
return (error);
1412
}
1413
1414
struct pflow_parsed_get {
1415
int id;
1416
};
1417
#define _OUT(_field) offsetof(struct pflow_parsed_get, _field)
1418
static const struct nlattr_parser nla_p_get[] = {
1419
{ .type = PFLOWNL_GET_ID, .off = _OUT(id), .cb = nlattr_get_uint32 },
1420
};
1421
#undef _OUT
1422
NL_DECLARE_PARSER(get_parser, struct genlmsghdr, nlf_p_empty, nla_p_get);
1423
1424
static bool
1425
nlattr_add_sockaddr(struct nl_writer *nw, int attr, const struct sockaddr *s)
1426
{
1427
int off = nlattr_add_nested(nw, attr);
1428
if (off == 0)
1429
return (false);
1430
1431
nlattr_add_u8(nw, PFLOWNL_ADDR_FAMILY, s->sa_family);
1432
1433
switch (s->sa_family) {
1434
case AF_INET: {
1435
const struct sockaddr_in *in = (const struct sockaddr_in *)s;
1436
nlattr_add_u16(nw, PFLOWNL_ADDR_PORT, in->sin_port);
1437
nlattr_add_in_addr(nw, PFLOWNL_ADDR_IP, &in->sin_addr);
1438
break;
1439
}
1440
case AF_INET6: {
1441
const struct sockaddr_in6 *in6 = (const struct sockaddr_in6 *)s;
1442
nlattr_add_u16(nw, PFLOWNL_ADDR_PORT, in6->sin6_port);
1443
nlattr_add_in6_addr(nw, PFLOWNL_ADDR_IP6, &in6->sin6_addr);
1444
break;
1445
}
1446
default:
1447
unhandled_af(s->sa_family);
1448
}
1449
1450
nlattr_set_len(nw, off);
1451
return (true);
1452
}
1453
1454
static int
1455
pflow_nl_get(struct nlmsghdr *hdr, struct nl_pstate *npt)
1456
{
1457
struct epoch_tracker et;
1458
struct pflow_parsed_get g = {};
1459
struct pflow_softc *sc = NULL;
1460
struct nl_writer *nw = npt->nw;
1461
struct genlmsghdr *ghdr_new;
1462
int error;
1463
1464
error = nl_parse_nlmsg(hdr, &get_parser, npt, &g);
1465
if (error != 0)
1466
return (error);
1467
1468
NET_EPOCH_ENTER(et);
1469
CK_LIST_FOREACH(sc, &V_pflowif_list, sc_next) {
1470
if (sc->sc_id == g.id)
1471
break;
1472
}
1473
if (sc == NULL) {
1474
error = ENOENT;
1475
goto out;
1476
}
1477
1478
if (! nlmsg_reply(nw, hdr, sizeof(struct genlmsghdr))) {
1479
nlmsg_abort(nw);
1480
error = ENOMEM;
1481
goto out;
1482
}
1483
1484
ghdr_new = nlmsg_reserve_object(nw, struct genlmsghdr);
1485
if (ghdr_new == NULL) {
1486
nlmsg_abort(nw);
1487
error = ENOMEM;
1488
goto out;
1489
}
1490
1491
ghdr_new->cmd = PFLOWNL_CMD_GET;
1492
ghdr_new->version = 0;
1493
ghdr_new->reserved = 0;
1494
1495
nlattr_add_u32(nw, PFLOWNL_GET_ID, sc->sc_id);
1496
nlattr_add_u16(nw, PFLOWNL_GET_VERSION, sc->sc_version);
1497
if (sc->sc_flowsrc)
1498
nlattr_add_sockaddr(nw, PFLOWNL_GET_SRC, sc->sc_flowsrc);
1499
if (sc->sc_flowdst)
1500
nlattr_add_sockaddr(nw, PFLOWNL_GET_DST, sc->sc_flowdst);
1501
nlattr_add_u32(nw, PFLOWNL_GET_OBSERVATION_DOMAIN,
1502
sc->sc_observation_dom);
1503
nlattr_add_u8(nw, PFLOWNL_GET_SOCKET_STATUS, sc->so != NULL);
1504
1505
if (! nlmsg_end(nw)) {
1506
nlmsg_abort(nw);
1507
error = ENOMEM;
1508
}
1509
1510
out:
1511
NET_EPOCH_EXIT(et);
1512
1513
return (error);
1514
}
1515
1516
struct pflow_sockaddr {
1517
union {
1518
struct sockaddr_in in;
1519
struct sockaddr_in6 in6;
1520
struct sockaddr_storage storage;
1521
};
1522
};
1523
static bool
1524
pflow_postparse_sockaddr(void *parsed_args, struct nl_pstate *npt __unused)
1525
{
1526
struct pflow_sockaddr *s = (struct pflow_sockaddr *)parsed_args;
1527
1528
if (s->storage.ss_family == AF_INET)
1529
s->storage.ss_len = sizeof(struct sockaddr_in);
1530
else if (s->storage.ss_family == AF_INET6)
1531
s->storage.ss_len = sizeof(struct sockaddr_in6);
1532
else
1533
return (false);
1534
1535
return (true);
1536
}
1537
1538
#define _OUT(_field) offsetof(struct pflow_sockaddr, _field)
1539
static struct nlattr_parser nla_p_sockaddr[] = {
1540
{ .type = PFLOWNL_ADDR_FAMILY, .off = _OUT(in.sin_family), .cb = nlattr_get_uint8 },
1541
{ .type = PFLOWNL_ADDR_PORT, .off = _OUT(in.sin_port), .cb = nlattr_get_uint16 },
1542
{ .type = PFLOWNL_ADDR_IP, .off = _OUT(in.sin_addr), .cb = nlattr_get_in_addr },
1543
{ .type = PFLOWNL_ADDR_IP6, .off = _OUT(in6.sin6_addr), .cb = nlattr_get_in6_addr },
1544
};
1545
NL_DECLARE_ATTR_PARSER_EXT(addr_parser, nla_p_sockaddr, pflow_postparse_sockaddr);
1546
#undef _OUT
1547
1548
struct pflow_parsed_set {
1549
int id;
1550
uint16_t version;
1551
struct sockaddr_storage src;
1552
struct sockaddr_storage dst;
1553
uint32_t observation_dom;
1554
};
1555
#define _OUT(_field) offsetof(struct pflow_parsed_set, _field)
1556
static const struct nlattr_parser nla_p_set[] = {
1557
{ .type = PFLOWNL_SET_ID, .off = _OUT(id), .cb = nlattr_get_uint32 },
1558
{ .type = PFLOWNL_SET_VERSION, .off = _OUT(version), .cb = nlattr_get_uint16 },
1559
{ .type = PFLOWNL_SET_SRC, .off = _OUT(src), .arg = &addr_parser, .cb = nlattr_get_nested },
1560
{ .type = PFLOWNL_SET_DST, .off = _OUT(dst), .arg = &addr_parser, .cb = nlattr_get_nested },
1561
{ .type = PFLOWNL_SET_OBSERVATION_DOMAIN, .off = _OUT(observation_dom), .cb = nlattr_get_uint32 },
1562
};
1563
#undef _OUT
1564
NL_DECLARE_PARSER(set_parser, struct genlmsghdr, nlf_p_empty, nla_p_set);
1565
1566
static int
1567
pflow_set(struct pflow_softc *sc, const struct pflow_parsed_set *pflowr, struct ucred *cred)
1568
{
1569
struct thread *td;
1570
struct socket *so;
1571
int error = 0;
1572
1573
td = curthread;
1574
1575
PFLOW_ASSERT(sc);
1576
1577
if (pflowr->version != 0) {
1578
switch(pflowr->version) {
1579
case PFLOW_PROTO_5:
1580
case PFLOW_PROTO_10:
1581
break;
1582
default:
1583
return(EINVAL);
1584
}
1585
}
1586
1587
pflow_flush(sc);
1588
1589
if (pflowr->dst.ss_len != 0) {
1590
if (sc->sc_flowdst != NULL &&
1591
sc->sc_flowdst->sa_family != pflowr->dst.ss_family) {
1592
free(sc->sc_flowdst, M_DEVBUF);
1593
sc->sc_flowdst = NULL;
1594
if (sc->so != NULL) {
1595
soclose(sc->so);
1596
sc->so = NULL;
1597
}
1598
}
1599
1600
switch (pflowr->dst.ss_family) {
1601
case AF_INET:
1602
if (sc->sc_flowdst == NULL) {
1603
if ((sc->sc_flowdst = malloc(
1604
sizeof(struct sockaddr_in),
1605
M_DEVBUF, M_NOWAIT)) == NULL)
1606
return (ENOMEM);
1607
}
1608
memcpy(sc->sc_flowdst, &pflowr->dst,
1609
sizeof(struct sockaddr_in));
1610
sc->sc_flowdst->sa_len = sizeof(struct
1611
sockaddr_in);
1612
break;
1613
case AF_INET6:
1614
if (sc->sc_flowdst == NULL) {
1615
if ((sc->sc_flowdst = malloc(
1616
sizeof(struct sockaddr_in6),
1617
M_DEVBUF, M_NOWAIT)) == NULL)
1618
return (ENOMEM);
1619
}
1620
memcpy(sc->sc_flowdst, &pflowr->dst,
1621
sizeof(struct sockaddr_in6));
1622
sc->sc_flowdst->sa_len = sizeof(struct
1623
sockaddr_in6);
1624
break;
1625
default:
1626
break;
1627
}
1628
}
1629
1630
if (pflowr->src.ss_len != 0) {
1631
if (sc->sc_flowsrc != NULL)
1632
free(sc->sc_flowsrc, M_DEVBUF);
1633
sc->sc_flowsrc = NULL;
1634
if (sc->so != NULL) {
1635
soclose(sc->so);
1636
sc->so = NULL;
1637
}
1638
switch(pflowr->src.ss_family) {
1639
case AF_INET:
1640
if ((sc->sc_flowsrc = malloc(
1641
sizeof(struct sockaddr_in),
1642
M_DEVBUF, M_NOWAIT)) == NULL)
1643
return (ENOMEM);
1644
memcpy(sc->sc_flowsrc, &pflowr->src,
1645
sizeof(struct sockaddr_in));
1646
sc->sc_flowsrc->sa_len = sizeof(struct
1647
sockaddr_in);
1648
break;
1649
case AF_INET6:
1650
if ((sc->sc_flowsrc = malloc(
1651
sizeof(struct sockaddr_in6),
1652
M_DEVBUF, M_NOWAIT)) == NULL)
1653
return (ENOMEM);
1654
memcpy(sc->sc_flowsrc, &pflowr->src,
1655
sizeof(struct sockaddr_in6));
1656
sc->sc_flowsrc->sa_len = sizeof(struct
1657
sockaddr_in6);
1658
break;
1659
default:
1660
break;
1661
}
1662
}
1663
1664
if (sc->so == NULL) {
1665
if (pflowvalidsockaddr(sc->sc_flowdst, 0)) {
1666
error = socreate(sc->sc_flowdst->sa_family,
1667
&so, SOCK_DGRAM, IPPROTO_UDP, cred, td);
1668
if (error)
1669
return (error);
1670
if (pflowvalidsockaddr(sc->sc_flowsrc, 1)) {
1671
error = sobind(so, sc->sc_flowsrc, td);
1672
if (error) {
1673
soclose(so);
1674
return (error);
1675
}
1676
}
1677
sc->so = so;
1678
}
1679
} else if (!pflowvalidsockaddr(sc->sc_flowdst, 0)) {
1680
soclose(sc->so);
1681
sc->so = NULL;
1682
}
1683
1684
if (pflowr->observation_dom != 0)
1685
sc->sc_observation_dom = pflowr->observation_dom;
1686
1687
/* error check is above */
1688
if (pflowr->version != 0)
1689
sc->sc_version = pflowr->version;
1690
1691
pflow_setmtu(sc, ETHERMTU);
1692
1693
switch (sc->sc_version) {
1694
case PFLOW_PROTO_5:
1695
callout_stop(&sc->sc_tmo6);
1696
callout_stop(&sc->sc_tmo_tmpl);
1697
break;
1698
case PFLOW_PROTO_10:
1699
callout_reset(&sc->sc_tmo_tmpl, PFLOW_TMPL_TIMEOUT * hz,
1700
pflow_timeout_tmpl, sc);
1701
break;
1702
default: /* NOTREACHED */
1703
break;
1704
}
1705
1706
return (0);
1707
}
1708
1709
static int
1710
pflow_nl_set(struct nlmsghdr *hdr, struct nl_pstate *npt)
1711
{
1712
struct epoch_tracker et;
1713
struct pflow_parsed_set s = {};
1714
struct pflow_softc *sc = NULL;
1715
int error;
1716
1717
error = nl_parse_nlmsg(hdr, &set_parser, npt, &s);
1718
if (error != 0)
1719
return (error);
1720
1721
NET_EPOCH_ENTER(et);
1722
CK_LIST_FOREACH(sc, &V_pflowif_list, sc_next) {
1723
if (sc->sc_id == s.id)
1724
break;
1725
}
1726
if (sc == NULL) {
1727
error = ENOENT;
1728
goto out;
1729
}
1730
1731
PFLOW_LOCK(sc);
1732
error = pflow_set(sc, &s, nlp_get_cred(npt->nlp));
1733
PFLOW_UNLOCK(sc);
1734
1735
out:
1736
NET_EPOCH_EXIT(et);
1737
return (error);
1738
}
1739
1740
static const struct genl_cmd pflow_cmds[] = {
1741
{
1742
.cmd_num = PFLOWNL_CMD_LIST,
1743
.cmd_name = "LIST",
1744
.cmd_cb = pflow_nl_list,
1745
.cmd_flags = GENL_CMD_CAP_DO | GENL_CMD_CAP_DUMP | GENL_CMD_CAP_HASPOL,
1746
.cmd_priv = PRIV_NETINET_PF,
1747
},
1748
{
1749
.cmd_num = PFLOWNL_CMD_CREATE,
1750
.cmd_name = "CREATE",
1751
.cmd_cb = pflow_nl_create,
1752
.cmd_flags = GENL_CMD_CAP_DO | GENL_CMD_CAP_DUMP | GENL_CMD_CAP_HASPOL,
1753
.cmd_priv = PRIV_NETINET_PF,
1754
},
1755
{
1756
.cmd_num = PFLOWNL_CMD_DEL,
1757
.cmd_name = "DEL",
1758
.cmd_cb = pflow_nl_del,
1759
.cmd_flags = GENL_CMD_CAP_DO | GENL_CMD_CAP_DUMP | GENL_CMD_CAP_HASPOL,
1760
.cmd_priv = PRIV_NETINET_PF,
1761
},
1762
{
1763
.cmd_num = PFLOWNL_CMD_GET,
1764
.cmd_name = "GET",
1765
.cmd_cb = pflow_nl_get,
1766
.cmd_flags = GENL_CMD_CAP_DUMP | GENL_CMD_CAP_HASPOL,
1767
.cmd_priv = PRIV_NETINET_PF,
1768
},
1769
{
1770
.cmd_num = PFLOWNL_CMD_SET,
1771
.cmd_name = "SET",
1772
.cmd_cb = pflow_nl_set,
1773
.cmd_flags = GENL_CMD_CAP_DO | GENL_CMD_CAP_DUMP | GENL_CMD_CAP_HASPOL,
1774
.cmd_priv = PRIV_NETINET_PF,
1775
},
1776
};
1777
1778
static const struct nlhdr_parser *all_parsers[] = {
1779
&del_parser,
1780
&get_parser,
1781
&set_parser,
1782
};
1783
1784
static unsigned pflow_do_osd_jail_slot;
1785
1786
static uint16_t family_id;
1787
static int
1788
pflow_init(void)
1789
{
1790
bool ret;
1791
1792
NL_VERIFY_PARSERS(all_parsers);
1793
1794
static osd_method_t methods[PR_MAXMETHOD] = {
1795
[PR_METHOD_REMOVE] = pflow_jail_remove,
1796
};
1797
pflow_do_osd_jail_slot = osd_jail_register(NULL, methods);
1798
1799
family_id = genl_register_family(PFLOWNL_FAMILY_NAME, 0, 2,
1800
PFLOWNL_CMD_MAX);
1801
MPASS(family_id != 0);
1802
ret = genl_register_cmds(family_id, pflow_cmds, nitems(pflow_cmds));
1803
1804
return (ret ? 0 : ENODEV);
1805
}
1806
1807
static void
1808
pflow_uninit(void)
1809
{
1810
osd_jail_deregister(pflow_do_osd_jail_slot);
1811
genl_unregister_family(family_id);
1812
}
1813
1814
static int
1815
pflow_modevent(module_t mod, int type, void *data)
1816
{
1817
int error = 0;
1818
1819
switch (type) {
1820
case MOD_LOAD:
1821
error = pflow_init();
1822
break;
1823
case MOD_UNLOAD:
1824
pflow_uninit();
1825
break;
1826
default:
1827
error = EINVAL;
1828
break;
1829
}
1830
1831
return (error);
1832
}
1833
1834
static moduledata_t pflow_mod = {
1835
pflowname,
1836
pflow_modevent,
1837
0
1838
};
1839
1840
DECLARE_MODULE(pflow, pflow_mod, SI_SUB_PROTO_FIREWALL, SI_ORDER_ANY);
1841
MODULE_VERSION(pflow, 1);
1842
MODULE_DEPEND(pflow, pf, PF_MODVER, PF_MODVER, PF_MODVER);
1843
1844