summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/network.h47
-rw-r--r--src/build.c72
-rw-r--r--src/network.c55
-rw-r--r--src/parse.c23
-rw-r--r--src/sync-alarm.c2
-rw-r--r--src/sync-ftfw.c8
-rw-r--r--src/sync-mode.c11
-rw-r--r--src/sync-notrack.c5
8 files changed, 90 insertions, 133 deletions
diff --git a/include/network.h b/include/network.h
index 1195303..11e65c7 100644
--- a/include/network.h
+++ b/include/network.h
@@ -9,25 +9,34 @@
struct nf_conntrack;
struct nethdr {
- uint8_t version;
+ uint8_t version:4,
+ type:4;
uint8_t flags;
uint16_t len;
uint32_t seq;
};
-#define NETHDR_SIZ sizeof(struct nethdr)
+#define NETHDR_SIZ nethdr_align(sizeof(struct nethdr))
+
+int nethdr_align(int len);
+int nethdr_size(int len);
+void nethdr_set(struct nethdr *net, int type);
+void nethdr_set_ack(struct nethdr *net);
#define NETHDR_DATA(x) \
- (struct netpld *)(((char *)x) + sizeof(struct nethdr))
+ (struct netattr *)(((char *)x) + NETHDR_SIZ)
+#define NETHDR_TAIL(x) \
+ (struct netattr *)(((char *)x) + x->len)
struct nethdr_ack {
- uint8_t version;
+ uint8_t version:4,
+ type:4;
uint8_t flags;
uint16_t len;
uint32_t seq;
uint32_t from;
uint32_t to;
};
-#define NETHDR_ACK_SIZ sizeof(struct nethdr_ack)
+#define NETHDR_ACK_SIZ nethdr_align(sizeof(struct nethdr_ack))
enum {
NET_F_UNUSED = (1 << 0),
@@ -49,17 +58,17 @@ enum {
#define BUILD_NETMSG(ct, query) \
({ \
char __net[4096]; \
- memset(__net, 0, NETHDR_SIZ + NETPLD_SIZ); \
- build_netmsg(ct, query, (struct nethdr *) __net); \
- (struct nethdr *) __net; \
+ struct nethdr *__hdr = (struct nethdr *) __net; \
+ memset(__hdr, 0, NETHDR_SIZ); \
+ nethdr_set(__hdr, query); \
+ build_payload(ct, __hdr); \
+ HDR_HOST2NETWORK(__hdr); \
+ __hdr; \
})
struct us_conntrack;
struct mcast_sock;
-void build_netmsg(struct nf_conntrack *ct, int query, struct nethdr *net);
-size_t prepare_send_netmsg(struct mcast_sock *m, void *data);
-
enum {
SEQ_UNKNOWN,
SEQ_UNSET,
@@ -129,12 +138,6 @@ static inline int between(uint32_t seq1, uint32_t seq2, uint32_t seq3)
return seq3 - seq2 >= seq1 - seq2;
}
-struct netpld {
- uint16_t len;
- uint16_t query;
-};
-#define NETPLD_SIZ sizeof(struct netpld)
-
#define PLD_NETWORK2HOST(x) \
({ \
x->len = ntohs(x->len); \
@@ -158,12 +161,6 @@ struct netattr {
x->nta_attr = ntohs(x->nta_attr); \
})
-#define PLD_DATA(x) \
- (struct netattr *)(((char *)x) + sizeof(struct netpld))
-
-#define PLD_TAIL(x) \
- (struct netattr *)(((char *)x) + sizeof(struct netpld) + x->len)
-
#define NTA_DATA(x) \
(void *)(((char *)x) + sizeof(struct netattr))
@@ -207,8 +204,8 @@ struct nta_attr_natseqadj {
uint32_t repl_seq_offset_after;
};
-void build_netpld(struct nf_conntrack *ct, struct netpld *pld, int query);
+void build_payload(const struct nf_conntrack *ct, struct nethdr *n);
-int parse_netpld(struct nf_conntrack *ct, struct nethdr *net, int *query, size_t remain);
+int parse_payload(struct nf_conntrack *ct, struct nethdr *n, size_t remain);
#endif
diff --git a/src/build.c b/src/build.c
index 84515cf..e094aa0 100644
--- a/src/build.c
+++ b/src/build.c
@@ -21,12 +21,12 @@
#include "network.h"
static inline void *
-put_header(struct netpld *pld, int attr, size_t len)
+put_header(struct nethdr *n, int attr, size_t len)
{
- struct netattr *nta = PLD_TAIL(pld);
+ struct netattr *nta = NETHDR_TAIL(n);
int total_size = NTA_ALIGN(NTA_LENGTH(len));
int attr_size = NTA_LENGTH(len);
- pld->len += total_size;
+ n->len += total_size;
nta->nta_attr = htons(attr);
nta->nta_len = htons(attr_size);
memset((unsigned char *)nta + attr_size, 0, total_size - attr_size);
@@ -34,45 +34,45 @@ put_header(struct netpld *pld, int attr, size_t len)
}
static inline void
-addattr(struct netpld *pld, int attr, const void *data, size_t len)
+addattr(struct nethdr *n, int attr, const void *data, size_t len)
{
- void *ptr = put_header(pld, attr, len);
+ void *ptr = put_header(n, attr, len);
memcpy(ptr, data, len);
}
static inline void
-__build_u8(const struct nf_conntrack *ct, int a, struct netpld *pld, int b)
+__build_u8(const struct nf_conntrack *ct, int a, struct nethdr *n, int b)
{
- void *ptr = put_header(pld, b, sizeof(uint8_t));
+ void *ptr = put_header(n, b, sizeof(uint8_t));
memcpy(ptr, nfct_get_attr(ct, a), sizeof(uint8_t));
}
static inline void
-__build_u16(const struct nf_conntrack *ct, int a, struct netpld *pld, int b)
+__build_u16(const struct nf_conntrack *ct, int a, struct nethdr *n, int b)
{
uint32_t data = nfct_get_attr_u16(ct, a);
data = htons(data);
- addattr(pld, b, &data, sizeof(uint16_t));
+ addattr(n, b, &data, sizeof(uint16_t));
}
static inline void
-__build_u32(const struct nf_conntrack *ct, int a, struct netpld *pld, int b)
+__build_u32(const struct nf_conntrack *ct, int a, struct nethdr *n, int b)
{
uint32_t data = nfct_get_attr_u32(ct, a);
data = htonl(data);
- addattr(pld, b, &data, sizeof(uint32_t));
+ addattr(n, b, &data, sizeof(uint32_t));
}
static inline void
-__build_group(const struct nf_conntrack *ct, int a, struct netpld *pld,
+__build_group(const struct nf_conntrack *ct, int a, struct nethdr *n,
int b, int size)
{
- void *ptr = put_header(pld, b, size);
+ void *ptr = put_header(n, b, size);
nfct_get_attr_grp(ct, a, ptr);
}
static inline void
-__build_natseqadj(const struct nf_conntrack *ct, struct netpld *pld)
+__build_natseqadj(const struct nf_conntrack *ct, struct nethdr *n)
{
struct nta_attr_natseqadj data = {
.orig_seq_correction_pos =
@@ -88,7 +88,7 @@ __build_natseqadj(const struct nf_conntrack *ct, struct netpld *pld)
.repl_seq_offset_after =
htonl(nfct_get_attr_u32(ct, ATTR_REPL_NAT_SEQ_OFFSET_AFTER))
};
- addattr(pld, NTA_NAT_SEQ_ADJ, &data, sizeof(struct nta_attr_natseqadj));
+ addattr(n, NTA_NAT_SEQ_ADJ, &data, sizeof(struct nta_attr_natseqadj));
}
static enum nf_conntrack_attr nat_type[] =
@@ -97,65 +97,61 @@ static enum nf_conntrack_attr nat_type[] =
ATTR_REPL_NAT_SEQ_OFFSET_BEFORE, ATTR_REPL_NAT_SEQ_OFFSET_AFTER };
/* XXX: ICMP not supported */
-void build_netpld(struct nf_conntrack *ct, struct netpld *pld, int query)
+void build_payload(const struct nf_conntrack *ct, struct nethdr *n)
{
if (nfct_attr_grp_is_set(ct, ATTR_GRP_ORIG_IPV4)) {
- __build_group(ct, ATTR_GRP_ORIG_IPV4, pld, NTA_IPV4,
+ __build_group(ct, ATTR_GRP_ORIG_IPV4, n, NTA_IPV4,
sizeof(struct nfct_attr_grp_ipv4));
} else if (nfct_attr_grp_is_set(ct, ATTR_GRP_ORIG_IPV6)) {
- __build_group(ct, ATTR_GRP_ORIG_IPV6, pld, NTA_IPV6,
+ __build_group(ct, ATTR_GRP_ORIG_IPV6, n, NTA_IPV6,
sizeof(struct nfct_attr_grp_ipv6));
}
- __build_u8(ct, ATTR_L4PROTO, pld, NTA_L4PROTO);
+ __build_u8(ct, ATTR_L4PROTO, n, NTA_L4PROTO);
if (nfct_attr_grp_is_set(ct, ATTR_GRP_ORIG_PORT)) {
- __build_group(ct, ATTR_GRP_ORIG_PORT, pld, NTA_PORT,
+ __build_group(ct, ATTR_GRP_ORIG_PORT, n, NTA_PORT,
sizeof(struct nfct_attr_grp_port));
}
- __build_u32(ct, ATTR_STATUS, pld, NTA_STATUS);
+ __build_u32(ct, ATTR_STATUS, n, NTA_STATUS);
if (nfct_attr_is_set(ct, ATTR_TCP_STATE))
- __build_u8(ct, ATTR_TCP_STATE, pld, NTA_STATE);
+ __build_u8(ct, ATTR_TCP_STATE, n, NTA_STATE);
if (nfct_attr_is_set(ct, ATTR_MARK))
- __build_u32(ct, ATTR_MARK, pld, NTA_MARK);
+ __build_u32(ct, ATTR_MARK, n, NTA_MARK);
/* setup the master conntrack */
if (nfct_attr_grp_is_set(ct, ATTR_GRP_MASTER_IPV4)) {
- __build_group(ct, ATTR_GRP_MASTER_IPV4, pld, NTA_MASTER_IPV4,
+ __build_group(ct, ATTR_GRP_MASTER_IPV4, n, NTA_MASTER_IPV4,
sizeof(struct nfct_attr_grp_ipv4));
- __build_u8(ct, ATTR_MASTER_L4PROTO, pld, NTA_MASTER_L4PROTO);
+ __build_u8(ct, ATTR_MASTER_L4PROTO, n, NTA_MASTER_L4PROTO);
if (nfct_attr_grp_is_set(ct, ATTR_GRP_MASTER_PORT)) {
__build_group(ct, ATTR_GRP_MASTER_PORT,
- pld, NTA_MASTER_PORT,
+ n, NTA_MASTER_PORT,
sizeof(struct nfct_attr_grp_port));
}
} else if (nfct_attr_grp_is_set(ct, ATTR_GRP_MASTER_IPV6)) {
- __build_group(ct, ATTR_GRP_MASTER_IPV6, pld, NTA_MASTER_IPV6,
+ __build_group(ct, ATTR_GRP_MASTER_IPV6, n, NTA_MASTER_IPV6,
sizeof(struct nfct_attr_grp_ipv6));
- __build_u8(ct, ATTR_MASTER_L4PROTO, pld, NTA_MASTER_L4PROTO);
+ __build_u8(ct, ATTR_MASTER_L4PROTO, n, NTA_MASTER_L4PROTO);
if (nfct_attr_grp_is_set(ct, ATTR_GRP_MASTER_PORT)) {
__build_group(ct, ATTR_GRP_MASTER_PORT,
- pld, NTA_MASTER_PORT,
+ n, NTA_MASTER_PORT,
sizeof(struct nfct_attr_grp_port));
}
}
/* NAT */
if (nfct_getobjopt(ct, NFCT_GOPT_IS_SNAT))
- __build_u32(ct, ATTR_REPL_IPV4_DST, pld, NTA_SNAT_IPV4);
+ __build_u32(ct, ATTR_REPL_IPV4_DST, n, NTA_SNAT_IPV4);
if (nfct_getobjopt(ct, NFCT_GOPT_IS_DNAT))
- __build_u32(ct, ATTR_REPL_IPV4_SRC, pld, NTA_DNAT_IPV4);
+ __build_u32(ct, ATTR_REPL_IPV4_SRC, n, NTA_DNAT_IPV4);
if (nfct_getobjopt(ct, NFCT_GOPT_IS_SPAT))
- __build_u16(ct, ATTR_REPL_PORT_DST, pld, NTA_SPAT_PORT);
+ __build_u16(ct, ATTR_REPL_PORT_DST, n, NTA_SPAT_PORT);
if (nfct_getobjopt(ct, NFCT_GOPT_IS_DPAT))
- __build_u16(ct, ATTR_REPL_PORT_SRC, pld, NTA_DPAT_PORT);
+ __build_u16(ct, ATTR_REPL_PORT_SRC, n, NTA_DPAT_PORT);
/* NAT sequence adjustment */
if (nfct_attr_is_set_array(ct, nat_type, 6))
- __build_natseqadj(ct, pld);
-
- pld->query = query;
-
- PLD_HOST2NETWORK(pld);
+ __build_natseqadj(ct, n);
}
diff --git a/src/network.c b/src/network.c
index ca00881..34992ec 100644
--- a/src/network.c
+++ b/src/network.c
@@ -25,48 +25,40 @@
#include <time.h>
#include <string.h>
+#define NETHDR_ALIGNTO 4
+
static unsigned int seq_set, cur_seq;
-static size_t __do_prepare(struct mcast_sock *m, void *data, size_t len)
+int nethdr_align(int value)
{
- struct nethdr *net = data;
+ return (value + NETHDR_ALIGNTO - 1) & ~(NETHDR_ALIGNTO - 1);
+}
+int nethdr_size(int len)
+{
+ return NETHDR_SIZ + len;
+}
+
+static inline void __nethdr_set(struct nethdr *net, int len, int type)
+{
if (!seq_set) {
seq_set = 1;
cur_seq = time(NULL);
}
- net->version = CONNTRACKD_PROTOCOL_VERSION;
- net->len = len;
- net->seq = cur_seq++;
- HDR_HOST2NETWORK(net);
-
- return len;
+ net->version = CONNTRACKD_PROTOCOL_VERSION;
+ net->type = type;
+ net->len = len;
+ net->seq = cur_seq++;
}
-static size_t __prepare_ctl(struct mcast_sock *m, void *data)
+void nethdr_set(struct nethdr *net, int type)
{
- return __do_prepare(m, data, NETHDR_ACK_SIZ);
+ __nethdr_set(net, NETHDR_SIZ, type);
}
-static size_t __prepare_data(struct mcast_sock *m, void *data)
+void nethdr_set_ack(struct nethdr *net)
{
- struct nethdr *net = (struct nethdr *) data;
- struct netpld *pld = NETHDR_DATA(net);
-
- return __do_prepare(m, data, ntohs(pld->len) + NETPLD_SIZ + NETHDR_SIZ);
-}
-
-size_t prepare_send_netmsg(struct mcast_sock *m, void *data)
-{
- int ret = 0;
- struct nethdr *net = (struct nethdr *) data;
-
- if (IS_DATA(net))
- ret = __prepare_data(m, data);
- else if (IS_CTL(net))
- ret = __prepare_ctl(m, data);
-
- return ret;
+ __nethdr_set(net, NETHDR_ACK_SIZ, 0);
}
static size_t tx_buflenmax;
@@ -129,13 +121,6 @@ ssize_t mcast_buffered_pending_netmsg(struct mcast_sock *m)
return ret;
}
-void build_netmsg(struct nf_conntrack *ct, int query, struct nethdr *net)
-{
- struct netpld *pld = NETHDR_DATA(net);
-
- build_netpld(ct, pld, query);
-}
-
static int local_seq_set = 0;
/* this function only tracks, it does not update the last sequence received */
diff --git a/src/parse.c b/src/parse.c
index 4eb74b2..17a0107 100644
--- a/src/parse.c
+++ b/src/parse.c
@@ -150,30 +150,16 @@ parse_nat_seq_adj(struct nf_conntrack *ct, int attr, void *data)
ntohl(this->orig_seq_correction_pos));
}
-int
-parse_netpld(struct nf_conntrack *ct,
- struct nethdr *net,
- int *query,
- size_t remain)
+int parse_payload(struct nf_conntrack *ct, struct nethdr *net, size_t remain)
{
int len;
struct netattr *attr;
- struct netpld *pld;
- if (remain < NETHDR_SIZ + sizeof(struct netpld))
+ if (remain < net->len)
return -1;
- pld = NETHDR_DATA(net);
-
- if (remain < NETHDR_SIZ + sizeof(struct netpld) + ntohs(pld->len))
- return -1;
-
- if (net->len < NETHDR_SIZ + sizeof(struct netpld) + ntohs(pld->len))
- return -1;
-
- PLD_NETWORK2HOST(pld);
- len = pld->len;
- attr = PLD_DATA(pld);
+ len = net->len - NETHDR_SIZ;
+ attr = NETHDR_DATA(net);
while (len > ssizeof(struct netattr)) {
ATTR_NETWORK2HOST(attr);
@@ -187,6 +173,5 @@ parse_netpld(struct nf_conntrack *ct,
attr = NTA_NEXT(attr, len);
}
- *query = pld->query;
return 0;
}
diff --git a/src/sync-alarm.c b/src/sync-alarm.c
index 377af16..fe3d9af 100644
--- a/src/sync-alarm.c
+++ b/src/sync-alarm.c
@@ -29,7 +29,6 @@
static void refresher(struct alarm_block *a, void *data)
{
- size_t len;
struct nethdr *net;
struct us_conntrack *u = data;
@@ -40,7 +39,6 @@ static void refresher(struct alarm_block *a, void *data)
((random() % 5 + 1) * 200000) - 1);
net = BUILD_NETMSG(u->ct, NFCT_Q_UPDATE);
- len = prepare_send_netmsg(STATE_SYNC(mcast_client), net);
mcast_buffered_send_netmsg(STATE_SYNC(mcast_client), net);
}
diff --git a/src/sync-ftfw.c b/src/sync-ftfw.c
index 293f9ab..a4895d4 100644
--- a/src/sync-ftfw.c
+++ b/src/sync-ftfw.c
@@ -451,10 +451,9 @@ out:
static void ftfw_send(struct nethdr *net, struct us_conntrack *u)
{
- struct netpld *pld = NETHDR_DATA(net);
struct cache_ftfw *cn;
- switch(ntohs(pld->query)) {
+ switch(net->type) {
case NFCT_Q_CREATE:
case NFCT_Q_UPDATE:
case NFCT_Q_DESTROY:
@@ -490,7 +489,9 @@ static void ftfw_send(struct nethdr *net, struct us_conntrack *u)
static int tx_queue_xmit(void *data1, const void *data2)
{
struct nethdr *net = data1;
- size_t len = prepare_send_netmsg(STATE_SYNC(mcast_client), net);
+
+ nethdr_set_ack(net);
+ HDR_HOST2NETWORK(net);
dp("tx_queue sq: %u fl:%u len:%u\n",
ntohl(net->seq), net->flags, ntohs(net->len));
@@ -510,7 +511,6 @@ static int tx_list_xmit(struct list_head *i, struct us_conntrack *u, int type)
{
int ret;
struct nethdr *net = BUILD_NETMSG(u->ct, type);
- size_t len = prepare_send_netmsg(STATE_SYNC(mcast_client), net);
dp("tx_list sq: %u fl:%u len:%u\n",
ntohl(net->seq), net->flags, ntohs(net->len));
diff --git a/src/sync-mode.c b/src/sync-mode.c
index ac9d3f3..cfed7f4 100644
--- a/src/sync-mode.c
+++ b/src/sync-mode.c
@@ -36,7 +36,6 @@
static void do_mcast_handler_step(struct nethdr *net, size_t remain)
{
- int query;
char __ct[nfct_maxsize()];
struct nf_conntrack *ct = (struct nf_conntrack *)(void*) __ct;
struct us_conntrack *u;
@@ -62,13 +61,13 @@ static void do_mcast_handler_step(struct nethdr *net, size_t remain)
memset(ct, 0, sizeof(__ct));
- if (parse_netpld(ct, net, &query, remain) == -1) {
+ if (parse_payload(ct, net, remain) == -1) {
STATE(malformed)++;
dlog(LOG_ERR, "parsing failed: malformed message");
return;
}
- switch(query) {
+ switch(net->type) {
case NFCT_Q_CREATE:
retry:
if ((u = cache_add(STATE_SYNC(external), ct))) {
@@ -100,7 +99,7 @@ retry:
break;
default:
STATE(malformed)++;
- dlog(LOG_ERR, "mcast unknown query %d\n", query);
+ dlog(LOG_ERR, "mcast unknown query %d\n", net->type);
break;
}
}
@@ -109,7 +108,7 @@ retry:
static void mcast_handler(void)
{
ssize_t numbytes;
- size_t remain;
+ ssize_t remain;
char __net[65536], *ptr = __net; /* XXX: maximum MTU for IPv4 */
numbytes = mcast_recv(STATE_SYNC(mcast_server), __net, sizeof(__net));
@@ -397,11 +396,9 @@ static void dump_sync(struct nf_conntrack *ct)
static void mcast_send_sync(struct us_conntrack *u, int query)
{
- size_t len;
struct nethdr *net;
net = BUILD_NETMSG(u->ct, query);
- len = prepare_send_netmsg(STATE_SYNC(mcast_client), net);
if (STATE_SYNC(sync)->send)
STATE_SYNC(sync)->send(net, u);
diff --git a/src/sync-notrack.c b/src/sync-notrack.c
index c5ea1e6..fdb0c43 100644
--- a/src/sync-notrack.c
+++ b/src/sync-notrack.c
@@ -155,8 +155,8 @@ static int notrack_recv(const struct nethdr *net)
static int tx_queue_xmit(void *data1, const void *data2)
{
struct nethdr *net = data1;
- size_t len = prepare_send_netmsg(STATE_SYNC(mcast_client), net);
-
+ nethdr_set_ack(net);
+ HDR_HOST2NETWORK(net);
mcast_buffered_send_netmsg(STATE_SYNC(mcast_client), net);
queue_del(tx_queue, net);
@@ -167,7 +167,6 @@ static int tx_list_xmit(struct list_head *i, struct us_conntrack *u, int type)
{
int ret;
struct nethdr *net = BUILD_NETMSG(u->ct, type);
- size_t len = prepare_send_netmsg(STATE_SYNC(mcast_client), net);
list_del_init(i);
tx_list_len--;