From fdda1474cc8654430f245b7f01c30e8ff171fa60 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Sat, 18 Dec 2010 20:18:49 +0100 Subject: src: add support for CTA_SECCTX This patch adds support for the new attribute CTA_SECCTX that supersedes CTA_SECMARK. Signed-off-by: Pablo Neira Ayuso --- include/internal/object.h | 3 +++ include/libnetfilter_conntrack/libnetfilter_conntrack.h | 1 + .../libnetfilter_conntrack/linux_nfnetlink_conntrack.h | 10 +++++++++- src/conntrack/api.c | 3 +++ src/conntrack/compare.c | 10 ++++++++++ src/conntrack/copy.c | 9 +++++++++ src/conntrack/getter.c | 6 ++++++ src/conntrack/parse.c | 17 +++++++++++++++++ src/conntrack/setter.c | 1 + src/conntrack/snprintf_default.c | 11 +++++++++++ src/conntrack/snprintf_xml.c | 6 ++++++ 11 files changed, 76 insertions(+), 1 deletion(-) diff --git a/include/internal/object.h b/include/internal/object.h index 8d95aa1..76a0566 100644 --- a/include/internal/object.h +++ b/include/internal/object.h @@ -166,6 +166,9 @@ struct nf_conntrack { * length accepted is 16 bytes, this limit is enforced during module load. */ #define __NFCT_HELPER_NAMELEN 16 char helper_name[__NFCT_HELPER_NAMELEN]; +/* According to Eric Paris this field can be up to 4096 + * bytes long. For that reason, we allocate this dynamically. */ + char *secctx; union __nfct_protoinfo protoinfo; struct __nfct_counters counters[__DIR_MAX]; diff --git a/include/libnetfilter_conntrack/libnetfilter_conntrack.h b/include/libnetfilter_conntrack/libnetfilter_conntrack.h index 5315f42..aaf1638 100644 --- a/include/libnetfilter_conntrack/libnetfilter_conntrack.h +++ b/include/libnetfilter_conntrack/libnetfilter_conntrack.h @@ -127,6 +127,7 @@ enum nf_conntrack_attr { ATTR_TCP_WSCALE_ORIG, /* u8 bits */ ATTR_TCP_WSCALE_REPL = 60, /* u8 bits */ ATTR_ZONE, /* u16 bits */ + ATTR_SECCTX, /* string */ ATTR_MAX }; diff --git a/include/libnetfilter_conntrack/linux_nfnetlink_conntrack.h b/include/libnetfilter_conntrack/linux_nfnetlink_conntrack.h index 65af53e..3b0c009 100644 --- a/include/libnetfilter_conntrack/linux_nfnetlink_conntrack.h +++ b/include/libnetfilter_conntrack/linux_nfnetlink_conntrack.h @@ -43,8 +43,9 @@ enum ctattr_type { CTA_TUPLE_MASTER, CTA_NAT_SEQ_ADJ_ORIG, CTA_NAT_SEQ_ADJ_REPLY, - CTA_SECMARK, + CTA_SECMARK, /* obsolete */ CTA_ZONE, + CTA_SECCTX, __CTA_MAX }; #define CTA_MAX (__CTA_MAX - 1) @@ -177,6 +178,13 @@ enum ctattr_help { }; #define CTA_HELP_MAX (__CTA_HELP_MAX - 1) +enum ctattr_secctx { + CTA_SECCTX_UNSPEC, + CTA_SECCTX_NAME, + __CTA_SECCTX_MAX +}; +#define CTA_SECCTX_MAX (__CTA_SECCTX_MAX - 1) + #ifdef __cplusplus } #endif diff --git a/src/conntrack/api.c b/src/conntrack/api.c index 7a5767b..8e5b2fe 100644 --- a/src/conntrack/api.c +++ b/src/conntrack/api.c @@ -90,6 +90,8 @@ void nfct_destroy(struct nf_conntrack *ct) { assert(ct != NULL); free(ct); + if (ct->secctx) + free(ct->secctx); ct = NULL; /* bugtrap */ } @@ -353,6 +355,7 @@ void nfct_callback_unregister2(struct nfct_handle *h) * - ATTR_USE * - ATTR_ID * - ATTR_*_COUNTER_* + * - ATTR_SECCTX * The call of this function for such attributes do nothing. */ void nfct_set_attr(struct nf_conntrack *ct, diff --git a/src/conntrack/compare.c b/src/conntrack/compare.c index 134cefd..1cdad1c 100644 --- a/src/conntrack/compare.c +++ b/src/conntrack/compare.c @@ -368,6 +368,14 @@ cmp_zone(const struct nf_conntrack *ct1, return (ct1->zone == ct2->zone); } +static int +cmp_secctx(const struct nf_conntrack *ct1, + const struct nf_conntrack *ct2, + unsigned int flags) +{ + return strcmp(ct1->secctx, ct2->secctx) == 0; +} + static int cmp_meta(const struct nf_conntrack *ct1, const struct nf_conntrack *ct2, unsigned int flags) @@ -388,6 +396,8 @@ static int cmp_meta(const struct nf_conntrack *ct1, return 0; if (!__cmp(ATTR_ZONE, ct1, ct2, flags, cmp_zone)) return 0; + if (!__cmp(ATTR_SECCTX, ct1, ct2, flags, cmp_secctx)) + return 0; return 1; } diff --git a/src/conntrack/copy.c b/src/conntrack/copy.c index 8d8a6b7..9148640 100644 --- a/src/conntrack/copy.c +++ b/src/conntrack/copy.c @@ -415,6 +415,14 @@ static void copy_attr_zone(struct nf_conntrack *dest, dest->zone = orig->zone; } +static void copy_attr_secctx(struct nf_conntrack *dest, + const struct nf_conntrack *orig) +{ + if (dest->secctx) + free(dest->secctx); + dest->secctx = strdup(orig->secctx); +} + const copy_attr copy_attr_array[ATTR_MAX] = { [ATTR_ORIG_IPV4_SRC] = copy_attr_orig_ipv4_src, [ATTR_ORIG_IPV4_DST] = copy_attr_orig_ipv4_dst, @@ -478,4 +486,5 @@ 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_SECCTX] = copy_attr_secctx, }; diff --git a/src/conntrack/getter.c b/src/conntrack/getter.c index 056fe8a..8a093c6 100644 --- a/src/conntrack/getter.c +++ b/src/conntrack/getter.c @@ -317,6 +317,11 @@ static const void *get_attr_zone(const struct nf_conntrack *ct) return &ct->zone; } +static const void *get_attr_secctx(const struct nf_conntrack *ct) +{ + return ct->secctx; +} + const get_attr get_attr_array[ATTR_MAX] = { [ATTR_ORIG_IPV4_SRC] = get_attr_orig_ipv4_src, [ATTR_ORIG_IPV4_DST] = get_attr_orig_ipv4_dst, @@ -380,4 +385,5 @@ 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_SECCTX] = get_attr_secctx, }; diff --git a/src/conntrack/parse.c b/src/conntrack/parse.c index 64e6e93..841693e 100644 --- a/src/conntrack/parse.c +++ b/src/conntrack/parse.c @@ -422,6 +422,20 @@ __parse_helper(const struct nfattr *attr, struct nf_conntrack *ct) set_bit(ATTR_HELPER_NAME, ct->set); } +static void +__parse_secctx(const struct nfattr *attr, struct nf_conntrack *ct) +{ + struct nfattr *tb[CTA_SECCTX_MAX]; + + nfnl_parse_nested(tb, CTA_SECCTX_MAX, attr); + if (!tb[CTA_SECCTX_NAME-1]) + return; + + ct->secctx = strdup(NFA_DATA(tb[CTA_SECCTX-1])); + if (ct->secctx) + set_bit(ATTR_SECCTX, ct->set); +} + int __parse_message_type(const struct nlmsghdr *nlh) { u_int16_t type = NFNL_MSG_TYPE(nlh->nlmsg_type); @@ -521,4 +535,7 @@ void __parse_conntrack(const struct nlmsghdr *nlh, ct->zone = ntohs(*(u_int16_t *)NFA_DATA(cda[CTA_ZONE-1])); set_bit(ATTR_ZONE, ct->set); } + + if (cda[CTA_SECCTX-1]) + __parse_secctx(cda[CTA_SECCTX-1], ct); } diff --git a/src/conntrack/setter.c b/src/conntrack/setter.c index 0f907ab..99ac8d7 100644 --- a/src/conntrack/setter.c +++ b/src/conntrack/setter.c @@ -410,4 +410,5 @@ 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_SECCTX] = set_attr_do_nothing, }; diff --git a/src/conntrack/snprintf_default.c b/src/conntrack/snprintf_default.c index 4a61f8a..abb9d9f 100644 --- a/src/conntrack/snprintf_default.c +++ b/src/conntrack/snprintf_default.c @@ -225,6 +225,12 @@ __snprintf_zone(char *buf, unsigned int len, const struct nf_conntrack *ct) return (snprintf(buf, len, "zone=%u ", ct->zone)); } +static int +__snprintf_secctx(char *buf, unsigned int len, const struct nf_conntrack *ct) +{ + return (snprintf(buf, len, "secctx=%s ", ct->secctx)); +} + int __snprintf_conntrack_default(char *buf, unsigned int len, const struct nf_conntrack *ct, @@ -321,6 +327,11 @@ int __snprintf_conntrack_default(char *buf, BUFFER_SIZE(ret, size, len, offset); } + if (test_bit(ATTR_SECCTX, ct->set)) { + ret = __snprintf_secctx(buf+offset, len, ct); + BUFFER_SIZE(ret, size, len, offset); + } + if (test_bit(ATTR_ZONE, ct->set)) { ret = __snprintf_zone(buf+offset, len, ct); BUFFER_SIZE(ret, size, len, offset); diff --git a/src/conntrack/snprintf_xml.c b/src/conntrack/snprintf_xml.c index cc588ee..97f6650 100644 --- a/src/conntrack/snprintf_xml.c +++ b/src/conntrack/snprintf_xml.c @@ -345,6 +345,12 @@ int __snprintf_conntrack_xml(char *buf, BUFFER_SIZE(ret, size, len, offset); } + if (test_bit(ATTR_SECCTX, ct->set)) { + ret = snprintf(buf+offset, len, + "%s", ct->secctx); + BUFFER_SIZE(ret, size, len, offset); + } + if (test_bit(ATTR_ZONE, ct->set)) { ret = snprintf(buf+offset, len, "%u", ct->zone); BUFFER_SIZE(ret, size, len, offset); -- cgit v1.2.3