From patchwork Tue Apr 15 11:54:53 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ken-ichirou MATSUZAWA X-Patchwork-Id: 339253 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 1579D140080 for ; Tue, 15 Apr 2014 21:55:15 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751012AbaDOLzF (ORCPT ); Tue, 15 Apr 2014 07:55:05 -0400 Received: from mail-pb0-f53.google.com ([209.85.160.53]:58593 "EHLO mail-pb0-f53.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750853AbaDOLzA (ORCPT ); Tue, 15 Apr 2014 07:55:00 -0400 Received: by mail-pb0-f53.google.com with SMTP id rp16so9422593pbb.12 for ; Tue, 15 Apr 2014 04:55:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=date:from:to:cc:subject:message-id:references:mime-version :content-type:content-disposition:in-reply-to:user-agent; bh=OiNNx10Dhd1tatDxR1Nqx7gIt/LA6+VRNRw1pCh59dU=; b=tpinUz9lN0vP7OwQz3LO+m5hQLDPz2GRaqazRUz3o7mTJEAbx3mzjOdiM1CzcTpSs+ +w9ggd9xlM3/fIKy17jjpw3BKNtyKxvsAD4U0kyCpYvUx2nUHjAp26b7hKO4eFJ6+VOO 2QwUXFJofwb/+HLuv0qGTmRnRuZ8EOv5X+x8obxjSvJweyHlaDDbf3B5Qd0SfktdjUMt GBy65DTBj5IOzkw5xfmABh1XAhdrwGVehwO8f4tzg0j3N4G4Of4/hvrn/S6C8ztz8ewI 3BoWnUwdkq4g9jgN0xkKCSKjFM263FghZs8ggqbi1cu94syV0yBmw/eEtrnjVL+00EH+ g2yw== X-Received: by 10.68.171.4 with SMTP id aq4mr1446887pbc.150.1397562899957; Tue, 15 Apr 2014 04:54:59 -0700 (PDT) Received: from gmail.com (softbank220009032009.bbtec.net. [220.9.32.9]) by mx.google.com with ESMTPSA id it4sm39898536pbd.48.2014.04.15.04.54.57 for (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Tue, 15 Apr 2014 04:54:58 -0700 (PDT) Date: Tue, 15 Apr 2014 20:54:53 +0900 From: Ken-ichirou MATSUZAWA To: Pablo Neira Ayuso Cc: netfilter-devel@vger.kernel.org Subject: [libnetfilter_conntrack PATCH 1/3 resend] conntrack: add mark event filter Message-ID: <20140415115453.GA6947@gmail.com> References: <20140408102614.GA29462@gmail.com> <20140408103002.GB29462@gmail.com> <20140414125324.GA22192@localhost> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20140414125324.GA22192@localhost> User-Agent: Mutt/1.5.21 (2010-09-15) Sender: netfilter-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org This patch adds mark filter for event listener, using same struct nfct_filter_dump_mark. Signed-off-by Ken-ichirou MATSUZAWA --- include/internal/object.h | 7 +++ .../libnetfilter_conntrack.h | 1 + src/conntrack/bsf.c | 55 ++++++++++++++++++++++ src/conntrack/filter.c | 13 +++++ 4 files changed, 76 insertions(+) diff --git a/include/internal/object.h b/include/internal/object.h index 540ad0d..1259467 100644 --- a/include/internal/object.h +++ b/include/internal/object.h @@ -263,6 +263,13 @@ struct nfct_filter { u_int32_t mask[4]; } l3proto_ipv6[2][__FILTER_IPV6_MAX]; + u_int32_t mark_elems; + struct { +#define __FILTER_MARK_MAX 127 + u_int32_t val; + u_int32_t mask; + } mark[__FILTER_MARK_MAX]; + u_int32_t set[1]; }; diff --git a/include/libnetfilter_conntrack/libnetfilter_conntrack.h b/include/libnetfilter_conntrack/libnetfilter_conntrack.h index d4542ba..890721a 100644 --- a/include/libnetfilter_conntrack/libnetfilter_conntrack.h +++ b/include/libnetfilter_conntrack/libnetfilter_conntrack.h @@ -496,6 +496,7 @@ enum nfct_filter_attr { NFCT_FILTER_DST_IPV4, /* struct nfct_filter_ipv4 */ NFCT_FILTER_SRC_IPV6, /* struct nfct_filter_ipv6 */ NFCT_FILTER_DST_IPV6, /* struct nfct_filter_ipv6 */ + NFCT_FILTER_MARK, /* struct nfct_filter_dump_mark */ NFCT_FILTER_MAX }; diff --git a/src/conntrack/bsf.c b/src/conntrack/bsf.c index 534202f..632c201 100644 --- a/src/conntrack/bsf.c +++ b/src/conntrack/bsf.c @@ -663,6 +663,58 @@ bsf_add_daddr_ipv6_filter(const struct nfct_filter *f, struct sock_filter *this) return bsf_add_addr_ipv6_filter(f, this, CTA_IP_V6_DST); } +static int +bsf_add_mark_filter(const struct nfct_filter *f, struct sock_filter *this) +{ + unsigned int i, j; + unsigned int label_continue, jt; + struct stack *s; + struct jump jmp; + + /* nothing to filter, skip */ + if (f->mark_elems == 0) + return 0; + + /* XXX: see bsf_add_addr_ipv4_filter() */ + s = stack_create(sizeof(struct jump), 3 + 127); + if (s == NULL) { + errno = ENOMEM; + return -1; + } + + jt = 1; + if (f->logic[NFCT_FILTER_MARK] == NFCT_FILTER_LOGIC_POSITIVE) + label_continue = 1; + else + label_continue = 2; + + j = 0; + j += nfct_bsf_load_payload_offset(this, j); + j += nfct_bsf_find_attr(this, CTA_MARK, j); + j += nfct_bsf_cmp_k_stack(this, 0, label_continue - j, j, s); + j += nfct_bsf_x_equal_a(this, j); + + for (i = 0; i < f->mark_elems; i++) { + int mark = f->mark[i].val & f->mark[i].mask; + + j += nfct_bsf_load_attr(this, BPF_W, j); + j += nfct_bsf_alu_and(this, f->mark[i].mask, j); + j += nfct_bsf_cmp_k_stack(this, mark, jt - j, j, s); + } + + while (stack_pop(s, &jmp) != -1) + this[jmp.line].jt += jmp.jt + j; + + if (f->logic[NFCT_FILTER_MARK] == NFCT_FILTER_LOGIC_NEGATIVE) + j += nfct_bsf_jump_to(this, 1, j); + + j += nfct_bsf_ret_verdict(this, NFCT_FILTER_REJECT, j); + + stack_destroy(s); + + return j; +} + /* this buffer must be big enough to store all the autogenerated lines */ #define BSF_BUFFER_SIZE 2048 @@ -696,6 +748,9 @@ int __setup_netlink_socket_filter(int fd, struct nfct_filter *f) j += bsf_add_state_filter(f, &bsf[j]); show_filter(bsf, from, j, "---- check state ----"); from = j; + j += bsf_add_mark_filter(f, &bsf[j]); + show_filter(bsf, from, j, "---- check mark ----"); + from = j; /* nothing to filter, skip */ if (j == 0) diff --git a/src/conntrack/filter.c b/src/conntrack/filter.c index 026545a..78fbbc5 100644 --- a/src/conntrack/filter.c +++ b/src/conntrack/filter.c @@ -79,6 +79,18 @@ static void filter_attr_dst_ipv6(struct nfct_filter *filter, const void *value) filter->l3proto_elems_ipv6[1]++; } +static void filter_attr_mark(struct nfct_filter *filter, const void *value) +{ + const struct nfct_filter_dump_mark *this = value; + + if (filter->mark_elems >= __FILTER_MARK_MAX) + return; + + filter->mark[filter->mark_elems].val = this->val; + filter->mark[filter->mark_elems].mask = this->mask; + filter->mark_elems++; +} + const filter_attr filter_attr_array[NFCT_FILTER_MAX] = { [NFCT_FILTER_L4PROTO] = filter_attr_l4proto, [NFCT_FILTER_L4PROTO_STATE] = filter_attr_l4proto_state, @@ -86,4 +98,5 @@ const filter_attr filter_attr_array[NFCT_FILTER_MAX] = { [NFCT_FILTER_DST_IPV4] = filter_attr_dst_ipv4, [NFCT_FILTER_SRC_IPV6] = filter_attr_src_ipv6, [NFCT_FILTER_DST_IPV6] = filter_attr_dst_ipv6, + [NFCT_FILTER_MARK] = filter_attr_mark, };