summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/conntrackd.h2
-rw-r--r--qa/testsuite/06update8
-rw-r--r--src/conntrack.c82
-rw-r--r--src/filter.c3
-rw-r--r--src/main.c4
-rw-r--r--src/sync-mode.c12
6 files changed, 103 insertions, 8 deletions
diff --git a/include/conntrackd.h b/include/conntrackd.h
index 8baa088..9359dfa 100644
--- a/include/conntrackd.h
+++ b/include/conntrackd.h
@@ -47,6 +47,8 @@
#define ALL_RESYNC_MASTER 44 /* resync w/all kernel tables */
#define ALL_FLUSH_CACHE 45 /* flush all caches */
#define ALL_COMMIT 46 /* commit all tables */
+#define EXP_DUMP_INT_XML 47 /* dump internal cache in XML */
+#define EXP_DUMP_EXT_XML 48 /* dump external cache in XML */
#define DEFAULT_CONFIGFILE "/etc/conntrackd/conntrackd.conf"
#define DEFAULT_LOCKFILE "/var/lock/conntrackd.lock"
diff --git a/qa/testsuite/06update b/qa/testsuite/06update
new file mode 100644
index 0000000..0408303
--- /dev/null
+++ b/qa/testsuite/06update
@@ -0,0 +1,8 @@
+# create dummy flow
+-I -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 --state SYN_RECV -u SEEN_REPLY,ASSURED -t 50 ; OK
+# find it again using mark
+-L -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 ; OK
+# set fixed timeout
+-U -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 -u FIXED_TIMEOUT; OK
+# delete it
+-D -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20; OK
diff --git a/src/conntrack.c b/src/conntrack.c
index 9602e2e..f808994 100644
--- a/src/conntrack.c
+++ b/src/conntrack.c
@@ -340,12 +340,12 @@ static char commands_v_options[NUMBER_OF_CMD][NUMBER_OF_OPT] =
/*CT_EVENT*/ {2,2,2,2,2,0,0,0,2,0,0,0,0,0,2,0,0,2,2,2,2,2,2,2},
/*VERSION*/ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
/*HELP*/ {0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
-/*EXP_LIST*/ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0},
+/*EXP_LIST*/ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,2,0,0,0,0},
/*EXP_CREATE*/{1,1,2,2,1,1,2,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0},
/*EXP_DELETE*/{1,1,2,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
/*EXP_GET*/ {1,1,2,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
/*EXP_FLUSH*/ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
-/*EXP_EVENT*/ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+/*EXP_EVENT*/ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0},
/*CT_COUNT*/ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
/*EXP_COUNT*/ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
/*X_STATS*/ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
@@ -1062,6 +1062,20 @@ event_sighandler(int s)
exit(0);
}
+static void __attribute__((noreturn))
+exp_event_sighandler(int s)
+{
+ if (dump_xml_header_done == 0) {
+ printf("</expect>\n");
+ fflush(stdout);
+ }
+
+ fprintf(stderr, "%s v%s (conntrack-tools): ", PROGNAME, VERSION);
+ fprintf(stderr, "%d expectation events have been shown.\n", counter);
+ nfct_close(cth);
+ exit(0);
+}
+
static int event_cb(enum nf_conntrack_msg_type type,
struct nf_conntrack *ct,
void *data)
@@ -1229,6 +1243,16 @@ static void copy_mark(struct nf_conntrack *tmp,
}
}
+static void copy_status(struct nf_conntrack *tmp, const struct nf_conntrack *ct)
+{
+ if (options & CT_OPT_STATUS) {
+ /* copy existing flags, we only allow setting them. */
+ uint32_t status = nfct_get_attr_u32(ct, ATTR_STATUS);
+ status |= nfct_get_attr_u32(tmp, ATTR_STATUS);
+ nfct_set_attr_u32(tmp, ATTR_STATUS, status);
+ }
+}
+
static int update_cb(enum nf_conntrack_msg_type type,
struct nf_conntrack *ct,
void *data)
@@ -1255,6 +1279,7 @@ static int update_cb(enum nf_conntrack_msg_type type,
nfct_copy(tmp, ct, NFCT_CP_ORIG);
nfct_copy(tmp, obj, NFCT_CP_META);
copy_mark(tmp, ct, &tmpl.mark);
+ copy_status(tmp, ct);
/* do not send NFCT_Q_UPDATE if ct appears unchanged */
if (nfct_cmp(tmp, ct, NFCT_CMP_ALL | NFCT_CMP_MASK)) {
@@ -1296,8 +1321,27 @@ static int dump_exp_cb(enum nf_conntrack_msg_type type,
void *data)
{
char buf[1024];
+ unsigned int op_type = NFCT_O_DEFAULT;
+ unsigned int op_flags = 0;
+
+ if (output_mask & _O_XML) {
+ op_type = NFCT_O_XML;
+ if (dump_xml_header_done) {
+ dump_xml_header_done = 0;
+ printf("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
+ "<expect>\n");
+ }
+ }
+ if (output_mask & _O_TMS) {
+ if (!(output_mask & _O_XML)) {
+ struct timeval tv;
+ gettimeofday(&tv, NULL);
+ printf("[%-8ld.%-6ld]\t", tv.tv_sec, tv.tv_usec);
+ } else
+ op_flags |= NFCT_OF_TIME;
+ }
- nfexp_snprintf(buf,sizeof(buf), exp, NFCT_T_UNKNOWN, NFCT_O_DEFAULT, 0);
+ nfexp_snprintf(buf,sizeof(buf), exp, NFCT_T_UNKNOWN, op_type, op_flags);
printf("%s\n", buf);
counter++;
@@ -1308,8 +1352,27 @@ static int event_exp_cb(enum nf_conntrack_msg_type type,
struct nf_expect *exp, void *data)
{
char buf[1024];
+ unsigned int op_type = NFCT_O_DEFAULT;
+ unsigned int op_flags = 0;
- nfexp_snprintf(buf,sizeof(buf), exp, type, NFCT_O_DEFAULT, 0);
+ if (output_mask & _O_XML) {
+ op_type = NFCT_O_XML;
+ if (dump_xml_header_done) {
+ dump_xml_header_done = 0;
+ printf("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
+ "<expect>\n");
+ }
+ }
+ if (output_mask & _O_TMS) {
+ if (!(output_mask & _O_XML)) {
+ struct timeval tv;
+ gettimeofday(&tv, NULL);
+ printf("[%-8ld.%-6ld]\t", tv.tv_sec, tv.tv_usec);
+ } else
+ op_flags |= NFCT_OF_TIME;
+ }
+
+ nfexp_snprintf(buf,sizeof(buf), exp, type, op_type, op_flags);
printf("%s\n", buf);
counter++;
@@ -1674,8 +1737,13 @@ int main(int argc, char *argv[])
nfexp_callback_register(cth, NFCT_T_ALL, dump_exp_cb, NULL);
res = nfexp_query(cth, NFCT_Q_DUMP, &family);
nfct_close(cth);
+
+ if (dump_xml_header_done == 0) {
+ printf("</expect>\n");
+ fflush(stdout);
+ }
break;
-
+
case CT_CREATE:
if ((options & CT_OPT_ORIG) && !(options & CT_OPT_REPL))
nfct_setobjopt(tmpl.ct, NFCT_SOPT_SETUP_REPLY);
@@ -1855,8 +1923,8 @@ int main(int argc, char *argv[])
if (!cth)
exit_error(OTHER_PROBLEM, "Can't open handler");
- signal(SIGINT, event_sighandler);
- signal(SIGTERM, event_sighandler);
+ signal(SIGINT, exp_event_sighandler);
+ signal(SIGTERM, exp_event_sighandler);
nfexp_callback_register(cth, NFCT_T_ALL, event_exp_cb, NULL);
res = nfexp_catch(cth);
nfct_close(cth);
diff --git a/src/filter.c b/src/filter.c
index e8515d6..afefbfa 100644
--- a/src/filter.c
+++ b/src/filter.c
@@ -467,8 +467,9 @@ int exp_filter_find(struct exp_filter *f, const struct nf_expect *exp)
{
struct exp_filter_item *item;
+ /* if filtering is not active, accept everything. */
if (f == NULL)
- return 0;
+ return 1;
list_for_each_entry(item, &f->list, head) {
const char *name = nfexp_get_attr(exp, ATTR_EXP_HELPER_NAME);
diff --git a/src/main.c b/src/main.c
index 342ed45..0850a29 100644
--- a/src/main.c
+++ b/src/main.c
@@ -290,6 +290,10 @@ int main(int argc, char *argv[])
action = CT_DUMP_INT_XML;
else if (action == CT_DUMP_EXTERNAL)
action = CT_DUMP_EXT_XML;
+ else if (action == EXP_DUMP_INTERNAL)
+ action = EXP_DUMP_INT_XML;
+ else if (action == EXP_DUMP_EXTERNAL)
+ action = EXP_DUMP_EXT_XML;
else {
show_usage(argv[0]);
fprintf(stderr, "Error: Invalid parameters\n");
diff --git a/src/sync-mode.c b/src/sync-mode.c
index 2505631..10fdb9e 100644
--- a/src/sync-mode.c
+++ b/src/sync-mode.c
@@ -706,6 +706,18 @@ static int local_handler_sync(int fd, int type, void *data)
}
local_commit(fd);
break;
+ case EXP_DUMP_INT_XML:
+ if (fork_process_new(CTD_PROC_ANY, 0, NULL, NULL) == 0) {
+ STATE(mode)->internal->exp.dump(fd, NFCT_O_XML);
+ exit(EXIT_SUCCESS);
+ }
+ break;
+ case EXP_DUMP_EXT_XML:
+ if (fork_process_new(CTD_PROC_ANY, 0, NULL, NULL) == 0) {
+ STATE_SYNC(external)->exp.dump(fd, NFCT_O_XML);
+ exit(EXIT_SUCCESS);
+ }
+ break;
default:
if (STATE_SYNC(sync)->local)
ret = STATE_SYNC(sync)->local(fd, type, data);