summaryrefslogtreecommitdiff
path: root/src/external_inject.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/external_inject.c')
-rw-r--r--src/external_inject.c134
1 files changed, 116 insertions, 18 deletions
diff --git a/src/external_inject.c b/src/external_inject.c
index a54bb13..0ad3478 100644
--- a/src/external_inject.c
+++ b/src/external_inject.c
@@ -1,6 +1,7 @@
/*
- * (C) 2009 by Pablo Neira Ayuso <pablo@netfilter.org>
- *
+ * (C) 2006-2011 by Pablo Neira Ayuso <pablo@netfilter.org>
+ * (C) 2011 by Vyatta Inc. <http://www.vyatta.com>
+ *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
@@ -41,7 +42,7 @@ struct {
static int external_inject_init(void)
{
/* handler to directly inject conntracks into kernel-space */
- inject = nfct_open(CONNTRACK, 0);
+ inject = nfct_open(CONFIG(netlink).subsys_id, 0);
if (inject == NULL) {
dlog(LOG_ERR, "can't open netlink handler: %s",
strerror(errno));
@@ -59,7 +60,7 @@ static void external_inject_close(void)
nfct_close(inject);
}
-static void external_inject_new(struct nf_conntrack *ct)
+static void external_inject_ct_new(struct nf_conntrack *ct)
{
int ret, retry = 1;
@@ -87,7 +88,7 @@ retry:
}
}
-static void external_inject_upd(struct nf_conntrack *ct)
+static void external_inject_ct_upd(struct nf_conntrack *ct)
{
int ret;
@@ -128,7 +129,7 @@ static void external_inject_upd(struct nf_conntrack *ct)
dlog_ct(STATE(log), ct, NFCT_O_PLAIN);
}
-static void external_inject_del(struct nf_conntrack *ct)
+static void external_inject_ct_del(struct nf_conntrack *ct)
{
if (nl_destroy_conntrack(inject, ct) == -1) {
if (errno != ENOENT) {
@@ -141,19 +142,21 @@ static void external_inject_del(struct nf_conntrack *ct)
}
}
-static void external_inject_dump(int fd, int type)
+static void external_inject_ct_dump(int fd, int type)
{
}
-static void external_inject_commit(struct nfct_handle *h, int fd)
+static int external_inject_ct_commit(struct nfct_handle *h, int fd)
{
+ /* close the commit socket. */
+ return LOCAL_RET_OK;
}
-static void external_inject_flush(void)
+static void external_inject_ct_flush(void)
{
}
-static void external_inject_stats(int fd)
+static void external_inject_ct_stats(int fd)
{
char buf[512];
int size;
@@ -172,15 +175,110 @@ static void external_inject_stats(int fd)
send(fd, buf, size, 0);
}
+struct {
+ uint32_t add_ok;
+ uint32_t add_fail;
+ uint32_t upd_ok;
+ uint32_t upd_fail;
+ uint32_t del_ok;
+ uint32_t del_fail;
+} exp_external_inject_stat;
+
+static void external_inject_exp_new(struct nf_expect *exp)
+{
+ int ret, retry = 1;
+
+retry:
+ if (nl_create_expect(inject, exp, 0) == -1) {
+ /* if the state entry exists, we delete and try again */
+ if (errno == EEXIST && retry == 1) {
+ ret = nl_destroy_expect(inject, exp);
+ if (ret == 0 || (ret == -1 && errno == ENOENT)) {
+ if (retry) {
+ retry = 0;
+ goto retry;
+ }
+ }
+ exp_external_inject_stat.add_fail++;
+ dlog(LOG_ERR, "inject-add1: %s", strerror(errno));
+ dlog_exp(STATE(log), exp, NFCT_O_PLAIN);
+ return;
+ }
+ exp_external_inject_stat.add_fail++;
+ dlog(LOG_ERR, "inject-add2: %s", strerror(errno));
+ dlog_exp(STATE(log), exp, NFCT_O_PLAIN);
+ } else {
+ exp_external_inject_stat.add_ok++;
+ }
+}
+
+static void external_inject_exp_del(struct nf_expect *exp)
+{
+ if (nl_destroy_expect(inject, exp) == -1) {
+ if (errno != ENOENT) {
+ exp_external_inject_stat.del_fail++;
+ dlog(LOG_ERR, "inject-del: %s", strerror(errno));
+ dlog_exp(STATE(log), exp, NFCT_O_PLAIN);
+ }
+ } else {
+ exp_external_inject_stat.del_ok++;
+ }
+}
+
+static void external_inject_exp_dump(int fd, int type)
+{
+}
+
+static int external_inject_exp_commit(struct nfct_handle *h, int fd)
+{
+ /* close the commit socket. */
+ return LOCAL_RET_OK;
+}
+
+static void external_inject_exp_flush(void)
+{
+}
+
+static void external_inject_exp_stats(int fd)
+{
+ char buf[512];
+ int size;
+
+ size = sprintf(buf, "external inject:\n"
+ "connections created:\t\t%12u\tfailed:\t%12u\n"
+ "connections updated:\t\t%12u\tfailed:\t%12u\n"
+ "connections destroyed:\t\t%12u\tfailed:\t%12u\n\n",
+ exp_external_inject_stat.add_ok,
+ exp_external_inject_stat.add_fail,
+ exp_external_inject_stat.upd_ok,
+ exp_external_inject_stat.upd_fail,
+ exp_external_inject_stat.del_ok,
+ exp_external_inject_stat.del_fail);
+
+ send(fd, buf, size, 0);
+}
+
struct external_handler external_inject = {
.init = external_inject_init,
.close = external_inject_close,
- .new = external_inject_new,
- .update = external_inject_upd,
- .destroy = external_inject_del,
- .dump = external_inject_dump,
- .commit = external_inject_commit,
- .flush = external_inject_flush,
- .stats = external_inject_stats,
- .stats_ext = external_inject_stats,
+ .ct = {
+ .new = external_inject_ct_new,
+ .upd = external_inject_ct_upd,
+ .del = external_inject_ct_del,
+ .dump = external_inject_ct_dump,
+ .commit = external_inject_ct_commit,
+ .flush = external_inject_ct_flush,
+ .stats = external_inject_ct_stats,
+ .stats_ext = external_inject_ct_stats,
+ },
+ .exp = {
+ .new = external_inject_exp_new,
+ .upd = external_inject_exp_new,
+ .del = external_inject_exp_del,
+ .dump = external_inject_exp_dump,
+ .commit = external_inject_exp_commit,
+ .flush = external_inject_exp_flush,
+ .stats = external_inject_exp_stats,
+ .stats_ext = external_inject_exp_stats,
+ },
};