8#include <linux/ethtool.h>
10#include <netlink/netlink.h>
11#include <netlink/attr.h>
12#include <netlink/utils.h>
13#include <netlink/route/classifier.h>
14#include <netlink/route/action.h>
15#include <netlink/route/cls/flower.h>
26 uint16_t cf_vlan_ethtype;
28 uint8_t cf_src_mac[ETH_ALEN];
29 uint8_t cf_src_mac_mask[ETH_ALEN];
30 uint8_t cf_dst_mac[ETH_ALEN];
31 uint8_t cf_dst_mac_mask[ETH_ALEN];
32 in_addr_t cf_ipv4_src;
33 in_addr_t cf_ipv4_src_mask;
34 in_addr_t cf_ipv4_dst;
35 in_addr_t cf_ipv4_dst_mask;
37 uint8_t cf_ip_dscp_mask;
40#define FLOWER_ATTR_FLAGS (1 << 0)
41#define FLOWER_ATTR_ACTION (1 << 1)
42#define FLOWER_ATTR_VLAN_ID (1 << 2)
43#define FLOWER_ATTR_VLAN_PRIO (1 << 3)
44#define FLOWER_ATTR_VLAN_ETH_TYPE (1 << 4)
45#define FLOWER_ATTR_DST_MAC (1 << 5)
46#define FLOWER_ATTR_DST_MAC_MASK (1 << 6)
47#define FLOWER_ATTR_SRC_MAC (1 << 7)
48#define FLOWER_ATTR_SRC_MAC_MASK (1 << 8)
49#define FLOWER_ATTR_IP_DSCP (1 << 9)
50#define FLOWER_ATTR_IP_DSCP_MASK (1 << 10)
51#define FLOWER_ATTR_PROTO (1 << 11)
52#define FLOWER_ATTR_IPV4_SRC (1 << 12)
53#define FLOWER_ATTR_IPV4_SRC_MASK (1 << 13)
54#define FLOWER_ATTR_IPV4_DST (1 << 14)
55#define FLOWER_ATTR_IPV4_DST_MASK (1 << 15)
58#define FLOWER_DSCP_MAX 0xe0
59#define FLOWER_DSCP_MASK_MAX 0xe0
60#define FLOWER_VID_MAX 4095
61#define FLOWER_VLAN_PRIO_MAX 7
63static struct nla_policy flower_policy[TCA_FLOWER_MAX + 1] = {
65 [TCA_FLOWER_KEY_ETH_TYPE] = { .type =
NLA_U16 },
66 [TCA_FLOWER_KEY_ETH_DST] = { .maxlen = ETH_ALEN },
67 [TCA_FLOWER_KEY_ETH_DST_MASK] = { .maxlen = ETH_ALEN },
68 [TCA_FLOWER_KEY_ETH_SRC] = { .maxlen = ETH_ALEN },
69 [TCA_FLOWER_KEY_ETH_SRC_MASK] = { .maxlen = ETH_ALEN },
70 [TCA_FLOWER_KEY_VLAN_ID] = { .type =
NLA_U16 },
71 [TCA_FLOWER_KEY_VLAN_PRIO] = { .type =
NLA_U8 },
72 [TCA_FLOWER_KEY_IP_TOS] = { .type =
NLA_U8 },
73 [TCA_FLOWER_KEY_IP_TOS_MASK] = { .type =
NLA_U8 },
74 [TCA_FLOWER_KEY_VLAN_ETH_TYPE] = { .type =
NLA_U16 },
75 [TCA_FLOWER_KEY_IPV4_SRC] = { .type =
NLA_U32 },
76 [TCA_FLOWER_KEY_IPV4_SRC_MASK] = { .type =
NLA_U32 },
77 [TCA_FLOWER_KEY_IPV4_DST] = { .type =
NLA_U32 },
78 [TCA_FLOWER_KEY_IPV4_DST_MASK] = { .type =
NLA_U32 },
81static int flower_msg_parser(
struct rtnl_tc *tc,
void *data)
83 struct rtnl_flower *f = data;
84 struct nlattr *tb[TCA_FLOWER_MAX + 1];
87 err = tca_parse(tb, TCA_FLOWER_MAX, tc, flower_policy);
91 if (tb[TCA_FLOWER_FLAGS]) {
93 f->cf_mask |= FLOWER_ATTR_FLAGS;
96 if (tb[TCA_FLOWER_ACT]) {
97 err = rtnl_act_parse(&f->cf_act, tb[TCA_FLOWER_ACT]);
101 f->cf_mask |= FLOWER_ATTR_ACTION;
104 if (tb[TCA_FLOWER_KEY_ETH_TYPE]) {
105 f->cf_proto =
nla_get_u16(tb[TCA_FLOWER_KEY_ETH_TYPE]);
106 f->cf_mask |= FLOWER_ATTR_PROTO;
109 if (tb[TCA_FLOWER_KEY_VLAN_ID]) {
110 f->cf_vlan_id =
nla_get_u16(tb[TCA_FLOWER_KEY_VLAN_ID]);
111 f->cf_mask |= FLOWER_ATTR_VLAN_ID;
114 if (tb[TCA_FLOWER_KEY_VLAN_PRIO]) {
115 f->cf_vlan_prio =
nla_get_u8(tb[TCA_FLOWER_KEY_VLAN_PRIO]);
116 f->cf_mask |= FLOWER_ATTR_VLAN_PRIO;
119 if (tb[TCA_FLOWER_KEY_VLAN_ETH_TYPE]) {
120 f->cf_vlan_ethtype =
nla_get_u16(tb[TCA_FLOWER_KEY_VLAN_ETH_TYPE]);
121 f->cf_mask |= FLOWER_ATTR_VLAN_ETH_TYPE;
124 if (tb[TCA_FLOWER_KEY_ETH_DST]) {
125 nla_memcpy(f->cf_dst_mac, tb[TCA_FLOWER_KEY_ETH_DST], ETH_ALEN);
126 f->cf_mask |= FLOWER_ATTR_DST_MAC;
129 if (tb[TCA_FLOWER_KEY_ETH_DST_MASK]) {
130 nla_memcpy(f->cf_dst_mac_mask, tb[TCA_FLOWER_KEY_ETH_DST_MASK], ETH_ALEN);
131 f->cf_mask |= FLOWER_ATTR_DST_MAC_MASK;
134 if (tb[TCA_FLOWER_KEY_ETH_SRC]) {
135 nla_memcpy(f->cf_src_mac, tb[TCA_FLOWER_KEY_ETH_SRC], ETH_ALEN);
136 f->cf_mask |= FLOWER_ATTR_SRC_MAC;
139 if (tb[TCA_FLOWER_KEY_ETH_SRC_MASK]) {
140 nla_memcpy(f->cf_src_mac_mask, tb[TCA_FLOWER_KEY_ETH_SRC_MASK], ETH_ALEN);
141 f->cf_mask |= FLOWER_ATTR_SRC_MAC_MASK;
144 if (tb[TCA_FLOWER_KEY_IP_TOS]) {
145 f->cf_ip_dscp =
nla_get_u8(tb[TCA_FLOWER_KEY_IP_TOS]);
146 f->cf_mask |= FLOWER_ATTR_IP_DSCP;
149 if (tb[TCA_FLOWER_KEY_IP_TOS_MASK]) {
150 f->cf_ip_dscp_mask =
nla_get_u8(tb[TCA_FLOWER_KEY_IP_TOS_MASK]);
151 f->cf_mask |= FLOWER_ATTR_IP_DSCP_MASK;
154 if (tb[TCA_FLOWER_KEY_IPV4_SRC]) {
155 f->cf_ipv4_src =
nla_get_u32(tb[TCA_FLOWER_KEY_IPV4_SRC]);
156 f->cf_mask |= FLOWER_ATTR_IPV4_SRC;
159 if (tb[TCA_FLOWER_KEY_IPV4_SRC_MASK]) {
160 f->cf_ipv4_src_mask =
162 f->cf_mask |= FLOWER_ATTR_IPV4_SRC_MASK;
165 if (tb[TCA_FLOWER_KEY_IPV4_DST]) {
166 f->cf_ipv4_dst =
nla_get_u32(tb[TCA_FLOWER_KEY_IPV4_DST]);
167 f->cf_mask |= FLOWER_ATTR_IPV4_DST;
170 if (tb[TCA_FLOWER_KEY_IPV4_DST_MASK]) {
171 f->cf_ipv4_dst_mask =
173 f->cf_mask |= FLOWER_ATTR_IPV4_DST_MASK;
179static int flower_msg_fill(
struct rtnl_tc *tc,
void *data,
struct nl_msg *msg)
181 struct rtnl_flower *f = data;
187 if (f->cf_mask & FLOWER_ATTR_FLAGS)
190 if (f->cf_mask & FLOWER_ATTR_ACTION) {
191 err = rtnl_act_fill(msg, TCA_FLOWER_ACT, f->cf_act);
196 if (f->cf_mask & FLOWER_ATTR_PROTO)
197 NLA_PUT_U16(msg, TCA_FLOWER_KEY_ETH_TYPE, f->cf_proto);
199 if (f->cf_mask & FLOWER_ATTR_VLAN_ID)
200 NLA_PUT_U16(msg, TCA_FLOWER_KEY_VLAN_ID, f->cf_vlan_id);
202 if (f->cf_mask & FLOWER_ATTR_VLAN_PRIO)
203 NLA_PUT_U8(msg, TCA_FLOWER_KEY_VLAN_PRIO, f->cf_vlan_prio);
205 if (f->cf_mask & FLOWER_ATTR_VLAN_ETH_TYPE)
206 NLA_PUT_U16(msg, TCA_FLOWER_KEY_VLAN_ETH_TYPE, f->cf_vlan_ethtype);
208 if (f->cf_mask & FLOWER_ATTR_DST_MAC)
209 NLA_PUT(msg, TCA_FLOWER_KEY_ETH_DST, ETH_ALEN, f->cf_dst_mac);
211 if (f->cf_mask & FLOWER_ATTR_DST_MAC_MASK)
212 NLA_PUT(msg, TCA_FLOWER_KEY_ETH_DST_MASK, ETH_ALEN, f->cf_dst_mac_mask);
214 if (f->cf_mask & FLOWER_ATTR_SRC_MAC)
215 NLA_PUT(msg, TCA_FLOWER_KEY_ETH_SRC, ETH_ALEN, f->cf_src_mac);
217 if (f->cf_mask & FLOWER_ATTR_SRC_MAC_MASK)
218 NLA_PUT(msg, TCA_FLOWER_KEY_ETH_SRC_MASK, ETH_ALEN, f->cf_src_mac_mask);
220 if (f->cf_mask & FLOWER_ATTR_IP_DSCP)
221 NLA_PUT_U8(msg, TCA_FLOWER_KEY_IP_TOS, f->cf_ip_dscp);
223 if (f->cf_mask & FLOWER_ATTR_IP_DSCP_MASK)
224 NLA_PUT_U8(msg, TCA_FLOWER_KEY_IP_TOS_MASK, f->cf_ip_dscp_mask);
226 if (f->cf_mask & FLOWER_ATTR_IPV4_SRC)
227 NLA_PUT_U32(msg, TCA_FLOWER_KEY_IPV4_SRC, f->cf_ipv4_src);
229 if (f->cf_mask & FLOWER_ATTR_IPV4_SRC_MASK)
231 f->cf_ipv4_src_mask);
233 if (f->cf_mask & FLOWER_ATTR_IPV4_DST)
234 NLA_PUT_U32(msg, TCA_FLOWER_KEY_IPV4_DST, f->cf_ipv4_dst);
236 if (f->cf_mask & FLOWER_ATTR_IPV4_DST_MASK)
238 f->cf_ipv4_dst_mask);
246static void flower_free_data(
struct rtnl_tc *tc,
void *data)
248 struct rtnl_flower *f = data;
251 rtnl_act_put_all(&f->cf_act);
254static int flower_clone(
void *_dst,
void *_src)
256 struct rtnl_flower *dst = _dst, *src = _src;
259 if (!(dst->cf_act = rtnl_act_alloc()))
262 memcpy(dst->cf_act, src->cf_act,
sizeof(
struct rtnl_act));
265 nl_init_list_head(&dst->cf_act->ce_list);
267 if ( src->cf_act->c_opts
268 && !(dst->cf_act->c_opts =
nl_data_clone(src->cf_act->c_opts)))
271 if ( src->cf_act->c_xstats
272 && !(dst->cf_act->c_xstats =
nl_data_clone(src->cf_act->c_xstats)))
275 if ( src->cf_act->c_subdata
276 && !(dst->cf_act->c_subdata =
nl_data_clone(src->cf_act->c_subdata)))
279 if (dst->cf_act->c_link) {
283 dst->cf_act->a_next = NULL;
289static void flower_dump_details(
struct rtnl_tc *tc,
void *data,
292 struct rtnl_flower *f = data;
293 char addr_str[INET_ADDRSTRLEN];
294 char mask_str[INET_ADDRSTRLEN];
299 if (f->cf_mask & FLOWER_ATTR_FLAGS)
300 nl_dump(p,
" flags %u", f->cf_flags);
302 if (f->cf_mask & FLOWER_ATTR_PROTO)
303 nl_dump(p,
" protocol %u", f->cf_proto);
305 if (f->cf_mask & FLOWER_ATTR_VLAN_ID)
306 nl_dump(p,
" vlan_id %u", f->cf_vlan_id);
308 if (f->cf_mask & FLOWER_ATTR_VLAN_PRIO)
309 nl_dump(p,
" vlan_prio %u", f->cf_vlan_prio);
311 if (f->cf_mask & FLOWER_ATTR_VLAN_ETH_TYPE)
312 nl_dump(p,
" vlan_ethtype %u", f->cf_vlan_ethtype);
314 if (f->cf_mask & FLOWER_ATTR_DST_MAC)
315 nl_dump(p,
" dst_mac %02x:%02x:%02x:%02x:%02x:%02x",
316 f->cf_dst_mac[0], f->cf_dst_mac[1],
317 f->cf_dst_mac[2], f->cf_dst_mac[3],
318 f->cf_dst_mac[4], f->cf_dst_mac[5]);
320 if (f->cf_mask & FLOWER_ATTR_DST_MAC_MASK)
321 nl_dump(p,
" dst_mac_mask %02x:%02x:%02x:%02x:%02x:%02x",
322 f->cf_dst_mac_mask[0], f->cf_dst_mac_mask[1],
323 f->cf_dst_mac_mask[2], f->cf_dst_mac_mask[3],
324 f->cf_dst_mac_mask[4], f->cf_dst_mac_mask[5]);
326 if (f->cf_mask & FLOWER_ATTR_SRC_MAC)
327 nl_dump(p,
" src_mac %02x:%02x:%02x:%02x:%02x:%02x",
328 f->cf_src_mac[0], f->cf_src_mac[1],
329 f->cf_src_mac[2], f->cf_src_mac[3],
330 f->cf_src_mac[4], f->cf_src_mac[5]);
332 if (f->cf_mask & FLOWER_ATTR_SRC_MAC_MASK)
333 nl_dump(p,
" src_mac_mask %02x:%02x:%02x:%02x:%02x:%02x",
334 f->cf_src_mac_mask[0], f->cf_src_mac_mask[1],
335 f->cf_src_mac_mask[2], f->cf_src_mac_mask[3],
336 f->cf_src_mac_mask[4], f->cf_src_mac_mask[5]);
338 if (f->cf_mask & FLOWER_ATTR_IP_DSCP)
339 nl_dump(p,
" dscp %u", f->cf_ip_dscp);
341 if (f->cf_mask & FLOWER_ATTR_IP_DSCP_MASK)
342 nl_dump(p,
" dscp_mask %u", f->cf_ip_dscp_mask);
344 if (f->cf_mask & FLOWER_ATTR_IPV4_SRC) {
345 inet_ntop(AF_INET, &f->cf_ipv4_src, addr_str,
sizeof(addr_str));
346 inet_ntop(AF_INET, &f->cf_ipv4_src_mask, mask_str,
sizeof(mask_str));
347 nl_dump(p,
"IPv4 src %s mask %s\n", addr_str, mask_str);
350 if (f->cf_mask & FLOWER_ATTR_IPV4_DST) {
351 inet_ntop(AF_INET, &f->cf_ipv4_dst, addr_str,
sizeof(addr_str));
352 inet_ntop(AF_INET, &f->cf_ipv4_dst_mask, mask_str,
sizeof(mask_str));
353 nl_dump(p,
"IPv4 dst %s mask %s\n", addr_str, mask_str);
368int rtnl_flower_set_proto(
struct rtnl_cls *cls, uint16_t proto)
370 struct rtnl_flower *f;
375 f->cf_proto = htons(proto);
376 f->cf_mask |= FLOWER_ATTR_PROTO;
387int rtnl_flower_get_proto(
struct rtnl_cls *cls, uint16_t *proto)
389 struct rtnl_flower *f;
394 if (!(f->cf_mask & FLOWER_ATTR_PROTO))
395 return -NLE_MISSING_ATTR;
397 *proto = ntohs(f->cf_proto);
408int rtnl_flower_set_vlan_id(
struct rtnl_cls *cls, uint16_t vid)
410 struct rtnl_flower *f;
415 if (vid > FLOWER_VID_MAX)
419 f->cf_mask |= FLOWER_ATTR_VLAN_ID;
430int rtnl_flower_get_vlan_id(
struct rtnl_cls *cls, uint16_t *vid)
432 struct rtnl_flower *f;
437 if (!(f->cf_mask & FLOWER_ATTR_VLAN_ID))
438 return -NLE_MISSING_ATTR;
440 *vid = f->cf_vlan_id;
451int rtnl_flower_set_vlan_prio(
struct rtnl_cls *cls, uint8_t prio)
453 struct rtnl_flower *f;
458 if (prio > FLOWER_VLAN_PRIO_MAX)
461 f->cf_vlan_prio = prio;
462 f->cf_mask |= FLOWER_ATTR_VLAN_PRIO;
473int rtnl_flower_get_vlan_prio(
struct rtnl_cls *cls, uint8_t *prio)
475 struct rtnl_flower *f;
480 if (!(f->cf_mask & FLOWER_ATTR_VLAN_PRIO))
481 return -NLE_MISSING_ATTR;
483 *prio = f->cf_vlan_prio;
494int rtnl_flower_set_vlan_ethtype(
struct rtnl_cls *cls, uint16_t ethtype)
496 struct rtnl_flower *f;
501 if (!(f->cf_mask & FLOWER_ATTR_PROTO))
502 return -NLE_MISSING_ATTR;
504 if (f->cf_proto != htons(ETH_P_8021Q))
507 f->cf_vlan_ethtype = htons(ethtype);
508 f->cf_mask |= FLOWER_ATTR_VLAN_ETH_TYPE;
520int rtnl_flower_set_dst_mac(
struct rtnl_cls *cls,
unsigned char *mac,
523 struct rtnl_flower *f;
529 memcpy(f->cf_dst_mac, mac, ETH_ALEN);
530 f->cf_mask |= FLOWER_ATTR_DST_MAC;
533 memcpy(f->cf_dst_mac_mask, mask, ETH_ALEN);
534 f->cf_mask |= FLOWER_ATTR_DST_MAC_MASK;
550int rtnl_flower_get_dst_mac(
struct rtnl_cls *cls,
unsigned char *mac,
553 struct rtnl_flower *f;
558 if (!(f->cf_mask & FLOWER_ATTR_DST_MAC))
559 return -NLE_MISSING_ATTR;
562 memcpy(mac, f->cf_dst_mac, ETH_ALEN);
565 memcpy(mask, f->cf_dst_mac_mask, ETH_ALEN);
577int rtnl_flower_set_src_mac(
struct rtnl_cls *cls,
unsigned char *mac,
580 struct rtnl_flower *f;
586 memcpy(f->cf_src_mac, mac, ETH_ALEN);
587 f->cf_mask |= FLOWER_ATTR_SRC_MAC;
590 memcpy(f->cf_src_mac_mask, mask, ETH_ALEN);
591 f->cf_mask |= FLOWER_ATTR_SRC_MAC_MASK;
607int rtnl_flower_get_src_mac(
struct rtnl_cls *cls,
unsigned char *mac,
610 struct rtnl_flower *f;
615 if (!(f->cf_mask & FLOWER_ATTR_SRC_MAC))
616 return -NLE_MISSING_ATTR;
619 memcpy(mac, f->cf_src_mac, ETH_ALEN);
622 memcpy(mask, f->cf_src_mac_mask, ETH_ALEN);
634int rtnl_flower_set_ip_dscp(
struct rtnl_cls *cls, uint8_t dscp, uint8_t mask)
636 struct rtnl_flower *f;
641 if (dscp > FLOWER_DSCP_MAX)
644 if (mask > FLOWER_DSCP_MASK_MAX)
647 f->cf_ip_dscp = dscp;
648 f->cf_mask |= FLOWER_ATTR_IP_DSCP;
651 f->cf_ip_dscp_mask = mask;
652 f->cf_mask |= FLOWER_ATTR_IP_DSCP_MASK;
665int rtnl_flower_get_ip_dscp(
struct rtnl_cls *cls, uint8_t *dscp, uint8_t *mask)
667 struct rtnl_flower *f;
672 if (!(f->cf_mask & FLOWER_ATTR_IP_DSCP))
673 return -NLE_MISSING_ATTR;
675 *dscp = f->cf_ip_dscp;
676 *mask = f->cf_ip_dscp_mask;
688int rtnl_flower_set_ipv4_src(
struct rtnl_cls *cls, in_addr_t addr,
691 struct rtnl_flower *f;
697 f->cf_ipv4_src = addr;
698 f->cf_mask |= FLOWER_ATTR_IPV4_SRC;
701 f->cf_ipv4_src_mask = mask;
702 f->cf_mask |= FLOWER_ATTR_IPV4_SRC_MASK;
718int rtnl_flower_get_ipv4_src(
struct rtnl_cls *cls, in_addr_t *out_addr,
721 struct rtnl_flower *f;
726 if (!(f->cf_mask & FLOWER_ATTR_IPV4_SRC))
727 return -NLE_MISSING_ATTR;
730 *out_addr = f->cf_ipv4_src;
733 if (f->cf_mask & FLOWER_ATTR_IPV4_SRC_MASK)
734 *out_mask = f->cf_ipv4_src_mask;
736 *out_mask = 0xffffffff;
749int rtnl_flower_set_ipv4_dst(
struct rtnl_cls *cls, in_addr_t addr,
752 struct rtnl_flower *f;
758 f->cf_ipv4_dst = addr;
759 f->cf_mask |= FLOWER_ATTR_IPV4_DST;
762 f->cf_ipv4_dst_mask = mask;
763 f->cf_mask |= FLOWER_ATTR_IPV4_DST_MASK;
779int rtnl_flower_get_ipv4_dst(
struct rtnl_cls *cls, in_addr_t *out_addr,
782 struct rtnl_flower *f;
787 if (!(f->cf_mask & FLOWER_ATTR_IPV4_DST))
788 return -NLE_MISSING_ATTR;
791 *out_addr = f->cf_ipv4_dst;
794 if (f->cf_mask & FLOWER_ATTR_IPV4_DST_MASK)
795 *out_mask = f->cf_ipv4_dst_mask;
797 *out_mask = 0xffffffff;
809int rtnl_flower_append_action(
struct rtnl_cls *cls,
struct rtnl_act *act)
811 struct rtnl_flower *f;
819 f->cf_mask |= FLOWER_ATTR_ACTION;
822 return rtnl_act_append(&f->cf_act, act);
831int rtnl_flower_del_action(
struct rtnl_cls *cls,
struct rtnl_act *act)
833 struct rtnl_flower *f;
842 if (!(f->cf_mask & FLOWER_ATTR_ACTION))
845 ret = rtnl_act_remove(&f->cf_act, act);
850 f->cf_mask &= ~FLOWER_ATTR_ACTION;
861struct rtnl_act* rtnl_flower_get_action(
struct rtnl_cls *cls)
863 struct rtnl_flower *f;
868 if (!(f->cf_mask & FLOWER_ATTR_ACTION))
871 rtnl_act_get(f->cf_act);
882int rtnl_flower_set_flags(
struct rtnl_cls *cls,
int flags)
884 struct rtnl_flower *f;
890 f->cf_mask |= FLOWER_ATTR_FLAGS;
897static struct rtnl_tc_ops flower_ops = {
899 .to_type = RTNL_TC_TYPE_CLS,
900 .to_size =
sizeof(
struct rtnl_flower),
901 .to_msg_parser = flower_msg_parser,
902 .to_free_data = flower_free_data,
903 .to_clone = flower_clone,
904 .to_msg_fill = flower_msg_fill,
910static void _nl_init flower_init(
void)
915static void _nl_exit flower_exit(
void)
uint32_t nla_get_u32(const struct nlattr *nla)
Return payload of 32 bit integer attribute.
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.
#define NLA_PUT_U32(msg, attrtype, value)
Add 32 bit integer 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.
struct nl_data * nl_data_clone(const struct nl_data *src)
Clone an abstract data object.
void nl_object_get(struct nl_object *obj)
Acquire a reference on a object.
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_DETAILS
Dump all attributes but no statistics.
Attribute validation policy.
uint16_t type
Type of attribute or NLA_UNSPEC.