From 76ac8ebe5e49385585c8e29fe530ed4baef390bf Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Sun, 2 Nov 2008 21:35:42 +0100 Subject: network: rework TLV-based protocol This patch reworks the TLV-based protocol to reduce the overhead in the message building. The idea is to group some attributes that must be present in a consistent configuration. Putting them together help us to save some cycles in the message building. Now, oprofile reports ~15% of samples in the build path instead of ~25%. CPU consumption for 3000 HTTP GET requests per second (1000 concurrent with apache benchmark tool) is ~45% in my testbed, that is ~19% more consumption than with no replication at all. Signed-off-by: Pablo Neira Ayuso --- src/parse.c | 153 +++++++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 111 insertions(+), 42 deletions(-) (limited to 'src/parse.c') diff --git a/src/parse.c b/src/parse.c index b14e487..0184c5a 100644 --- a/src/parse.c +++ b/src/parse.c @@ -24,61 +24,127 @@ #define ssizeof(x) (int)sizeof(x) #endif -static void parse_u8(struct nf_conntrack *ct, int attr, void *data) +static void parse_u8(struct nf_conntrack *ct, int attr, void *data); +static void parse_u16(struct nf_conntrack *ct, int attr, void *data); +static void parse_u32(struct nf_conntrack *ct, int attr, void *data); +static void parse_group(struct nf_conntrack *ct, int attr, void *data); +static void parse_nat_seq_adj(struct nf_conntrack *ct, int attr, void *data); + +struct parser { + void (*parse)(struct nf_conntrack *ct, int attr, void *data); + int attr; +}; + +static struct parser h[ATTR_MAX] = { + [NTA_IPV4] = { + .parse = parse_group, + .attr = ATTR_GRP_ORIG_IPV4, + }, + [NTA_IPV6] = { + .parse = parse_group, + .attr = ATTR_GRP_ORIG_IPV6, + }, + [NTA_PORT] = { + .parse = parse_group, + .attr = ATTR_GRP_ORIG_PORT, + }, + [NTA_L4PROTO] = { + .parse = parse_u8, + .attr = ATTR_L4PROTO, + }, + [NTA_STATE] = { + .parse = parse_u8, + .attr = ATTR_TCP_STATE, + }, + [NTA_STATUS] = { + .parse = parse_u32, + .attr = ATTR_STATUS, + }, + [NTA_MARK] = { + .parse = parse_u32, + .attr = ATTR_MARK, + }, + [NTA_TIMEOUT] = { + .parse = parse_u32, + .attr = ATTR_TIMEOUT, + }, + [NTA_MASTER_IPV4] = { + .parse = parse_group, + .attr = ATTR_GRP_MASTER_IPV4, + }, + [NTA_MASTER_IPV6] = { + .parse = parse_group, + .attr = ATTR_GRP_MASTER_IPV6, + }, + [NTA_MASTER_PORT] = { + .parse = parse_group, + .attr = ATTR_GRP_MASTER_PORT, + }, + [NTA_SNAT_IPV4] = { + .parse = parse_u32, + .attr = ATTR_SNAT_IPV4, + }, + [NTA_DNAT_IPV4] = { + .parse = parse_u32, + .attr = ATTR_DNAT_IPV4, + }, + [NTA_SPAT_PORT] = { + .parse = parse_u16, + .attr = ATTR_SNAT_PORT, + }, + [NTA_DPAT_PORT] = { + .parse = parse_u16, + .attr = ATTR_SNAT_PORT, + }, + [NTA_NAT_SEQ_ADJ] = { + .parse = parse_nat_seq_adj, + }, +}; + +static void +parse_u8(struct nf_conntrack *ct, int attr, void *data) { uint8_t *value = (uint8_t *) data; - nfct_set_attr_u8(ct, attr, *value); + nfct_set_attr_u8(ct, h[attr].attr, *value); } -static void parse_u16(struct nf_conntrack *ct, int attr, void *data) +static void +parse_u16(struct nf_conntrack *ct, int attr, void *data) { uint16_t *value = (uint16_t *) data; - nfct_set_attr_u16(ct, attr, ntohs(*value)); + nfct_set_attr_u16(ct, h[attr].attr, ntohs(*value)); } -static void parse_u32(struct nf_conntrack *ct, int attr, void *data) +static void +parse_u32(struct nf_conntrack *ct, int attr, void *data) { uint32_t *value = (uint32_t *) data; - nfct_set_attr_u32(ct, attr, ntohl(*value)); + nfct_set_attr_u32(ct, h[attr].attr, ntohl(*value)); } -static void parse_pointer_be(struct nf_conntrack *ct, int attr, void *data) +static void +parse_group(struct nf_conntrack *ct, int attr, void *data) { - nfct_set_attr(ct, attr, data); + nfct_set_attr_grp(ct, h[attr].attr, data); } -typedef void (*parse)(struct nf_conntrack *ct, int attr, void *data); - -static parse h[ATTR_MAX] = { - [ATTR_IPV4_SRC] = parse_pointer_be, - [ATTR_IPV4_DST] = parse_pointer_be, - [ATTR_IPV6_SRC] = parse_pointer_be, - [ATTR_IPV6_DST] = parse_pointer_be, - [ATTR_L3PROTO] = parse_u8, - [ATTR_PORT_SRC] = parse_u16, - [ATTR_PORT_DST] = parse_u16, - [ATTR_L4PROTO] = parse_u8, - [ATTR_TCP_STATE] = parse_u8, - [ATTR_SNAT_IPV4] = parse_u32, - [ATTR_DNAT_IPV4] = parse_u32, - [ATTR_SNAT_PORT] = parse_u16, - [ATTR_DNAT_PORT] = parse_u16, - [ATTR_TIMEOUT] = parse_u32, - [ATTR_MARK] = parse_u32, - [ATTR_STATUS] = parse_u32, - [ATTR_MASTER_IPV4_SRC] = parse_u32, - [ATTR_MASTER_IPV4_DST] = parse_u32, - [ATTR_MASTER_L3PROTO] = parse_u8, - [ATTR_MASTER_PORT_SRC] = parse_u16, - [ATTR_MASTER_PORT_DST] = parse_u16, - [ATTR_MASTER_L4PROTO] = parse_u8, - [ATTR_ORIG_NAT_SEQ_CORRECTION_POS] = parse_u32, - [ATTR_ORIG_NAT_SEQ_OFFSET_BEFORE] = parse_u32, - [ATTR_ORIG_NAT_SEQ_OFFSET_AFTER] = parse_u32, - [ATTR_REPL_NAT_SEQ_CORRECTION_POS] = parse_u32, - [ATTR_REPL_NAT_SEQ_OFFSET_BEFORE] = parse_u32, - [ATTR_REPL_NAT_SEQ_OFFSET_AFTER] = parse_u32, -}; +static void +parse_nat_seq_adj(struct nf_conntrack *ct, int attr, void *data) +{ + struct nta_attr_natseqadj *this = data; + nfct_set_attr_u32(ct, ATTR_ORIG_NAT_SEQ_CORRECTION_POS, + ntohl(this->orig_seq_correction_pos)); + nfct_set_attr_u32(ct, ATTR_ORIG_NAT_SEQ_OFFSET_BEFORE, + ntohl(this->orig_seq_correction_pos)); + nfct_set_attr_u32(ct, ATTR_ORIG_NAT_SEQ_OFFSET_AFTER, + ntohl(this->orig_seq_correction_pos)); + nfct_set_attr_u32(ct, ATTR_REPL_NAT_SEQ_CORRECTION_POS, + ntohl(this->orig_seq_correction_pos)); + nfct_set_attr_u32(ct, ATTR_REPL_NAT_SEQ_OFFSET_BEFORE, + ntohl(this->orig_seq_correction_pos)); + nfct_set_attr_u32(ct, ATTR_REPL_NAT_SEQ_OFFSET_AFTER, + ntohl(this->orig_seq_correction_pos)); +} int parse_netpld(struct nf_conntrack *ct, @@ -109,8 +175,11 @@ parse_netpld(struct nf_conntrack *ct, ATTR_NETWORK2HOST(attr); if (attr->nta_len > len) return -1; - if (h[attr->nta_attr]) - h[attr->nta_attr](ct, attr->nta_attr, NTA_DATA(attr)); + if (h[attr->nta_attr].parse == NULL) { + attr = NTA_NEXT(attr, len); + continue; + } + h[attr->nta_attr].parse(ct, attr->nta_attr, NTA_DATA(attr)); attr = NTA_NEXT(attr, len); } -- cgit v1.2.3