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