From patchwork Thu Jun 30 21:19:33 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aaron Conole X-Patchwork-Id: 642767 X-Patchwork-Delegate: pablo@netfilter.org 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 3rgXVw0wCmz9s9Z for ; Fri, 1 Jul 2016 07:19:52 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=bytheb-org.20150623.gappssmtp.com header.i=@bytheb-org.20150623.gappssmtp.com header.b=Dz7wIiFO; dkim-atps=neutral Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752057AbcF3VTp (ORCPT ); Thu, 30 Jun 2016 17:19:45 -0400 Received: from mail-qk0-f196.google.com ([209.85.220.196]:36168 "EHLO mail-qk0-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752477AbcF3VTm (ORCPT ); Thu, 30 Jun 2016 17:19:42 -0400 Received: by mail-qk0-f196.google.com with SMTP id r68so16807988qka.3 for ; Thu, 30 Jun 2016 14:19:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bytheb-org.20150623.gappssmtp.com; s=20150623; h=from:to:subject:date:message-id:in-reply-to:references; bh=7EJL8P4mh1ow4JEKwl9ejg9GueCVSxrahiWSPgK1i7Q=; b=Dz7wIiFOC0Uxo+iJqUS/JwmaWw8lyqjTW9NEIeofSt9idvYP5shuNbb3fLySl8CIsI pnXD7ZVYBm4cXXA8GtwUcdoBd7Qvy3Fd+nQ5iasTpK5ppFhtWnvszg+tynSyy1VLFxMV Idn9zBa10IIUybnJnVMEC0tfMeFDDXviKle4DUYbsPaT/74cX6zCOU3VZdydyhTvca+v v4Ajjvv3GYCpAztMQPaoAxPfllq1NerPIP5BURa+MVRRG4dX1+UWNW8WFs7I3zilyUUo ZKaUhAE2yHG8PYtOmNPzBU5zpzyhvkLFBOVWfsUIimNOL7ICosHH0urbKjzxFyDc4x1+ r8ag== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=7EJL8P4mh1ow4JEKwl9ejg9GueCVSxrahiWSPgK1i7Q=; b=gNsY2ZHmtYzvPUiPJAmv3k21zb3Fbsl7mAOCXX2SAXzi3tTOWdqs2uzu0epJAIk9j6 3x99j9o6uAPKFSVZZ+OorsAMT/fUt0o18WozXq09exE6uAnka7kH6JbQW5EcrhzRaxZ5 0YgOJkN+nUX5RV30kb9PtAGxBZ0nhOn/yQIR6EkgX2Rupz1Yz2oPuGYOTZCmrre5n4Ju u1DhRwC16UBAyw7kXMNJ+4ULvV+Lc6bjmD4qgNxwwIXLUu0+R0Y+lCnXJ95AZkmt68uS BNxmDoQjaAWGsBu+IfkUnstXLAckaJqaVct80OjqfCJ/dHxGjo7RnyVm+ZaeHMRsfb/S jGOg== X-Gm-Message-State: ALyK8tISzSOWhL6wCZcMlf7AbAMvq3GATE8kQYa/S1r7Ec+kNc65rJ1NmsAlBT7sIQKTXw== X-Received: by 10.55.189.131 with SMTP id n125mr20948121qkf.194.1467321581380; Thu, 30 Jun 2016 14:19:41 -0700 (PDT) Received: from dhcp-25-97.bos.redhat.com (nat-pool-bos-t.redhat.com. [66.187.233.206]) by smtp.gmail.com with ESMTPSA id 56sm2839640qtt.31.2016.06.30.14.19.40 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 30 Jun 2016 14:19:40 -0700 (PDT) From: Aaron Conole To: netdev@vger.kernel.org, netfilter-devel@vger.kernel.org Subject: [PATCH nf-next 1/3] netfilter: bridge: add and use br_nf_hook_thresh Date: Thu, 30 Jun 2016 17:19:33 -0400 Message-Id: <1467321575-6107-2-git-send-email-aconole@bytheb.org> X-Mailer: git-send-email 2.5.5 In-Reply-To: <1467321575-6107-1-git-send-email-aconole@bytheb.org> References: <1467321575-6107-1-git-send-email-aconole@bytheb.org> Sender: netfilter-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org From: Florian Westphal This replaces the last uses of NF_HOOK_THRESH(). Followup patch will remove it and rename nf_hook_thresh. The reason is that inet (non-bridge) netfilter no longer invokes the hooks from hooks, so we do no longer need the thresh value to skip hooks with a lower priority. The bridge netfilter however may need to do this. br_nf_hook_thresh is a wrapper that is supposed to do this, i.e. only call hooks with a priority that exceeds NF_BR_PRI_BRNF. It's used only in the recursion cases of br_netfilter. Signed-off-by: Florian Westphal Signed-off-by: Aaron Conole --- include/net/netfilter/br_netfilter.h | 6 ++++ net/bridge/br_netfilter_hooks.c | 57 ++++++++++++++++++++++++++++++------ net/bridge/br_netfilter_ipv6.c | 12 ++++---- 3 files changed, 59 insertions(+), 16 deletions(-) diff --git a/include/net/netfilter/br_netfilter.h b/include/net/netfilter/br_netfilter.h index e8d1448..0b0c35c 100644 --- a/include/net/netfilter/br_netfilter.h +++ b/include/net/netfilter/br_netfilter.h @@ -15,6 +15,12 @@ static inline struct nf_bridge_info *nf_bridge_alloc(struct sk_buff *skb) void nf_bridge_update_protocol(struct sk_buff *skb); +int br_nf_hook_thresh(unsigned int hook, struct net *net, struct sock *sk, + struct sk_buff *skb, struct net_device *indev, + struct net_device *outdev, + int (*okfn)(struct net *, struct sock *, + struct sk_buff *)); + static inline struct nf_bridge_info * nf_bridge_info_get(const struct sk_buff *skb) { diff --git a/net/bridge/br_netfilter_hooks.c b/net/bridge/br_netfilter_hooks.c index 2d25979..19f230c 100644 --- a/net/bridge/br_netfilter_hooks.c +++ b/net/bridge/br_netfilter_hooks.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -395,11 +396,10 @@ bridged_dnat: skb->dev = nf_bridge->physindev; nf_bridge_update_protocol(skb); nf_bridge_push_encap_header(skb); - NF_HOOK_THRESH(NFPROTO_BRIDGE, - NF_BR_PRE_ROUTING, - net, sk, skb, skb->dev, NULL, - br_nf_pre_routing_finish_bridge, - 1); + br_nf_hook_thresh(NF_BR_PRE_ROUTING, + net, sk, skb, skb->dev, + NULL, + br_nf_pre_routing_finish); return 0; } ether_addr_copy(eth_hdr(skb)->h_dest, dev->dev_addr); @@ -417,10 +417,8 @@ bridged_dnat: skb->dev = nf_bridge->physindev; nf_bridge_update_protocol(skb); nf_bridge_push_encap_header(skb); - NF_HOOK_THRESH(NFPROTO_BRIDGE, NF_BR_PRE_ROUTING, net, sk, skb, - skb->dev, NULL, - br_handle_frame_finish, 1); - + br_nf_hook_thresh(NF_BR_PRE_ROUTING, net, sk, skb, skb->dev, NULL, + br_handle_frame_finish); return 0; } @@ -992,6 +990,47 @@ static struct notifier_block brnf_notifier __read_mostly = { .notifier_call = brnf_device_event, }; +/* recursively invokes nf_hook_slow (again), skipping already-called + * hooks (< NF_BR_PRI_BRNF). + * + * Called with rcu read lock held. + */ +int br_nf_hook_thresh(unsigned int hook, struct net *net, + struct sock *sk, struct sk_buff *skb, + struct net_device *indev, + struct net_device *outdev, + int (*okfn)(struct net *, struct sock *, + struct sk_buf *)) +{ + struct nf_hook_ops *elem; + struct nf_hook_state state; + struct list_head *head; + int ret; + + head = &net->nf.hooks[NFPROTO_BRIDGE][hook]; + + list_for_each_entry_rcu(elem, head, list) { + struct nf_hook_ops *next; + + next = list_entry_rcu(list_next_rcu(&elem->list), + struct nf_hook_ops, list); + if (next->priority <= NF_BR_PRI_BRNF) + continue; + } + + if (&elem->list == head) + return okfn(net, sk, skb); + + nf_hook_state_init(&state, head, hook, NF_BR_PRI_BRNF + 1, + NFPROTO_BRIDGE, indev, outdev, sk, net, okfn); + + ret = nf_hook_slow(skb, &state); + if (ret == 1) + ret = okfn(net, sk, skb); + + return ret; +} + #ifdef CONFIG_SYSCTL static int brnf_sysctl_call_tables(struct ctl_table *ctl, int write, diff --git a/net/bridge/br_netfilter_ipv6.c b/net/bridge/br_netfilter_ipv6.c index 5e59a84..5989661 100644 --- a/net/bridge/br_netfilter_ipv6.c +++ b/net/bridge/br_netfilter_ipv6.c @@ -187,10 +187,9 @@ static int br_nf_pre_routing_finish_ipv6(struct net *net, struct sock *sk, struc skb->dev = nf_bridge->physindev; nf_bridge_update_protocol(skb); nf_bridge_push_encap_header(skb); - NF_HOOK_THRESH(NFPROTO_BRIDGE, NF_BR_PRE_ROUTING, - net, sk, skb, skb->dev, NULL, - br_nf_pre_routing_finish_bridge, - 1); + br_nf_hook_thresh(NF_BR_PRE_ROUTING, + net, sk, skb, skb->dev, NULL, + br_nf_pre_routing_finish_bridge); return 0; } ether_addr_copy(eth_hdr(skb)->h_dest, dev->dev_addr); @@ -207,9 +206,8 @@ static int br_nf_pre_routing_finish_ipv6(struct net *net, struct sock *sk, struc skb->dev = nf_bridge->physindev; nf_bridge_update_protocol(skb); nf_bridge_push_encap_header(skb); - NF_HOOK_THRESH(NFPROTO_BRIDGE, NF_BR_PRE_ROUTING, net, sk, skb, - skb->dev, NULL, - br_handle_frame_finish, 1); + br_nf_hook_thresh(NF_BR_PRE_ROUTING, net, sk, skb, + skb->dev, NULL, br_handle_frame_finish); return 0; }