* [PATCH conntracktools] conntrackd: support replication of connlabels @ 2013-06-30 21:10 Florian Westphal 2013-06-30 21:10 ` [PATCH 2/2] conntrack: add connlabel format attribute Florian Westphal 0 siblings, 1 reply; 3+ messages in thread From: Florian Westphal @ 2013-06-30 21:10 UTC (permalink / raw) To: netfilter-devel; +Cc: Florian Westphal - check if ct has label attribute, and at least one label (bit) is set - serialize bitmap into array-of-u32, in network byte order - add code to build new nfct_bitmask object from array-of-u32 Current parse functions don't have length information, this adds optional parse2() which gets struct netattr pointer. Attributes that want to use parse2 need to set .maxsize to nonzero value. Signed-off-by: Florian Westphal <fw@strlen.de> --- Change since v1: - don't show label names in conntrack -i/-e output I'll apply this if noone objects. include/network.h | 4 +++ src/build.c | 39 ++++++++++++++++++++++++++++ src/parse.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++-------- 3 files changed, 110 insertions(+), 10 deletions(-) diff --git a/include/network.h b/include/network.h index 79745f3..cc312cb 100644 --- a/include/network.h +++ b/include/network.h @@ -228,9 +228,13 @@ enum nta_attr { NTA_TCP_WSCALE_ORIG, /* uint8_t */ NTA_TCP_WSCALE_REPL, /* uint8_t */ NTA_HELPER_NAME, /* string (variable length) */ + NTA_LABELS, /* array of uint32_t (variable length) */ NTA_MAX }; +/* allow to serialize/replicate up to 4k labels per flow */ +#define NTA_LABELS_MAX_SIZE (4096/sizeof(uint32_t)) + struct nta_attr_natseqadj { uint32_t orig_seq_correction_pos; uint32_t orig_seq_offset_before; diff --git a/src/build.c b/src/build.c index e15eb4f..5799b51 100644 --- a/src/build.c +++ b/src/build.c @@ -158,6 +158,42 @@ static void build_l4proto_udp(const struct nf_conntrack *ct, struct nethdr *n) sizeof(struct nfct_attr_grp_port)); } +static void ct_build_clabel(const struct nf_conntrack *ct, struct nethdr *n) +{ + const struct nfct_bitmask *b; + uint32_t *words; + unsigned int wordcount, i, maxbit; + + if (!nfct_attr_is_set(ct, ATTR_CONNLABELS)) + return; + + b = nfct_get_attr(ct, ATTR_CONNLABELS); + + maxbit = nfct_bitmask_maxbit(b); + for (i=0; i <= maxbit; i++) { + if (nfct_bitmask_test_bit(b, i)) + break; + } + + if (i > maxbit) + return; + + wordcount = (nfct_bitmask_maxbit(b) / 32) + 1; + words = put_header(n, NTA_LABELS, wordcount * sizeof(*words)); + + for (i=0; i < wordcount; i++) { + int bit = 31; + uint32_t tmp = 0; + + do { + if (nfct_bitmask_test_bit(b, (32 * i) + bit)) + tmp |= (1 << bit); + } while (--bit >= 0); + + words[i] = htonl(tmp); + } +} + #ifndef IPPROTO_DCCP #define IPPROTO_DCCP 33 #endif @@ -233,6 +269,9 @@ void ct2msg(const struct nf_conntrack *ct, struct nethdr *n) if (nfct_attr_is_set(ct, ATTR_HELPER_NAME)) ct_build_str(ct, ATTR_HELPER_NAME, n, NTA_HELPER_NAME); + + if (nfct_attr_is_set(ct, ATTR_CONNLABELS)) + ct_build_clabel(ct, n); } static void diff --git a/src/parse.c b/src/parse.c index 8ce4495..f3ec6ac 100644 --- a/src/parse.c +++ b/src/parse.c @@ -29,15 +29,19 @@ static void ct_parse_u8(struct nf_conntrack *ct, int attr, void *data); static void ct_parse_u16(struct nf_conntrack *ct, int attr, void *data); static void ct_parse_u32(struct nf_conntrack *ct, int attr, void *data); -static void ct_parse_str(struct nf_conntrack *ct, int attr, void *data); +static void ct_parse_str(struct nf_conntrack *ct, + const struct netattr *, void *data); static void ct_parse_group(struct nf_conntrack *ct, int attr, void *data); static void ct_parse_nat_seq_adj(struct nf_conntrack *ct, int attr, void *data); +static void ct_parse_clabel(struct nf_conntrack *ct, + const struct netattr *, void *data); struct ct_parser { void (*parse)(struct nf_conntrack *ct, int attr, void *data); - int attr; - int size; - int max_size; + void (*parse2)(struct nf_conntrack *ct, const struct netattr *, void *); + uint16_t attr; + uint16_t size; + uint16_t max_size; }; static struct ct_parser h[NTA_MAX] = { @@ -176,10 +180,15 @@ static struct ct_parser h[NTA_MAX] = { .size = NTA_SIZE(sizeof(uint8_t)), }, [NTA_HELPER_NAME] = { - .parse = ct_parse_str, + .parse2 = ct_parse_str, .attr = ATTR_HELPER_NAME, .max_size = NFCT_HELPER_NAME_MAX, }, + [NTA_LABELS] = { + .parse2 = ct_parse_clabel, + .attr = ATTR_CONNLABELS, + .max_size = NTA_SIZE(NTA_LABELS_MAX_SIZE), + }, }; static void @@ -204,9 +213,9 @@ ct_parse_u32(struct nf_conntrack *ct, int attr, void *data) } static void -ct_parse_str(struct nf_conntrack *ct, int attr, void *data) +ct_parse_str(struct nf_conntrack *ct, const struct netattr *attr, void *data) { - nfct_set_attr(ct, h[attr].attr, data); + nfct_set_attr(ct, h[attr->nta_attr].attr, data); } static void @@ -216,6 +225,44 @@ ct_parse_group(struct nf_conntrack *ct, int attr, void *data) } static void +ct_parse_clabel(struct nf_conntrack *ct, const struct netattr *attr, void *data) +{ + struct nfct_bitmask *bitm; + unsigned int i, wordcount; + const uint32_t *words; + unsigned int len; + + len = attr->nta_len - NTA_LENGTH(0); + wordcount = len / sizeof(*words); + if (!wordcount) + return; + + if (len & (sizeof(*words) - 1)) + return; + + bitm = nfct_bitmask_new((len * 8) - 1); + if (!bitm) + return; + + words = data; + for (i=0; i < wordcount; i++) { + uint32_t word; + int bit; + + if (words[i] == 0) + continue; + + word = htonl(words[i]); + bit = 31; + do { + if (word & (1 << bit)) + nfct_bitmask_set_bit(bitm, (32 * i) + bit); + } while (--bit >= 0); + } + nfct_set_attr(ct, ATTR_CONNLABELS, bitm); +} + +static void ct_parse_nat_seq_adj(struct nf_conntrack *ct, int attr, void *data) { struct nta_attr_natseqadj *this = data; @@ -248,14 +295,22 @@ int msg2ct(struct nf_conntrack *ct, struct nethdr *net, size_t remain) ATTR_NETWORK2HOST(attr); if (attr->nta_len > len) return -1; + if (attr->nta_len < NTA_LENGTH(0)) + return -1; if (attr->nta_attr > NTA_MAX) return -1; if (h[attr->nta_attr].size && attr->nta_len != h[attr->nta_attr].size) return -1; - if (h[attr->nta_attr].max_size && - attr->nta_len > h[attr->nta_attr].max_size) - return -1; + + if (h[attr->nta_attr].max_size) { + if (attr->nta_len > h[attr->nta_attr].max_size) + return -1; + h[attr->nta_attr].parse2(ct, attr, NTA_DATA(attr)); + attr = NTA_NEXT(attr, len); + continue; + } + if (h[attr->nta_attr].parse == NULL) { attr = NTA_NEXT(attr, len); continue; @@ -457,6 +512,8 @@ int msg2exp(struct nf_expect *exp, struct nethdr *net, size_t remain) goto err; if (attr->nta_attr > NTA_MAX) goto err; + if (attr->nta_len < NTA_LENGTH(0)) + goto err; if (exp_h[attr->nta_attr].size && attr->nta_len != exp_h[attr->nta_attr].size) goto err; -- 1.8.1.5 ^ permalink raw reply related [flat|nested] 3+ messages in thread
* [PATCH 2/2] conntrack: add connlabel format attribute 2013-06-30 21:10 [PATCH conntracktools] conntrackd: support replication of connlabels Florian Westphal @ 2013-06-30 21:10 ` Florian Westphal 2013-06-30 21:39 ` Pablo Neira Ayuso 0 siblings, 1 reply; 3+ messages in thread From: Florian Westphal @ 2013-06-30 21:10 UTC (permalink / raw) To: netfilter-devel; +Cc: Florian Westphal Signed-off-by: Florian Westphal <fw@strlen.de> --- Change since v1: - rename option to '-o labels' - make it incompatible with xml option (can't add attributes to existing xml output buffer without insane hackery ] conntrack.8 | 4 +++- src/conntrack.c | 39 +++++++++++++++++++++++++++++++++++---- 2 files changed, 38 insertions(+), 5 deletions(-) diff --git a/conntrack.8 b/conntrack.8 index a411fd4..41a59ce 100644 --- a/conntrack.8 +++ b/conntrack.8 @@ -88,11 +88,13 @@ Show the in-kernel connection tracking system statistics. Atomically zero counters after reading them. This option is only valid in combination with the "-L, --dump" command options. .TP -.BI "-o, --output [extended,xml,timestamp,id,ktimestamp] " +.BI "-o, --output [extended,xml,timestamp,id,ktimestamp,labels] " Display output in a certain format. With the extended output option, this tool displays the layer 3 information. With ktimestamp, it displays the in-kernel timestamp available since 2.6.38 (you can enable it via echo 1 > /proc/sys/net/netfilter/nf_conntrack_timestamp). +The labels output option tells conntrack to show the names of labels that +might be present, this is currently incompatible with xml output. .TP .BI "-e, --event-mask " "[ALL|NEW|UPDATES|DESTROY][,...]" Set the bitmask of events that are to be generated by the in-kernel ctnetlink diff --git a/src/conntrack.c b/src/conntrack.c index d4e79de..74561ba 100644 --- a/src/conntrack.c +++ b/src/conntrack.c @@ -488,6 +488,7 @@ static unsigned int addr_valid_flags[ADDR_VALID_FLAGS_MAX] = { static LIST_HEAD(proto_list); static unsigned int options; +static struct nfct_labelmap *label_map; void register_proto(struct ctproto_handler *h) { @@ -731,6 +732,7 @@ enum { _O_TMS = (1 << 2), _O_ID = (1 << 3), _O_KTMS = (1 << 4), + _O_LAB = (1 << 5), }; enum { @@ -749,8 +751,8 @@ static struct parse_parameter { { IPS_ASSURED, IPS_SEEN_REPLY, 0, IPS_FIXED_TIMEOUT, IPS_EXPECTED} }, { {"ALL", "NEW", "UPDATES", "DESTROY"}, 4, { CT_EVENT_F_ALL, CT_EVENT_F_NEW, CT_EVENT_F_UPD, CT_EVENT_F_DEL } }, - { {"xml", "extended", "timestamp", "id", "ktimestamp"}, 5, - { _O_XML, _O_EXT, _O_TMS, _O_ID, _O_KTMS }, + { {"xml", "extended", "timestamp", "id", "ktimestamp", "labels", }, 6, + { _O_XML, _O_EXT, _O_TMS, _O_ID, _O_KTMS, _O_LAB }, }, }; @@ -1108,6 +1110,15 @@ exp_event_sighandler(int s) exit(0); } +static void print_labels(const struct nfct_bitmask *b) +{ + char buf[1024]; + if (!b) + return; + nfct_snprintf_labels(buf, sizeof(buf), label_map, b, NFCT_O_DEFAULT); + printf(" labels=%s", buf); +} + static int event_cb(enum nf_conntrack_msg_type type, struct nf_conntrack *ct, void *data) @@ -1152,7 +1163,11 @@ static int event_cb(enum nf_conntrack_msg_type type, nfct_snprintf(buf, sizeof(buf), ct, type, op_type, op_flags); - printf("%s\n", buf); + printf("%s", buf); + + if (output_mask & _O_LAB) + print_labels(nfct_get_attr(ct, ATTR_CONNLABELS)); + printf("\n"); fflush(stdout); counter++; @@ -1195,8 +1210,11 @@ static int dump_cb(enum nf_conntrack_msg_type type, op_flags |= NFCT_OF_ID; nfct_snprintf(buf, sizeof(buf), ct, NFCT_T_UNKNOWN, op_type, op_flags); - printf("%s\n", buf); + printf("%s", buf); + if (output_mask & _O_LAB) + print_labels(nfct_get_attr(ct, ATTR_CONNLABELS)); + printf("\n"); counter++; return NFCT_CB_CONTINUE; @@ -1879,6 +1897,17 @@ int main(int argc, char *argv[]) case 'o': options |= CT_OPT_OUTPUT; parse_parameter(optarg, &output_mask, PARSE_OUTPUT); + if (output_mask & _O_LAB) { + if (output_mask & _O_XML) { + output_mask &= ~_O_LAB; + break; + } + label_map = nfct_labelmap_new(NULL); + if (!label_map) { + perror("nfct_labelmap_new"); + output_mask &= ~_O_LAB; + } + } break; case 'z': options |= CT_OPT_ZERO; @@ -2372,6 +2401,8 @@ try_proc: free_tmpl_objects(); free_options(); + if (label_map) + nfct_labelmap_destroy(label_map); if (command && exit_msg[cmd][0]) { fprintf(stderr, "%s v%s (conntrack-tools): ",PROGNAME,VERSION); -- 1.8.1.5 ^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH 2/2] conntrack: add connlabel format attribute 2013-06-30 21:10 ` [PATCH 2/2] conntrack: add connlabel format attribute Florian Westphal @ 2013-06-30 21:39 ` Pablo Neira Ayuso 0 siblings, 0 replies; 3+ messages in thread From: Pablo Neira Ayuso @ 2013-06-30 21:39 UTC (permalink / raw) To: Florian Westphal; +Cc: netfilter-devel On Sun, Jun 30, 2013 at 11:10:48PM +0200, Florian Westphal wrote: > Signed-off-by: Florian Westphal <fw@strlen.de> > --- > Change since v1: > - rename option to '-o labels' > - make it incompatible with xml option (can't > add attributes to existing xml output > buffer without insane hackery ] Ah, now I understand the XML issue. You can have something like in libnetfilter_conntrack: extern int nfct_snprintf_clabels(char *buf, unsigned int size, const struct nf_conntrack *ct, const unsigned int msg_type, const unsigned int out_type, const unsigned int out_flags, struct nfct_labelmap *map, const struct nfct_bitmask *b); We have then two interfaces, the normal nfct_snprintf(...) for people that don't need clabels, and the one that includes clabels (including XML support). Having two interfaces to print seems fine to me. You could even emulate nfct_snprintf by allow last two parameters (labelmap and bitmask) to be NULL, that will simply the patch as nfct_snprintf will interface call nfct_snprintf_clabels. You'll have to adapt this patch for the conntrack util though. Thanks. > conntrack.8 | 4 +++- > src/conntrack.c | 39 +++++++++++++++++++++++++++++++++++---- > 2 files changed, 38 insertions(+), 5 deletions(-) > > diff --git a/conntrack.8 b/conntrack.8 > index a411fd4..41a59ce 100644 > --- a/conntrack.8 > +++ b/conntrack.8 > @@ -88,11 +88,13 @@ Show the in-kernel connection tracking system statistics. > Atomically zero counters after reading them. This option is only valid in > combination with the "-L, --dump" command options. > .TP > -.BI "-o, --output [extended,xml,timestamp,id,ktimestamp] " > +.BI "-o, --output [extended,xml,timestamp,id,ktimestamp,labels] " > Display output in a certain format. With the extended output option, this tool > displays the layer 3 information. With ktimestamp, it displays the in-kernel > timestamp available since 2.6.38 (you can enable it via echo 1 > > /proc/sys/net/netfilter/nf_conntrack_timestamp). > +The labels output option tells conntrack to show the names of labels that > +might be present, this is currently incompatible with xml output. > .TP > .BI "-e, --event-mask " "[ALL|NEW|UPDATES|DESTROY][,...]" > Set the bitmask of events that are to be generated by the in-kernel ctnetlink > diff --git a/src/conntrack.c b/src/conntrack.c > index d4e79de..74561ba 100644 > --- a/src/conntrack.c > +++ b/src/conntrack.c > @@ -488,6 +488,7 @@ static unsigned int addr_valid_flags[ADDR_VALID_FLAGS_MAX] = { > static LIST_HEAD(proto_list); > > static unsigned int options; > +static struct nfct_labelmap *label_map; > > void register_proto(struct ctproto_handler *h) > { > @@ -731,6 +732,7 @@ enum { > _O_TMS = (1 << 2), > _O_ID = (1 << 3), > _O_KTMS = (1 << 4), > + _O_LAB = (1 << 5), > }; > > enum { > @@ -749,8 +751,8 @@ static struct parse_parameter { > { IPS_ASSURED, IPS_SEEN_REPLY, 0, IPS_FIXED_TIMEOUT, IPS_EXPECTED} }, > { {"ALL", "NEW", "UPDATES", "DESTROY"}, 4, > { CT_EVENT_F_ALL, CT_EVENT_F_NEW, CT_EVENT_F_UPD, CT_EVENT_F_DEL } }, > - { {"xml", "extended", "timestamp", "id", "ktimestamp"}, 5, > - { _O_XML, _O_EXT, _O_TMS, _O_ID, _O_KTMS }, > + { {"xml", "extended", "timestamp", "id", "ktimestamp", "labels", }, 6, > + { _O_XML, _O_EXT, _O_TMS, _O_ID, _O_KTMS, _O_LAB }, > }, > }; > > @@ -1108,6 +1110,15 @@ exp_event_sighandler(int s) > exit(0); > } > > +static void print_labels(const struct nfct_bitmask *b) > +{ > + char buf[1024]; > + if (!b) > + return; > + nfct_snprintf_labels(buf, sizeof(buf), label_map, b, NFCT_O_DEFAULT); > + printf(" labels=%s", buf); > +} > + > static int event_cb(enum nf_conntrack_msg_type type, > struct nf_conntrack *ct, > void *data) > @@ -1152,7 +1163,11 @@ static int event_cb(enum nf_conntrack_msg_type type, > > nfct_snprintf(buf, sizeof(buf), ct, type, op_type, op_flags); > > - printf("%s\n", buf); > + printf("%s", buf); > + > + if (output_mask & _O_LAB) > + print_labels(nfct_get_attr(ct, ATTR_CONNLABELS)); > + printf("\n"); > fflush(stdout); > > counter++; > @@ -1195,8 +1210,11 @@ static int dump_cb(enum nf_conntrack_msg_type type, > op_flags |= NFCT_OF_ID; > > nfct_snprintf(buf, sizeof(buf), ct, NFCT_T_UNKNOWN, op_type, op_flags); > - printf("%s\n", buf); > + printf("%s", buf); > > + if (output_mask & _O_LAB) > + print_labels(nfct_get_attr(ct, ATTR_CONNLABELS)); > + printf("\n"); > counter++; > > return NFCT_CB_CONTINUE; > @@ -1879,6 +1897,17 @@ int main(int argc, char *argv[]) > case 'o': > options |= CT_OPT_OUTPUT; > parse_parameter(optarg, &output_mask, PARSE_OUTPUT); > + if (output_mask & _O_LAB) { > + if (output_mask & _O_XML) { > + output_mask &= ~_O_LAB; > + break; > + } > + label_map = nfct_labelmap_new(NULL); > + if (!label_map) { > + perror("nfct_labelmap_new"); > + output_mask &= ~_O_LAB; > + } > + } > break; > case 'z': > options |= CT_OPT_ZERO; > @@ -2372,6 +2401,8 @@ try_proc: > > free_tmpl_objects(); > free_options(); > + if (label_map) > + nfct_labelmap_destroy(label_map); > > if (command && exit_msg[cmd][0]) { > fprintf(stderr, "%s v%s (conntrack-tools): ",PROGNAME,VERSION); > -- > 1.8.1.5 > > -- > To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2013-06-30 21:39 UTC | newest] Thread overview: 3+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2013-06-30 21:10 [PATCH conntracktools] conntrackd: support replication of connlabels Florian Westphal 2013-06-30 21:10 ` [PATCH 2/2] conntrack: add connlabel format attribute Florian Westphal 2013-06-30 21:39 ` Pablo Neira Ayuso
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).