suricata
source-napatech.c
Go to the documentation of this file.
1 /* Copyright (C) 2012-2020 Open Information Security Foundation
2  *
3  * You can copy, redistribute or modify this Program under the terms of
4  * the GNU General Public License version 2 as published by the Free
5  * Software Foundation.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * version 2 along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15  * 02110-1301, USA.
16  */
17 
18 /**
19  * \file
20  *
21  - * \author nPulse Technologies, LLC.
22  - * \author Matt Keeler <mk@npulsetech.com>
23  * *
24  * Support for NAPATECH adapter with the 3GD Driver/API.
25  * Requires libntapi from Napatech A/S.
26  *
27  */
28 #include "suricata-common.h"
29 #include "suricata.h"
30 #include "threadvars.h"
31 #include "util-optimize.h"
32 #include "tm-queuehandlers.h"
33 #include "tm-threads.h"
34 #include "tm-modules.h"
35 #include "util-privs.h"
36 #include "tmqh-packetpool.h"
37 #include "util-napatech.h"
38 #include "source-napatech.h"
39 
40 #ifndef HAVE_NAPATECH
41 
42 TmEcode NoNapatechSupportExit(ThreadVars*, const void*, void**);
43 
45 {
46  tmm_modules[TMM_RECEIVENAPATECH].name = "NapatechStream";
47  tmm_modules[TMM_RECEIVENAPATECH].ThreadInit = NoNapatechSupportExit;
52 }
53 
55 {
56  tmm_modules[TMM_DECODENAPATECH].name = "NapatechDecode";
57  tmm_modules[TMM_DECODENAPATECH].ThreadInit = NoNapatechSupportExit;
63 }
64 
65 TmEcode NoNapatechSupportExit(ThreadVars *tv, const void *initdata, void **data)
66 {
68  "Error creating thread %s: you do not have support for Napatech adapter "
69  "enabled please recompile with --enable-napatech",
70  tv->name);
71  exit(EXIT_FAILURE);
72 }
73 
74 #else /* Implied we do have NAPATECH support */
75 
76 
77 #include <numa.h>
78 #include <nt.h>
79 
80 extern int max_pending_packets;
81 
82 typedef struct NapatechThreadVars_
83 {
85  NtNetStreamRx_t rx_stream;
86  uint16_t stream_id;
87  int hba;
90 
91 #ifdef NAPATECH_ENABLE_BYPASS
92 static int NapatechBypassCallback(Packet *p);
93 #endif
94 
95 TmEcode NapatechStreamThreadInit(ThreadVars *, const void *, void **);
97 TmEcode NapatechPacketLoop(ThreadVars *tv, void *data, void *slot);
98 
99 TmEcode NapatechDecodeThreadInit(ThreadVars *, const void *, void **);
102 
103 /* These are used as the threads are exiting to get a comprehensive count of
104  * all the packets received and dropped.
105  */
106 SC_ATOMIC_DECLARE(uint64_t, total_packets);
107 SC_ATOMIC_DECLARE(uint64_t, total_drops);
108 SC_ATOMIC_DECLARE(uint16_t, total_tallied);
109 
110 /* Streams are counted as they are instantiated in order to know when all threads
111  * are running*/
112 SC_ATOMIC_DECLARE(uint16_t, stream_count);
113 
114 SC_ATOMIC_DECLARE(uint16_t, numa0_count);
115 SC_ATOMIC_DECLARE(uint16_t, numa1_count);
116 SC_ATOMIC_DECLARE(uint16_t, numa2_count);
117 SC_ATOMIC_DECLARE(uint16_t, numa3_count);
118 
119 SC_ATOMIC_DECLARE(uint64_t, flow_callback_cnt);
120 SC_ATOMIC_DECLARE(uint64_t, flow_callback_handled_pkts);
121 SC_ATOMIC_DECLARE(uint64_t, flow_callback_udp_pkts);
122 SC_ATOMIC_DECLARE(uint64_t, flow_callback_tcp_pkts);
123 SC_ATOMIC_DECLARE(uint64_t, flow_callback_unhandled_pkts);
124 
125 /**
126  * \brief Register the Napatech receiver (reader) module.
127  */
129 {
130  tmm_modules[TMM_RECEIVENAPATECH].name = "NapatechStream";
139 
140  SC_ATOMIC_INIT(total_packets);
141  SC_ATOMIC_INIT(total_drops);
142  SC_ATOMIC_INIT(total_tallied);
143  SC_ATOMIC_INIT(stream_count);
144 
145  SC_ATOMIC_INIT(numa0_count);
146  SC_ATOMIC_INIT(numa1_count);
147  SC_ATOMIC_INIT(numa2_count);
148  SC_ATOMIC_INIT(numa3_count);
149 
150  SC_ATOMIC_INIT(flow_callback_cnt);
151  SC_ATOMIC_INIT(flow_callback_handled_pkts);
152  SC_ATOMIC_INIT(flow_callback_udp_pkts);
153  SC_ATOMIC_INIT(flow_callback_tcp_pkts);
154  SC_ATOMIC_INIT(flow_callback_unhandled_pkts);
155 }
156 
157 /**
158  * \brief Register the Napatech decoder module.
159  */
161 {
162  tmm_modules[TMM_DECODENAPATECH].name = "NapatechDecode";
169 }
170 
171 #ifdef NAPATECH_ENABLE_BYPASS
172 /**
173  * \brief template of IPv4 header
174  */
175 struct ipv4_hdr
176 {
177  uint8_t version_ihl; /**< version and header length */
178  uint8_t type_of_service; /**< type of service */
179  uint16_t total_length; /**< length of packet */
180  uint16_t packet_id; /**< packet ID */
181  uint16_t fragment_offset; /**< fragmentation offset */
182  uint8_t time_to_live; /**< time to live */
183  uint8_t next_proto_id; /**< protocol ID */
184  uint16_t hdr_checksum; /**< header checksum */
185  uint32_t src_addr; /**< source address */
186  uint32_t dst_addr; /**< destination address */
187 } __attribute__ ((__packed__));
188 
189 /**
190  * \brief template of IPv6 header
191  */
192 struct ipv6_hdr
193 {
194  uint32_t vtc_flow; /**< IP version, traffic class & flow label. */
195  uint16_t payload_len; /**< IP packet length - includes sizeof(ip_header). */
196  uint8_t proto; /**< Protocol, next header. */
197  uint8_t hop_limits; /**< Hop limits. */
198  uint8_t src_addr[16]; /**< IP address of source host. */
199  uint8_t dst_addr[16]; /**< IP address of destination host(s). */
200 } __attribute__ ((__packed__));
201 
202 /**
203  * \brief template of UDP header
204  */
205 struct udp_hdr
206 {
207  uint16_t src_port; /**< UDP source port. */
208  uint16_t dst_port; /**< UDP destination port. */
209  uint16_t dgram_len; /**< UDP datagram length */
210  uint16_t dgram_cksum; /**< UDP datagram checksum */
211 } __attribute__ ((__packed__));
212 
213 /**
214  * \brief template of TCP header
215  */
216 struct tcp_hdr
217 {
218  uint16_t src_port; /**< TCP source port. */
219  uint16_t dst_port; /**< TCP destination port. */
220  uint32_t sent_seq; /**< TX data sequence number. */
221  uint32_t recv_ack; /**< RX data acknowledgement sequence number. */
222  uint8_t data_off; /**< Data offset. */
223  uint8_t tcp_flags; /**< TCP flags */
224  uint16_t rx_win; /**< RX flow control window. */
225  uint16_t cksum; /**< TCP checksum. */
226  uint16_t tcp_urp; /**< TCP urgent pointer, if any. */
227 } __attribute__ ((__packed__));
228 
229 
230 /* The hardware will assign a "color" value indicating what filters are matched
231  * by a given packet. These constants indicate what bits are set in the color
232  * field for different protocols
233  *
234  */
235 #define RTE_PTYPE_L2_ETHER 0x10000000
236 #define RTE_PTYPE_L3_IPV4 0x01000000
237 #define RTE_PTYPE_L3_IPV6 0x04000000
238 #define RTE_PTYPE_L4_TCP 0x00100000
239 #define RTE_PTYPE_L4_UDP 0x00200000
240 
241 /* These masks are used to extract layer 3 and layer 4 protocol
242  * values from the color field in the packet descriptor.
243  */
244 #define RTE_PTYPE_L3_MASK 0x0f000000
245 #define RTE_PTYPE_L4_MASK 0x00f00000
246 
247 #define COLOR_IS_SPAN 0x00001000
248 
249 static int is_inline = 0;
250 static int inline_port_map[MAX_PORTS] = { -1 };
251 
252 /**
253  * \brief Binds two ports together for inline operation.
254  *
255  * Get the ID of an adapter on which a given port resides.
256  *
257  * \param port one of the ports in a pairing.
258  * \param peer the other port in a pairing.
259  * \return ID of the adapter.
260  *
261  */
262 int NapatechSetPortmap(int port, int peer)
263 {
264  if ((inline_port_map[port] == -1) && (inline_port_map[peer] == -1)) {
265  inline_port_map[port] = peer;
266  inline_port_map[peer] = port;
267  } else {
269  "Port pairing is already configured.");
270  return 0;
271  }
272  return 1;
273 }
274 
275 /**
276  * \brief Returns the ID of the adapter
277  *
278  * Get the ID of an adapter on which a given port resides.
279  *
280  * \param port for which adapter ID is requested.
281  * \return ID of the adapter.
282  *
283  */
284 int NapatechGetAdapter(uint8_t port)
285 {
286  static int port_adapter_map[MAX_PORTS] = { -1 };
287  int status;
288  NtInfo_t h_info; /* Info handle */
289  NtInfoStream_t h_info_stream; /* Info stream handle */
290 
291  if (unlikely(port_adapter_map[port] == -1)) {
292  if ((status = NT_InfoOpen(&h_info_stream, "ExampleInfo")) != NT_SUCCESS) {
294  return -1;
295  }
296  /* Read the system info */
297  h_info.cmd = NT_INFO_CMD_READ_PORT_V9;
298  h_info.u.port_v9.portNo = (uint8_t) port;
299  if ((status = NT_InfoRead(h_info_stream, &h_info)) != NT_SUCCESS) {
300  /* Get the status code as text */
302  NT_InfoClose(h_info_stream);
303  return -1;
304  }
305  port_adapter_map[port] = h_info.u.port_v9.data.adapterNo;
306  }
307  return port_adapter_map[port];
308 }
309 
310 /**
311  * \brief IPv4 4-tuple convenience structure
312  */
313 struct IPv4Tuple4
314 {
315  uint32_t sa; /*!< Source address */
316  uint32_t da; /*!< Destination address */
317  uint16_t sp; /*!< Source port */
318  uint16_t dp; /*!< Destination port */
319 };
320 
321 /**
322  * \brief IPv6 4-tuple convenience structure
323  */
324 struct IPv6Tuple4
325 {
326  uint8_t sa[16]; /*!< Source address */
327  uint8_t da[16]; /*!< Destination address */
328  uint16_t sp; /*!< Source port */
329  uint16_t dp; /*!< Destination port */
330 };
331 
332 
333 /**
334  * \brief Compares the byte order value of two IPv6 addresses.
335  *
336  *
337  * \param addr_a The first address to compare
338  * \param addr_b The second adress to compare
339  *
340  * \return -1 if addr_a < addr_b
341  * 1 if addr_a > addr_b
342  * 0 if addr_a == addr_b
343  */
344 static int CompareIPv6Addr(uint8_t addr_a[16], uint8_t addr_b[16]) {
345  uint16_t pos;
346  for (pos = 0; pos < 16; ++pos) {
347  if (addr_a[pos] < addr_b[pos]) {
348  return -1;
349  } else if (addr_a[pos] > addr_b[pos]) {
350  return 1;
351  } /* else they are equal - check next position*/
352  }
353 
354  /* if we get here the addresses are equal */
355  return 0;
356 }
357 
358 /**
359  * \brief Initializes the FlowStreams used to program flow data.
360  *
361  * Opens a FlowStream on the adapter associated with the rx port. This
362  * FlowStream is subsequently used to program the adapter with
363  * flows to bypass.
364  *
365  * \return the flow stream handle, NULL if failure.
366  */
367 static NtFlowStream_t InitFlowStream(int adapter, int stream_id)
368 {
369  int status;
370  NtFlowStream_t hFlowStream;
371 
372  NtFlowAttr_t attr;
373  char flow_name[80];
374 
375  NT_FlowOpenAttrInit(&attr);
376  NT_FlowOpenAttrSetAdapterNo(&attr, adapter);
377 
378  snprintf(flow_name, sizeof(flow_name), "Flow_stream_%d", stream_id );
379  SCLogDebug("Opening flow programming stream: %s", flow_name);
380  if ((status = NT_FlowOpen_Attr(&hFlowStream, flow_name, &attr)) != NT_SUCCESS) {
382  "Napatech bypass functionality not supported by the FPGA version on adapter %d - disabling support.",
383  adapter);
384  return NULL;
385  }
386  return hFlowStream;
387 }
388 
389 /**
390  * \brief Callback function to process Bypass events on Napatech Adapter.
391  *
392  * Callback function that sets up the Flow tables on the Napatech card
393  * so that subsequent packets from this flow are bypassed on the hardware.
394  *
395  * \param p packet containing information about the flow to be bypassed
396  * \param is_inline indicates if Suricata is being run in inline mode.
397  *
398  * \return Error code indicating success (1) or failure (0).
399  *
400  */
401 static int ProgramFlow(Packet *p, int is_inline)
402 {
403  NtFlow_t flow_match;
404  memset(&flow_match, 0, sizeof(flow_match));
405 
406  NapatechPacketVars *ntpv = &(p->ntpv);
407 
408  /*
409  * The hardware decoder will "color" the packets according to the protocols
410  * in the packet and the port the packet arrived on. packet_type gets
411  * these bits and we mask out layer3, layer4, and is_span to determine
412  * the protocols and if the packet is coming in from a SPAN port.
413  */
414  uint32_t packet_type = ((ntpv->dyn3->color_hi << 14) & 0xFFFFC000) | ntpv->dyn3->color_lo;
415  uint8_t *packet = (uint8_t *) ntpv->dyn3 + ntpv->dyn3->descrLength;
416 
417  uint32_t layer3 = packet_type & RTE_PTYPE_L3_MASK;
418  uint32_t layer4 = packet_type & RTE_PTYPE_L4_MASK;
419  uint32_t is_span = packet_type & COLOR_IS_SPAN;
420 
421  /*
422  * When we're programming the flows to arrive on a span port,
423  * where upstream and downstream packets arrive on the same port,
424  * the hardware is configured to swap the source and dest
425  * fields if the src addr > dest addr. We need to program the
426  * flow tables to match. We'll compare addresses and set
427  * do_swap accordingly.
428  */
429 
430  uint32_t do_swap = 0;
431 
432  SC_ATOMIC_ADD(flow_callback_cnt, 1);
433 
434  /* Only bypass TCP and UDP */
435  if (PKT_IS_TCP(p)) {
436  SC_ATOMIC_ADD(flow_callback_tcp_pkts, 1);
437  } else if PKT_IS_UDP(p) {
438  SC_ATOMIC_ADD(flow_callback_udp_pkts, 1);
439  } else {
440  SC_ATOMIC_ADD(flow_callback_unhandled_pkts, 1);
441  }
442 
443  struct IPv4Tuple4 v4Tuple;
444  struct IPv6Tuple4 v6Tuple;
445  struct ipv4_hdr *pIPv4_hdr = NULL;
446  struct ipv6_hdr *pIPv6_hdr = NULL;
447 
448  switch (layer3) {
449  case RTE_PTYPE_L3_IPV4:
450  {
451  pIPv4_hdr = (struct ipv4_hdr *) (packet + ntpv->dyn3->offset0);
452  if (!is_span) {
453  v4Tuple.sa = pIPv4_hdr->src_addr;
454  v4Tuple.da = pIPv4_hdr->dst_addr;
455  } else {
456  do_swap = (htonl(pIPv4_hdr->src_addr) > htonl(pIPv4_hdr->dst_addr));
457  if (!do_swap) {
458  /* already in order */
459  v4Tuple.sa = pIPv4_hdr->src_addr;
460  v4Tuple.da = pIPv4_hdr->dst_addr;
461  } else { /* swap */
462  v4Tuple.sa = pIPv4_hdr->dst_addr;
463  v4Tuple.da = pIPv4_hdr->src_addr;
464  }
465  }
466  break;
467  }
468  case RTE_PTYPE_L3_IPV6:
469  {
470  pIPv6_hdr = (struct ipv6_hdr *) (packet + ntpv->dyn3->offset0);
471  do_swap = (CompareIPv6Addr(pIPv6_hdr->src_addr, pIPv6_hdr->dst_addr) > 0);
472 
473  if (!is_span) {
474  memcpy(&(v6Tuple.sa), pIPv6_hdr->src_addr, 16);
475  memcpy(&(v6Tuple.da), pIPv6_hdr->dst_addr, 16);
476  } else {
477  /* sort src/dest address before programming */
478  if (!do_swap) {
479  /* already in order */
480  memcpy(&(v6Tuple.sa), pIPv6_hdr->src_addr, 16);
481  memcpy(&(v6Tuple.da), pIPv6_hdr->dst_addr, 16);
482  } else { /* swap the addresses */
483  memcpy(&(v6Tuple.sa), pIPv6_hdr->dst_addr, 16);
484  memcpy(&(v6Tuple.da), pIPv6_hdr->src_addr, 16);
485  }
486  }
487  break;
488  }
489  default:
490  {
491  return 0;
492  }
493  }
494 
495  switch (layer4) {
496  case RTE_PTYPE_L4_TCP:
497  {
498  struct tcp_hdr *tcp_hdr = (struct tcp_hdr *) (packet + ntpv->dyn3->offset1);
499  if (layer3 == RTE_PTYPE_L3_IPV4) {
500  if (!is_span) {
501  v4Tuple.dp = tcp_hdr->dst_port;
502  v4Tuple.sp = tcp_hdr->src_port;
503  flow_match.keyId = NAPATECH_KEYTYPE_IPV4;
504  } else {
505  if (!do_swap) {
506  v4Tuple.sp = tcp_hdr->src_port;
507  v4Tuple.dp = tcp_hdr->dst_port;
508  } else {
509  v4Tuple.sp = tcp_hdr->dst_port;
510  v4Tuple.dp = tcp_hdr->src_port;
511  }
512  flow_match.keyId = NAPATECH_KEYTYPE_IPV4_SPAN;
513  }
514  memcpy(&(flow_match.keyData), &v4Tuple, sizeof(v4Tuple));
515  } else {
516  if (!is_span) {
517  v6Tuple.dp = tcp_hdr->dst_port;
518  v6Tuple.sp = tcp_hdr->src_port;
519  flow_match.keyId = NAPATECH_KEYTYPE_IPV6;
520  } else {
521  if (!do_swap) {
522  v6Tuple.sp = tcp_hdr->src_port;
523  v6Tuple.dp = tcp_hdr->dst_port;
524  } else {
525  v6Tuple.dp = tcp_hdr->src_port;
526  v6Tuple.sp = tcp_hdr->dst_port;
527  }
528  flow_match.keyId = NAPATECH_KEYTYPE_IPV6_SPAN;
529  }
530  memcpy(&(flow_match.keyData), &v6Tuple, sizeof(v6Tuple));
531  }
532  flow_match.ipProtocolField = 6;
533  break;
534  }
535  case RTE_PTYPE_L4_UDP:
536  {
537  struct udp_hdr *udp_hdr = (struct udp_hdr *) (packet + ntpv->dyn3->offset1);
538  if (layer3 == RTE_PTYPE_L3_IPV4) {
539  if (!is_span) {
540  v4Tuple.dp = udp_hdr->dst_port;
541  v4Tuple.sp = udp_hdr->src_port;
542  flow_match.keyId = NAPATECH_KEYTYPE_IPV4;
543  } else {
544  if (!do_swap) {
545  v4Tuple.sp = udp_hdr->src_port;
546  v4Tuple.dp = udp_hdr->dst_port;
547  } else {
548  v4Tuple.dp = udp_hdr->src_port;
549  v4Tuple.sp = udp_hdr->dst_port;
550  }
551  flow_match.keyId = NAPATECH_KEYTYPE_IPV4_SPAN;
552  }
553  memcpy(&(flow_match.keyData), &v4Tuple, sizeof(v4Tuple));
554  } else { /* layer3 is IPV6 */
555  if (!is_span) {
556  v6Tuple.dp = udp_hdr->dst_port;
557  v6Tuple.sp = udp_hdr->src_port;
558  flow_match.keyId = NAPATECH_KEYTYPE_IPV6;
559  } else {
560  if (!do_swap) {
561  v6Tuple.sp = udp_hdr->src_port;
562  v6Tuple.dp = udp_hdr->dst_port;
563  } else {
564  v6Tuple.dp = udp_hdr->src_port;
565  v6Tuple.sp = udp_hdr->dst_port;
566  }
567  flow_match.keyId = NAPATECH_KEYTYPE_IPV6_SPAN;
568  }
569  memcpy(&(flow_match.keyData), &v6Tuple, sizeof(v6Tuple));
570  }
571  flow_match.ipProtocolField = 17;
572  break;
573  }
574  default:
575  {
576  return 0;
577  }
578  }
579 
580  flow_match.op = 1; /* program flow */
581  flow_match.gfi = 1; /* Generate FlowInfo records */
582  flow_match.tau = 1; /* tcp automatic unlearn */
583 
585  flow_match.keySetId = NAPATECH_FLOWTYPE_DROP;
586  } else {
587  if (is_inline) {
588  flow_match.keySetId = NAPATECH_FLOWTYPE_PASS;
589  } else {
590  flow_match.keySetId = NAPATECH_FLOWTYPE_DROP;
591  }
592  }
593 
594  if (NT_FlowWrite(ntpv->flow_stream, &flow_match, -1) != NT_SUCCESS) {
596  SCLogError(SC_ERR_NAPATECH_OPEN_FAILED,"NT_FlowWrite failed!.");
597  exit(EXIT_FAILURE);
598  }
599  }
600 
601  return 1;
602 }
603 
604 /**
605  * \brief Callback from Suricata when a flow that should be bypassed
606  * is identified.
607  */
608 
609 static int NapatechBypassCallback(Packet *p)
610 {
611  NapatechPacketVars *ntpv = &(p->ntpv);
612 
613  /*
614  * Since, at this point, we don't know what action to take,
615  * simply mark this packet as one that should be
616  * bypassed when the packet is returned by suricata with a
617  * pass/drop verdict.
618  */
619  ntpv->bypass = 1;
620 
621  return 1;
622 }
623 
624 #endif
625 
626 /**
627  * \brief Initialize the Napatech receiver thread, generate a single
628  * NapatechThreadVar structure for each thread, this will
629  * contain a NtNetStreamRx_t stream handle which is used when the
630  * thread executes to acquire the packets.
631  *
632  * \param tv Thread variable to ThreadVars
633  * \param initdata Initial data to the adapter passed from the user,
634  * this is processed by the user.
635  *
636  * For now, we assume that we have only a single name for the NAPATECH
637  * adapter.
638  *
639  * \param data data pointer gets populated with
640  *
641  */
642 TmEcode NapatechStreamThreadInit(ThreadVars *tv, const void *initdata, void **data)
643 {
644  SCEnter();
645  struct NapatechStreamDevConf *conf = (struct NapatechStreamDevConf *) initdata;
646  uint16_t stream_id = conf->stream_id;
647  *data = NULL;
648 
649  NapatechThreadVars *ntv = SCCalloc(1, sizeof (NapatechThreadVars));
650  if (unlikely(ntv == NULL)) {
652  "Failed to allocate memory for NAPATECH thread vars.");
653  }
654 
655  memset(ntv, 0, sizeof (NapatechThreadVars));
656  ntv->stream_id = stream_id;
657  ntv->tv = tv;
658  ntv->hba = conf->hba;
659  SCLogDebug("Started processing packets from NAPATECH Stream: %lu", ntv->stream_id);
660 
661  *data = (void *) ntv;
663 }
664 
665 /**
666  * \brief Callback to indicate that the packet buffer can be returned to the hardware.
667  *
668  * Called when Suricata is done processing the packet. Before the packet is released
669  * this also checks the action to see if the packet should be dropped and programs the
670  * flow hardware if the flow is to be bypassed and the Napatech packet buffer is released.
671  *
672  *
673  * \param p Packet to return to the system.
674  *
675  */
676 static void NapatechReleasePacket(struct Packet_ *p)
677 {
678  /*
679  * If the packet is to be dropped we need to set the wirelength
680  * before releasing the Napatech buffer back to NTService.
681  */
682 #ifdef NAPATECH_ENABLE_BYPASS
683  if (is_inline && PACKET_TEST_ACTION(p, ACTION_DROP)) {
684  p->ntpv.dyn3->wireLength = 0;
685  }
686 
687  /*
688  * If this flow is to be programmed for hardware bypass we do it now. This is done
689  * here because the action is not available in the packet structure at the time of the
690  * bypass callback and it needs to be done before we release the packet structure.
691  */
692  if (p->ntpv.bypass == 1) {
693  ProgramFlow(p, is_inline);
694  }
695 #endif
696 
697  NT_NetRxRelease(p->ntpv.rx_stream, p->ntpv.nt_packet_buf);
699 }
700 
701 /**
702  * \brief Returns the NUMA node associated with the currently running thread.
703  *
704  * \return ID of the NUMA node.
705  *
706  */
707 static int GetNumaNode(void)
708 {
709  int cpu = 0;
710  int node = 0;
711 
712 #if defined(__linux__)
713  cpu = sched_getcpu();
714  node = numa_node_of_cpu(cpu);
715 #else
717  "Auto configuration of NUMA node is not supported on this OS.");
718 #endif
719 
720  return node;
721 }
722 
723 /**
724  * \brief Outputs hints on the optimal host-buffer configuration to aid tuning.
725  *
726  * \param log_level of the currently running instance.
727  *
728  */
729 static void RecommendNUMAConfig(SCLogLevel log_level)
730 {
731  char string0[16];
732  char string1[16];
733  char string2[16];
734  char string3[16];
735  int set_cpu_affinity = 0;
736 
737  if (ConfGetBool("threading.set-cpu-affinity", &set_cpu_affinity) != 1) {
738  set_cpu_affinity = 0;
739  }
740 
741  if (set_cpu_affinity) {
742  SCLog(log_level, __FILE__, __FUNCTION__, __LINE__,
743  "Minimum host buffers that should be defined in ntservice.ini:");
744 
745  SCLog(log_level, __FILE__, __FUNCTION__, __LINE__, " NUMA Node 0: %d",
746  (SC_ATOMIC_GET(numa0_count)));
747 
748  if (numa_max_node() >= 1)
749  SCLog(log_level, __FILE__, __FUNCTION__, __LINE__,
750  " NUMA Node 1: %d ", (SC_ATOMIC_GET(numa1_count)));
751 
752  if (numa_max_node() >= 2)
753  SCLog(log_level, __FILE__, __FUNCTION__, __LINE__,
754  " NUMA Node 2: %d ", (SC_ATOMIC_GET(numa2_count)));
755 
756  if (numa_max_node() >= 3)
757  SCLog(log_level, __FILE__, __FUNCTION__, __LINE__,
758  " NUMA Node 3: %d ", (SC_ATOMIC_GET(numa3_count)));
759 
760  snprintf(string0, 16, "[%d, 16, 0]", SC_ATOMIC_GET(numa0_count));
761  snprintf(string1, 16, (numa_max_node() >= 1 ? ",[%d, 16, 1]" : ""),
762  SC_ATOMIC_GET(numa1_count));
763  snprintf(string2, 16, (numa_max_node() >= 2 ? ",[%d, 16, 2]" : ""),
764  SC_ATOMIC_GET(numa2_count));
765  snprintf(string3, 16, (numa_max_node() >= 3 ? ",[%d, 16, 3]" : ""),
766  SC_ATOMIC_GET(numa3_count));
767 
768  SCLog(log_level, __FILE__, __FUNCTION__, __LINE__,
769  "E.g.: HostBuffersRx=%s%s%s%s", string0, string1, string2,
770  string3);
771  } else if (log_level == SC_LOG_ERROR) {
773  "Or, try running /opt/napatech3/bin/ntpl -e \"delete=all\" to clean-up stream NUMA config.");
774  }
775 }
776 
777 /**
778  * \brief Main Napatechpacket processing loop
779  *
780  * \param tv Thread variable to ThreadVars
781  * \param data Pointer to NapatechThreadVars with data specific to Napatech
782  * \param slot TMSlot where this instance is running.
783  *
784  */
785 TmEcode NapatechPacketLoop(ThreadVars *tv, void *data, void *slot)
786 {
787  int32_t status;
788  char error_buffer[100];
789  uint64_t pkt_ts;
790  NtNetBuf_t packet_buffer;
791  NapatechThreadVars *ntv = (NapatechThreadVars *) data;
792  uint64_t hba_pkt_drops = 0;
793  uint64_t hba_byte_drops = 0;
794  uint16_t hba_pkt = 0;
795  int numa_node = -1;
796  int set_cpu_affinity = 0;
797  int closer = 0;
798  int is_autoconfig = 0;
799 
800  /* This just keeps the startup output more orderly. */
801  usleep(200000 * ntv->stream_id);
802 
803 #ifdef NAPATECH_ENABLE_BYPASS
804  NtFlowStream_t flow_stream[MAX_ADAPTERS] = { 0 };
805 
806  /* Get a FlowStream handle for each adapter so we can efficiently find the
807  * correct handle corresponding to the port on which a packet is received.
808  */
809  int adapter = 0;
810  for (adapter = 0; adapter < NapatechGetNumAdapters(); ++adapter) {
811  flow_stream[adapter] = InitFlowStream(adapter, ntv->stream_id);
812  }
813 #endif
814 
815  if (ConfGetBool("napatech.auto-config", &is_autoconfig) == 0) {
816  is_autoconfig = 0;
817  }
818 
819  if (is_autoconfig) {
820  numa_node = GetNumaNode();
821  switch (numa_node) {
822  case 0:
823  SC_ATOMIC_ADD(numa0_count, 1);
824  break;
825  case 1:
826  SC_ATOMIC_ADD(numa1_count, 1);
827  break;
828  case 2:
829  SC_ATOMIC_ADD(numa2_count, 1);
830  break;
831  case 3:
832  SC_ATOMIC_ADD(numa3_count, 1);
833  break;
834  default:
835  break;
836  }
837 
838  if (ConfGetBool("threading.set-cpu-affinity", &set_cpu_affinity) != 1) {
839  set_cpu_affinity = 0;
840  }
841 
842  if (set_cpu_affinity) {
843  NapatechSetupNuma(ntv->stream_id, numa_node);
844  }
845 
846  numa_node = GetNumaNode();
847  SC_ATOMIC_ADD(stream_count, 1);
848  if (SC_ATOMIC_GET(stream_count) == NapatechGetNumConfiguredStreams()) {
849 
850 #ifdef NAPATECH_ENABLE_BYPASS
851  if (ConfGetBool("napatech.inline", &is_inline) == 0) {
852  is_inline = 0;
853  }
854 
855  /* Initialize the port map before we setup traffic filters */
856  for (int i = 0; i < MAX_PORTS; ++i) {
857  inline_port_map[i] = -1;
858  }
859 #endif
860  /* The last thread to run sets up and deletes the streams */
863 
864  closer = 1;
865 
866  if (status == 0x20002061) {
868  "Check host buffer configuration in ntservice.ini.");
869  RecommendNUMAConfig(SC_LOG_ERROR);
870  exit(EXIT_FAILURE);
871 
872  } else if (status == 0x20000008) {
874  "Check napatech.ports in the suricata config file.");
875  }
876  RecommendNUMAConfig(SC_LOG_PERF);
877  SCLogNotice("Napatech packet input engine started.");
878  }
879  } // is_autoconfig
880 
881  SCLogInfo(
882  "Napatech Packet Loop Started - cpu: %3d, cpu_numa: %3d stream: %3u ",
883  sched_getcpu(), numa_node, ntv->stream_id);
884 
885  if (ntv->hba > 0) {
886  char *s_hbad_pkt = SCCalloc(1, 32);
887  if (unlikely(s_hbad_pkt == NULL)) {
889  "Failed to allocate memory for NAPATECH stream counter.");
890  }
891  snprintf(s_hbad_pkt, 32, "nt%d.hba_drop", ntv->stream_id);
892  hba_pkt = StatsRegisterCounter(s_hbad_pkt, tv);
894  StatsSetUI64(tv, hba_pkt, 0);
895  }
896  SCLogDebug("Opening NAPATECH Stream: %lu for processing", ntv->stream_id);
897 
898  if ((status = NT_NetRxOpen(&(ntv->rx_stream), "SuricataStream",
899  NT_NET_INTERFACE_PACKET, ntv->stream_id, ntv->hba)) != NT_SUCCESS) {
900 
902  SCFree(ntv);
904  }
905  TmSlot *s = (TmSlot *) slot;
906  ntv->slot = s->slot_next;
907 
908  while (!(suricata_ctl_flags & SURICATA_STOP)) {
909  /* make sure we have at least one packet in the packet pool, to prevent
910  * us from alloc'ing packets at line rate */
911  PacketPoolWait();
912 
913  /* Napatech returns packets 1 at a time */
914  status = NT_NetRxGet(ntv->rx_stream, &packet_buffer, 1000);
915  if (unlikely(
916  status == NT_STATUS_TIMEOUT || status == NT_STATUS_TRYAGAIN)) {
917  if (status == NT_STATUS_TIMEOUT) {
918  TmThreadsCaptureHandleTimeout(tv, NULL);
919  }
920  continue;
921  } else if (unlikely(status != NT_SUCCESS)) {
923  SCLogInfo("Failed to read from Napatech Stream %d: %s",
924  ntv->stream_id, error_buffer);
925  break;
926  }
927 
929 #ifdef NAPATECH_ENABLE_BYPASS
930  p->ntpv.bypass = 0;
931 #endif
932 
933  p->ntpv.rx_stream = ntv->rx_stream;
934 
935  if (unlikely(p == NULL)) {
936  NT_NetRxRelease(ntv->rx_stream, packet_buffer);
938  }
939 
940  pkt_ts = NT_NET_GET_PKT_TIMESTAMP(packet_buffer);
941 
942  /*
943  * Handle the different timestamp forms that the napatech cards could use
944  * - NT_TIMESTAMP_TYPE_NATIVE is not supported due to having an base
945  * of 0 as opposed to NATIVE_UNIX which has a base of 1/1/1970
946  */
947  switch (NT_NET_GET_PKT_TIMESTAMP_TYPE(packet_buffer)) {
948  case NT_TIMESTAMP_TYPE_NATIVE_UNIX:
949  p->ts.tv_sec = pkt_ts / 100000000;
950  p->ts.tv_usec = ((pkt_ts % 100000000) / 100) + ((pkt_ts % 100) > 50 ? 1 : 0);
951  break;
952  case NT_TIMESTAMP_TYPE_PCAP:
953  p->ts.tv_sec = pkt_ts >> 32;
954  p->ts.tv_usec = pkt_ts & 0xFFFFFFFF;
955  break;
956  case NT_TIMESTAMP_TYPE_PCAP_NANOTIME:
957  p->ts.tv_sec = pkt_ts >> 32;
958  p->ts.tv_usec = ((pkt_ts & 0xFFFFFFFF) / 1000) + ((pkt_ts % 1000) > 500 ? 1 : 0);
959  break;
960  case NT_TIMESTAMP_TYPE_NATIVE_NDIS:
961  /* number of seconds between 1/1/1601 and 1/1/1970 */
962  p->ts.tv_sec = (pkt_ts / 100000000) - 11644473600;
963  p->ts.tv_usec = ((pkt_ts % 100000000) / 100) + ((pkt_ts % 100) > 50 ? 1 : 0);
964  break;
965  default:
967  "Packet from Napatech Stream: %u does not have a supported timestamp format",
968  ntv->stream_id);
969  NT_NetRxRelease(ntv->rx_stream, packet_buffer);
971  }
972 
973  if (unlikely(ntv->hba > 0)) {
974  NtNetRx_t stat_cmd;
975  stat_cmd.cmd = NT_NETRX_READ_CMD_STREAM_DROP;
976  /* Update drop counter */
977  if (unlikely((status = NT_NetRxRead(ntv->rx_stream, &stat_cmd)) != NT_SUCCESS)) {
979  SCLogInfo("Couldn't retrieve drop statistics from the RX stream: %u",
980  ntv->stream_id);
981  } else {
982  hba_pkt_drops = stat_cmd.u.streamDrop.pktsDropped;
983 
984  StatsSetUI64(tv, hba_pkt, hba_pkt_drops);
985  }
987  }
988 
989 #ifdef NAPATECH_ENABLE_BYPASS
990  p->ntpv.dyn3 = _NT_NET_GET_PKT_DESCR_PTR_DYN3(packet_buffer);
991  p->BypassPacketsFlow = (NapatechIsBypassSupported() ? NapatechBypassCallback : NULL);
992  NT_NET_SET_PKT_TXPORT(packet_buffer, inline_port_map[p->ntpv.dyn3->rxPort]);
993  p->ntpv.flow_stream = flow_stream[NapatechGetAdapter(p->ntpv.dyn3->rxPort)];
994 
995 #endif
996 
997  p->ReleasePacket = NapatechReleasePacket;
998  p->ntpv.nt_packet_buf = packet_buffer;
999  p->ntpv.stream_id = ntv->stream_id;
1001 
1002  if (unlikely(PacketSetData(p, (uint8_t *)NT_NET_GET_PKT_L2_PTR(packet_buffer), NT_NET_GET_PKT_WIRE_LENGTH(packet_buffer)))) {
1003  TmqhOutputPacketpool(ntv->tv, p);
1004  NT_NetRxRelease(ntv->rx_stream, packet_buffer);
1006  }
1007 
1008  if (unlikely(TmThreadsSlotProcessPkt(ntv->tv, ntv->slot, p) != TM_ECODE_OK)) {
1009  NT_NetRxRelease(ntv->rx_stream, packet_buffer);
1011  }
1012 
1013  /*
1014  * At this point the packet and the Napatech Packet Buffer have been returned
1015  * to the system in the NapatechReleasePacket() Callback.
1016  */
1017 
1019  } // while
1020 
1021  if (closer) {
1023  }
1024 
1025  if (unlikely(ntv->hba > 0)) {
1026  SCLogInfo("Host Buffer Allowance Drops - pkts: %ld, bytes: %ld", hba_pkt_drops, hba_byte_drops);
1027  }
1028 
1030 }
1031 
1032 /**
1033  * \brief Print some stats to the log at program exit.
1034  *
1035  * \param tv Pointer to ThreadVars.
1036  * \param data Pointer to data, ErfFileThreadVars.
1037  */
1039 {
1040  NapatechThreadVars *ntv = (NapatechThreadVars *) data;
1042 
1043  double percent = 0;
1044  if (stat.current_drop_packets > 0)
1045  percent = (((double) stat.current_drop_packets)
1046  / (stat.current_packets + stat.current_drop_packets)) * 100;
1047 
1048  SCLogInfo("nt%lu - pkts: %lu; drop: %lu (%5.2f%%); bytes: %lu",
1049  (uint64_t) ntv->stream_id, stat.current_packets,
1050  stat.current_drop_packets, percent, stat.current_bytes);
1051 
1052  SC_ATOMIC_ADD(total_packets, stat.current_packets);
1053  SC_ATOMIC_ADD(total_drops, stat.current_drop_packets);
1054  SC_ATOMIC_ADD(total_tallied, 1);
1055 
1056  if (SC_ATOMIC_GET(total_tallied) == NapatechGetNumConfiguredStreams()) {
1057  if (SC_ATOMIC_GET(total_drops) > 0)
1058  percent = (((double) SC_ATOMIC_GET(total_drops)) / (SC_ATOMIC_GET(total_packets)
1059  + SC_ATOMIC_GET(total_drops))) * 100;
1060 
1061  SCLogInfo(" ");
1062  SCLogInfo("--- Total Packets: %ld Total Dropped: %ld (%5.2f%%)",
1063  SC_ATOMIC_GET(total_packets), SC_ATOMIC_GET(total_drops), percent);
1064 
1065 #ifdef NAPATECH_ENABLE_BYPASS
1066  SCLogInfo("--- BypassCB - Total: %ld, UDP: %ld, TCP: %ld, Unhandled: %ld",
1067  SC_ATOMIC_GET(flow_callback_cnt),
1068  SC_ATOMIC_GET(flow_callback_udp_pkts),
1069  SC_ATOMIC_GET(flow_callback_tcp_pkts),
1070  SC_ATOMIC_GET(flow_callback_unhandled_pkts));
1071 #endif
1072  }
1073 }
1074 
1075 /**
1076  * \brief Deinitializes the NAPATECH card.
1077  * \param tv pointer to ThreadVars
1078  * \param data pointer that gets cast into PcapThreadVars for ptv
1079  */
1081 {
1082  SCEnter();
1083  NapatechThreadVars *ntv = (NapatechThreadVars *) data;
1084 
1085  SCLogDebug("Closing Napatech Stream: %d", ntv->stream_id);
1086  NT_NetRxClose(ntv->rx_stream);
1087 
1089 }
1090 
1091 /**
1092  * \brief This function passes off to link type decoders.
1093  *
1094  * NapatechDecode decodes packets from Napatech and passes
1095  * them off to the proper link type decoder.
1096  *
1097  * \param t pointer to ThreadVars
1098  * \param p pointer to the current packet
1099  * \param data pointer that gets cast into PcapThreadVars for ptv
1100  */
1102 {
1103  SCEnter();
1104 
1106 
1108 
1109  // update counters
1111 
1112  switch (p->datalink) {
1113  case LINKTYPE_ETHERNET:
1115  break;
1116  default:
1118  "Datalink type %" PRId32 " not yet supported in module NapatechDecode",
1119  p->datalink);
1120  break;
1121  }
1122 
1125 }
1126 
1127 /**
1128  * \brief Initialization of Napatech Thread.
1129  *
1130  * \param t pointer to ThreadVars
1131  * \param initdata - unused.
1132  * \param data pointer that gets cast into DecoderThreadVars
1133  */
1134 TmEcode NapatechDecodeThreadInit(ThreadVars *tv, const void *initdata, void **data)
1135 {
1136  SCEnter();
1137  DecodeThreadVars *dtv = NULL;
1139  if (dtv == NULL) {
1141  }
1142 
1144  *data = (void *) dtv;
1146 }
1147 
1148 /**
1149  * \brief Deinitialization of Napatech Thread.
1150  *
1151  * \param tv pointer to ThreadVars
1152  * \param data pointer that gets cast into DecoderThreadVars
1153  */
1155 {
1156  if (data != NULL) {
1157  DecodeThreadVarsFree(tv, data);
1158  }
1160 }
1161 
1162 #endif /* HAVE_NAPATECH */
TmModule_::cap_flags
uint8_t cap_flags
Definition: tm-modules.h:67
TMM_RECEIVENAPATECH
@ TMM_RECEIVENAPATECH
Definition: tm-threads-common.h:59
PKT_IS_UDP
#define PKT_IS_UDP(p)
Definition: decode.h:260
NapatechPacketVars_::stream_id
uint64_t stream_id
Definition: util-napatech.h:31
tm-threads.h
NapatechStreamThreadInit
TmEcode NapatechStreamThreadInit(ThreadVars *, const void *, void **)
Initialize the Napatech receiver thread, generate a single NapatechThreadVar structure for each threa...
Definition: source-napatech.c:642
NapatechGetCurrentStats
NapatechCurrentStats NapatechGetCurrentStats(uint16_t id)
Definition: util-napatech.c:193
max_pending_packets
int max_pending_packets
Definition: suricata.c:212
NapatechPacketVars_
Definition: util-napatech.h:30
ThreadVars_::name
char name[16]
Definition: threadvars.h:65
PacketFreeOrRelease
void PacketFreeOrRelease(Packet *p)
Return a packet to where it was allocated.
Definition: decode.c:165
SC_ATOMIC_INIT
#define SC_ATOMIC_INIT(name)
wrapper for initializing an atomic variable.
Definition: util-atomic.h:315
PKT_IS_PSEUDOPKT
#define PKT_IS_PSEUDOPKT(p)
return 1 if the packet is a pseudo packet
Definition: decode.h:1147
ConfGetBool
int ConfGetBool(const char *name, int *val)
Retrieve a configuration value as an boolen.
Definition: conf.c:516
NapatechSetPortmap
int NapatechSetPortmap(int port, int peer)
unlikely
#define unlikely(expr)
Definition: util-optimize.h:35
NapatechThreadVars_::rx_stream
NtNetStreamRx_t rx_stream
Definition: source-napatech.c:85
NapatechStreamDevConf
Definition: source-napatech.h:35
SC_ERR_NAPATECH_NOSUPPORT
@ SC_ERR_NAPATECH_NOSUPPORT
Definition: util-error.h:248
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:298
TMM_DECODENAPATECH
@ TMM_DECODENAPATECH
Definition: tm-threads-common.h:60
NapatechDecode
TmEcode NapatechDecode(ThreadVars *, Packet *, void *)
This function passes off to link type decoders.
Definition: source-napatech.c:1101
MAX_ADAPTERS
#define MAX_ADAPTERS
Definition: util-napatech.h:60
SC_ATOMIC_ADD
#define SC_ATOMIC_ADD(name, val)
add a value to our atomic variable
Definition: util-atomic.h:333
StatsSetUI64
void StatsSetUI64(ThreadVars *tv, uint16_t id, uint64_t x)
Sets a value of type double to the local counter.
Definition: counters.c:191
NapatechStreamDevConf::stream_id
uint16_t stream_id
Definition: source-napatech.h:36
NapatechDeleteFilters
uint32_t NapatechDeleteFilters(void)
Definition: util-napatech.c:1338
SC_ERR_NAPATECH_TIMESTAMP_TYPE_NOT_SUPPORTED
@ SC_ERR_NAPATECH_TIMESTAMP_TYPE_NOT_SUPPORTED
Definition: util-error.h:250
SURICATA_STOP
#define SURICATA_STOP
Definition: suricata.h:90
StatsSetupPrivate
int StatsSetupPrivate(ThreadVars *tv)
Definition: counters.c:1194
tm-modules.h
util-privs.h
NapatechThreadVars_::hba
int hba
Definition: source-napatech.c:87
StatsSyncCountersIfSignalled
#define StatsSyncCountersIfSignalled(tv)
Definition: counters.h:137
PacketDecodeFinalize
void PacketDecodeFinalize(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p)
Finalize decoding of a packet.
Definition: decode.c:118
proto
uint8_t proto
Definition: decode-template.h:0
NapatechStreamDevConf::hba
intmax_t hba
Definition: source-napatech.h:37
SC_WARN_COMPATIBILITY
@ SC_WARN_COMPATIBILITY
Definition: util-error.h:193
TmqhOutputPacketpool
void TmqhOutputPacketpool(ThreadVars *t, Packet *p)
Definition: tmqh-packetpool.c:375
Packet_::BypassPacketsFlow
int(* BypassPacketsFlow)(struct Packet_ *)
Definition: decode.h:496
TM_ECODE_FAILED
@ TM_ECODE_FAILED
Definition: tm-threads-common.h:81
tmqh-packetpool.h
TmModule_::PktAcqLoop
TmEcode(* PktAcqLoop)(ThreadVars *, void *, void *)
Definition: tm-modules.h:54
SCLog
void SCLog(int x, const char *file, const char *func, const int line, const char *fmt,...)
Definition: util-debug.c:618
TM_ECODE_OK
@ TM_ECODE_OK
Definition: tm-threads-common.h:80
SC_ERR_NAPATECH_OPEN_FAILED
@ SC_ERR_NAPATECH_OPEN_FAILED
Definition: util-error.h:246
NapatechThreadVars_
Definition: source-napatech.c:83
TmModule_::ThreadDeinit
TmEcode(* ThreadDeinit)(ThreadVars *, void *)
Definition: tm-modules.h:49
Packet_::datalink
int datalink
Definition: decode.h:583
NapatechStreamThreadDeinit
TmEcode NapatechStreamThreadDeinit(ThreadVars *tv, void *data)
Deinitializes the NAPATECH card.
Definition: source-napatech.c:1080
__attribute__
enum @31 __attribute__
DNP3 application header.
Definition: detect-engine-analyzer.c:579
PKT_IS_TCP
#define PKT_IS_TCP(p)
Definition: decode.h:259
DecodeRegisterPerfCounters
void DecodeRegisterPerfCounters(DecodeThreadVars *dtv, ThreadVars *tv)
Definition: decode.c:484
SC_LOG_ERROR
@ SC_LOG_ERROR
Definition: util-debug.h:56
NapatechCurrentStats_::current_packets
uint64_t current_packets
Definition: util-napatech.h:51
TmModule_::PktAcqBreakLoop
TmEcode(* PktAcqBreakLoop)(ThreadVars *, void *)
Definition: tm-modules.h:57
source-napatech.h
SCEnter
#define SCEnter(...)
Definition: util-debug.h:300
GET_PKT_DATA
#define GET_PKT_DATA(p)
Definition: decode.h:231
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:58
TmModule_::Func
TmEcode(* Func)(ThreadVars *, Packet *, void *)
Definition: tm-modules.h:52
SC_CAP_NET_ADMIN
#define SC_CAP_NET_ADMIN
Definition: util-privs.h:31
NapatechThreadVars_::slot
TmSlot * slot
Definition: source-napatech.c:88
BUG_ON
#define BUG_ON(x)
Definition: suricata-common.h:282
NapatechGetAdapter
int NapatechGetAdapter(uint8_t port)
PacketPoolWait
void PacketPoolWait(void)
Definition: tmqh-packetpool.c:84
NAPATECH_ERROR
#define NAPATECH_ERROR(err_type, status)
Definition: util-napatech.h:65
util-napatech.h
Packet_
Definition: decode.h:414
TM_FLAG_DECODE_TM
#define TM_FLAG_DECODE_TM
Definition: tm-modules.h:32
TmModuleNapatechDecodeRegister
void TmModuleNapatechDecodeRegister(void)
Register the Napatech decoder module.
Definition: source-napatech.c:160
tmm_modules
TmModule tmm_modules[TMM_SIZE]
Definition: tm-modules.c:33
GET_PKT_LEN
#define GET_PKT_LEN(p)
Definition: decode.h:230
SC_ERR_NAPATECH_PARSE_CONFIG
@ SC_ERR_NAPATECH_PARSE_CONFIG
Definition: util-error.h:255
NapatechGetNumConfiguredStreams
uint16_t NapatechGetNumConfiguredStreams(void)
Definition: runmode-napatech.c:55
TmSlot_
Definition: tm-threads.h:52
NapatechCurrentStats_::current_bytes
uint64_t current_bytes
Definition: util-napatech.h:52
SC_ATOMIC_DECLARE
SC_ATOMIC_DECLARE(uint64_t, total_packets)
TmEcode
TmEcode
Definition: tm-threads-common.h:79
NapatechDecodeThreadInit
TmEcode NapatechDecodeThreadInit(ThreadVars *, const void *, void **)
Initialization of Napatech Thread.
Definition: source-napatech.c:1134
TmModule_::name
const char * name
Definition: tm-modules.h:44
SCLogInfo
#define SCLogInfo(...)
Macro used to log INFORMATIONAL messages.
Definition: util-debug.h:217
SCLogLevel
SCLogLevel
The various log levels NOTE: when adding new level, don't forget to update SCLogMapLogLevelToSyslogLe...
Definition: util-debug.h:50
TM_FLAG_RECEIVE_TM
#define TM_FLAG_RECEIVE_TM
Definition: tm-modules.h:31
dtv
DecodeThreadVars * dtv
Definition: fuzz_decodepcapfile.c:30
Packet_::ntpv
NapatechPacketVars ntpv
Definition: decode.h:614
tm-queuehandlers.h
Packet_::ReleasePacket
void(* ReleasePacket)(struct Packet_ *)
Definition: decode.h:493
NapatechThreadVars
struct NapatechThreadVars_ NapatechThreadVars
DecodeThreadVarsFree
void DecodeThreadVarsFree(ThreadVars *tv, DecodeThreadVars *dtv)
Definition: decode.c:658
Packet_::ts
struct timeval ts
Definition: decode.h:457
suricata-common.h
ACTION_DROP
#define ACTION_DROP
Definition: action-globals.h:30
SCLogError
#define SCLogError(err_code,...)
Macro used to log ERROR messages.
Definition: util-debug.h:257
SC_LOG_PERF
@ SC_LOG_PERF
Definition: util-debug.h:60
TmModule_::ThreadInit
TmEcode(* ThreadInit)(ThreadVars *, const void *, void **)
Definition: tm-modules.h:47
FatalError
#define FatalError(x,...)
Definition: util-debug.h:532
NapatechGetNumFirstStream
uint16_t NapatechGetNumFirstStream(void)
Definition: runmode-napatech.c:60
tv
ThreadVars * tv
Definition: fuzz_decodepcapfile.c:29
util-optimize.h
TmModule_::ThreadExitPrintStats
void(* ThreadExitPrintStats)(ThreadVars *, void *)
Definition: tm-modules.h:48
threadvars.h
SC_ERR_NAPATECH_STREAMS_REGISTER_FAILED
@ SC_ERR_NAPATECH_STREAMS_REGISTER_FAILED
Definition: util-error.h:253
NapatechGetNumLastStream
uint16_t NapatechGetNumLastStream(void)
Definition: runmode-napatech.c:65
NapatechPacketVars_::nt_packet_buf
NtNetBuf_t nt_packet_buf
Definition: util-napatech.h:32
SCLogWarning
#define SCLogWarning(err_code,...)
Macro used to log WARNING messages.
Definition: util-debug.h:244
MAX_PORTS
#define MAX_PORTS
Definition: util-napatech.h:59
SCFree
#define SCFree(p)
Definition: util-mem.h:61
DecodeThreadVars_
Structure to hold thread specific data for all decode modules.
Definition: decode.h:631
SC_ERR_FATAL
@ SC_ERR_FATAL
Definition: util-error.h:203
NapatechThreadVars_::tv
ThreadVars * tv
Definition: source-napatech.c:84
NapatechDecodeThreadDeinit
TmEcode NapatechDecodeThreadDeinit(ThreadVars *tv, void *data)
Deinitialization of Napatech Thread.
Definition: source-napatech.c:1154
payload_len
uint16_t payload_len
Definition: stream-tcp-private.h:1
DecodeThreadVarsAlloc
DecodeThreadVars * DecodeThreadVarsAlloc(ThreadVars *tv)
Alloc and setup DecodeThreadVars.
Definition: decode.c:639
PacketSetData
int PacketSetData(Packet *p, const uint8_t *pktdata, uint32_t pktlen)
Set data for Packet and set length when zero copy is used.
Definition: decode.c:678
SC_ERR_DATALINK_UNIMPLEMENTED
@ SC_ERR_DATALINK_UNIMPLEMENTED
Definition: util-error.h:68
NapatechStreamThreadExitStats
void NapatechStreamThreadExitStats(ThreadVars *, void *)
Print some stats to the log at program exit.
Definition: source-napatech.c:1038
NapatechCurrentStats_::current_drop_packets
uint64_t current_drop_packets
Definition: util-napatech.h:53
TmModuleNapatechStreamRegister
void TmModuleNapatechStreamRegister(void)
Register the Napatech receiver (reader) module.
Definition: source-napatech.c:128
suricata.h
NapatechPacketVars_::rx_stream
NtNetStreamRx_t rx_stream
Definition: util-napatech.h:33
NapatechSetupTraffic
uint32_t NapatechSetupTraffic(uint32_t first_stream, uint32_t last_stream)
Definition: util-napatech.c:1365
NapatechPacketVars_::flow_stream
NtFlowStream_t flow_stream
Definition: util-napatech.h:34
NapatechThreadVars_::stream_id
uint16_t stream_id
Definition: source-napatech.c:86
NapatechCurrentStats_
Definition: util-napatech.h:50
TmSlot_::slot_next
struct TmSlot_ * slot_next
Definition: tm-threads.h:61
SC_ATOMIC_GET
#define SC_ATOMIC_GET(name)
Get the value from the atomic variable.
Definition: util-atomic.h:376
SCLogNotice
#define SCLogNotice(...)
Macro used to log NOTICE messages.
Definition: util-debug.h:232
StatsRegisterCounter
uint16_t StatsRegisterCounter(const char *name, struct ThreadVars_ *tv)
Registers a normal, unqualified counter.
Definition: counters.c:939
SCCalloc
#define SCCalloc(nm, sz)
Definition: util-mem.h:53
SCReturnInt
#define SCReturnInt(x)
Definition: util-debug.h:304
PacketGetFromQueueOrAlloc
Packet * PacketGetFromQueueOrAlloc(void)
Get a packet. We try to get a packet from the packetpool first, but if that is empty we alloc a packe...
Definition: decode.c:180
SC_CAP_NET_RAW
#define SC_CAP_NET_RAW
Definition: util-privs.h:32
DecodeEthernet
int DecodeEthernet(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint32_t len)
Definition: decode-ethernet.c:41
TmModule_::flags
uint8_t flags
Definition: tm-modules.h:70
DecodeUpdatePacketCounters
void DecodeUpdatePacketCounters(ThreadVars *tv, const DecodeThreadVars *dtv, const Packet *p)
Definition: decode.c:605
LINKTYPE_ETHERNET
#define LINKTYPE_ETHERNET
Definition: decode.h:1088
suricata_ctl_flags
volatile uint8_t suricata_ctl_flags
Definition: suricata.c:198
NapatechSetupNuma
bool NapatechSetupNuma(uint32_t stream, uint32_t numa)
Definition: util-napatech.c:1227
NapatechPacketLoop
TmEcode NapatechPacketLoop(ThreadVars *tv, void *data, void *slot)
Main Napatechpacket processing loop.
Definition: source-napatech.c:785
PACKET_TEST_ACTION
#define PACKET_TEST_ACTION(p, a)
Definition: decode.h:870