summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/conntrack/build.c46
-rw-r--r--src/conntrack/build_mnl.c51
-rw-r--r--src/conntrack/compare.c22
-rw-r--r--src/conntrack/copy.c14
-rw-r--r--src/conntrack/getter.c12
-rw-r--r--src/conntrack/parse.c12
-rw-r--r--src/conntrack/parse_mnl.c17
-rw-r--r--src/conntrack/setter.c14
-rw-r--r--src/conntrack/snprintf_default.c17
-rw-r--r--src/conntrack/snprintf_xml.c13
10 files changed, 198 insertions, 20 deletions
diff --git a/src/conntrack/build.c b/src/conntrack/build.c
index 0549084..01bdefb 100644
--- a/src/conntrack/build.c
+++ b/src/conntrack/build.c
@@ -86,18 +86,20 @@ static void __build_tuple_proto(struct nfnlhdr *req,
nfnl_nest_end(&req->nlh, nest);
}
-void __build_tuple(struct nfnlhdr *req,
- size_t size,
- const struct __nfct_tuple *t,
- const int type)
+static void __build_tuple_raw(struct nfnlhdr *req, size_t size,
+ const struct __nfct_tuple *t)
{
- struct nfattr *nest;
-
- nest = nfnl_nest(&req->nlh, size, type);
-
__build_tuple_ip(req, size, t);
__build_tuple_proto(req, size, t);
+}
+void __build_tuple(struct nfnlhdr *req, size_t size,
+ const struct __nfct_tuple *t, const int type)
+{
+ struct nfattr *nest;
+
+ nest = nfnl_nest(&req->nlh, size, type);
+ __build_tuple_raw(req, size, t);
nfnl_nest_end(&req->nlh, nest);
}
@@ -448,10 +450,20 @@ int __build_conntrack(struct nfnl_subsys_handle *ssh,
test_bit(ATTR_ORIG_PORT_DST, ct->head.set) ||
test_bit(ATTR_ORIG_L3PROTO, ct->head.set) ||
test_bit(ATTR_ORIG_L4PROTO, ct->head.set) ||
+ test_bit(ATTR_ORIG_ZONE, ct->head.set) ||
test_bit(ATTR_ICMP_TYPE, ct->head.set) ||
test_bit(ATTR_ICMP_CODE, ct->head.set) ||
- test_bit(ATTR_ICMP_ID, ct->head.set))
- __build_tuple(req, size, &ct->head.orig, CTA_TUPLE_ORIG);
+ test_bit(ATTR_ICMP_ID, ct->head.set)) {
+ const struct __nfct_tuple *t = &ct->head.orig;
+ struct nfattr *nest;
+
+ nest = nfnl_nest(&req->nlh, size, CTA_TUPLE_ORIG);
+ __build_tuple_raw(req, size, t);
+ if (test_bit(ATTR_ORIG_ZONE, ct->head.set))
+ nfnl_addattr16(&req->nlh, size, CTA_TUPLE_ZONE,
+ htons(t->zone));
+ nfnl_nest_end(&req->nlh, nest);
+ }
if (test_bit(ATTR_REPL_IPV4_SRC, ct->head.set) ||
test_bit(ATTR_REPL_IPV4_DST, ct->head.set) ||
@@ -460,8 +472,18 @@ int __build_conntrack(struct nfnl_subsys_handle *ssh,
test_bit(ATTR_REPL_PORT_SRC, ct->head.set) ||
test_bit(ATTR_REPL_PORT_DST, ct->head.set) ||
test_bit(ATTR_REPL_L3PROTO, ct->head.set) ||
- test_bit(ATTR_REPL_L4PROTO, ct->head.set))
- __build_tuple(req, size, &ct->repl, CTA_TUPLE_REPLY);
+ test_bit(ATTR_REPL_L4PROTO, ct->head.set) ||
+ test_bit(ATTR_REPL_ZONE, ct->head.set)) {
+ const struct __nfct_tuple *t = &ct->repl;
+ struct nfattr *nest;
+
+ nest = nfnl_nest(&req->nlh, size, CTA_TUPLE_REPLY);
+ __build_tuple_raw(req, size, t);
+ if (test_bit(ATTR_REPL_ZONE, ct->head.set))
+ nfnl_addattr16(&req->nlh, size, CTA_TUPLE_ZONE,
+ htons(t->zone));
+ nfnl_nest_end(&req->nlh, nest);
+ }
if (test_bit(ATTR_MASTER_IPV4_SRC, ct->head.set) ||
test_bit(ATTR_MASTER_IPV4_DST, ct->head.set) ||
diff --git a/src/conntrack/build_mnl.c b/src/conntrack/build_mnl.c
index a37bd73..8ed0690 100644
--- a/src/conntrack/build_mnl.c
+++ b/src/conntrack/build_mnl.c
@@ -81,6 +81,17 @@ nfct_build_tuple_proto(struct nlmsghdr *nlh, const struct __nfct_tuple *t)
}
int
+nfct_build_tuple_raw(struct nlmsghdr *nlh, const struct __nfct_tuple *t)
+{
+ if (nfct_build_tuple_ip(nlh, t) < 0)
+ return -1;
+ if (nfct_build_tuple_proto(nlh, t) < 0)
+ return -1;
+
+ return 0;
+}
+
+int
nfct_build_tuple(struct nlmsghdr *nlh, const struct __nfct_tuple *t, int type)
{
struct nlattr *nest;
@@ -89,9 +100,7 @@ nfct_build_tuple(struct nlmsghdr *nlh, const struct __nfct_tuple *t, int type)
if (nest == NULL)
return -1;
- if (nfct_build_tuple_ip(nlh, t) < 0)
- goto err;
- if (nfct_build_tuple_proto(nlh, t) < 0)
+ if (nfct_build_tuple_raw(nlh, t) < 0)
goto err;
mnl_attr_nest_end(nlh, nest);
@@ -410,10 +419,26 @@ nfct_nlmsg_build(struct nlmsghdr *nlh, const struct nf_conntrack *ct)
test_bit(ATTR_ORIG_PORT_DST, ct->head.set) ||
test_bit(ATTR_ORIG_L3PROTO, ct->head.set) ||
test_bit(ATTR_ORIG_L4PROTO, ct->head.set) ||
+ test_bit(ATTR_ORIG_ZONE, ct->head.set) ||
test_bit(ATTR_ICMP_TYPE, ct->head.set) ||
test_bit(ATTR_ICMP_CODE, ct->head.set) ||
test_bit(ATTR_ICMP_ID, ct->head.set)) {
- nfct_build_tuple(nlh, &ct->head.orig, CTA_TUPLE_ORIG);
+ const struct __nfct_tuple *t = &ct->head.orig;
+ struct nlattr *nest;
+
+ nest = mnl_attr_nest_start(nlh, CTA_TUPLE_ORIG);
+ if (nest == NULL)
+ return -1;
+
+ if (nfct_build_tuple_raw(nlh, t) < 0) {
+ mnl_attr_nest_cancel(nlh, nest);
+ return -1;
+ }
+
+ if (test_bit(ATTR_ORIG_ZONE, ct->head.set))
+ mnl_attr_put_u16(nlh, CTA_TUPLE_ZONE, htons(t->zone));
+
+ mnl_attr_nest_end(nlh, nest);
}
if (test_bit(ATTR_REPL_IPV4_SRC, ct->head.set) ||
@@ -424,10 +449,26 @@ nfct_nlmsg_build(struct nlmsghdr *nlh, const struct nf_conntrack *ct)
test_bit(ATTR_REPL_PORT_DST, ct->head.set) ||
test_bit(ATTR_REPL_L3PROTO, ct->head.set) ||
test_bit(ATTR_REPL_L4PROTO, ct->head.set) ||
+ test_bit(ATTR_REPL_ZONE, ct->head.set) ||
test_bit(ATTR_ICMP_TYPE, ct->head.set) ||
test_bit(ATTR_ICMP_CODE, ct->head.set) ||
test_bit(ATTR_ICMP_ID, ct->head.set)) {
- nfct_build_tuple(nlh, &ct->repl, CTA_TUPLE_REPLY);
+ const struct __nfct_tuple *t = &ct->repl;
+ struct nlattr *nest;
+
+ nest = mnl_attr_nest_start(nlh, CTA_TUPLE_REPLY);
+ if (nest == NULL)
+ return -1;
+
+ if (nfct_build_tuple_raw(nlh, t) < 0) {
+ mnl_attr_nest_cancel(nlh, nest);
+ return -1;
+ }
+
+ if (test_bit(ATTR_REPL_ZONE, ct->head.set))
+ mnl_attr_put_u16(nlh, CTA_TUPLE_ZONE, htons(t->zone));
+
+ mnl_attr_nest_end(nlh, nest);
}
if (test_bit(ATTR_MASTER_IPV4_SRC, ct->head.set) ||
diff --git a/src/conntrack/compare.c b/src/conntrack/compare.c
index e15ba93..8b2f3cb 100644
--- a/src/conntrack/compare.c
+++ b/src/conntrack/compare.c
@@ -149,6 +149,15 @@ cmp_orig_ipv6_dst(const struct nf_conntrack *ct1,
sizeof(struct in6_addr)) == 0);
}
+static int
+cmp_orig_zone(const struct nf_conntrack *ct1,
+ const struct nf_conntrack *ct2,
+ unsigned int flags)
+{
+ return nfct_get_attr_u16(ct1, ATTR_ORIG_ZONE) ==
+ nfct_get_attr_u16(ct2, ATTR_ORIG_ZONE);
+}
+
int __cmp_orig(const struct nf_conntrack *ct1,
const struct nf_conntrack *ct2,
unsigned int flags)
@@ -165,6 +174,8 @@ int __cmp_orig(const struct nf_conntrack *ct1,
return 0;
if (!__cmp(ATTR_ORIG_IPV6_DST, ct1, ct2, flags, cmp_orig_ipv6_dst, true))
return 0;
+ if (!__cmp(ATTR_ORIG_ZONE, ct1, ct2, flags, cmp_orig_zone, false))
+ return 0;
return 1;
}
@@ -259,6 +270,15 @@ cmp_repl_ipv6_dst(const struct nf_conntrack *ct1,
sizeof(struct in6_addr)) == 0);
}
+static int
+cmp_repl_zone(const struct nf_conntrack *ct1,
+ const struct nf_conntrack *ct2,
+ unsigned int flags)
+{
+ return nfct_get_attr_u16(ct1, ATTR_REPL_ZONE) ==
+ nfct_get_attr_u16(ct2, ATTR_REPL_ZONE);
+}
+
static int cmp_repl(const struct nf_conntrack *ct1,
const struct nf_conntrack *ct2,
unsigned int flags)
@@ -275,6 +295,8 @@ static int cmp_repl(const struct nf_conntrack *ct1,
return 0;
if (!__cmp(ATTR_REPL_IPV6_DST, ct1, ct2, flags, cmp_repl_ipv6_dst, true))
return 0;
+ if (!__cmp(ATTR_REPL_ZONE, ct1, ct2, flags, cmp_repl_zone, false))
+ return 0;
return 1;
}
diff --git a/src/conntrack/copy.c b/src/conntrack/copy.c
index 5915c16..249e7e0 100644
--- a/src/conntrack/copy.c
+++ b/src/conntrack/copy.c
@@ -89,6 +89,18 @@ static void copy_attr_repl_port_dst(struct nf_conntrack *dest,
dest->repl.l4dst.all = orig->repl.l4dst.all;
}
+static void copy_attr_orig_zone(struct nf_conntrack *dest,
+ const struct nf_conntrack *orig)
+{
+ dest->head.orig.zone = orig->head.orig.zone;
+}
+
+static void copy_attr_repl_zone(struct nf_conntrack *dest,
+ const struct nf_conntrack *orig)
+{
+ dest->repl.zone = orig->repl.zone;
+}
+
static void copy_attr_icmp_type(struct nf_conntrack *dest,
const struct nf_conntrack *orig)
{
@@ -535,6 +547,8 @@ const copy_attr copy_attr_array[ATTR_MAX] = {
[ATTR_TCP_WSCALE_ORIG] = copy_attr_tcp_wscale_orig,
[ATTR_TCP_WSCALE_REPL] = copy_attr_tcp_wscale_repl,
[ATTR_ZONE] = copy_attr_zone,
+ [ATTR_ORIG_ZONE] = copy_attr_orig_zone,
+ [ATTR_REPL_ZONE] = copy_attr_repl_zone,
[ATTR_SECCTX] = copy_attr_secctx,
[ATTR_TIMESTAMP_START] = copy_attr_timestamp_start,
[ATTR_TIMESTAMP_STOP] = copy_attr_timestamp_stop,
diff --git a/src/conntrack/getter.c b/src/conntrack/getter.c
index ae546ee..ef4ec1d 100644
--- a/src/conntrack/getter.c
+++ b/src/conntrack/getter.c
@@ -69,6 +69,16 @@ static const void *get_attr_repl_port_dst(const struct nf_conntrack *ct)
return &ct->repl.l4dst.all;
}
+static const void *get_attr_orig_zone(const struct nf_conntrack *ct)
+{
+ return &ct->head.orig.zone;
+}
+
+static const void *get_attr_repl_zone(const struct nf_conntrack *ct)
+{
+ return &ct->repl.zone;
+}
+
static const void *get_attr_icmp_type(const struct nf_conntrack *ct)
{
return &ct->head.orig.l4dst.icmp.type;
@@ -412,6 +422,8 @@ const get_attr get_attr_array[ATTR_MAX] = {
[ATTR_TCP_WSCALE_ORIG] = get_attr_tcp_wscale_orig,
[ATTR_TCP_WSCALE_REPL] = get_attr_tcp_wscale_repl,
[ATTR_ZONE] = get_attr_zone,
+ [ATTR_ORIG_ZONE] = get_attr_orig_zone,
+ [ATTR_REPL_ZONE] = get_attr_repl_zone,
[ATTR_SECCTX] = get_attr_secctx,
[ATTR_TIMESTAMP_START] = get_attr_timestamp_start,
[ATTR_TIMESTAMP_STOP] = get_attr_timestamp_stop,
diff --git a/src/conntrack/parse.c b/src/conntrack/parse.c
index 3eb8b81..b52454b 100644
--- a/src/conntrack/parse.c
+++ b/src/conntrack/parse.c
@@ -189,6 +189,18 @@ void __parse_tuple(const struct nfattr *attr,
__parse_ip(tb[CTA_TUPLE_IP-1], tuple, dir, set);
if (tb[CTA_TUPLE_PROTO-1])
__parse_proto(tb[CTA_TUPLE_PROTO-1], tuple, dir, set);
+
+ if (tb[CTA_TUPLE_ZONE-1]) {
+ tuple->zone = ntohs(*(uint16_t *)NFA_DATA(tb[CTA_TUPLE_ZONE-1]));
+ switch(dir) {
+ case __DIR_ORIG:
+ set_bit(ATTR_ORIG_ZONE, set);
+ break;
+ case __DIR_REPL:
+ set_bit(ATTR_REPL_ZONE, set);
+ break;
+ }
+ }
}
static void __parse_protoinfo_tcp(const struct nfattr *attr,
diff --git a/src/conntrack/parse_mnl.c b/src/conntrack/parse_mnl.c
index 2582cd7..56a575e 100644
--- a/src/conntrack/parse_mnl.c
+++ b/src/conntrack/parse_mnl.c
@@ -254,7 +254,12 @@ static int nfct_parse_tuple_attr_cb(const struct nlattr *attr, void *data)
if (mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0)
return MNL_CB_ERROR;
break;
+ case CTA_TUPLE_ZONE:
+ if (mnl_attr_validate(attr, MNL_TYPE_U16) < 0)
+ return MNL_CB_ERROR;
+ break;
}
+
tb[type] = attr;
return MNL_CB_OK;
}
@@ -278,6 +283,18 @@ nfct_parse_tuple(const struct nlattr *attr, struct __nfct_tuple *tuple,
return -1;
}
+ if (tb[CTA_TUPLE_ZONE]) {
+ tuple->zone = ntohs(mnl_attr_get_u16(tb[CTA_TUPLE_ZONE]));
+ switch(dir) {
+ case __DIR_ORIG:
+ set_bit(ATTR_ORIG_ZONE, set);
+ break;
+ case __DIR_REPL:
+ set_bit(ATTR_REPL_ZONE, set);
+ break;
+ }
+ }
+
return 0;
}
diff --git a/src/conntrack/setter.c b/src/conntrack/setter.c
index c648a10..eba2fb6 100644
--- a/src/conntrack/setter.c
+++ b/src/conntrack/setter.c
@@ -110,6 +110,18 @@ set_attr_repl_port_dst(struct nf_conntrack *ct, const void *value, size_t len)
}
static void
+set_attr_orig_zone(struct nf_conntrack *ct, const void *value, size_t len)
+{
+ ct->head.orig.zone = *((uint16_t *) value);
+}
+
+static void
+set_attr_repl_zone(struct nf_conntrack *ct, const void *value, size_t len)
+{
+ ct->repl.zone = *((uint16_t *) value);
+}
+
+static void
set_attr_icmp_type(struct nf_conntrack *ct, const void *value, size_t len)
{
uint8_t rtype;
@@ -507,6 +519,8 @@ const set_attr set_attr_array[ATTR_MAX] = {
[ATTR_TCP_WSCALE_ORIG] = set_attr_tcp_wscale_orig,
[ATTR_TCP_WSCALE_REPL] = set_attr_tcp_wscale_repl,
[ATTR_ZONE] = set_attr_zone,
+ [ATTR_ORIG_ZONE] = set_attr_orig_zone,
+ [ATTR_REPL_ZONE] = set_attr_repl_zone,
[ATTR_SECCTX] = set_attr_do_nothing,
[ATTR_TIMESTAMP_START] = set_attr_do_nothing,
[ATTR_TIMESTAMP_STOP] = set_attr_do_nothing,
diff --git a/src/conntrack/snprintf_default.c b/src/conntrack/snprintf_default.c
index 24e2f28..06466b1 100644
--- a/src/conntrack/snprintf_default.c
+++ b/src/conntrack/snprintf_default.c
@@ -171,6 +171,13 @@ int __snprintf_proto(char *buf,
return size;
}
+static int
+__snprintf_tuple_zone(char *buf, unsigned int len, const char *pfx,
+ const struct __nfct_tuple *tuple)
+{
+ return (snprintf(buf, len, "zone-%s=%u ", pfx, tuple->zone));
+}
+
static int __snprintf_status_assured(char *buf,
unsigned int len,
const struct nf_conntrack *ct)
@@ -396,6 +403,11 @@ int __snprintf_conntrack_default(char *buf,
ret = __snprintf_proto(buf+offset, len, &ct->head.orig);
BUFFER_SIZE(ret, size, len, offset);
+ if (test_bit(ATTR_ORIG_ZONE, ct->head.set)) {
+ ret = __snprintf_tuple_zone(buf+offset, len, "orig", &ct->head.orig);
+ BUFFER_SIZE(ret, size, len, offset);
+ }
+
if (test_bit(ATTR_ORIG_COUNTER_PACKETS, ct->head.set) &&
test_bit(ATTR_ORIG_COUNTER_BYTES, ct->head.set)) {
ret = __snprintf_counters(buf+offset, len, ct, __DIR_ORIG);
@@ -414,6 +426,11 @@ int __snprintf_conntrack_default(char *buf,
ret = __snprintf_proto(buf+offset, len, &ct->repl);
BUFFER_SIZE(ret, size, len, offset);
+ if (test_bit(ATTR_REPL_ZONE, ct->head.set)) {
+ ret = __snprintf_tuple_zone(buf+offset, len, "reply", &ct->repl);
+ BUFFER_SIZE(ret, size, len, offset);
+ }
+
if (test_bit(ATTR_REPL_COUNTER_PACKETS, ct->head.set) &&
test_bit(ATTR_REPL_COUNTER_BYTES, ct->head.set)) {
ret = __snprintf_counters(buf+offset, len, ct, __DIR_REPL);
diff --git a/src/conntrack/snprintf_xml.c b/src/conntrack/snprintf_xml.c
index bf52362..c3a836a 100644
--- a/src/conntrack/snprintf_xml.c
+++ b/src/conntrack/snprintf_xml.c
@@ -284,7 +284,7 @@ __snprintf_localtime_xml(char *buf, unsigned int len, const struct tm *tm)
static int __snprintf_tuple_xml(char *buf,
unsigned int len,
const struct nf_conntrack *ct,
- unsigned int dir)
+ unsigned int dir, bool zone_incl)
{
int ret;
unsigned int size = 0, offset = 0;
@@ -330,6 +330,11 @@ static int __snprintf_tuple_xml(char *buf,
ret = snprintf(buf+offset, len, "</layer4>");
BUFFER_SIZE(ret, size, len, offset);
+ if (zone_incl) {
+ ret = snprintf(buf+offset, len, "<zone>%u</zone>", tuple->zone);
+ BUFFER_SIZE(ret, size, len, offset);
+ }
+
if (test_bit(ATTR_ORIG_COUNTER_PACKETS, ct->head.set) &&
test_bit(ATTR_ORIG_COUNTER_BYTES, ct->head.set)) {
ret = snprintf(buf+offset, len, "<counters>");
@@ -398,10 +403,12 @@ int __snprintf_conntrack_xml(char *buf,
BUFFER_SIZE(ret, size, len, offset);
- ret = __snprintf_tuple_xml(buf+offset, len, ct, __DIR_ORIG);
+ ret = __snprintf_tuple_xml(buf+offset, len, ct, __DIR_ORIG,
+ test_bit(ATTR_ORIG_ZONE, ct->head.set));
BUFFER_SIZE(ret, size, len, offset);
- ret = __snprintf_tuple_xml(buf+offset, len, ct, __DIR_REPL);
+ ret = __snprintf_tuple_xml(buf+offset, len, ct, __DIR_REPL,
+ test_bit(ATTR_REPL_ZONE, ct->head.set));
BUFFER_SIZE(ret, size, len, offset);
if (test_bit(ATTR_TCP_STATE, ct->head.set) ||