diff options
Diffstat (limited to 'src/lib.h')
-rw-r--r-- | src/lib.h | 1899 |
1 files changed, 1899 insertions, 0 deletions
diff --git a/src/lib.h b/src/lib.h new file mode 100644 index 0000000..a5d4362 --- /dev/null +++ b/src/lib.h @@ -0,0 +1,1899 @@ +#ifndef _LIB_H +#define _LIB_H + +#include <libmnl/libmnl.h> +#include <stdlib.h> +#include "linux_list.h" + +#define ARRAY_MAX 4096 + +struct array { + void *data[ARRAY_MAX]; + int num; +}; + +struct array_u8 { + uint8_t data[ARRAY_MAX]; + int num; +}; + +struct array_u32 { + uint32_t data[ARRAY_MAX]; + int num; +}; + +enum test_batch_type { + ADD_TABLE = 0, + SET_TABLE, + DEL_TABLE, + ADD_BASECHAIN, + DEL_BASECHAIN, + ADD_CHAIN, + DEL_CHAIN, + ADD_SET, + SET_SET, + FLUSH_SET, + ADD_SETELEM, + DEL_SETELEM, + DEL_SET, + ADD_FLOWTABLE, + DEL_FLOWTABLE, + ADD_RULE, + DEL_RULE, + ADD_OBJECT, + DEL_OBJECT, +}; + +struct test_batch_cmd { + struct list_head list; + enum test_batch_type type; + int lineno; + void *obj; +}; + +struct test_batch { + struct list_head cmd; + uint32_t lineno; + char buf[1 << 21]; + struct mnl_socket *nl; + struct mnl_nlmsg_batch *batch; + struct { + int family; + const char *table; + struct rule *rule; + struct list_head *expr_list; /* for inner */ + struct set *set; + } ctx; +}; + +void setup_batch(struct test_batch *batch); + +struct table { + const char *name; + uint32_t *nfproto; + uint32_t *flags; + uint64_t *handle; + const char *userdata; + + /* storage */ + uint32_t _nfproto; + uint32_t _flags; + uint64_t _handle; +}; + +static inline struct table *table_init(void) +{ + struct table *table = calloc(1, sizeof(*table)); + + table->nfproto = &table->_nfproto; + table->flags = &table->_flags; + table->handle = &table->_handle; + + return table; +} + +void free_table(struct table *table); + +void set_table(struct test_batch *batch, struct table *table); +void add_table(struct test_batch *batch, struct table *table); +void del_table(struct test_batch *batch, struct table *table); + +struct chain { + const char *table; + const char *name; + const char *type; + const char *dev; + struct array *dev_array; + const char *userdata; + + uint32_t *family; + uint32_t *flags; + uint32_t *chain_id; + uint32_t *hooknum; + uint64_t *handle; + uint32_t *policy; + uint64_t *bytes; + uint64_t *pkts; + uint32_t *prio; + + /* storage */ + uint32_t _family; + uint32_t _flags; + uint32_t _chain_id; + uint32_t _hooknum; + uint64_t _handle; + uint32_t _policy; + uint64_t _bytes; + uint64_t _pkts; + uint32_t _prio; +}; + +static inline struct chain *chain_init(void) +{ + struct chain *c = calloc(1, sizeof(*c)); + + c->family = &c->_family; + c->flags = &c->_flags; + c->chain_id = &c->_chain_id; + c->hooknum = &c->_hooknum; + c->handle = &c->_handle; + c->policy = &c->_policy; + c->bytes = &c->_bytes; + c->pkts = &c->_pkts; + c->prio = &c->_prio; + + return c; +} + +void free_chain(struct chain *chain); + +void add_chain(struct test_batch *batch, struct chain *chain); +void del_chain(struct test_batch *batch, struct chain *chain); +void add_basechain(struct test_batch *batch, struct chain *chain); +void del_basechain(struct test_batch *batch, struct chain *chain); + +struct set { + const char *table; + const char *name; + struct list_head expr_list; + + uint32_t *family; + uint32_t *flags; + uint32_t *key_len; + uint32_t *key_type; + uint32_t *data_len; + uint32_t *data_type; + uint32_t *policy; + struct array_u8 *field_array; + uint32_t *size; + uint32_t *set_id; + uint64_t *timeout; + uint32_t *gc_interval; + const char *userdata; + uint32_t *obj_type; + uint64_t *handle; + + /* storage */ + uint32_t _family; + uint32_t _flags; + uint32_t _key_len; + uint32_t _key_type; + uint32_t _data_len; + uint32_t _data_type; + uint32_t _policy; + uint32_t _size; + uint32_t _set_id; + uint64_t _timeout; + uint32_t _gc_interval; + uint32_t _obj_type; + uint64_t _handle; +}; + +static inline struct set *set_init(void) +{ + struct set *set = calloc(1, sizeof(*set)); + + INIT_LIST_HEAD(&set->expr_list); + + set->family = &set->_family; + set->flags = &set->_flags; + set->key_len = &set->_key_len; + set->key_type = &set->_key_type; + set->data_len = &set->_data_len; + set->data_type = &set->_data_type; + set->policy = &set->_policy; + set->size = &set->_size; + set->set_id = &set->_set_id; + set->timeout = &set->_timeout; + set->gc_interval = &set->_gc_interval; + set->obj_type = &set->_obj_type; + set->handle = &set->_handle; + + return set; +} + +void add_set(struct test_batch *batch, struct set *set); +void del_set(struct test_batch *batch, struct set *set); +void flush_set(struct test_batch *batch, struct set *set); +void set_set(struct test_batch *batch, struct set *set); +void free_set(struct set *set); + +struct elem { + const char *table; + const char *set; + uint32_t set_id; + + const char *chain; + const char *objname; + uint8_t *userdata; + + struct list_head expr_list; + + uint32_t *family; + uint8_t *key; + int key_len; + uint8_t *key_end; + int key_end_len; + uint8_t *data; + int data_len; + uint32_t *flags; + uint32_t *verdict; + uint64_t *timeout; + uint64_t *expiration; + + /* storage */ + uint32_t _family; + uint8_t _key[16]; + uint8_t _key_end[16]; + uint8_t _data[64]; + uint32_t _flags; + uint32_t _verdict; + uint64_t _timeout; + uint64_t _expiration; +}; + +static inline struct elem *elem_init(void) +{ + struct elem *elem = calloc(1, sizeof(*elem)); + + INIT_LIST_HEAD(&elem->expr_list); + + elem->family = &elem->_family; + elem->key = elem->_key; + elem->key_end = elem->_key_end; + elem->data = elem->_data; + elem->flags = &elem->_flags; + elem->verdict = &elem->_verdict; + elem->timeout = &elem->_timeout; + elem->expiration = &elem->_expiration; + + return elem; +} + +void free_elem(struct elem *elem); + +void add_elem(struct test_batch *batch, struct elem *elem); +void del_elem(struct test_batch *batch, struct elem *elem); + +struct flowtable { + const char *table; + const char *name; + struct array *dev_array; + + uint32_t *family; + uint32_t *hooknum; + uint32_t *prio; + uint64_t *handle; + + /* storage */ + uint32_t _family; + uint32_t _hooknum; + uint32_t _prio; + uint64_t _handle; +}; + +static inline struct flowtable *flowtable_init(void) +{ + struct flowtable *f = calloc(1, sizeof(*f)); + + f->family = &f->_family; + f->hooknum = &f->_hooknum; + f->handle = &f->_handle; + f->prio = &f->_prio; + + return f; +} + +void add_flowtable(struct test_batch *batch, struct flowtable *flowtable); +void del_flowtable(struct test_batch *batch, struct flowtable *flowtable); +void free_flowtable(struct flowtable *flowtable); + +struct rule { + const char *table; + const char *chain; + uint32_t *family; + uint32_t *rule_id; + uint32_t *pos_id; + uint64_t *handle; + uint64_t *pos; + const char *userdata; + + /* set up when parsing match/target. */ + struct { + uint32_t *l4proto; + uint32_t *flags; + } compat; + + struct list_head expr_list; + + /* storage */ + uint32_t _family; + uint32_t _rule_id; + uint32_t _pos_id; + uint64_t _handle; + uint64_t _pos; +}; + +static inline struct rule *rule_init(void) +{ + struct rule *rule = calloc(1, sizeof(*rule)); + + rule->family = &rule->_family; + rule->rule_id = &rule->_rule_id; + rule->pos_id = &rule->_pos_id; + rule->handle = &rule->_handle; + rule->pos = &rule->_pos; + + INIT_LIST_HEAD(&rule->expr_list); + + return rule; +} + +void free_rule(struct rule *rule); + +void add_rule(struct test_batch *batch, struct rule *rule); +void del_rule(struct test_batch *batch, struct rule *rule); + +enum expr_type { + INVALID = 0, + BITWISE, + BYTEORDER, + CMP, + COUNTER, + CONNLIMIT, + CT, + DUP, + DYNSET, + EXTHDR, + FIB, + FWD, + HASH, + INNER, + IMMEDIATE, + LAST, + LIMIT, + LOG, + LOOKUP, + MASQ, + MATCH, + META, + NAT, + NUMGEN, + OBJREF, + OSF, + PAYLOAD, + QUEUE, + QUOTA, + RANGE, + REDIR, + REJECT, + RT, + SOCKET, + SYNPROXY, + TARGET, + TPROXY, + TUNNEL, + XFRM, +}; + +struct expr { + struct list_head list; + enum expr_type type; +}; + +int add_expr(struct test_batch *batch, struct expr *expr); + +struct bitwise { + struct expr expr; + + uint32_t *sreg; + uint32_t *dreg; + uint32_t *op; + uint32_t *len; + uint8_t *mask; + int mask_len; + uint8_t *xor; + int xor_len; + uint8_t *data; + int data_len; + + uint32_t _sreg; + uint32_t _dreg; + uint32_t _op; + uint32_t _len; + uint8_t _mask[16]; + uint8_t _xor[16]; + uint8_t _data[16]; +}; + +static inline struct bitwise *bitwise_init(void) +{ + struct bitwise *bitwise = calloc(1, sizeof(*bitwise)); + + bitwise->expr.type = BITWISE; + + bitwise->sreg = &bitwise->_sreg; + bitwise->dreg = &bitwise->_dreg; + bitwise->op = &bitwise->_op; + bitwise->len = &bitwise->_len; + bitwise->mask = bitwise->_mask; + bitwise->xor = bitwise->_xor; + bitwise->data = bitwise->_data; + + return bitwise; +} + +static inline void free_bitwise(struct bitwise *bitwise) +{ + free(bitwise); +} + +struct byteorder { + struct expr expr; + + uint32_t *sreg; + uint32_t *dreg; + uint32_t *op; + uint32_t *len; + uint32_t *size; + + uint32_t _sreg; + uint32_t _dreg; + uint32_t _op; + uint32_t _len; + uint32_t _size; +}; + +static inline struct byteorder *byteorder_init(void) +{ + struct byteorder *byteorder = calloc(1, sizeof(*byteorder)); + + byteorder->expr.type = BYTEORDER; + + byteorder->sreg = &byteorder->_sreg; + byteorder->dreg = &byteorder->_dreg; + byteorder->op = &byteorder->_op; + byteorder->len = &byteorder->_len; + byteorder->size = &byteorder->_size; + + return byteorder; +} + +static inline void free_byteorder(struct byteorder *byteorder) +{ + free(byteorder); +} + +struct cmp { + struct expr expr; + + uint32_t *sreg; + uint32_t *op; + uint8_t *data; + int data_len; + + uint32_t _sreg; + uint32_t _op; + uint8_t _data[16]; +}; + +static inline struct cmp *cmp_init(void) +{ + struct cmp *cmp = calloc(1, sizeof(*cmp)); + + cmp->expr.type = CMP; + + cmp->sreg = &cmp->_sreg; + cmp->op = &cmp->_op; + cmp->data = cmp->_data; + + return cmp; +} + +static inline void free_cmp(struct cmp *cmp) +{ + free(cmp); +} + +struct connlimit { + struct expr expr; + + uint32_t *count; + uint32_t *flags; + + uint32_t _count; + uint32_t _flags; +}; + +static inline struct connlimit *connlimit_init(void) +{ + struct connlimit *connlimit = calloc(1, sizeof(*connlimit)); + + connlimit->expr.type = CONNLIMIT; + + connlimit->count = &connlimit->_count; + connlimit->flags = &connlimit->_flags; + + return connlimit; +} + +static inline void free_connlimit(struct connlimit *connlimit) +{ + free(connlimit); +} + +struct counter { + struct expr expr; + + uint64_t *pkts; + uint64_t *bytes; + + /* storage */ + uint64_t _pkts; + uint64_t _bytes; +}; + +static inline struct counter *counter_init(void) +{ + struct counter *counter = calloc(1, sizeof(*counter)); + + counter->expr.type = COUNTER; + + counter->pkts = &counter->_pkts; + counter->bytes = &counter->_bytes; + + return counter; +} + +static inline void free_counter(struct counter *counter) +{ + free(counter); +} + +struct ct { + struct expr expr; + + uint32_t *sreg; + uint32_t *dreg; + uint32_t *key; + uint8_t *dir; + + uint32_t _sreg; + uint32_t _dreg; + uint32_t _key; + uint8_t _dir; +}; + +static inline struct ct *ct_init(void) +{ + struct ct *ct = calloc(1, sizeof(*ct)); + + ct->expr.type = CT; + + ct->sreg = &ct->_sreg; + ct->dreg = &ct->_dreg; + ct->key = &ct->_key; + ct->dir = &ct->_dir; + + return ct; +} + +static inline void free_ct(struct ct *ct) +{ + free(ct); +} + +struct dup { + struct expr expr; + + uint32_t *sreg_addr; + uint32_t *sreg_dev; + + uint32_t _sreg_addr; + uint32_t _sreg_dev; +}; + +static inline struct dup *dup_init(void) +{ + struct dup *dup = calloc(1, sizeof(*dup)); + + dup->expr.type = DUP; + + dup->sreg_addr = &dup->_sreg_addr; + dup->sreg_dev = &dup->_sreg_dev; + + return dup; +} + +static inline void free_dup(struct dup *dup) +{ + free(dup); +} + +struct dynset { + struct expr expr; + + const char *set; + struct list_head expr_list; + + uint32_t *set_id; + uint32_t *op; + uint32_t *sreg_key; + uint32_t *sreg_data; + uint64_t *timeout; + uint32_t *flags; + /* exprs */ + + /* storage */ + uint32_t _set_id; + uint32_t _op; + uint32_t _sreg_key; + uint32_t _sreg_data; + uint64_t _timeout; + uint32_t _flags; +}; + +static inline struct dynset *dynset_init(void) +{ + struct dynset *dynset = calloc(1, sizeof(*dynset)); + + dynset->expr.type = DYNSET; + + INIT_LIST_HEAD(&dynset->expr_list); + + dynset->set_id = &dynset->_set_id; + dynset->op = &dynset->_op; + dynset->sreg_key= &dynset->_sreg_key; + dynset->sreg_data = &dynset->_sreg_data; + dynset->timeout = &dynset->_timeout; + dynset->flags = &dynset->_flags; + + return dynset; +} + +static inline void free_dynset(struct dynset *dynset) +{ + free((void *)dynset->set); + free(dynset); +} + +struct exthdr { + struct expr expr; + + uint32_t *sreg; + uint32_t *dreg; + uint32_t *offset; + uint32_t *len; + uint32_t *type; + uint32_t *op; + uint32_t *flags; + + uint32_t _sreg; + uint32_t _dreg; + uint32_t _offset; + uint32_t _len; + uint32_t _type; + uint32_t _op; + uint32_t _flags; +}; + +static inline struct exthdr *exthdr_init(void) +{ + struct exthdr *exthdr = calloc(1, sizeof(*exthdr)); + + exthdr->expr.type = EXTHDR; + + exthdr->sreg = &exthdr->_sreg; + exthdr->dreg = &exthdr->_dreg; + exthdr->offset = &exthdr->_offset; + exthdr->len = &exthdr->_len; + exthdr->type = &exthdr->_type; + exthdr->op = &exthdr->_op; + exthdr->flags = &exthdr->_flags; + + return exthdr; +} + +static inline void free_exthdr(struct exthdr *exthdr) +{ + free(exthdr); +} + +struct fib { + struct expr expr; + + uint32_t *flags; + uint32_t *result; + uint32_t *dreg; + + /* storage */ + uint32_t _flags; + uint32_t _result; + uint32_t _dreg; +}; + +static inline struct fib *fib_init(void) +{ + struct fib *fib = calloc(1, sizeof(*fib)); + + fib->expr.type = FIB; + + fib->flags = &fib->_flags; + fib->result = &fib->_result; + fib->dreg = &fib->_dreg; + + return fib; +} + +static inline void free_fib(struct fib *fib) +{ + free(fib); +} + +struct fwd { + struct expr expr; + + uint32_t *sreg_addr; + uint32_t *sreg_dev; + uint32_t *nfproto; + + uint32_t _sreg_addr; + uint32_t _sreg_dev; + uint32_t _nfproto; +}; + +static inline struct fwd *fwd_init(void) +{ + struct fwd *fwd = calloc(1, sizeof(*fwd)); + + fwd->expr.type = FWD; + + fwd->sreg_addr = &fwd->_sreg_addr; + fwd->sreg_dev = &fwd->_sreg_dev; + fwd->nfproto = &fwd->_nfproto; + + return fwd; +} + +static inline void free_fwd(struct fwd *fwd) +{ + free(fwd); +} + +struct hash { + struct expr expr; + + uint32_t *type; + uint32_t *sreg; + uint32_t *dreg; + uint32_t *len; + uint32_t *modulus; + uint32_t *seed; + uint32_t *offset; + + uint32_t _type; + uint32_t _sreg; + uint32_t _dreg; + uint32_t _len; + uint32_t _modulus; + uint32_t _seed; + uint32_t _offset; +}; + +static inline struct hash *hash_init(void) +{ + struct hash *hash = calloc(1, sizeof(*hash)); + + hash->expr.type = HASH; + + hash->type = &hash->_type; + hash->sreg = &hash->_sreg; + hash->dreg = &hash->_dreg; + hash->len = &hash->_len; + hash->modulus = &hash->_modulus; + hash->seed = &hash->_seed; + hash->offset = &hash->_offset; + + return hash; +} + +static inline void free_hash(struct hash *hash) +{ + free(hash); +} + +struct inner { + struct expr expr; + + uint32_t _num; + uint32_t _type; + uint32_t _flags; + uint32_t _hdrsize; + + uint32_t *num; + uint32_t *type; + uint32_t *flags; + uint32_t *hdrsize; + + struct list_head expr_list; +}; + +static inline struct inner *inner_init(void) +{ + struct inner *inner = calloc(1, sizeof(*inner)); + + inner->expr.type = INNER; + + inner->num = &inner->_num; + inner->type = &inner->_type; + inner->flags = &inner->_flags; + inner->hdrsize = &inner->_hdrsize; + + INIT_LIST_HEAD(&inner->expr_list); + + return inner; +} + +void free_expr_list(struct list_head *expr_list); + +static inline void free_inner(struct inner *inner) +{ + free_expr_list(&inner->expr_list); + free(inner); +} + +struct immediate { + struct expr expr; + + const char *chain; + + uint32_t *dreg; + uint32_t *chain_id; + uint32_t *verdict; + uint8_t *data; + int data_len; + + uint32_t _dreg; + uint32_t _chain_id; + uint32_t _verdict; + uint8_t _data[16]; +}; + +static inline struct immediate *immediate_init(void) +{ + struct immediate *imm = calloc(1, sizeof(*imm)); + + imm->expr.type = IMMEDIATE; + + imm->dreg = &imm->_dreg; + imm->chain_id = &imm->_chain_id; + imm->verdict = &imm->_verdict; + imm->data = imm->_data; + + return imm; +} + +static inline void free_immediate(struct immediate *immediate) +{ + free((void *)immediate->chain); + free(immediate); +} + +struct last { + struct expr expr; + + uint64_t *msecs; + uint32_t *set; + + /* storage */ + uint64_t _msecs; + uint32_t _set; +}; + +static inline struct last *last_init(void) +{ + struct last *last = calloc(1, sizeof(*last)); + + last->expr.type = LAST; + + last->msecs = &last->_msecs; + last->set = &last->_set; + + return last; +} + +static inline void free_last(struct last *last) +{ + free(last); +} + +struct limit { + struct expr expr; + + uint64_t *rate; + uint64_t *unit; + uint32_t *burst; + uint32_t *type; + uint32_t *flags; + + /* storage */ + uint64_t _rate; + uint64_t _unit; + uint32_t _burst; + uint32_t _type; + uint32_t _flags; +}; + +static inline struct limit *limit_init(void) +{ + struct limit *limit = calloc(1, sizeof(*limit)); + + limit->expr.type = LIMIT; + + limit->rate = &limit->_rate; + limit->unit = &limit->_unit; + limit->burst = &limit->_burst; + limit->type = &limit->_type; + limit->flags = &limit->_flags; + + return limit; +} + +static inline void free_limit(struct limit *limit) +{ + free(limit); +} + +struct log { + struct expr expr; + + const char *prefix; + + uint32_t *snaplen; + uint16_t *group; + uint16_t *qthreshold; + uint32_t *level; + uint32_t *flags; + + /* storage */ + uint32_t _snaplen; + uint16_t _group; + uint16_t _qthreshold; + uint32_t _level; + uint32_t _flags; +}; + +static inline struct log *log_init(void) +{ + struct log *log = calloc(1, sizeof(*log)); + + log->expr.type = LOG; + + log->snaplen = &log->_snaplen; + log->group = &log->_group; + log->qthreshold = &log->_qthreshold; + log->level = &log->_level; + log->flags = &log->_flags; + + return log; +} + +static inline void free_log(struct log *log) +{ + free((void *)log->prefix); + free(log); +} + +struct lookup { + struct expr expr; + + const char *set; + uint32_t *set_id; + uint32_t *sreg; + uint32_t *dreg; + uint32_t *flags; + + /* storage */ + uint32_t _set_id; + uint32_t _sreg; + uint32_t _dreg; +}; + +static inline struct lookup *lookup_init(void) +{ + struct lookup *lookup = calloc(1, sizeof(*lookup)); + + lookup->expr.type = LOOKUP; + + lookup->set_id = &lookup->_set_id; + lookup->sreg = &lookup->_sreg; + lookup->dreg = &lookup->_dreg; + lookup->flags = NULL; // TODO + + return lookup; +} + +static inline void free_lookup(struct lookup *lookup) +{ + free((void *)lookup->set); + free(lookup); +} + +struct masq { + struct expr expr; + + uint32_t *sreg_proto_min; + uint32_t *sreg_proto_max; + uint32_t *flags; + + uint32_t _sreg_proto_min; + uint32_t _sreg_proto_max; + uint32_t _flags; +}; + +static inline struct masq *masq_init(void) +{ + struct masq *masq = calloc(1, sizeof(*masq)); + + masq->expr.type = MASQ; + + masq->sreg_proto_min = &masq->_sreg_proto_min; + masq->sreg_proto_max = &masq->_sreg_proto_max; + masq->flags = &masq->_flags; + + return masq; +} + +static inline void free_masq(struct masq *masq) +{ + free(masq); +} + +struct match { + struct expr expr; + + const char *name; + + uint32_t *rev; + uint8_t *data; + int data_len; + uint32_t *l4proto; + uint32_t *flags; + + /* storage */ + uint32_t _rev; + uint8_t _data[65536]; + uint32_t _l4proto; + uint32_t _flags; +}; + +static inline struct match *match_init(void) +{ + struct match *match = calloc(1, sizeof(*match)); + + match->expr.type = MATCH; + + match->rev = &match->_rev; + match->data = match->_data; + match->l4proto = &match->_l4proto; + match->flags = &match->_flags; + + return match; +} + +static inline void free_match(struct match *match) +{ + free((void *)match->name); + free(match); +} + +struct meta { + struct expr expr; + + uint32_t *sreg; + uint32_t *dreg; + uint32_t *key; + + uint32_t _sreg; + uint32_t _dreg; + uint32_t _key; +}; + +static inline struct meta *meta_init(void) +{ + struct meta *meta = calloc(1, sizeof(*meta)); + + meta->expr.type = META; + + meta->sreg = &meta->_sreg; + meta->dreg = &meta->_dreg; + meta->key = &meta->_key; + + return meta; +} + +static inline void free_meta(struct meta *meta) +{ + free(meta); +} + +struct nat { + struct expr expr; + + uint32_t *sreg_addr_min; + uint32_t *sreg_addr_max; + uint32_t *sreg_proto_min; + uint32_t *sreg_proto_max; + uint32_t *nfproto; + uint32_t *type; + uint32_t *flags; + + uint32_t _sreg_addr_min; + uint32_t _sreg_addr_max; + uint32_t _sreg_proto_min; + uint32_t _sreg_proto_max; + uint32_t _nfproto; + uint32_t _type; + uint32_t _flags; +}; + +static inline struct nat *nat_init(void) +{ + struct nat *nat = calloc(1, sizeof(*nat)); + + nat->expr.type = NAT; + + nat->sreg_addr_min = &nat->_sreg_addr_min; + nat->sreg_addr_max = &nat->_sreg_addr_max; + nat->sreg_proto_min = &nat->_sreg_proto_min; + nat->sreg_proto_max = &nat->_sreg_proto_max; + nat->nfproto = &nat->_nfproto; + nat->type = &nat->_type; + nat->flags = &nat->_flags; + + return nat; +} + +static inline void free_nat(struct nat *nat) +{ + free(nat); +} + +struct numgen { + struct expr expr; + + uint32_t *dreg; + uint32_t *modulus; + uint32_t *type; + uint32_t *offset; + + uint32_t _dreg; + uint32_t _modulus; + uint32_t _type; + uint32_t _offset; +}; + +static inline struct numgen *numgen_init(void) +{ + struct numgen *numgen = calloc(1, sizeof(*numgen)); + + numgen->expr.type = NUMGEN; + + numgen->dreg = &numgen->_dreg; + numgen->modulus = &numgen->_modulus; + numgen->type = &numgen->_type; + numgen->offset = &numgen->_offset; + + return numgen; +} + +static inline void free_numgen(struct numgen *numgen) +{ + free(numgen); +} + +struct objref { + struct expr expr; + + const char *set_name; + const char *name; + + uint32_t *type; + uint32_t *sreg; + uint32_t *set_id; + + uint32_t _type; + uint32_t _sreg; + uint32_t _set_id; +}; + +static inline struct objref *objref_init(void) +{ + struct objref *objref = calloc(1, sizeof(*objref)); + + objref->expr.type = OBJREF; + + objref->type = &objref->_type; + objref->sreg = &objref->_sreg; + objref->set_id = &objref->_set_id; + + return objref; +} + +static inline void free_objref(struct objref *objref) +{ + free((void *)objref->set_name); + free((void *)objref->name); + free(objref); +} + +struct osf { + struct expr expr; + + uint32_t *dreg; + uint32_t *ttl; + uint32_t *flags; + + uint32_t _dreg; + uint32_t _ttl; + uint32_t _flags; +}; + +static inline struct osf *osf_init(void) +{ + struct osf *osf = calloc(1, sizeof(*osf)); + + osf->expr.type = OSF; + + osf->dreg = &osf->_dreg; + osf->ttl = &osf->_ttl; + osf->flags = &osf->_flags; + + return osf; +} + +static inline void free_osf(struct osf *osf) +{ + free(osf); +} + +struct payload { + struct expr expr; + + uint32_t *sreg; + uint32_t *dreg; + uint32_t *offset; + uint32_t *base; + uint32_t *len; + uint32_t *csum_type; + uint32_t *csum_offset; + uint32_t *csum_flags; + + /* storage */ + uint32_t _sreg; + uint32_t _dreg; + uint32_t _offset; + uint32_t _base; + uint32_t _len; + uint32_t _csum_type; + uint32_t _csum_offset; + uint32_t _csum_flags; +}; + +static inline struct payload *payload_init(void) +{ + struct payload *payload = calloc(1, sizeof(*payload)); + + payload->expr.type = PAYLOAD; + + payload->sreg = &payload->_sreg; + payload->dreg = &payload->_dreg; + payload->offset = &payload->_offset; + payload->base = &payload->_base; + payload->len = &payload->_len; + payload->csum_type = &payload->_csum_type; + payload->csum_offset = &payload->_csum_offset; + payload->csum_flags = &payload->_csum_flags; + + return payload; +} + +static inline void free_payload(struct payload *payload) +{ + free(payload); +} + +struct queue { + struct expr expr; + + uint32_t *sreg_qnum; + uint16_t *queue_num; + uint16_t *queue_total; + uint16_t *flags; + + uint32_t _sreg_qnum; + uint16_t _queue_num; + uint16_t _queue_total; + uint16_t _flags; +}; + +static inline struct queue *queue_init(void) +{ + struct queue *queue = calloc(1, sizeof(*queue)); + + queue->expr.type = QUEUE; + + queue->sreg_qnum = &queue->_sreg_qnum; + queue->queue_num = &queue->_queue_num; + queue->queue_total = &queue->_queue_total; + queue->flags = &queue->_flags; + + return queue; +} + +static inline void free_queue(struct queue *queue) +{ + free(queue); +} + +struct quota { + struct expr expr; + + uint64_t *bytes; + uint64_t *consumed; + uint32_t *flags; + + /* storage */ + uint64_t _bytes; + uint64_t _consumed; + uint32_t _flags; +}; + +static inline struct quota *quota_init(void) +{ + struct quota *quota = calloc(1, sizeof(*quota)); + + quota->expr.type = QUOTA; + + quota->bytes = "a->_bytes; + quota->consumed = "a->_consumed; + quota->flags = "a->_flags; + + return quota; +} + +static inline void free_quota(struct quota *quota) +{ + free(quota); +} + +struct range { + struct expr expr; + + uint32_t *sreg; + uint32_t *op; + uint8_t *data_from; + int data_from_len; + uint8_t *data_to; + int data_to_len; + + uint32_t _sreg; + uint32_t _op; + uint8_t _data_from[16]; + uint8_t _data_to[16]; +}; + +static inline struct range *range_init(void) +{ + struct range *range = calloc(1, sizeof(*range)); + + range->expr.type = RANGE; + + range->sreg = &range->_sreg; + range->op = &range->_op; + range->data_from = range->_data_from; + range->data_to = range->_data_to; + + return range; +} + +static inline void free_range(struct range *range) +{ + free(range); +} + +struct redir { + struct expr expr; + + uint32_t *sreg_proto_min; + uint32_t *sreg_proto_max; + uint32_t *flags; + + uint32_t _sreg_proto_min; + uint32_t _sreg_proto_max; + uint32_t _flags; +}; + +static inline struct redir *redir_init(void) +{ + struct redir *redir = calloc(1, sizeof(*redir)); + + redir->expr.type = REDIR; + + redir->sreg_proto_min = &redir->_sreg_proto_min; + redir->sreg_proto_max = &redir->_sreg_proto_max; + redir->flags = &redir->_flags; + + return redir; +} + +static inline void free_redir(struct redir *redir) +{ + free(redir); +} + +struct reject { + struct expr expr; + + uint32_t *type; + uint8_t *icmp_code; + + /* storage */ + uint32_t _type; + uint8_t _icmp_code; +}; + +static inline struct reject *reject_init(void) +{ + struct reject *reject = calloc(1, sizeof(*reject)); + + reject->expr.type = REJECT; + + reject->type = &reject->_type; + reject->icmp_code = &reject->_icmp_code; + + return reject; +} + +static inline void free_reject(struct reject *reject) +{ + free(reject); +} + +struct rt { + struct expr expr; + + uint32_t *dreg; + uint32_t *key; + + uint32_t _dreg; + uint32_t _key; +}; + +static inline struct rt *rt_init(void) +{ + struct rt *rt = calloc(1, sizeof(*rt)); + + rt->expr.type = RT; + + rt->dreg = &rt->_dreg; + rt->key = &rt->_key; + + return rt; +} + +static inline void free_rt(struct rt *rt) +{ + free(rt); +} + +struct socket { + struct expr expr; + + uint32_t *dreg; + uint32_t *key; + uint32_t *level; + + uint32_t _dreg; + uint32_t _key; + uint32_t _level; +}; + +static inline struct socket *socket_init(void) +{ + struct socket *socket = calloc(1, sizeof(*socket)); + + socket->expr.type = SOCKET; + + socket->dreg = &socket->_dreg; + socket->key = &socket->_key; + socket->level = &socket->_level; + + return socket; +} + +static inline void free_socket(struct socket *socket) +{ + free(socket); +} + +struct synproxy { + struct expr expr; + + uint16_t *mss; + uint8_t *wscale; + uint32_t *flags; + + /* storage */ + uint16_t _mss; + uint8_t _wscale; + uint32_t _flags; +}; + +static inline struct synproxy *synproxy_init(void) +{ + struct synproxy *synproxy = calloc(1, sizeof(*synproxy)); + + synproxy->expr.type = SYNPROXY; + + synproxy->mss = &synproxy->_mss; + synproxy->wscale = &synproxy->_wscale; + synproxy->flags = &synproxy->_flags; + + return synproxy; +} + +static inline void free_synproxy(struct synproxy *synproxy) +{ + free(synproxy); +} + +struct target { + struct expr expr; + + const char *name; + + uint32_t *rev; + uint8_t *data; + int data_len; + uint32_t *l4proto; + uint32_t *flags; + + /* storage */ + uint32_t _rev; + uint8_t _data[65536]; + uint32_t _l4proto; + uint32_t _flags; +}; + +static inline struct target *target_init(void) +{ + struct target *target = calloc(1, sizeof(*target)); + + target->expr.type = TARGET; + + target->rev = &target->_rev; + target->data = target->_data; + target->l4proto = &target->_l4proto; + target->flags = &target->_flags; + + return target; +} + +static void free_target(struct target *target) +{ + free((void *)target->name); + free(target); +} + +struct tproxy { + struct expr expr; + + uint32_t *nfproto; + uint32_t *sreg_addr; + uint32_t *sreg_port; + + uint32_t _nfproto; + uint32_t _sreg_addr; + uint32_t _sreg_port; +}; + +static inline struct tproxy *tproxy_init(void) +{ + struct tproxy *tproxy = calloc(1, sizeof(*tproxy)); + + tproxy->expr.type = TPROXY; + + tproxy->nfproto = &tproxy->_nfproto; + tproxy->sreg_addr = &tproxy->_sreg_addr; + tproxy->sreg_port = &tproxy->_sreg_port; + + return tproxy; +} + +static inline void free_tproxy(struct tproxy *tproxy) +{ + free(tproxy); +} + +struct tunnel { + struct expr expr; + + uint32_t *dreg; + uint32_t *key; +// uint32_t *mode; + + uint32_t _dreg; + uint32_t _key; +//XXX uint32_t _mode; +}; + +static inline struct tunnel *tunnel_init(void) +{ + struct tunnel *tunnel = calloc(1, sizeof(*tunnel)); + + tunnel->expr.type = TUNNEL; + + tunnel->dreg = &tunnel->_dreg; + tunnel->key = &tunnel->_key; +//XXX tunnel->mode = &tunnel->_mode; + + return tunnel; +} + +static inline void free_tunnel(struct tunnel *tunnel) +{ + free(tunnel); +} + +struct xfrm { + struct expr expr; + + uint32_t *dreg; + uint32_t *key; + uint32_t *spnum; + uint8_t *dir; + + uint32_t _dreg; + uint32_t _key; + uint32_t _spnum; + uint8_t _dir; +}; + +static inline struct xfrm *xfrm_init(void) +{ + struct xfrm *xfrm = calloc(1, sizeof(*xfrm)); + + xfrm->expr.type = XFRM; + + xfrm->dreg = &xfrm->_dreg; + xfrm->key = &xfrm->_key; + xfrm->spnum = &xfrm->_spnum; + xfrm->dir = &xfrm->_dir; + + return xfrm; +} + +static inline void free_xfrm(struct xfrm *xfrm) +{ + free(xfrm); +} + +struct ct_helper { + const char *name; + uint8_t *l4proto; + uint16_t *l3proto; + + /* storage */ + uint8_t _l4proto; + uint16_t _l3proto; +}; + +static inline struct ct_helper *ct_helper_init(void) +{ + struct ct_helper *ct_helper = calloc(1, sizeof(*ct_helper)); + + ct_helper->l4proto = &ct_helper->_l4proto; + ct_helper->l3proto = &ct_helper->_l3proto; + + return ct_helper; +} + +struct ct_timeout { + const char *name; + uint8_t *l4proto; + uint16_t *l3proto; + struct array_u32 *timeout_array; + + /* storage */ + uint8_t _l4proto; + uint16_t _l3proto; +}; + +static inline struct ct_timeout *ct_timeout_init(void) +{ + struct ct_timeout *ct_timeout = calloc(1, sizeof(*ct_timeout)); + + ct_timeout->l4proto = &ct_timeout->_l4proto; + ct_timeout->l3proto = &ct_timeout->_l3proto; + + return ct_timeout; +} + +struct ct_expect { + const char *name; + uint8_t *l4proto; + uint16_t *l3proto; + uint16_t *dport; + uint32_t *timeout; + uint8_t *size; + + /* storage */ + uint8_t _l4proto; + uint16_t _l3proto; + uint16_t _dport; + uint32_t _timeout; + uint8_t _size; +}; + +static inline struct ct_expect *ct_expect_init(void) +{ + struct ct_expect *ct_expect = calloc(1, sizeof(*ct_expect)); + + ct_expect->l4proto = &ct_expect->_l4proto; + ct_expect->l3proto = &ct_expect->_l3proto; + ct_expect->dport = &ct_expect->_dport; + ct_expect->timeout = &ct_expect->_timeout; + ct_expect->size = &ct_expect->_size; + + return ct_expect; +} + +struct tunnel_tmpl { + uint32_t *id; + uint32_t *flags; + uint16_t *sport; + uint16_t *dport; + uint8_t *tos; + uint8_t *ttl; + uint32_t *src_v4; + uint8_t *src_v6; + uint32_t *dst_v4; + uint8_t *dst_v6; + uint32_t *flowlabel; + + /* storage */ + uint32_t _id; + uint32_t _flags; + uint16_t _sport; + uint16_t _dport; + uint8_t _tos; + uint8_t _ttl; + uint32_t _src_v4; + uint8_t _src_v6[16]; + uint32_t _dst_v4; + uint8_t _dst_v6[16]; + uint32_t _flowlabel; +}; + +static inline struct tunnel_tmpl *tunnel_tmpl_init(void) +{ + struct tunnel_tmpl *tunnel = calloc(1, sizeof(*tunnel)); + + tunnel->id = &tunnel->_id; + tunnel->flags = &tunnel->_flags; + tunnel->sport = &tunnel->_sport; + tunnel->dport = &tunnel->_dport; + tunnel->tos = &tunnel->_tos; + tunnel->ttl = &tunnel->_ttl; + tunnel->src_v4 = &tunnel->_src_v4; + tunnel->src_v6 = tunnel->_src_v6; + tunnel->dst_v4 = &tunnel->_dst_v4; + tunnel->dst_v6 = tunnel->_dst_v6; + tunnel->flowlabel = &tunnel->_flowlabel; + + return tunnel; +} + +struct secmark { + char *ctx; +}; + +static inline struct secmark *secmark_init(void) +{ + struct secmark *secmark = calloc(1, sizeof(*secmark)); + + return secmark; +} + +struct obj { + const char *table; + const char *name; + uint64_t *handle; + const char *userdata; + uint32_t *type; + uint32_t *family; + + union { + struct counter *counter; + struct quota *quota; + struct ct_helper *ct_helper; + struct limit *limit; + struct connlimit *connlimit; + struct tunnel_tmpl *tun; + struct ct_timeout *ct_timeout; + struct ct_expect *ct_expect; + struct secmark *secmark; + struct synproxy *synproxy; + } u; + + /* storage */ + uint32_t _type; + uint32_t _family; + uint64_t _handle; +}; + +static inline struct obj *obj_init(void) +{ + struct obj *obj = calloc(1, sizeof(*obj)); + + obj->type = &obj->_type; + obj->family = &obj->_family; + obj->handle = &obj->_handle; + + return obj; +} + +void add_obj(struct test_batch *batch, struct obj *obj); +void del_obj(struct test_batch *batch, struct obj *obj); +void free_obj(struct obj *obj); + +int batch_commit(struct test_batch *batch); +int batch_abort(struct test_batch *batch); + +static inline bool batch_empty(struct test_batch *batch) +{ + return list_empty(&batch->cmd); +} + +void batch_reset(struct test_batch *batch); +void batch_stop(struct test_batch *batch); + +int flush_ruleset(struct mnl_socket *nl); + +struct array *array_alloc(void); +bool array_add(struct array *array, void *data); +void array_free(struct array *array); + +struct array_u8 *array_u8_alloc(void); +bool array_u8_add(struct array_u8 *array, const char *data); +void array_u8_free(struct array_u8 *array); + +struct array_u32 *array_u32_alloc(void); +bool array_u32_add(struct array_u32 *array, const char *value); +void array_u32_free(struct array_u32 *array); + +bool kernel_is_tainted(void); +int list_hooks(struct mnl_socket *nl); + +#endif |