return 0;
}
+/**
+ * \brief Initializes the FlowStreams used to program flow data.
+ *
+ * Opens a FlowStream on the adapter associated with the rx port. This
+ * FlowStream is subsequently used to program the adapter with
+ * flows to bypass.
+ *
+ * \return the flow stream handle, NULL if failure.
+ */
+static NtFlowStream_t InitFlowStream(int adapter, int stream_id)
+{
+ int status;
+ NtFlowStream_t hFlowStream;
+
+ NtFlowAttr_t attr;
+ char flow_name[80];
+
+ NT_FlowOpenAttrInit(&attr);
+ NT_FlowOpenAttrSetAdapterNo(&attr, adapter);
+
+ snprintf(flow_name, sizeof(flow_name), "Flow_stream_%d", stream_id );
+ SCLogDebug("Opening flow programming stream: %s", flow_name);
+ if ((status = NT_FlowOpen_Attr(&hFlowStream, flow_name, &attr)) != NT_SUCCESS) {
+ SCLogWarning(SC_WARN_COMPATIBILITY,
+ "Napatech bypass functionality not supported by the FPGA version on adapter %d - disabling support.",
+ adapter);
+ return NULL;
+ }
+ return hFlowStream;
+}
+
/**
* \brief Callback function to process Bypass events on Napatech Adapter.
*
*/
static int ProgramFlow(Packet *p, int is_inline)
{
- int status;
NtFlow_t flow_match;
memset(&flow_match, 0, sizeof(flow_match));
NapatechPacketVars *ntpv = &(p->ntpv);
- int adapter = NapatechGetAdapter(ntpv->dyn3->rxPort);
-
- NtFlowStream_t *phFlowStream = NapatechGetFlowStreamPtr(adapter);
-
-
/*
* The hardware decoder will "color" the packets according to the protocols
* in the packet and the port the packet arrived on. packet_type gets
case RTE_PTYPE_L3_IPV4:
{
pIPv4_hdr = (struct ipv4_hdr *) (packet + ntpv->dyn3->offset0);
-
if (!is_span) {
v4Tuple.sa = pIPv4_hdr->src_addr;
v4Tuple.da = pIPv4_hdr->dst_addr;
}
}
- status = NT_FlowWrite(*phFlowStream, &flow_match, -1);
- if (status == NT_STATUS_TIMEOUT) {
- SCLogInfo("NT_FlowWrite returned NT_STATUS_TIMEOUT");
- } else if (status != NT_SUCCESS) {
- SCLogError(SC_ERR_NAPATECH_OPEN_FAILED,"NT_FlowWrite failed!.");
- exit(EXIT_FAILURE);
+ if (NT_FlowWrite(ntpv->flow_stream, &flow_match, -1) != NT_SUCCESS) {
+ if (!(suricata_ctl_flags & SURICATA_STOP)) {
+ SCLogError(SC_ERR_NAPATECH_OPEN_FAILED,"NT_FlowWrite failed!.");
+ exit(EXIT_FAILURE);
+ }
}
return 1;
/* This just keeps the startup output more orderly. */
usleep(200000 * ntv->stream_id);
+#ifdef NAPATECH_ENABLE_BYPASS
+ NtFlowStream_t flow_stream[MAX_ADAPTERS] = { 0 };
+
+ /* Get a FlowStream handle for each adapter so we can efficiently find the
+ * correct handle corresponding to the port on which a packet is received.
+ */
+ int adapter = 0;
+ for (adapter = 0; adapter < NapatechGetNumAdapters(); ++adapter) {
+ flow_stream[adapter] = InitFlowStream(adapter, ntv->stream_id);
+ }
+#endif
+
if (ConfGetBool("napatech.auto-config", &is_autoconfig) == 0) {
is_autoconfig = 0;
}
is_inline = 0;
}
- #ifdef NAPATECH_ENABLE_BYPASS
+#ifdef NAPATECH_ENABLE_BYPASS
/* Initialize the port map before we setup traffic filters */
for (int i = 0; i < MAX_PORTS; ++i) {
inline_port_map[i] = -1;
p->ntpv.dyn3 = _NT_NET_GET_PKT_DESCR_PTR_DYN3(packet_buffer);
p->BypassPacketsFlow = (NapatechIsBypassSupported() ? NapatechBypassCallback : NULL);
NT_NET_SET_PKT_TXPORT(packet_buffer, inline_port_map[p->ntpv.dyn3->rxPort]);
+ p->ntpv.flow_stream = flow_stream[NapatechGetAdapter(p->ntpv.dyn3->rxPort)];
+
#endif
+
p->ReleasePacket = NapatechReleasePacket;
p->ntpv.nt_packet_buf = packet_buffer;
p->ntpv.stream_id = ntv->stream_id;
} // while
if (closer) {
-#ifdef NAPATECH_ENABLE_BYPASS
- NapatechCloseFlowStreams();
-#endif
NapatechDeleteFilters();
}
uint16_t total_bypass_flows;
} FlowStatsCounters;
-static NtFlowStream_t hFlowStream[MAX_ADAPTERS];
static int bypass_supported;
int NapatechIsBypassSupported(void)
*
* \return count of the Napatech adapters present in the system.
*/
-static int GetNumAdapters(void)
+int NapatechGetNumAdapters(void)
{
NtInfoStream_t hInfo;
NtInfo_t hInfoSys;
int status;
+ static int num_adapters = -1;
- if ((status = NT_InfoOpen(&hInfo, "InfoStream")) != NT_SUCCESS) {
- NAPATECH_ERROR(SC_ERR_NAPATECH_OPEN_FAILED, status);
- exit(EXIT_FAILURE);
- }
+ if (num_adapters == -1) {
+ if ((status = NT_InfoOpen(&hInfo, "InfoStream")) != NT_SUCCESS) {
+ NAPATECH_ERROR(SC_ERR_NAPATECH_OPEN_FAILED, status);
+ exit(EXIT_FAILURE);
+ }
- hInfoSys.cmd = NT_INFO_CMD_READ_SYSTEM;
- if ((status = NT_InfoRead(hInfo, &hInfoSys)) != NT_SUCCESS) {
- NAPATECH_ERROR(SC_ERR_NAPATECH_OPEN_FAILED, status);
- exit(EXIT_FAILURE);
- }
+ hInfoSys.cmd = NT_INFO_CMD_READ_SYSTEM;
+ if ((status = NT_InfoRead(hInfo, &hInfoSys)) != NT_SUCCESS) {
+ NAPATECH_ERROR(SC_ERR_NAPATECH_OPEN_FAILED, status);
+ exit(EXIT_FAILURE);
+ }
- int num_adapters = hInfoSys.u.system.data.numAdapters;
+ num_adapters = hInfoSys.u.system.data.numAdapters;
+
+ NT_InfoClose(hInfo);
+ }
- NT_InfoClose(hInfo);
return num_adapters;
}
/**
- * \brief Initializes the FlowStreams used to program flow data.
+ * \brief Verifies that the Napatech adapters support bypass.
*
- * Opens a FlowStream on each adapter present in the system. This
- * FlowStream is subsequently used to program the adapter with
- * flows to bypass.
+ * Attempts to opens a FlowStream on each adapter present in the system.
+ * If successful then bypass is supported
*
* \return 1 if Bypass functionality is supported; zero otherwise.
*/
-int NapatechInitFlowStreams(void)
+int NapatechVerifyBypassSupport(void)
{
int status;
int adapter = 0;
- int num_adapters = GetNumAdapters();
- SCLogInfo("Found %d Napatech adapters.\n", num_adapters);
- memset(&hFlowStream, 0, sizeof(hFlowStream));
+ int num_adapters = NapatechGetNumAdapters();
+ SCLogInfo("Found %d Napatech adapters.", num_adapters);
+ NtFlowStream_t hFlowStream;
if (!NapatechUseHWBypass()) {
/* HW Bypass is disabled in the conf file */
snprintf(flow_name, sizeof(flow_name), "Flow stream %d", adapter );
SCLogInfo("Opening flow programming stream: %s\n", flow_name);
- if ((status = NT_FlowOpen_Attr(&hFlowStream[adapter], flow_name, &attr)) != NT_SUCCESS) {
+ if ((status = NT_FlowOpen_Attr(&hFlowStream, flow_name, &attr)) != NT_SUCCESS) {
SCLogWarning(SC_WARN_COMPATIBILITY, "Napatech bypass functionality not supported by the FPGA version on adapter %d - disabling support.", adapter);
bypass_supported = 0;
return 0;
}
+ NT_FlowClose(hFlowStream);
}
bypass_supported = 1;
return bypass_supported;
}
-/**
- * \brief Returns a pointer to the FlowStream associated with this adapter.
- *
- * \return count of the Napatech adapters present in the system.
- */
-NtFlowStream_t *NapatechGetFlowStreamPtr(int device)
-{
- return &hFlowStream[device];
-}
-
-/**
- * \brief Closes all open FlowStreams
- *
- * \return Success of the operation.
- */
-int NapatechCloseFlowStreams(void)
-{
- int status = 0;
- int adapter = 0;
- int num_adapters = GetNumAdapters();
-
- for (adapter = 0; adapter < num_adapters; ++adapter) {
- if (hFlowStream[adapter]) {
- SCLogInfo("Closing Napatech Flow Stream on adapter %d.", adapter);
- if ((status = NT_FlowClose(hFlowStream[adapter])) != NT_SUCCESS) {
- NAPATECH_ERROR(SC_ERR_SHUTDOWN, status);
- }
- hFlowStream[adapter] = NULL;
- }
- }
- return (status == NT_SUCCESS);
-}
-
/**
* \brief Updates statistic counters for Napatech FlowStats
uint64_t removed = 0;
int adapter = 0;
- for (adapter = 0; adapter < GetNumAdapters(); ++adapter) {
+ for (adapter = 0; adapter < NapatechGetNumAdapters(); ++adapter) {
hStat.cmd = NT_STATISTICS_READ_CMD_FLOW_V0;
hStat.u.flowData_v0.clear = clear_stats;
hStat.u.flowData_v0.adapterNo = adapter;
int is_inline,
int enable_stream_stats,
PacketCounters stream_counters[]
- )
-{
+ ) {
static uint64_t rxPktsStart[MAX_STREAMS] = {0};
static uint64_t rxByteStart[MAX_STREAMS] = {0};
static uint64_t dropPktStart[MAX_STREAMS] = {0};
current_stats[stream_id].current_bytes = rx_byte_total - rxByteStart[stream_id];
current_stats[stream_id].current_drop_packets = drop_pkts_total - dropPktStart[stream_id];
current_stats[stream_id].current_drop_bytes = drop_byte_total - dropByteStart[stream_id];
- }
+ }
if (enable_stream_stats) {
StatsSetUI64(tv, stream_counters[inst_id].pkts, current_stats[stream_id].current_packets);
total_stats.current_drop_packets = 0;
total_stats.current_drop_bytes = 0;
-
/* Read usage data for the chosen stream ID */
memset(&hStat, 0, sizeof (NtStatistics_t));
uint64_t total_dispatch_fwd_pkts = 0;
uint64_t total_dispatch_fwd_byte = 0;
- for (adapter = 0; adapter < GetNumAdapters(); ++adapter) {
+ for (adapter = 0; adapter < NapatechGetNumAdapters(); ++adapter) {
total_dispatch_host_pkts += hStat.u.query_v3.data.adapter.aAdapters[adapter].color.aColor[0].pkts;
total_dispatch_host_byte += hStat.u.query_v3.data.adapter.aAdapters[adapter].color.aColor[0].octets;
+ hStat.u.query_v3.data.adapter.aAdapters[adapter].color.aColor[4].octets;
total_stats.current_packets += hStat.u.query_v3.data.adapter.aAdapters[adapter].color.aColor[0].pkts
- + hStat.u.query_v3.data.adapter.aAdapters[adapter].color.aColor[1].pkts
- + hStat.u.query_v3.data.adapter.aAdapters[adapter].color.aColor[2].pkts
- + hStat.u.query_v3.data.adapter.aAdapters[adapter].color.aColor[3].pkts;
+ + hStat.u.query_v3.data.adapter.aAdapters[adapter].color.aColor[1].pkts
+ + hStat.u.query_v3.data.adapter.aAdapters[adapter].color.aColor[2].pkts
+ + hStat.u.query_v3.data.adapter.aAdapters[adapter].color.aColor[3].pkts;
total_stats.current_bytes = hStat.u.query_v3.data.adapter.aAdapters[adapter].color.aColor[0].octets
+ hStat.u.query_v3.data.adapter.aAdapters[adapter].color.aColor[1].octets