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.c95
1 files changed, 94 insertions, 1 deletions
diff --git a/src/external_inject.c b/src/external_inject.c
index ba5f3d1..0ad3478 100644
--- a/src/external_inject.c
+++ b/src/external_inject.c
@@ -42,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));
@@ -175,6 +175,89 @@ static void external_inject_ct_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,
@@ -188,4 +271,14 @@ struct external_handler external_inject = {
.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,
+ },
};