Tizen 2.1 base
[platform/upstream/libnl2.git] / lib / route / cls / cgroup.c
1 /*
2  * lib/route/cls/cgroup.c       Control Groups Classifier
3  *
4  *      This library is free software; you can redistribute it and/or
5  *      modify it under the terms of the GNU Lesser General Public
6  *      License as published by the Free Software Foundation version 2.1
7  *      of the License.
8  *
9  * Copyright (c) 2009 Thomas Graf <tgraf@suug.ch>
10  */
11
12 /**
13  * @ingroup cls_api
14  * @defgroup cgroup Control Groups Classifier
15  *
16  * @{
17  */
18
19 #include <netlink-local.h>
20 #include <netlink-tc.h>
21 #include <netlink/netlink.h>
22 #include <netlink/attr.h>
23 #include <netlink/utils.h>
24 #include <netlink/route/classifier.h>
25 #include <netlink/route/classifier-modules.h>
26 #include <netlink/route/cls/cgroup.h>
27 #include <netlink/route/cls/ematch.h>
28
29 /** @cond SKIP */
30 #define CGROUP_ATTR_EMATCH      0x001
31 /** @endcond */
32
33 static struct nla_policy cgroup_policy[TCA_CGROUP_MAX+1] = {
34         [TCA_CGROUP_EMATCHES]   = { .type = NLA_NESTED },
35 };
36
37 static void cgroup_free_data(struct rtnl_cls *cls)
38 {
39         struct rtnl_cgroup *cg = rtnl_cls_data(cls);
40
41         rtnl_ematch_tree_free(cg->cg_ematch);
42 }
43
44 static int cgroup_msg_parser(struct rtnl_cls *cls)
45 {
46         struct rtnl_cgroup *cg = rtnl_cls_data(cls);
47         struct nlattr *tb[TCA_CGROUP_MAX + 1];
48         int err;
49
50         err = tca_parse(tb, TCA_CGROUP_MAX, (struct rtnl_tca *) cls,
51                         cgroup_policy);
52         if (err < 0)
53                 return err;
54
55         if (tb[TCA_CGROUP_EMATCHES]) {
56                 if ((err = rtnl_ematch_parse(tb[TCA_CGROUP_EMATCHES],
57                                              &cg->cg_ematch)) < 0)
58                         return err;
59                 cg->cg_mask |= CGROUP_ATTR_EMATCH;
60         }
61
62 #if 0
63         TODO:
64         TCA_CGROUP_ACT,
65         TCA_CGROUP_POLICE,
66 #endif
67
68         return 0;
69 }
70
71 static void cgroup_dump_line(struct rtnl_cls *cls, struct nl_dump_params *p)
72 {
73         struct rtnl_cgroup *cg = rtnl_cls_data(cls);
74
75         if (cg->cg_mask & CGROUP_ATTR_EMATCH)
76                 nl_dump(p, " ematch");
77         else
78                 nl_dump(p, " match-all");
79 }
80
81 static void cgroup_dump_details(struct rtnl_cls *cls, struct nl_dump_params *p)
82 {
83         struct rtnl_cgroup *cg = rtnl_cls_data(cls);
84
85         if (cg->cg_mask & CGROUP_ATTR_EMATCH) {
86                 nl_dump(p, "\n");
87                 nl_dump_line(p, "    ematch ");
88                 rtnl_ematch_tree_dump(cg->cg_ematch, p);
89         }
90 }
91
92 /**
93  * @name Attribute Modifications
94  * @{
95  */
96
97 int rtnl_cgroup_set_ematch(struct rtnl_cls *cls, struct rtnl_ematch_tree *tree)
98 {
99         struct rtnl_cgroup *cg = rtnl_cls_data(cls);
100
101         if (cg->cg_ematch) {
102                 rtnl_ematch_tree_free(cg->cg_ematch);
103                 cg->cg_mask &= ~CGROUP_ATTR_EMATCH;
104         }
105
106         cg->cg_ematch = tree;
107
108         if (tree)
109                 cg->cg_mask |= CGROUP_ATTR_EMATCH;
110
111         return 0;
112 }
113
114 struct rtnl_ematch_tree *rtnl_cgroup_get_ematch(struct rtnl_cls *cls)
115 {
116         struct rtnl_cgroup *cg = rtnl_cls_data(cls);
117         return cg->cg_ematch;
118 }
119
120 static struct rtnl_cls_ops cgroup_ops = {
121         .co_kind                = "cgroup",
122         .co_size                = sizeof(struct rtnl_cgroup),
123         .co_msg_parser          = cgroup_msg_parser,
124         .co_free_data           = cgroup_free_data,
125         .co_dump = {
126             [NL_DUMP_LINE]      = cgroup_dump_line,
127             [NL_DUMP_DETAILS]   = cgroup_dump_details,
128         },
129 };
130
131 static void __init cgroup_init(void)
132 {
133         rtnl_cls_register(&cgroup_ops);
134 }
135
136 static void __exit cgroup_exit(void)
137 {
138         rtnl_cls_unregister(&cgroup_ops);
139 }
140
141 /** @} */