1*1b481fc3SMaciej Żenczykowski /*
2*1b481fc3SMaciej Żenczykowski * msgbuff.h - netlink message buffer
3*1b481fc3SMaciej Żenczykowski *
4*1b481fc3SMaciej Żenczykowski * Declarations of netlink message buffer and related functions.
5*1b481fc3SMaciej Żenczykowski */
6*1b481fc3SMaciej Żenczykowski
7*1b481fc3SMaciej Żenczykowski #ifndef ETHTOOL_NETLINK_MSGBUFF_H__
8*1b481fc3SMaciej Żenczykowski #define ETHTOOL_NETLINK_MSGBUFF_H__
9*1b481fc3SMaciej Żenczykowski
10*1b481fc3SMaciej Żenczykowski #include <string.h>
11*1b481fc3SMaciej Żenczykowski #include <libmnl/libmnl.h>
12*1b481fc3SMaciej Żenczykowski #include <linux/netlink.h>
13*1b481fc3SMaciej Żenczykowski #include <linux/genetlink.h>
14*1b481fc3SMaciej Żenczykowski
15*1b481fc3SMaciej Żenczykowski struct nl_context;
16*1b481fc3SMaciej Żenczykowski
17*1b481fc3SMaciej Żenczykowski /**
18*1b481fc3SMaciej Żenczykowski * struct nl_msg_buff - message buffer abstraction
19*1b481fc3SMaciej Żenczykowski * @buff: pointer to buffer
20*1b481fc3SMaciej Żenczykowski * @size: total size of allocated buffer
21*1b481fc3SMaciej Żenczykowski * @left: remaining length current message end to end of buffer
22*1b481fc3SMaciej Żenczykowski * @nlhdr: pointer to netlink header of current message
23*1b481fc3SMaciej Żenczykowski * @genlhdr: pointer to genetlink header of current message
24*1b481fc3SMaciej Żenczykowski * @payload: pointer to message payload (after genetlink header)
25*1b481fc3SMaciej Żenczykowski */
26*1b481fc3SMaciej Żenczykowski struct nl_msg_buff {
27*1b481fc3SMaciej Żenczykowski char *buff;
28*1b481fc3SMaciej Żenczykowski unsigned int size;
29*1b481fc3SMaciej Żenczykowski unsigned int left;
30*1b481fc3SMaciej Żenczykowski struct nlmsghdr *nlhdr;
31*1b481fc3SMaciej Żenczykowski struct genlmsghdr *genlhdr;
32*1b481fc3SMaciej Żenczykowski void *payload;
33*1b481fc3SMaciej Żenczykowski };
34*1b481fc3SMaciej Żenczykowski
35*1b481fc3SMaciej Żenczykowski void msgbuff_init(struct nl_msg_buff *msgbuff);
36*1b481fc3SMaciej Żenczykowski void msgbuff_done(struct nl_msg_buff *msgbuff);
37*1b481fc3SMaciej Żenczykowski int msgbuff_realloc(struct nl_msg_buff *msgbuff, unsigned int new_size);
38*1b481fc3SMaciej Żenczykowski int msgbuff_append(struct nl_msg_buff *dest, struct nl_msg_buff *src);
39*1b481fc3SMaciej Żenczykowski
40*1b481fc3SMaciej Żenczykowski int __msg_init(struct nl_msg_buff *msgbuff, int family, int cmd,
41*1b481fc3SMaciej Żenczykowski unsigned int flags, int version);
42*1b481fc3SMaciej Żenczykowski int msg_init(struct nl_context *nlctx, struct nl_msg_buff *msgbuff, int cmd,
43*1b481fc3SMaciej Żenczykowski unsigned int flags);
44*1b481fc3SMaciej Żenczykowski
45*1b481fc3SMaciej Żenczykowski bool ethnla_put(struct nl_msg_buff *msgbuff, uint16_t type, size_t len,
46*1b481fc3SMaciej Żenczykowski const void *data);
47*1b481fc3SMaciej Żenczykowski struct nlattr *ethnla_nest_start(struct nl_msg_buff *msgbuff, uint16_t type);
48*1b481fc3SMaciej Żenczykowski bool ethnla_fill_header(struct nl_msg_buff *msgbuff, uint16_t type,
49*1b481fc3SMaciej Żenczykowski const char *devname, uint32_t flags);
50*1b481fc3SMaciej Żenczykowski
51*1b481fc3SMaciej Żenczykowski /* length of current message */
msgbuff_len(const struct nl_msg_buff * msgbuff)52*1b481fc3SMaciej Żenczykowski static inline unsigned int msgbuff_len(const struct nl_msg_buff *msgbuff)
53*1b481fc3SMaciej Żenczykowski {
54*1b481fc3SMaciej Żenczykowski return msgbuff->nlhdr->nlmsg_len;
55*1b481fc3SMaciej Żenczykowski }
56*1b481fc3SMaciej Żenczykowski
57*1b481fc3SMaciej Żenczykowski /* reset message length to position returned by msgbuff_len() */
msgbuff_reset(const struct nl_msg_buff * msgbuff,unsigned int len)58*1b481fc3SMaciej Żenczykowski static inline void msgbuff_reset(const struct nl_msg_buff *msgbuff,
59*1b481fc3SMaciej Żenczykowski unsigned int len)
60*1b481fc3SMaciej Żenczykowski {
61*1b481fc3SMaciej Żenczykowski msgbuff->nlhdr->nlmsg_len = len;
62*1b481fc3SMaciej Żenczykowski }
63*1b481fc3SMaciej Żenczykowski
64*1b481fc3SMaciej Żenczykowski /* put data wrappers */
65*1b481fc3SMaciej Żenczykowski
ethnla_nest_end(struct nl_msg_buff * msgbuff,struct nlattr * nest)66*1b481fc3SMaciej Żenczykowski static inline void ethnla_nest_end(struct nl_msg_buff *msgbuff,
67*1b481fc3SMaciej Żenczykowski struct nlattr *nest)
68*1b481fc3SMaciej Żenczykowski {
69*1b481fc3SMaciej Żenczykowski mnl_attr_nest_end(msgbuff->nlhdr, nest);
70*1b481fc3SMaciej Żenczykowski }
71*1b481fc3SMaciej Żenczykowski
ethnla_nest_cancel(struct nl_msg_buff * msgbuff,struct nlattr * nest)72*1b481fc3SMaciej Żenczykowski static inline void ethnla_nest_cancel(struct nl_msg_buff *msgbuff,
73*1b481fc3SMaciej Żenczykowski struct nlattr *nest)
74*1b481fc3SMaciej Żenczykowski {
75*1b481fc3SMaciej Żenczykowski mnl_attr_nest_cancel(msgbuff->nlhdr, nest);
76*1b481fc3SMaciej Żenczykowski }
77*1b481fc3SMaciej Żenczykowski
ethnla_put_u32(struct nl_msg_buff * msgbuff,uint16_t type,uint32_t data)78*1b481fc3SMaciej Żenczykowski static inline bool ethnla_put_u32(struct nl_msg_buff *msgbuff, uint16_t type,
79*1b481fc3SMaciej Żenczykowski uint32_t data)
80*1b481fc3SMaciej Żenczykowski {
81*1b481fc3SMaciej Żenczykowski return ethnla_put(msgbuff, type, sizeof(uint32_t), &data);
82*1b481fc3SMaciej Żenczykowski }
83*1b481fc3SMaciej Żenczykowski
ethnla_put_u16(struct nl_msg_buff * msgbuff,uint16_t type,uint16_t data)84*1b481fc3SMaciej Żenczykowski static inline bool ethnla_put_u16(struct nl_msg_buff *msgbuff, uint16_t type,
85*1b481fc3SMaciej Żenczykowski uint16_t data)
86*1b481fc3SMaciej Żenczykowski {
87*1b481fc3SMaciej Żenczykowski return ethnla_put(msgbuff, type, sizeof(uint16_t), &data);
88*1b481fc3SMaciej Żenczykowski }
89*1b481fc3SMaciej Żenczykowski
ethnla_put_u8(struct nl_msg_buff * msgbuff,uint16_t type,uint8_t data)90*1b481fc3SMaciej Żenczykowski static inline bool ethnla_put_u8(struct nl_msg_buff *msgbuff, uint16_t type,
91*1b481fc3SMaciej Żenczykowski uint8_t data)
92*1b481fc3SMaciej Żenczykowski {
93*1b481fc3SMaciej Żenczykowski return ethnla_put(msgbuff, type, sizeof(uint8_t), &data);
94*1b481fc3SMaciej Żenczykowski }
95*1b481fc3SMaciej Żenczykowski
ethnla_put_flag(struct nl_msg_buff * msgbuff,uint16_t type,bool val)96*1b481fc3SMaciej Żenczykowski static inline bool ethnla_put_flag(struct nl_msg_buff *msgbuff, uint16_t type,
97*1b481fc3SMaciej Żenczykowski bool val)
98*1b481fc3SMaciej Żenczykowski {
99*1b481fc3SMaciej Żenczykowski if (val)
100*1b481fc3SMaciej Żenczykowski return ethnla_put(msgbuff, type, 0, &val);
101*1b481fc3SMaciej Żenczykowski else
102*1b481fc3SMaciej Żenczykowski return false;
103*1b481fc3SMaciej Żenczykowski }
104*1b481fc3SMaciej Żenczykowski
ethnla_put_bitfield32(struct nl_msg_buff * msgbuff,uint16_t type,uint32_t value,uint32_t selector)105*1b481fc3SMaciej Żenczykowski static inline bool ethnla_put_bitfield32(struct nl_msg_buff *msgbuff,
106*1b481fc3SMaciej Żenczykowski uint16_t type, uint32_t value,
107*1b481fc3SMaciej Żenczykowski uint32_t selector)
108*1b481fc3SMaciej Żenczykowski {
109*1b481fc3SMaciej Żenczykowski struct nla_bitfield32 val = {
110*1b481fc3SMaciej Żenczykowski .value = value,
111*1b481fc3SMaciej Żenczykowski .selector = selector,
112*1b481fc3SMaciej Żenczykowski };
113*1b481fc3SMaciej Żenczykowski
114*1b481fc3SMaciej Żenczykowski return ethnla_put(msgbuff, type, sizeof(val), &val);
115*1b481fc3SMaciej Żenczykowski }
116*1b481fc3SMaciej Żenczykowski
ethnla_put_strz(struct nl_msg_buff * msgbuff,uint16_t type,const char * data)117*1b481fc3SMaciej Żenczykowski static inline bool ethnla_put_strz(struct nl_msg_buff *msgbuff, uint16_t type,
118*1b481fc3SMaciej Żenczykowski const char *data)
119*1b481fc3SMaciej Żenczykowski {
120*1b481fc3SMaciej Żenczykowski return ethnla_put(msgbuff, type, strlen(data) + 1, data);
121*1b481fc3SMaciej Żenczykowski }
122*1b481fc3SMaciej Żenczykowski
123*1b481fc3SMaciej Żenczykowski #endif /* ETHTOOL_NETLINK_MSGBUFF_H__ */
124