dect
/
libnl
Archived
13
0
Fork 0

"checkpoint"

This commit is contained in:
Rich Fought 2012-10-05 17:32:20 -07:00
parent 20035ce021
commit e8b3356dd2
3 changed files with 354 additions and 253 deletions

View File

@ -817,10 +817,10 @@ struct nfnl_exp {
char * exp_fn; //optional
uint8_t exp_nat_dir; // optional
struct nfnl_ct_dir exp_expect; // required
struct nfnl_ct_dir exp_master; // required
struct nfnl_ct_dir exp_mask; // required
struct nfnl_ct_dir exp_nat; // optional
struct nfnl_exp_dir exp_expect; // required
struct nfnl_exp_dir exp_master; // required
struct nfnl_exp_dir exp_mask; // required
struct nfnl_exp_dir exp_nat; // optional
};
struct nfnl_log {

View File

@ -26,10 +26,10 @@ extern "C" {
struct nfnl_exp;
enum nfnl_exp_tuples {
NFNL_EXP_EXPECT,
NFNL_EXP_MASTER,
NFNL_EXP_MASK,
NFNL_EXP_NAT
NFNL_EXP_TUPLE_EXPECT,
NFNL_EXP_TUPLE_MASTER,
NFNL_EXP_TUPLE_MASK,
NFNL_EXP_TUPLE_NAT
};
extern struct nl_object_ops exp_obj_ops;
@ -98,31 +98,28 @@ extern uint8_t nfnl_exp_get_nat_dir(const struct nfnl_exp *, int);
// The int argument specifies which nfnl_ct_dir (expect, master, mask or nat)
// Expectation objects only use orig, not reply
extern int nfnl_exp_test_tuple(const struct nfnl_exp *, int);
extern int nfnl_exp_set_src(struct nfnl_exp *, int, struct nl_addr *);
extern int nfnl_exp_test_src(const struct nfnl_exp *);
extern struct nl_addr * nfnl_ct_get_src(const struct nfnl_exp *, int);
extern int nfnl_exp_set_dst(struct nfnl_exp *, int, struct nl_addr *);
extern int nfnl_exp_test_dst(const struct nfnl_exp *);
extern struct nl_addr * nfnl_exp_get_dst(const struct nfnl_exp *, int);
extern int nfnl_exp_set_l4proto(struct nfnl_exp *, int, uint8_t);
extern int nfnl_exp_test_l4proto(const struct nfnl_exp *);
extern struct uint8_t * nfnl_exp_get_l4proto(const struct nfnl_exp *, int);
extern void nfnl_exp_set_l4protonum(struct nfnl_exp *, int, uint8_t);
extern int nfnl_exp_test_l4protonum(const struct nfnl_exp *, int);
extern uint8_t * nfnl_exp_get_l4protonum(const struct nfnl_exp *, int);
extern void nfnl_exp_set_src_port(struct nfnl_exp *, int, uint16_t);
extern void nfnl_exp_set_ports(struct nfnl_exp *, int, uint16_t, uint16_t);
extern int nfnl_exp_test_ports(const struct nfnl_exp *, int);
extern uint16_t nfnl_exp_get_src_port(const struct nfnl_exp *, int);
extern void nfnl_exp_set_dst_port(struct nfnl_exp *, int, uint16_t);
extern uint16_t nfnl_exp_get_dst_port(const struct nfnl_exp *, int);
extern void nfnl_exp_set_icmp_id(struct nfnl_exp *, int, uint16_t);
extern void nfnl_exp_set_icmp(struct nfnl_exp *, int, uint16_t, uint8_t, uint8_t);
extern int nfnl_exp_test_icmp(const struct nfnl_exp *, int);
extern uint16_t nfnl_exp_get_icmp_id(const struct nfnl_exp *, int);
extern void nfnl_exp_set_icmp_type(struct nfnl_exp *, int, uint8_t);
extern uint8_t nfnl_exp_get_icmp_type(const struct nfnl_exp *, int);
extern void nfnl_exp_set_icmp_code(struct nfnl_exp *, int, uint8_t);
extern uint8_t nfnl_exp_get_icmp_code(const struct nfnl_exp *, int);
// TODO: Expectation table does support CPU stats get command, not sure if the same

View File

@ -28,34 +28,38 @@
// these parent attributes will include nested attributes.
/** @cond SKIP */
#define EXP_ATTR_FAMILY (1UL << 0)
#define EXP_ATTR_TIMEOUT (1UL << 1) // 32-bit
#define EXP_ATTR_ID (1UL << 2) // 32-bit
#define EXP_ATTR_HELPER_NAME (1UL << 3) // string (16 bytes max)
#define EXP_ATTR_ZONE (1UL << 4) // 16-bit
#define EXP_ATTR_CLASS (1UL << 5) // 32-bit
#define EXP_ATTR_FLAGS (1UL << 6) // 32-bit
#define EXP_ATTR_FN (1UL << 7) // String
#define EXP_ATTR_FAMILY (1UL << 0) // 8-bit
#define EXP_ATTR_TIMEOUT (1UL << 1) // 32-bit
#define EXP_ATTR_ID (1UL << 2) // 32-bit
#define EXP_ATTR_HELPER_NAME (1UL << 3) // string (16 bytes max)
#define EXP_ATTR_ZONE (1UL << 4) // 16-bit
#define EXP_ATTR_CLASS (1UL << 5) // 32-bit
#define EXP_ATTR_FLAGS (1UL << 6) // 32-bit
#define EXP_ATTR_FN (1UL << 7) // String
// Tuples
#define EXP_ATTR_EXPECT (1UL << 8) // contains ip, proto
#define EXP_ATTR_EXPECT_IP (1UL << 9) // contains src, dst
#define EXP_ATTR_EXPECT_L4PROTO (1UL << 10) // contains l4proto # + PORT attrs or ICMP attrs
#define EXP_ATTR_EXPECT_L4PROTO_NUM (1UL << 11)
#define EXP_ATTR_MASTER (1UL << 12) // contains ip, proto
#define EXP_ATTR_MASTER_IP (1UL << 13) // contains src, dst
#define EXP_ATTR_MASTER_L4PROTO (1UL << 14) // contains l4proto # + PORT attrs or ICMP attrs
#define EXP_ATTR_MASTER_L4PROTO_NUM (1UL << 15)
#define EXP_ATTR_MASK (1UL << 16) // contains ip, proto
#define EXP_ATTR_MASK_IP (1UL << 17) // contains src, dst
#define EXP_ATTR_MASK_L4PROTO (1UL << 18) // contains l4proto # + PORT attrs or ICMP attrs
#define EXP_ATTR_MASK_L4PROTO_NUM (1UL << 19)
#define EXP_ATTR_NAT (1UL << 20) // contains ip, proto
#define EXP_ATTR_NAT_IP (1UL << 21) // contains src, dst
#define EXP_ATTR_NAT_L4PROTO (1UL << 22) // contains l4proto # + PORT attrs or ICMP attrs
#define EXP_ATTR_NAT_L4PROTO_NUM (1UL << 23)
#define EXP_ATTR_EXPECT_IP_SRC (1UL << 8)
#define EXP_ATTR_EXPECT_IP_DST (1UL << 9)
#define EXP_ATTR_EXPECT_L4PROTO_NUM (1UL << 10) // contains l4proto # + PORT attrs or ICMP attrs
#define EXP_ATTR_EXPECT_L4PROTO_PORTS (1UL << 11)
#define EXP_ATTR_EXPECT_L4PROTO_ICMP (1UL << 12)
#define EXP_ATTR_MASTER_IP_SRC (1UL << 13)
#define EXP_ATTR_MASTER_IP_DST (1UL << 14)
#define EXP_ATTR_MASTER_L4PROTO_NUM (1UL << 15) // contains l4proto # + PORT attrs or ICMP attrs
#define EXP_ATTR_MASTER_L4PROTO_PORTS (1UL << 16)
#define EXP_ATTR_MASTER_L4PROTO_ICMP (1UL << 17)
#define EXP_ATTR_MASK_IP_SRC (1UL << 18)
#define EXP_ATTR_MASK_IP_DST (1UL << 19)
#define EXP_ATTR_MASK_L4PROTO_NUM (1UL << 20) // contains l4proto # + PORT attrs or ICMP attrs
#define EXP_ATTR_MASK_L4PROTO_PORTS (1UL << 21)
#define EXP_ATTR_MASK_L4PROTO_ICMP (1UL << 22)
#define EXP_ATTR_NAT_IP_SRC (1UL << 23)
#define EXP_ATTR_NAT_IP_DST (1UL << 24)
#define EXP_ATTR_NAT_L4PROTO_NUM (1UL << 25) // contains l4proto # + PORT attrs or ICMP attrs
#define EXP_ATTR_NAT_L4PROTO_PORTS (1UL << 26)
#define EXP_ATTR_NAT_L4PROTO_ICMP (1UL << 27)
#define EXP_ATTR_NAT_DIR (1UL << 24)
#define EXP_ATTR_NAT_DIR (1UL << 28)
/** @endcond */
static void exp_free_data(struct nl_object *c)
@ -145,6 +149,12 @@ static int exp_clone(struct nl_object *_dst, struct nl_object *_src)
dst->exp_nat.dst = addr;
}
if (src->exp_fn)
dst->exp_fn = strdup(src->exp_fn)
if (src->exp_helper_name)
dst->exp_helper_name = strdup(src->exp_helper_name);
return 0;
}
@ -174,15 +184,16 @@ static void ct_dump_tuples(struct nfnl_exp *exp, struct nl_dump_params *p)
{
struct nl_addr *tuple_src, *tuple_dst;
int tuple_sport = 0, tuple_dport = 0;
int i = NFNL_EXP_EXPECT;
int i = NFNL_EXP_TUPLE_EXPECT;
int icmp = 0;
for (i; i <= NFNL_EXP_NAT; i++) {
for (i; i <= NFNL_EXP_TUPLE_NAT; i++) {
if (nfnl_exp_test_tuple(exp, i)) {
tuple_src = nfnl_ct_get_src(exp, i);
tuple_dst = nfnl_ct_get_dst(exp, i);
// Test needed for NAT case
if (nfnl_exp_test_src(exp, i))
tuple_src = nfnl_exp_get_src(exp, i);
if (nfnl_exp_test_dst(exp, i))
tuple_dst = nfnl_exp_get_dst(exp, i);
// Don't have tests for individual ports/types/codes/ids,
// just test L4 Proto. Ugly, but can't do much else without
@ -294,75 +305,23 @@ static void ct_dump_stats(struct nl_object *a, struct nl_dump_params *p)
}
*/
static int exp_cmp_tuples_loose(struct nfnl_ct_dir *a, struct nfnl_ct_dir *b)
{
static int exp_cmp_l4proto_ports (union nfnl_exp_protodata *a, union nfnl_exp_protodata *b) {
// Must return 0 for match, 1 for mismatch
// Parent attribute, so must reflect lower level attribute diffs
int d = exp_cmp_tuples_ip_loose(a, b);
if (d == 0) {
d = exp_cmp_tuples_proto(&a->proto, &b->proto))
}
return d;
}
static int exp_cmp_tuples(struct nfnl_exp_dir *a, struct nfnl_exp_dir *b)
{
// Must return 0 for match, 1 for mismatch
// Parent attribute, so must reflect lower level attribute diffs
int d = exp_cmp_tuples_ip(a, b);
if (d == 0) {
d = exp_cmp_tuples_proto(&a->proto, &b->proto))
}
return d;
}
static int exp_cmp_tuples_ip_loose(struct nfnl_exp_dir *a, struct nfnl_exp_dir *b) {
// Must return 0 for match, 1 for mismatch
int d = nl_addr_cmp_prefix(a->src, b->src);
if (d == 0) {
d = nl_addr_cmp_prefix(a->dst, b->dst);
}
return d;
}
static int exp_cmp_tuples_ip(struct nfnl_exp_dir *a, struct nfnl_exp_dir *b) {
// Must return 0 for match, 1 for mismatch
int d = nl_addr_cmp(a->src, b->src);
if (d == 0) {
d = nl_addr_cmp(a->dst, b->dst);
}
return d;
}
static int exp_cmp_tuples_proto(struct nfnl_exp_proto *a, struct nfnl_exp_proto *b) {
// Must return 0 for match, 1 for mismatch
// Parent attribute, so must reflect lower level attribute diffs
int d = exp_cmp_tuples_protonum(a->l4protonum, b->l4protonum);
if (d == 0) {
// Check actual proto data
if (a->l4protonum == IPPROTO_ICMP ||
a->l4protonum == IPPROTO_ICMPV6) {
d == ( (a->l4protodata.icmp.code != b->l4protodata.icmp.code) ||
(a->l4protodata.icmp.type != b->l4protodata.icmp.type) ||
(a->l4protodata.icmp.id != b->l4protodata.icmp.id) )
} else {
d == ( (a->l4protodata.port.src != b->l4protodata.port.src) ||
(a->l4protodata.port.dst != b->l4protodata.icmp.dst) )
}
}
int d = 0;
d = ( (a->port.src != b->port.src) ||
(a->port.dst != b->port.dst) );
return d;
}
static int exp_cmp_tuples_protonum(uint8_t a, uint8_t b) {
static int exp_cmp_l4proto_icmp (union nfnl_exp_protodata *a, union nfnl_exp_protodata *b) {
// Must return 0 for match, 1 for mismatch
return (a != b)
int d = 0;
d = ( (a->icmp.code != b->icmp.code) ||
(a->icmp.type != b->icmp.type) ||
(a->icmp.id != b->icmp.id) );
return d;
}
static int exp_compare(struct nl_object *_a, struct nl_object *_b,
@ -374,73 +333,97 @@ static int exp_compare(struct nl_object *_a, struct nl_object *_b,
#define EXP_DIFF(ATTR, EXPR) ATTR_DIFF(attrs, EXP_ATTR_##ATTR, a, b, EXPR)
#define EXP_DIFF_VAL(ATTR, FIELD) EXP_DIFF(ATTR, a->FIELD != b->FIELD)
#define EXP_DIFF_STRING(ATTR, FIELD) EXP_DIFF(ATTR, (strncmp(a->FIELD, b->FIELD, 16) != 0))
#define EXP_DIFF_STRING(ATTR, FIELD) EXP_DIFF(ATTR, (strcmp(a->FIELD, b->FIELD) != 0))
#define EXP_DIFF_ADDR(ATTR, FIELD) \
((flags & LOOSE_COMPARISON) \
? EXP_DIFF(ATTR, nl_addr_cmp_prefix(a->FIELD, b->FIELD)) \
: EXP_DIFF(ATTR, nl_addr_cmp(a->FIELD, b->FIELD)))
#define EXP_DIFF_L4PROTO_PORTS(ATTR, FIELD) \
EXP_DIFF(ATTR, exp_cmp_l4proto_ports(a->FIELD, b->FIELD))
#define EXP_DIFF_L4PROTO_ICMP(ATTR, FIELD) \
EXP_DIFF(ATTR, exp_cmp_l4proto_icmp(a->FIELD, b->FIELD))
#define EXP_DIFF_TUPLE(ATTR, FIELD) \
((flags & LOOSE_COMPARISON) \
? EXP_DIFF(ATTR, exp_cmp_tuples_loose(a->FIELD, b->FIELD)) \
: EXP_DIFF(ATTR, exp_cmp_tuples(a->FIELD, b->FIELD)))
diff |= EXP_DIFF_VAL(FAMILY, exp_family);
diff |= EXP_DIFF_VAL(TIMEOUT, exp_timeout);
diff |= EXP_DIFF_VAL(ID, exp_id);
diff |= EXP_DIFF_VAL(ZONE, exp_zone);
diff |= EXP_DIFF_VAL(CLASS, exp_class);
diff |= EXP_DIFF_VAL(FLAGS, exp_flags);
diff |= EXP_DIFF_VAL(NAT_DIR, exp_nat_dir);
#define EXP_DIFF_IP(ATTR, FIELD) \
((flags & LOOSE_COMPARISON) \
? EXP_DIFF(ATTR, exp_cmp_tuples_ip_loose(a->FIELD, b->FIELD)) \
: EXP_DIFF(ATTR, exp_cmp_tuples_ip(a->FIELD, b->FIELD)))
diff |= EXP_DIFF_STRING(FN, exp_fn);
diff |= EXP_DIFF_STRING(HELPER_NAME, exp_helper_name);
#define EXP_DIFF_PROTO(ATTR, FIELD) \
EXP_DIFF(ATTR, exp_cmp_tuples_proto(a->FIELD, b->FIELD))
diff |= EXP_DIFF_ADDR(EXPECT_IP_SRC, exp_expect.src);
diff |= EXP_DIFF_ADDR(EXPECT_IP_DST, exp_expect.dst);
diff |= EXP_DIFF_VAL(EXPECT_L4PROTO_NUM, exp_expect.proto.l4protonum);
diff |= EXP_DIFF_L4PROTO_PORTS(EXPECT_L4PROTO_PORTS, exp_expect.proto.l4protodata.port);
diff |= EXP_DIFF_L4PROTO_ICMP(EXPECT_L4PROTO_ICMP, exp_expect.proto.l4protodata.icmp);
diff |= EXP_DIFF_VAL(FAMILY, exp_family);
diff |= EXP_DIFF_VAL(TIMEOUT, exp_timeout);
diff |= EXP_DIFF_VAL(ID, exp_id);
diff |= EXP_DIFF_VAL(ZONE, exp_zone);
diff |= EXP_DIFF_VAL(CLASS, exp_class);
diff |= EXP_DIFF_VAL(FLAGS, exp_flags);
diff |= EXP_DIFF_VAL(NAT_DIR, exp_flags);
diff |= EXP_DIFF_ADDR(MASTER_IP_SRC, exp_master.src);
diff |= EXP_DIFF_ADDR(MASTER_IP_DST, exp_master.dst);
diff |= EXP_DIFF_VAL(MASTER_L4PROTO_NUM, exp_master.proto.l4protonum);
diff |= EXP_DIFF_L4PROTO_PORTS(MASTER_L4PROTO_PORTS, exp_master.proto.l4protodata.port);
diff |= EXP_DIFF_L4PROTO_ICMP(MASTER_L4PROTO_ICMP, exp_master.proto.l4protodata.icmp);
diff |= EXP_DIFF(FLAGS, (a->exp_flags ^ b->exp_flags));
diff |= EXP_DIFF_ADDR(MASK_IP_SRC, exp_mask.src);
diff |= EXP_DIFF_ADDR(MASK_IP_DST, exp_mask.dst);
diff |= EXP_DIFF_VAL(MASK_L4PROTO_NUM, exp_mask.proto.l4protonum);
diff |= EXP_DIFF_L4PROTO_PORTS(MASK_L4PROTO_PORTS, exp_mask.proto.l4protodata.port);
diff |= EXP_DIFF_L4PROTO_ICMP(MASK_L4PROTO_ICMP, exp_mask.proto.l4protodata.icmp);
#undef CT_DIFF
#undef CT_DIFF_VAL
diff |= EXP_DIFF_ADDR(NAT_IP_SRC, exp_nat.src);
diff |= EXP_DIFF_ADDR(NAT_IP_DST, exp_nat.dst);
diff |= EXP_DIFF_VAL(NAT_L4PROTO_NUM, exp_nat.proto.l4protonum);
diff |= EXP_DIFF_L4PROTO_PORTS(NAT_L4PROTO_PORTS, exp_nat.proto.l4protodata.port);
diff |= EXP_DIFF_L4PROTO_ICMP(NAT_L4PROTO_ICMP, exp_nat.proto.l4protodata.icmp);
#undef EXP_DIFF
#undef EXP_DIFF_VAL
#undef EXP_DIFF_STRING
#undef CT_DIFF_TUPLE
#undef CT_DIFF_IP
#undef CT_DIFF_PROTO
#undef EXP_DIFF_ADDR
#undef EXP_DIFF_L4PROTO_PORTS
#undef EXP_DIFF_L4PROTO_ICMP
return diff;
return diff;
}
static const struct trans_tbl ct_attrs[] = {
__ADD(CT_ATTR_FAMILY, family)
__ADD(CT_ATTR_PROTO, proto)
__ADD(CT_ATTR_TCP_STATE, tcpstate)
__ADD(CT_ATTR_STATUS, status)
__ADD(CT_ATTR_TIMEOUT, timeout)
__ADD(CT_ATTR_MARK, mark)
__ADD(CT_ATTR_USE, use)
__ADD(CT_ATTR_ID, id)
__ADD(CT_ATTR_ORIG_SRC, origsrc)
__ADD(CT_ATTR_ORIG_DST, origdst)
__ADD(CT_ATTR_ORIG_SRC_PORT, origsrcport)
__ADD(CT_ATTR_ORIG_DST_PORT, origdstport)
__ADD(CT_ATTR_ORIG_ICMP_ID, origicmpid)
__ADD(CT_ATTR_ORIG_ICMP_TYPE, origicmptype)
__ADD(CT_ATTR_ORIG_ICMP_CODE, origicmpcode)
__ADD(CT_ATTR_ORIG_PACKETS, origpackets)
__ADD(CT_ATTR_ORIG_BYTES, origbytes)
__ADD(CT_ATTR_REPL_SRC, replysrc)
__ADD(CT_ATTR_REPL_DST, replydst)
__ADD(CT_ATTR_REPL_SRC_PORT, replysrcport)
__ADD(CT_ATTR_REPL_DST_PORT, replydstport)
__ADD(CT_ATTR_REPL_ICMP_ID, replyicmpid)
__ADD(CT_ATTR_REPL_ICMP_TYPE, replyicmptype)
__ADD(CT_ATTR_REPL_ICMP_CODE, replyicmpcode)
__ADD(CT_ATTR_REPL_PACKETS, replypackets)
__ADD(CT_ATTR_REPL_BYTES, replybytes)
// CLI arguments?
static const struct trans_tbl exp_attrs[] = {
__ADD(EXP_ATTR_FAMILY, family)
__ADD(EXP_ATTR_TIMEOUT, timeout)
__ADD(EXP_ATTR_ID, id)
__ADD(EXP_ATTR_HELPER_NAME, helpername)
__ADD(EXP_ATTR_ZONE, zone)
__ADD(EXP_ATTR_CLASS, class)
__ADD(EXP_ATTR_FLAGS, flags)
__ADD(EXP_ATTR_FN, function)
__ADD(EXP_ATTR_EXPECT_IP_SRC, expectipsrc)
__ADD(EXP_ATTR_EXPECT_IP_DST, expectipdst)
__ADD(EXP_ATTR_EXPECT_L4PROTO_NUM, expectprotonum)
__ADD(EXP_ATTR_EXPECT_L4PROTO_PORTS,expectports)
__ADD(EXP_ATTR_EXPECT_L4PROTO_ICMP ,expecticmp)
__ADD(EXP_ATTR_MASTER_IP_SRC, masteripsrc)
__ADD(EXP_ATTR_MASTER_IP_DST, masteripdst)
__ADD(EXP_ATTR_MASTER_L4PROTO_NUM, masterprotonum)
__ADD(EXP_ATTR_MASTER_L4PROTO_PORTS,masterports)
__ADD(EXP_ATTR_MASTER_L4PROTO_ICMP ,mastericmp)
__ADD(EXP_ATTR_MASK_IP_SRC, maskipsrc)
__ADD(EXP_ATTR_MASK_IP_DST, maskipdst)
__ADD(EXP_ATTR_MASK_L4PROTO_NUM, maskprotonum)
__ADD(EXP_ATTR_MASK_L4PROTO_PORTS, maskports)
__ADD(EXP_ATTR_MASK_L4PROTO_ICMP , maskicmp)
__ADD(EXP_ATTR_NAT_IP_SRC, natipsrc)
__ADD(EXP_ATTR_NAT_IP_DST, natipdst)
__ADD(EXP_ATTR_NAT_L4PROTO_NUM, natprotonum)
__ADD(EXP_ATTR_NAT_L4PROTO_PORTS, natports)
__ADD(EXP_ATTR_NAT_L4PROTO_ICMP, naticmp)
__ADD(EXP_ATTR_NAT_DIR, natdir)
};
static char *ct_attrs2str(int attrs, char *buf, size_t len)
static char *exp_attrs2str(int attrs, char *buf, size_t len)
{
return __flags2str(attrs, buf, len, ct_attrs, ARRAY_SIZE(ct_attrs));
return __flags2str(attrs, buf, len, exp_attrs, ARRAY_SIZE(exp_attrs));
}
/**
@ -448,19 +431,19 @@ static char *ct_attrs2str(int attrs, char *buf, size_t len)
* @{
*/
struct nfnl_ct *nfnl_ct_alloc(void)
struct nfnl_exp *nfnl_exp_alloc(void)
{
return (struct nfnl_ct *) nl_object_alloc(&ct_obj_ops);
return (struct nfnl_exp *) nl_object_alloc(&exp_obj_ops);
}
void nfnl_ct_get(struct nfnl_ct *ct)
void nfnl_exp_get(struct nfnl_exp *exp)
{
nl_object_get((struct nl_object *) ct);
nl_object_get((struct nl_object *) exp);
}
void nfnl_ct_put(struct nfnl_ct *ct)
void nfnl_exp_put(struct nfnl_exp *exp)
{
nl_object_put((struct nl_object *) ct);
nl_object_put((struct nl_object *) exp);
}
/** @} */
@ -484,22 +467,6 @@ uint8_t nfnl_exp_get_family(const struct nfnl_exp *exp)
return AF_UNSPEC;
}
void nfnl_exp_set_proto(struct nfnl_exp *exp, uint8_t proto)
{
exp->exp_proto = proto;
exp->ce_mask |= EXP_ATTR_PROTO;
}
int nfnl_exp_test_proto(const struct nfnl_exp *exp)
{
return !!(exp->ce_mask & EXP_ATTR_PROTO);
}
uint8_t nfnl_exp_get_proto(const struct nfnl_exp *ct)
{
return exp->ct_proto;
}
void nfnl_exp_set_flags(struct nfnl_exp *exp, uint32_t flags)
{
exp->exp_flags |= flags;
@ -512,7 +479,7 @@ void nfnl_exp_unset_flags(struct nfnl_exp *exp, uint32_t flags)
exp->ce_mask |= EXP_ATTR_FLAGS;
}
uint32_t nfnl_exp_get_status(const struct nfnl_exp *exp)
uint32_t nfnl_exp_get_flags(const struct nfnl_exp *exp)
{
return exp->exp_flags;
}
@ -525,11 +492,11 @@ static const struct trans_tbl flag_table[] = {
char * nfnl_exp_flags2str(int flags, char *buf, size_t len)
{
return __flags2str(flags, buf, len, status_flags,
return __flags2str(flags, buf, len, flag_table,
ARRAY_SIZE(flag_table));
}
int nfnl_exp_str2status(const char *name)
int nfnl_exp_str2flags(const char *name)
{
return __str2flags(name, flag_table, ARRAY_SIZE(flag_table));
}
@ -566,6 +533,75 @@ uint32_t nfnl_exp_get_id(const struct nfnl_exp *exp)
return exp->exp_id;
}
static struct nfnl_exp_dir *exp_get_dir(struct nfnl_exp *exp, int tuple)
{
struct nfnl_exp_dir *dir = NULL;
switch (tuple) {
case NFNL_EXP_TUPLE_MASTER:
dir = &exp->exp_master;
break;
case NFNL_EXP_TUPLE_MASK:
dir = &exp->exp_mask;
break;
case NFNL_EXP_TUPLE_NAT:
dir = &exp->exp_nat;
break;
case NFNL_EXP_TUPLE_EXPECT:
default :
dir = &exp->exp_expect;
break;
}
return dir;
}
static int exp_get_src_attr(int tuple)
{
int attr = 0;
switch (tuple) {
case NFNL_EXP_TUPLE_MASTER:
attr = EXP_ATTR_MASTER_IP_SRC;
break;
case NFNL_EXP_TUPLE_MASK:
attr = EXP_ATTR_MASK_IP_SRC;
break;
case NFNL_EXP_TUPLE_NAT:
attr = EXP_ATTR_NAT_IP_SRC;
break;
case NFNL_EXP_TUPLE_EXPECT:
default :
attr = EXP_ATTR_EXPECT_IP_SRC;
break;
}
return attr;
}
static int exp_get_dst_attr(int tuple)
{
int attr = 0;
switch (tuple) {
case NFNL_EXP_TUPLE_MASTER:
attr = EXP_ATTR_MASTER_IP_DST;
break;
case NFNL_EXP_TUPLE_MASK:
attr = EXP_ATTR_MASK_IP_DST;
break;
case NFNL_EXP_TUPLE_NAT:
attr = EXP_ATTR_NAT_IP_DST;
break;
case NFNL_EXP_TUPLE_EXPECT:
default :
attr = EXP_ATTR_EXPECT_IP_DST;
break;
}
return attr;
}
static int exp_set_addr(struct nfnl_exp *exp, struct nl_addr *addr,
int attr, struct nl_addr ** exp_addr)
{
@ -587,104 +623,172 @@ static int exp_set_addr(struct nfnl_exp *exp, struct nl_addr *addr,
int nfnl_exp_set_src(struct nfnl_exp *exp, int tuple, struct nl_addr *addr)
{
struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig;
int attr = repl ? CT_ATTR_REPL_SRC : CT_ATTR_ORIG_SRC;
struct nfnl_exp_dir *dir = exp_get_dir(exp, tuple);
switch (tuple) {
case :
dir = &exp->exp_expect;
attr = EXP_ATTR_
break;
case :
dir = &exp->exp_master;
break;
case :
dir = &exp->exp_mask;
break;
case :
dir = &exp->exp_nat;
default :
}
return ct_set_addr(ct, addr, attr, &dir->src);
return exp_set_addr(exp, addr, exp_get_src_attr(tuple), &dir->src);
}
int nfnl_ct_set_dst(struct nfnl_ct *ct, int repl, struct nl_addr *addr)
int nfnl_exp_set_dst(struct nfnl_exp *exp, int tuple, struct nl_addr *addr)
{
struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig;
int attr = repl ? CT_ATTR_REPL_DST : CT_ATTR_ORIG_DST;
return ct_set_addr(ct, addr, attr, &dir->dst);
struct nfnl_exp_dir *dir = exp_get_dir(exp, tuple);
return exp_set_addr(exp, addr, exp_get_dst_attr(tuple), &dir->dst);
}
struct nl_addr *nfnl_ct_get_src(const struct nfnl_ct *ct, int repl)
int nfnl_exp_test_src(const struct nfnl_exp *exp, int tuple)
{
const struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig;
int attr = repl ? CT_ATTR_REPL_SRC : CT_ATTR_ORIG_SRC;
if (!(ct->ce_mask & attr))
return !!(exp->ce_mask & exp_get_src_attr(tuple));
}
int nfnl_exp_test_dst(const struct nfnl_exp *exp, int tuple)
{
return !!(exp->ce_mask & exp_get_dst_attr(tuple));
}
struct nl_addr *nfnl_exp_get_src(const struct nfnl_exp *exp, int tuple)
{
const struct nfnl_exp_dir *dir = exp_get_dir(exp, tuple);
if (!(exp->ce_mask & exp_get_src_attr(tuple)))
return NULL;
return dir->src;
}
struct nl_addr *nfnl_ct_get_dst(const struct nfnl_ct *ct, int repl)
struct nl_addr *nfnl_exp_get_dst(const struct nfnl_exp *exp, int tuple)
{
const struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig;
int attr = repl ? CT_ATTR_REPL_DST : CT_ATTR_ORIG_DST;
if (!(ct->ce_mask & attr))
const struct nfnl_exp_dir *dir = exp_get_dir(exp, tuple);
if (!(exp->ce_mask & exp_get_dst_attr(tuple)))
return NULL;
return dir->dst;
}
void nfnl_ct_set_src_port(struct nfnl_ct *ct, int repl, uint16_t port)
static int exp_get_l4protonum_attr(int tuple)
{
struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig;
int attr = repl ? CT_ATTR_REPL_SRC_PORT : CT_ATTR_ORIG_SRC_PORT;
int attr = 0;
dir->proto.port.src = port;
ct->ce_mask |= attr;
switch (tuple) {
case NFNL_EXP_TUPLE_MASTER:
attr = EXP_ATTR_MASTER_L4PROTO_NUM;
break;
case NFNL_EXP_TUPLE_MASK:
attr = EXP_ATTR_MASK_L4PROTO_NUM;
break;
case NFNL_EXP_TUPLE_NAT:
attr = EXP_ATTR_NAT_L4PROTO_NUM;
break;
case NFNL_EXP_TUPLE_EXPECT:
default :
attr = EXP_ATTR_EXPECT_L4PROTO_NUM;
break;
}
return attr;
}
int nfnl_ct_test_src_port(const struct nfnl_ct *ct, int repl)
void nfnl_exp_set_l4protonum(struct nfnl_exp *exp, int tuple, uint8_t l4protonum)
{
int attr = repl ? CT_ATTR_REPL_SRC_PORT : CT_ATTR_ORIG_SRC_PORT;
return !!(ct->ce_mask & attr);
const struct nfnl_exp_dir *dir = exp_get_dir(exp, tuple);
dir->proto.l4protonum = l4protonum;
exp->ce_mask |= exp_get_l4protonum_attr(exp, tuple);
}
uint16_t nfnl_ct_get_src_port(const struct nfnl_ct *ct, int repl)
int nfnl_exp_test_l4protonum(const struct nfnl_exp *exp, int tuple)
{
const struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig;
return dir->proto.port.src;
return !!(exp->ce_mask & exp_get_l4protonum_attr(exp, tuple));
}
void nfnl_ct_set_dst_port(struct nfnl_ct *ct, int repl, uint16_t port)
struct uint8_t * nfnl_exp_get_l4protonum(const struct nfnl_exp *exp, int tuple)
{
struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig;
int attr = repl ? CT_ATTR_REPL_DST_PORT : CT_ATTR_ORIG_DST_PORT;
dir->proto.port.dst = port;
ct->ce_mask |= attr;
const struct nfnl_exp_dir *dir = exp_get_dir(exp, tuple);
return dir->proto.l4protonum;
}
int nfnl_ct_test_dst_port(const struct nfnl_ct *ct, int repl)
static int exp_get_l4ports_attr(int tuple)
{
int attr = repl ? CT_ATTR_REPL_DST_PORT : CT_ATTR_ORIG_DST_PORT;
return !!(ct->ce_mask & attr);
int attr = 0;
switch (tuple) {
case NFNL_EXP_TUPLE_MASTER:
attr = EXP_ATTR_MASTER_L4PROTO_PORTS;
break;
case NFNL_EXP_TUPLE_MASK:
attr = EXP_ATTR_MASK_L4PROTO_PORTS;
break;
case NFNL_EXP_TUPLE_NAT:
attr = EXP_ATTR_NAT_L4PROTO_PORTS;
break;
case NFNL_EXP_TUPLE_EXPECT:
default :
attr = EXP_ATTR_EXPECT_L4PROTO_PORTS;
break;
}
return attr;
}
uint16_t nfnl_ct_get_dst_port(const struct nfnl_ct *ct, int repl)
void nfnl_exp_set_src_ports(struct nfnl_exp *exp, int tuple, uint16_t srcport, uint16_t dstport)
{
const struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig;
struct nfnl_exp_dir *dir = exp_get_dir(exp, tuple);
return dir->proto.port.dst;
dir->proto.l4protodata.port.src = srcport;
dir->proto.l4protodata.port.dst = dstport;
exp->ce_mask |= exp_get_l4ports_attr(tuple);
}
void nfnl_ct_set_icmp_id(struct nfnl_ct *ct, int repl, uint16_t id)
int nfnl_exp_test_ports(const struct nfnl_exp *exp, int tuple)
{
struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig;
int attr = repl ? CT_ATTR_REPL_ICMP_ID : CT_ATTR_ORIG_ICMP_ID;
return !!(exp->ce_mask & exp_get_l4ports_attr(tuple));
}
dir->proto.icmp.id = id;
ct->ce_mask |= attr;
uint16_t nfnl_exp_get_src_port(const struct nfnl_exp *exp, int tuple)
{
const struct nfnl_exp_dir *dir = exp_get_dir(exp, tuple);
return dir->proto.l4protodata.port.src;
}
uint16_t nfnl_exp_get_dst_port(const struct nfnl_exp *exp, int tuple)
{
const struct nfnl_exp_dir *dir = exp_get_dir(exp, tuple);
return dir->proto.l4protodata.port.dst;
}
static int exp_get_l4icmp_attr(int tuple)
{
int attr = 0;
switch (tuple) {
case NFNL_EXP_TUPLE_MASTER:
attr = EXP_ATTR_MASTER_L4PROTO_ICMP;
break;
case NFNL_EXP_TUPLE_MASK:
attr = EXP_ATTR_MASK_L4PROTO_ICMP;
break;
case NFNL_EXP_TUPLE_NAT:
attr = EXP_ATTR_NAT_L4PROTO_ICMP;
break;
case NFNL_EXP_TUPLE_EXPECT:
default :
attr = EXP_ATTR_EXPECT_L4PROTO_ICMP;
break;
}
return attr;
}
void nfnl_ct_set_icmp(struct nfnl_exp *exp, int tuple, uint16_t id, uint8_t type, uint8_t, code)
{
struct nfnl_exp_dir *dir = exp_get_dir(exp, tuple);
dir->proto.l4protodata.icmp.id = id;
dir->proto.l4protodata.icmp.type = type;
dir->proto.l4protodata.icmp.code = code;
exp->ce_mask |= exp_get_l4icmp_attr(tuple);
}
int nfnl_ct_test_icmp_id(const struct nfnl_ct *ct, int repl)