From patchwork Fri Jan 25 02:32:30 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marcelo Leitner X-Patchwork-Id: 1030779 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 43m33Y0WDdz9s7T for ; Fri, 25 Jan 2019 13:33:13 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728627AbfAYCdL (ORCPT ); Thu, 24 Jan 2019 21:33:11 -0500 Received: from mx1.redhat.com ([209.132.183.28]:46620 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728575AbfAYCdJ (ORCPT ); Thu, 24 Jan 2019 21:33:09 -0500 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 16E3CAC5EB; Fri, 25 Jan 2019 02:33:09 +0000 (UTC) Received: from localhost.localdomain (ovpn-116-7.gru2.redhat.com [10.97.116.7]) by smtp.corp.redhat.com (Postfix) with ESMTPS id BCA7E1690C; Fri, 25 Jan 2019 02:33:04 +0000 (UTC) Received: by localhost.localdomain (Postfix, from userid 1000) id E6A49180BE2; Fri, 25 Jan 2019 00:33:02 -0200 (-02) From: Marcelo Ricardo Leitner To: Guy Shattah , Marcelo Leitner , Aaron Conole , John Hurley , Simon Horman , Justin Pettit , Gregory Rose , Eelco Chaudron , Flavio Leitner , Florian Westphal , Jiri Pirko , Rashid Khan , Sushil Kulkarni , Andy Gospodarek , Roi Dayan , Yossi Kuperman , Or Gerlitz , Rony Efraim , "davem@davemloft.net" Cc: netdev@vger.kernel.org Subject: [RFC PATCH 1/6] flow_dissector: add support for matching on ConnTrack Date: Fri, 25 Jan 2019 00:32:30 -0200 Message-Id: <144ea7746432c8177a1b9a62db98e7b3ada3c642.1548285996.git.mleitner@redhat.com> In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.28]); Fri, 25 Jan 2019 02:33:09 +0000 (UTC) Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org This a preliminary patch to add support on flow dissector for matching on ConnTrack information. 2 FIXMEs in place: - reusing nf_conn_labels may not be feasible, as we don't want to pull too much of ConnTrack into flow dissector. - CT may be there, but it may not be using labels. As hashing zeroes is different than not having the information, it should either be handled as a new dissector key or have an extra bit in flow_dissector_key_ct indicating its presence. Having it as an extra key may speed searches not using labels. Signed-off-by: Marcelo Ricardo Leitner --- include/net/flow_dissector.h | 17 ++++++++++++++ include/uapi/linux/netfilter/xt_connlabel.h | 5 +++++ net/core/flow_dissector.c | 25 +++++++++++++++++++++ 3 files changed, 47 insertions(+) diff --git a/include/net/flow_dissector.h b/include/net/flow_dissector.h index 6a4586dcdeded9b6cfe7d299d368b6a6ea6801cc..2b5a20a0f65c28d9907697ac3ef7e03d0e20209a 100644 --- a/include/net/flow_dissector.h +++ b/include/net/flow_dissector.h @@ -4,7 +4,9 @@ #include #include +#include #include +#include /** * struct flow_dissector_key_control: @@ -199,6 +201,19 @@ struct flow_dissector_key_ip { __u8 ttl; }; +/** + * struct flow_dissector_key_ct: + */ +struct flow_dissector_key_ct { + __u16 zone; + __u8 state; + __u32 mark; + /* FIXME: Use nf_conn_labels instead? But it pulls all netfilter */ +#define NF_CT_LABELS_MAX_SIZE ((XT_CONNLABEL_MAXBIT + 1) / BITS_PER_BYTE) + unsigned long label[NF_CT_LABELS_MAX_SIZE / sizeof(long)]; +#undef NF_CT_LABELS_MAX_SIZE +}; + enum flow_dissector_key_id { FLOW_DISSECTOR_KEY_CONTROL, /* struct flow_dissector_key_control */ FLOW_DISSECTOR_KEY_BASIC, /* struct flow_dissector_key_basic */ @@ -224,6 +239,7 @@ enum flow_dissector_key_id { FLOW_DISSECTOR_KEY_CVLAN, /* struct flow_dissector_key_flow_vlan */ FLOW_DISSECTOR_KEY_ENC_IP, /* struct flow_dissector_key_ip */ FLOW_DISSECTOR_KEY_ENC_OPTS, /* struct flow_dissector_key_enc_opts */ + FLOW_DISSECTOR_KEY_CT, /* struct flow_dissector_key_ct */ FLOW_DISSECTOR_KEY_MAX, }; @@ -254,6 +270,7 @@ struct flow_keys { #define FLOW_KEYS_HASH_START_FIELD basic struct flow_dissector_key_basic basic; struct flow_dissector_key_tags tags; + struct flow_dissector_key_ct ct; struct flow_dissector_key_vlan vlan; struct flow_dissector_key_vlan cvlan; struct flow_dissector_key_keyid keyid; diff --git a/include/uapi/linux/netfilter/xt_connlabel.h b/include/uapi/linux/netfilter/xt_connlabel.h index 2312f0ec07b2791ffaece0a95eebaefa727f14be..20a1c1fe79a7676c4b9f8727c393443f2d545784 100644 --- a/include/uapi/linux/netfilter/xt_connlabel.h +++ b/include/uapi/linux/netfilter/xt_connlabel.h @@ -1,4 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +#ifndef _NF_CONNTRACK_CONNLABEL_H +#define _NF_CONNTRACK_CONNLABEL_H + #include #define XT_CONNLABEL_MAXBIT 127 @@ -11,3 +14,5 @@ struct xt_connlabel_mtinfo { __u16 bit; __u16 options; }; + +#endif diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c index 2e8d91e54179c32b41ab53b9fa424fe1691acde0..73336466423aedff9a6fc4724f6c6efe44d5225a 100644 --- a/net/core/flow_dissector.c +++ b/net/core/flow_dissector.c @@ -26,6 +26,8 @@ #include #include #include +#include +#include static DEFINE_MUTEX(flow_dissector_mutex); @@ -798,6 +800,29 @@ bool __skb_flow_dissect(const struct sk_buff *skb, } rcu_read_unlock(); + if (dissector_uses_key(flow_dissector, + FLOW_DISSECTOR_KEY_CT)) { + struct flow_dissector_key_ct *key_ct; + enum ip_conntrack_info ctinfo; + struct nf_conn_labels *labels; + struct nf_conn *ct; + + ct = nf_ct_get(skb, &ctinfo); + if (ct) { + key_ct = skb_flow_dissector_target(flow_dissector, + FLOW_DISSECTOR_KEY_CT, + target_container); + key_ct->zone = ct->zone.id; + key_ct->state = ctinfo; + key_ct->mark = ct->mark; + labels = nf_ct_labels_find(ct); + /* FIXME: should this be a new key then? */ + if (labels) + memcpy(key_ct->label, labels->bits, + sizeof(key_ct->label)); + } + } + if (dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_ETH_ADDRS)) { struct ethhdr *eth = eth_hdr(skb);