}
}
-/**
-* \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 NetmapIfaceConfig corresponding to the interface name
-*/
-static void *ParseNetmapConfig(const char *iface_name)
+static int ParseNetmapSettings(NetmapIfaceSettings *ns, const char *iface,
+ ConfNode *if_root, ConfNode *if_default)
{
- char *threadsstr = NULL;
- ConfNode *if_root;
- ConfNode *if_default = NULL;
- ConfNode *netmap_node;
- char *tmpctype;
- char *copymodestr;
- int boolval;
- char *bpf_filter = NULL;
- char *out_iface = NULL;
-
- if (iface_name == NULL) {
- return NULL;
- }
-
- NetmapIfaceConfig *aconf = SCMalloc(sizeof(*aconf));
- if (unlikely(aconf == NULL)) {
- return NULL;
- }
-
- memset(aconf, 0, sizeof(*aconf));
- aconf->DerefFunc = NetmapDerefConfig;
- aconf->threads = 0;
- aconf->promisc = 1;
- aconf->checksum_mode = CHECKSUM_VALIDATION_AUTO;
- aconf->copy_mode = NETMAP_COPY_MODE_NONE;
- strlcpy(aconf->iface_name, iface_name, sizeof(aconf->iface_name));
- SC_ATOMIC_INIT(aconf->ref);
- (void) SC_ATOMIC_ADD(aconf->ref, 1);
-
- strlcpy(aconf->iface, aconf->iface_name, sizeof(aconf->iface));
- if (aconf->iface[0]) {
- size_t len = strlen(aconf->iface);
- if (aconf->iface[len-1] == '+') {
- aconf->iface[len-1] = '\0';
- aconf->iface_sw = 1;
+ ns->threads = 0;
+ ns->promisc = 1;
+ ns->checksum_mode = CHECKSUM_VALIDATION_AUTO;
+ ns->copy_mode = NETMAP_COPY_MODE_NONE;
+
+ strlcpy(ns->iface, iface, sizeof(ns->iface));
+ if (ns->iface[0]) {
+ size_t len = strlen(ns->iface);
+ if (ns->iface[len-1] == '+') {
+ ns->iface[len-1] = '\0';
+ ns->sw_ring = 1;
}
}
+ char *bpf_filter = NULL;
if (ConfGet("bpf-filter", &bpf_filter) == 1) {
if (strlen(bpf_filter) > 0) {
- aconf->bpf_filter = bpf_filter;
+ ns->bpf_filter = bpf_filter;
SCLogInfo("Going to use command-line provided bpf filter '%s'",
- aconf->bpf_filter);
+ ns->bpf_filter);
}
}
- /* Find initial node */
- netmap_node = ConfGetNode("netmap");
- if (netmap_node == NULL) {
- SCLogInfo("Unable to find netmap config using default value");
- goto finalize;
- }
-
- if_root = ConfFindDeviceConfig(netmap_node, aconf->iface_name);
-
- if_default = ConfFindDeviceConfig(netmap_node, "default");
-
if (if_root == NULL && if_default == NULL) {
SCLogInfo("Unable to find netmap config for "
- "interface \"%s\" or \"default\", using default value",
- aconf->iface_name);
+ "interface \"%s\" or \"default\", using default values",
+ iface);
goto finalize;
- }
/* If there is no setting for current interface use default one as main iface */
- if (if_root == NULL) {
+ } else if (if_root == NULL) {
if_root = if_default;
if_default = NULL;
}
+ char *threadsstr = NULL;
if (ConfGetChildValueWithDefault(if_root, if_default, "threads", &threadsstr) != 1) {
- aconf->threads = 0;
+ ns->threads = 0;
} else {
if (strcmp(threadsstr, "auto") == 0) {
- aconf->threads = 0;
- } else {
- aconf->threads = (uint8_t)atoi(threadsstr);
- }
- }
-
- if (ConfGetChildValueWithDefault(if_root, if_default, "copy-iface", &out_iface) == 1) {
- if (strlen(out_iface) > 0) {
- aconf->out_iface_name = out_iface;
- }
- }
-
- if (ConfGetChildValueWithDefault(if_root, if_default, "copy-mode", ©modestr) == 1) {
- if (aconf->out_iface_name == NULL) {
- SCLogInfo("Copy mode activated but no destination"
- " iface. Disabling feature");
- } else if (strlen(copymodestr) <= 0) {
- aconf->out_iface_name = NULL;
- } else if (strcmp(copymodestr, "ips") == 0) {
- SCLogInfo("Netmap IPS mode activated %s->%s",
- aconf->iface_name,
- aconf->out_iface_name);
- aconf->copy_mode = NETMAP_COPY_MODE_IPS;
- } else if (strcmp(copymodestr, "tap") == 0) {
- SCLogInfo("Netmap TAP mode activated %s->%s",
- aconf->iface_name,
- aconf->out_iface_name);
- aconf->copy_mode = NETMAP_COPY_MODE_TAP;
+ ns->threads = 0;
} else {
- SCLogInfo("Invalid mode (not in tap, ips)");
- }
- }
-
- if (aconf->out_iface_name && aconf->out_iface_name[0]) {
- strlcpy(aconf->out_iface, aconf->out_iface_name,
- sizeof(aconf->out_iface));
- size_t len = strlen(aconf->out_iface);
- if (aconf->out_iface[len-1] == '+') {
- aconf->out_iface[len-1] = '\0';
- aconf->out_iface_sw = 1;
+ ns->threads = (uint8_t)atoi(threadsstr);
}
}
/* load netmap bpf filter */
/* command line value has precedence */
- if (ConfGet("bpf-filter", &bpf_filter) != 1) {
+ if (ns->bpf_filter == NULL) {
if (ConfGetChildValueWithDefault(if_root, if_default, "bpf-filter", &bpf_filter) == 1) {
if (strlen(bpf_filter) > 0) {
- aconf->bpf_filter = bpf_filter;
- SCLogInfo("Going to use bpf filter %s", aconf->bpf_filter);
+ ns->bpf_filter = bpf_filter;
+ SCLogInfo("Going to use bpf filter %s", ns->bpf_filter);
}
}
}
+ int boolval = 0;
(void)ConfGetChildValueBoolWithDefault(if_root, if_default, "disable-promisc", (int *)&boolval);
if (boolval) {
- SCLogInfo("Disabling promiscuous mode on iface %s", aconf->iface);
- aconf->promisc = 0;
+ SCLogInfo("Disabling promiscuous mode on iface %s", ns->iface);
+ ns->promisc = 0;
}
- if (ConfGetChildValueWithDefault(if_root, if_default, "checksum-checks", &tmpctype) == 1) {
+ char *tmpctype;
+ if (ConfGetChildValueWithDefault(if_root, if_default,
+ "checksum-checks", &tmpctype) == 1)
+ {
if (strcmp(tmpctype, "auto") == 0) {
- aconf->checksum_mode = CHECKSUM_VALIDATION_AUTO;
+ ns->checksum_mode = CHECKSUM_VALIDATION_AUTO;
} else if (ConfValIsTrue(tmpctype)) {
- aconf->checksum_mode = CHECKSUM_VALIDATION_ENABLE;
+ ns->checksum_mode = CHECKSUM_VALIDATION_ENABLE;
} else if (ConfValIsFalse(tmpctype)) {
- aconf->checksum_mode = CHECKSUM_VALIDATION_DISABLE;
+ ns->checksum_mode = CHECKSUM_VALIDATION_DISABLE;
} else {
- SCLogError(SC_ERR_INVALID_ARGUMENT, "Invalid value for checksum-checks for %s", aconf->iface_name);
+ SCLogWarning(SC_ERR_INVALID_ARGUMENT, "Invalid value for "
+ "checksum-checks for %s", iface);
+ }
+ }
+
+ char *copymodestr;
+ if (ConfGetChildValueWithDefault(if_root, if_default,
+ "copy-mode", ©modestr) == 1)
+ {
+ if (strcmp(copymodestr, "ips") == 0) {
+ ns->copy_mode = NETMAP_COPY_MODE_IPS;
+ } else if (strcmp(copymodestr, "tap") == 0) {
+ ns->copy_mode = NETMAP_COPY_MODE_TAP;
+ } else {
+ SCLogWarning(SC_ERR_INVALID_ARGUMENT, "Invalid copy-mode "
+ "(valid are tap, ips)");
}
}
finalize:
- if (aconf->iface_sw) {
+ if (ns->sw_ring) {
/* just one thread per interface supported */
- aconf->threads = 1;
- } else if (aconf->threads == 0) {
+ ns->threads = 1;
+ } else if (ns->threads == 0) {
/* As NetmapGetRSSCount is broken on Linux, first run
* GetIfaceRSSQueuesNum. If that fails, run NetmapGetRSSCount */
- aconf->threads = GetIfaceRSSQueuesNum(aconf->iface);
- if (aconf->threads == 0) {
- aconf->threads = NetmapGetRSSCount(aconf->iface);
+ ns->threads = GetIfaceRSSQueuesNum(ns->iface);
+ if (ns->threads == 0) {
+ ns->threads = NetmapGetRSSCount(ns->iface);
}
}
- if (aconf->threads <= 0) {
- aconf->threads = 1;
+ if (ns->threads <= 0) {
+ ns->threads = 1;
}
+
+ return 0;
+}
+
+/**
+* \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 NetmapIfaceConfig corresponding to the interface name
+*/
+static void *ParseNetmapConfig(const char *iface_name)
+{
+ ConfNode *if_root = NULL;
+ ConfNode *if_default = NULL;
+ ConfNode *netmap_node;
+ char *out_iface = NULL;
+
+ if (iface_name == NULL) {
+ return NULL;
+ }
+
+ NetmapIfaceConfig *aconf = SCMalloc(sizeof(*aconf));
+ if (unlikely(aconf == NULL)) {
+ return NULL;
+ }
+
+ memset(aconf, 0, sizeof(*aconf));
+ aconf->DerefFunc = NetmapDerefConfig;
+ strlcpy(aconf->iface_name, iface_name, sizeof(aconf->iface_name));
+ SC_ATOMIC_INIT(aconf->ref);
+ (void) SC_ATOMIC_ADD(aconf->ref, 1);
+
+ /* Find initial node */
+ netmap_node = ConfGetNode("netmap");
+ if (netmap_node == NULL) {
+ SCLogInfo("Unable to find netmap config using default value");
+ } else {
+ if_root = ConfFindDeviceConfig(netmap_node, aconf->iface_name);
+ if_default = ConfFindDeviceConfig(netmap_node, "default");
+ }
+
+ /* parse settings for capture iface */
+ ParseNetmapSettings(&aconf->in, aconf->iface_name, if_root, if_default);
+
+ /* if we have a copy iface, parse that as well */
+ if (ConfGetChildValueWithDefault(if_root, if_default, "copy-iface", &out_iface) == 1) {
+ if (strlen(out_iface) > 0) {
+ if_root = ConfFindDeviceConfig(netmap_node, out_iface);
+ ParseNetmapSettings(&aconf->out, out_iface, if_root, if_default);
+ }
+ }
+
SC_ATOMIC_RESET(aconf->ref);
- (void) SC_ATOMIC_ADD(aconf->ref, aconf->threads);
- SCLogPerf("Using %d threads for interface %s", aconf->threads,
+ (void) SC_ATOMIC_ADD(aconf->ref, aconf->in.threads);
+ SCLogPerf("Using %d threads for interface %s", aconf->in.threads,
aconf->iface_name);
return aconf;
static int NetmapConfigGeThreadsCount(void *conf)
{
NetmapIfaceConfig *aconf = (NetmapIfaceConfig *)conf;
- return aconf->threads;
+ return aconf->in.threads;
}
int NetmapRunModeIsIPS()
memset(ntv, 0, sizeof(*ntv));
ntv->tv = tv;
- ntv->checksum_mode = aconf->checksum_mode;
- ntv->copy_mode = aconf->copy_mode;
+ ntv->checksum_mode = aconf->in.checksum_mode;
+ ntv->copy_mode = aconf->in.copy_mode;
ntv->livedev = LiveGetDevice(aconf->iface_name);
if (ntv->livedev == NULL) {
goto error_ntv;
}
- if (NetmapOpen(aconf->iface, aconf->promisc, &ntv->ifsrc, 1) != 0) {
+ if (NetmapOpen(aconf->in.iface, aconf->in.promisc, &ntv->ifsrc, 1) != 0) {
goto error_ntv;
}
- if (unlikely(!aconf->iface_sw && !ntv->ifsrc->rx_rings_cnt)) {
+ if (unlikely(!aconf->in.sw_ring && !ntv->ifsrc->rx_rings_cnt)) {
SCLogError(SC_ERR_NETMAP_CREATE,
"Input interface '%s' does not have Rx rings",
aconf->iface_name);
goto error_src;
}
- if (unlikely(aconf->iface_sw && aconf->threads > 1)) {
+ if (unlikely(aconf->in.sw_ring && aconf->in.threads > 1)) {
SCLogError(SC_ERR_INVALID_VALUE,
"Interface '%s+'. "
"Thread count can't be greater than 1 for SW ring.",
aconf->iface_name);
goto error_src;
- } else if (unlikely(aconf->threads > ntv->ifsrc->rx_rings_cnt)) {
+ } else if (unlikely(aconf->in.threads > ntv->ifsrc->rx_rings_cnt)) {
SCLogError(SC_ERR_INVALID_VALUE,
"Thread count can't be greater than Rx ring count. "
"Configured %d threads for interface '%s' with %d Rx rings.",
- aconf->threads, aconf->iface_name, ntv->ifsrc->rx_rings_cnt);
+ aconf->in.threads, aconf->iface_name, ntv->ifsrc->rx_rings_cnt);
goto error_src;
}
- if (aconf->iface_sw) {
+ if (aconf->in.sw_ring) {
ntv->thread_idx = 0;
} else {
do {
}
/* calculate thread rings binding */
- if (aconf->iface_sw) {
+ if (aconf->in.sw_ring) {
ntv->src_ring_from = ntv->src_ring_to = ntv->ifsrc->rings_cnt;
} else {
- int tmp = (ntv->ifsrc->rx_rings_cnt + 1) / aconf->threads;
+ int tmp = (ntv->ifsrc->rx_rings_cnt + 1) / aconf->in.threads;
ntv->src_ring_from = ntv->thread_idx * tmp;
ntv->src_ring_to = ntv->src_ring_from + tmp - 1;
- if (ntv->thread_idx == (aconf->threads - 1)) {
+ if (ntv->thread_idx == (aconf->in.threads - 1)) {
ntv->src_ring_to = ntv->ifsrc->rx_rings_cnt - 1;
}
}
SCLogDebug("netmap: %s thread:%d rings:%d-%d", aconf->iface_name,
ntv->thread_idx, ntv->src_ring_from, ntv->src_ring_to);
- if (aconf->copy_mode != NETMAP_COPY_MODE_NONE) {
- if (NetmapOpen(aconf->out_iface, 0, &ntv->ifdst, 1) != 0) {
+ if (aconf->in.copy_mode != NETMAP_COPY_MODE_NONE) {
+ if (NetmapOpen(aconf->out.iface, aconf->out.promisc, &ntv->ifdst, 1) != 0) {
goto error_src;
}
- if (unlikely(!aconf->out_iface_sw && !ntv->ifdst->tx_rings_cnt)) {
+ if (unlikely(!aconf->out.sw_ring && !ntv->ifdst->tx_rings_cnt)) {
SCLogError(SC_ERR_NETMAP_CREATE,
"Output interface '%s' does not have Tx rings",
- aconf->out_iface_name);
+ aconf->out.iface);
goto error_dst;
}
/* calculate dst rings bindings */
for (int i = ntv->src_ring_from; i <= ntv->src_ring_to; i++) {
NetmapRing *ring = &ntv->ifsrc->rings[i];
- if (aconf->out_iface_sw) {
+ if (aconf->out.sw_ring) {
ring->dst_ring_from = ring->dst_ring_to = ntv->ifdst->rings_cnt;
} else if (ntv->ifdst->tx_rings_cnt > ntv->ifsrc->rx_rings_cnt) {
int tmp = (ntv->ifdst->tx_rings_cnt + 1) / ntv->ifsrc->rx_rings_cnt;
ring->dst_next_ring = ring->dst_ring_from;
SCLogDebug("netmap: %s(%d)->%s(%d-%d)",
- aconf->iface_name, i, aconf->out_iface_name,
+ aconf->in.iface, i, aconf->out.iface,
ring->dst_ring_from, ring->dst_ring_to);
}
}
/* enable zero-copy mode for workers runmode */
char const *active_runmode = RunmodeGetActive();
- if ((aconf->copy_mode != NETMAP_COPY_MODE_NONE) && active_runmode
- && !strcmp("workers", active_runmode)) {
+ if ((aconf->in.copy_mode != NETMAP_COPY_MODE_NONE) && active_runmode &&
+ strcmp("workers", active_runmode) == 0) {
ntv->flags |= NETMAP_FLAG_ZERO_COPY;
SCLogPerf("Enabling zero copy mode for %s->%s",
- aconf->iface_name, aconf->out_iface_name);
+ aconf->in.iface, aconf->out.iface);
} else {
uint16_t ring_size = ntv->ifsrc->rings[0].rx->num_slots;
if (ring_size > max_pending_packets) {
}
}
- if (aconf->bpf_filter) {
+ if (aconf->in.bpf_filter) {
SCLogConfig("Using BPF '%s' on iface '%s'",
- aconf->bpf_filter, ntv->ifsrc->ifname);
+ aconf->in.bpf_filter, ntv->ifsrc->ifname);
if (pcap_compile_nopcap(default_packet_size, /* snaplen_arg */
LINKTYPE_ETHERNET, /* linktype_arg */
&ntv->bpf_prog, /* program */
- aconf->bpf_filter, /* const char *buf */
+ aconf->in.bpf_filter, /* const char *buf */
1, /* optimize */
PCAP_NETMASK_UNKNOWN /* mask */
- ) == -1) {
+ ) == -1)
+ {
SCLogError(SC_ERR_NETMAP_CREATE, "Filter compilation failed.");
goto error_dst;
}
SCReturnInt(TM_ECODE_OK);
error_dst:
- if (aconf->copy_mode != NETMAP_COPY_MODE_NONE) {
+ if (aconf->in.copy_mode != NETMAP_COPY_MODE_NONE) {
NetmapClose(ntv->ifdst);
}
error_src: