|
@@ -11,109 +11,13 @@
|
|
|
|
|
|
#include <linux/module.h>
|
|
|
#include <linux/slab.h>
|
|
|
-#include <linux/types.h>
|
|
|
-#include <linux/string.h>
|
|
|
-#include <linux/errno.h>
|
|
|
#include <linux/skbuff.h>
|
|
|
-#include <linux/cgroup.h>
|
|
|
#include <linux/rcupdate.h>
|
|
|
-#include <linux/fdtable.h>
|
|
|
#include <net/rtnetlink.h>
|
|
|
#include <net/pkt_cls.h>
|
|
|
#include <net/sock.h>
|
|
|
#include <net/cls_cgroup.h>
|
|
|
|
|
|
-static inline struct cgroup_cls_state *css_cls_state(struct cgroup_subsys_state *css)
|
|
|
-{
|
|
|
- return css ? container_of(css, struct cgroup_cls_state, css) : NULL;
|
|
|
-}
|
|
|
-
|
|
|
-static inline struct cgroup_cls_state *task_cls_state(struct task_struct *p)
|
|
|
-{
|
|
|
- return css_cls_state(task_css(p, net_cls_subsys_id));
|
|
|
-}
|
|
|
-
|
|
|
-static struct cgroup_subsys_state *
|
|
|
-cgrp_css_alloc(struct cgroup_subsys_state *parent_css)
|
|
|
-{
|
|
|
- struct cgroup_cls_state *cs;
|
|
|
-
|
|
|
- cs = kzalloc(sizeof(*cs), GFP_KERNEL);
|
|
|
- if (!cs)
|
|
|
- return ERR_PTR(-ENOMEM);
|
|
|
- return &cs->css;
|
|
|
-}
|
|
|
-
|
|
|
-static int cgrp_css_online(struct cgroup_subsys_state *css)
|
|
|
-{
|
|
|
- struct cgroup_cls_state *cs = css_cls_state(css);
|
|
|
- struct cgroup_cls_state *parent = css_cls_state(css_parent(css));
|
|
|
-
|
|
|
- if (parent)
|
|
|
- cs->classid = parent->classid;
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-static void cgrp_css_free(struct cgroup_subsys_state *css)
|
|
|
-{
|
|
|
- kfree(css_cls_state(css));
|
|
|
-}
|
|
|
-
|
|
|
-static int update_classid(const void *v, struct file *file, unsigned n)
|
|
|
-{
|
|
|
- int err;
|
|
|
- struct socket *sock = sock_from_file(file, &err);
|
|
|
- if (sock)
|
|
|
- sock->sk->sk_classid = (u32)(unsigned long)v;
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-static void cgrp_attach(struct cgroup_subsys_state *css,
|
|
|
- struct cgroup_taskset *tset)
|
|
|
-{
|
|
|
- struct task_struct *p;
|
|
|
- struct cgroup_cls_state *cs = css_cls_state(css);
|
|
|
- void *v = (void *)(unsigned long)cs->classid;
|
|
|
-
|
|
|
- cgroup_taskset_for_each(p, css, tset) {
|
|
|
- task_lock(p);
|
|
|
- iterate_fd(p->files, 0, update_classid, v);
|
|
|
- task_unlock(p);
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-static u64 read_classid(struct cgroup_subsys_state *css, struct cftype *cft)
|
|
|
-{
|
|
|
- return css_cls_state(css)->classid;
|
|
|
-}
|
|
|
-
|
|
|
-static int write_classid(struct cgroup_subsys_state *css, struct cftype *cft,
|
|
|
- u64 value)
|
|
|
-{
|
|
|
- css_cls_state(css)->classid = (u32) value;
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-static struct cftype ss_files[] = {
|
|
|
- {
|
|
|
- .name = "classid",
|
|
|
- .read_u64 = read_classid,
|
|
|
- .write_u64 = write_classid,
|
|
|
- },
|
|
|
- { } /* terminate */
|
|
|
-};
|
|
|
-
|
|
|
-struct cgroup_subsys net_cls_subsys = {
|
|
|
- .name = "net_cls",
|
|
|
- .css_alloc = cgrp_css_alloc,
|
|
|
- .css_online = cgrp_css_online,
|
|
|
- .css_free = cgrp_css_free,
|
|
|
- .attach = cgrp_attach,
|
|
|
- .subsys_id = net_cls_subsys_id,
|
|
|
- .base_cftypes = ss_files,
|
|
|
- .module = THIS_MODULE,
|
|
|
-};
|
|
|
-
|
|
|
struct cls_cgroup_head {
|
|
|
u32 handle;
|
|
|
struct tcf_exts exts;
|
|
@@ -305,25 +209,12 @@ static struct tcf_proto_ops cls_cgroup_ops __read_mostly = {
|
|
|
|
|
|
static int __init init_cgroup_cls(void)
|
|
|
{
|
|
|
- int ret;
|
|
|
-
|
|
|
- ret = cgroup_load_subsys(&net_cls_subsys);
|
|
|
- if (ret)
|
|
|
- goto out;
|
|
|
-
|
|
|
- ret = register_tcf_proto_ops(&cls_cgroup_ops);
|
|
|
- if (ret)
|
|
|
- cgroup_unload_subsys(&net_cls_subsys);
|
|
|
-
|
|
|
-out:
|
|
|
- return ret;
|
|
|
+ return register_tcf_proto_ops(&cls_cgroup_ops);
|
|
|
}
|
|
|
|
|
|
static void __exit exit_cgroup_cls(void)
|
|
|
{
|
|
|
unregister_tcf_proto_ops(&cls_cgroup_ops);
|
|
|
-
|
|
|
- cgroup_unload_subsys(&net_cls_subsys);
|
|
|
}
|
|
|
|
|
|
module_init(init_cgroup_cls);
|