#include <unistd.h>
#include <stdlib.h>
#include <netinet/in.h>
+#include <errno.h>
#include <ulogd/ulogd.h>
+#include <libnfnetlink/libnfnetlink.h>
#include <libnetfilter_log/libnetfilter_log.h>
#ifndef NFLOG_GROUP_DEFAULT
struct nflog_g_handle *nful_gh;
unsigned char *nfulog_buf;
struct ulogd_fd nful_fd;
+ int nlbufsiz;
};
/* configuration entries */
static struct config_keyset libulog_kset = {
- .num_ces = 8,
+ .num_ces = 10,
.ces = {
{
.key = "bufsize",
.options = CONFIG_OPT_NONE,
.u.value = 0,
},
-
+ {
+ .key = "netlink_socket_buffer_size",
+ .type = CONFIG_TYPE_INT,
+ .options = CONFIG_OPT_NONE,
+ .u.value = 0,
+ },
+ {
+ .key = "netlink_socket_buffer_maxsize",
+ .type = CONFIG_TYPE_INT,
+ .options = CONFIG_OPT_NONE,
+ .u.value = 0,
+ },
}
};
#define seq_ce(x) (x->ces[5])
#define seq_global_ce(x) (x->ces[6])
#define label_ce(x) (x->ces[7])
+#define nlsockbufsize_ce(x) (x->ces[8])
+#define nlsockbufmaxsize_ce(x) (x->ces[9])
enum nflog_keys {
NFLOG_KEY_RAW_MAC = 0,
return 0;
}
+static int setnlbufsiz(struct ulogd_pluginstance *upi, int size)
+{
+ struct nflog_input *ui = (struct nflog_input *)upi->private;
+
+ if (size < nlsockbufmaxsize_ce(upi->config_kset).u.value) {
+ ui->nlbufsiz = nfnl_rcvbufsiz(nflog_nfnlh(ui->nful_h), size);
+ return 1;
+ }
+
+ ulogd_log(ULOGD_NOTICE, "Maximum buffer size (%d) in NFLOG has been "
+ "reached. Please, consider rising "
+ "`netlink_socket_buffer_size` and "
+ "`netlink_socket_buffer_maxsize` "
+ "clauses.\n", ui->nlbufsiz);
+ return 0;
+}
+
/* callback called from ulogd core when fd is readable */
static int nful_read_cb(int fd, unsigned int what, void *param)
{
* grab all the processing time just for us. there might be other
* sockets that have pending work */
len = recv(fd, ui->nfulog_buf, bufsiz_ce(upi->config_kset).u.value, 0);
- if (len < 0)
+ if (len < 0) {
+ if (errno == ENOBUFS) {
+ if (nlsockbufmaxsize_ce(upi->config_kset).u.value) {
+ int s = ui->nlbufsiz * 2;
+ if (setnlbufsiz(upi, s)) {
+ ulogd_log(ULOGD_NOTICE,
+ "We are losing events, "
+ "increasing buffer size "
+ "to %d\n", ui->nlbufsiz);
+ }
+ } else {
+ ulogd_log(ULOGD_NOTICE,
+ "We are losing events. Please, "
+ "consider using the clauses "
+ "`netlink_socket_buffer_size' and "
+ "`netlink_socket_buffer_maxsize\n'");
+ }
+ }
return len;
+ }
nflog_handle_packet(ui->nful_h, (char *)ui->nfulog_buf, len);
nflog_set_mode(ui->nful_gh, NFULNL_COPY_PACKET, 0xffff);
- //nflog_set_nlbufsiz(&ui->nful_gh, );
- //nfnl_set_rcvbuf();
-
+ if (nlsockbufsize_ce(upi->config_kset).u.value) {
+ setnlbufsiz(upi, nlsockbufsize_ce(upi->config_kset).u.value);
+ ulogd_log(ULOGD_NOTICE, "NFLOG netlink buffer size has been "
+ "set to %d\n", ui->nlbufsiz);
+ }
+
/* set log flags based on configuration */
flags = 0;
if (seq_ce(upi->config_kset).u.value != 0)