|
@@ -34,6 +34,37 @@ static int cgroup_mt_check_v0(const struct xt_mtchk_param *par)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+static int cgroup_mt_check_v1(const struct xt_mtchk_param *par)
|
|
|
+{
|
|
|
+ struct xt_cgroup_info_v1 *info = par->matchinfo;
|
|
|
+ struct cgroup *cgrp;
|
|
|
+
|
|
|
+ if ((info->invert_path & ~1) || (info->invert_classid & ~1))
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ if (!info->has_path && !info->has_classid) {
|
|
|
+ pr_info("xt_cgroup: no path or classid specified\n");
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (info->has_path && info->has_classid) {
|
|
|
+ pr_info("xt_cgroup: both path and classid specified\n");
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (info->has_path) {
|
|
|
+ cgrp = cgroup_get_from_path(info->path);
|
|
|
+ if (IS_ERR(cgrp)) {
|
|
|
+ pr_info("xt_cgroup: invalid path, errno=%ld\n",
|
|
|
+ PTR_ERR(cgrp));
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+ info->priv = cgrp;
|
|
|
+ }
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
static bool
|
|
|
cgroup_mt_v0(const struct sk_buff *skb, struct xt_action_param *par)
|
|
|
{
|
|
@@ -46,6 +77,31 @@ cgroup_mt_v0(const struct sk_buff *skb, struct xt_action_param *par)
|
|
|
info->invert;
|
|
|
}
|
|
|
|
|
|
+static bool cgroup_mt_v1(const struct sk_buff *skb, struct xt_action_param *par)
|
|
|
+{
|
|
|
+ const struct xt_cgroup_info_v1 *info = par->matchinfo;
|
|
|
+ struct sock_cgroup_data *skcd = &skb->sk->sk_cgrp_data;
|
|
|
+ struct cgroup *ancestor = info->priv;
|
|
|
+
|
|
|
+ if (!skb->sk || !sk_fullsock(skb->sk))
|
|
|
+ return false;
|
|
|
+
|
|
|
+ if (ancestor)
|
|
|
+ return cgroup_is_descendant(sock_cgroup_ptr(skcd), ancestor) ^
|
|
|
+ info->invert_path;
|
|
|
+ else
|
|
|
+ return (info->classid == sock_cgroup_classid(skcd)) ^
|
|
|
+ info->invert_classid;
|
|
|
+}
|
|
|
+
|
|
|
+static void cgroup_mt_destroy_v1(const struct xt_mtdtor_param *par)
|
|
|
+{
|
|
|
+ struct xt_cgroup_info_v1 *info = par->matchinfo;
|
|
|
+
|
|
|
+ if (info->priv)
|
|
|
+ cgroup_put(info->priv);
|
|
|
+}
|
|
|
+
|
|
|
static struct xt_match cgroup_mt_reg[] __read_mostly = {
|
|
|
{
|
|
|
.name = "cgroup",
|
|
@@ -59,6 +115,19 @@ static struct xt_match cgroup_mt_reg[] __read_mostly = {
|
|
|
(1 << NF_INET_POST_ROUTING) |
|
|
|
(1 << NF_INET_LOCAL_IN),
|
|
|
},
|
|
|
+ {
|
|
|
+ .name = "cgroup",
|
|
|
+ .revision = 1,
|
|
|
+ .family = NFPROTO_UNSPEC,
|
|
|
+ .checkentry = cgroup_mt_check_v1,
|
|
|
+ .match = cgroup_mt_v1,
|
|
|
+ .matchsize = sizeof(struct xt_cgroup_info_v1),
|
|
|
+ .destroy = cgroup_mt_destroy_v1,
|
|
|
+ .me = THIS_MODULE,
|
|
|
+ .hooks = (1 << NF_INET_LOCAL_OUT) |
|
|
|
+ (1 << NF_INET_POST_ROUTING) |
|
|
|
+ (1 << NF_INET_LOCAL_IN),
|
|
|
+ },
|
|
|
};
|
|
|
|
|
|
static int __init cgroup_mt_init(void)
|