libnl  3.5.0
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-2013 Thomas Graf <tgraf@suug.ch>
10  */
11 
12 /**
13  * @ingroup cls
14  * @defgroup cls_cgroup Control Groups Classifier
15  *
16  * @{
17  */
18 
19 #include <netlink-private/netlink.h>
20 #include <netlink-private/tc.h>
21 #include <netlink/netlink.h>
22 #include <netlink/attr.h>
23 #include <netlink/utils.h>
24 #include <netlink-private/route/tc-api.h>
25 #include <netlink/route/classifier.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 int cgroup_clone(void *_dst, void *_src)
38 {
39  struct rtnl_cgroup *dst = NULL, *src = _src;
40 
41  dst = calloc(1, sizeof(*dst));
42  if (!dst)
43  return -NLE_NOMEM;
44 
45  dst->cg_mask = src->cg_mask;
46  dst->cg_ematch = rtnl_ematch_tree_clone(src->cg_ematch);
47  if (!dst) {
48  free(dst);
49  return -NLE_NOMEM;
50  }
51 
52  return 0;
53 }
54 
55 static void cgroup_free_data(struct rtnl_tc *tc, void *data)
56 {
57  struct rtnl_cgroup *c = data;
58 
59  if (!c)
60  return;
61 
62  rtnl_ematch_tree_free(c->cg_ematch);
63 }
64 
65 static int cgroup_msg_parser(struct rtnl_tc *tc, void *data)
66 {
67  struct nlattr *tb[TCA_CGROUP_MAX + 1];
68  struct rtnl_cgroup *c = data;
69  int err;
70 
71  err = tca_parse(tb, TCA_CGROUP_MAX, tc, cgroup_policy);
72  if (err < 0)
73  return err;
74 
75  if (tb[TCA_CGROUP_EMATCHES]) {
76  if ((err = rtnl_ematch_parse_attr(tb[TCA_CGROUP_EMATCHES],
77  &c->cg_ematch)) < 0)
78  return err;
79  c->cg_mask |= CGROUP_ATTR_EMATCH;
80  }
81 
82 #if 0
83  TODO:
84  TCA_CGROUP_ACT,
85  TCA_CGROUP_POLICE,
86 #endif
87 
88  return 0;
89 }
90 
91 static void cgroup_dump_line(struct rtnl_tc *tc, void *data,
92  struct nl_dump_params *p)
93 {
94  struct rtnl_cgroup *c = data;
95 
96  if (!c)
97  return;
98 
99  if (c->cg_mask & CGROUP_ATTR_EMATCH)
100  nl_dump(p, " ematch");
101  else
102  nl_dump(p, " match-all");
103 }
104 
105 static void cgroup_dump_details(struct rtnl_tc *tc, void *data,
106  struct nl_dump_params *p)
107 {
108  struct rtnl_cgroup *c = data;
109 
110  if (!c)
111  return;
112 
113  if (c->cg_mask & CGROUP_ATTR_EMATCH) {
114  nl_dump_line(p, " ematch ");
115 
116  if (c->cg_ematch)
117  rtnl_ematch_tree_dump(c->cg_ematch, p);
118  else
119  nl_dump(p, "<no tree>");
120  } else
121  nl_dump(p, "no options");
122 }
123 
124 static int cgroup_fill_msg(struct rtnl_tc *tc, void *data,
125  struct nl_msg *msg)
126 {
127  struct rtnl_cgroup *c = data;
128 
129  if (!c)
130  BUG();
131 
132  if (!(tc->ce_mask & TCA_ATTR_HANDLE))
133  return -NLE_MISSING_ATTR;
134 
135  if (c->cg_mask & CGROUP_ATTR_EMATCH)
136  return rtnl_ematch_fill_attr(msg, TCA_CGROUP_EMATCHES,
137  c->cg_ematch);
138 
139  return 0;
140 }
141 
142 
143 /**
144  * @name Attribute Modifications
145  * @{
146  */
147 
148 void rtnl_cgroup_set_ematch(struct rtnl_cls *cls, struct rtnl_ematch_tree *tree)
149 {
150  struct rtnl_cgroup *c;
151 
152  if (!(c = rtnl_tc_data(TC_CAST(cls))))
153  BUG();
154 
155  if (c->cg_ematch) {
156  rtnl_ematch_tree_free(c->cg_ematch);
157  c->cg_mask &= ~CGROUP_ATTR_EMATCH;
158  }
159 
160  c->cg_ematch = tree;
161 
162  if (tree)
163  c->cg_mask |= CGROUP_ATTR_EMATCH;
164 }
165 
166 struct rtnl_ematch_tree *rtnl_cgroup_get_ematch(struct rtnl_cls *cls)
167 {
168  struct rtnl_cgroup *c;
169 
170  if (!(c = rtnl_tc_data(TC_CAST(cls))))
171  BUG();
172 
173  return c->cg_ematch;
174 }
175 
176 /** @} */
177 
178 static struct rtnl_tc_ops cgroup_ops = {
179  .to_kind = "cgroup",
180  .to_type = RTNL_TC_TYPE_CLS,
181  .to_size = sizeof(struct rtnl_cgroup),
182  .to_clone = cgroup_clone,
183  .to_msg_parser = cgroup_msg_parser,
184  .to_free_data = cgroup_free_data,
185  .to_msg_fill = cgroup_fill_msg,
186  .to_dump = {
187  [NL_DUMP_LINE] = cgroup_dump_line,
188  [NL_DUMP_DETAILS] = cgroup_dump_details,
189  },
190 };
191 
192 static void __init cgroup_init(void)
193 {
194  rtnl_tc_register(&cgroup_ops);
195 }
196 
197 static void __exit cgroup_exit(void)
198 {
199  rtnl_tc_unregister(&cgroup_ops);
200 }
201 
202 /** @} */
Dump object briefly on one line.
Definition: types.h:22
int rtnl_tc_register(struct rtnl_tc_ops *ops)
Register a traffic control module.
Definition: tc.c:1021
Attribute validation policy.
Definition: attr.h:69
struct rtnl_ematch_tree * rtnl_ematch_tree_clone(struct rtnl_ematch_tree *src)
Clone ematch tree object.
Definition: ematch.c:334
void rtnl_ematch_tree_free(struct rtnl_ematch_tree *tree)
Free ematch tree object.
Definition: ematch.c:280
Dump all attributes but no statistics.
Definition: types.h:23
void rtnl_tc_unregister(struct rtnl_tc_ops *ops)
Unregister a traffic control module.
Definition: tc.c:1055
int rtnl_ematch_parse_attr(struct nlattr *attr, struct rtnl_ematch_tree **result)
Parse ematch netlink attributes.
Definition: ematch.c:398
#define TC_CAST(ptr)
Macro to cast qdisc/class/classifier to tc object.
Definition: tc.h:56
void * rtnl_tc_data(struct rtnl_tc *tc)
Return pointer to private data of traffic control object.
Definition: tc.c:1082
Nested attributes.
Definition: attr.h:48
uint16_t type
Type of attribute or NLA_UNSPEC.
Definition: attr.h:71
Dumping parameters.
Definition: types.h:33
void nl_dump(struct nl_dump_params *params, const char *fmt,...)
Dump a formatted character string.
Definition: utils.c:962