diff options
Diffstat (limited to 'src/external_inject.c')
-rw-r--r-- | src/external_inject.c | 134 |
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, + }, }; |