6#include <netlink-private/netlink.h>
7#include <netlink-private/tc.h>
8#include <netlink/netlink.h>
9#include <netlink/attr.h>
10#include <netlink/utils.h>
11#include <netlink-private/route/tc-api.h>
12#include <netlink/route/classifier.h>
13#include <netlink/route/action.h>
14#include <netlink/route/cls/flower.h>
18#define FLOWER_ATTR_FLAGS (1 << 0)
19#define FLOWER_ATTR_ACTION (1 << 1)
20#define FLOWER_ATTR_VLAN_ID (1 << 2)
21#define FLOWER_ATTR_VLAN_PRIO (1 << 3)
22#define FLOWER_ATTR_VLAN_ETH_TYPE (1 << 4)
23#define FLOWER_ATTR_DST_MAC (1 << 5)
24#define FLOWER_ATTR_DST_MAC_MASK (1 << 6)
25#define FLOWER_ATTR_SRC_MAC (1 << 7)
26#define FLOWER_ATTR_SRC_MAC_MASK (1 << 8)
27#define FLOWER_ATTR_IP_DSCP (1 << 9)
28#define FLOWER_ATTR_IP_DSCP_MASK (1 << 10)
29#define FLOWER_ATTR_PROTO (1 << 11)
30#define FLOWER_ATTR_IPV4_SRC (1 << 12)
31#define FLOWER_ATTR_IPV4_SRC_MASK (1 << 13)
32#define FLOWER_ATTR_IPV4_DST (1 << 14)
33#define FLOWER_ATTR_IPV4_DST_MASK (1 << 15)
36#define FLOWER_DSCP_MAX 0xe0
37#define FLOWER_DSCP_MASK_MAX 0xe0
38#define FLOWER_VID_MAX 4095
39#define FLOWER_VLAN_PRIO_MAX 7
41static struct nla_policy flower_policy[TCA_FLOWER_MAX + 1] = {
43 [TCA_FLOWER_KEY_ETH_TYPE] = { .type =
NLA_U16 },
44 [TCA_FLOWER_KEY_ETH_DST] = { .maxlen = ETH_ALEN },
45 [TCA_FLOWER_KEY_ETH_DST_MASK] = { .maxlen = ETH_ALEN },
46 [TCA_FLOWER_KEY_ETH_SRC] = { .maxlen = ETH_ALEN },
47 [TCA_FLOWER_KEY_ETH_SRC_MASK] = { .maxlen = ETH_ALEN },
48 [TCA_FLOWER_KEY_VLAN_ID] = { .type =
NLA_U16 },
49 [TCA_FLOWER_KEY_VLAN_PRIO] = { .type =
NLA_U8 },
50 [TCA_FLOWER_KEY_IP_TOS] = { .type =
NLA_U8 },
51 [TCA_FLOWER_KEY_IP_TOS_MASK] = { .type =
NLA_U8 },
52 [TCA_FLOWER_KEY_VLAN_ETH_TYPE] = { .type =
NLA_U16 },
53 [TCA_FLOWER_KEY_IPV4_SRC] = { .type =
NLA_U32 },
54 [TCA_FLOWER_KEY_IPV4_SRC_MASK] = { .type =
NLA_U32 },
55 [TCA_FLOWER_KEY_IPV4_DST] = { .type =
NLA_U32 },
56 [TCA_FLOWER_KEY_IPV4_DST_MASK] = { .type =
NLA_U32 },
59static int flower_msg_parser(
struct rtnl_tc *tc,
void *data)
61 struct rtnl_flower *f = data;
62 struct nlattr *tb[TCA_FLOWER_MAX + 1];
65 err = tca_parse(tb, TCA_FLOWER_MAX, tc, flower_policy);
69 if (tb[TCA_FLOWER_FLAGS]) {
71 f->cf_mask |= FLOWER_ATTR_FLAGS;
74 if (tb[TCA_FLOWER_ACT]) {
75 err = rtnl_act_parse(&f->cf_act, tb[TCA_FLOWER_ACT]);
79 f->cf_mask |= FLOWER_ATTR_ACTION;
82 if (tb[TCA_FLOWER_KEY_ETH_TYPE]) {
83 f->cf_proto =
nla_get_u16(tb[TCA_FLOWER_KEY_ETH_TYPE]);
84 f->cf_mask |= FLOWER_ATTR_PROTO;
87 if (tb[TCA_FLOWER_KEY_VLAN_ID]) {
88 f->cf_vlan_id =
nla_get_u16(tb[TCA_FLOWER_KEY_VLAN_ID]);
89 f->cf_mask |= FLOWER_ATTR_VLAN_ID;
92 if (tb[TCA_FLOWER_KEY_VLAN_PRIO]) {
93 f->cf_vlan_prio =
nla_get_u8(tb[TCA_FLOWER_KEY_VLAN_PRIO]);
94 f->cf_mask |= FLOWER_ATTR_VLAN_PRIO;
97 if (tb[TCA_FLOWER_KEY_VLAN_ETH_TYPE]) {
98 f->cf_vlan_ethtype =
nla_get_u16(tb[TCA_FLOWER_KEY_VLAN_ETH_TYPE]);
99 f->cf_mask |= FLOWER_ATTR_VLAN_ETH_TYPE;
102 if (tb[TCA_FLOWER_KEY_ETH_DST]) {
103 nla_memcpy(f->cf_dst_mac, tb[TCA_FLOWER_KEY_ETH_DST], ETH_ALEN);
104 f->cf_mask |= FLOWER_ATTR_DST_MAC;
107 if (tb[TCA_FLOWER_KEY_ETH_DST_MASK]) {
108 nla_memcpy(f->cf_dst_mac_mask, tb[TCA_FLOWER_KEY_ETH_DST_MASK], ETH_ALEN);
109 f->cf_mask |= FLOWER_ATTR_DST_MAC_MASK;
112 if (tb[TCA_FLOWER_KEY_ETH_SRC]) {
113 nla_memcpy(f->cf_src_mac, tb[TCA_FLOWER_KEY_ETH_SRC], ETH_ALEN);
114 f->cf_mask |= FLOWER_ATTR_SRC_MAC;
117 if (tb[TCA_FLOWER_KEY_ETH_SRC_MASK]) {
118 nla_memcpy(f->cf_src_mac_mask, tb[TCA_FLOWER_KEY_ETH_SRC_MASK], ETH_ALEN);
119 f->cf_mask |= FLOWER_ATTR_SRC_MAC_MASK;
122 if (tb[TCA_FLOWER_KEY_IP_TOS]) {
123 f->cf_ip_dscp =
nla_get_u8(tb[TCA_FLOWER_KEY_IP_TOS]);
124 f->cf_mask |= FLOWER_ATTR_IP_DSCP;
127 if (tb[TCA_FLOWER_KEY_IP_TOS_MASK]) {
128 f->cf_ip_dscp_mask =
nla_get_u8(tb[TCA_FLOWER_KEY_IP_TOS_MASK]);
129 f->cf_mask |= FLOWER_ATTR_IP_DSCP_MASK;
132 if (tb[TCA_FLOWER_KEY_IPV4_SRC]) {
133 f->cf_ipv4_src =
nla_get_u32(tb[TCA_FLOWER_KEY_IPV4_SRC]);
134 f->cf_mask |= FLOWER_ATTR_IPV4_SRC;
137 if (tb[TCA_FLOWER_KEY_IPV4_SRC_MASK]) {
138 f->cf_ipv4_src_mask =
140 f->cf_mask |= FLOWER_ATTR_IPV4_SRC_MASK;
143 if (tb[TCA_FLOWER_KEY_IPV4_DST]) {
144 f->cf_ipv4_dst =
nla_get_u32(tb[TCA_FLOWER_KEY_IPV4_DST]);
145 f->cf_mask |= FLOWER_ATTR_IPV4_DST;
148 if (tb[TCA_FLOWER_KEY_IPV4_DST_MASK]) {
149 f->cf_ipv4_dst_mask =
151 f->cf_mask |= FLOWER_ATTR_IPV4_DST_MASK;
157static int flower_msg_fill(
struct rtnl_tc *tc,
void *data,
struct nl_msg *msg)
159 struct rtnl_flower *f = data;
165 if (f->cf_mask & FLOWER_ATTR_FLAGS)
168 if (f->cf_mask & FLOWER_ATTR_ACTION) {
169 err = rtnl_act_fill(msg, TCA_FLOWER_ACT, f->cf_act);
174 if (f->cf_mask & FLOWER_ATTR_PROTO)
175 NLA_PUT_U16(msg, TCA_FLOWER_KEY_ETH_TYPE, f->cf_proto);
177 if (f->cf_mask & FLOWER_ATTR_VLAN_ID)
178 NLA_PUT_U16(msg, TCA_FLOWER_KEY_VLAN_ID, f->cf_vlan_id);
180 if (f->cf_mask & FLOWER_ATTR_VLAN_PRIO)
181 NLA_PUT_U8(msg, TCA_FLOWER_KEY_VLAN_PRIO, f->cf_vlan_prio);
183 if (f->cf_mask & FLOWER_ATTR_VLAN_ETH_TYPE)
184 NLA_PUT_U16(msg, TCA_FLOWER_KEY_VLAN_ETH_TYPE, f->cf_vlan_ethtype);
186 if (f->cf_mask & FLOWER_ATTR_DST_MAC)
187 NLA_PUT(msg, TCA_FLOWER_KEY_ETH_DST, ETH_ALEN, f->cf_dst_mac);
189 if (f->cf_mask & FLOWER_ATTR_DST_MAC_MASK)
190 NLA_PUT(msg, TCA_FLOWER_KEY_ETH_DST_MASK, ETH_ALEN, f->cf_dst_mac_mask);
192 if (f->cf_mask & FLOWER_ATTR_SRC_MAC)
193 NLA_PUT(msg, TCA_FLOWER_KEY_ETH_SRC, ETH_ALEN, f->cf_src_mac);
195 if (f->cf_mask & FLOWER_ATTR_SRC_MAC_MASK)
196 NLA_PUT(msg, TCA_FLOWER_KEY_ETH_SRC_MASK, ETH_ALEN, f->cf_src_mac_mask);
198 if (f->cf_mask & FLOWER_ATTR_IP_DSCP)
199 NLA_PUT_U8(msg, TCA_FLOWER_KEY_IP_TOS, f->cf_ip_dscp);
201 if (f->cf_mask & FLOWER_ATTR_IP_DSCP_MASK)
202 NLA_PUT_U8(msg, TCA_FLOWER_KEY_IP_TOS_MASK, f->cf_ip_dscp_mask);
204 if (f->cf_mask & FLOWER_ATTR_IPV4_SRC)
205 NLA_PUT_U32(msg, TCA_FLOWER_KEY_IPV4_SRC, f->cf_ipv4_src);
207 if (f->cf_mask & FLOWER_ATTR_IPV4_SRC_MASK)
209 f->cf_ipv4_src_mask);
211 if (f->cf_mask & FLOWER_ATTR_IPV4_DST)
212 NLA_PUT_U32(msg, TCA_FLOWER_KEY_IPV4_DST, f->cf_ipv4_dst);
214 if (f->cf_mask & FLOWER_ATTR_IPV4_DST_MASK)
216 f->cf_ipv4_dst_mask);
224static void flower_free_data(
struct rtnl_tc *tc,
void *data)
226 struct rtnl_flower *f = data;
229 rtnl_act_put_all(&f->cf_act);
232static int flower_clone(
void *_dst,
void *_src)
234 struct rtnl_flower *dst = _dst, *src = _src;
237 if (!(dst->cf_act = rtnl_act_alloc()))
240 memcpy(dst->cf_act, src->cf_act,
sizeof(
struct rtnl_act));
243 nl_init_list_head(&dst->cf_act->ce_list);
245 if ( src->cf_act->c_opts
246 && !(dst->cf_act->c_opts =
nl_data_clone(src->cf_act->c_opts)))
249 if ( src->cf_act->c_xstats
250 && !(dst->cf_act->c_xstats =
nl_data_clone(src->cf_act->c_xstats)))
253 if ( src->cf_act->c_subdata
254 && !(dst->cf_act->c_subdata =
nl_data_clone(src->cf_act->c_subdata)))
257 if (dst->cf_act->c_link) {
261 dst->cf_act->a_next = NULL;
267static void flower_dump_details(
struct rtnl_tc *tc,
void *data,
270 struct rtnl_flower *f = data;
271 char addr_str[INET_ADDRSTRLEN];
272 char mask_str[INET_ADDRSTRLEN];
277 if (f->cf_mask & FLOWER_ATTR_FLAGS)
278 nl_dump(p,
" flags %u", f->cf_flags);
280 if (f->cf_mask & FLOWER_ATTR_PROTO)
281 nl_dump(p,
" protocol %u", f->cf_proto);
283 if (f->cf_mask & FLOWER_ATTR_VLAN_ID)
284 nl_dump(p,
" vlan_id %u", f->cf_vlan_id);
286 if (f->cf_mask & FLOWER_ATTR_VLAN_PRIO)
287 nl_dump(p,
" vlan_prio %u", f->cf_vlan_prio);
289 if (f->cf_mask & FLOWER_ATTR_VLAN_ETH_TYPE)
290 nl_dump(p,
" vlan_ethtype %u", f->cf_vlan_ethtype);
292 if (f->cf_mask & FLOWER_ATTR_DST_MAC)
293 nl_dump(p,
" dst_mac %02x:%02x:%02x:%02x:%02x:%02x",
294 f->cf_dst_mac[0], f->cf_dst_mac[1],
295 f->cf_dst_mac[2], f->cf_dst_mac[3],
296 f->cf_dst_mac[4], f->cf_dst_mac[5]);
298 if (f->cf_mask & FLOWER_ATTR_DST_MAC_MASK)
299 nl_dump(p,
" dst_mac_mask %02x:%02x:%02x:%02x:%02x:%02x",
300 f->cf_dst_mac_mask[0], f->cf_dst_mac_mask[1],
301 f->cf_dst_mac_mask[2], f->cf_dst_mac_mask[3],
302 f->cf_dst_mac_mask[4], f->cf_dst_mac_mask[5]);
304 if (f->cf_mask & FLOWER_ATTR_SRC_MAC)
305 nl_dump(p,
" src_mac %02x:%02x:%02x:%02x:%02x:%02x",
306 f->cf_src_mac[0], f->cf_src_mac[1],
307 f->cf_src_mac[2], f->cf_src_mac[3],
308 f->cf_src_mac[4], f->cf_src_mac[5]);
310 if (f->cf_mask & FLOWER_ATTR_SRC_MAC_MASK)
311 nl_dump(p,
" src_mac_mask %02x:%02x:%02x:%02x:%02x:%02x",
312 f->cf_src_mac_mask[0], f->cf_src_mac_mask[1],
313 f->cf_src_mac_mask[2], f->cf_src_mac_mask[3],
314 f->cf_src_mac_mask[4], f->cf_src_mac_mask[5]);
316 if (f->cf_mask & FLOWER_ATTR_IP_DSCP)
317 nl_dump(p,
" dscp %u", f->cf_ip_dscp);
319 if (f->cf_mask & FLOWER_ATTR_IP_DSCP_MASK)
320 nl_dump(p,
" dscp_mask %u", f->cf_ip_dscp_mask);
322 if (f->cf_mask & FLOWER_ATTR_IPV4_SRC) {
323 inet_ntop(AF_INET, &f->cf_ipv4_src, addr_str,
sizeof(addr_str));
324 inet_ntop(AF_INET, &f->cf_ipv4_src_mask, mask_str,
sizeof(mask_str));
325 nl_dump(p,
"IPv4 src %s mask %s\n", addr_str, mask_str);
328 if (f->cf_mask & FLOWER_ATTR_IPV4_DST) {
329 inet_ntop(AF_INET, &f->cf_ipv4_dst, addr_str,
sizeof(addr_str));
330 inet_ntop(AF_INET, &f->cf_ipv4_dst_mask, mask_str,
sizeof(mask_str));
331 nl_dump(p,
"IPv4 dst %s mask %s\n", addr_str, mask_str);
346int rtnl_flower_set_proto(
struct rtnl_cls *cls, uint16_t proto)
348 struct rtnl_flower *f;
353 f->cf_proto = htons(proto);
354 f->cf_mask |= FLOWER_ATTR_PROTO;
365int rtnl_flower_get_proto(
struct rtnl_cls *cls, uint16_t *proto)
367 struct rtnl_flower *f;
372 if (!(f->cf_mask & FLOWER_ATTR_PROTO))
373 return -NLE_MISSING_ATTR;
375 *proto = ntohs(f->cf_proto);
386int rtnl_flower_set_vlan_id(
struct rtnl_cls *cls, uint16_t vid)
388 struct rtnl_flower *f;
393 if (vid > FLOWER_VID_MAX)
397 f->cf_mask |= FLOWER_ATTR_VLAN_ID;
408int rtnl_flower_get_vlan_id(
struct rtnl_cls *cls, uint16_t *vid)
410 struct rtnl_flower *f;
415 if (!(f->cf_mask & FLOWER_ATTR_VLAN_ID))
416 return -NLE_MISSING_ATTR;
418 *vid = f->cf_vlan_id;
429int rtnl_flower_set_vlan_prio(
struct rtnl_cls *cls, uint8_t prio)
431 struct rtnl_flower *f;
436 if (prio > FLOWER_VLAN_PRIO_MAX)
439 f->cf_vlan_prio = prio;
440 f->cf_mask |= FLOWER_ATTR_VLAN_PRIO;
451int rtnl_flower_get_vlan_prio(
struct rtnl_cls *cls, uint8_t *prio)
453 struct rtnl_flower *f;
458 if (!(f->cf_mask & FLOWER_ATTR_VLAN_PRIO))
459 return -NLE_MISSING_ATTR;
461 *prio = f->cf_vlan_prio;
472int rtnl_flower_set_vlan_ethtype(
struct rtnl_cls *cls, uint16_t ethtype)
474 struct rtnl_flower *f;
479 if (!(f->cf_mask & FLOWER_ATTR_PROTO))
480 return -NLE_MISSING_ATTR;
482 if (f->cf_proto != htons(ETH_P_8021Q))
485 f->cf_vlan_ethtype = htons(ethtype);
486 f->cf_mask |= FLOWER_ATTR_VLAN_ETH_TYPE;
498int rtnl_flower_set_dst_mac(
struct rtnl_cls *cls,
unsigned char *mac,
501 struct rtnl_flower *f;
507 memcpy(f->cf_dst_mac, mac, ETH_ALEN);
508 f->cf_mask |= FLOWER_ATTR_DST_MAC;
511 memcpy(f->cf_dst_mac_mask, mask, ETH_ALEN);
512 f->cf_mask |= FLOWER_ATTR_DST_MAC_MASK;
528int rtnl_flower_get_dst_mac(
struct rtnl_cls *cls,
unsigned char *mac,
531 struct rtnl_flower *f;
536 if (!(f->cf_mask & FLOWER_ATTR_DST_MAC))
537 return -NLE_MISSING_ATTR;
540 memcpy(mac, f->cf_dst_mac, ETH_ALEN);
543 memcpy(mask, f->cf_dst_mac_mask, ETH_ALEN);
555int rtnl_flower_set_src_mac(
struct rtnl_cls *cls,
unsigned char *mac,
558 struct rtnl_flower *f;
564 memcpy(f->cf_src_mac, mac, ETH_ALEN);
565 f->cf_mask |= FLOWER_ATTR_SRC_MAC;
568 memcpy(f->cf_src_mac_mask, mask, ETH_ALEN);
569 f->cf_mask |= FLOWER_ATTR_SRC_MAC_MASK;
585int rtnl_flower_get_src_mac(
struct rtnl_cls *cls,
unsigned char *mac,
588 struct rtnl_flower *f;
593 if (!(f->cf_mask & FLOWER_ATTR_SRC_MAC))
594 return -NLE_MISSING_ATTR;
597 memcpy(mac, f->cf_src_mac, ETH_ALEN);
600 memcpy(mask, f->cf_src_mac_mask, ETH_ALEN);
612int rtnl_flower_set_ip_dscp(
struct rtnl_cls *cls, uint8_t dscp, uint8_t mask)
614 struct rtnl_flower *f;
619 if (dscp > FLOWER_DSCP_MAX)
622 if (mask > FLOWER_DSCP_MASK_MAX)
625 f->cf_ip_dscp = dscp;
626 f->cf_mask |= FLOWER_ATTR_IP_DSCP;
629 f->cf_ip_dscp_mask = mask;
630 f->cf_mask |= FLOWER_ATTR_IP_DSCP_MASK;
643int rtnl_flower_get_ip_dscp(
struct rtnl_cls *cls, uint8_t *dscp, uint8_t *mask)
645 struct rtnl_flower *f;
650 if (!(f->cf_mask & FLOWER_ATTR_IP_DSCP))
651 return -NLE_MISSING_ATTR;
653 *dscp = f->cf_ip_dscp;
654 *mask = f->cf_ip_dscp_mask;
666int rtnl_flower_set_ipv4_src(
struct rtnl_cls *cls, in_addr_t addr,
669 struct rtnl_flower *f;
675 f->cf_ipv4_src = addr;
676 f->cf_mask |= FLOWER_ATTR_IPV4_SRC;
679 f->cf_ipv4_src_mask = mask;
680 f->cf_mask |= FLOWER_ATTR_IPV4_SRC_MASK;
696int rtnl_flower_get_ipv4_src(
struct rtnl_cls *cls, in_addr_t *out_addr,
699 struct rtnl_flower *f;
704 if (!(f->cf_mask & FLOWER_ATTR_IPV4_SRC))
705 return -NLE_MISSING_ATTR;
708 *out_addr = f->cf_ipv4_src;
711 if (f->cf_mask & FLOWER_ATTR_IPV4_SRC_MASK)
712 *out_mask = f->cf_ipv4_src_mask;
714 *out_mask = 0xffffffff;
727int rtnl_flower_set_ipv4_dst(
struct rtnl_cls *cls, in_addr_t addr,
730 struct rtnl_flower *f;
736 f->cf_ipv4_dst = addr;
737 f->cf_mask |= FLOWER_ATTR_IPV4_DST;
740 f->cf_ipv4_dst_mask = mask;
741 f->cf_mask |= FLOWER_ATTR_IPV4_DST_MASK;
757int rtnl_flower_get_ipv4_dst(
struct rtnl_cls *cls, in_addr_t *out_addr,
760 struct rtnl_flower *f;
765 if (!(f->cf_mask & FLOWER_ATTR_IPV4_DST))
766 return -NLE_MISSING_ATTR;
769 *out_addr = f->cf_ipv4_dst;
772 if (f->cf_mask & FLOWER_ATTR_IPV4_DST_MASK)
773 *out_mask = f->cf_ipv4_dst_mask;
775 *out_mask = 0xffffffff;
787int rtnl_flower_append_action(
struct rtnl_cls *cls,
struct rtnl_act *act)
789 struct rtnl_flower *f;
797 f->cf_mask |= FLOWER_ATTR_ACTION;
800 return rtnl_act_append(&f->cf_act, act);
809int rtnl_flower_del_action(
struct rtnl_cls *cls,
struct rtnl_act *act)
811 struct rtnl_flower *f;
820 if (!(f->cf_mask & FLOWER_ATTR_ACTION))
823 ret = rtnl_act_remove(&f->cf_act, act);
828 f->cf_mask &= ~FLOWER_ATTR_ACTION;
839struct rtnl_act* rtnl_flower_get_action(
struct rtnl_cls *cls)
841 struct rtnl_flower *f;
846 if (!(f->cf_mask & FLOWER_ATTR_ACTION))
849 rtnl_act_get(f->cf_act);
860int rtnl_flower_set_flags(
struct rtnl_cls *cls,
int flags)
862 struct rtnl_flower *f;
868 f->cf_mask |= FLOWER_ATTR_FLAGS;
875static struct rtnl_tc_ops flower_ops = {
877 .to_type = RTNL_TC_TYPE_CLS,
878 .to_size =
sizeof(
struct rtnl_flower),
879 .to_msg_parser = flower_msg_parser,
880 .to_free_data = flower_free_data,
881 .to_clone = flower_clone,
882 .to_msg_fill = flower_msg_fill,
888static void __init flower_init(
void)
893static void __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 *tc)
Return pointer to private data of traffic control object.
int rtnl_tc_register(struct rtnl_tc_ops *ops)
Register a traffic control module.
void rtnl_tc_unregister(struct rtnl_tc_ops *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.