xref: /aosp_15_r20/external/ethtool/netlink/msgbuff.h (revision 1b481fc3bb1b45d4cf28d1ec12969dc1055f555d)
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