diff options
Diffstat (limited to 'src/conntrack.c')
-rw-r--r-- | src/conntrack.c | 52 |
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); |