summaryrefslogtreecommitdiffstats
path: root/src/conntrack.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/conntrack.c')
-rw-r--r--src/conntrack.c52
1 files changed, 35 insertions, 17 deletions
diff --git a/src/conntrack.c b/src/conntrack.c
index 2bd71e1..0d71352 100644
--- a/src/conntrack.c
+++ b/src/conntrack.c
@@ -139,6 +139,8 @@ static int alloc_tmpl_objects(struct ct_tmpl *tmpl)
static void free_tmpl_objects(struct ct_tmpl *tmpl)
{
+ if (!tmpl)
+ return;
if (tmpl->ct)
nfct_destroy(tmpl->ct);
if (tmpl->exptuple)
@@ -536,7 +538,7 @@ static const char usage_parameters[] =
"Common parameters and options:\n"
" -s, --src, --orig-src ip\t\tSource address from original direction\n"
" -d, --dst, --orig-dst ip\t\tDestination address from original direction\n"
- " -r, --reply-src ip\t\tSource addres from reply direction\n"
+ " -r, --reply-src ip\t\tSource address from reply direction\n"
" -q, --reply-dst ip\t\tDestination address from reply direction\n"
" -p, --protonum proto\t\tLayer 4 Protocol, eg. 'tcp'\n"
" -f, --family proto\t\tLayer 3 Protocol, eg. 'ipv6'\n"
@@ -1942,7 +1944,7 @@ static int event_cb(const struct nlmsghdr *nlh, void *data)
nfct_snprintf_labels(buf, sizeof(buf), ct, type, op_type, op_flags, labelmap);
done:
- if (nlh->nlmsg_pid) {
+ if (nlh->nlmsg_pid && !(output_mask & _O_XML)) {
char *prog = get_progname(nlh->nlmsg_pid);
if (prog)
@@ -1987,10 +1989,14 @@ static int mnl_nfct_delete_cb(const struct nlmsghdr *nlh, void *data)
res = nfct_mnl_request(modifier_sock, NFNL_SUBSYS_CTNETLINK,
nfct_get_attr_u8(ct, ATTR_ORIG_L3PROTO),
IPCTNL_MSG_CT_DELETE, NLM_F_ACK, NULL, ct, NULL);
- if (res < 0)
+ if (res < 0) {
+ /* the entry has vanish in middle of the delete */
+ if (errno == ENOENT)
+ goto done;
exit_error(OTHER_PROBLEM,
"Operation failed: %s",
err2str(errno, CT_DELETE));
+ }
if (output_mask & _O_SAVE) {
ct_save_snprintf(buf, sizeof(buf), ct, labelmap, NFCT_T_DESTROY);
@@ -2182,15 +2188,26 @@ static int mnl_nfct_update_cb(const struct nlmsghdr *nlh, void *data)
if (nfct_cmp(tmp, ct, NFCT_CMP_ALL | NFCT_CMP_MASK))
goto destroy_ok;
- res = nfct_mnl_request(modifier_sock, NFNL_SUBSYS_CTNETLINK, cmd->family,
+ res = nfct_mnl_request(modifier_sock, NFNL_SUBSYS_CTNETLINK,
+ nfct_get_attr_u8(ct, ATTR_ORIG_L3PROTO),
IPCTNL_MSG_CT_NEW, NLM_F_ACK, NULL, tmp, NULL);
if (res < 0) {
- fprintf(stderr, "Operation failed: %s\n",
- err2str(errno, CT_UPDATE));
+ /* the entry has vanish in middle of the update */
+ if (errno == ENOENT)
+ goto destroy_ok;
+ else if (cmd->options & (CT_OPT_ADD_LABEL | CT_OPT_DEL_LABEL) &&
+ !nfct_attr_is_set(ct, ATTR_CONNLABELS) &&
+ errno == ENOSPC)
+ goto destroy_ok;
+
+ exit_error(OTHER_PROBLEM,
+ "Operation failed: %s",
+ err2str(errno, CT_UPDATE));
}
- res = nfct_mnl_request(modifier_sock, NFNL_SUBSYS_CTNETLINK, cmd->family,
- IPCTNL_MSG_CT_GET, NLM_F_ACK,
+ res = nfct_mnl_request(modifier_sock, NFNL_SUBSYS_CTNETLINK,
+ nfct_get_attr_u8(ct, ATTR_ORIG_L3PROTO),
+ IPCTNL_MSG_CT_GET, 0,
mnl_nfct_print_cb, tmp, NULL);
if (res < 0) {
/* the entry has vanish in middle of the update */
@@ -2884,7 +2901,7 @@ static int print_stats(const struct ct_cmd *cmd)
fprintf(stderr, "%s v%s (conntrack-tools): ",PROGNAME,VERSION);
fprintf(stderr, exit_msg[cmd->cmd], counter);
if (counter == 0 &&
- !(cmd->command & (CT_LIST | EXP_LIST | CT_ADD)))
+ !(cmd->command & (CT_LIST | EXP_LIST)))
return -1;
}
@@ -3005,8 +3022,7 @@ static void do_parse(struct ct_cmd *ct_cmd, int argc, char *argv[])
if (tmpl->filter_status_kernel.mask == 0)
tmpl->filter_status_kernel.mask = status;
- tmpl->mark.value = status;
- tmpl->filter_status_kernel.val = tmpl->mark.value;
+ tmpl->filter_status_kernel.val = status;
tmpl->filter_status_kernel_set = true;
break;
case 'e':
@@ -3217,6 +3233,7 @@ static int do_command_ct(const char *progname, struct ct_cmd *cmd,
struct nfct_mnl_socket *modifier_sock = &_modifier_sock;
struct nfct_mnl_socket *event_sock = &_event_sock;
struct nfct_filter_dump *filter_dump;
+ uint16_t nl_flags = 0;
int res = 0;
switch(cmd->command) {
@@ -3303,14 +3320,15 @@ static int do_command_ct(const char *progname, struct ct_cmd *cmd,
nfct_set_attr(cmd->tmpl.ct, ATTR_CONNLABELS,
xnfct_bitmask_clone(cmd->tmpl.label_modify));
+ if (cmd->command == CT_CREATE)
+ nl_flags = NLM_F_EXCL;
+
res = nfct_mnl_request(sock, NFNL_SUBSYS_CTNETLINK, cmd->family,
IPCTNL_MSG_CT_NEW,
- NLM_F_CREATE | NLM_F_ACK | NLM_F_EXCL,
+ NLM_F_CREATE | NLM_F_ACK | nl_flags,
NULL, cmd->tmpl.ct, NULL);
if (res >= 0)
counter++;
- else if (errno == EEXIST && cmd->command == CT_ADD)
- res = 0;
break;
case EXP_CREATE:
@@ -3375,7 +3393,7 @@ static int do_command_ct(const char *progname, struct ct_cmd *cmd,
case CT_GET:
res = nfct_mnl_request(sock, NFNL_SUBSYS_CTNETLINK, cmd->family,
- IPCTNL_MSG_CT_GET, NLM_F_ACK,
+ IPCTNL_MSG_CT_GET, 0,
mnl_nfct_dump_cb, cmd->tmpl.ct, cmd);
break;
@@ -3833,8 +3851,8 @@ int main(int argc, char *argv[])
exit_error(OTHER_PROBLEM, "OOM");
do_parse(cmd, argc, argv);
- do_command_ct(argv[0], cmd, sock);
- res = print_stats(cmd);
+ res = do_command_ct(argv[0], cmd, sock);
+ res |= print_stats(cmd);
free(cmd);
}
nfct_mnl_socket_close(sock);