13#include "nl-default.h"
15#include <linux/tc_act/tc_vlan.h>
17#include <netlink/netlink.h>
18#include <netlink/attr.h>
19#include <netlink/utils.h>
20#include <netlink/route/act/vlan.h>
26 struct tc_vlan v_parm;
33#define VLAN_F_VID (1 << 0)
34#define VLAN_F_PROTO (1 << 1)
35#define VLAN_F_PRIO (1 << 2)
36#define VLAN_F_ACT (1 << 3)
37#define VLAN_F_MODE (1 << 4)
41 [TCA_VLAN_PUSH_VLAN_ID] = { .type =
NLA_U16 },
42 [TCA_VLAN_PUSH_VLAN_PROTOCOL] = { .type =
NLA_U16 },
43 [TCA_VLAN_PUSH_VLAN_PRIORITY] = { .type =
NLA_U8 },
46static int vlan_msg_parser(
struct rtnl_tc *tc,
void *data)
49 struct nlattr *tb[TCA_VLAN_MAX + 1];
52 err = tca_parse(tb, TCA_VLAN_MAX, tc, vlan_policy);
57 if (!tb[TCA_VLAN_PARMS])
58 return -NLE_MISSING_ATTR;
60 nla_memcpy(&v->v_parm, tb[TCA_VLAN_PARMS],
sizeof(v->v_parm));
61 v->v_flags |= VLAN_F_ACT;
62 v->v_flags |= VLAN_F_MODE;
65 if (tb[TCA_VLAN_PUSH_VLAN_ID]) {
67 v->v_flags |= VLAN_F_VID;
70 if (tb[TCA_VLAN_PUSH_VLAN_PROTOCOL]) {
71 v->v_proto =
nla_get_u16(tb[TCA_VLAN_PUSH_VLAN_PROTOCOL]);
72 v->v_flags |= VLAN_F_PROTO;
75 if (tb[TCA_VLAN_PUSH_VLAN_PRIORITY]) {
76 v->v_prio =
nla_get_u8(tb[TCA_VLAN_PUSH_VLAN_PRIORITY]);
77 v->v_flags |= VLAN_F_PRIO;
83static int vlan_msg_fill(
struct rtnl_tc *tc,
void *data,
struct nl_msg *msg)
89 if (!(v->v_flags & VLAN_F_MODE))
90 return -NLE_MISSING_ATTR;
92 NLA_PUT(msg, TCA_VLAN_PARMS,
sizeof(v->v_parm), &v->v_parm);
95 if ((v->v_parm.v_action != TCA_VLAN_ACT_POP) && !(v->v_flags & VLAN_F_VID))
96 return -NLE_MISSING_ATTR;
98 if (v->v_flags & VLAN_F_VID)
101 if (v->v_flags & VLAN_F_PROTO)
102 NLA_PUT_U16(msg, TCA_VLAN_PUSH_VLAN_PROTOCOL, v->v_proto);
104 if (v->v_flags & VLAN_F_PRIO)
105 NLA_PUT_U8(msg, TCA_VLAN_PUSH_VLAN_PRIORITY, v->v_prio);
113static void vlan_free_data(
struct rtnl_tc *tc,
void *data)
117static void vlan_dump_line(
struct rtnl_tc *tc,
void *data,
125 if (!(v->v_flags & VLAN_F_ACT))
128 if (TC_ACT_EXT_CMP(v->v_parm.action, TC_ACT_GOTO_CHAIN))
129 nl_dump(p,
" goto chain %u", v->v_parm.action & TC_ACT_EXT_VAL_MASK);
131 if (TC_ACT_EXT_CMP(v->v_parm.action, TC_ACT_JUMP))
132 nl_dump(p,
" jump %u", v->v_parm.action & TC_ACT_EXT_VAL_MASK);
134 switch(v->v_parm.action){
156static void vlan_dump_details(
struct rtnl_tc *tc,
void *data,
164 if (v->v_flags & VLAN_F_MODE) {
165 switch (v->v_parm.v_action) {
166 case TCA_VLAN_ACT_POP:
169 case TCA_VLAN_ACT_PUSH:
172 case TCA_VLAN_ACT_MODIFY:
178 if (v->v_flags & VLAN_F_VID)
179 nl_dump(p,
" vlan id %u", v->v_vid);
181 if (v->v_flags & VLAN_F_PRIO)
182 nl_dump(p,
" priority %u", v->v_prio);
184 if (v->v_flags & VLAN_F_PROTO)
185 nl_dump(p,
" protocol %u", v->v_proto);
206 if (mode > TCA_VLAN_ACT_MODIFY)
209 v->v_parm.v_action = mode;
210 v->v_flags |= VLAN_F_MODE;
228 if (!(v->v_flags & VLAN_F_MODE))
229 return -NLE_MISSING_ATTR;
231 *out_mode = v->v_parm.v_action;
248 v->v_parm.action = action;
249 v->v_flags |= VLAN_F_ACT;
267 if (!(v->v_flags & VLAN_F_ACT))
268 return -NLE_MISSING_ATTR;
270 *out_action = v->v_parm.action;
287 v->v_proto = protocol;
288 v->v_flags |= VLAN_F_PROTO;
306 if (!(v->v_flags & VLAN_F_PROTO))
307 return -NLE_MISSING_ATTR;
309 *out_protocol = v->v_proto;
330 v->v_flags |= VLAN_F_VID;
348 if (!(v->v_flags & VLAN_F_VID))
349 return -NLE_MISSING_ATTR;
372 v->v_flags |= VLAN_F_PRIO;
390 if (!(v->v_flags & VLAN_F_PRIO))
391 return -NLE_MISSING_ATTR;
393 *out_prio = v->v_prio;
399static struct rtnl_tc_ops vlan_ops = {
401 .to_type = RTNL_TC_TYPE_ACT,
403 .to_msg_parser = vlan_msg_parser,
404 .to_free_data = vlan_free_data,
406 .to_msg_fill = vlan_msg_fill,
413static void _nl_init vlan_init(
void)
418static void _nl_exit vlan_exit(
void)
int rtnl_vlan_get_vlan_prio(struct rtnl_act *act, uint8_t *out_prio)
Get vlan prio.
int rtnl_vlan_set_mode(struct rtnl_act *act, int mode)
Set vlan mode.
int rtnl_vlan_set_protocol(struct rtnl_act *act, uint16_t protocol)
Set protocol.
int rtnl_vlan_set_vlan_prio(struct rtnl_act *act, uint8_t prio)
Set vlan prio.
int rtnl_vlan_set_action(struct rtnl_act *act, int action)
Set general action.
int rtnl_vlan_set_vlan_id(struct rtnl_act *act, uint16_t vid)
Set vlan id.
int rtnl_vlan_get_protocol(struct rtnl_act *act, uint16_t *out_protocol)
Get protocol.
int rtnl_vlan_get_vlan_id(struct rtnl_act *act, uint16_t *out_vid)
Get vlan id.
int rtnl_vlan_get_mode(struct rtnl_act *act, int *out_mode)
Get vlan mode.
int rtnl_vlan_get_action(struct rtnl_act *act, int *out_action)
Get general action.
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.
#define NLA_PUT_U8(msg, attrtype, value)
Add 8 bit integer attribute to netlink message.
#define NLA_PUT(msg, attrtype, attrlen, data)
Add unspecific attribute to netlink message.
uint8_t nla_get_u8(const struct nlattr *nla)
Return value of 8 bit integer attribute.
int nla_memcpy(void *dest, const struct nlattr *src, int count)
Copy attribute payload to another memory area.
void * rtnl_tc_data_peek(struct rtnl_tc *tc)
Returns the private data of the traffic control object.
#define TC_CAST(ptr)
Macro to cast qdisc/class/classifier to tc object.
void * rtnl_tc_data(struct rtnl_tc *)
Return pointer to private data of traffic control object.
int rtnl_tc_register(struct rtnl_tc_ops *)
Register a traffic control module.
void rtnl_tc_unregister(struct rtnl_tc_ops *)
Unregister a traffic control module.
void nl_dump(struct nl_dump_params *params, const char *fmt,...)
Dump a formatted character string.
@ NL_DUMP_LINE
Dump object briefly on one line.
@ NL_DUMP_DETAILS
Dump all attributes but no statistics.
Attribute validation policy.
uint16_t minlen
Minimal length of payload required.
uint16_t type
Type of attribute or NLA_UNSPEC.