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/vlan.h> 28 #define VLAN_F_VID (1 << 0) 29 #define VLAN_F_PROTO (1 << 1) 30 #define VLAN_F_PRIO (1 << 2) 31 #define VLAN_F_ACT (1 << 3) 32 #define VLAN_F_MODE (1 << 4) 34 static struct nla_policy vlan_policy[TCA_VLAN_MAX + 1] = {
35 [TCA_VLAN_PARMS] = { .
minlen =
sizeof(
struct tc_vlan) },
36 [TCA_VLAN_PUSH_VLAN_ID] = { .type =
NLA_U16 },
37 [TCA_VLAN_PUSH_VLAN_PROTOCOL] = { .type =
NLA_U16 },
38 [TCA_VLAN_PUSH_VLAN_PRIORITY] = { .type =
NLA_U8 },
41 static int vlan_msg_parser(
struct rtnl_tc *tc,
void *data)
43 struct rtnl_vlan *v = data;
44 struct nlattr *tb[TCA_VLAN_MAX + 1];
47 err = tca_parse(tb, TCA_VLAN_MAX, tc, vlan_policy);
52 if (!tb[TCA_VLAN_PARMS])
53 return -NLE_MISSING_ATTR;
55 nla_memcpy(&v->v_parm, tb[TCA_VLAN_PARMS],
sizeof(v->v_parm));
56 v->v_flags |= VLAN_F_ACT;
57 v->v_flags |= VLAN_F_MODE;
60 if (tb[TCA_VLAN_PUSH_VLAN_ID]) {
62 v->v_flags |= VLAN_F_VID;
65 if (tb[TCA_VLAN_PUSH_VLAN_PROTOCOL]) {
66 v->v_proto =
nla_get_u16(tb[TCA_VLAN_PUSH_VLAN_PROTOCOL]);
67 v->v_flags |= VLAN_F_PROTO;
70 if (tb[TCA_VLAN_PUSH_VLAN_PRIORITY]) {
71 v->v_prio =
nla_get_u8(tb[TCA_VLAN_PUSH_VLAN_PRIORITY]);
72 v->v_flags |= VLAN_F_PRIO;
78 static int vlan_msg_fill(
struct rtnl_tc *tc,
void *data,
struct nl_msg *msg)
80 struct rtnl_vlan *v = data;
84 if (!(v->v_flags & VLAN_F_MODE))
85 return -NLE_MISSING_ATTR;
87 NLA_PUT(msg, TCA_VLAN_PARMS,
sizeof(v->v_parm), &v->v_parm);
90 if ((v->v_parm.v_action != TCA_VLAN_ACT_POP) && !(v->v_flags & VLAN_F_VID))
91 return -NLE_MISSING_ATTR;
93 if (v->v_flags & VLAN_F_VID)
96 if (v->v_flags & VLAN_F_PROTO)
97 NLA_PUT_U16(msg, TCA_VLAN_PUSH_VLAN_PROTOCOL, v->v_proto);
99 if (v->v_flags & VLAN_F_PRIO)
100 NLA_PUT_U8(msg, TCA_VLAN_PUSH_VLAN_PRIORITY, v->v_prio);
108 static void vlan_free_data(
struct rtnl_tc *tc,
void *data)
112 static int vlan_clone(
void *_dst,
void *_src)
114 struct rtnl_vlan *dst = _dst, *src = _src;
116 memcpy(&dst->v_parm, &src->v_parm,
sizeof(src->v_parm));
120 static void vlan_dump_line(
struct rtnl_tc *tc,
void *data,
123 struct rtnl_vlan *v = data;
128 if (!(v->v_flags & VLAN_F_ACT))
131 if (TC_ACT_EXT_CMP(v->v_parm.action, TC_ACT_GOTO_CHAIN))
132 nl_dump(p,
" goto chain %u", v->v_parm.action & TC_ACT_EXT_VAL_MASK);
134 if (TC_ACT_EXT_CMP(v->v_parm.action, TC_ACT_JUMP))
135 nl_dump(p,
" jump %u", v->v_parm.action & TC_ACT_EXT_VAL_MASK);
137 switch(v->v_parm.action){
159 static void vlan_dump_details(
struct rtnl_tc *tc,
void *data,
162 struct rtnl_vlan *v = data;
167 if (v->v_flags & VLAN_F_MODE) {
168 switch (v->v_parm.v_action) {
169 case TCA_VLAN_ACT_POP:
172 case TCA_VLAN_ACT_PUSH:
175 case TCA_VLAN_ACT_MODIFY:
181 if (v->v_flags & VLAN_F_VID)
182 nl_dump(p,
" vlan id %u", v->v_vid);
184 if (v->v_flags & VLAN_F_PRIO)
185 nl_dump(p,
" priority %u", v->v_prio);
187 if (v->v_flags & VLAN_F_PROTO)
188 nl_dump(p,
" protocol %u", v->v_proto);
209 if (mode > TCA_VLAN_ACT_MODIFY)
212 v->v_parm.v_action = mode;
213 v->v_flags |= VLAN_F_MODE;
231 if (!(v->v_flags & VLAN_F_MODE))
232 return -NLE_MISSING_ATTR;
234 *out_mode = v->v_parm.v_action;
251 v->v_parm.action = action;
252 v->v_flags |= VLAN_F_ACT;
270 if (!(v->v_flags & VLAN_F_ACT))
271 return -NLE_MISSING_ATTR;
273 *out_action = v->v_parm.action;
290 v->v_proto = protocol;
291 v->v_flags |= VLAN_F_PROTO;
309 if (!(v->v_flags & VLAN_F_PROTO))
310 return -NLE_MISSING_ATTR;
312 *out_protocol = v->v_proto;
333 v->v_flags |= VLAN_F_VID;
351 if (!(v->v_flags & VLAN_F_VID))
352 return -NLE_MISSING_ATTR;
375 v->v_flags |= VLAN_F_PRIO;
393 if (!(v->v_flags & VLAN_F_PRIO))
394 return -NLE_MISSING_ATTR;
396 *out_prio = v->v_prio;
402 static struct rtnl_tc_ops vlan_ops = {
404 .to_type = RTNL_TC_TYPE_ACT,
405 .to_size =
sizeof(
struct rtnl_vlan),
406 .to_msg_parser = vlan_msg_parser,
407 .to_free_data = vlan_free_data,
408 .to_clone = vlan_clone,
409 .to_msg_fill = vlan_msg_fill,
416 static void __init vlan_init(
void)
421 static void __exit vlan_exit(
void)
Dump object briefly on one line.
int rtnl_tc_register(struct rtnl_tc_ops *ops)
Register a traffic control module.
int rtnl_vlan_get_action(struct rtnl_act *act, int *out_action)
Get general action.
int rtnl_vlan_get_protocol(struct rtnl_act *act, uint16_t *out_protocol)
Get protocol.
Attribute validation policy.
uint8_t nla_get_u8(const struct nlattr *nla)
Return value of 8 bit integer attribute.
int rtnl_vlan_set_action(struct rtnl_act *act, int action)
Set general action.
int rtnl_vlan_get_vlan_prio(struct rtnl_act *act, uint8_t *out_prio)
Get vlan prio.
#define NLA_PUT_U8(msg, attrtype, value)
Add 8 bit integer attribute to netlink message.
Dump all attributes but no statistics.
int rtnl_vlan_set_protocol(struct rtnl_act *act, uint16_t protocol)
Set protocol.
int rtnl_vlan_set_vlan_id(struct rtnl_act *act, uint16_t vid)
Set vlan id.
void rtnl_tc_unregister(struct rtnl_tc_ops *ops)
Unregister a traffic control module.
int rtnl_vlan_get_vlan_id(struct rtnl_act *act, uint16_t *out_vid)
Get vlan id.
int nla_memcpy(void *dest, const struct nlattr *src, int count)
Copy attribute payload to another memory area.
#define TC_CAST(ptr)
Macro to cast qdisc/class/classifier to tc object.
#define NLA_PUT(msg, attrtype, attrlen, data)
Add unspecific attribute to netlink message.
int rtnl_vlan_set_mode(struct rtnl_act *act, int mode)
Set vlan mode.
uint16_t minlen
Minimal length of payload required.
void * rtnl_tc_data(struct rtnl_tc *tc)
Return pointer to private data of traffic control object.
uint16_t nla_get_u16(const struct nlattr *nla)
Return payload of 16 bit integer attribute.
#define NLA_PUT_U16(msg, attrtype, value)
Add 16 bit integer attribute to netlink message.
int rtnl_vlan_set_vlan_prio(struct rtnl_act *act, uint8_t prio)
Set vlan prio.
void nl_dump(struct nl_dump_params *params, const char *fmt,...)
Dump a formatted character string.
void * rtnl_tc_data_peek(struct rtnl_tc *tc)
Returns the private data of the traffic control object.
int rtnl_vlan_get_mode(struct rtnl_act *act, int *out_mode)
Get vlan mode.