const char *RunModeAFPGetDefaultMode(void)
{
-#ifdef HAVE_AF_PACKET
-#ifdef HAVE_PACKET_FANOUT
- if (AFPConfGetThreads() <= 1) {
- return default_mode_auto;
- } else {
- return default_mode_autofp;
- }
-#else
- return default_mode_auto;
-#endif
-#else
- return NULL;
-#endif
+ return default_mode_autofp;
}
void RunModeIdsAFPRegister(void)
return;
}
+/**
+ * \brief extract information from config file
+ *
+ * The returned structure will be freed by the thread init function.
+ * This is thus necessary to or copy the structure before giving it
+ * to thread or to reparse the file for each thread (and thus have
+ * new structure.
+ *
+ * \return a AFPIfaceConfig corresponding to the interface name
+ */
+AFPIfaceConfig *ParseAFPConfig(char *iface)
+{
+ char *threadsstr = NULL;
+ ConfNode *if_root;
+ ConfNode *af_packet_node;
+ AFPIfaceConfig *aconf = SCMalloc(sizeof(*aconf));
+ char *tmpclusterid;
+ char *tmpctype;
+ intmax_t value;
+
+ if (aconf == NULL) {
+ return NULL;
+ }
+ strlcpy(aconf->iface, iface, sizeof(aconf->iface));
+ aconf->threads = 1;
+ aconf->buffer_size = 0;
+ aconf->cluster_id = 1;
+ aconf->cluster_type = PACKET_FANOUT_HASH;
+
+ /* Find initial node */
+ af_packet_node = ConfGetNode("af-packet");
+ if (af_packet_node == NULL) {
+ SCLogInfo("Unable to find af-packet config using default value");
+ return aconf;
+ }
+
+ if_root = ConfNodeLookupKeyValue(af_packet_node, "interface", iface);
+ if (if_root == NULL) {
+ SCLogInfo("Unable to find af-packet config for "
+ "interface %s, using default value",
+ iface);
+ return aconf;
+ }
+
+ if (ConfGetChildValue(if_root, "threads", &threadsstr) != 1) {
+ aconf->threads = 1;
+ } else {
+ if (threadsstr != NULL) {
+ aconf->threads = (uint8_t)atoi(threadsstr);
+ }
+ }
+ if (aconf->threads == 0) {
+ aconf->threads = 1;
+ }
+ if (ConfGetChildValue(if_root, "cluster-id", &tmpclusterid) != 1) {
+ SCLogError(SC_ERR_INVALID_ARGUMENT,"Could not get cluster-id from config");
+ } else {
+ aconf->cluster_id = (uint16_t)atoi(tmpclusterid);
+ SCLogDebug("Going to use cluster-id %" PRId32, aconf->cluster_id);
+ }
+
+ if (ConfGetChildValue(if_root, "cluster-type", &tmpctype) != 1) {
+ SCLogError(SC_ERR_GET_CLUSTER_TYPE_FAILED,"Could not get cluster-type fron config");
+ } else if (strcmp(tmpctype, "cluster_round_robin") == 0) {
+ SCLogInfo("Using round-robin cluster mode for AF_PACKET (iface %s)",
+ aconf->iface);
+ aconf->cluster_type = PACKET_FANOUT_LB;
+ } else if (strcmp(tmpctype, "cluster_flow") == 0) {
+ /* In hash mode, we also ask for defragmentation needed to
+ * compute the hash */
+ uint16_t defrag = 0;
+ SCLogInfo("Using flow cluster mode for AF_PACKET (iface %s)",
+ aconf->iface);
+ ConfGetChildValueBool(if_root, "defrag", (int *)&defrag);
+ if (defrag) {
+ SCLogInfo("Using defrag kernel functionnality for AF_PACKET (iface %s)",
+ aconf->iface);
+ defrag = PACKET_FANOUT_FLAG_DEFRAG;
+ }
+ aconf->cluster_type = PACKET_FANOUT_HASH | defrag;
+ } else if (strcmp(tmpctype, "cluster_cpu") == 0) {
+ SCLogInfo("Using cpu cluster mode for AF_PACKET (iface %s)",
+ aconf->iface);
+ aconf->cluster_type = PACKET_FANOUT_CPU;
+ } else {
+ SCLogError(SC_ERR_INVALID_CLUSTER_TYPE,"invalid cluster-type %s",tmpctype);
+ return NULL;
+ }
+
+ if ((ConfGetChildValueInt(if_root, "buffer-size", &value)) == 1) {
+ aconf->buffer_size = value;
+ } else {
+ aconf->buffer_size = 0;
+ }
+
+ return aconf;
+}
+
+
/**
* \brief RunModeIdsAFPAuto set up the following thread packet handlers:
* - Receive thread (from live iface)
if (nlive == 1) {
char *live_dev = NULL;
- char *live_devc = NULL;
- if (ConfGet("af-packet.interface", &live_dev) == 0) {
+ AFPIfaceConfig *aconf;
+ /* TODO be clever than that */
+ if (ConfGet("af-packet.live-interface", &live_dev) == 0) {
SCLogError(SC_ERR_RUNMODE, "Failed retrieving "
- "af-packet.interface from Conf");
+ "interface from command line");
exit(EXIT_FAILURE);
}
SCLogDebug("live_dev %s", live_dev);
- live_devc = SCStrdup(live_dev);
+ if (live_dev == NULL) {
+ printf("Failed to lookup live dev\n");
+ exit(EXIT_FAILURE);
+ }
+ SCLogDebug("live_dev %s", live_dev);
+
+ aconf = ParseAFPConfig(live_dev);
+ if (aconf == NULL) {
+ printf("Failed to allocate config\n");
+ exit(EXIT_FAILURE);
+ }
/* create the threads */
ThreadVars *tv_receiveafp =
printf("ERROR: TmModuleGetByName failed for ReceiveAFP\n");
exit(EXIT_FAILURE);
}
- TmSlotSetFuncAppend(tv_receiveafp, tm_module, (void *)live_devc);
+ TmSlotSetFuncAppend(tv_receiveafp, tm_module, (void *)aconf);
TmThreadSetCPU(tv_receiveafp, RECEIVE_CPU_SET);
for (thread = 0; thread < nlive; thread++) {
char *live_dev = LiveGetDevice(thread);
char *tnamec = NULL;
- char *live_devc = NULL;
+ AFPIfaceConfig *aconf;
+
if (live_dev == NULL) {
printf("Failed to lookup live dev %d\n", thread);
exit(EXIT_FAILURE);
}
SCLogDebug("live_dev %s", live_dev);
+ aconf = ParseAFPConfig(live_dev);
+ if (aconf == NULL) {
+ printf("Failed to allocate config %d\n", thread);
+ exit(EXIT_FAILURE);
+ }
+
snprintf(tname, sizeof(tname),"RecvAFP-%s", live_dev);
tnamec = SCStrdup(tname);
- live_devc = SCStrdup(live_dev);
/* create the threads */
ThreadVars *tv_receiveafp =
printf("ERROR: TmModuleGetByName failed for ReceiveAFP\n");
exit(EXIT_FAILURE);
}
- TmSlotSetFuncAppend(tv_receiveafp, tm_module, (void *)live_devc);
+ TmSlotSetFuncAppend(tv_receiveafp, tm_module, (void *)aconf);
TmThreadSetCPU(tv_receiveafp, RECEIVE_CPU_SET);
char tname[12];
char qname[12];
char queues[2048] = "";
- int afp_threads;
+ int thread;
char *live_dev = NULL;
- char *live_devc = NULL;
-
- RunModeInitialize();
-
- TimeModeSetLive();
-
/* Available cpus */
uint16_t ncpus = UtilCpuGetNumProcessorsOnline();
-
- /* always create at least one thread */
+ int nlive = LiveGetDeviceCount();
int thread_max = TmThreadGetNbThreads(DETECT_CPU_SET);
+ /* always create at least one thread */
if (thread_max == 0)
thread_max = ncpus * threading_detect_ratio;
if (thread_max < 1)
thread_max = 1;
- int thread;
+ RunModeInitialize();
+
+ TimeModeSetLive();
+
for (thread = 0; thread < thread_max; thread++) {
if (strlen(queues) > 0)
strlcat(queues, ",", sizeof(queues));
}
SCLogDebug("queues %s", queues);
- if (ConfGet("af-packet.interface", &live_dev) == 0) {
- SCLogError(SC_ERR_RUNMODE, "Failed retrieving "
- "af-packet.interface from Conf");
- exit(EXIT_FAILURE);
- }
- SCLogDebug("live_dev %s", live_dev);
-
-
- afp_threads = AFPConfGetThreads();
- SCLogInfo("Going to use %" PRId32 " AF_PACKET receive thread(s)",
- afp_threads);
- /* create the threads */
- for (thread = 0; thread < afp_threads; thread++) {
- snprintf(tname, sizeof(tname), "RxAFP%"PRIu16, thread+1);
- char *thread_name = SCStrdup(tname);
+ if (nlive == 1) {
+ AFPIfaceConfig *aconf;
+ int afp_thread;
- ThreadVars *tv_receive =
- TmThreadCreatePacketHandler(thread_name,
- "packetpool", "packetpool",
- queues, "flow", "varslot");
- if (tv_receive == NULL) {
- printf("ERROR: TmThreadsCreate failed\n");
+ if (ConfGet("af-packet.live-interface", &live_dev) == 0) {
+ SCLogError(SC_ERR_RUNMODE, "Failed retrieving "
+ "interface from command line");
exit(EXIT_FAILURE);
}
- TmModule *tm_module = TmModuleGetByName("ReceiveAFP");
- if (tm_module == NULL) {
- printf("ERROR: TmModuleGetByName failed for ReceiveAFP\n");
+ SCLogDebug("live_dev %s", live_dev);
+
+ aconf = ParseAFPConfig(live_dev);
+ if (aconf == NULL) {
+ printf("Failed to allocate config %d\n", thread);
exit(EXIT_FAILURE);
}
- live_devc = SCStrdup(live_dev);
- TmSlotSetFuncAppend(tv_receive, tm_module, live_devc);
- tm_module = TmModuleGetByName("DecodeAFP");
- if (tm_module == NULL) {
- printf("ERROR: TmModuleGetByName DecodeAFP failed\n");
- exit(EXIT_FAILURE);
+ SCLogInfo("Going to use %" PRId32 " AF_PACKET receive thread(s)",
+ aconf->threads);
+ /* create the threads */
+ for (afp_thread = 0; afp_thread < aconf->threads; afp_thread++) {
+ snprintf(tname, sizeof(tname), "RxAFP%"PRIu16, afp_thread+1);
+ char *thread_name = SCStrdup(tname);
+
+ ThreadVars *tv_receive =
+ TmThreadCreatePacketHandler(thread_name,
+ "packetpool", "packetpool",
+ queues, "flow", "varslot");
+ if (tv_receive == NULL) {
+ printf("ERROR: TmThreadsCreate failed\n");
+ exit(EXIT_FAILURE);
+ }
+ TmModule *tm_module = TmModuleGetByName("ReceiveAFP");
+ if (tm_module == NULL) {
+ printf("ERROR: TmModuleGetByName failed for ReceiveAFP\n");
+ exit(EXIT_FAILURE);
+ }
+ TmSlotSetFuncAppend(tv_receive, tm_module, aconf);
+
+ tm_module = TmModuleGetByName("DecodeAFP");
+ if (tm_module == NULL) {
+ printf("ERROR: TmModuleGetByName DecodeAFP failed\n");
+ exit(EXIT_FAILURE);
+ }
+ TmSlotSetFuncAppend(tv_receive, tm_module, NULL);
+
+ TmThreadSetCPU(tv_receive, RECEIVE_CPU_SET);
+
+ if (TmThreadSpawn(tv_receive) != TM_ECODE_OK) {
+ printf("ERROR: TmThreadSpawn failed\n");
+ exit(EXIT_FAILURE);
+ }
}
- TmSlotSetFuncAppend(tv_receive, tm_module, NULL);
+ } else { /* Multiple input device */
+ SCLogInfo("Using %d live device(s).", nlive);
+ int lthread;
- TmThreadSetCPU(tv_receive, RECEIVE_CPU_SET);
+ for (lthread = 0; lthread < nlive; lthread++) {
+ char *live_dev = LiveGetDevice(lthread);
+ AFPIfaceConfig *aconf;
- if (TmThreadSpawn(tv_receive) != TM_ECODE_OK) {
- printf("ERROR: TmThreadSpawn failed\n");
- exit(EXIT_FAILURE);
+ if (live_dev == NULL) {
+ printf("Failed to lookup live dev %d\n", lthread);
+ exit(EXIT_FAILURE);
+ }
+ SCLogDebug("live_dev %s", live_dev);
+
+ aconf = ParseAFPConfig(live_dev);
+ if (aconf == NULL) {
+ printf("Failed to allocate config %d\n", lthread);
+ exit(EXIT_FAILURE);
+ }
+
+ for (thread = 0; thread < aconf->threads; thread++) {
+ snprintf(tname, sizeof(tname), "RxAFP%s%"PRIu16, live_dev, thread+1);
+ char *thread_name = SCStrdup(tname);
+
+ ThreadVars *tv_receive =
+ TmThreadCreatePacketHandler(thread_name,
+ "packetpool", "packetpool",
+ queues, "flow", "varslot");
+ if (tv_receive == NULL) {
+ printf("ERROR: TmThreadsCreate failed\n");
+ exit(EXIT_FAILURE);
+ }
+ TmModule *tm_module = TmModuleGetByName("ReceiveAFP");
+ if (tm_module == NULL) {
+ printf("ERROR: TmModuleGetByName failed for ReceiveAFP\n");
+ exit(EXIT_FAILURE);
+ }
+ TmSlotSetFuncAppend(tv_receive, tm_module, aconf);
+
+ tm_module = TmModuleGetByName("DecodeAFP");
+ if (tm_module == NULL) {
+ printf("ERROR: TmModuleGetByName DecodeAFP failed\n");
+ exit(EXIT_FAILURE);
+ }
+ TmSlotSetFuncAppend(tv_receive, tm_module, NULL);
+
+ TmThreadSetCPU(tv_receive, RECEIVE_CPU_SET);
+
+ if (TmThreadSpawn(tv_receive) != TM_ECODE_OK) {
+ printf("ERROR: TmThreadSpawn failed\n");
+ exit(EXIT_FAILURE);
+ }
+ }
}
}
RunModeInitialize();
TimeModeSetLive();
- if (ConfGet("af-packet.interface", &afp_dev) == 0) {
+ if (ConfGet("af-packet.live-interface", &afp_dev) == 0) {
SCLogError(SC_ERR_RUNMODE, "Failed retrieving "
- "af-packet.interface from Conf");
+ "interface from command line");
exit(EXIT_FAILURE);
}
int cluster_id;
int cluster_type;
+ int threads;
+
ThreadVars *tv;
TmSlot *slot;
static int AFPCreateSocket(AFPThreadVars *ptv, char *devname, int verbose);
-int AFPConfGetThreads()
-{
- int afp_threads = 1;
- char *threadsstr = NULL;
-
- if (ConfGet("af-packet.threads", &threadsstr) != 1) {
- afp_threads = 1;
- } else {
- if (threadsstr != NULL) {
- afp_threads = (uint8_t)atoi(threadsstr);
- }
- }
- if (afp_threads == 0) {
- afp_threads = 1;
- }
- return afp_threads;
-}
-
/**
* \brief AF packet read function.
#ifdef HAVE_PACKET_FANOUT
/* add binded socket to fanout group */
- if (AFPConfGetThreads() > 1) {
+ if (ptv->threads > 1) {
uint32_t option = 0;
uint16_t mode = ptv->cluster_type;
uint16_t id = ptv->cluster_id;
TmEcode ReceiveAFPThreadInit(ThreadVars *tv, void *initdata, void **data) {
SCEnter();
int r;
- intmax_t value;
-#ifdef HAVE_PACKET_FANOUT
- char *tmpclusterid;
- char *tmpctype;
-#endif
+ AFPIfaceConfig *afpconfig = initdata;
/* use max_pending_packets as AFP read size unless it's bigger than
* our size limit */
ptv->tv = tv;
ptv->cooked = 0;
- strlcpy(ptv->iface, initdata, AFP_IFACE_NAME_LENGTH);
+ strlcpy(ptv->iface, afpconfig->iface, AFP_IFACE_NAME_LENGTH);
ptv->iface[AFP_IFACE_NAME_LENGTH - 1]= '\0';
- if ((ConfGetInt("af-packet.buffer-size", &value)) == 1) {
- ptv->buffer_size = value;
- } else {
- ptv->buffer_size = 0;
- }
+ ptv->buffer_size = afpconfig->buffer_size;
+ ptv->threads = 1;
#ifdef HAVE_PACKET_FANOUT
ptv->cluster_type = PACKET_FANOUT_LB;
ptv->cluster_id = 1;
/* We only set cluster info if the number of reader threads is greater than 1 */
- if (AFPConfGetThreads() > 1) {
- if (ConfGet("af-packet.cluster-id", &tmpclusterid) != 1) {
- SCLogError(SC_ERR_INVALID_ARGUMENT,"could not get af-packet.cluster-id");
- return TM_ECODE_FAILED;
- } else {
- ptv->cluster_id = (uint16_t)atoi(tmpclusterid);
- SCLogDebug("Going to use cluster-id %" PRId32, ptv->cluster_id);
- }
-
- if (ConfGet("af-packet.cluster-type", &tmpctype) != 1) {
- SCLogError(SC_ERR_GET_CLUSTER_TYPE_FAILED,"Could not get af-packet.cluster-type");
- return TM_ECODE_FAILED;
- } else if (strcmp(tmpctype, "cluster_round_robin") == 0) {
- SCLogInfo("Using round-robin cluster mode for AF_PACKET (thread %s)",
- ptv->tv->name);
- ptv->cluster_type = PACKET_FANOUT_LB;
- } else if (strcmp(tmpctype, "cluster_flow") == 0) {
- /* In hash mode, we also ask for defragmentation needed to
- * compute the hash */
- uint16_t defrag = 0;
- SCLogInfo("Using flow cluster mode for AF_PACKET (thread %s)",
- ptv->tv->name);
- ConfGetBool("af-packet.defrag", (int *)&defrag);
- if (defrag) {
- SCLogInfo("Using defrag kernel functionnality for AF_PACKET (thread %s)",
- ptv->tv->name);
- defrag = PACKET_FANOUT_FLAG_DEFRAG;
- }
- ptv->cluster_type = PACKET_FANOUT_HASH | defrag;
- } else if (strcmp(tmpctype, "cluster_cpu") == 0) {
- SCLogInfo("Using cpu cluster mode for AF_PACKET (thread %s)",
- ptv->tv->name);
- ptv->cluster_type = PACKET_FANOUT_CPU;
- } else {
- SCLogError(SC_ERR_INVALID_CLUSTER_TYPE,"invalid cluster-type %s",tmpctype);
- return TM_ECODE_FAILED;
- }
+ if (afpconfig->threads > 1) {
+ ptv->cluster_id = afpconfig->cluster_id;
+ ptv->cluster_type = afpconfig->cluster_type;
+ ptv->threads = afpconfig->threads;
}
#endif
- r = AFPCreateSocket(ptv, initdata, 1);
+ r = AFPCreateSocket(ptv, ptv->iface, 1);
if (r < 0) {
SCLogError(SC_ERR_AFP_CREATE, "Couldn't init AF_PACKET socket");
SCFree(ptv);
*data = (void *)ptv;
+
+ /* we've received a single use structure, we can free it */
+ SCFree(initdata);
SCReturnInt(TM_ECODE_OK);
}