xref: /aosp_15_r20/external/ethtool/netlink/netlink.h (revision 1b481fc3bb1b45d4cf28d1ec12969dc1055f555d)
1 /*
2  * netlink.h - common interface for all netlink code
3  *
4  * Declarations of data structures, global data and helpers for netlink code
5  */
6 
7 #ifndef ETHTOOL_NETLINK_INT_H__
8 #define ETHTOOL_NETLINK_INT_H__
9 
10 #include <libmnl/libmnl.h>
11 #include <linux/netlink.h>
12 #include <linux/genetlink.h>
13 #include <linux/ethtool_netlink.h>
14 #include "nlsock.h"
15 
16 #define WILDCARD_DEVNAME "*"
17 #define CMDMASK_WORDS DIV_ROUND_UP(__ETHTOOL_MSG_KERNEL_CNT, 32)
18 
19 enum link_mode_class {
20 	LM_CLASS_UNKNOWN,
21 	LM_CLASS_REAL,
22 	LM_CLASS_AUTONEG,
23 	LM_CLASS_PORT,
24 	LM_CLASS_PAUSE,
25 	LM_CLASS_FEC,
26 };
27 
28 struct nl_op_info {
29 	uint32_t		op_flags;
30 	uint32_t		hdr_flags;
31 	uint8_t			hdr_policy_loaded:1;
32 };
33 
34 struct nl_context {
35 	struct cmd_context	*ctx;
36 	void			*cmd_private;
37 	const char		*devname;
38 	bool			is_dump;
39 	int			exit_code;
40 	unsigned int		suppress_nlerr;
41 	uint16_t		ethnl_fam;
42 	uint32_t		ethnl_mongrp;
43 	struct nl_op_info	*ops_info;
44 	struct nl_socket	*ethnl_socket;
45 	struct nl_socket	*ethnl2_socket;
46 	struct nl_socket	*rtnl_socket;
47 	bool			is_monitor;
48 	uint32_t		filter_cmds[CMDMASK_WORDS];
49 	const char		*filter_devname;
50 	bool			no_banner;
51 	const char		*cmd;
52 	const char		*param;
53 	char			**argp;
54 	unsigned int		argc;
55 	bool			ioctl_fallback;
56 	bool			wildcard_unsupported;
57 };
58 
59 struct attr_tb_info {
60 	const struct nlattr **tb;
61 	unsigned int max_type;
62 };
63 
64 #define DECLARE_ATTR_TB_INFO(tbl) \
65 	struct attr_tb_info tbl ## _info = { (tbl), (MNL_ARRAY_SIZE(tbl) - 1) }
66 
67 int nomsg_reply_cb(const struct nlmsghdr *nlhdr, void *data);
68 int attr_cb(const struct nlattr *attr, void *data);
69 
70 int netlink_init(struct cmd_context *ctx);
71 bool netlink_cmd_check(struct cmd_context *ctx, unsigned int cmd,
72 		       bool allow_wildcard);
73 const char *get_dev_name(const struct nlattr *nest);
74 int get_dev_info(const struct nlattr *nest, int *ifindex, char *ifname);
75 u32 get_stats_flag(struct nl_context *nlctx, unsigned int nlcmd,
76 		   unsigned int hdrattr);
77 
78 int linkmodes_reply_cb(const struct nlmsghdr *nlhdr, void *data);
79 int linkinfo_reply_cb(const struct nlmsghdr *nlhdr, void *data);
80 int wol_reply_cb(const struct nlmsghdr *nlhdr, void *data);
81 int debug_reply_cb(const struct nlmsghdr *nlhdr, void *data);
82 int features_reply_cb(const struct nlmsghdr *nlhdr, void *data);
83 int privflags_reply_cb(const struct nlmsghdr *nlhdr, void *data);
84 int rings_reply_cb(const struct nlmsghdr *nlhdr, void *data);
85 int channels_reply_cb(const struct nlmsghdr *nlhdr, void *data);
86 int coalesce_reply_cb(const struct nlmsghdr *nlhdr, void *data);
87 int pause_reply_cb(const struct nlmsghdr *nlhdr, void *data);
88 int eee_reply_cb(const struct nlmsghdr *nlhdr, void *data);
89 int cable_test_reply_cb(const struct nlmsghdr *nlhdr, void *data);
90 int cable_test_ntf_cb(const struct nlmsghdr *nlhdr, void *data);
91 int cable_test_tdr_reply_cb(const struct nlmsghdr *nlhdr, void *data);
92 int cable_test_tdr_ntf_cb(const struct nlmsghdr *nlhdr, void *data);
93 int fec_reply_cb(const struct nlmsghdr *nlhdr, void *data);
94 int module_reply_cb(const struct nlmsghdr *nlhdr, void *data);
95 
96 /* dump helpers */
97 
98 int dump_link_modes(struct nl_context *nlctx, const struct nlattr *bitset,
99 		    bool mask, unsigned int class, const char *before,
100 		    const char *between, const char *after,
101 		    const char *if_none);
102 
show_u32(const char * key,const char * fmt,const struct nlattr * attr)103 static inline void show_u32(const char *key,
104 			    const char *fmt,
105 			    const struct nlattr *attr)
106 {
107 	if (is_json_context()) {
108 		if (attr)
109 			print_uint(PRINT_JSON, key, NULL,
110 				   mnl_attr_get_u32(attr));
111 	} else {
112 		if (attr)
113 			printf("%s%u\n", fmt, mnl_attr_get_u32(attr));
114 		else
115 			printf("%sn/a\n", fmt);
116 	}
117 }
118 
u8_to_bool(const uint8_t * val)119 static inline const char *u8_to_bool(const uint8_t *val)
120 {
121 	if (val)
122 		return *val ? "on" : "off";
123 	else
124 		return "n/a";
125 }
126 
show_bool_val(const char * key,const char * fmt,uint8_t * val)127 static inline void show_bool_val(const char *key, const char *fmt, uint8_t *val)
128 {
129 	if (is_json_context()) {
130 		if (val)
131 			print_bool(PRINT_JSON, key, NULL, *val);
132 	} else {
133 		print_string(PRINT_FP, NULL, fmt, u8_to_bool(val));
134 	}
135 }
136 
show_bool(const char * key,const char * fmt,const struct nlattr * attr)137 static inline void show_bool(const char *key, const char *fmt,
138 			     const struct nlattr *attr)
139 {
140 	show_bool_val(key, fmt, attr ? mnl_attr_get_payload(attr) : NULL);
141 }
142 
show_cr(void)143 static inline void show_cr(void)
144 {
145 	if (!is_json_context())
146 		putchar('\n');
147 }
148 
149 /* misc */
150 
copy_devname(char * dst,const char * src)151 static inline void copy_devname(char *dst, const char *src)
152 {
153 	strncpy(dst, src, ALTIFNAMSIZ);
154 	dst[ALTIFNAMSIZ - 1] = '\0';
155 }
156 
dev_ok(const struct nl_context * nlctx)157 static inline bool dev_ok(const struct nl_context *nlctx)
158 {
159 	return !nlctx->filter_devname ||
160 	       (nlctx->devname &&
161 		!strcmp(nlctx->devname, nlctx->filter_devname));
162 }
163 
netlink_init_ethnl2_socket(struct nl_context * nlctx)164 static inline int netlink_init_ethnl2_socket(struct nl_context *nlctx)
165 {
166 	if (nlctx->ethnl2_socket)
167 		return 0;
168 	return nlsock_init(nlctx, &nlctx->ethnl2_socket, NETLINK_GENERIC);
169 }
170 
netlink_init_rtnl_socket(struct nl_context * nlctx)171 static inline int netlink_init_rtnl_socket(struct nl_context *nlctx)
172 {
173 	if (nlctx->rtnl_socket)
174 		return 0;
175 	return nlsock_init(nlctx, &nlctx->rtnl_socket, NETLINK_ROUTE);
176 }
177 
178 #endif /* ETHTOOL_NETLINK_INT_H__ */
179