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