@ -37,6 +37,7 @@
# include "util-time.h"
# include "util-cpu.h"
# include "util-affinity.h"
# include "util-runmodes.h"
static const char * default_mode_auto = NULL ;
static const char * default_mode_autofp = NULL ;
@ -44,11 +45,7 @@ static const char *default_mode_autofp = NULL;
const char * RunModeIdsPfringGetDefaultMode ( void )
{
# ifdef HAVE_PFRING
if ( PfringConfGetThreads ( ) < = 1 ) {
return default_mode_auto ;
} else {
return default_mode_autofp ;
}
return default_mode_autofp ;
# else
return NULL ;
# endif
@ -72,6 +69,103 @@ void RunModeIdsPfringRegister(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 .
*
* If old config system is used , then return the smae parameters
* value for each interface .
*
* \ return a PfringIfaceConfig corresponding to the interface name
*/
void * ParsePfringConfig ( const char * iface )
{
char * threadsstr = NULL ;
ConfNode * if_root ;
ConfNode * pf_ring_node ;
PfringIfaceConfig * pfconf = SCMalloc ( sizeof ( * pfconf ) ) ;
char * tmpclusterid ;
# ifdef HAVE_PFRING_CLUSTER_TYPE
char * tmpctype = NULL ;
char * default_ctype = strdup ( " cluster_round_robin " ) ;
# endif
if ( iface = = NULL ) {
return NULL ;
}
if ( pfconf = = NULL ) {
return NULL ;
}
strlcpy ( pfconf - > iface , iface , sizeof ( pfconf - > iface ) ) ;
pfconf - > threads = 1 ;
pfconf - > cluster_id = 1 ;
# ifdef HAVE_PFRING_CLUSTER_TYPE
pfconf - > ctype = ( cluster_type ) default_ctype ;
# endif
/* Find initial node */
pf_ring_node = ConfGetNode ( " pfring " ) ;
if ( pf_ring_node = = NULL ) {
SCLogInfo ( " Unable to find pfring config using default value " ) ;
return pfconf ;
}
if_root = ConfNodeLookupKeyValue ( pf_ring_node , " interface " , iface ) ;
if ( if_root = = NULL ) {
SCLogInfo ( " Unable to find af-packet config for "
" interface %s, using default value " ,
iface ) ;
return pfconf ;
}
if ( ConfGetChildValue ( if_root , " threads " , & threadsstr ) ! = 1 ) {
pfconf - > threads = 1 ;
} else {
if ( threadsstr ! = NULL ) {
pfconf - > threads = ( uint8_t ) atoi ( threadsstr ) ;
}
}
if ( pfconf - > threads = = 0 ) {
pfconf - > threads = 1 ;
}
if ( ConfGetChildValue ( if_root , " cluster-id " , & tmpclusterid ) ! = 1 ) {
SCLogError ( SC_ERR_INVALID_ARGUMENT , " Could not get cluster-id from config " ) ;
} else {
pfconf - > cluster_id = ( uint16_t ) atoi ( tmpclusterid ) ;
SCLogDebug ( " Going to use cluster-id % " PRId32 , pfconf - > cluster_id ) ;
}
# ifdef HAVE_PFRING_CLUSTER_TYPE
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 PF_RING (iface %s) " ,
pfconf - > iface ) ;
pfconf - > ctype = ( cluster_type ) tmpctype ;
} else if ( strcmp ( tmpctype , " cluster_flow " ) = = 0 ) {
SCLogInfo ( " Using flow cluster mode for PF_RING (iface %s) " ,
pfconf - > iface ) ;
pfconf - > ctype = ( cluster_type ) tmpctype ;
} else {
SCLogError ( SC_ERR_INVALID_CLUSTER_TYPE , " invalid cluster-type %s " , tmpctype ) ;
return NULL ;
}
# endif
return pfconf ;
}
int PfringConfigGeThreadsCount ( void * conf )
{
PfringIfaceConfig * pfp = ( PfringIfaceConfig * ) conf ;
return pfp - > threads ;
}
/**
* \ brief RunModeIdsPfringAuto set up the following thread packet handlers :
* - Receive thread ( from pfring )
@ -95,214 +189,21 @@ int RunModeIdsPfringAuto(DetectEngineCtx *de_ctx)
SCEnter ( ) ;
/* We include only if pfring is enabled */
# ifdef HAVE_PFRING
char tname [ 12 ] ;
uint16_t cpu = 0 ;
/* Available cpus */
uint16_t ncpus = UtilCpuGetNumProcessorsOnline ( ) ;
int ret ;
char live_dev = NULL ;
RunModeInitialize ( ) ;
TimeModeSetLive ( ) ;
/* create the threads */
ThreadVars * tv_receivepfring =
TmThreadCreatePacketHandler ( " ReceivePfring " ,
" packetpool " , " packetpool " ,
" pickup-queue1 " , " simple " ,
" 1slot " ) ;
if ( tv_receivepfring = = NULL ) {
printf ( " ERROR: TmThreadsCreate failed \n " ) ;
exit ( EXIT_FAILURE ) ;
}
TmModule * tm_module = TmModuleGetByName ( " ReceivePfring " ) ;
if ( tm_module = = NULL ) {
printf ( " ERROR: TmModuleGetByName failed for ReceivePfring \n " ) ;
exit ( EXIT_FAILURE ) ;
}
TmSlotSetFuncAppend ( tv_receivepfring , tm_module , NULL ) ;
if ( threading_set_cpu_affinity ) {
TmThreadSetCPUAffinity ( tv_receivepfring , 0 ) ;
if ( ncpus > 1 )
TmThreadSetThreadPriority ( tv_receivepfring , PRIO_MEDIUM ) ;
}
if ( TmThreadSpawn ( tv_receivepfring ) ! = TM_ECODE_OK ) {
printf ( " ERROR: TmThreadSpawn failed \n " ) ;
exit ( EXIT_FAILURE ) ;
}
ThreadVars * tv_decode1 =
TmThreadCreatePacketHandler ( " Decode1 " ,
" pickup-queue1 " , " simple " ,
" decode-queue1 " , " simple " ,
" 1slot " ) ;
if ( tv_decode1 = = NULL ) {
printf ( " ERROR: TmThreadsCreate failed for Decode1 \n " ) ;
exit ( EXIT_FAILURE ) ;
}
tm_module = TmModuleGetByName ( " DecodePfring " ) ;
if ( tm_module = = NULL ) {
printf ( " ERROR: TmModuleGetByName DecodePfring failed \n " ) ;
exit ( EXIT_FAILURE ) ;
}
TmSlotSetFuncAppend ( tv_decode1 , tm_module , NULL ) ;
if ( threading_set_cpu_affinity ) {
TmThreadSetCPUAffinity ( tv_decode1 , 0 ) ;
if ( ncpus > 1 )
TmThreadSetThreadPriority ( tv_decode1 , PRIO_MEDIUM ) ;
}
if ( TmThreadSpawn ( tv_decode1 ) ! = TM_ECODE_OK ) {
printf ( " ERROR: TmThreadSpawn failed \n " ) ;
exit ( EXIT_FAILURE ) ;
}
ThreadVars * tv_stream1 =
TmThreadCreatePacketHandler ( " Stream1 " ,
" decode-queue1 " , " simple " ,
" stream-queue1 " , " simple " ,
" 1slot " ) ;
if ( tv_stream1 = = NULL ) {
printf ( " ERROR: TmThreadsCreate failed for Stream1 \n " ) ;
exit ( EXIT_FAILURE ) ;
}
tm_module = TmModuleGetByName ( " StreamTcp " ) ;
if ( tm_module = = NULL ) {
printf ( " ERROR: TmModuleGetByName StreamTcp failed \n " ) ;
exit ( EXIT_FAILURE ) ;
}
TmSlotSetFuncAppend ( tv_stream1 , tm_module , NULL ) ;
if ( threading_set_cpu_affinity ) {
TmThreadSetCPUAffinity ( tv_stream1 , 0 ) ;
if ( ncpus > 1 )
TmThreadSetThreadPriority ( tv_stream1 , PRIO_MEDIUM ) ;
}
if ( TmThreadSpawn ( tv_stream1 ) ! = TM_ECODE_OK ) {
printf ( " ERROR: TmThreadSpawn failed \n " ) ;
exit ( EXIT_FAILURE ) ;
}
/* start with cpu 1 so that if we're creating an odd number of detect
* threads we ' re not creating the most on CPU0 . */
if ( ncpus > 0 )
cpu = 1 ;
/* always create at least one thread */
int thread_max = TmThreadGetNbThreads ( DETECT_CPU_SET ) ;
if ( thread_max = = 0 )
thread_max = ncpus * threading_detect_ratio ;
if ( thread_max < 1 )
thread_max = 1 ;
int thread ;
for ( thread = 0 ; thread < thread_max ; thread + + ) {
snprintf ( tname , sizeof ( tname ) , " Detect% " PRIu16 , thread + 1 ) ;
char * thread_name = SCStrdup ( tname ) ;
SCLogDebug ( " Assigning %s affinity to cpu %u " , thread_name , cpu ) ;
ThreadVars * tv_detect_ncpu =
TmThreadCreatePacketHandler ( thread_name ,
" stream-queue1 " , " simple " ,
" verdict-queue " , " simple " ,
" 1slot " ) ;
if ( tv_detect_ncpu = = NULL ) {
printf ( " ERROR: TmThreadsCreate failed \n " ) ;
exit ( EXIT_FAILURE ) ;
}
tm_module = TmModuleGetByName ( " Detect " ) ;
if ( tm_module = = NULL ) {
printf ( " ERROR: TmModuleGetByName Detect failed \n " ) ;
exit ( EXIT_FAILURE ) ;
}
TmSlotSetFuncAppend ( tv_detect_ncpu , tm_module , ( void * ) de_ctx ) ;
if ( threading_set_cpu_affinity ) {
TmThreadSetCPUAffinity ( tv_detect_ncpu , ( int ) cpu ) ;
/* If we have more than one core/cpu, the first Detect thread
* ( at cpu 0 ) will have less priority ( higher ' nice ' value )
* In this case we will set the thread priority to + 10 ( default is 0 )
*/
if ( cpu = = 0 & & ncpus > 1 ) {
TmThreadSetThreadPriority ( tv_detect_ncpu , PRIO_LOW ) ;
} else if ( ncpus > 1 ) {
TmThreadSetThreadPriority ( tv_detect_ncpu , PRIO_MEDIUM ) ;
}
}
ConfGet ( " pfring.live-interface " , & live_dev ) ;
char * thread_group_name = SCStrdup ( " Detect " ) ;
if ( thread_group_name = = NULL ) {
printf ( " Error allocating memory \n " ) ;
exit ( EXIT_FAILURE ) ;
}
tv_detect_ncpu - > thread_group_name = thread_group_name ;
if ( TmThreadSpawn ( tv_detect_ncpu ) ! = TM_ECODE_OK ) {
printf ( " ERROR: TmThreadSpawn failed \n " ) ;
exit ( EXIT_FAILURE ) ;
}
if ( ( cpu + 1 ) = = ncpus )
cpu = 0 ;
else
cpu + + ;
}
ThreadVars * tv_rreject =
TmThreadCreatePacketHandler ( " RespondReject " ,
" verdict-queue " , " simple " ,
" alert-queue1 " , " simple " ,
" 1slot " ) ;
if ( tv_rreject = = NULL ) {
printf ( " ERROR: TmThreadsCreate failed \n " ) ;
exit ( EXIT_FAILURE ) ;
}
tm_module = TmModuleGetByName ( " RespondReject " ) ;
if ( tm_module = = NULL ) {
printf ( " ERROR: TmModuleGetByName for RespondReject failed \n " ) ;
exit ( EXIT_FAILURE ) ;
}
TmSlotSetFuncAppend ( tv_rreject , tm_module , NULL ) ;
if ( threading_set_cpu_affinity ) {
TmThreadSetCPUAffinity ( tv_rreject , 0 ) ;
if ( ncpus > 1 )
TmThreadSetThreadPriority ( tv_rreject , PRIO_MEDIUM ) ;
}
if ( TmThreadSpawn ( tv_rreject ) ! = TM_ECODE_OK ) {
printf ( " ERROR: TmThreadSpawn failed \n " ) ;
exit ( EXIT_FAILURE ) ;
}
ThreadVars * tv_outputs =
TmThreadCreatePacketHandler ( " Outputs " ,
" alert-queue1 " , " simple " ,
" packetpool " , " packetpool " ,
" varslot " ) ;
if ( tv_outputs = = NULL ) {
printf ( " ERROR: TmThreadCreatePacketHandler for Outputs failed \n " ) ;
exit ( EXIT_FAILURE ) ;
}
if ( threading_set_cpu_affinity ) {
TmThreadSetCPUAffinity ( tv_outputs , 0 ) ;
if ( ncpus > 1 )
TmThreadSetThreadPriority ( tv_outputs , PRIO_MEDIUM ) ;
}
SetupOutputs ( tv_outputs ) ;
if ( TmThreadSpawn ( tv_outputs ) ! = TM_ECODE_OK ) {
ret = RunModeSetLiveCaptureAuto ( de_ctx , ParsePfringConfig , " ReceivePfring " , " DecodePfring " ,
" RxPFR " , live_dev ) ;
if ( ret ! = 0 ) {
printf ( " ERROR: TmThreadSpawn failed \n " ) ;
exit ( EXIT_FAILURE ) ;
}
# endif /* HAVE_PFRING */
return 0 ;
}
@ -313,150 +214,34 @@ int RunModeIdsPfringAutoFp(DetectEngineCtx *de_ctx)
/* We include only if pfring is enabled */
# ifdef HAVE_PFRING
char tname [ 12 ] ;
char qname [ 12 ] ;
uint16_t cpu = 0 ;
char queues [ 2048 ] = " " ;
int ret ;
char * live_dev = NULL ;
RunModeInitialize ( ) ;
TimeModeSetLive ( ) ;
/* Available cpus */
uint16_t ncpus = UtilCpuGetNumProcessorsOnline ( ) ;
/* start with cpu 1 so that if we're creating an odd number of detect
* threads we ' re not creating the most on CPU0 . */
if ( ncpus > 0 )
cpu = 1 ;
/* always create at least one thread */
int thread_max = TmThreadGetNbThreads ( DETECT_CPU_SET ) ;
if ( thread_max = = 0 )
thread_max = ncpus * threading_detect_ratio ;
if ( thread_max < 1 )
thread_max = 1 ;
int thread ;
for ( thread = 0 ; thread < thread_max ; thread + + ) {
if ( strlen ( queues ) > 0 )
strlcat ( queues , " , " , sizeof ( queues ) ) ;
snprintf ( qname , sizeof ( qname ) , " pickup% " PRIu16 , thread + 1 ) ;
strlcat ( queues , qname , sizeof ( queues ) ) ;
}
SCLogDebug ( " queues %s " , queues ) ;
int pfring_threads = PfringConfGetThreads ( ) ;
if ( pfring_threads = = 0 ) {
pfring_threads = 1 ;
}
/* create the threads */
for ( thread = 0 ; thread < pfring_threads ; thread + + ) {
snprintf ( tname , sizeof ( tname ) , " RxPfring% " PRIu16 , 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 ( " ReceivePfring " ) ;
if ( tm_module = = NULL ) {
printf ( " ERROR: TmModuleGetByName failed for ReceivePfring \n " ) ;
exit ( EXIT_FAILURE ) ;
}
TmSlotSetFuncAppend ( tv_receive , tm_module , NULL ) ;
tm_module = TmModuleGetByName ( " DecodePfring " ) ;
if ( tm_module = = NULL ) {
printf ( " ERROR: TmModuleGetByName DecodePfring failed \n " ) ;
exit ( EXIT_FAILURE ) ;
}
TmSlotSetFuncAppend ( tv_receive , tm_module , NULL ) ;
ConfGet ( " pfring.live-interface " , & live_dev ) ;
if ( threading_set_cpu_affinity ) {
TmThreadSetCPUAffinity ( tv_receive , 0 ) ;
if ( ncpus > 1 )
TmThreadSetThreadPriority ( tv_receive , PRIO_MEDIUM ) ;
}
SCLogDebug ( " live_dev %s " , live_dev ) ;
if ( TmThreadSpawn ( tv_receive ) ! = TM_ECODE_OK ) {
printf ( " ERROR: TmThreadSpawn failed \n " ) ;
exit ( EXIT_FAILURE ) ;
}
ret = RunModeSetLiveCaptureAutoFp ( de_ctx ,
ParsePfringConfig ,
PfringConfigGeThreadsCount ,
" ReceivePfring " ,
" DecodePfring " , " RxPFR " ,
live_dev ) ;
if ( ret ! = 0 ) {
printf ( " ERROR: Unable to start runmode \n " ) ;
if ( live_dev )
SCFree ( live_dev ) ;
exit ( EXIT_FAILURE ) ;
}
for ( thread = 0 ; thread < thread_max ; thread + + ) {
snprintf ( tname , sizeof ( tname ) , " Detect% " PRIu16 , thread + 1 ) ;
snprintf ( qname , sizeof ( qname ) , " pickup% " PRIu16 , thread + 1 ) ;
SCLogDebug ( " tname %s, qname %s " , tname , qname ) ;
char * thread_name = SCStrdup ( tname ) ;
SCLogDebug ( " Assigning %s affinity to cpu %u " , thread_name , cpu ) ;
ThreadVars * tv_detect_ncpu =
TmThreadCreatePacketHandler ( thread_name ,
qname , " flow " ,
" packetpool " , " packetpool " ,
" varslot " ) ;
if ( tv_detect_ncpu = = NULL ) {
printf ( " ERROR: TmThreadsCreate failed \n " ) ;
exit ( EXIT_FAILURE ) ;
}
TmModule * tm_module = TmModuleGetByName ( " StreamTcp " ) ;
if ( tm_module = = NULL ) {
printf ( " ERROR: TmModuleGetByName StreamTcp failed \n " ) ;
exit ( EXIT_FAILURE ) ;
}
TmSlotSetFuncAppend ( tv_detect_ncpu , tm_module , NULL ) ;
tm_module = TmModuleGetByName ( " Detect " ) ;
if ( tm_module = = NULL ) {
printf ( " ERROR: TmModuleGetByName Detect failed \n " ) ;
exit ( EXIT_FAILURE ) ;
}
TmSlotSetFuncAppend ( tv_detect_ncpu , tm_module , ( void * ) de_ctx ) ;
if ( threading_set_cpu_affinity ) {
TmThreadSetCPUAffinity ( tv_detect_ncpu , ( int ) cpu ) ;
/* If we have more than one core/cpu, the first Detect thread
* ( at cpu 0 ) will have less priority ( higher ' nice ' value )
* In this case we will set the thread priority to + 10 ( default is 0 )
*/
if ( cpu = = 0 & & ncpus > 1 ) {
TmThreadSetThreadPriority ( tv_detect_ncpu , PRIO_LOW ) ;
} else if ( ncpus > 1 ) {
TmThreadSetThreadPriority ( tv_detect_ncpu , PRIO_MEDIUM ) ;
}
}
char * thread_group_name = SCStrdup ( " Detect " ) ;
if ( thread_group_name = = NULL ) {
printf ( " Error allocating memory \n " ) ;
exit ( EXIT_FAILURE ) ;
}
tv_detect_ncpu - > thread_group_name = thread_group_name ;
/* add outputs as well */
SetupOutputs ( tv_detect_ncpu ) ;
if ( TmThreadSpawn ( tv_detect_ncpu ) ! = TM_ECODE_OK ) {
printf ( " ERROR: TmThreadSpawn failed \n " ) ;
exit ( EXIT_FAILURE ) ;
}
if ( ( cpu + 1 ) = = ncpus )
cpu = 0 ;
else
cpu + + ;
}
if ( live_dev )
SCFree ( live_dev ) ;
SCLogInfo ( " RunModeIdsPfringAutoFp initialised " ) ;
# endif /* HAVE_PFRING */
return 0 ;