1# Copyright 2017 syzkaller project authors. All rights reserved.
2# Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
3
4include <asm/ioctls.h>
5include <linux/if_tun.h>
6include <linux/if_bridge.h>
7include <linux/net.h>
8include <linux/net_tstamp.h>
9include <linux/route.h>
10include <linux/socket.h>
11include <uapi/linux/in.h>
12include <uapi/linux/ethtool.h>
13include <uapi/linux/if_ether.h>
14
15resource sock[fd]
16type sock_port int16be[20000:20004]
17
18# TODO: describe socketcall syscall
19
20socket(domain flags[socket_domain], type flags[socket_type], proto int8) sock
21socketpair(domain flags[socket_domain], type flags[socket_type], proto int8, fds ptr[out, pipefd])
22bind(fd sock, addr ptr[in, sockaddr_storage], addrlen len[addr])
23connect(fd sock, addr ptr[in, sockaddr_storage], addrlen len[addr])
24accept(fd sock, peer ptr[out, sockaddr_storage, opt], peerlen ptr[inout, len[peer, int32]]) sock
25accept4(fd sock, peer ptr[out, sockaddr_storage, opt], peerlen ptr[inout, len[peer, int32]], flags flags[accept_flags]) sock
26sendto(fd sock, buf buffer[in], len len[buf], f flags[send_flags], addr ptr[in, sockaddr_storage, opt], addrlen len[addr])
27recvfrom(fd sock, buf buffer[out], len len[buf], f flags[recv_flags], addr ptr[in, sockaddr_storage, opt], addrlen len[addr])
28getsockname(fd sock, addr ptr[out, sockaddr_storage], addrlen ptr[inout, len[addr, int32]])
29getpeername(fd sock, peer ptr[out, sockaddr_storage], peerlen ptr[inout, len[peer, int32]])
30
31sendmsg(fd sock, msg ptr[in, send_msghdr], f flags[send_flags])
32sendmmsg(fd sock, mmsg ptr[in, array[send_mmsghdr]], vlen len[mmsg], f flags[send_flags])
33recvmsg(fd sock, msg ptr[in, recv_msghdr], f flags[recv_flags])
34recvmmsg(fd sock, mmsg ptr[in, array[recv_mmsghdr]], vlen len[mmsg], f flags[recv_flags], timeout ptr[in, timespec, opt])
35
36listen(fd sock, backlog int32)
37shutdown(fd sock, how flags[shutdown_flags])
38
39getsockopt(fd sock, level int32, optname int32, optval buffer[out], optlen ptr[inout, len[optval, int32]])
40setsockopt(fd sock, level int32, optname int32, optval buffer[in], optlen len[optval])
41
42socket_domain = AF_UNIX, AF_INET, AF_INET6, AF_IPX, AF_NETLINK, AF_X25, AF_AX25, AF_ATMPVC, AF_APPLETALK, AF_PACKET
43socket_type = SOCK_STREAM, SOCK_DGRAM, SOCK_RAW, SOCK_RDM, SOCK_SEQPACKET, SOCK_DCCP, SOCK_PACKET, SOCK_NONBLOCK, SOCK_CLOEXEC
44accept_flags = SOCK_NONBLOCK, SOCK_CLOEXEC
45shutdown_flags = SHUT_RD, SHUT_WR
46send_flags = MSG_CONFIRM, MSG_DONTROUTE, MSG_DONTWAIT, MSG_EOR, MSG_MORE, MSG_NOSIGNAL, MSG_OOB, MSG_PROBE, MSG_BATCH, MSG_FASTOPEN, MSG_ZEROCOPY
47recv_flags = MSG_CMSG_CLOEXEC, MSG_DONTWAIT, MSG_ERRQUEUE, MSG_OOB, MSG_PEEK, MSG_TRUNC, MSG_WAITALL, MSG_WAITFORONE
48cmsg_levels = SOL_SOCKET, IPPROTO_ICMP, SOL_IP, SOL_TCP, SOL_UDP, SOL_IPV6, SOL_ICMPV6, SOL_SCTP, SOL_UDPLITE, SOL_RAW, SOL_IPX, SOL_AX25, SOL_ATALK, SOL_NETROM, SOL_ROSE, SOL_DECNET, SOL_PACKET, SOL_ATM, SOL_AAL, SOL_IRDA, SOL_NETBEUI, SOL_LLC, SOL_DCCP, SOL_NETLINK, SOL_TIPC, SOL_RXRPC, SOL_PPPOL2TP, SOL_BLUETOOTH, SOL_PNPIPE, SOL_RDS, SOL_IUCV, SOL_CAIF, SOL_ALG, SOL_NFC, SOL_KCM
49
50# This sockaddr type corresponds to the struct sockaddr and is 16 bytes or less.
51# TODO: add AF_APPLETALK, AF_ATMPVC, AF_X25, AF_ROSE, AF_DECnet, AF_ATMSVC, AF_IRDA, AF_IB, AF_TIPC, AF_IUCV, AF_RXRPC, AF_ISDN, AF_PHONET, AF_IEEE802154, AF_CAIF, AF_QIPCRTR
52# Note: AF_UNIX, AF_INET6, AF_PACKET, AF_ALG, AF_PPPOX sockaddr is bigger than 16 bytes
53# Note: AF_NETROM sockaddr is the same as AF_AX25
54sockaddr [
55	in		sockaddr_in
56	ax25		sockaddr_ax25
57	ipx		sockaddr_ipx
58	nl		sockaddr_nl
59	llc		sockaddr_llc
60	can		sockaddr_can
61	sco		sockaddr_sco
62	l2		sockaddr_l2
63	hci		sockaddr_hci
64	rc		sockaddr_rc
65	nfc		sockaddr_nfc
66	vsock		sockaddr_vm
67	xdp		sockaddr_xdp
68	ethernet	sockaddr_ethernet
69	generic		sockaddr_generic
70] [size[SOCKADDR_SIZE]]
71
72# This sockaddr type corresponds to the sockaddr_storage type and is 128 bytes size.
73sockaddr_storage [
74	un		sockaddr_un
75	in		sockaddr_in
76	ax25		sockaddr_ax25
77	ipx		sockaddr_ipx
78	in6		sockaddr_in6
79	nl		sockaddr_nl
80	ll		sockaddr_ll
81	pppoe		sockaddr_pppoe
82	pppol2tp	sockaddr_pppol2tp
83	pppol2tpin6	sockaddr_pppol2tpin6
84	pppol2tpv3	sockaddr_pppol2tpv3
85	pppol2tpv3in6	sockaddr_pppol2tpv3in6
86	pptp		sockaddr_pptp
87	llc		sockaddr_llc
88	can		sockaddr_can
89	sco		sockaddr_sco
90	l2		sockaddr_l2
91	hci		sockaddr_hci
92	rc		sockaddr_rc
93	alg		sockaddr_alg
94	nfc		sockaddr_nfc
95	nfc_llcp	sockaddr_nfc_llcp
96	vsock		sockaddr_vm
97	xdp		sockaddr_xdp
98	ethernet	sockaddr_ethernet
99	generic		sockaddr_storage_generic
100] [size[SOCKADDR_STORAGE_SIZE]]
101
102define SOCKADDR_SIZE	sizeof(struct sockaddr)
103define SOCKADDR_STORAGE_SIZE	sizeof(struct sockaddr_storage)
104
105sockaddr_generic {
106	sa_family	flags[socket_domain, int16]
107	sa_data		array[int8, 14]
108}
109
110sockaddr_storage_generic {
111	sa_family	flags[socket_domain, int16]
112	sa_data		array[int8, 126]
113}
114
115send_msghdr {
116	msg_name	ptr[in, sockaddr_storage, opt]
117	msg_namelen	len[msg_name, int32]
118	msg_iov		ptr[in, array[iovec_in]]
119	msg_iovlen	len[msg_iov, intptr]
120	msg_control	ptr[in, array[cmsghdr], opt]
121	msg_controllen	bytesize[msg_control, intptr]
122	msg_flags	flags[send_flags, int32]
123}
124
125send_mmsghdr {
126	msg_hdr	send_msghdr
127	msg_len	int32
128}
129
130recv_msghdr {
131	msg_name	ptr[out, sockaddr_storage, opt]
132	msg_namelen	len[msg_name, int32]
133	msg_iov		ptr[in, array[iovec_out]]
134	msg_iovlen	len[msg_iov, intptr]
135	msg_control	ptr[out, array[int8], opt]
136	msg_controllen	bytesize[msg_control, intptr]
137	msg_flags	int32
138}
139
140recv_mmsghdr {
141	msg_hdr	recv_msghdr
142	msg_len	int32
143}
144
145cmsghdr {
146	cmsg_len	len[parent, intptr]
147	cmsg_level	flags[cmsg_levels, int32]
148	cmsg_type	int32
149	data		array[int8]
150} [align_ptr]
151
152# Socket options
153
154# http://lxr.free-electrons.com/source/include/uapi/asm-generic/socket.h
155
156setsockopt$sock_void(fd sock, level const[SOL_SOCKET], optname flags[sockopt_opt_sock_void], optval const[0], optlen const[0])
157getsockopt$sock_int(fd sock, level const[SOL_SOCKET], optname flags[sockopt_opt_sock_int], optval ptr[out, int32], optlen ptr[inout, len[optval, int32]])
158setsockopt$sock_int(fd sock, level const[SOL_SOCKET], optname flags[sockopt_opt_sock_int], optval ptr[in, int32], optlen len[optval])
159getsockopt$sock_linger(fd sock, level const[SOL_SOCKET], optname const[SO_LINGER], optval ptr[out, linger], optlen ptr[inout, len[optval, int32]])
160setsockopt$sock_linger(fd sock, level const[SOL_SOCKET], optname const[SO_LINGER], optval ptr[in, linger], optlen len[optval])
161getsockopt$sock_cred(fd sock, level const[SOL_SOCKET], optname const[SO_PEERCRED], optval ptr[out, ucred], optlen ptr[inout, len[optval, int32]])
162setsockopt$sock_cred(fd sock, level const[SOL_SOCKET], optname const[SO_PEERCRED], optval ptr[in, ucred], optlen len[optval])
163getsockopt$sock_timeval(fd sock, level const[SOL_SOCKET], optname flags[sockopt_opt_sock_timeval], optval ptr[out, timeval], optlen ptr[inout, len[optval, int32]])
164setsockopt$sock_timeval(fd sock, level const[SOL_SOCKET], optname flags[sockopt_opt_sock_timeval], optval ptr[in, timeval], optlen len[optval])
165setsockopt$sock_attach_bpf(fd sock, level const[SOL_SOCKET], optname const[SO_ATTACH_BPF], optval ptr[in, fd_bpf_prog], optlen len[optval])
166setsockopt$SO_TIMESTAMPING(fd sock, level const[SOL_SOCKET], optname const[SO_TIMESTAMPING], optval ptr[in, flags[sockopt_so_timestamping, int32]], optlen len[optval])
167getsockopt$SO_TIMESTAMPING(fd sock, level const[SOL_SOCKET], optname const[SO_TIMESTAMPING], optval ptr[out, int32], optlen ptr[inout, len[optval, int32]])
168setsockopt$SO_ATTACH_FILTER(fd sock, level const[SOL_SOCKET], optname const[SO_ATTACH_FILTER], optval ptr[in, sock_fprog], optlen len[optval])
169setsockopt$SO_BINDTODEVICE(fd sock, level const[SOL_SOCKET], optname const[SO_BINDTODEVICE], optval ptr[in, devname], optlen len[optval])
170getsockopt$SO_BINDTODEVICE(fd sock, level const[SOL_SOCKET], optname const[SO_BINDTODEVICE], optval ptr[out, devname], optlen len[optval])
171getsockopt$sock_buf(fd sock, level const[SOL_SOCKET], optname flags[sockopt_opt_sock_buf], optval buffer[out], optlen ptr[inout, len[optval, int32]])
172getsockopt$SO_COOKIE(fd sock, level const[SOL_SOCKET], optname const[SO_COOKIE], optval ptr[out, int64], optlen ptr[inout, len[optval, int32]])
173
174linger {
175	onoff	bool32
176	linger	int32
177}
178
179sockopt_opt_sock_void = SO_DETACH_FILTER, SO_MARK
180sockopt_opt_sock_int = SO_ACCEPTCONN, SO_BROADCAST, SO_DEBUG, SO_DOMAIN, SO_ERROR, SO_DONTROUTE, SO_KEEPALIVE, SO_PEEK_OFF, SO_PRIORITY, SO_PROTOCOL, SO_RCVBUF, SO_RCVBUFFORCE, SO_RCVLOWAT, SO_SNDLOWAT, SO_REUSEADDR, SO_SNDBUF, SO_SNDBUFFORCE, SO_TIMESTAMP, SO_TYPE, SO_REUSEPORT, SO_OOBINLINE, SO_NO_CHECK, SO_PASSCRED, SO_TIMESTAMPNS, SO_LOCK_FILTER, SO_PASSSEC, SO_RXQ_OVFL, SO_WIFI_STATUS, SO_NOFCS, SO_SELECT_ERR_QUEUE, SO_BUSY_POLL, SO_MAX_PACING_RATE, SO_ZEROCOPY
181sockopt_opt_sock_timeval = SO_RCVTIMEO, SO_SNDTIMEO
182sockopt_opt_sock_buf = SO_PEERNAME, SO_PEERSEC, SO_GET_FILTER, SO_MEMINFO, SO_PEERGROUPS
183sockopt_so_timestamping = SOF_TIMESTAMPING_TX_HARDWARE, SOF_TIMESTAMPING_TX_SOFTWARE, SOF_TIMESTAMPING_RX_HARDWARE, SOF_TIMESTAMPING_RX_SOFTWARE, SOF_TIMESTAMPING_SOFTWARE, SOF_TIMESTAMPING_SYS_HARDWARE, SOF_TIMESTAMPING_RAW_HARDWARE, SOF_TIMESTAMPING_OPT_ID, SOF_TIMESTAMPING_TX_SCHED, SOF_TIMESTAMPING_TX_ACK, SOF_TIMESTAMPING_OPT_CMSG, SOF_TIMESTAMPING_OPT_TSONLY
184
185# Socket ioctls
186
187# Since some socket ioctls are forwarded to the network device, adding device ioctls here as well.
188
189# http://lxr.free-electrons.com/source/include/uapi/linux/sockios.h
190
191# http://lxr.free-electrons.com/source/include/uapi/asm-generic/sockios.h
192
193# TODO: add SIOCADDRT, SIOCDELRT, SIOCRTMSG, SIOCDRARP, SIOCGRARP, SIOCSRARP, SIOCGIFVLAN, SIOCSIFVLAN, SIOCGSTAMP, SIOCGSTAMPNS
194
195ioctl$sock_SIOCETHTOOL(fd sock, cmd const[SIOCETHTOOL], arg ptr[inout, ifreq_t[ptr[inout, ethtool_cmd_u]]])
196
197ioctl$sock_SIOCOUTQ(fd sock, cmd const[SIOCOUTQ], arg ptr[out, int32])
198ioctl$sock_SIOCINQ(fd sock, cmd const[SIOCINQ], arg ptr[out, int32])
199
200ioctl$sock_SIOCGIFCONF(fd sock, cmd const[SIOCGIFNAME], arg ptr[inout, ifconf])
201
202ifreq_ioctls = SIOCGIFNAME, SIOCSIFLINK, SIOCGIFFLAGS, SIOCSIFFLAGS, SIOCGIFADDR, SIOCSIFADDR, SIOCGIFDSTADDR, SIOCSIFDSTADDR, SIOCGIFBRDADDR, SIOCSIFBRDADDR, SIOCGIFNETMASK, SIOCSIFNETMASK, SIOCGIFMETRIC, SIOCSIFMETRIC, SIOCGIFMEM, SIOCSIFMEM, SIOCGIFMTU, SIOCSIFMTU, SIOCSIFNAME, SIOCSIFHWADDR, SIOCGIFENCAP, SIOCSIFENCAP, SIOCGIFHWADDR, SIOCGIFSLAVE, SIOCSIFSLAVE, SIOCADDMULTI, SIOCDELMULTI, SIOCGIFINDEX, SIOCSIFPFLAGS, SIOCGIFPFLAGS, SIOCDIFADDR, SIOCSIFHWBROADCAST, SIOCGIFCOUNT, SIOCGIFTXQLEN, SIOCSIFTXQLEN, SIOCETHTOOL, SIOCGMIIPHY, SIOCGMIIREG, SIOCSMIIREG, SIOCWANDEV, SIOCGIFMAP, SIOCSIFMAP, SIOCBONDENSLAVE, SIOCBONDRELEASE, SIOCBONDSETHWADDR, SIOCBONDSLAVEINFOQUERY, SIOCBONDINFOQUERY, SIOCBONDCHANGEACTIVE, SIOCBRADDIF, SIOCBRDELIF, SIOCSHWTSTAMP, SIOCGHWTSTAMP
203
204ioctl$sock_ifreq(fd sock, cmd flags[ifreq_ioctls], arg ptr[inout, ifreq])
205
206ioctl$sock_SIOCGIFINDEX(fd sock, cmd const[SIOCGIFINDEX], arg ptr[inout, ifreq_t[ifindex]])
207
208ioctl$sock_SIOCGIFBR(fd sock, cmd const[SIOCGIFBR], arg ptr[inout, brctl_arg])
209ioctl$sock_SIOCSIFBR(fd sock, cmd const[SIOCSIFBR], arg ptr[inout, brctl_arg])
210
211ioctl$sock_SIOCOUTQNSD(fd sock, cmd const[SIOCOUTQNSD], arg ptr[out, int32])
212
213ioctl$sock_SIOCGSKNS(fd sock, cmd const[SIOCGSKNS], arg ptr[inout, int32])
214
215ioctl$sock_SIOCADDDLCI(fd sock, cmd const[SIOCADDDLCI], arg ptr[inout, dlci_add])
216ioctl$sock_SIOCDELDLCI(fd sock, cmd const[SIOCDELDLCI], arg ptr[in, dlci_add])
217
218ioctl$sock_SIOCBRADDBR(fd sock, cmd const[SIOCBRADDBR], arg ptr[in, devname])
219ioctl$sock_SIOCBRDELBR(fd sock, cmd const[SIOCBRDELBR], arg ptr[in, devname])
220
221define SIOCDEVPRIVATE_BEG	(SIOCDEVPRIVATE)
222define SIOCDEVPRIVATE_END	(SIOCDEVPRIVATE + 15)
223
224define SIOCPROTOPRIVATE_BEG	(SIOCPROTOPRIVATE)
225define SIOCPROTOPRIVATE_END	(SIOCPROTOPRIVATE + 15)
226
227ioctl$sock_netdev_private(fd sock, cmd int16[SIOCDEVPRIVATE_BEG:SIOCDEVPRIVATE_END], arg ptr[in, array[int8]])
228ioctl$sock_proto_private(fd sock, cmd int16[SIOCPROTOPRIVATE_BEG:SIOCPROTOPRIVATE_END], arg ptr[in, array[int8]])
229
230ioctl$sock_FIOSETOWN(fd sock, cmd const[FIOSETOWN], arg ptr[in, pid])
231ioctl$sock_SIOCSPGRP(fd sock, cmd const[SIOCSPGRP], arg ptr[in, pid])
232
233ioctl$sock_FIOGETOWN(fd sock, cmd const[FIOGETOWN], arg ptr[out, pid])
234ioctl$sock_SIOCGPGRP(fd sock, cmd const[SIOCGPGRP], arg ptr[out, pid])
235
236resource ifindex[int32]
237
238type ifreq_dev_t[DEVNAME, ELEM] {
239	ifr_ifrn	string[DEVNAME, IFNAMSIZ]
240	elem		ELEM
241} [size[IFREQ_SIZE]]
242
243type ifreq_t[ELEM] ifreq_dev_t[devnames, ELEM]
244
245type ifreq ifreq_t[ifr_ifru]
246
247ifr_ifru [
248	ifru_addrs	sockaddr
249	ifru_hwaddr	mac_addr
250	ifru_flags	flags[ifru_flags, int16]
251	ifru_ivalue	int32
252	ifru_mtu	int32
253	ifru_map	ifmap
254	ifru_names	devname
255	ifru_data	ptr[in, array[int8, 32]]
256	ifru_settings	if_settings
257]
258
259define IFREQ_SIZE	sizeof(struct ifreq)
260
261# We could add "eth0" to this list as well, but this will affect the connection
262# between fuzzer and manager and produce lots of "no output" crashes
263# (actually, this is not true now since all testing is done in a separate
264# network namespace, but we still don't mess with eth0).
265devnames = "", "lo", "tunl0", "gre0", "gretap0", "ip_vti0", "ip6_vti0", "sit0", "ip6tnl0", "ip6gre0", "ip6gretap0", "bond0", "dummy0", "eql", "ifb0", "ipddp0", "yam0", "bcsf0", "bcsh0", "teql0", "nr0", "rose0", "irlan0", "erspan0", "bpq0", "vlan0", "bridge0", "vcan0", "team0", "syz_tun", "veth0", "veth1", "veth0_to_bridge", "veth1_to_bridge", "veth0_to_bond", "veth1_to_bond", "veth0_to_team", "veth1_to_team", "bridge_slave_0", "bridge_slave_1", "bond_slave_0", "bond_slave_1", "team_slave_0", "team_slave_1", "syzkaller0", "syzkaller1"
266
267type devname string[devnames, IFNAMSIZ]
268
269devname_mask {
270	lo	flags[devname_mask_values, int8]
271} [size[IFNAMSIZ]]
272
273devname_mask_values = 0, 0xff
274
275ifru_flags = IFF_TUN, IFF_TAP, IFF_NO_PI, IFF_ONE_QUEUE, IFF_VNET_HDR, IFF_TUN_EXCL, IFF_MULTI_QUEUE, IFF_ATTACH_QUEUE, IFF_DETACH_QUEUE, IFF_PERSIST, IFF_NOFILTER
276
277ifmap {
278	mem_start	intptr
279	mem_end		intptr
280	base_addr	int16
281	irq		int8
282	dma		int8
283	port		int8
284}
285
286if_settings {
287	type		int32
288	size		int32
289	ifs_ifsu	ifs_ifsu
290}
291
292ifs_ifsu [
293	raw_hdlc	ptr[in, raw_hdlc_proto]
294	cisco		ptr[in, cisco_proto]
295	fr		ptr[in, fr_proto]
296	fr_pvc		ptr[in, fr_proto_pvc]
297	fr_pvc_info	ptr[in, fr_proto_pvc_info]
298	sync		ptr[in, sync_serial_settings]
299	te1		ptr[in, te1_settings]
300]
301
302raw_hdlc_proto {
303	encode	int16
304	parity	int16
305}
306
307cisco_proto {
308	val	int32
309	timeout	int32
310}
311
312fr_proto {
313	t391	int32
314	t392	int32
315	n391	int32
316	n392	int32
317	n393	int32
318	lmi	int16
319	dce	int16
320}
321
322fr_proto_pvc {
323	dlcl	int32
324}
325
326fr_proto_pvc_info {
327	dlci	int32
328	master	devname
329}
330
331sync_serial_settings {
332	rate	int32
333	type	int32
334	loop	int16
335}
336
337te1_settings {
338	rate	int32
339	type	int32
340	loop	int16
341	slot	int32
342}
343
344ifconf [
345	buf	ifconf_buf
346	req	ifconf_req
347]
348
349ifconf_buf {
350	ifc_len		len[ifcu_buf, int32]
351	ifcu_buf	ptr[inout, array[int8], opt]
352}
353
354ifconf_req {
355	ifc_len		len[ifcu_req, int32]
356	ifcu_req	ptr[inout, ifreq, opt]
357}
358
359brctl_cmds = BRCTL_GET_VERSION, BRCTL_GET_BRIDGES, BRCTL_ADD_BRIDGE, BRCTL_DEL_BRIDGE
360
361brctl_arg [
362	get	brctl_arg_get
363	add_del	brctl_arg_add_del
364	generic	brctl_arg_generic
365]
366
367brctl_arg_get {
368	cmd	const[BRCTL_GET_BRIDGES, int64]
369	buf	ptr[out, array[int8]]
370	indices	int64
371}
372
373brctl_arg_add_del {
374	cmd	const[BRCTL_ADD_BRIDGE, int64]
375	devname	ptr[in, devname]
376	pad	int64
377}
378
379brctl_arg_generic {
380	a0	flags[brctl_cmds, int64]
381	a1	int64
382	a2	int64
383}
384
385dlci_add {
386	devname	devname
387	dlci	int16
388}
389
390# ETHTOOL declaration part
391# http://elixir.free-electrons.com/linux/latest/source/include/uapi/linux/ethtool.h
392
393ethtool_cmd_flags = ETHTOOL_GSET, ETHTOOL_SSET, ETHTOOL_GDRVINFO, ETHTOOL_GREGS, ETHTOOL_GWOL, ETHTOOL_SWOL, ETHTOOL_GMSGLVL, ETHTOOL_SMSGLVL, ETHTOOL_NWAY_RST, ETHTOOL_GLINK, ETHTOOL_GEEPROM, ETHTOOL_SEEPROM, ETHTOOL_GCOALESCE, ETHTOOL_SCOALESCE, ETHTOOL_GRINGPARAM, ETHTOOL_SRINGPARAM, ETHTOOL_GPAUSEPARAM, ETHTOOL_SPAUSEPARAM, ETHTOOL_GRXCSUM, ETHTOOL_SRXCSUM, ETHTOOL_GTXCSUM, ETHTOOL_STXCSUM, ETHTOOL_GSG, ETHTOOL_SSG, ETHTOOL_TEST, ETHTOOL_GSTRINGS, ETHTOOL_PHYS_ID, ETHTOOL_GSTATS, ETHTOOL_GTSO, ETHTOOL_STSO, ETHTOOL_GPERMADDR, ETHTOOL_GUFO, ETHTOOL_SUFO, ETHTOOL_GGSO, ETHTOOL_SGSO, ETHTOOL_GFLAGS, ETHTOOL_SFLAGS, ETHTOOL_GPFLAGS, ETHTOOL_SPFLAGS, ETHTOOL_GRXFH, ETHTOOL_SRXFH, ETHTOOL_GGRO, ETHTOOL_SGRO, ETHTOOL_GRXRINGS, ETHTOOL_GRXCLSRLCNT, ETHTOOL_GRXCLSRULE, ETHTOOL_GRXCLSRLALL, ETHTOOL_SRXCLSRLDEL, ETHTOOL_SRXCLSRLINS, ETHTOOL_FLASHDEV, ETHTOOL_RESET, ETHTOOL_SRXNTUPLE, ETHTOOL_GRXNTUPLE, ETHTOOL_GSSET_INFO, ETHTOOL_GRXFHINDIR, ETHTOOL_SRXFHINDIR, ETHTOOL_GFEATURES, ETHTOOL_SFEATURES, ETHTOOL_GCHANNELS, ETHTOOL_SCHANNELS, ETHTOOL_SET_DUMP, ETHTOOL_GET_DUMP_FLAG, ETHTOOL_GET_DUMP_DATA, ETHTOOL_GET_TS_INFO, ETHTOOL_GMODULEINFO, ETHTOOL_GMODULEEEPROM, ETHTOOL_GEEE, ETHTOOL_SEEE, ETHTOOL_GRSSH, ETHTOOL_SRSSH, ETHTOOL_GTUNABLE, ETHTOOL_STUNABLE, ETHTOOL_GPHYSTATS, ETHTOOL_PERQUEUE, ETHTOOL_GLINKSETTINGS, ETHTOOL_SLINKSETTINGS, ETHTOOL_PHY_GTUNABLE, ETHTOOL_PHY_STUNABLE
394
395ethtool_cmd_u [
396	ethtool_cmd		ethtool_cmd
397	ethtool_drvinfo		ethtool_drvinfo
398	ethtool_wolinfo		ethtool_wolinfo
399	ethtool_regs		ethtool_regs
400	ethtool_eeprom		ethtool_eeprom
401	ethtool_eee		ethtool_eee
402	ethtool_modinfo		ethtool_modinfo
403	ethtool_coalesce	ethtool_coalesce
404	ethtool_ringparam	ethtool_ringparam
405	ethtool_channels	ethtool_channels
406	ethtool_pauseparam	ethtool_pauseparam
407	ethtool_gstrings	ethtool_gstrings
408	ethtool_sset_info	ethtool_sset_info
409	ethtool_test		ethtool_test
410	ethtool_stats		ethtool_stats
411	ethtool_perm_addr	ethtool_perm_addr
412	ethtool_rxnfc		ethtool_rxnfc
413	ethtool_rxfh_indir	ethtool_rxfh_indir
414	ethtool_rxfh		ethtool_rxfh
415	ethtool_rx_ntuple	ethtool_rx_ntuple
416	ethtool_flash		ethtool_flash
417	ethtool_dump		ethtool_dump
418	ethtool_gfeatures	ethtool_gfeatures
419	ethtool_sfeatures	ethtool_sfeatures
420	ethtool_ts_info		ethtool_ts_info
421	ethtool_per_queue_op	ethtool_per_queue_op
422	ethtool_link_settings	ethtool_link_settings
423] [varlen]
424
425ethtool_cmd {
426	cmd			flags[ethtool_cmd_flags, int32]
427	supported		int32
428	advertising		int32
429	speed			int16
430	duplex			int8
431	port			int8
432	phy_address		int8
433	transceiver		int8
434	autoneg			int8
435	mdio_support		int8
436	maxtxpkt		int32
437	maxrxpkt		int32
438	speed_hi		int16
439	eth_tp_mdix		int8
440	eth_tp_mdix_ctrl	int8
441	lp_advertising		int32
442	reserved		array[int32, 2]
443}
444
445ethtool_drvinfo {
446	cmd		const[ETHTOOL_GDRVINFO, int32]
447	driver		array[int8, 32]
448	version		array[int8, 32]
449	fw_version	array[int8, ETHTOOL_FWVERS_LEN]
450	bus_info	array[int8, ETHTOOL_BUSINFO_LEN]
451	erom_version	array[int8, ETHTOOL_EROMVERS_LEN]
452	reserved2	array[int8, 12]
453	n_priv_flags	int32
454	n_stats		int32
455	testinfo_len	int32
456	eedump_len	int32
457	regdump_len	int32
458}
459
460ethtool_wolinfo_cmd_flags = ETHTOOL_GWOL, ETHTOOL_SWOL
461
462ethtool_wolinfo {
463	cmd		flags[ethtool_wolinfo_cmd_flags, int32]
464	supported	int32
465	wolopts		int32
466	sopass		array[int8, SOPASS_MAX]
467}
468
469ethtool_regs {
470	cmd	const[ETHTOOL_GREGS, int32]
471	version	int32
472	len	len[data, int32]
473	data	array[int8]
474}
475
476ethtool_eeprom_cmd_flags = ETHTOOL_GEEPROM, ETHTOOL_GMODULEEEPROM, ETHTOOL_SEEPROM
477
478ethtool_eeprom {
479	cmd	flags[ethtool_eeprom_cmd_flags, int32]
480	magic	int32
481	offset	int32
482	len	len[data, int32]
483	data	array[int8]
484}
485
486ethtool_eee_cmd_flags = ETHTOOL_GEEE, ETHTOOL_SEEE
487
488ethtool_eee {
489	cmd		flags[ethtool_eee_cmd_flags, int32]
490	supported	int32
491	advertised	int32
492	lp_advertised	int32
493	eee_active	int32
494	eee_enabled	int32
495	tx_lpi_enabled	int32
496	tx_lpi_timer	int32
497	reserved	array[int32, 2]
498}
499
500ethtool_modinfo {
501	cmd		const[ETHTOOL_GMODULEINFO, int32]
502	type		int32
503	eeprom_len	int32
504	reserved	array[int8, 8]
505}
506
507ethtool_coalesce_cmd_flags = ETHTOOL_GCOALESCE, ETHTOOL_SCOALESCE
508
509ethtool_coalesce {
510	cmd				flags[ethtool_coalesce_cmd_flags, int32]
511	rx_coalesce_usecs		int32
512	rx_max_coalesced_frames		int32
513	rx_coalesce_usecs_irq		int32
514	rx_max_coalesced_frames_irq	int32
515	tx_coalesce_usecs		int32
516	tx_max_coalesced_frames		int32
517	tx_coalesce_usecs_irq		int32
518	tx_max_coalesced_frames_irq	int32
519	stats_block_coalesce_usecs	int32
520	use_adaptive_rx_coalesce	int32
521	use_adaptive_tx_coalesce	int32
522	pkt_rate_low			int32
523	rx_coalesce_usecs_low		int32
524	rx_max_coalesced_frames_low	int32
525	tx_coalesce_usecs_low		int32
526	tx_max_coalesced_frames_low	int32
527	pkt_rate_high			int32
528	rx_coalesce_usecs_high		int32
529	rx_max_coalesced_frames_high	int32
530	tx_coalesce_usecs_high		int32
531	tx_max_coalesced_frames_high	int32
532	rate_sample_interval		int32
533}
534
535ethtool_ringparam_cmd_flags = ETHTOOL_GRINGPARAM, ETHTOOL_SRINGPARAM
536
537ethtool_ringparam {
538	cmd			flags[ethtool_ringparam_cmd_flags, int32]
539	rx_max_pending		int32
540	rx_mini_max_pending	int32
541	rx_jumbo_max_pending	int32
542	tx_max_pending		int32
543	rx_pending		int32
544	rx_mini_pending		int32
545	rx_jumbo_pending	int32
546	tx_pending		int32
547}
548
549ethtool_channels_cmd_flags = ETHTOOL_GCHANNELS, ETHTOOL_SCHANNELS
550
551ethtool_channels {
552	cmd		flags[ethtool_channels_cmd_flags, int32]
553	max_rx		int32
554	max_tx		int32
555	max_other	int32
556	max_combined	int32
557	rx_count	int32
558	tx_count	int32
559	other_count	int32
560	combined_count	int32
561}
562
563ethtool_pauseparam_cmd_flags = ETHTOOL_GPAUSEPARAM, ETHTOOL_SPAUSEPARAM
564
565ethtool_pauseparam {
566	cmd		flags[ethtool_pauseparam_cmd_flags, int32]
567	autoneg		int32
568	rx_pause	int32
569	tx_pause	int32
570}
571
572ethtool_gstrings {
573	cmd		const[ETHTOOL_GSTRINGS, int32]
574	string_set	int32
575	len		len[data, int32]
576	data		array[int8]
577}
578
579ethtool_sset_info {
580	cmd		const[ETHTOOL_GSSET_INFO, int32]
581	reserved	int32
582	sset_mask	int64
583	data		array[int32]
584}
585
586ethtool_test {
587	cmd		const[ETHTOOL_TEST, int32]
588	flags		int32
589	reserved	int32
590	len		len[data, int32]
591	data		array[int64]
592}
593
594ethtool_stats {
595	cmd	const[ETHTOOL_GSTATS, int32]
596	n_stats	len[data, int32]
597	data	array[int64]
598}
599
600ethtool_perm_addr {
601	cmd	const[ETHTOOL_GPERMADDR, int32]
602	size	len[data, int32]
603	data	array[int8]
604}
605
606# http://elixir.free-electrons.com/linux/latest/source/include/uapi/linux/ethtool.h#L1565
607traffic_flow_types = TCP_V4_FLOW, UDP_V4_FLOW, SCTP_V4_FLOW, AH_ESP_V4_FLOW, TCP_V6_FLOW, UDP_V6_FLOW, SCTP_V6_FLOW, AH_ESP_V6_FLOW, AH_V4_FLOW, ESP_V4_FLOW, AH_V6_FLOW, ESP_V6_FLOW, IPV4_USER_FLOW, IP_USER_FLOW, IPV6_USER_FLOW, IPV4_FLOW, IPV6_FLOW, ETHER_FLOW
608
609ethtool_rxnfc_cmd_flags = ETHTOOL_GRXFH, ETHTOOL_SRXFH, ETHTOOL_GRXRINGS, ETHTOOL_GRXCLSRLCNT, ETHTOOL_GRXCLSRULE, ETHTOOL_GRXCLSRLALL, ETHTOOL_SRXCLSRLDEL, ETHTOOL_SRXCLSRLINS
610
611ethtool_rxnfc {
612	cmd		flags[ethtool_rxnfc_cmd_flags, int32]
613	flow_type	flags[traffic_flow_types, int32]
614	data		int64
615	fs		ethtool_rx_flow_spec
616	rule_cnt	len[rule_locs, int32]
617	rule_locs	array[int32]
618}
619
620ethtool_rx_flow_spec {
621	flow_type	flags[traffic_flow_types, int32]
622	h_u		ethtool_flow_union
623	h_ext		ethtool_flow_ext
624	m_u		ethtool_flow_union
625	m_ext		ethtool_flow_ext
626	ring_cookie	int64
627	location	int32
628}
629
630ethtool_flow_union [
631	tcp_ip4_spec	ethtool_tcpip4_spec
632	udp_ip4_spec	ethtool_tcpip4_spec
633	sctp_ip4_spec	ethtool_tcpip4_spec
634	ah_ip4_spec	ethtool_ah_espip4_spec
635	esp_ip4_spec	ethtool_ah_espip4_spec
636	usr_ip4_spec	ethtool_usrip4_spec
637	tcp_ip6_spec	ethtool_tcpip6_spec
638	udp_ip6_spec	ethtool_tcpip6_spec
639	sctp_ip6_spec	ethtool_tcpip6_spec
640	ah_ip6_spec	ethtool_ah_espip6_spec
641	esp_ip6_spec	ethtool_ah_espip6_spec
642	usr_ip6_spec	ethtool_usrip6_spec
643	ether_spec	ethhdr
644	hdata		array[int8, 52]
645]
646
647ethtool_flow_ext {
648	padding		array[int8, 2]
649	h_dest		mac_addr
650	vlan_etype	int16be
651	vlan_tci	int16be
652	data		array[int32be, 2]
653}
654
655ethtool_tcpip4_spec {
656	ip4src	ipv4_addr
657	ip4dst	ipv4_addr
658	psrc	sock_port
659	pdst	sock_port
660	tos	int8
661}
662
663ethtool_ah_espip4_spec {
664	ip4src	ipv4_addr
665	ip4dst	ipv4_addr
666	spi	int32be
667	tos	int8
668}
669
670ethtool_usrip4_spec {
671	ip4src		ipv4_addr
672	ip4dst		ipv4_addr
673	l4_4_bytes	int32be
674	tos		int8
675	ip_ver		const[ETH_RX_NFC_IP4, int8]
676	proto		int8
677}
678
679ethtool_tcpip6_spec {
680	ip6src	ipv6_addr
681	ip6dst	ipv6_addr
682	psrc	sock_port
683	pdst	sock_port
684	tclass	int8
685}
686
687ethtool_ah_espip6_spec {
688	ip6src	ipv6_addr
689	ip6dst	ipv6_addr
690	spi	int32be
691	tclass	int8
692}
693
694ethtool_usrip6_spec {
695	ip6src		ipv6_addr
696	ip6dst		ipv6_addr
697	l4_4_bytes	int32be
698	tclass		int8
699	l4_proto	int8
700}
701
702ethhdr {
703	h_dest		mac_addr
704	h_source	mac_addr
705	h_proto		int16be
706} [packed]
707
708ethtool_rxfh_indir_flags = ETHTOOL_GRXFHINDIR, ETHTOOL_SRXFHINDIR
709
710ethtool_rxfh_indir {
711	cmd		flags[ethtool_rxfh_indir_flags, int32]
712	size		len[ring_index, int32]
713	ring_index	array[int32]
714}
715
716ethtool_rxfh_cmd_flags = ETHTOOL_GRSSH, ETHTOOL_SRSSH
717
718ethtool_rxfh {
719	cmd		flags[ethtool_rxfh_cmd_flags, int32]
720	rss_context	int32
721	indir_size	int32
722	key_size	int32
723	hfunc		int8
724	rsvd8		array[int8, 3]
725	rsvd32		int32
726	rss_config	array[int32]
727}
728
729ethtool_rx_ntuple {
730	cmd	const[ETHTOOL_SRXNTUPLE, int32]
731	fs	ethtool_rx_ntuple_flow_spec
732}
733
734ethtool_rx_ntuple_flow_spec_action_flags = ETHTOOL_RXNTUPLE_ACTION_DROP, ETHTOOL_RXNTUPLE_ACTION_CLEAR
735
736ethtool_rx_ntuple_flow_spec {
737	flow_type	flags[traffic_flow_types, int32]
738	h_u		ethtool_rx_ntuple_flow_spec_union
739	m_u		ethtool_rx_ntuple_flow_spec_union
740	vlan_tag	int16
741	vlan_tag_mask	int16
742	data		int64
743	data_mask	int64
744	action		flags[ethtool_rx_ntuple_flow_spec_action_flags, int32]
745}
746
747ethtool_rx_ntuple_flow_spec_union [
748	tcp_ip4_spec	ethtool_tcpip4_spec
749	udp_ip4_spec	ethtool_tcpip4_spec
750	sctp_ip4_spec	ethtool_tcpip4_spec
751	ah_ip4_spec	ethtool_ah_espip4_spec
752	esp_ip4_spec	ethtool_ah_espip4_spec
753	usr_ip4_spec	ethtool_usrip4_spec
754	ether_spec	ethhdr
755	hdata		array[int8, 72]
756]
757
758ethtool_flash {
759	cmd	const[ETHTOOL_FLASHDEV, int32]
760	region	int32
761	data	array[int8, ETHTOOL_FLASH_MAX_FILENAME]
762}
763
764ethtool_dump_cmd_flags = ETHTOOL_GET_DUMP_FLAG, ETHTOOL_GET_DUMP_DATA, ETHTOOL_SET_DUMP
765
766ethtool_dump {
767	cmd	flags[ethtool_dump_cmd_flags, int32]
768	version	int32
769	flag	int32
770	len	len[data, int32]
771	data	array[int8]
772}
773
774ethtool_gfeatures {
775	cmd		const[ETHTOOL_GFEATURES, int32]
776	size		len[features, int32]
777	features	array[ethtool_get_features_block]
778}
779
780ethtool_get_features_block {
781	available	int32
782	requested	int32
783	active		int32
784	never_changed	int32
785}
786
787ethtool_sfeatures {
788	cmd		const[ETHTOOL_SFEATURES, int32]
789	size		len[features, int32]
790	features	array[ethtool_set_features_block]
791}
792
793ethtool_set_features_block {
794	valid		int32
795	requested	int32
796}
797
798ethtool_ts_info {
799	cmd		const[ETHTOOL_GET_TS_INFO, int32]
800	so_timestamping	int32
801	phc_index	int32
802	tx_types	int32
803	tx_reserved	array[int32, 3]
804	rx_filters	int32
805	rx_reserved	array[int32, 3]
806}
807
808ethtool_per_queue_op {
809	cmd		const[ETHTOOL_PERQUEUE, int32]
810	sub_command	int32
811	queue_mask	array[int32, MAX_NUM_QUEUE]
812	data		array[int8]
813}
814
815ethtool_link_settings_cmd_flags = ETHTOOL_GLINKSETTINGS, ETHTOOL_SLINKSETTINGS
816
817ethtool_link_settings {
818	cmd			flags[ethtool_link_settings_cmd_flags, int32]
819	speed			int32
820	duplex			int8
821	port			int8
822	phy_address		int8
823	autoneg			int8
824	mdio_support		int8
825	eth_tp_mdix		int8
826	eth_tp_mdix_ctrl	int8
827	link_mode_masks_nwords	int8
828	reserved		array[int32, 8]
829	link_mode_masks		array[int32]
830}
831