linux/net/core/netclassid_cgroup.c
<<
>>
Prefs
   1/*
   2 * net/core/netclassid_cgroup.c Classid Cgroupfs Handling
   3 *
   4 *              This program is free software; you can redistribute it and/or
   5 *              modify it under the terms of the GNU General Public License
   6 *              as published by the Free Software Foundation; either version
   7 *              2 of the License, or (at your option) any later version.
   8 *
   9 * Authors:     Thomas Graf <tgraf@suug.ch>
  10 */
  11
  12#include <linux/slab.h>
  13#include <linux/cgroup.h>
  14#include <linux/fdtable.h>
  15#include <net/cls_cgroup.h>
  16#include <net/sock.h>
  17
  18static inline struct cgroup_cls_state *css_cls_state(struct cgroup_subsys_state *css)
  19{
  20        return css ? container_of(css, struct cgroup_cls_state, css) : NULL;
  21}
  22
  23struct cgroup_cls_state *task_cls_state(struct task_struct *p)
  24{
  25        return css_cls_state(task_css_check(p, net_cls_cgrp_id,
  26                                            rcu_read_lock_bh_held()));
  27}
  28EXPORT_SYMBOL_GPL(task_cls_state);
  29
  30static struct cgroup_subsys_state *
  31cgrp_css_alloc(struct cgroup_subsys_state *parent_css)
  32{
  33        struct cgroup_cls_state *cs;
  34
  35        cs = kzalloc(sizeof(*cs), GFP_KERNEL);
  36        if (!cs)
  37                return ERR_PTR(-ENOMEM);
  38
  39        return &cs->css;
  40}
  41
  42static int cgrp_css_online(struct cgroup_subsys_state *css)
  43{
  44        struct cgroup_cls_state *cs = css_cls_state(css);
  45        struct cgroup_cls_state *parent = css_cls_state(css->parent);
  46
  47        if (parent)
  48                cs->classid = parent->classid;
  49
  50        return 0;
  51}
  52
  53static void cgrp_css_free(struct cgroup_subsys_state *css)
  54{
  55        kfree(css_cls_state(css));
  56}
  57
  58static int update_classid_sock(const void *v, struct file *file, unsigned n)
  59{
  60        int err;
  61        struct socket *sock = sock_from_file(file, &err);
  62
  63        if (sock) {
  64                spin_lock(&cgroup_sk_update_lock);
  65                sock_cgroup_set_classid(&sock->sk->sk_cgrp_data,
  66                                        (unsigned long)v);
  67                spin_unlock(&cgroup_sk_update_lock);
  68        }
  69        return 0;
  70}
  71
  72static void update_classid(struct cgroup_subsys_state *css, void *v)
  73{
  74        struct css_task_iter it;
  75        struct task_struct *p;
  76
  77        css_task_iter_start(css, &it);
  78        while ((p = css_task_iter_next(&it))) {
  79                task_lock(p);
  80                iterate_fd(p->files, 0, update_classid_sock, v);
  81                task_unlock(p);
  82        }
  83        css_task_iter_end(&it);
  84}
  85
  86static void cgrp_attach(struct cgroup_taskset *tset)
  87{
  88        struct cgroup_subsys_state *css;
  89
  90        cgroup_taskset_first(tset, &css);
  91        update_classid(css,
  92                       (void *)(unsigned long)css_cls_state(css)->classid);
  93}
  94
  95static u64 read_classid(struct cgroup_subsys_state *css, struct cftype *cft)
  96{
  97        return css_cls_state(css)->classid;
  98}
  99
 100static int write_classid(struct cgroup_subsys_state *css, struct cftype *cft,
 101                         u64 value)
 102{
 103        struct cgroup_cls_state *cs = css_cls_state(css);
 104
 105        cgroup_sk_alloc_disable();
 106
 107        cs->classid = (u32)value;
 108
 109        update_classid(css, (void *)(unsigned long)cs->classid);
 110        return 0;
 111}
 112
 113static struct cftype ss_files[] = {
 114        {
 115                .name           = "classid",
 116                .read_u64       = read_classid,
 117                .write_u64      = write_classid,
 118        },
 119        { }     /* terminate */
 120};
 121
 122struct cgroup_subsys net_cls_cgrp_subsys = {
 123        .css_alloc              = cgrp_css_alloc,
 124        .css_online             = cgrp_css_online,
 125        .css_free               = cgrp_css_free,
 126        .attach                 = cgrp_attach,
 127        .legacy_cftypes         = ss_files,
 128};
 129