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>
18#include "nl-aux-route/nl-route.h"
27 uint16_t cf_vlan_ethtype;
29 uint8_t cf_src_mac[ETH_ALEN];
30 uint8_t cf_src_mac_mask[ETH_ALEN];
31 uint8_t cf_dst_mac[ETH_ALEN];
32 uint8_t cf_dst_mac_mask[ETH_ALEN];
33 in_addr_t cf_ipv4_src;
34 in_addr_t cf_ipv4_src_mask;
35 in_addr_t cf_ipv4_dst;
36 in_addr_t cf_ipv4_dst_mask;
38 uint8_t cf_ip_dscp_mask;
41#define FLOWER_ATTR_FLAGS (1 << 0)
42#define FLOWER_ATTR_ACTION (1 << 1)
43#define FLOWER_ATTR_VLAN_ID (1 << 2)
44#define FLOWER_ATTR_VLAN_PRIO (1 << 3)
45#define FLOWER_ATTR_VLAN_ETH_TYPE (1 << 4)
46#define FLOWER_ATTR_DST_MAC (1 << 5)
47#define FLOWER_ATTR_DST_MAC_MASK (1 << 6)
48#define FLOWER_ATTR_SRC_MAC (1 << 7)
49#define FLOWER_ATTR_SRC_MAC_MASK (1 << 8)
50#define FLOWER_ATTR_IP_DSCP (1 << 9)
51#define FLOWER_ATTR_IP_DSCP_MASK (1 << 10)
52#define FLOWER_ATTR_PROTO (1 << 11)
53#define FLOWER_ATTR_IPV4_SRC (1 << 12)
54#define FLOWER_ATTR_IPV4_SRC_MASK (1 << 13)
55#define FLOWER_ATTR_IPV4_DST (1 << 14)
56#define FLOWER_ATTR_IPV4_DST_MASK (1 << 15)
59#define FLOWER_DSCP_MAX 0xe0
60#define FLOWER_DSCP_MASK_MAX 0xe0
61#define FLOWER_VID_MAX 4095
62#define FLOWER_VLAN_PRIO_MAX 7
64static struct nla_policy flower_policy[TCA_FLOWER_MAX + 1] = {
66 [TCA_FLOWER_KEY_ETH_TYPE] = { .type =
NLA_U16 },
67 [TCA_FLOWER_KEY_ETH_DST] = { .maxlen = ETH_ALEN },
68 [TCA_FLOWER_KEY_ETH_DST_MASK] = { .maxlen = ETH_ALEN },
69 [TCA_FLOWER_KEY_ETH_SRC] = { .maxlen = ETH_ALEN },
70 [TCA_FLOWER_KEY_ETH_SRC_MASK] = { .maxlen = ETH_ALEN },
71 [TCA_FLOWER_KEY_VLAN_ID] = { .type =
NLA_U16 },
72 [TCA_FLOWER_KEY_VLAN_PRIO] = { .type =
NLA_U8 },
73 [TCA_FLOWER_KEY_IP_TOS] = { .type =
NLA_U8 },
74 [TCA_FLOWER_KEY_IP_TOS_MASK] = { .type =
NLA_U8 },
75 [TCA_FLOWER_KEY_VLAN_ETH_TYPE] = { .type =
NLA_U16 },
76 [TCA_FLOWER_KEY_IPV4_SRC] = { .type =
NLA_U32 },
77 [TCA_FLOWER_KEY_IPV4_SRC_MASK] = { .type =
NLA_U32 },
78 [TCA_FLOWER_KEY_IPV4_DST] = { .type =
NLA_U32 },
79 [TCA_FLOWER_KEY_IPV4_DST_MASK] = { .type =
NLA_U32 },
82static int flower_msg_parser(
struct rtnl_tc *tc,
void *data)
84 struct rtnl_flower *f = data;
85 struct nlattr *tb[TCA_FLOWER_MAX + 1];
88 err = tca_parse(tb, TCA_FLOWER_MAX, tc, flower_policy);
92 if (tb[TCA_FLOWER_FLAGS]) {
94 f->cf_mask |= FLOWER_ATTR_FLAGS;
97 if (tb[TCA_FLOWER_ACT]) {
98 err = rtnl_act_parse(&f->cf_act, tb[TCA_FLOWER_ACT]);
102 f->cf_mask |= FLOWER_ATTR_ACTION;
105 if (tb[TCA_FLOWER_KEY_ETH_TYPE]) {
106 f->cf_proto =
nla_get_u16(tb[TCA_FLOWER_KEY_ETH_TYPE]);
107 f->cf_mask |= FLOWER_ATTR_PROTO;
110 if (tb[TCA_FLOWER_KEY_VLAN_ID]) {
111 f->cf_vlan_id =
nla_get_u16(tb[TCA_FLOWER_KEY_VLAN_ID]);
112 f->cf_mask |= FLOWER_ATTR_VLAN_ID;
115 if (tb[TCA_FLOWER_KEY_VLAN_PRIO]) {
116 f->cf_vlan_prio =
nla_get_u8(tb[TCA_FLOWER_KEY_VLAN_PRIO]);
117 f->cf_mask |= FLOWER_ATTR_VLAN_PRIO;
120 if (tb[TCA_FLOWER_KEY_VLAN_ETH_TYPE]) {
121 f->cf_vlan_ethtype =
nla_get_u16(tb[TCA_FLOWER_KEY_VLAN_ETH_TYPE]);
122 f->cf_mask |= FLOWER_ATTR_VLAN_ETH_TYPE;
125 if (tb[TCA_FLOWER_KEY_ETH_DST]) {
126 nla_memcpy(f->cf_dst_mac, tb[TCA_FLOWER_KEY_ETH_DST], ETH_ALEN);
127 f->cf_mask |= FLOWER_ATTR_DST_MAC;
130 if (tb[TCA_FLOWER_KEY_ETH_DST_MASK]) {
131 nla_memcpy(f->cf_dst_mac_mask, tb[TCA_FLOWER_KEY_ETH_DST_MASK], ETH_ALEN);
132 f->cf_mask |= FLOWER_ATTR_DST_MAC_MASK;
135 if (tb[TCA_FLOWER_KEY_ETH_SRC]) {
136 nla_memcpy(f->cf_src_mac, tb[TCA_FLOWER_KEY_ETH_SRC], ETH_ALEN);
137 f->cf_mask |= FLOWER_ATTR_SRC_MAC;
140 if (tb[TCA_FLOWER_KEY_ETH_SRC_MASK]) {
141 nla_memcpy(f->cf_src_mac_mask, tb[TCA_FLOWER_KEY_ETH_SRC_MASK], ETH_ALEN);
142 f->cf_mask |= FLOWER_ATTR_SRC_MAC_MASK;
145 if (tb[TCA_FLOWER_KEY_IP_TOS]) {
146 f->cf_ip_dscp =
nla_get_u8(tb[TCA_FLOWER_KEY_IP_TOS]);
147 f->cf_mask |= FLOWER_ATTR_IP_DSCP;
150 if (tb[TCA_FLOWER_KEY_IP_TOS_MASK]) {
151 f->cf_ip_dscp_mask =
nla_get_u8(tb[TCA_FLOWER_KEY_IP_TOS_MASK]);
152 f->cf_mask |= FLOWER_ATTR_IP_DSCP_MASK;
155 if (tb[TCA_FLOWER_KEY_IPV4_SRC]) {
156 f->cf_ipv4_src =
nla_get_u32(tb[TCA_FLOWER_KEY_IPV4_SRC]);
157 f->cf_mask |= FLOWER_ATTR_IPV4_SRC;
160 if (tb[TCA_FLOWER_KEY_IPV4_SRC_MASK]) {
161 f->cf_ipv4_src_mask =
163 f->cf_mask |= FLOWER_ATTR_IPV4_SRC_MASK;
166 if (tb[TCA_FLOWER_KEY_IPV4_DST]) {
167 f->cf_ipv4_dst =
nla_get_u32(tb[TCA_FLOWER_KEY_IPV4_DST]);
168 f->cf_mask |= FLOWER_ATTR_IPV4_DST;
171 if (tb[TCA_FLOWER_KEY_IPV4_DST_MASK]) {
172 f->cf_ipv4_dst_mask =
174 f->cf_mask |= FLOWER_ATTR_IPV4_DST_MASK;
180static int flower_msg_fill(
struct rtnl_tc *tc,
void *data,
struct nl_msg *msg)
182 struct rtnl_flower *f = data;
188 if (f->cf_mask & FLOWER_ATTR_FLAGS)
191 if (f->cf_mask & FLOWER_ATTR_ACTION) {
192 err = rtnl_act_fill(msg, TCA_FLOWER_ACT, f->cf_act);
197 if (f->cf_mask & FLOWER_ATTR_PROTO)
198 NLA_PUT_U16(msg, TCA_FLOWER_KEY_ETH_TYPE, f->cf_proto);
200 if (f->cf_mask & FLOWER_ATTR_VLAN_ID)
201 NLA_PUT_U16(msg, TCA_FLOWER_KEY_VLAN_ID, f->cf_vlan_id);
203 if (f->cf_mask & FLOWER_ATTR_VLAN_PRIO)
204 NLA_PUT_U8(msg, TCA_FLOWER_KEY_VLAN_PRIO, f->cf_vlan_prio);
206 if (f->cf_mask & FLOWER_ATTR_VLAN_ETH_TYPE)
207 NLA_PUT_U16(msg, TCA_FLOWER_KEY_VLAN_ETH_TYPE, f->cf_vlan_ethtype);
209 if (f->cf_mask & FLOWER_ATTR_DST_MAC)
210 NLA_PUT(msg, TCA_FLOWER_KEY_ETH_DST, ETH_ALEN, f->cf_dst_mac);
212 if (f->cf_mask & FLOWER_ATTR_DST_MAC_MASK)
213 NLA_PUT(msg, TCA_FLOWER_KEY_ETH_DST_MASK, ETH_ALEN, f->cf_dst_mac_mask);
215 if (f->cf_mask & FLOWER_ATTR_SRC_MAC)
216 NLA_PUT(msg, TCA_FLOWER_KEY_ETH_SRC, ETH_ALEN, f->cf_src_mac);
218 if (f->cf_mask & FLOWER_ATTR_SRC_MAC_MASK)
219 NLA_PUT(msg, TCA_FLOWER_KEY_ETH_SRC_MASK, ETH_ALEN, f->cf_src_mac_mask);
221 if (f->cf_mask & FLOWER_ATTR_IP_DSCP)
222 NLA_PUT_U8(msg, TCA_FLOWER_KEY_IP_TOS, f->cf_ip_dscp);
224 if (f->cf_mask & FLOWER_ATTR_IP_DSCP_MASK)
225 NLA_PUT_U8(msg, TCA_FLOWER_KEY_IP_TOS_MASK, f->cf_ip_dscp_mask);
227 if (f->cf_mask & FLOWER_ATTR_IPV4_SRC)
228 NLA_PUT_U32(msg, TCA_FLOWER_KEY_IPV4_SRC, f->cf_ipv4_src);
230 if (f->cf_mask & FLOWER_ATTR_IPV4_SRC_MASK)
232 f->cf_ipv4_src_mask);
234 if (f->cf_mask & FLOWER_ATTR_IPV4_DST)
235 NLA_PUT_U32(msg, TCA_FLOWER_KEY_IPV4_DST, f->cf_ipv4_dst);
237 if (f->cf_mask & FLOWER_ATTR_IPV4_DST_MASK)
239 f->cf_ipv4_dst_mask);
247static void flower_free_data(
struct rtnl_tc *tc,
void *data)
249 struct rtnl_flower *f = data;
252 rtnl_act_put_all(&f->cf_act);
255static int flower_clone(
void *_dst,
void *_src)
257 struct rtnl_flower *dst = _dst, *src = _src;
260 if (!(dst->cf_act = rtnl_act_alloc()))
263 memcpy(dst->cf_act, src->cf_act,
sizeof(
struct rtnl_act));
266 nl_init_list_head(&dst->cf_act->ce_list);
268 if ( src->cf_act->c_opts
269 && !(dst->cf_act->c_opts =
nl_data_clone(src->cf_act->c_opts)))
272 if ( src->cf_act->c_xstats
273 && !(dst->cf_act->c_xstats =
nl_data_clone(src->cf_act->c_xstats)))
276 if ( src->cf_act->c_subdata
277 && !(dst->cf_act->c_subdata =
nl_data_clone(src->cf_act->c_subdata)))
280 if (dst->cf_act->c_link) {
284 dst->cf_act->a_next = NULL;
290static void flower_dump_details(
struct rtnl_tc *tc,
void *data,
293 struct rtnl_flower *f = data;
294 char addr_str[INET_ADDRSTRLEN];
295 char mask_str[INET_ADDRSTRLEN];
300 if (f->cf_mask & FLOWER_ATTR_FLAGS)
301 nl_dump(p,
" flags %u", f->cf_flags);
303 if (f->cf_mask & FLOWER_ATTR_PROTO)
304 nl_dump(p,
" protocol %u", f->cf_proto);
306 if (f->cf_mask & FLOWER_ATTR_VLAN_ID)
307 nl_dump(p,
" vlan_id %u", f->cf_vlan_id);
309 if (f->cf_mask & FLOWER_ATTR_VLAN_PRIO)
310 nl_dump(p,
" vlan_prio %u", f->cf_vlan_prio);
312 if (f->cf_mask & FLOWER_ATTR_VLAN_ETH_TYPE)
313 nl_dump(p,
" vlan_ethtype %u", f->cf_vlan_ethtype);
315 if (f->cf_mask & FLOWER_ATTR_DST_MAC)
316 nl_dump(p,
" dst_mac %02x:%02x:%02x:%02x:%02x:%02x",
317 f->cf_dst_mac[0], f->cf_dst_mac[1],
318 f->cf_dst_mac[2], f->cf_dst_mac[3],
319 f->cf_dst_mac[4], f->cf_dst_mac[5]);
321 if (f->cf_mask & FLOWER_ATTR_DST_MAC_MASK)
322 nl_dump(p,
" dst_mac_mask %02x:%02x:%02x:%02x:%02x:%02x",
323 f->cf_dst_mac_mask[0], f->cf_dst_mac_mask[1],
324 f->cf_dst_mac_mask[2], f->cf_dst_mac_mask[3],
325 f->cf_dst_mac_mask[4], f->cf_dst_mac_mask[5]);
327 if (f->cf_mask & FLOWER_ATTR_SRC_MAC)
328 nl_dump(p,
" src_mac %02x:%02x:%02x:%02x:%02x:%02x",
329 f->cf_src_mac[0], f->cf_src_mac[1],
330 f->cf_src_mac[2], f->cf_src_mac[3],
331 f->cf_src_mac[4], f->cf_src_mac[5]);
333 if (f->cf_mask & FLOWER_ATTR_SRC_MAC_MASK)
334 nl_dump(p,
" src_mac_mask %02x:%02x:%02x:%02x:%02x:%02x",
335 f->cf_src_mac_mask[0], f->cf_src_mac_mask[1],
336 f->cf_src_mac_mask[2], f->cf_src_mac_mask[3],
337 f->cf_src_mac_mask[4], f->cf_src_mac_mask[5]);
339 if (f->cf_mask & FLOWER_ATTR_IP_DSCP)
340 nl_dump(p,
" dscp %u", f->cf_ip_dscp);
342 if (f->cf_mask & FLOWER_ATTR_IP_DSCP_MASK)
343 nl_dump(p,
" dscp_mask %u", f->cf_ip_dscp_mask);
345 if (f->cf_mask & FLOWER_ATTR_IPV4_SRC) {
346 inet_ntop(AF_INET, &f->cf_ipv4_src, addr_str,
sizeof(addr_str));
347 inet_ntop(AF_INET, &f->cf_ipv4_src_mask, mask_str,
sizeof(mask_str));
348 nl_dump(p,
"IPv4 src %s mask %s\n", addr_str, mask_str);
351 if (f->cf_mask & FLOWER_ATTR_IPV4_DST) {
352 inet_ntop(AF_INET, &f->cf_ipv4_dst, addr_str,
sizeof(addr_str));
353 inet_ntop(AF_INET, &f->cf_ipv4_dst_mask, mask_str,
sizeof(mask_str));
354 nl_dump(p,
"IPv4 dst %s mask %s\n", addr_str, mask_str);
369int rtnl_flower_set_proto(
struct rtnl_cls *cls, uint16_t proto)
371 struct rtnl_flower *f;
376 f->cf_proto = htons(proto);
377 f->cf_mask |= FLOWER_ATTR_PROTO;
388int rtnl_flower_get_proto(
struct rtnl_cls *cls, uint16_t *proto)
390 struct rtnl_flower *f;
395 if (!(f->cf_mask & FLOWER_ATTR_PROTO))
396 return -NLE_MISSING_ATTR;
398 *proto = ntohs(f->cf_proto);
409int rtnl_flower_set_vlan_id(
struct rtnl_cls *cls, uint16_t vid)
411 struct rtnl_flower *f;
416 if (vid > FLOWER_VID_MAX)
420 f->cf_mask |= FLOWER_ATTR_VLAN_ID;
431int rtnl_flower_get_vlan_id(
struct rtnl_cls *cls, uint16_t *vid)
433 struct rtnl_flower *f;
438 if (!(f->cf_mask & FLOWER_ATTR_VLAN_ID))
439 return -NLE_MISSING_ATTR;
441 *vid = f->cf_vlan_id;
452int rtnl_flower_set_vlan_prio(
struct rtnl_cls *cls, uint8_t prio)
454 struct rtnl_flower *f;
459 if (prio > FLOWER_VLAN_PRIO_MAX)
462 f->cf_vlan_prio = prio;
463 f->cf_mask |= FLOWER_ATTR_VLAN_PRIO;
474int rtnl_flower_get_vlan_prio(
struct rtnl_cls *cls, uint8_t *prio)
476 struct rtnl_flower *f;
481 if (!(f->cf_mask & FLOWER_ATTR_VLAN_PRIO))
482 return -NLE_MISSING_ATTR;
484 *prio = f->cf_vlan_prio;
495int rtnl_flower_set_vlan_ethtype(
struct rtnl_cls *cls, uint16_t ethtype)
497 struct rtnl_flower *f;
502 if (!(f->cf_mask & FLOWER_ATTR_PROTO))
503 return -NLE_MISSING_ATTR;
505 if (f->cf_proto != htons(ETH_P_8021Q))
508 f->cf_vlan_ethtype = htons(ethtype);
509 f->cf_mask |= FLOWER_ATTR_VLAN_ETH_TYPE;
521int rtnl_flower_set_dst_mac(
struct rtnl_cls *cls,
unsigned char *mac,
524 struct rtnl_flower *f;
530 memcpy(f->cf_dst_mac, mac, ETH_ALEN);
531 f->cf_mask |= FLOWER_ATTR_DST_MAC;
534 memcpy(f->cf_dst_mac_mask, mask, ETH_ALEN);
535 f->cf_mask |= FLOWER_ATTR_DST_MAC_MASK;
551int rtnl_flower_get_dst_mac(
struct rtnl_cls *cls,
unsigned char *mac,
554 struct rtnl_flower *f;
559 if (!(f->cf_mask & FLOWER_ATTR_DST_MAC))
560 return -NLE_MISSING_ATTR;
563 memcpy(mac, f->cf_dst_mac, ETH_ALEN);
566 memcpy(mask, f->cf_dst_mac_mask, ETH_ALEN);
578int rtnl_flower_set_src_mac(
struct rtnl_cls *cls,
unsigned char *mac,
581 struct rtnl_flower *f;
587 memcpy(f->cf_src_mac, mac, ETH_ALEN);
588 f->cf_mask |= FLOWER_ATTR_SRC_MAC;
591 memcpy(f->cf_src_mac_mask, mask, ETH_ALEN);
592 f->cf_mask |= FLOWER_ATTR_SRC_MAC_MASK;
608int rtnl_flower_get_src_mac(
struct rtnl_cls *cls,
unsigned char *mac,
611 struct rtnl_flower *f;
616 if (!(f->cf_mask & FLOWER_ATTR_SRC_MAC))
617 return -NLE_MISSING_ATTR;
620 memcpy(mac, f->cf_src_mac, ETH_ALEN);
623 memcpy(mask, f->cf_src_mac_mask, ETH_ALEN);
635int rtnl_flower_set_ip_dscp(
struct rtnl_cls *cls, uint8_t dscp, uint8_t mask)
637 struct rtnl_flower *f;
642 if (dscp > FLOWER_DSCP_MAX)
645 if (mask > FLOWER_DSCP_MASK_MAX)
648 f->cf_ip_dscp = dscp;
649 f->cf_mask |= FLOWER_ATTR_IP_DSCP;
652 f->cf_ip_dscp_mask = mask;
653 f->cf_mask |= FLOWER_ATTR_IP_DSCP_MASK;
666int rtnl_flower_get_ip_dscp(
struct rtnl_cls *cls, uint8_t *dscp, uint8_t *mask)
668 struct rtnl_flower *f;
673 if (!(f->cf_mask & FLOWER_ATTR_IP_DSCP))
674 return -NLE_MISSING_ATTR;
676 *dscp = f->cf_ip_dscp;
677 *mask = f->cf_ip_dscp_mask;
689int rtnl_flower_set_ipv4_src(
struct rtnl_cls *cls, in_addr_t addr,
692 struct rtnl_flower *f;
698 f->cf_ipv4_src = addr;
699 f->cf_mask |= FLOWER_ATTR_IPV4_SRC;
702 f->cf_ipv4_src_mask = mask;
703 f->cf_mask |= FLOWER_ATTR_IPV4_SRC_MASK;
719int rtnl_flower_get_ipv4_src(
struct rtnl_cls *cls, in_addr_t *out_addr,
722 struct rtnl_flower *f;
727 if (!(f->cf_mask & FLOWER_ATTR_IPV4_SRC))
728 return -NLE_MISSING_ATTR;
731 *out_addr = f->cf_ipv4_src;
734 if (f->cf_mask & FLOWER_ATTR_IPV4_SRC_MASK)
735 *out_mask = f->cf_ipv4_src_mask;
737 *out_mask = 0xffffffff;
750int rtnl_flower_set_ipv4_dst(
struct rtnl_cls *cls, in_addr_t addr,
753 struct rtnl_flower *f;
759 f->cf_ipv4_dst = addr;
760 f->cf_mask |= FLOWER_ATTR_IPV4_DST;
763 f->cf_ipv4_dst_mask = mask;
764 f->cf_mask |= FLOWER_ATTR_IPV4_DST_MASK;
780int rtnl_flower_get_ipv4_dst(
struct rtnl_cls *cls, in_addr_t *out_addr,
783 struct rtnl_flower *f;
788 if (!(f->cf_mask & FLOWER_ATTR_IPV4_DST))
789 return -NLE_MISSING_ATTR;
792 *out_addr = f->cf_ipv4_dst;
795 if (f->cf_mask & FLOWER_ATTR_IPV4_DST_MASK)
796 *out_mask = f->cf_ipv4_dst_mask;
798 *out_mask = 0xffffffff;
810int rtnl_flower_append_action(
struct rtnl_cls *cls,
struct rtnl_act *act)
812 struct rtnl_flower *f;
821 if ((err = _rtnl_act_append_get(&f->cf_act, act)) < 0)
824 f->cf_mask |= FLOWER_ATTR_ACTION;
834int rtnl_flower_del_action(
struct rtnl_cls *cls,
struct rtnl_act *act)
836 struct rtnl_flower *f;
845 if (!(f->cf_mask & FLOWER_ATTR_ACTION))
848 ret = rtnl_act_remove(&f->cf_act, act);
853 f->cf_mask &= ~FLOWER_ATTR_ACTION;
864struct rtnl_act* rtnl_flower_get_action(
struct rtnl_cls *cls)
866 struct rtnl_flower *f;
871 if (!(f->cf_mask & FLOWER_ATTR_ACTION))
874 rtnl_act_get(f->cf_act);
885int rtnl_flower_set_flags(
struct rtnl_cls *cls,
int flags)
887 struct rtnl_flower *f;
893 f->cf_mask |= FLOWER_ATTR_FLAGS;
900static struct rtnl_tc_ops flower_ops = {
902 .to_type = RTNL_TC_TYPE_CLS,
903 .to_size =
sizeof(
struct rtnl_flower),
904 .to_msg_parser = flower_msg_parser,
905 .to_free_data = flower_free_data,
906 .to_clone = flower_clone,
907 .to_msg_fill = flower_msg_fill,
913static void _nl_init flower_init(
void)
918static 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.