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