libnl: /data/src/libnl3/lib/route/cls/cgroup.c Source File

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
27 static struct nla_policy cgroup_policy[TCA_CGROUP_MAX+1] = {
28 [TCA_CGROUP_EMATCHES] = { .type = NLA_NESTED },
29 };
30
31 static 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
46 static 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
56 static 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
82 static 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
96 static 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
115 static 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
139 void 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
157 struct 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
169 static 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
183 static void __init cgroup_init(void)
184 {
185 rtnl_tc_register(&cgroup_ops);
186 }
187
188 static void __exit cgroup_exit(void)
189 {
190 rtnl_tc_unregister(&cgroup_ops);
191 }
192
193 /** @} */
NLA_NESTED
@ NLA_NESTED
Nested attributes.
Definition: attr.h:42
rtnl_ematch_tree_clone
struct rtnl_ematch_tree * rtnl_ematch_tree_clone(struct rtnl_ematch_tree *src)
Clone ematch tree object.
Definition: ematch.c:328
rtnl_ematch_tree_free
void rtnl_ematch_tree_free(struct rtnl_ematch_tree *tree)
Free ematch tree object.
Definition: ematch.c:274
rtnl_ematch_parse_attr
int rtnl_ematch_parse_attr(struct nlattr *attr, struct rtnl_ematch_tree **result)
Parse ematch netlink attributes.
Definition: ematch.c:392
rtnl_tc_data
void * rtnl_tc_data(struct rtnl_tc *tc)
Return pointer to private data of traffic control object.
Definition: tc.c:1076
TC_CAST
#define TC_CAST(ptr)
Macro to cast qdisc/class/classifier to tc object.
Definition: tc.h:50
rtnl_tc_register
int rtnl_tc_register(struct rtnl_tc_ops *ops)
Register a traffic control module.
Definition: tc.c:1015
rtnl_tc_unregister
void rtnl_tc_unregister(struct rtnl_tc_ops *ops)
Unregister a traffic control module.
Definition: tc.c:1049
nl_dump
void nl_dump(struct nl_dump_params *params, const char *fmt,...)
Dump a formatted character string.
Definition: utils.c:955
NL_DUMP_LINE
@ NL_DUMP_LINE
Dump object briefly on one line.
Definition: types.h:16
NL_DUMP_DETAILS
@ NL_DUMP_DETAILS
Dump all attributes but no statistics.
Definition: types.h:17
nl_dump_params
Dumping parameters.
Definition: types.h:28
nla_policy
Attribute validation policy.
Definition: attr.h:63
nla_policy::type
uint16_t type
Type of attribute or NLA_UNSPEC.
Definition: attr.h:65