FreeBSD kernel netgraph code
netflow_v9.c
Go to the documentation of this file.
1/*-
2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3 *
4 * Copyright (c) 2010 Alexander V. Chernikov <melifaro@ipfw.ru>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 *
28 * $FreeBSD$
29 */
30
31#include <sys/cdefs.h>
32__FBSDID("$FreeBSD$");
33
34#include "opt_inet6.h"
35#include "opt_route.h"
36#include <sys/param.h>
37#include <sys/systm.h>
38#include <sys/counter.h>
39#include <sys/kernel.h>
40#include <sys/ktr.h>
41#include <sys/limits.h>
42#include <sys/malloc.h>
43#include <sys/mbuf.h>
44#include <sys/syslog.h>
45#include <sys/socket.h>
46#include <vm/uma.h>
47
48#include <net/if.h>
49#include <net/route.h>
50#include <net/ethernet.h>
51#include <netinet/in.h>
52#include <netinet/in_systm.h>
53#include <netinet/ip.h>
54#include <netinet/ip6.h>
55#include <netinet/tcp.h>
56#include <netinet/udp.h>
57
58#include <netgraph/ng_message.h>
59#include <netgraph/netgraph.h>
60
64
65MALLOC_DECLARE(M_NETFLOW_GENERAL);
66MALLOC_DEFINE(M_NETFLOW_GENERAL, "netflow_general", "plog, V9 templates data");
67
68/*
69 * Base V9 templates for L4+ IPv4/IPv6 protocols
70 */
72{
93 {0, 0}
94};
95
97{
103 { NETFLOW_V9_FIELD_IN_PKTS, sizeof(CNTR)},
118 {0, 0}
119};
120
121/*
122 * Pre-compiles flow exporter for all possible FlowSets
123 * so we can add flowset to packet via simple memcpy()
124 */
125static void
127{
128 uint16_t *p, *template_fields_cnt;
129 int cnt;
130
131 int flowset_size = sizeof(struct netflow_v9_flowset_header) +
132 _NETFLOW_V9_TEMPLATE_SIZE(_netflow_v9_record_ipv4_tcp) + /* netflow_v9_record_ipv4_tcp */
133 _NETFLOW_V9_TEMPLATE_SIZE(_netflow_v9_record_ipv6_tcp); /* netflow_v9_record_ipv6_tcp */
134
135 priv->v9_flowsets[0] = malloc(flowset_size, M_NETFLOW_GENERAL, M_WAITOK | M_ZERO);
136
137 if (flowset_size % 4)
138 flowset_size += 4 - (flowset_size % 4); /* Padding to 4-byte boundary */
139
140 priv->flowsets_count = 1;
141 p = (uint16_t *)priv->v9_flowsets[0];
142 *p++ = 0; /* Flowset ID, 0 is reserved for Template FlowSets */
143 *p++ = htons(flowset_size); /* Total FlowSet length */
144
145 /*
146 * Most common TCP/UDP IPv4 template, ID = 256
147 */
149 template_fields_cnt = p++;
150 for (cnt = 0; _netflow_v9_record_ipv4_tcp[cnt].field_id != 0; cnt++) {
151 *p++ = htons(_netflow_v9_record_ipv4_tcp[cnt].field_id);
152 *p++ = htons(_netflow_v9_record_ipv4_tcp[cnt].field_length);
153 }
154 *template_fields_cnt = htons(cnt);
155
156 /*
157 * TCP/UDP IPv6 template, ID = 257
158 */
160 template_fields_cnt = p++;
161 for (cnt = 0; _netflow_v9_record_ipv6_tcp[cnt].field_id != 0; cnt++) {
162 *p++ = htons(_netflow_v9_record_ipv6_tcp[cnt].field_id);
163 *p++ = htons(_netflow_v9_record_ipv6_tcp[cnt].field_length);
164 }
165 *template_fields_cnt = htons(cnt);
166
167 priv->flowset_records[0] = 2;
168}
169
170/* Closes current data flowset */
171static void inline
172close_flowset(struct mbuf *m, struct netflow_v9_packet_opt *t)
173{
174 struct mbuf *m_old;
175 uint32_t zero = 0;
176 int offset = 0;
177 uint16_t *flowset_length, len;
178
179 /* Hack to ensure we are not crossing mbuf boundary, length is uint16_t */
180 m_old = m_getptr(m, t->flow_header + offsetof(struct netflow_v9_flowset_header, length), &offset);
181 flowset_length = (uint16_t *)(mtod(m_old, char *) + offset);
182
183 len = (uint16_t)(m_pktlen(m) - t->flow_header);
184 /* Align on 4-byte boundary (RFC 3954, Clause 5.3) */
185 if (len % 4) {
186 if (m_append(m, 4 - (len % 4), (void *)&zero) != 1)
187 panic("ng_netflow: m_append() failed!");
188
189 len += 4 - (len % 4);
190 }
191
192 *flowset_length = htons(len);
193}
194
195/*
196 * Non-static functions called from ng_netflow.c
197 */
198
199/* We have full datagram in fib data. Send it to export hook. */
200int
202{
203 struct mbuf *m = NGI_M(item);
204 struct netflow_v9_export_dgram *dgram = mtod(m,
205 struct netflow_v9_export_dgram *);
206 struct netflow_v9_header *header = &dgram->header;
207 struct timespec ts;
208 int error = 0;
209
210 if (t == NULL) {
211 CTR0(KTR_NET, "export9_send(): V9 export packet without tag");
212 NG_FREE_ITEM(item);
213 return (0);
214 }
215
216 /* Close flowset if not closed already */
217 if (m_pktlen(m) != t->flow_header)
218 close_flowset(m, t);
219
220 /* Fill export header. */
221 header->count = t->count;
222 header->sys_uptime = htonl(MILLIUPTIME(time_uptime));
223 getnanotime(&ts);
224 header->unix_secs = htonl(ts.tv_sec);
225 header->seq_num = htonl(atomic_fetchadd_32(&fe->flow9_seq, 1));
226 header->count = htons(t->count);
227 header->source_id = htonl(fe->domain_id);
228
229 if (priv->export9 != NULL)
230 NG_FWD_ITEM_HOOK_FLAGS(error, item, priv->export9, flags);
231 else
232 NG_FREE_ITEM(item);
233
234 free(t, M_NETFLOW_GENERAL);
235
236 return (error);
237}
238
239/* Add V9 record to dgram. */
240int
242{
243 size_t len = 0;
244 struct netflow_v9_flowset_header fsh;
246 struct mbuf *m = NGI_M(item);
247 uint16_t flow_type;
248 struct flow_entry_data *fed;
249#ifdef INET6
250 struct flow6_entry_data *fed6;
251#endif
252 if (t == NULL) {
253 CTR0(KTR_NET, "ng_netflow: V9 export packet without tag!");
254 return (0);
255 }
256
257 /* Prepare flow record */
258 fed = (struct flow_entry_data *)&fle->f;
259#ifdef INET6
260 fed6 = (struct flow6_entry_data *)&fle->f;
261#endif
262 /* We can use flow_type field since fle6 offset is equal to fle */
263 flow_type = fed->r.flow_type;
264
265 switch (flow_type) {
267 {
268 /* IPv4 TCP/UDP/[SCTP] */
269 struct netflow_v9_record_ipv4_tcp *rec = &rg.rec.v4_tcp;
270
271 rec->src_addr = fed->r.r_src.s_addr;
272 rec->dst_addr = fed->r.r_dst.s_addr;
273 rec->next_hop = fed->next_hop.s_addr;
274 rec->i_ifx = htons(fed->fle_i_ifx);
275 rec->o_ifx = htons(fed->fle_o_ifx);
276 rec->i_packets = htonl(fed->packets);
277 rec->i_octets = htonl(fed->bytes);
278 rec->o_packets = htonl(0);
279 rec->o_octets = htonl(0);
280 rec->first = htonl(MILLIUPTIME(fed->first));
281 rec->last = htonl(MILLIUPTIME(fed->last));
282 rec->s_port = fed->r.r_sport;
283 rec->d_port = fed->r.r_dport;
284 rec->flags = fed->tcp_flags;
285 rec->prot = fed->r.r_ip_p;
286 rec->tos = fed->r.r_tos;
287 rec->dst_mask = fed->dst_mask;
288 rec->src_mask = fed->src_mask;
289
290 /* Not supported fields. */
291 rec->src_as = rec->dst_as = 0;
292
293 len = sizeof(struct netflow_v9_record_ipv4_tcp);
294 break;
295 }
296#ifdef INET6
298 {
299 /* IPv6 TCP/UDP/[SCTP] */
300 struct netflow_v9_record_ipv6_tcp *rec = &rg.rec.v6_tcp;
301
302 rec->src_addr = fed6->r.src.r_src6;
303 rec->dst_addr = fed6->r.dst.r_dst6;
304 rec->next_hop = fed6->n.next_hop6;
305 rec->i_ifx = htons(fed6->fle_i_ifx);
306 rec->o_ifx = htons(fed6->fle_o_ifx);
307 rec->i_packets = htonl(fed6->packets);
308 rec->i_octets = htonl(fed6->bytes);
309 rec->o_packets = htonl(0);
310 rec->o_octets = htonl(0);
311 rec->first = htonl(MILLIUPTIME(fed6->first));
312 rec->last = htonl(MILLIUPTIME(fed6->last));
313 rec->s_port = fed6->r.r_sport;
314 rec->d_port = fed6->r.r_dport;
315 rec->flags = fed6->tcp_flags;
316 rec->prot = fed6->r.r_ip_p;
317 rec->tos = fed6->r.r_tos;
318 rec->dst_mask = fed6->dst_mask;
319 rec->src_mask = fed6->src_mask;
320
321 /* Not supported fields. */
322 rec->src_as = rec->dst_as = 0;
323
324 len = sizeof(struct netflow_v9_record_ipv6_tcp);
325 break;
326 }
327#endif
328 default:
329 {
330 CTR1(KTR_NET, "export9_add(): Don't know what to do with %d flow type!", flow_type);
331 return (0);
332 }
333 }
334
335 /* Check if new records has the same template */
336 if (flow_type != t->flow_type) {
337 /* close old flowset */
338 if (t->flow_type != 0)
339 close_flowset(m, t);
340
341 t->flow_type = flow_type;
342 t->flow_header = m_pktlen(m);
343
344 /* Generate data flowset ID */
345 fsh.id = htons(NETFLOW_V9_MAX_RESERVED_FLOWSET + flow_type);
346 fsh.length = 0;
347
348 /* m_append should not fail since all data is already allocated */
349 if (m_append(m, sizeof(fsh), (void *)&fsh) != 1)
350 panic("ng_netflow: m_append() failed");
351
352 }
353
354 if (m_append(m, len, (void *)&rg.rec) != 1)
355 panic("ng_netflow: m_append() failed");
356
357 t->count++;
358
359 if (m_pktlen(m) + sizeof(struct netflow_v9_record_general) + sizeof(struct netflow_v9_flowset_header) >= _NETFLOW_V9_MAX_SIZE(t->mtu))
360 return (1); /* end of datagram */
361 return (0);
362}
363
364/*
365 * Detach export datagram from fib instance, if there is any.
366 * If there is no, allocate a new one.
367 */
368item_p
370{
371 item_p item = NULL;
372 struct netflow_v9_packet_opt *t = NULL;
373
374 mtx_lock(&fe->export9_mtx);
375 if (fe->exp.item9 != NULL) {
376 item = fe->exp.item9;
377 fe->exp.item9 = NULL;
378 t = fe->exp.item9_opt;
379 fe->exp.item9_opt = NULL;
380 }
381 mtx_unlock(&fe->export9_mtx);
382
383 if (item == NULL) {
384 struct netflow_v9_export_dgram *dgram;
385 struct mbuf *m;
386 uint16_t mtu = priv->mtu;
387
388 /* Allocate entire packet at once, allowing easy m_append() calls */
389 m = m_getm(NULL, mtu, M_NOWAIT, MT_DATA);
390 if (m == NULL)
391 return (NULL);
392
393 t = malloc(sizeof(struct netflow_v9_packet_opt), M_NETFLOW_GENERAL, M_NOWAIT | M_ZERO);
394 if (t == NULL) {
395 m_free(m);
396 return (NULL);
397 }
398
399 item = ng_package_data(m, NG_NOFLAGS);
400 if (item == NULL) {
401 free(t, M_NETFLOW_GENERAL);
402 return (NULL);
403 }
404
405 dgram = mtod(m, struct netflow_v9_export_dgram *);
406 dgram->header.count = 0;
407 dgram->header.version = htons(NETFLOW_V9);
408 /* Set mbuf current data length */
409 m->m_len = m->m_pkthdr.len = sizeof(struct netflow_v9_header);
410
411 t->count = 0;
412 t->mtu = mtu;
413 t->flow_header = m->m_len;
414
415 /*
416 * Check if we need to insert templates into packet
417 */
418
419 struct netflow_v9_flowset_header *fl;
420
421 if ((time_uptime >= priv->templ_time + fe->templ_last_ts) ||
422 (fe->sent_packets >= priv->templ_packets + fe->templ_last_pkt)) {
423 fe->templ_last_ts = time_uptime;
425
426 fl = priv->v9_flowsets[0];
427 m_append(m, ntohs(fl->length), (void *)fl);
428 t->flow_header = m->m_len;
429 t->count += priv->flowset_records[0];
430 }
431 }
432
433 *tt = t;
434 return (item);
435}
436
437/*
438 * Re-attach incomplete datagram back to fib instance.
439 * If there is already another one, then send incomplete.
440 */
441void
443{
444 /*
445 * It may happen on SMP, that some thread has already
446 * put its item there, in this case we bail out and
447 * send what we have to collector.
448 */
449 mtx_lock(&fe->export9_mtx);
450 if (fe->exp.item9 == NULL) {
451 fe->exp.item9 = item;
452 fe->exp.item9_opt = t;
453 mtx_unlock(&fe->export9_mtx);
454 } else {
455 mtx_unlock(&fe->export9_mtx);
456 export9_send(priv, fe, item, t, flags);
457 }
458}
459
460/* Allocate memory and set up flow cache */
461void
463{
465
466 priv->templ_time = NETFLOW_V9_MAX_TIME_TEMPL;
467 priv->templ_packets = NETFLOW_V9_MAX_PACKETS_TEMPL;
468 priv->mtu = BASE_MTU;
469}
470
471/* Free all flow cache memory. Called from ng_netflow_cache_flush() */
472void
474{
475 int i;
476
477 /* Free flowsets*/
478 for (i = 0; i < priv->flowsets_count; i++)
479 free(priv->v9_flowsets[i], M_NETFLOW_GENERAL);
480}
481
482/* Get a snapshot of NetFlow v9 settings */
483void
485{
486
487 i->templ_time = priv->templ_time;
488 i->templ_packets = priv->templ_packets;
489 i->mtu = priv->mtu;
490}
#define NETFLOW_V9_FIELD_INPUT_SNMP
Definition: netflow.h:158
#define NETFLOW_V9_FIELD_IN_PKTS
Definition: netflow.h:150
#define NETFLOW_V9_FIELD_IPV4_DST_ADDR
Definition: netflow.h:160
#define NETFLOW_V9_FIELD_IPV4_NEXT_HOP
Definition: netflow.h:163
#define NETFLOW_V9_FIELD_OUT_BYTES
Definition: netflow.h:171
#define NETFLOW_V9_FIELD_DST_MASK
Definition: netflow.h:161
#define NETFLOW_V9_FIELD_IPV4_SRC_ADDR
Definition: netflow.h:156
#define NETFLOW_V9_FIELD_DST_AS
Definition: netflow.h:165
#define NETFLOW_V9_FIELD_L4_DST_PORT
Definition: netflow.h:159
#define NETFLOW_V9_MAX_RESERVED_FLOWSET
Definition: netflow.h:215
#define NETFLOW_V9_FIELD_IPV6_DST_ADDR
Definition: netflow.h:174
#define NETFLOW_V9_FIELD_TCP_FLAGS
Definition: netflow.h:154
#define NETFLOW_V9_FIELD_SRC_AS
Definition: netflow.h:164
uint8_t flags
Definition: netflow.h:14
#define NETFLOW_V9_FIELD_OUT_PKTS
Definition: netflow.h:172
#define NETFLOW_V9_FIELD_TOS
Definition: netflow.h:153
#define NETFLOW_V9_FIELD_L4_SRC_PORT
Definition: netflow.h:155
#define NETFLOW_V9_FIELD_SRC_MASK
Definition: netflow.h:157
#define NETFLOW_V9
Definition: netflow.h:55
#define NETFLOW_V9_FIELD_IN_BYTES
Definition: netflow.h:149
#define NETFLOW_V9_FIELD_PROTOCOL
Definition: netflow.h:152
#define NETFLOW_V9_FIELD_IPV6_NEXT_HOP
Definition: netflow.h:201
#define NETFLOW_V9_FIELD_OUTPUT_SNMP
Definition: netflow.h:162
#define NETFLOW_V9_FIELD_IPV6_SRC_ADDR
Definition: netflow.h:173
#define NETFLOW_V9_FIELD_LAST_SWITCHED
Definition: netflow.h:169
#define NETFLOW_V9_FIELD_FIRST_SWITCHED
Definition: netflow.h:170
static void close_flowset(struct mbuf *m, struct netflow_v9_packet_opt *t)
Definition: netflow_v9.c:172
void ng_netflow_copyv9info(priv_p priv, struct ng_netflow_v9info *i)
Definition: netflow_v9.c:484
struct netflow_v9_template _netflow_v9_record_ipv4_tcp[]
Definition: netflow_v9.c:71
struct netflow_v9_template _netflow_v9_record_ipv6_tcp[]
Definition: netflow_v9.c:96
void return_export9_dgram(priv_p priv, fib_export_p fe, item_p item, struct netflow_v9_packet_opt *t, int flags)
Definition: netflow_v9.c:442
void ng_netflow_v9_cache_init(priv_p priv)
Definition: netflow_v9.c:462
int export9_add(item_p item, struct netflow_v9_packet_opt *t, struct flow_entry *fle)
Definition: netflow_v9.c:241
__FBSDID("$FreeBSD$")
MALLOC_DECLARE(M_NETFLOW_GENERAL)
MALLOC_DEFINE(M_NETFLOW_GENERAL, "netflow_general", "plog, V9 templates data")
int export9_send(priv_p priv, fib_export_p fe, item_p item, struct netflow_v9_packet_opt *t, int flags)
Definition: netflow_v9.c:201
void ng_netflow_v9_cache_flush(priv_p priv)
Definition: netflow_v9.c:473
item_p get_export9_dgram(priv_p priv, fib_export_p fe, struct netflow_v9_packet_opt **tt)
Definition: netflow_v9.c:369
static void generate_v9_templates(priv_p priv)
Definition: netflow_v9.c:126
#define NETFLOW_V9_FLOW_V6_L4
Definition: netflow_v9.h:127
#define NETFLOW_V9_MAX_TIME_TEMPL
Definition: netflow_v9.h:118
#define _NETFLOW_V9_MAX_SIZE(x)
Definition: netflow_v9.h:112
#define NETFLOW_V9_FLOW_V4_L4
Definition: netflow_v9.h:124
#define _NETFLOW_V9_TEMPLATE_SIZE(x)
Definition: netflow_v9.h:120
#define CNTR
Definition: netflow_v9.h:38
#define NETFLOW_V9_MAX_PACKETS_TEMPL
Definition: netflow_v9.h:117
#define BASE_MTU
Definition: netflow_v9.h:107
#define NG_FWD_ITEM_HOOK_FLAGS(error, item, hook, flags)
Definition: netgraph.h:888
#define NGI_M(i)
Definition: netgraph.h:833
#define NG_NOFLAGS
Definition: netgraph.h:1171
item_p ng_package_data(struct mbuf *m, int flags)
Definition: ng_base.c:3520
#define NG_FREE_ITEM(item)
Definition: netgraph.h:847
u_int16_t mtu
#define MILLIUPTIME(t)
Definition: ng_netflow.h:509
#define m_pktlen(m)
Definition: ng_netflow.h:499
struct ubt_hci_evhdr header
Definition: ng_ubt_var.h:0
uint8_t length
Definition: ng_ubt_var.h:1
struct mtx export9_mtx
Definition: ng_netflow.h:392
struct netflow_export_item exp
Definition: ng_netflow.h:389
uint32_t flow9_seq
Definition: ng_netflow.h:394
uint32_t sent_packets
Definition: ng_netflow.h:399
uint32_t templ_last_pkt
Definition: ng_netflow.h:398
uint32_t templ_last_ts
Definition: ng_netflow.h:397
uint32_t domain_id
Definition: ng_netflow.h:395
Definition: ng_netflow.h:266
struct flow6_rec r
Definition: ng_netflow.h:268
uint8_t src_mask
Definition: ng_netflow.h:276
uint8_t dst_mask
Definition: ng_netflow.h:275
struct in6_addr next_hop6
Definition: ng_netflow.h:271
uint16_t fle_o_ifx
Definition: ng_netflow.h:273
union flow6_entry_data::@22 n
long first
Definition: ng_netflow.h:279
u_long packets
Definition: ng_netflow.h:277
u_long bytes
Definition: ng_netflow.h:278
u_char tcp_flags
Definition: ng_netflow.h:281
long last
Definition: ng_netflow.h:280
struct in6_addr r_dst6
Definition: ng_netflow.h:223
struct in6_addr r_src6
Definition: ng_netflow.h:219
union flow6_rec::@16 src
union flow6_rec::@17 dst
Definition: ng_netflow.h:251
u_char tcp_flags
Definition: ng_netflow.h:263
long last
Definition: ng_netflow.h:262
u_long bytes
Definition: ng_netflow.h:260
struct flow_rec r
Definition: ng_netflow.h:253
u_long packets
Definition: ng_netflow.h:259
struct in_addr next_hop
Definition: ng_netflow.h:254
uint16_t fle_o_ifx
Definition: ng_netflow.h:255
long first
Definition: ng_netflow.h:261
uint8_t dst_mask
Definition: ng_netflow.h:257
uint8_t src_mask
Definition: ng_netflow.h:258
Definition: ng_netflow.h:299
struct flow_entry_data f
Definition: ng_netflow.h:301
struct in_addr r_dst
Definition: ng_netflow.h:195
uint16_t flow_type
Definition: ng_netflow.h:192
struct in_addr r_src
Definition: ng_netflow.h:194
struct netflow_v9_packet_opt * item9_opt
Definition: ng_netflow.h:381
struct netflow_v9_header header
Definition: netflow_v9.h:134
uint16_t version
Definition: netflow.h:81
uint16_t count
Definition: netflow.h:82
union netflow_v9_record_general::@10 rec
struct netflow_v9_record_ipv6_tcp v6_tcp
Definition: netflow_v9.h:103
struct netflow_v9_record_ipv4_tcp v4_tcp
Definition: netflow_v9.h:102
struct in6_addr next_hop
Definition: netflow_v9.h:78
struct in6_addr src_addr
Definition: netflow_v9.h:76
struct in6_addr dst_addr
Definition: netflow_v9.h:77
uint16_t templ_time
Definition: ng_netflow.h:180
uint16_t templ_packets
Definition: ng_netflow.h:179
Definition: ng_sscfu.c:66