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/module.h>
  13#include <linux/slab.h>
  14#include <linux/cgroup.h>
  15#include <linux/fdtable.h>
  16#include <net/cls_cgroup.h>
  17#include <net/sock.h>
  18
  19static inline struct cgroup_cls_state *css_cls_state(struct cgroup_subsys_state *css)
  20{
  21        return css ? container_of(css, struct cgroup_cls_state, css) : NULL;
  22}
  23
  24struct cgroup_cls_state *task_cls_state(struct task_struct *p)
  25{
  26        return css_cls_state(task_css(p, net_cls_cgrp_id));
  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(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                sock->sk->sk_classid = (u32)(unsigned long)v;
  65
  66        return 0;
  67}
  68
  69static void cgrp_attach(struct cgroup_subsys_state *css,
  70                        struct cgroup_taskset *tset)
  71{
  72        struct cgroup_cls_state *cs = css_cls_state(css);
  73        void *v = (void *)(unsigned long)cs->classid;
  74        struct task_struct *p;
  75
  76        cgroup_taskset_for_each(p, tset) {
  77                task_lock(p);
  78                iterate_fd(p->files, 0, update_classid, v);
  79                task_unlock(p);
  80        }
  81}
  82
  83static u64 read_classid(struct cgroup_subsys_state *css, struct cftype *cft)
  84{
  85        return css_cls_state(css)->classid;
  86}
  87
  88static int write_classid(struct cgroup_subsys_state *css, struct cftype *cft,
  89                         u64 value)
  90{
  91        css_cls_state(css)->classid = (u32) value;
  92
  93        return 0;
  94}
  95
  96static struct cftype ss_files[] = {
  97        {
  98                .name           = "classid",
  99                .read_u64       = read_classid,
 100                .write_u64      = write_classid,
 101        },
 102        { }     /* terminate */
 103};
 104
 105struct cgroup_subsys net_cls_cgrp_subsys = {
 106        .css_alloc              = cgrp_css_alloc,
 107        .css_online             = cgrp_css_online,
 108        .css_free               = cgrp_css_free,
 109        .attach                 = cgrp_attach,
 110        .legacy_cftypes         = ss_files,
 111};
 112