Line data Source code
1 : #ifndef HEADER_fd_src_app_shared_commands_configure_fd_ethtool_ioctl_h
2 : #define HEADER_fd_src_app_shared_commands_configure_fd_ethtool_ioctl_h
3 :
4 : /* fd_ethtool_ioctl is a wrapper around the ethtool ioctl commands
5 : for managing network devices.
6 :
7 : Generic netlink is a more modern API for this, but not all operations
8 : are supported and it is more complicated. All the following
9 : operations seem to be supported by the older ioctl interface across
10 : the commonly used network drivers.
11 :
12 : - channels: Modern NICs generally support multiqueue, a feature that
13 : steers packets to multiple rx/tx queues, allowing CPU processing to
14 : be distributed. In the ethtool terminology a queue is called a
15 : channel.
16 :
17 : - rxfh: To route a packet into the multiple queues, the kernel will
18 : hash incoming packets and then lookup a queue index in the RXFH
19 : indirection table. The RXFH APIs allow us to modify this table
20 : to change how incoming packets are steered to various queues.
21 :
22 : - feature: Network devices have many feature flags to enable or
23 : disable particular behaviors. These APIs manage those features.
24 :
25 : - ntuple: n-tuple is a kernel name for hardware flow steering. These
26 : APIs allow us to create rules that match packets and perform actions
27 : on them, such as steering them towards specific queues.
28 :
29 : There is special handling in many of these functions for EOPNOTSUPP.
30 : This is to facilitate correct behavior on network devices that do not
31 : support these ioctl commands. For example, if the ioctl to get the
32 : number of channels is not supported, then we can assume the channel
33 : count is one and return success. Similarly, if the ioctl to manage
34 : ntuple rules is not supported, we can assume that the clear function
35 : is successful. */
36 :
37 : #include <linux/if.h>
38 :
39 : #include "../../../../util/fd_util_base.h"
40 :
41 : #define FD_ETHTOOL_MAX_RXFH_TABLE_CNT (32768)
42 :
43 0 : #define FD_ETHTOOL_FEATURE_NTUPLE "rx-ntuple-filter"
44 : #define FD_ETHTOOL_FEATURE_TXUDPSEG "tx-udp-segmentation"
45 : #define FD_ETHTOOL_FEATURE_TXGRESEG "tx-gre-segmentation"
46 : #define FD_ETHTOOL_FEATURE_TXGRECSUMSEG "tx-gre-csum-segmentation"
47 : #define FD_ETHTOOL_FEATURE_RXUDPGROFWD "rx-udp-gro-forwarding"
48 :
49 : struct fd_ethtool_ioctl {
50 : int fd;
51 : struct ifreq ifr;
52 : };
53 : typedef struct fd_ethtool_ioctl fd_ethtool_ioctl_t;
54 :
55 : FD_PROTOTYPES_BEGIN
56 :
57 : /* fd_ethtool_ioctl_init prepares the resources necessary for issuing
58 : ioctl system calls for the given network device. Returns ioc on
59 : success and NULL on failure. */
60 :
61 : fd_ethtool_ioctl_t *
62 : fd_ethtool_ioctl_init( fd_ethtool_ioctl_t * ioc,
63 : char const * device );
64 :
65 : /* fd_ethtool_ioctl_fini closes any resources used by ioc */
66 :
67 : void
68 : fd_ethtool_ioctl_fini( fd_ethtool_ioctl_t * ioc );
69 :
70 : /* fd_ethtool_ioctl_channels_set_num sets the number of active channels
71 : or queues. If 0 is given, it will set to the maximum number of
72 : queues allowed by the hardware. Returns nonzero on failure. */
73 :
74 : int
75 : fd_ethtool_ioctl_channels_set_num( fd_ethtool_ioctl_t * ioc,
76 : uint num /* 0 for max */ );
77 :
78 : /* fd_ethtool_ioctl_channels_get_num gets information about the state
79 : of hardware channels, including whether multiqueue is supported at
80 : all, how many queues are currently in use, and the max allowed.
81 : Returns nonzero on failure. */
82 :
83 : struct fd_ethtool_ioctl_channels {
84 : int supported;
85 : uint current;
86 : uint max;
87 : };
88 : typedef struct fd_ethtool_ioctl_channels fd_ethtool_ioctl_channels_t;
89 :
90 : int
91 : fd_ethtool_ioctl_channels_get_num( fd_ethtool_ioctl_t * ioc,
92 : fd_ethtool_ioctl_channels_t * channels );
93 :
94 : /* fd_ethtool_ioctl_rxfh_set_default sets the RXFH indirection table
95 : to its default state, which is to round-robin all hashes across all
96 : active queues. In this state, changing the active queue count will
97 : not be blocked by the RXFH table. Returns nonzero on failure. */
98 :
99 : int
100 : fd_ethtool_ioctl_rxfh_set_default( fd_ethtool_ioctl_t * ioc );
101 :
102 : /* fd_ethtool_ioctl_rxfh_set_suffix modifies the RXFH table to isolate
103 : a prefix of queues. The typical use case is to prevent general
104 : packets from landing on these queues so ntuple rules can steer
105 : special packets to them instead. start_idx is inclusive, so the
106 : table will be distributed across [start_idx, queue_cnt).
107 : Returns nonzero on failure. */
108 :
109 : int
110 : fd_ethtool_ioctl_rxfh_set_suffix( fd_ethtool_ioctl_t * ioc,
111 : uint start_idx );
112 :
113 : /* fd_ethtool_ioctl_rxfh_get_queue_cnt gets the maximum number of queues
114 : that the RXFH table can indirect to. Usually, this is equal to the
115 : current number of active channels. However, some devices have further
116 : restrictions and not all queues can be used. Returns nonzero on
117 : failure. */
118 :
119 : int
120 : fd_ethtool_ioctl_rxfh_get_queue_cnt( fd_ethtool_ioctl_t * ioc,
121 : uint * queue_cnt );
122 :
123 : /* fd_ethtool_ioctl_rxfh_get_table writes the current state of the
124 : RXFH table into the user-supplied table array, which must have space
125 : for FD_ETHTOOL_MAX_RXFH_TABLE_CNT elements. The actual element
126 : count of the table is stored in table_ele_cnt. Returns nonzero on
127 : failure. */
128 :
129 : int
130 : fd_ethtool_ioctl_rxfh_get_table( fd_ethtool_ioctl_t * ioc,
131 : uint * table,
132 : uint * table_ele_cnt );
133 :
134 : /* fd_ethtool_ioctl_feature_set enables or disables the network device
135 : feature with the given name. Returns nonzero on failure. */
136 :
137 : int
138 : fd_ethtool_ioctl_feature_set( fd_ethtool_ioctl_t * ioc,
139 : char const * name,
140 : int enabled );
141 :
142 : /* fd_ethtool_ioctl_feature_test sets enabled to 1 if the feature
143 : with the given name is enabled. Returns nonzero on failure. */
144 :
145 : int
146 : fd_ethtool_ioctl_feature_test( fd_ethtool_ioctl_t * ioc,
147 : char const * name,
148 : int * enabled );
149 :
150 : /* fd_ethtool_ioctl_feature_gro_set enables or disables the
151 : generic-receive-offload feature. Returns nonzero on failure. */
152 :
153 : int
154 : fd_ethtool_ioctl_feature_gro_set( fd_ethtool_ioctl_t * ioc,
155 : int enabled );
156 :
157 : /* fd_ethtool_ioctl_feature_gro_test sets enabled to 1 if the
158 : generic-receive-offload feature is enabled. Sets supported to 1
159 : if this feature is supported. Returns nonzero on failure. */
160 :
161 : int
162 : fd_ethtool_ioctl_feature_gro_test( fd_ethtool_ioctl_t * ioc,
163 : int * enabled,
164 : int * supported );
165 :
166 : /* fd_ethtool_ioctl_ntuple_clear deletes any active ntuple flow steering
167 : rules, which is the default state. Returns nonzero on failure. */
168 :
169 : int
170 : fd_ethtool_ioctl_ntuple_clear( fd_ethtool_ioctl_t * ioc );
171 :
172 : /* fd_ethtool_ioctl_ntuple_set_udp_dport installs a flow steering rule
173 : at the given rule_idx to route all UDP/IPv4 packets with the given
174 : destination port to the given queue_idx. Note that if a rule already
175 : exists at rule_idx, it may be overwritten.
176 :
177 : In order to facilitate load balancing flows across multiple queues,
178 : a nonzero rule_group_idx can be given. rule_group_cnt must be a
179 : nonzero power of 2. This forms a mask of the lowest N bits of the
180 : IPv4 source address and masked addresses matching rule_group_idx
181 : are steered to the given queue_idx. For example, we can create a
182 : group of rules for queue 0 where the lowest bit of the address is 0
183 : and a second set of rules for queue 1 where the lowest bit is 1.
184 :
185 : Returns nonzero on failure. */
186 :
187 : int
188 : fd_ethtool_ioctl_ntuple_set_udp_dport( fd_ethtool_ioctl_t * ioc,
189 : uint rule_idx,
190 : ushort dport,
191 : uint rule_group_idx,
192 : uint rule_group_cnt,
193 : uint queue_idx );
194 :
195 : /* fd_ethtool_ioctl_ntuple_set_gre installs a flow steering rule at the
196 : given rule_idx to route all GRE traffic (IP proto 47) to the given
197 : queue_idx. Note that if a rule already exists at rule_idx, it may
198 : be overwritten.
199 :
200 : Returns nonzero on failure. */
201 : int
202 : fd_ethtool_ioctl_ntuple_set_gre( fd_ethtool_ioctl_t * ioc,
203 : uint rule_idx,
204 : uint queue_idx );
205 :
206 : /* fd_ethtool_ioctl_ntuple_validate queries all ntuple rules and then
207 : sets valid to 1 if they match the expected set of rules for GRE to go
208 : to gre_queue (unless it is UINT_MAX), and the given UDP destination
209 : ports and the given number of queues (each queue should have a group
210 : of rules, one for each port in dports). In other words, this makes
211 : sure the existing rules are correct and that no other rules are
212 : active. If dports_cnt is zero and gre_queue is UINT_MAX, then this
213 : effectively checks whether any rules exist. Returns nonzero on
214 : failure (uncertain if valid or not). */
215 :
216 : int
217 : fd_ethtool_ioctl_ntuple_validate( fd_ethtool_ioctl_t * ioc,
218 : ushort const * dports,
219 : uint dports_cnt,
220 : uint queue_cnt,
221 : uint gre_queue,
222 : int * valid );
223 :
224 : /* fd_ethtool_ioctl_rxfh_set_flow_hash_udp4 configures the NIC to
225 : include source and destination ports in the RSS hash for UDP/IPv4
226 : flows. By default, many NICs only hash on IP addresses for UDP,
227 : which causes poor load balancing when traffic has a fixed destination
228 : IP and port (e.g. gossip). Including ports in the hash provides
229 : much better entropy and queue distribution. Returns nonzero on
230 : failure. */
231 :
232 : int
233 : fd_ethtool_ioctl_rxfh_set_flow_hash_udp4( fd_ethtool_ioctl_t * ioc );
234 :
235 : /* fd_ethtool_ioctl_is_modified returns nonzero if device has a nondefault
236 : channel count, a nondefault RSS indirection table, or ntuple rules.
237 : For a bond master, checks its members and returns nonzero if any is
238 : modified. Terminates on query failure. */
239 : int
240 : fd_ethtool_ioctl_is_modified( char const * device );
241 :
242 : /* fd_ethtool_ioctl_reset clears all ntuple rules and restores the maximum
243 : channel count and default RSS indirection table on device. Leaves
244 : the ntuple feature flag unchanged. For a bond master, resets each
245 : member. Skips devices already at defaults. Returns nonzero if any
246 : state changed. Terminates on failure. Call before configuring VFs
247 : or installing rules. */
248 : int
249 : fd_ethtool_ioctl_reset( char const * device );
250 :
251 : FD_PROTOTYPES_END
252 :
253 : #endif /* HEADER_fd_src_app_shared_commands_configure_fd_ethtool_ioctl_h */
|