From ea0469ea8f507eed0496c2cedbe1c5894169dd1c Mon Sep 17 00:00:00 2001 From: "/C=EU/ST=EU/CN=Pablo Neira Ayuso/emailAddress=pablo@netfilter.org" Date: Wed, 14 May 2008 17:40:59 +0000 Subject: improve nfct_copy --- src/conntrack/copy.c | 429 ++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 389 insertions(+), 40 deletions(-) (limited to 'src/conntrack/copy.c') diff --git a/src/conntrack/copy.c b/src/conntrack/copy.c index e03abc8..142f868 100644 --- a/src/conntrack/copy.c +++ b/src/conntrack/copy.c @@ -7,51 +7,400 @@ #include "internal.h" -#define TS_ORIG \ -({ \ - ((1 << ATTR_ORIG_IPV4_SRC) | (1 << ATTR_ORIG_IPV4_DST) | \ - (1 << ATTR_ORIG_IPV6_SRC) | (1 << ATTR_ORIG_IPV6_DST) | \ - (1 << ATTR_ORIG_PORT_SRC) | (1 << ATTR_ORIG_PORT_DST) | \ - (1 << ATTR_ORIG_L3PROTO) | (1 << ATTR_ORIG_L4PROTO) | \ - (1 << ATTR_ICMP_TYPE) | (1 << ATTR_ICMP_CODE) | \ - (1 << ATTR_ICMP_ID)); \ -}) - -#define TS_REPL \ -({ \ - ((1 << ATTR_REPL_IPV4_SRC) | (1 << ATTR_REPL_IPV4_DST) | \ - (1 << ATTR_REPL_IPV6_SRC) | (1 << ATTR_REPL_IPV6_DST) | \ - (1 << ATTR_REPL_PORT_SRC) | (1 << ATTR_REPL_PORT_DST) | \ - (1 << ATTR_REPL_L3PROTO) | (1 << ATTR_REPL_L4PROTO) | \ - (1 << ATTR_ICMP_TYPE) | (1 << ATTR_ICMP_CODE) | \ - (1 << ATTR_ICMP_ID)); \ -}) - -#define TUPLE_SET(dir) (dir == __DIR_ORIG ? TS_ORIG : TS_REPL) - -void __copy_tuple(struct nf_conntrack *ct2, - const struct nf_conntrack *ct1, - int dir) -{ - memcpy(&ct2->tuple[dir].src, - &ct1->tuple[dir].src, +static void copy_attr_orig_ipv4_src(struct nf_conntrack *dest, + const struct nf_conntrack *orig) +{ + dest->tuple[__DIR_ORIG].src.v4 = orig->tuple[__DIR_ORIG].src.v4; +} + +static void copy_attr_orig_ipv4_dst(struct nf_conntrack *dest, + const struct nf_conntrack *orig) +{ + dest->tuple[__DIR_ORIG].dst.v4 = orig->tuple[__DIR_ORIG].dst.v4; +} + +static void copy_attr_repl_ipv4_src(struct nf_conntrack *dest, + const struct nf_conntrack *orig) +{ + dest->tuple[__DIR_REPL].src.v4 = orig->tuple[__DIR_REPL].src.v4; +} + +static void copy_attr_repl_ipv4_dst(struct nf_conntrack *dest, + const struct nf_conntrack *orig) +{ + dest->tuple[__DIR_REPL].dst.v4 = orig->tuple[__DIR_REPL].dst.v4; +} + +static void copy_attr_orig_ipv6_src(struct nf_conntrack *dest, + const struct nf_conntrack *orig) +{ + memcpy(&dest->tuple[__DIR_ORIG].src, + &orig->tuple[__DIR_ORIG].src, + sizeof(union __nfct_address)); +} + +static void copy_attr_orig_ipv6_dst(struct nf_conntrack *dest, + const struct nf_conntrack *orig) +{ + memcpy(&dest->tuple[__DIR_ORIG].dst, + &orig->tuple[__DIR_ORIG].dst, + sizeof(union __nfct_address)); +} + +static void copy_attr_repl_ipv6_src(struct nf_conntrack *dest, + const struct nf_conntrack *orig) +{ + memcpy(&dest->tuple[__DIR_REPL].src, + &orig->tuple[__DIR_REPL].src, + sizeof(union __nfct_address)); +} + +static void copy_attr_repl_ipv6_dst(struct nf_conntrack *dest, + const struct nf_conntrack *orig) +{ + memcpy(&dest->tuple[__DIR_REPL].dst, + &orig->tuple[__DIR_REPL].dst, + sizeof(union __nfct_address)); +} + +static void copy_attr_orig_port_src(struct nf_conntrack *dest, + const struct nf_conntrack *orig) +{ + dest->tuple[__DIR_ORIG].l4src.all = orig->tuple[__DIR_ORIG].l4src.all; +} + +static void copy_attr_orig_port_dst(struct nf_conntrack *dest, + const struct nf_conntrack *orig) +{ + dest->tuple[__DIR_ORIG].l4dst.all = orig->tuple[__DIR_ORIG].l4dst.all; +} + +static void copy_attr_repl_port_src(struct nf_conntrack *dest, + const struct nf_conntrack *orig) +{ + dest->tuple[__DIR_REPL].l4src.all = orig->tuple[__DIR_REPL].l4src.all; +} + +static void copy_attr_repl_port_dst(struct nf_conntrack *dest, + const struct nf_conntrack *orig) +{ + dest->tuple[__DIR_REPL].l4dst.all = orig->tuple[__DIR_REPL].l4dst.all; +} + +static void copy_attr_icmp_type(struct nf_conntrack *dest, + const struct nf_conntrack *orig) +{ + dest->tuple[__DIR_ORIG].l4dst.icmp.type = + orig->tuple[__DIR_ORIG].l4dst.icmp.type; + +} + +static void copy_attr_icmp_code(struct nf_conntrack *dest, + const struct nf_conntrack *orig) +{ + dest->tuple[__DIR_ORIG].l4dst.icmp.code = + orig->tuple[__DIR_ORIG].l4dst.icmp.code; + +} + +static void copy_attr_icmp_id(struct nf_conntrack *dest, + const struct nf_conntrack *orig) +{ + dest->tuple[__DIR_ORIG].l4src.icmp.id = + orig->tuple[__DIR_ORIG].l4src.icmp.id; +} + +static void copy_attr_orig_l3proto(struct nf_conntrack *dest, + const struct nf_conntrack *orig) +{ + dest->tuple[__DIR_ORIG].l3protonum = orig->tuple[__DIR_ORIG].l3protonum; +} + +static void copy_attr_repl_l3proto(struct nf_conntrack *dest, + const struct nf_conntrack *orig) +{ + dest->tuple[__DIR_REPL].l3protonum = orig->tuple[__DIR_REPL].l3protonum; +} + +static void copy_attr_orig_l4proto(struct nf_conntrack *dest, + const struct nf_conntrack *orig) +{ + dest->tuple[__DIR_ORIG].protonum = orig->tuple[__DIR_ORIG].protonum; +} + +static void copy_attr_repl_l4proto(struct nf_conntrack *dest, + const struct nf_conntrack *orig) +{ + dest->tuple[__DIR_REPL].protonum = orig->tuple[__DIR_REPL].protonum; +} + +static void copy_attr_master_ipv4_src(struct nf_conntrack *dest, + const struct nf_conntrack *orig) +{ + dest->tuple[__DIR_MASTER].src.v4 = orig->tuple[__DIR_MASTER].src.v4; +} + +static void copy_attr_master_ipv4_dst(struct nf_conntrack *dest, + const struct nf_conntrack *orig) +{ + dest->tuple[__DIR_MASTER].dst.v4 = orig->tuple[__DIR_MASTER].dst.v4; +} + +static void copy_attr_master_ipv6_src(struct nf_conntrack *dest, + const struct nf_conntrack *orig) +{ + memcpy(&dest->tuple[__DIR_MASTER].src, + &orig->tuple[__DIR_MASTER].src, sizeof(union __nfct_address)); +} - memcpy(&ct2->tuple[dir].dst, - &ct1->tuple[dir].dst, +static void copy_attr_master_ipv6_dst(struct nf_conntrack *dest, + const struct nf_conntrack *orig) +{ + memcpy(&dest->tuple[__DIR_MASTER].dst, + &orig->tuple[__DIR_MASTER].dst, sizeof(union __nfct_address)); +} + +static void copy_attr_master_port_src(struct nf_conntrack *dest, + const struct nf_conntrack *orig) +{ + dest->tuple[__DIR_MASTER].l4src.all = + orig->tuple[__DIR_MASTER].l4src.all; +} + +static void copy_attr_master_port_dst(struct nf_conntrack *dest, + const struct nf_conntrack *orig) +{ + dest->tuple[__DIR_MASTER].l4dst.all = + orig->tuple[__DIR_MASTER].l4dst.all; +} + +static void copy_attr_master_l3proto(struct nf_conntrack *dest, + const struct nf_conntrack *orig) +{ + dest->tuple[__DIR_MASTER].l3protonum = + orig->tuple[__DIR_MASTER].l3protonum; +} + +static void copy_attr_master_l4proto(struct nf_conntrack *dest, + const struct nf_conntrack *orig) +{ + dest->tuple[__DIR_MASTER].protonum = + orig->tuple[__DIR_MASTER].protonum; +} + +static void copy_attr_tcp_state(struct nf_conntrack *dest, + const struct nf_conntrack *orig) +{ + dest->protoinfo.tcp.state = orig->protoinfo.tcp.state; +} + +static void copy_attr_tcp_flags_orig(struct nf_conntrack *dest, + const struct nf_conntrack *orig) +{ + dest->protoinfo.tcp.flags[__DIR_ORIG].value = + orig->protoinfo.tcp.flags[__DIR_ORIG].value; +} + +static void copy_attr_tcp_flags_repl(struct nf_conntrack *dest, + const struct nf_conntrack *orig) +{ + dest->protoinfo.tcp.flags[__DIR_REPL].value = + orig->protoinfo.tcp.flags[__DIR_REPL].value; +} + +static void copy_attr_tcp_mask_orig(struct nf_conntrack *dest, + const struct nf_conntrack *orig) +{ + dest->protoinfo.tcp.flags[__DIR_ORIG].mask = + orig->protoinfo.tcp.flags[__DIR_ORIG].mask; +} + +static void copy_attr_tcp_mask_repl(struct nf_conntrack *dest, + const struct nf_conntrack *orig) +{ + dest->protoinfo.tcp.flags[__DIR_REPL].mask = + orig->protoinfo.tcp.flags[__DIR_REPL].mask; +} + +static void copy_attr_snat_ipv4(struct nf_conntrack *dest, + const struct nf_conntrack *orig) +{ + dest->snat.min_ip = orig->snat.min_ip; +} + +static void copy_attr_dnat_ipv4(struct nf_conntrack *dest, + const struct nf_conntrack *orig) +{ + dest->dnat.min_ip = orig->dnat.min_ip; +} + +static void copy_attr_snat_port(struct nf_conntrack *dest, + const struct nf_conntrack *orig) +{ + dest->snat.l4min.all = orig->snat.l4min.all; +} + +static void copy_attr_dnat_port(struct nf_conntrack *dest, + const struct nf_conntrack *orig) +{ + dest->dnat.l4min.all = orig->dnat.l4min.all; +} + +static void copy_attr_timeout(struct nf_conntrack *dest, + const struct nf_conntrack *orig) +{ + dest->timeout = orig->timeout; +} + +static void copy_attr_mark(struct nf_conntrack *dest, + const struct nf_conntrack *orig) +{ + dest->mark = orig->mark; +} + +static void copy_attr_secmark(struct nf_conntrack *dest, + const struct nf_conntrack *orig) +{ + dest->secmark = orig->secmark; +} + +static void copy_attr_orig_counter_packets(struct nf_conntrack *dest, + const struct nf_conntrack *orig) +{ + dest->counters[__DIR_ORIG].packets = orig->counters[__DIR_ORIG].packets; +} + +static void copy_attr_repl_counter_packets(struct nf_conntrack *dest, + const struct nf_conntrack *orig) +{ + dest->counters[__DIR_REPL].packets = orig->counters[__DIR_REPL].packets; +} - ct2->tuple[dir].l3protonum = ct1->tuple[dir].l3protonum; - ct2->tuple[dir].protonum = ct1->tuple[dir].protonum; +static void copy_attr_orig_counter_bytes(struct nf_conntrack *dest, + const struct nf_conntrack *orig) +{ + dest->counters[__DIR_ORIG].bytes = orig->counters[__DIR_ORIG].bytes; +} + +static void copy_attr_repl_counter_bytes(struct nf_conntrack *dest, + const struct nf_conntrack *orig) +{ + dest->counters[__DIR_REPL].bytes = orig->counters[__DIR_REPL].bytes; +} - memcpy(&ct2->tuple[dir].l4src, - &ct1->tuple[dir].l4src, - sizeof(union __nfct_l4)); +static void copy_attr_status(struct nf_conntrack *dest, + const struct nf_conntrack *orig) +{ + dest->status = orig->status; +} - memcpy(&ct2->tuple[dir].l4dst, - &ct1->tuple[dir].l4dst, - sizeof(union __nfct_l4)); +static void copy_attr_use(struct nf_conntrack *dest, + const struct nf_conntrack *orig) +{ + dest->use = orig->use; +} - /* XXX: this is safe but better convert bitset to uint64_t */ - ct2->set[0] |= ct1->set[0] & TUPLE_SET(__DIR_ORIG); +static void copy_attr_id(struct nf_conntrack *dest, + const struct nf_conntrack *orig) +{ + dest->id = orig->id; } + +static void copy_attr_orig_cor_pos(struct nf_conntrack *dest, + const struct nf_conntrack *orig) +{ + dest->tuple[__DIR_ORIG].natseq.correction_pos = + orig->tuple[__DIR_ORIG].natseq.correction_pos; +} + +static void copy_attr_orig_off_bfr(struct nf_conntrack *dest, + const struct nf_conntrack *orig) +{ + dest->tuple[__DIR_ORIG].natseq.offset_before = + orig->tuple[__DIR_ORIG].natseq.offset_before; +} + +static void copy_attr_orig_off_aft(struct nf_conntrack *dest, + const struct nf_conntrack *orig) +{ + dest->tuple[__DIR_ORIG].natseq.offset_after = + orig->tuple[__DIR_ORIG].natseq.offset_after; +} + +static void copy_attr_repl_cor_pos(struct nf_conntrack *dest, + const struct nf_conntrack *orig) +{ + dest->tuple[__DIR_REPL].natseq.correction_pos = + orig->tuple[__DIR_REPL].natseq.correction_pos; +} + +static void copy_attr_repl_off_bfr(struct nf_conntrack *dest, + const struct nf_conntrack *orig) +{ + dest->tuple[__DIR_REPL].natseq.offset_before = + orig->tuple[__DIR_REPL].natseq.offset_before; +} + +static void copy_attr_repl_off_aft(struct nf_conntrack *dest, + const struct nf_conntrack *orig) +{ + dest->tuple[__DIR_REPL].natseq.offset_after = + orig->tuple[__DIR_REPL].natseq.offset_after; +} + +copy_attr copy_attr_array[] = { + [ATTR_ORIG_IPV4_SRC] = copy_attr_orig_ipv4_src, + [ATTR_ORIG_IPV4_DST] = copy_attr_orig_ipv4_dst, + [ATTR_REPL_IPV4_SRC] = copy_attr_repl_ipv4_src, + [ATTR_REPL_IPV4_DST] = copy_attr_repl_ipv4_dst, + [ATTR_ORIG_IPV6_SRC] = copy_attr_orig_ipv6_src, + [ATTR_ORIG_IPV6_DST] = copy_attr_orig_ipv6_dst, + [ATTR_REPL_IPV6_SRC] = copy_attr_repl_ipv6_src, + [ATTR_REPL_IPV6_DST] = copy_attr_repl_ipv6_dst, + [ATTR_ORIG_PORT_SRC] = copy_attr_orig_port_src, + [ATTR_ORIG_PORT_DST] = copy_attr_orig_port_dst, + [ATTR_REPL_PORT_SRC] = copy_attr_repl_port_src, + [ATTR_REPL_PORT_DST] = copy_attr_repl_port_dst, + [ATTR_ICMP_TYPE] = copy_attr_icmp_type, + [ATTR_ICMP_CODE] = copy_attr_icmp_code, + [ATTR_ICMP_ID] = copy_attr_icmp_id, + [ATTR_ORIG_L3PROTO] = copy_attr_orig_l3proto, + [ATTR_REPL_L3PROTO] = copy_attr_repl_l3proto, + [ATTR_ORIG_L4PROTO] = copy_attr_orig_l4proto, + [ATTR_REPL_L4PROTO] = copy_attr_repl_l4proto, + [ATTR_TCP_STATE] = copy_attr_tcp_state, + [ATTR_SNAT_IPV4] = copy_attr_snat_ipv4, + [ATTR_DNAT_IPV4] = copy_attr_dnat_ipv4, + [ATTR_SNAT_PORT] = copy_attr_snat_port, + [ATTR_DNAT_PORT] = copy_attr_dnat_port, + [ATTR_TIMEOUT] = copy_attr_timeout, + [ATTR_MARK] = copy_attr_mark, + [ATTR_ORIG_COUNTER_PACKETS] = copy_attr_orig_counter_packets, + [ATTR_ORIG_COUNTER_BYTES] = copy_attr_orig_counter_bytes, + [ATTR_REPL_COUNTER_PACKETS] = copy_attr_repl_counter_packets, + [ATTR_REPL_COUNTER_BYTES] = copy_attr_repl_counter_bytes, + [ATTR_USE] = copy_attr_use, + [ATTR_ID] = copy_attr_id, + [ATTR_STATUS] = copy_attr_status, + [ATTR_TCP_FLAGS_ORIG] = copy_attr_tcp_flags_orig, + [ATTR_TCP_FLAGS_REPL] = copy_attr_tcp_flags_repl, + [ATTR_TCP_MASK_ORIG] = copy_attr_tcp_mask_orig, + [ATTR_TCP_MASK_REPL] = copy_attr_tcp_mask_repl, + [ATTR_MASTER_IPV4_SRC] = copy_attr_master_ipv4_src, + [ATTR_MASTER_IPV4_DST] = copy_attr_master_ipv4_dst, + [ATTR_MASTER_IPV6_SRC] = copy_attr_master_ipv6_src, + [ATTR_MASTER_IPV6_DST] = copy_attr_master_ipv6_dst, + [ATTR_MASTER_PORT_SRC] = copy_attr_master_port_src, + [ATTR_MASTER_PORT_DST] = copy_attr_master_port_dst, + [ATTR_MASTER_L3PROTO] = copy_attr_master_l3proto, + [ATTR_MASTER_L4PROTO] = copy_attr_master_l4proto, + [ATTR_SECMARK] = copy_attr_secmark, + [ATTR_ORIG_NAT_SEQ_CORRECTION_POS] = copy_attr_orig_cor_pos, + [ATTR_ORIG_NAT_SEQ_OFFSET_BEFORE] = copy_attr_orig_off_bfr, + [ATTR_ORIG_NAT_SEQ_OFFSET_AFTER] = copy_attr_orig_off_aft, + [ATTR_REPL_NAT_SEQ_CORRECTION_POS] = copy_attr_repl_cor_pos, + [ATTR_REPL_NAT_SEQ_OFFSET_BEFORE] = copy_attr_repl_off_bfr, + [ATTR_REPL_NAT_SEQ_OFFSET_AFTER] = copy_attr_repl_off_aft, +}; -- cgit v1.2.3