diff options
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | conntrack.8 | 6 | ||||
-rw-r--r-- | conntrackd.conf.5 | 4 | ||||
-rw-r--r-- | extensions/libct_proto_tcp.c | 4 | ||||
-rw-r--r-- | nfct.8 | 2 | ||||
-rw-r--r-- | src/Makefile.am | 80 | ||||
-rw-r--r-- | src/channel.c | 4 | ||||
-rw-r--r-- | src/channel_mcast.c | 2 | ||||
-rw-r--r-- | src/channel_tcp.c | 2 | ||||
-rw-r--r-- | src/channel_udp.c | 2 | ||||
-rw-r--r-- | src/conntrack.c | 146 | ||||
-rw-r--r-- | src/fds.c | 4 | ||||
-rw-r--r-- | src/filter.c | 2 | ||||
-rw-r--r-- | src/helpers/rpc.c | 5 | ||||
-rw-r--r-- | src/main.c | 5 | ||||
-rw-r--r-- | src/multichannel.c | 2 | ||||
-rw-r--r-- | src/origin.c | 2 | ||||
-rw-r--r-- | src/process.c | 2 | ||||
-rw-r--r-- | src/queue.c | 2 | ||||
-rw-r--r-- | src/read_config_yy.y | 265 | ||||
-rw-r--r-- | src/run.c | 23 | ||||
-rw-r--r-- | src/tcp.c | 4 | ||||
-rw-r--r-- | src/udp.c | 4 | ||||
-rw-r--r-- | src/vector.c | 9 | ||||
-rw-r--r-- | tests/conntrack/load-stress.sh | 62 | ||||
-rw-r--r-- | tests/conntrack/testsuite/09dumpopt | 12 |
26 files changed, 434 insertions, 223 deletions
diff --git a/configure.ac b/configure.ac index 01e6027..da852b1 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -AC_INIT([conntrack-tools],[1.4.7],[pablo@netfilter.org]) +AC_INIT([conntrack-tools],[1.4.8],[pablo@netfilter.org]) AC_CONFIG_AUX_DIR([build-aux]) AC_CANONICAL_HOST diff --git a/conntrack.8 b/conntrack.8 index 6fbb41f..3b6a15b 100644 --- a/conntrack.8 +++ b/conntrack.8 @@ -180,7 +180,7 @@ Specify the conntrack mark. Optionally, a mask value can be specified. In "\-\-update" mode, this mask specifies the bits that should be zeroed before XORing the MARK value into the ctmark. Otherwise, the mask is logically ANDed with the existing mark before the -comparision. In "\-\-create" mode, the mask is ignored. +comparison. In "\-\-create" mode, the mask is ignored. .TP .BI "-l, --label " "LABEL" Specify a conntrack label. @@ -193,6 +193,10 @@ Use multiple \-l options to specify multiple labels that need to be set. Specify the conntrack label to add to the selected conntracks. This option is only available in conjunction with "\-I, \-\-create", "\-A, \-\-add" or "\-U, \-\-update". +As a rule of thumb, you must use either the 'connlabel' match in your iptables +ruleset or the 'ct label' statement in your nftables ruleset, this turns on the +ct label support in the kernel and it allows you to update labels via +"\-U, \-\-update", otherwise label updates are ignored. .TP .BI "--label-del " "[LABEL]" Specify the conntrack label to delete from the selected conntracks. diff --git a/conntrackd.conf.5 b/conntrackd.conf.5 index a73c3f7..50d7b98 100644 --- a/conntrackd.conf.5 +++ b/conntrackd.conf.5 @@ -52,7 +52,7 @@ You should consider this file as case-sensitive. Empty lines and lines starting with the '#' character are ignored. Before starting to develop a new configuration, you may want to learn the -concepts behind this technlogy at +concepts behind this technology at \fIhttp://conntrack-tools.netfilter.org/manual.html\fP. There are complete configuration examples at the end of this man page. @@ -630,7 +630,7 @@ filter-sets in positive or negative logic depending on your needs. You can select if \fBconntrackd(8)\fP filters the event messages from user-space or kernel-space. The kernel-space event filtering saves some CPU cycles by avoiding the copy of the event message from kernel-space to -user-space. The kernel-space event filtering is prefered, however, you require +user-space. The kernel-space event filtering is preferred, however, you require a \fBLinux kernel >= 2.6.29\fP to filter from kernel-space. The syntax for this section is: \fBFilter From <from> { }\fP. diff --git a/extensions/libct_proto_tcp.c b/extensions/libct_proto_tcp.c index 27f5833..4681693 100644 --- a/extensions/libct_proto_tcp.c +++ b/extensions/libct_proto_tcp.c @@ -165,13 +165,13 @@ static int parse_options(char c, case '8': port = htons(atoi(optarg)); nfct_set_attr_u16(exptuple, ATTR_ORIG_PORT_SRC, port); - nfct_set_attr_u8(exptuple, ATTR_ORIG_L4PROTO, port); + nfct_set_attr_u8(exptuple, ATTR_ORIG_L4PROTO, IPPROTO_TCP); *flags |= CT_TCP_EXPTUPLE_SPORT; break; case '9': port = htons(atoi(optarg)); nfct_set_attr_u16(exptuple, ATTR_ORIG_PORT_DST, port); - nfct_set_attr_u8(exptuple, ATTR_ORIG_L4PROTO, port); + nfct_set_attr_u8(exptuple, ATTR_ORIG_L4PROTO, IPPROTO_TCP); *flags |= CT_TCP_EXPTUPLE_DPORT; break; } @@ -8,7 +8,7 @@ nfct \- command line tool to configure with the connection tracking system .BR "nfct command subsystem [parameters]" .SH DESCRIPTION .B nfct -is the command line tool that allows to configure the Connection Tracking +is the command line tool that allows you to configure the Connection Tracking System. .SH COMMANDS .TP diff --git a/src/Makefile.am b/src/Makefile.am index 2986ab3..352aa37 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -11,7 +11,18 @@ BUILT_SOURCES = read_config_yy.h sbin_PROGRAMS = conntrack conntrackd nfct conntrack_SOURCES = conntrack.c -conntrack_LDADD = ../extensions/libct_proto_tcp.la ../extensions/libct_proto_udp.la ../extensions/libct_proto_udplite.la ../extensions/libct_proto_icmp.la ../extensions/libct_proto_icmpv6.la ../extensions/libct_proto_sctp.la ../extensions/libct_proto_dccp.la ../extensions/libct_proto_gre.la ../extensions/libct_proto_unknown.la ${LIBNETFILTER_CONNTRACK_LIBS} ${LIBMNL_LIBS} ${LIBNFNETLINK_LIBS} +conntrack_LDADD = ../extensions/libct_proto_dccp.la \ + ../extensions/libct_proto_gre.la \ + ../extensions/libct_proto_icmp.la \ + ../extensions/libct_proto_icmpv6.la \ + ../extensions/libct_proto_sctp.la \ + ../extensions/libct_proto_tcp.la \ + ../extensions/libct_proto_udp.la \ + ../extensions/libct_proto_udplite.la \ + ../extensions/libct_proto_unknown.la \ + ${LIBMNL_LIBS} \ + ${LIBNETFILTER_CONNTRACK_LIBS} \ + ${LIBNFNETLINK_LIBS} nfct_SOURCES = nfct.c @@ -35,22 +46,54 @@ if HAVE_CTHELPER nfct_LDADD += ${LIBNETFILTER_CTHELPER_LIBS} endif -conntrackd_SOURCES = alarm.c main.c run.c hash.c queue.c queue_tx.c rbtree.c \ - local.c log.c mcast.c udp.c netlink.c vector.c \ - filter.c fds.c event.c process.c origin.c date.c \ - cache.c cache-ct.c cache-exp.c \ - cache_timer.c \ - ctnl.c \ - sync-mode.c sync-alarm.c sync-ftfw.c sync-notrack.c \ - traffic_stats.c stats-mode.c \ - network.c cidr.c \ - build.c parse.c \ - channel.c multichannel.c channel_mcast.c channel_udp.c \ - tcp.c channel_tcp.c \ - external_cache.c external_inject.c \ - internal_cache.c internal_bypass.c \ - read_config_yy.y read_config_lex.l \ - stack.c resync.c +conntrackd_SOURCES = alarm.c \ + build.c \ + cache.c \ + cache-ct.c \ + cache-exp.c \ + cache_timer.c \ + channel.c \ + channel_mcast.c \ + channel_tcp.c \ + channel_udp.c \ + cidr.c \ + ctnl.c \ + date.c \ + event.c \ + external_cache.c \ + external_inject.c \ + fds.c \ + filter.c \ + hash.c \ + internal_bypass.c \ + internal_cache.c \ + local.c \ + log.c \ + main.c \ + mcast.c \ + multichannel.c \ + netlink.c \ + network.c \ + origin.c \ + parse.c \ + process.c \ + queue.c \ + queue_tx.c \ + rbtree.c \ + read_config_lex.l \ + read_config_yy.y \ + resync.c \ + run.c \ + stack.c \ + stats-mode.c \ + sync-alarm.c \ + sync-ftfw.c \ + sync-mode.c \ + sync-notrack.c \ + tcp.c \ + traffic_stats.c \ + udp.c \ + vector.c if HAVE_CTHELPER conntrackd_SOURCES += cthelper.c helpers.c utils.c expect.c @@ -60,9 +103,6 @@ if HAVE_SYSTEMD conntrackd_SOURCES += systemd.c endif -# yacc and lex generate dirty code -read_config_yy.o read_config_lex.o: AM_CFLAGS += -Wno-incompatible-pointer-types -Wno-discarded-qualifiers - conntrackd_LDADD = ${LIBMNL_LIBS} ${LIBNETFILTER_CONNTRACK_LIBS} \ ${libdl_LIBS} ${LIBNFNETLINK_LIBS} diff --git a/src/channel.c b/src/channel.c index acbfa7d..0b89391 100644 --- a/src/channel.c +++ b/src/channel.c @@ -56,7 +56,7 @@ channel_buffer_open(int mtu, int headersiz) { struct channel_buffer *b; - b = calloc(sizeof(struct channel_buffer), 1); + b = calloc(1, sizeof(struct channel_buffer)); if (b == NULL) return NULL; @@ -94,7 +94,7 @@ channel_open(struct channel_conf *cfg) if (cfg->channel_flags >= CHANNEL_F_MAX) return NULL; - c = calloc(sizeof(struct channel), 1); + c = calloc(1, sizeof(struct channel)); if (c == NULL) return NULL; diff --git a/src/channel_mcast.c b/src/channel_mcast.c index 35801d7..9c9dc62 100644 --- a/src/channel_mcast.c +++ b/src/channel_mcast.c @@ -19,7 +19,7 @@ static void struct mcast_channel *m; struct mcast_conf *c = conf; - m = calloc(sizeof(struct mcast_channel), 1); + m = calloc(1, sizeof(struct mcast_channel)); if (m == NULL) return NULL; diff --git a/src/channel_tcp.c b/src/channel_tcp.c index a84603c..173c47a 100644 --- a/src/channel_tcp.c +++ b/src/channel_tcp.c @@ -21,7 +21,7 @@ static void struct tcp_channel *m; struct tcp_conf *c = conf; - m = calloc(sizeof(struct tcp_channel), 1); + m = calloc(1, sizeof(struct tcp_channel)); if (m == NULL) return NULL; diff --git a/src/channel_udp.c b/src/channel_udp.c index a46a2b1..3b3d754 100644 --- a/src/channel_udp.c +++ b/src/channel_udp.c @@ -19,7 +19,7 @@ static void struct udp_channel *m; struct udp_conf *c = conf; - m = calloc(sizeof(struct udp_channel), 1); + m = calloc(1, sizeof(struct udp_channel)); if (m == NULL) return NULL; diff --git a/src/conntrack.c b/src/conntrack.c index 2bd71e1..2d4e864 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) @@ -335,7 +337,7 @@ static struct option original_opts[] = { {0, 0, 0, 0} }; -static const char *getopt_str = ":L::I::U::D::G::E::F::A::hVs:d:r:q:" +static const char *getopt_str = ":LIUDGEFAhVs:d:r:q:" "p:t:u:e:a:z[:]:{:}:m:i:f:o:n::" "g::c:b:C::Sj::w:l:<:>::(:):"; @@ -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" @@ -1211,17 +1213,55 @@ parse_parameter_mask(const char *arg, unsigned int *status, unsigned int *mask, exit_error(PARAMETER_PROBLEM, "Bad parameter `%s'", arg); } -static void +static int parse_value(const char *str, uint32_t *ret, uint64_t max) +{ + char *endptr; + uint64_t val; + + assert(max <= UINT32_MAX); + + errno = 0; + val = strtoul(str, &endptr, 0); + if (endptr == str || + *endptr != '\0' || + (val == ULONG_MAX && errno == ERANGE) || + val > max) + return -1; + + *ret = val; + + return 0; +} + +static int parse_u32_mask(const char *arg, struct u32_mask *m) { - char *end; + uint64_t val, mask; + char *endptr; + + val = strtoul(arg, &endptr, 0); + if (endptr == arg || + (*endptr != '\0' && *endptr != '/') || + (val == ULONG_MAX && errno == ERANGE) || + val > UINT32_MAX) + return -1; - m->value = (uint32_t) strtoul(arg, &end, 0); + m->value = val; - if (*end == '/') - m->mask = (uint32_t) strtoul(end+1, NULL, 0); - else + if (*endptr == '/') { + mask = strtoul(endptr + 1, &endptr, 0); + if (endptr == arg || + *endptr != '\0' || + (val == ULONG_MAX && errno == ERANGE) || + val > UINT32_MAX) + return -1; + + m->mask = mask; + } else { m->mask = ~0; + } + + return 0; } static int @@ -1874,6 +1914,25 @@ static char *get_progname(uint32_t portid) return NULL; } +static void event_print_timestamp(const struct nf_conntrack *ct) +{ + struct timeval tv; + + /* nfct_attr_is_set returns -1 if attr is unknown */ + if (nfct_attr_is_set(ct, ATTR_TIMESTAMP_EVENT) > 0) { + uint64_t event_ts = nfct_get_attr_u64(ct, ATTR_TIMESTAMP_EVENT); + static const uint64_t ns_per_s = 1000000000ul; + static const uint64_t ns_to_usec = 1000ul; + + tv.tv_sec = event_ts / ns_per_s; + tv.tv_usec = (event_ts % ns_per_s) / ns_to_usec; + } else { + gettimeofday(&tv, NULL); + } + + printf("[%-.8ld.%-.6ld]\t", tv.tv_sec, tv.tv_usec); +} + static int event_cb(const struct nlmsghdr *nlh, void *data) { struct nfgenmsg *nfh = mnl_nlmsg_get_payload(nlh); @@ -1929,9 +1988,7 @@ static int event_cb(const struct nlmsghdr *nlh, void *data) op_flags = NFCT_OF_SHOW_LAYER3; 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); + event_print_timestamp(ct); } else op_flags |= NFCT_OF_TIME; } @@ -1942,7 +1999,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 +2044,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 destroy_ok; 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 +2243,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 +2956,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; } @@ -2901,6 +2973,7 @@ static void do_parse(struct ct_cmd *ct_cmd, int argc, char *argv[]) struct ct_tmpl *tmpl; int res = 0, partial; union ct_address ad; + uint32_t value; int c, cmd; /* we release these objects in the exit_error() path. */ @@ -3005,8 +3078,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': @@ -3062,21 +3134,25 @@ static void do_parse(struct ct_cmd *ct_cmd, int argc, char *argv[]) case 'w': case '(': case ')': + if (parse_value(optarg, &value, UINT16_MAX) < 0) + exit_error(OTHER_PROBLEM, "unexpected value '%s' with -%c option", optarg, c); + options |= opt2type[c]; - nfct_set_attr_u16(tmpl->ct, - opt2attr[c], - strtoul(optarg, NULL, 0)); + nfct_set_attr_u16(tmpl->ct, opt2attr[c], value); break; case 'i': case 'c': + if (parse_value(optarg, &value, UINT32_MAX) < 0) + exit_error(OTHER_PROBLEM, "unexpected value '%s' with -%c option", optarg, c); + options |= opt2type[c]; - nfct_set_attr_u32(tmpl->ct, - opt2attr[c], - strtoul(optarg, NULL, 0)); + nfct_set_attr_u32(tmpl->ct, opt2attr[c], value); break; case 'm': options |= opt2type[c]; - parse_u32_mask(optarg, &tmpl->mark); + if (parse_u32_mask(optarg, &tmpl->mark) < 0) + exit_error(OTHER_PROBLEM, "unexpected value '%s' with -%c option", optarg, c); + tmpl->filter_mark_kernel.val = tmpl->mark.value; tmpl->filter_mark_kernel.mask = tmpl->mark.mask; tmpl->filter_mark_kernel_set = true; @@ -3217,6 +3293,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 +3380,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 +3453,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 +3911,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); @@ -30,7 +30,7 @@ struct fds *create_fds(void) { struct fds *fds; - fds = (struct fds *) calloc(sizeof(struct fds), 1); + fds = calloc(1, sizeof(struct fds)); if (fds == NULL) return NULL; @@ -60,7 +60,7 @@ int register_fd(int fd, void (*cb)(void *data), void *data, struct fds *fds) if (fd > fds->maxfd) fds->maxfd = fd; - item = calloc(sizeof(struct fds_item), 1); + item = calloc(1, sizeof(struct fds_item)); if (item == NULL) return -1; diff --git a/src/filter.c b/src/filter.c index ee316e7..e863ea9 100644 --- a/src/filter.c +++ b/src/filter.c @@ -77,7 +77,7 @@ struct ct_filter *ct_filter_create(void) int i; struct ct_filter *filter; - filter = calloc(sizeof(struct ct_filter), 1); + filter = calloc(1, sizeof(struct ct_filter)); if (!filter) return NULL; diff --git a/src/helpers/rpc.c b/src/helpers/rpc.c index 732e9ba..d8e4903 100644 --- a/src/helpers/rpc.c +++ b/src/helpers/rpc.c @@ -399,6 +399,11 @@ rpc_helper_cb(struct pkt_buff *pkt, uint32_t protoff, xid, rpc_info->xid); goto out; } + /* Ignore portmap program number */ + if (rpc_info->pm_prog == PMAPPROG) { + pr_debug("RPC REPL: ignore portmap program number %lu\n", PMAPPROG); + goto out; + } if (rpc_reply(data, offset, datalen, rpc_info, &port_ptr) < 0) goto out; @@ -175,7 +175,7 @@ int main(int argc, char *argv[]) } show_usage(argv[0]); dlog(LOG_ERR, "Missing config filename"); - break; + exit(EXIT_FAILURE); case 'F': set_operation_mode(&type, REQUEST, argv); i = set_action_by_table(i, argc, argv, @@ -309,8 +309,7 @@ int main(int argc, char *argv[]) default: show_usage(argv[0]); dlog(LOG_ERR, "Unknown option: %s", argv[i]); - return 0; - break; + exit(EXIT_FAILURE); } } diff --git a/src/multichannel.c b/src/multichannel.c index 952b567..25a9908 100644 --- a/src/multichannel.c +++ b/src/multichannel.c @@ -21,7 +21,7 @@ multichannel_open(struct channel_conf *conf, int len) if (len <= 0 || len > MULTICHANNEL_MAX) return NULL; - m = calloc(sizeof(struct multichannel), 1); + m = calloc(1, sizeof(struct multichannel)); if (m == NULL) return NULL; diff --git a/src/origin.c b/src/origin.c index 3c65f3d..e44ffa0 100644 --- a/src/origin.c +++ b/src/origin.c @@ -31,7 +31,7 @@ int origin_register(struct nfct_handle *h, int origin_type) { struct origin *nlp; - nlp = calloc(sizeof(struct origin), 1); + nlp = calloc(1, sizeof(struct origin)); if (nlp == NULL) return -1; diff --git a/src/process.c b/src/process.c index 08598ee..47f14da 100644 --- a/src/process.c +++ b/src/process.c @@ -37,7 +37,7 @@ int fork_process_new(int type, int flags, void (*cb)(void *data), void *data) } } } - c = calloc(sizeof(struct child_process), 1); + c = calloc(1, sizeof(struct child_process)); if (c == NULL) return -1; diff --git a/src/queue.c b/src/queue.c index e94dc7c..cab754b 100644 --- a/src/queue.c +++ b/src/queue.c @@ -33,7 +33,7 @@ queue_create(const char *name, int max_objects, unsigned int flags) { struct queue *b; - b = calloc(sizeof(struct queue), 1); + b = calloc(1, sizeof(struct queue)); if (b == NULL) return NULL; diff --git a/src/read_config_yy.y b/src/read_config_yy.y index f06c6af..a116b0b 100644 --- a/src/read_config_yy.y +++ b/src/read_config_yy.y @@ -47,14 +47,24 @@ extern char *yytext; extern int yylineno; int yylex (void); -int yyerror (char *msg); +int yyerror (const char *msg); void yyrestart (FILE *input_file); struct ct_conf conf; static void __kernel_filter_start(void); static void __kernel_filter_add_state(int value); -static void __max_dedicated_links_reached(void); + +static struct channel_conf *conf_get_channel(void) +{ + if (conf.channel_num >= MULTICHANNEL_MAX) { + dlog(LOG_ERR, "too many dedicated links in the configuration " + "file (Maximum: %d)", MULTICHANNEL_MAX); + exit(EXIT_FAILURE); + } + + return &conf.channel[conf.channel_num]; +} struct stack symbol_stack; @@ -213,6 +223,8 @@ purge: T_PURGE T_NUMBER multicast_line : T_MULTICAST '{' multicast_options '}' { + struct channel_conf *channel_conf = conf_get_channel(); + if (conf.channel_type_global != CHANNEL_NONE && conf.channel_type_global != CHANNEL_MCAST) { dlog(LOG_ERR, "cannot use `Multicast' with other " @@ -220,13 +232,15 @@ multicast_line : T_MULTICAST '{' multicast_options '}' exit(EXIT_FAILURE); } conf.channel_type_global = CHANNEL_MCAST; - conf.channel[conf.channel_num].channel_type = CHANNEL_MCAST; - conf.channel[conf.channel_num].channel_flags = CHANNEL_F_BUFFERED; + channel_conf->channel_type = CHANNEL_MCAST; + channel_conf->channel_flags = CHANNEL_F_BUFFERED; conf.channel_num++; }; multicast_line : T_MULTICAST T_DEFAULT '{' multicast_options '}' { + struct channel_conf *channel_conf = conf_get_channel(); + if (conf.channel_type_global != CHANNEL_NONE && conf.channel_type_global != CHANNEL_MCAST) { dlog(LOG_ERR, "cannot use `Multicast' with other " @@ -234,9 +248,8 @@ multicast_line : T_MULTICAST T_DEFAULT '{' multicast_options '}' exit(EXIT_FAILURE); } conf.channel_type_global = CHANNEL_MCAST; - conf.channel[conf.channel_num].channel_type = CHANNEL_MCAST; - conf.channel[conf.channel_num].channel_flags = CHANNEL_F_DEFAULT | - CHANNEL_F_BUFFERED; + channel_conf->channel_type = CHANNEL_MCAST; + channel_conf->channel_flags = CHANNEL_F_DEFAULT | CHANNEL_F_BUFFERED; conf.channel_default = conf.channel_num; conf.channel_num++; }; @@ -246,15 +259,15 @@ multicast_options : multicast_option : T_IPV4_ADDR T_IP { - __max_dedicated_links_reached(); + struct channel_conf *channel_conf = conf_get_channel(); - if (!inet_aton($2, &conf.channel[conf.channel_num].u.mcast.in)) { + if (!inet_aton($2, &channel_conf->u.mcast.in.inet_addr)) { dlog(LOG_WARNING, "%s is not a valid IPv4 address", $2); free($2); break; } - if (conf.channel[conf.channel_num].u.mcast.ipproto == AF_INET6) { + if (channel_conf->u.mcast.ipproto == AF_INET6) { dlog(LOG_WARNING, "your multicast address is IPv4 but " "is binded to an IPv6 interface? " "Surely, this is not what you want"); @@ -262,16 +275,15 @@ multicast_option : T_IPV4_ADDR T_IP } free($2); - conf.channel[conf.channel_num].u.mcast.ipproto = AF_INET; + channel_conf->u.mcast.ipproto = AF_INET; }; multicast_option : T_IPV6_ADDR T_IP { - __max_dedicated_links_reached(); + struct channel_conf *channel_conf = conf_get_channel(); int err; - err = inet_pton(AF_INET6, $2, - &conf.channel[conf.channel_num].u.mcast.in); + err = inet_pton(AF_INET6, $2, &channel_conf->u.mcast.in); if (err == 0) { dlog(LOG_WARNING, "%s is not a valid IPv6 address", $2); free($2); @@ -281,7 +293,7 @@ multicast_option : T_IPV6_ADDR T_IP exit(EXIT_FAILURE); } - if (conf.channel[conf.channel_num].u.mcast.ipproto == AF_INET) { + if (channel_conf->u.mcast.ipproto == AF_INET) { dlog(LOG_WARNING, "your multicast address is IPv6 but " "is binded to an IPv4 interface? " "Surely this is not what you want"); @@ -289,10 +301,10 @@ multicast_option : T_IPV6_ADDR T_IP break; } - conf.channel[conf.channel_num].u.mcast.ipproto = AF_INET6; + channel_conf->u.mcast.ipproto = AF_INET6; - if (conf.channel[conf.channel_num].channel_ifname[0] && - !conf.channel[conf.channel_num].u.mcast.ifa.interface_index6) { + if (channel_conf->channel_ifname[0] && + !channel_conf->u.mcast.ifa.interface_index6) { unsigned int idx; idx = if_nametoindex($2); @@ -302,31 +314,31 @@ multicast_option : T_IPV6_ADDR T_IP break; } - conf.channel[conf.channel_num].u.mcast.ifa.interface_index6 = idx; - conf.channel[conf.channel_num].u.mcast.ipproto = AF_INET6; + channel_conf->u.mcast.ifa.interface_index6 = idx; + channel_conf->u.mcast.ipproto = AF_INET6; } free($2); }; multicast_option : T_IPV4_IFACE T_IP { - __max_dedicated_links_reached(); + struct channel_conf *channel_conf = conf_get_channel(); - if (!inet_aton($2, &conf.channel[conf.channel_num].u.mcast.ifa)) { + if (!inet_aton($2, &channel_conf->u.mcast.ifa.interface_addr)) { dlog(LOG_WARNING, "%s is not a valid IPv4 address", $2); free($2); break; } free($2); - if (conf.channel[conf.channel_num].u.mcast.ipproto == AF_INET6) { + if (channel_conf->u.mcast.ipproto == AF_INET6) { dlog(LOG_WARNING, "your multicast interface is IPv4 but " "is binded to an IPv6 interface? " "Surely, this is not what you want"); break; } - conf.channel[conf.channel_num].u.mcast.ipproto = AF_INET; + channel_conf->u.mcast.ipproto = AF_INET; }; multicast_option : T_IPV6_IFACE T_IP @@ -337,11 +349,10 @@ multicast_option : T_IPV6_IFACE T_IP multicast_option : T_IFACE T_STRING { + struct channel_conf *channel_conf = conf_get_channel(); unsigned int idx; - __max_dedicated_links_reached(); - - strncpy(conf.channel[conf.channel_num].channel_ifname, $2, IFNAMSIZ); + strncpy(channel_conf->channel_ifname, $2, IFNAMSIZ); idx = if_nametoindex($2); if (!idx) { @@ -350,9 +361,9 @@ multicast_option : T_IFACE T_STRING break; } - if (conf.channel[conf.channel_num].u.mcast.ipproto == AF_INET6) { - conf.channel[conf.channel_num].u.mcast.ifa.interface_index6 = idx; - conf.channel[conf.channel_num].u.mcast.ipproto = AF_INET6; + if (channel_conf->u.mcast.ipproto == AF_INET6) { + channel_conf->u.mcast.ifa.interface_index6 = idx; + channel_conf->u.mcast.ipproto = AF_INET6; } free($2); @@ -360,36 +371,43 @@ multicast_option : T_IFACE T_STRING multicast_option : T_GROUP T_NUMBER { - __max_dedicated_links_reached(); - conf.channel[conf.channel_num].u.mcast.port = $2; + struct channel_conf *channel_conf = conf_get_channel(); + + channel_conf->u.mcast.port = $2; }; multicast_option: T_SNDBUFF T_NUMBER { - __max_dedicated_links_reached(); - conf.channel[conf.channel_num].u.mcast.sndbuf = $2; + struct channel_conf *channel_conf = conf_get_channel(); + + channel_conf->u.mcast.sndbuf = $2; }; multicast_option: T_RCVBUFF T_NUMBER { - __max_dedicated_links_reached(); - conf.channel[conf.channel_num].u.mcast.rcvbuf = $2; + struct channel_conf *channel_conf = conf_get_channel(); + + channel_conf->u.mcast.rcvbuf = $2; }; -multicast_option: T_CHECKSUM T_ON +multicast_option: T_CHECKSUM T_ON { - __max_dedicated_links_reached(); - conf.channel[conf.channel_num].u.mcast.checksum = 0; + struct channel_conf *channel_conf = conf_get_channel(); + + channel_conf->u.mcast.checksum = 0; }; multicast_option: T_CHECKSUM T_OFF { - __max_dedicated_links_reached(); - conf.channel[conf.channel_num].u.mcast.checksum = 1; + struct channel_conf *channel_conf = conf_get_channel(); + + channel_conf->u.mcast.checksum = 1; }; udp_line : T_UDP '{' udp_options '}' { + struct channel_conf *channel_conf = conf_get_channel(); + if (conf.channel_type_global != CHANNEL_NONE && conf.channel_type_global != CHANNEL_UDP) { dlog(LOG_ERR, "cannot use `UDP' with other " @@ -397,13 +415,15 @@ udp_line : T_UDP '{' udp_options '}' exit(EXIT_FAILURE); } conf.channel_type_global = CHANNEL_UDP; - conf.channel[conf.channel_num].channel_type = CHANNEL_UDP; - conf.channel[conf.channel_num].channel_flags = CHANNEL_F_BUFFERED; + channel_conf->channel_type = CHANNEL_UDP; + channel_conf->channel_flags = CHANNEL_F_BUFFERED; conf.channel_num++; }; udp_line : T_UDP T_DEFAULT '{' udp_options '}' { + struct channel_conf *channel_conf = conf_get_channel(); + if (conf.channel_type_global != CHANNEL_NONE && conf.channel_type_global != CHANNEL_UDP) { dlog(LOG_ERR, "cannot use `UDP' with other " @@ -411,9 +431,8 @@ udp_line : T_UDP T_DEFAULT '{' udp_options '}' exit(EXIT_FAILURE); } conf.channel_type_global = CHANNEL_UDP; - conf.channel[conf.channel_num].channel_type = CHANNEL_UDP; - conf.channel[conf.channel_num].channel_flags = CHANNEL_F_DEFAULT | - CHANNEL_F_BUFFERED; + channel_conf->channel_type = CHANNEL_UDP; + channel_conf->channel_flags = CHANNEL_F_DEFAULT | CHANNEL_F_BUFFERED; conf.channel_default = conf.channel_num; conf.channel_num++; }; @@ -423,24 +442,23 @@ udp_options : udp_option : T_IPV4_ADDR T_IP { - __max_dedicated_links_reached(); + struct channel_conf *channel_conf = conf_get_channel(); - if (!inet_aton($2, &conf.channel[conf.channel_num].u.udp.server.ipv4)) { + if (!inet_aton($2, &channel_conf->u.udp.server.ipv4.inet_addr)) { dlog(LOG_WARNING, "%s is not a valid IPv4 address", $2); free($2); break; } free($2); - conf.channel[conf.channel_num].u.udp.ipproto = AF_INET; + channel_conf->u.udp.ipproto = AF_INET; }; udp_option : T_IPV6_ADDR T_IP { - __max_dedicated_links_reached(); + struct channel_conf *channel_conf = conf_get_channel(); int err; - err = inet_pton(AF_INET6, $2, - &conf.channel[conf.channel_num].u.udp.server.ipv6); + err = inet_pton(AF_INET6, $2, &channel_conf->u.udp.server.ipv6); if (err == 0) { dlog(LOG_WARNING, "%s is not a valid IPv6 address", $2); free($2); @@ -451,29 +469,28 @@ udp_option : T_IPV6_ADDR T_IP } free($2); - conf.channel[conf.channel_num].u.udp.ipproto = AF_INET6; + channel_conf->u.udp.ipproto = AF_INET6; }; udp_option : T_IPV4_DEST_ADDR T_IP { - __max_dedicated_links_reached(); + struct channel_conf *channel_conf = conf_get_channel(); - if (!inet_aton($2, &conf.channel[conf.channel_num].u.udp.client)) { + if (!inet_aton($2, &channel_conf->u.udp.client.inet_addr)) { dlog(LOG_WARNING, "%s is not a valid IPv4 address", $2); free($2); break; } free($2); - conf.channel[conf.channel_num].u.udp.ipproto = AF_INET; + channel_conf->u.udp.ipproto = AF_INET; }; udp_option : T_IPV6_DEST_ADDR T_IP { - __max_dedicated_links_reached(); + struct channel_conf *channel_conf = conf_get_channel(); int err; - err = inet_pton(AF_INET6, $2, - &conf.channel[conf.channel_num].u.udp.client); + err = inet_pton(AF_INET6, $2, &channel_conf->u.udp.client); if (err == 0) { dlog(LOG_WARNING, "%s is not a valid IPv6 address", $2); free($2); @@ -484,15 +501,15 @@ udp_option : T_IPV6_DEST_ADDR T_IP } free($2); - conf.channel[conf.channel_num].u.udp.ipproto = AF_INET6; + channel_conf->u.udp.ipproto = AF_INET6; }; udp_option : T_IFACE T_STRING { + struct channel_conf *channel_conf = conf_get_channel(); int idx; - __max_dedicated_links_reached(); - strncpy(conf.channel[conf.channel_num].channel_ifname, $2, IFNAMSIZ); + strncpy(channel_conf->channel_ifname, $2, IFNAMSIZ); idx = if_nametoindex($2); if (!idx) { @@ -500,43 +517,50 @@ udp_option : T_IFACE T_STRING free($2); break; } - conf.channel[conf.channel_num].u.udp.server.ipv6.scope_id = idx; + channel_conf->u.udp.server.ipv6.scope_id = idx; free($2); }; udp_option : T_PORT T_NUMBER { - __max_dedicated_links_reached(); - conf.channel[conf.channel_num].u.udp.port = $2; + struct channel_conf *channel_conf = conf_get_channel(); + + channel_conf->u.udp.port = $2; }; udp_option: T_SNDBUFF T_NUMBER { - __max_dedicated_links_reached(); - conf.channel[conf.channel_num].u.udp.sndbuf = $2; + struct channel_conf *channel_conf = conf_get_channel(); + + channel_conf->u.udp.sndbuf = $2; }; udp_option: T_RCVBUFF T_NUMBER { - __max_dedicated_links_reached(); - conf.channel[conf.channel_num].u.udp.rcvbuf = $2; + struct channel_conf *channel_conf = conf_get_channel(); + + channel_conf->u.udp.rcvbuf = $2; }; -udp_option: T_CHECKSUM T_ON +udp_option: T_CHECKSUM T_ON { - __max_dedicated_links_reached(); - conf.channel[conf.channel_num].u.udp.checksum = 0; + struct channel_conf *channel_conf = conf_get_channel(); + + channel_conf->u.udp.checksum = 0; }; udp_option: T_CHECKSUM T_OFF { - __max_dedicated_links_reached(); - conf.channel[conf.channel_num].u.udp.checksum = 1; + struct channel_conf *channel_conf = conf_get_channel(); + + channel_conf->u.udp.checksum = 1; }; tcp_line : T_TCP '{' tcp_options '}' { + struct channel_conf *channel_conf = conf_get_channel(); + if (conf.channel_type_global != CHANNEL_NONE && conf.channel_type_global != CHANNEL_TCP) { dlog(LOG_ERR, "cannot use `TCP' with other " @@ -544,15 +568,17 @@ tcp_line : T_TCP '{' tcp_options '}' exit(EXIT_FAILURE); } conf.channel_type_global = CHANNEL_TCP; - conf.channel[conf.channel_num].channel_type = CHANNEL_TCP; - conf.channel[conf.channel_num].channel_flags = CHANNEL_F_BUFFERED | - CHANNEL_F_STREAM | - CHANNEL_F_ERRORS; + channel_conf->channel_type = CHANNEL_TCP; + channel_conf->channel_flags = CHANNEL_F_BUFFERED | + CHANNEL_F_STREAM | + CHANNEL_F_ERRORS; conf.channel_num++; }; tcp_line : T_TCP T_DEFAULT '{' tcp_options '}' { + struct channel_conf *channel_conf = conf_get_channel(); + if (conf.channel_type_global != CHANNEL_NONE && conf.channel_type_global != CHANNEL_TCP) { dlog(LOG_ERR, "cannot use `TCP' with other " @@ -560,11 +586,11 @@ tcp_line : T_TCP T_DEFAULT '{' tcp_options '}' exit(EXIT_FAILURE); } conf.channel_type_global = CHANNEL_TCP; - conf.channel[conf.channel_num].channel_type = CHANNEL_TCP; - conf.channel[conf.channel_num].channel_flags = CHANNEL_F_DEFAULT | - CHANNEL_F_BUFFERED | - CHANNEL_F_STREAM | - CHANNEL_F_ERRORS; + channel_conf->channel_type = CHANNEL_TCP; + channel_conf->channel_flags = CHANNEL_F_DEFAULT | + CHANNEL_F_BUFFERED | + CHANNEL_F_STREAM | + CHANNEL_F_ERRORS; conf.channel_default = conf.channel_num; conf.channel_num++; }; @@ -574,24 +600,23 @@ tcp_options : tcp_option : T_IPV4_ADDR T_IP { - __max_dedicated_links_reached(); + struct channel_conf *channel_conf = conf_get_channel(); - if (!inet_aton($2, &conf.channel[conf.channel_num].u.tcp.server.ipv4)) { + if (!inet_aton($2, &channel_conf->u.tcp.server.ipv4.inet_addr)) { dlog(LOG_WARNING, "%s is not a valid IPv4 address", $2); free($2); break; } free($2); - conf.channel[conf.channel_num].u.tcp.ipproto = AF_INET; + channel_conf->u.tcp.ipproto = AF_INET; }; tcp_option : T_IPV6_ADDR T_IP { - __max_dedicated_links_reached(); + struct channel_conf *channel_conf = conf_get_channel(); int err; - err = inet_pton(AF_INET6, $2, - &conf.channel[conf.channel_num].u.tcp.server.ipv6); + err = inet_pton(AF_INET6, $2, &channel_conf->u.tcp.server.ipv6); if (err == 0) { dlog(LOG_WARNING, "%s is not a valid IPv6 address", $2); free($2); @@ -602,29 +627,28 @@ tcp_option : T_IPV6_ADDR T_IP } free($2); - conf.channel[conf.channel_num].u.tcp.ipproto = AF_INET6; + channel_conf->u.tcp.ipproto = AF_INET6; }; tcp_option : T_IPV4_DEST_ADDR T_IP { - __max_dedicated_links_reached(); + struct channel_conf *channel_conf = conf_get_channel(); - if (!inet_aton($2, &conf.channel[conf.channel_num].u.tcp.client)) { + if (!inet_aton($2, &channel_conf->u.tcp.client.inet_addr)) { dlog(LOG_WARNING, "%s is not a valid IPv4 address", $2); free($2); break; } free($2); - conf.channel[conf.channel_num].u.tcp.ipproto = AF_INET; + channel_conf->u.tcp.ipproto = AF_INET; }; tcp_option : T_IPV6_DEST_ADDR T_IP { - __max_dedicated_links_reached(); + struct channel_conf *channel_conf = conf_get_channel(); int err; - err = inet_pton(AF_INET6, $2, - &conf.channel[conf.channel_num].u.tcp.client); + err = inet_pton(AF_INET6, $2, &channel_conf->u.tcp.client); if (err == 0) { dlog(LOG_WARNING, "%s is not a valid IPv6 address", $2); free($2); @@ -635,15 +659,15 @@ tcp_option : T_IPV6_DEST_ADDR T_IP } free($2); - conf.channel[conf.channel_num].u.tcp.ipproto = AF_INET6; + channel_conf->u.tcp.ipproto = AF_INET6; }; tcp_option : T_IFACE T_STRING { + struct channel_conf *channel_conf = conf_get_channel(); int idx; - __max_dedicated_links_reached(); - strncpy(conf.channel[conf.channel_num].channel_ifname, $2, IFNAMSIZ); + strncpy(channel_conf->channel_ifname, $2, IFNAMSIZ); idx = if_nametoindex($2); if (!idx) { @@ -651,44 +675,48 @@ tcp_option : T_IFACE T_STRING free($2); break; } - conf.channel[conf.channel_num].u.tcp.server.ipv6.scope_id = idx; + channel_conf->u.tcp.server.ipv6.scope_id = idx; free($2); }; tcp_option : T_PORT T_NUMBER { - __max_dedicated_links_reached(); - conf.channel[conf.channel_num].u.tcp.port = $2; + struct channel_conf *channel_conf = conf_get_channel(); + + channel_conf->u.tcp.port = $2; }; tcp_option: T_SNDBUFF T_NUMBER { - __max_dedicated_links_reached(); - conf.channel[conf.channel_num].u.tcp.sndbuf = $2; + struct channel_conf *channel_conf = conf_get_channel(); + + channel_conf->u.tcp.sndbuf = $2; }; tcp_option: T_RCVBUFF T_NUMBER { - __max_dedicated_links_reached(); - conf.channel[conf.channel_num].u.tcp.rcvbuf = $2; + struct channel_conf *channel_conf = conf_get_channel(); + + channel_conf->u.tcp.rcvbuf = $2; }; -tcp_option: T_CHECKSUM T_ON +tcp_option: T_CHECKSUM T_ON { - __max_dedicated_links_reached(); - conf.channel[conf.channel_num].u.tcp.checksum = 0; + struct channel_conf *channel_conf = conf_get_channel(); + + channel_conf->u.tcp.checksum = 0; }; tcp_option: T_CHECKSUM T_OFF { - __max_dedicated_links_reached(); - conf.channel[conf.channel_num].u.tcp.checksum = 1; + struct channel_conf *channel_conf = conf_get_channel(); + + channel_conf->u.tcp.checksum = 1; }; tcp_option: T_ERROR_QUEUE_LENGTH T_NUMBER { - __max_dedicated_links_reached(); CONFIG(channelc).error_queue_length = $2; }; @@ -1239,7 +1267,7 @@ filter_address_item : T_IPV4_ADDR T_IP } } - if (!inet_aton($2, &ip.ipv4)) { + if (!inet_aton($2, (struct in_addr *) &ip.ipv4)) { dlog(LOG_WARNING, "%s is not a valid IPv4, ignoring", $2); free($2); break; @@ -1681,7 +1709,7 @@ helper_policy_expect_timeout: T_HELPER_EXPECT_TIMEOUT T_NUMBER %% int __attribute__((noreturn)) -yyerror(char *msg) +yyerror(const char *msg) { dlog(LOG_ERR, "parsing config file in line (%d), symbol '%s': %s", yylineno, yytext, msg); @@ -1712,15 +1740,6 @@ static void __kernel_filter_add_state(int value) &filter_proto); } -static void __max_dedicated_links_reached(void) -{ - if (conf.channel_num >= MULTICHANNEL_MAX) { - dlog(LOG_ERR, "too many dedicated links in the configuration " - "file (Maximum: %d)", MULTICHANNEL_MAX); - exit(EXIT_FAILURE); - } -} - int init_config(char *filename) { @@ -277,6 +277,18 @@ init(void) } register_fd(STATE(local).fd, local_cb, NULL, STATE(fds)); + /* Initialization */ + if (CONFIG(flags) & (CTD_SYNC_MODE | CTD_STATS_MODE)) + if (ctnl_init() < 0) + return -1; + +#ifdef BUILD_CTHELPER + if (CONFIG(flags) & CTD_HELPER) { + if (cthelper_init() < 0) + return -1; + } +#endif + /* Signals handling */ sigemptyset(&STATE(block)); sigaddset(&STATE(block), SIGTERM); @@ -296,17 +308,6 @@ init(void) if (signal(SIGCHLD, child) == SIG_ERR) return -1; - /* Initialization */ - if (CONFIG(flags) & (CTD_SYNC_MODE | CTD_STATS_MODE)) - if (ctnl_init() < 0) - return -1; - -#ifdef BUILD_CTHELPER - if (CONFIG(flags) & CTD_HELPER) { - if (cthelper_init() < 0) - return -1; - } -#endif time(&STATE(stats).daemon_start_time); dlog(LOG_NOTICE, "initialization completed"); @@ -31,7 +31,7 @@ struct tcp_sock *tcp_server_create(struct tcp_conf *c) struct tcp_sock *m; socklen_t socklen = sizeof(int); - m = calloc(sizeof(struct tcp_sock), 1); + m = calloc(1, sizeof(struct tcp_sock)); if (m == NULL) return NULL; @@ -209,7 +209,7 @@ struct tcp_sock *tcp_client_create(struct tcp_conf *c) { struct tcp_sock *m; - m = calloc(sizeof(struct tcp_sock), 1); + m = calloc(1, sizeof(struct tcp_sock)); if (m == NULL) return NULL; @@ -25,7 +25,7 @@ struct udp_sock *udp_server_create(struct udp_conf *conf) struct udp_sock *m; socklen_t socklen = sizeof(int); - m = calloc(sizeof(struct udp_sock), 1); + m = calloc(1, sizeof(struct udp_sock)); if (m == NULL) return NULL; @@ -97,7 +97,7 @@ struct udp_sock *udp_client_create(struct udp_conf *conf) struct udp_sock *m; socklen_t socklen = sizeof(int); - m = calloc(sizeof(struct udp_sock), 1); + m = calloc(1, sizeof(struct udp_sock)); if (m == NULL) return NULL; diff --git a/src/vector.c b/src/vector.c index c81e7ce..29e8fbe 100644 --- a/src/vector.c +++ b/src/vector.c @@ -35,7 +35,7 @@ struct vector *vector_create(size_t size) { struct vector *v; - v = calloc(sizeof(struct vector), 1); + v = calloc(1, sizeof(struct vector)); if (v == NULL) return NULL; @@ -60,13 +60,16 @@ void vector_destroy(struct vector *v) int vector_add(struct vector *v, void *data) { + void *ptr; + if (v->cur_elems >= v->max_elems) { v->max_elems += DEFAULT_VECTOR_GROWTH; - v->data = realloc(v->data, v->max_elems * v->size); - if (v->data == NULL) { + ptr = realloc(v->data, v->max_elems * v->size); + if (!ptr) { v->max_elems -= DEFAULT_VECTOR_GROWTH; return -1; } + v->data = ptr; } memcpy(v->data + (v->size * v->cur_elems), data, v->size); v->cur_elems++; diff --git a/tests/conntrack/load-stress.sh b/tests/conntrack/load-stress.sh new file mode 100644 index 0000000..597c4c6 --- /dev/null +++ b/tests/conntrack/load-stress.sh @@ -0,0 +1,62 @@ +#!/bin/bash + +SPORT_COUNT=128 +DPORT_COUNT=128 + +function ct_data_gen() +{ + for (( d = 1; d <= $DPORT_COUNT; d++ )) do + for (( s = 1; s <= $SPORT_COUNT; s++ )) do + ip netns exec ct-ns-test conntrack -I -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport ${s} --dport ${d} --state LISTEN -u SEEN_REPLY -t 300 &> /dev/null + if [ $? -ne 0 ] + then + echo "[FAILED] cannot insert conntrack entries" + exit 1 + fi + done + done +} + +ip netns add ct-ns-test + +if [ $UID -ne 0 ] +then + echo "Run this test as root" + exit 1 +fi + +echo "Creating conntrack entries, please wait..." +ct_data_gen +ip netns exec ct-ns-test conntrack -U -p tcp -m 1 +if [ $? -ne 0 ] +then + echo "[FAILED] cannot update conntrack entries" + exit 1 +fi + +COUNT=`ip netns exec ct-ns-test conntrack -L | wc -l` +if [ $COUNT -ne 16384 ] +then + echo "$COUNT entries, expecting 131072" + exit 1 +fi + +ip netns exec ct-ns-test conntrack -F +if [ $? -ne 0 ] +then + echo "[FAILED] faild to flush conntrack entries" + exit 1 +fi + +COUNT=`ip netns exec ct-ns-test conntrack -L | wc -l` +if [ $COUNT -ne 0 ] +then + echo "$COUNT entries, expecting 0" + exit 1 +fi + +ip netns del ct-ns-test + +echo "[OK] test successful" + +exit 0 diff --git a/tests/conntrack/testsuite/09dumpopt b/tests/conntrack/testsuite/09dumpopt index c1e0e6e..9dcd51f 100644 --- a/tests/conntrack/testsuite/09dumpopt +++ b/tests/conntrack/testsuite/09dumpopt @@ -25,7 +25,7 @@ # delete reverse -D -w 11 -r 2.2.2.2 -q 1.1.1.1 -p tcp --reply-port-src 11 --reply-port-dst 21 ; OK # delete v6 conntrack --D -w 11-s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 ; OK +-D -w 11 -s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 ; OK # delete icmp ping request entry -D -w 11 -u SEEN_REPLY -s 1.1.1.1 -d 2.2.2.2 -r 2.2.2.2 -q 1.1.1.1 -p icmp --icmp-type 8 --icmp-code 0 --icmp-id 1226 ; OK # delete old entries @@ -33,7 +33,7 @@ # delete reverse -D -w 10 -r 2.2.2.2 -q 1.1.1.1 -p tcp --reply-port-src 11 --reply-port-dst 21 ; OK # delete v6 conntrack --D -w 10-s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 ; OK +-D -w 10 -s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 ; OK # delete icmp ping request entry -D -w 10 -u SEEN_REPLY -s 1.1.1.1 -d 2.2.2.2 -r 2.2.2.2 -q 1.1.1.1 -p icmp --icmp-type 8 --icmp-code 0 --icmp-id 1226 ; OK # @@ -64,7 +64,7 @@ # delete reverse -D -w 11 -r 2.2.2.2 -q 1.1.1.1 -p tcp --reply-port-src 11 --reply-port-dst 21 ; OK # delete v6 conntrack --D -w 11-s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 ; OK +-D -w 11 -s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 ; OK # delete icmp ping request entry -D -w 11 -u SEEN_REPLY -s 1.1.1.1 -d 2.2.2.2 -r 2.2.2.2 -q 1.1.1.1 -p icmp --icmp-type 8 --icmp-code 0 --icmp-id 1226 ; OK # delete old entries @@ -72,7 +72,7 @@ # delete reverse -D -w 10 -r 2.2.2.2 -q 1.1.1.1 -p tcp --reply-port-src 11 --reply-port-dst 21 ; BAD # delete v6 conntrack --D -w 10-s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 ; BAD +-D -w 10 -s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 ; BAD # delete icmp ping request entry -D -w 10 -u SEEN_REPLY -s 1.1.1.1 -d 2.2.2.2 -r 2.2.2.2 -q 1.1.1.1 -p icmp --icmp-type 8 --icmp-code 0 --icmp-id 1226 ; BAD # @@ -161,13 +161,13 @@ # IGMP -D -w 10 -s 0.0.0.0 -d 224.0.0.22 -r 224.0.0.22 -q 0.0.0.0 -p 2 ; OK # Some fency protocol --D -w 10 -s 0.0.0.0 -d 224.0.0.22 -r 224.0.0.22 -q 0.0.0.0 -p 200 ; OK +-D -w 10 -s 0.0.0.0 -d 224.0.0.22 -r 224.0.0.22 -q 0.0.0.0 -p 200 ; OK # Some fency protocol with IPv6 -D -w 10 -s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p 200 ; OK # Delete stuff in zone 11, should succeed # IGMP -D -w 11 -s 0.0.0.0 -d 224.0.0.22 -r 224.0.0.22 -q 0.0.0.0 -p 2 ; OK # Some fency protocol --D -w 11 -s 0.0.0.0 -d 224.0.0.22 -r 224.0.0.22 -q 0.0.0.0 -p 200 ; OK +-D -w 11 -s 0.0.0.0 -d 224.0.0.22 -r 224.0.0.22 -q 0.0.0.0 -p 200 ; OK # Some fency protocol with IPv6 -D -w 11 -s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p 200 ; OK |