1 // Copyright 2017 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #pragma once
6 
7 #include <zircon/device/ioctl.h>
8 #include <zircon/device/ioctl-wrapper.h>
9 
10 #include <stdint.h>
11 
12 #define IOCTL_ETHERTAP_CONFIG \
13     IOCTL(IOCTL_KIND_GET_HANDLE, IOCTL_FAMILY_ETHERTAP, 1)
14 
15 #define ETHERTAP_MAX_NAME_LEN 31
16 #define ETHERTAP_MAX_MTU 2000
17 
18 // Ethertap signals on the socket are used to indicate link status. It is an error to assert that a
19 // device is both online and offline; the device will be shutdown. A device is in the offline state
20 // when it is created.
21 // ZX_USER_SIGNAL_7 is reserved for internal ethertap use.
22 #define ETHERTAP_SIGNAL_ONLINE  ZX_USER_SIGNAL_0
23 #define ETHERTAP_SIGNAL_OFFLINE ZX_USER_SIGNAL_1
24 
25 // Enables tracing of the ethertap device itself
26 #define ETHERTAP_OPT_TRACE         (1u << 0)
27 #define ETHERTAP_OPT_TRACE_PACKETS (1u << 1)
28 // Report EthmacSetParam() over Control channel of socket, and return success from EthmacSetParam().
29 // If this option is not set, EthmacSetParam() will return ZX_ERR_NOT_SUPPORTED.
30 #define ETHERTAP_OPT_REPORT_PARAM  (1u << 2)
31 
32 // An ethertap device has a fixed mac address and mtu, and transfers ethernet frames over the
33 // returned data socket. To destroy the device, close the socket.
34 typedef struct ethertap_ioctl_config {
35     // The name of this tap device.
36     char name[ETHERTAP_MAX_NAME_LEN + 1];
37 
38     // Ethertap options (see above).
39     uint32_t options;
40 
41     // Ethernet protocol fields for the ethermac device.
42     uint32_t features;
43     uint32_t mtu;
44     uint8_t mac[6];
45 } ethertap_ioctl_config_t;
46 
47 // A header is prepended to socket communication from ethertap. This tells whether
48 // the subsequent bytes are a packet, a setparam report, etc.
49 
50 #define ETHERTAP_MSG_PACKET (1u)
51 #define ETHERTAP_MSG_PARAM_REPORT (2u)
52 
53 typedef struct ethertap_socket_header {
54     uint32_t type;
55     int32_t info; // Might not be used yet; also there for 64-bit alignment
56 } ethertap_socket_header_t;
57 
58 // If EthmacSetParam() reporting is requested, this struct is written to the Control
59 // channel of the ethertap socket each time the function is called.
60 //
61 // CAUTION: The Control channel holds only one piece of data at a time. If EthmacSetParam()
62 // is called more than once without reading the struct, structs 2..N will be lost: consecutive
63 // calls of EthmacSetParam() without reading this struct will retain the very first result only.
64 // EthmacSetParam() will still return ZX_OK in that case, since it is a limitation of test
65 // infrastructure and not a simulated failure of the ethmac device under test.
66 
67 #define SETPARAM_REPORT_DATA_SIZE 64
68 
69 typedef struct ethertap_setparam_report {
70     uint32_t param;
71     int32_t value;
72     // As needed for debug/test of individual params, the next two fields can be used
73     // to return a hash or slice of the data sent in the ioctl data field.
74     uint8_t data[SETPARAM_REPORT_DATA_SIZE];
75     size_t data_length;
76 } ethertap_setparam_report_t;
77 
78 // ssize_t ioctl_ethertap_config(int fd, const ethertap_ioctl_config_t* in, zx_handle_t* out);
79 IOCTL_WRAPPER_INOUT(ioctl_ethertap_config, IOCTL_ETHERTAP_CONFIG, \
80         ethertap_ioctl_config_t, zx_handle_t);
81