From patchwork Thu Nov 19 18:52:51 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tejun Heo X-Patchwork-Id: 546611 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 1011E1414A0 for ; Fri, 20 Nov 2015 05:54:18 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b=m3xykoIP; dkim-atps=neutral Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1161163AbbKSSxz (ORCPT ); Thu, 19 Nov 2015 13:53:55 -0500 Received: from mail-yk0-f180.google.com ([209.85.160.180]:32891 "EHLO mail-yk0-f180.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1161118AbbKSSxH (ORCPT ); Thu, 19 Nov 2015 13:53:07 -0500 Received: by ykdv3 with SMTP id v3so121226877ykd.0; Thu, 19 Nov 2015 10:53:06 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=RBUxfblHD29XaSmLsdf/vpjVk1otG+gVC73hoge6el0=; b=m3xykoIP2fZmLrTfhL2PPuUfBNAlAyRN5zcTDnJyU4NjTdalItKNZY70U+OCKNPY+v 8QhJmqCqQDJnumcU1ReEBULVlSNKF8I9JHMVd5hdDyS1LNVqGd5zLhsFkx7pi20EwuGm LStN4KFVlZImrc/8cLJk5v/nJDPGosa+n/cISqyyRHYkQO8fGL4tacD1nhQgWf4YR/31 92aGTqKP0Fj5EjiT1/A5RcmggUJqgZ66eT2HAvkNH6H9hORB9xyiNTQbbPe1/2BAFnRj txflNz6IpGPB4BH0CZHI6k2iM2qoivpRXqsvyLExef5UX/kesZ3oAUyex2eYspKqIDAs EJlw== X-Received: by 10.129.33.198 with SMTP id h189mr8030140ywh.195.1447959186227; Thu, 19 Nov 2015 10:53:06 -0800 (PST) Received: from mtj.duckdns.org.com ([2620:10d:c091:200::f:9c1]) by smtp.googlemail.com with ESMTPSA id v127sm8775576ywd.53.2015.11.19.10.53.04 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 19 Nov 2015 10:53:05 -0800 (PST) From: Tejun Heo To: davem@davemloft.net, pablo@netfilter.org, kaber@trash.net, kadlec@blackhole.kfki.hu, lizefan@huawei.com, hannes@cmpxchg.org Cc: netdev@vger.kernel.org, netfilter-devel@vger.kernel.org, coreteam@netfilter.org, cgroups@vger.kernel.org, linux-kernel@vger.kernel.org, kernel-team@fb.com, daniel@iogearbox.net, daniel.wagner@bmw-carit.de, nhorman@tuxdriver.com, Tejun Heo , Jan Engelhardt Subject: [PATCH 7/7] netfilter: implement xt_cgroup2 match Date: Thu, 19 Nov 2015 13:52:51 -0500 Message-Id: <1447959171-20749-8-git-send-email-tj@kernel.org> X-Mailer: git-send-email 2.5.0 In-Reply-To: <1447959171-20749-1-git-send-email-tj@kernel.org> References: <1447959171-20749-1-git-send-email-tj@kernel.org> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org This patch implements xt_cgroup2 which matches cgroup2 membership of the associated socket. The match is recursive and invertible. For rationales on introducing another cgroup based match, please refer to a preceding commit "sock, cgroup: add sock->sk_cgroup". v2: Included linux/limits.h from xt_cgroup2.h for PATH_MAX. Added explicit alignment to the priv field. Both suggested by Jan. Signed-off-by: Tejun Heo Cc: Daniel Borkmann Cc: Daniel Wagner CC: Neil Horman Cc: Jan Engelhardt --- include/uapi/linux/netfilter/xt_cgroup2.h | 15 ++++++ net/netfilter/Kconfig | 10 ++++ net/netfilter/Makefile | 1 + net/netfilter/xt_cgroup2.c | 78 +++++++++++++++++++++++++++++++ 4 files changed, 104 insertions(+) create mode 100644 include/uapi/linux/netfilter/xt_cgroup2.h create mode 100644 net/netfilter/xt_cgroup2.c diff --git a/include/uapi/linux/netfilter/xt_cgroup2.h b/include/uapi/linux/netfilter/xt_cgroup2.h new file mode 100644 index 0000000..ea51335 --- /dev/null +++ b/include/uapi/linux/netfilter/xt_cgroup2.h @@ -0,0 +1,15 @@ +#ifndef _XT_CGROUP2_H +#define _XT_CGROUP2_H + +#include +#include + +struct xt_cgroup2_info { + char path[PATH_MAX]; + __u8 invert; + + /* kernel internal data */ + void *priv __attribute__((aligned(8))); +}; + +#endif /* _XT_CGROUP2_H */ diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig index e22349e..5fd12dd 100644 --- a/net/netfilter/Kconfig +++ b/net/netfilter/Kconfig @@ -974,6 +974,16 @@ config NETFILTER_XT_MATCH_BPF To compile it as a module, choose M here. If unsure, say N. +config NETFILTER_XT_MATCH_CGROUP2 + tristate '"cgroup2" match support' + depends on NETFILTER_ADVANCED + depends on CGROUPS + select SOCK_CGROUP_DATA + help + cgroup2 matching allows you to match locally generated and + early demuxed packets based on the v2 cgroup the socket is + associated with on creation. + config NETFILTER_XT_MATCH_CGROUP tristate '"control group" match support' depends on NETFILTER_ADVANCED diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile index 7638c36..86cee05 100644 --- a/net/netfilter/Makefile +++ b/net/netfilter/Makefile @@ -152,6 +152,7 @@ obj-$(CONFIG_NETFILTER_XT_MATCH_MULTIPORT) += xt_multiport.o obj-$(CONFIG_NETFILTER_XT_MATCH_NFACCT) += xt_nfacct.o obj-$(CONFIG_NETFILTER_XT_MATCH_OSF) += xt_osf.o obj-$(CONFIG_NETFILTER_XT_MATCH_OWNER) += xt_owner.o +obj-$(CONFIG_NETFILTER_XT_MATCH_CGROUP2) += xt_cgroup2.o obj-$(CONFIG_NETFILTER_XT_MATCH_CGROUP) += xt_cgroup.o obj-$(CONFIG_NETFILTER_XT_MATCH_PHYSDEV) += xt_physdev.o obj-$(CONFIG_NETFILTER_XT_MATCH_PKTTYPE) += xt_pkttype.o diff --git a/net/netfilter/xt_cgroup2.c b/net/netfilter/xt_cgroup2.c new file mode 100644 index 0000000..39884b3 --- /dev/null +++ b/net/netfilter/xt_cgroup2.c @@ -0,0 +1,78 @@ +#include +#include +#include +#include +#include +#include + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Tejun Heo "); +MODULE_DESCRIPTION("Xtables: cgroup2 socket ownership matching"); +MODULE_ALIAS("ipt_cgroup2"); +MODULE_ALIAS("ip6t_cgroup2"); + +static int cgroup2_mt_check(const struct xt_mtchk_param *par) +{ + struct xt_cgroup2_info *info = par->matchinfo; + struct cgroup *cgrp; + + if (info->invert & ~1) + return -EINVAL; + + cgrp = cgroup_get_from_path(info->path); + if (IS_ERR(cgrp)) { + pr_info("xt_cgroup2: invalid path, errno=%ld\n", PTR_ERR(cgrp)); + return -EINVAL; + } + info->priv = cgrp; + + return 0; +} + +static bool cgroup2_mt(const struct sk_buff *skb, struct xt_action_param *par) +{ + const struct xt_cgroup2_info *info = par->matchinfo; + struct cgroup *ancestor = info->priv; + struct cgroup *cgrp; + + if (!skb->sk || !sk_fullsock(skb->sk)) + return false; + + cgrp = sock_cgroup_ptr(&skb->sk->sk_cgrp_data); + + return cgroup_is_descendant(cgrp, ancestor) ^ info->invert; +} + +static void cgroup2_mt_destroy(const struct xt_mtdtor_param *par) +{ + struct xt_cgroup2_info *info = par->matchinfo; + + cgroup_put(info->priv); +} + +static struct xt_match cgroup2_mt_reg __read_mostly = { + .name = "cgroup2", + .revision = 0, + .family = NFPROTO_UNSPEC, + .checkentry = cgroup2_mt_check, + .match = cgroup2_mt, + .matchsize = sizeof(struct xt_cgroup2_info), + .destroy = cgroup2_mt_destroy, + .me = THIS_MODULE, + .hooks = (1 << NF_INET_LOCAL_OUT) | + (1 << NF_INET_POST_ROUTING) | + (1 << NF_INET_LOCAL_IN), +}; + +static int __init cgroup2_mt_init(void) +{ + return xt_register_match(&cgroup2_mt_reg); +} + +static void __exit cgroup2_mt_exit(void) +{ + xt_unregister_match(&cgroup2_mt_reg); +} + +module_init(cgroup2_mt_init); +module_exit(cgroup2_mt_exit);