xref: /aosp_15_r20/external/ethtool/netlink/msgbuff.h (revision 1b481fc3bb1b45d4cf28d1ec12969dc1055f555d)
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 
51 /* length of current message */
msgbuff_len(const struct nl_msg_buff * msgbuff)52 static inline unsigned int msgbuff_len(const struct nl_msg_buff *msgbuff)
53 {
54 	return msgbuff->nlhdr->nlmsg_len;
55 }
56 
57 /* reset message length to position returned by msgbuff_len() */
msgbuff_reset(const struct nl_msg_buff * msgbuff,unsigned int len)58 static inline void msgbuff_reset(const struct nl_msg_buff *msgbuff,
59 				 unsigned int len)
60 {
61 	msgbuff->nlhdr->nlmsg_len = len;
62 }
63 
64 /* put data wrappers */
65 
ethnla_nest_end(struct nl_msg_buff * msgbuff,struct nlattr * nest)66 static inline void ethnla_nest_end(struct nl_msg_buff *msgbuff,
67 				   struct nlattr *nest)
68 {
69 	mnl_attr_nest_end(msgbuff->nlhdr, nest);
70 }
71 
ethnla_nest_cancel(struct nl_msg_buff * msgbuff,struct nlattr * nest)72 static inline void ethnla_nest_cancel(struct nl_msg_buff *msgbuff,
73 				      struct nlattr *nest)
74 {
75 	mnl_attr_nest_cancel(msgbuff->nlhdr, nest);
76 }
77 
ethnla_put_u32(struct nl_msg_buff * msgbuff,uint16_t type,uint32_t data)78 static inline bool ethnla_put_u32(struct nl_msg_buff *msgbuff, uint16_t type,
79 				  uint32_t data)
80 {
81 	return ethnla_put(msgbuff, type, sizeof(uint32_t), &data);
82 }
83 
ethnla_put_u16(struct nl_msg_buff * msgbuff,uint16_t type,uint16_t data)84 static inline bool ethnla_put_u16(struct nl_msg_buff *msgbuff, uint16_t type,
85 				  uint16_t data)
86 {
87 	return ethnla_put(msgbuff, type, sizeof(uint16_t), &data);
88 }
89 
ethnla_put_u8(struct nl_msg_buff * msgbuff,uint16_t type,uint8_t data)90 static inline bool ethnla_put_u8(struct nl_msg_buff *msgbuff, uint16_t type,
91 				 uint8_t data)
92 {
93 	return ethnla_put(msgbuff, type, sizeof(uint8_t), &data);
94 }
95 
ethnla_put_flag(struct nl_msg_buff * msgbuff,uint16_t type,bool val)96 static inline bool ethnla_put_flag(struct nl_msg_buff *msgbuff, uint16_t type,
97 				   bool val)
98 {
99 	if (val)
100 		return ethnla_put(msgbuff, type, 0, &val);
101 	else
102 		return false;
103 }
104 
ethnla_put_bitfield32(struct nl_msg_buff * msgbuff,uint16_t type,uint32_t value,uint32_t selector)105 static inline bool ethnla_put_bitfield32(struct nl_msg_buff *msgbuff,
106 					 uint16_t type, uint32_t value,
107 					 uint32_t selector)
108 {
109 	struct nla_bitfield32 val = {
110 		.value		= value,
111 		.selector	= selector,
112 	};
113 
114 	return ethnla_put(msgbuff, type, sizeof(val), &val);
115 }
116 
ethnla_put_strz(struct nl_msg_buff * msgbuff,uint16_t type,const char * data)117 static inline bool ethnla_put_strz(struct nl_msg_buff *msgbuff, uint16_t type,
118 				   const char *data)
119 {
120 	return ethnla_put(msgbuff, type, strlen(data) + 1, data);
121 }
122 
123 #endif /* ETHTOOL_NETLINK_MSGBUFF_H__ */
124