libnl 3.5.0

mirred.c
1 /*
2 * lib/route/act/mirred.c mirred action
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) 2013 Cong Wang <xiyou.wangcong@gmail.com>
10 */
11
12 /**
13 * @ingroup act
14 * @defgroup act_mirred Mirror and Redirect
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/act/mirred.h>
26
27 static struct nla_policy mirred_policy[TCA_MIRRED_MAX + 1] = {
28 [TCA_MIRRED_PARMS] = { .minlen = sizeof(struct tc_mirred) },
29 };
30
31 static int mirred_msg_parser(struct rtnl_tc *tc, void *data)
32 {
33 struct rtnl_mirred *u = data;
34 struct nlattr *tb[TCA_MIRRED_MAX + 1];
35 int err;
36
37 err = tca_parse(tb, TCA_MIRRED_MAX, tc, mirred_policy);
38 if (err < 0)
39 return err;
40
41 if (!tb[TCA_MIRRED_PARMS])
42 return -NLE_MISSING_ATTR;
43
44 nla_memcpy(&u->m_parm, tb[TCA_MIRRED_PARMS], sizeof(u->m_parm));
45 return 0;
46 }
47
48 static void mirred_free_data(struct rtnl_tc *tc, void *data)
49 {
50 }
51
52 static int mirred_clone(void *_dst, void *_src)
53 {
54 struct rtnl_mirred *dst = _dst, *src = _src;
55
56 memcpy(&dst->m_parm, &src->m_parm, sizeof(src->m_parm));
57 return 0;
58 }
59
60 static void mirred_dump_line(struct rtnl_tc *tc, void *data,
61 struct nl_dump_params *p)
62 {
63 struct rtnl_mirred *u = data;
64 if (!u)
65 return;
66
67 nl_dump(p, " index %u", u->m_parm.ifindex);
68
69 if (u->m_parm.eaction == TCA_EGRESS_MIRROR)
70 nl_dump(p, " egress mirror");
71 else if (u->m_parm.eaction == TCA_EGRESS_REDIR)
72 nl_dump(p, " egress redirect");
73
74 switch(u->m_parm.action) {
75 case TC_ACT_UNSPEC:
76 nl_dump(p, " unspecified");
77 break;
78 case TC_ACT_PIPE:
79 nl_dump(p, " pipe");
80 break;
81 case TC_ACT_STOLEN:
82 nl_dump(p, " stolen");
83 break;
84 case TC_ACT_SHOT:
85 nl_dump(p, " shot");
86 break;
87 case TC_ACT_QUEUED:
88 nl_dump(p, " queued");
89 break;
90 case TC_ACT_REPEAT:
91 nl_dump(p, " repeat");
92 break;
93 }
94 }
95
96 static void mirred_dump_details(struct rtnl_tc *tc, void *data,
97 struct nl_dump_params *p)
98 {
99 }
100
101 static void mirred_dump_stats(struct rtnl_tc *tc, void *data,
102 struct nl_dump_params *p)
103 {
104 struct rtnl_mirred *u = data;
105
106 if (!u)
107 return;
108 /* TODO */
109 }
110
111
112 static int mirred_msg_fill(struct rtnl_tc *tc, void *data, struct nl_msg *msg)
113 {
114 struct rtnl_mirred *u = data;
115
116 if (!u)
117 return 0;
118
119 NLA_PUT(msg, TCA_MIRRED_PARMS, sizeof(u->m_parm), &u->m_parm);
120 return 0;
121
122 nla_put_failure:
123 return -NLE_NOMEM;
124 }
125
126 /**
127 * @name Attribute Modifications
128 * @{
129 */
130
131 int rtnl_mirred_set_action(struct rtnl_act *act, int action)
132 {
133 struct rtnl_mirred *u;
134
135 if (!(u = (struct rtnl_mirred *) rtnl_tc_data(TC_CAST(act))))
136 return -NLE_NOMEM;
137
138 if (action > TCA_INGRESS_MIRROR || action < TCA_EGRESS_REDIR)
139 return -NLE_INVAL;
140
141 switch (action) {
142 case TCA_EGRESS_MIRROR:
143 case TCA_EGRESS_REDIR:
144 u->m_parm.eaction = action;
145 break;
146 case TCA_INGRESS_REDIR:
147 case TCA_INGRESS_MIRROR:
148 default:
149 return NLE_OPNOTSUPP;
150 }
151 return 0;
152 }
153
154 int rtnl_mirred_get_action(struct rtnl_act *act)
155 {
156 struct rtnl_mirred *u;
157
158 if (!(u = (struct rtnl_mirred *) rtnl_tc_data(TC_CAST(act))))
159 return -NLE_NOMEM;
160 return u->m_parm.eaction;
161 }
162
163 int rtnl_mirred_set_ifindex(struct rtnl_act *act, uint32_t ifindex)
164 {
165 struct rtnl_mirred *u;
166
167 if (!(u = (struct rtnl_mirred *) rtnl_tc_data(TC_CAST(act))))
168 return -NLE_NOMEM;
169
170 u->m_parm.ifindex = ifindex;
171 return 0;
172 }
173
174 uint32_t rtnl_mirred_get_ifindex(struct rtnl_act *act)
175 {
176 struct rtnl_mirred *u;
177
178 if ((u = (struct rtnl_mirred *) rtnl_tc_data(TC_CAST(act))))
179 return u->m_parm.ifindex;
180 return 0;
181 }
182
183 int rtnl_mirred_set_policy(struct rtnl_act *act, int policy)
184 {
185 struct rtnl_mirred *u;
186
187 if (!(u = (struct rtnl_mirred *) rtnl_tc_data(TC_CAST(act))))
188 return -NLE_NOMEM;
189
190 if (policy > TC_ACT_REPEAT || policy < TC_ACT_OK)
191 return -NLE_INVAL;
192
193 switch (u->m_parm.eaction) {
194 case TCA_EGRESS_MIRROR:
195 case TCA_EGRESS_REDIR:
196 u->m_parm.action = policy;
197 break;
198 case TCA_INGRESS_REDIR:
199 case TCA_INGRESS_MIRROR:
200 default:
201 return NLE_OPNOTSUPP;
202 }
203 return 0;
204 }
205
206 int rtnl_mirred_get_policy(struct rtnl_act *act)
207 {
208 struct rtnl_mirred *u;
209
210 if (!(u = (struct rtnl_mirred *) rtnl_tc_data(TC_CAST(act))))
211 return -NLE_NOMEM;
212 return u->m_parm.action;
213 }
214
215 /** @} */
216
217 static struct rtnl_tc_ops mirred_ops = {
218 .to_kind = "mirred",
219 .to_type = RTNL_TC_TYPE_ACT,
220 .to_size = sizeof(struct rtnl_mirred),
221 .to_msg_parser = mirred_msg_parser,
222 .to_free_data = mirred_free_data,
223 .to_clone = mirred_clone,
224 .to_msg_fill = mirred_msg_fill,
225 .to_dump = {
226 [NL_DUMP_LINE] = mirred_dump_line,
227 [NL_DUMP_DETAILS] = mirred_dump_details,
228 [NL_DUMP_STATS] = mirred_dump_stats,
229 },
230 };
231
232 static void __init mirred_init(void)
233 {
234 rtnl_tc_register(&mirred_ops);
235 }
236
237 static void __exit mirred_exit(void)
238 {
239 rtnl_tc_unregister(&mirred_ops);
240 }
241
242 /** @} */
NL_DUMP_LINE
Dump object briefly on one line.
Definition: types.h:22
rtnl_tc_register
int rtnl_tc_register(struct rtnl_tc_ops *ops)
Register a traffic control module.
Definition: tc.c:1021
nla_policy
Attribute validation policy.
Definition: attr.h:69
NL_DUMP_DETAILS
Dump all attributes but no statistics.
Definition: types.h:23
rtnl_tc_unregister
void rtnl_tc_unregister(struct rtnl_tc_ops *ops)
Unregister a traffic control module.
Definition: tc.c:1055
nla_memcpy
int nla_memcpy(void *dest, const struct nlattr *src, int count)
Copy attribute payload to another memory area.
Definition: attr.c:354
TC_CAST
#define TC_CAST(ptr)
Macro to cast qdisc/class/classifier to tc object.
Definition: tc.h:56
NLA_PUT
#define NLA_PUT(msg, attrtype, attrlen, data)
Add unspecific attribute to netlink message.
Definition: attr.h:165
nla_policy::minlen
uint16_t minlen
Minimal length of payload required.
Definition: attr.h:74
rtnl_tc_data
void * rtnl_tc_data(struct rtnl_tc *tc)
Return pointer to private data of traffic control object.
Definition: tc.c:1082
nl_dump_params
Dumping parameters.
Definition: types.h:33
nl_dump
void nl_dump(struct nl_dump_params *params, const char *fmt,...)
Dump a formatted character string.
Definition: utils.c:962
NL_DUMP_STATS
Dump all attributes including statistics.
Definition: types.h:24