add list of blocked ports for IPv6
[tldk.git] / lib / libtle_udp / tle_udp_impl.h
1 /*
2  * Copyright (c) 2016  Intel Corporation.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15
16 #ifndef _TLE_UDP_IMPL_H_
17 #define _TLE_UDP_IMPL_H_
18
19 #include <stdint.h>
20 #include <sys/socket.h>
21 #include <netinet/in.h>
22 #include <rte_common.h>
23 #include <rte_mbuf.h>
24
25 #ifdef __cplusplus
26 extern "C" {
27 #endif
28
29 /**
30  * <udp_ctx>  - each such ctx represents an 'independent copy of the stack'.
31  * It owns set of <udp_stream>s and <udp_dev>s entities and provides
32  * (de)multiplexing input/output packets from/into UDP devices into/from
33  * UDP streams.
34  * <udp_dev> is an abstraction for the underlying device, that is able
35  * to RX/TX packets and may provide some HW offload capabilities.
36  * It is a user responsibility to add to the <udp_ctx> all <udp_dev>s,
37  * that context has to manage, before starting to do stream operations
38  * (open/send/recv,close) over that context.
39  * Right now adding/deleting <udp_dev>s to the context with open
40  * streams is not supported.
41  * <udp_stream> represents an UDP endpoint <addr, port> and is an analogy to
42  * socket entity.
43  * As with a socket, there are ability to do recv/send over it.
44  * <udp_stream> belongs to particular <udp_ctx> but is visible globally across
45  * the process, i.e. any thread within the process can do recv/send over it
46  * without any further synchronisation.
47  * While 'upper' layer API is thread safe, lower layer API (rx_bulk/tx_bulk)
48  * is not thread safe and is not supposed to be run on multiple threads
49  * in parallel.
50  * So single thread can drive multiple <udp_ctx>s and do IO for them,
51  * but multiple threads can't drive same <udp_ctx> without some
52  * explicit synchronization.
53  */
54
55 struct tle_udp_ctx;
56 struct tle_udp_dev;
57
58 /**
59  * Blocked UDP ports info.
60  */
61 struct tle_bl_port {
62         uint32_t nb_port; /**< number of blocked ports. */
63         const uint16_t *port; /**< list of blocked ports. */
64 };
65
66 /**
67  * UDP device parameters.
68  */
69 struct tle_udp_dev_param {
70         uint32_t rx_offload; /**< DEV_RX_OFFLOAD_* supported. */
71         uint32_t tx_offload; /**< DEV_TX_OFFLOAD_* supported. */
72         struct in_addr local_addr4;  /**< local IPv4 address assigned. */
73         struct in6_addr local_addr6; /**< local IPv6 address assigned. */
74         struct tle_bl_port bl4; /**< blocked ports for IPv4 address. */
75         struct tle_bl_port bl6; /**< blocked ports for IPv4 address. */
76 };
77
78 #define TLE_UDP_MAX_HDR 0x60
79
80 struct tle_udp_dest {
81         struct rte_mempool *head_mp; /**< MP for fragment feaders. */
82         struct tle_udp_dev *dev;     /**< device to send packets through. */
83         uint16_t mtu;                /**< MTU for given destination. */
84         uint8_t l2_len;  /**< L2 header lenght. */
85         uint8_t l3_len;  /**< L3 header lenght. */
86         uint8_t hdr[TLE_UDP_MAX_HDR]; /**< L2/L3 headers. */
87 };
88
89 /**
90  * UDP context creation parameters.
91  */
92 struct tle_udp_ctx_param {
93         int32_t socket_id;         /**< socket ID to allocate memory for. */
94         uint32_t max_streams;      /**< max number of streams in context. */
95         uint32_t max_stream_rbufs; /**< max recv mbufs per stream. */
96         uint32_t max_stream_sbufs; /**< max send mbufs per stream. */
97         uint32_t send_bulk_size;   /**< expected # of packets per send call. */
98
99         int (*lookup4)(void *opaque, const struct in_addr *addr,
100                 struct tle_udp_dest *res);
101         /**< will be called by send() to get IPv4 packet destination info. */
102         void *lookup4_data;
103         /**< opaque data pointer for lookup4() callback. */
104
105         int (*lookup6)(void *opaque, const struct in6_addr *addr,
106                 struct tle_udp_dest *res);
107         /**< will be called by send() to get IPv6 packet destination info. */
108         void *lookup6_data;
109         /**< opaque data pointer for lookup6() callback. */
110 };
111
112 /**
113  * create UDP context.
114  * @param ctx_prm
115  *   Parameters used to create and initialise the UDP context.
116  * @return
117  *   Pointer to UDP context structure that can be used in future UDP
118  *   operations, or NULL on error, with error code set in rte_errno.
119  *   Possible rte_errno errors include:
120  *   - EINVAL - invalid parameter passed to function
121  *   - ENOMEM - out of memory
122  */
123 struct tle_udp_ctx *
124 tle_udp_create(const struct tle_udp_ctx_param *ctx_prm);
125
126 /**
127  * Destroy given UDP context.
128  *
129  * @param ctx
130  *   UDP context to destroy
131  */
132 void tle_udp_destroy(struct tle_udp_ctx *ctx);
133
134 /**
135  * Add new device into the given UDP context.
136  * This function is not multi-thread safe.
137  *
138  * @param ctx
139  *   UDP context to add new device into.
140  * @param dev_prm
141  *   Parameters used to create and initialise new device inside the
142  *   UDP context.
143  * @return
144  *   Pointer to UDP device structure that can be used in future UDP
145  *   operations, or NULL on error, with error code set in rte_errno.
146  *   Possible rte_errno errors include:
147  *   - EINVAL - invalid parameter passed to function
148  *   - ENODEV - max possible value of open devices is reached
149  *   - ENOMEM - out of memory
150  */
151 struct tle_udp_dev *
152 tle_udp_add_dev(struct tle_udp_ctx *ctx,
153                 const struct tle_udp_dev_param *dev_prm);
154
155 /**
156  * Remove and destroy previously added device from the given UDP context.
157  * This function is not multi-thread safe.
158  *
159  * @param dev
160  *   UDP device to remove and destroy.
161  * @return
162  *   zero on successful completion.
163  *   - -EINVAL - invalid parameter passed to function
164  */
165 int tle_udp_del_dev(struct tle_udp_dev *dev);
166
167 /**
168  * Flags to the UDP context that destinations info might be changed,
169  * so if it has any destinations data cached, then
170  * it has to be invalidated.
171  * @param ctx
172  *   UDP context to invalidate.
173  */
174 void tle_udp_ctx_invalidate(struct tle_udp_ctx *ctx);
175
176 struct tle_udp_stream;
177
178 /**
179  * Stream asynchronous notification mechanisms:
180  * a) recv/send callback.
181  * Stream recv/send notification callbacks behaviour is edge-triggered (ET).
182  * recv callback will be invoked if stream receive buffer was empty and
183  * new packet(s) have arrived.
184  * send callback will be invoked when stream send buffer was full,
185  * and some packets belonging to that stream were sent
186  * (part of send buffer became free again).
187  * Note that both recv and send callbacks are called with sort of read lock
188  * held on that stream. So it is not permitted to call stream_close()
189  * within the callback function. Doing that would cause a deadlock.
190  * While it is allowed to call stream send/recv functions within the
191  * callback, it is not recommended: callback function will be invoked
192  * within tle_udp_rx_bulk/tle_udp_tx_bulk context and some heavy processing
193  * within the callback functions might cause performance degradation
194  * or even loss of packets for further streams.
195  * b) recv/send event.
196  * Stream recv/send events behavour is level-triggered (LT).
197  * receive event will be raised by either
198  * tle_udp_rx_burst() or tle_udp_stream_recv() as long as there are any
199  * remaining packets inside stream receive buffer.
200  * send event will be raised by either
201  * tle_udp_tx_burst() or tle_udp_stream_send() as long as there are any
202  * free space inside stream send buffer.
203  * Note that callback and event are mutually exclusive on <stream, op> basis.
204  * It is not possible to  open a stream with both recv event and callback
205  * specified.
206  * Though it is possible to open a stream with recv callback and send event,
207  * or visa-versa.
208  * If the user doesn't need any notification mechanism for that stream,
209  * both event and callback could be set to zero.
210  */
211
212 /**
213  * Stream recv/send callback function and data.
214  */
215 struct tle_udp_stream_cb {
216         void (*func)(void *, struct tle_udp_stream *);
217         void *data;
218 };
219
220 struct tle_event;
221
222 /**
223  * UDP stream creation parameters.
224  */
225 struct tle_udp_stream_param {
226         struct sockaddr_storage local_addr;  /**< stream local address. */
227         struct sockaddr_storage remote_addr; /**< stream remote address. */
228
229         /* _cb and _ev are mutually exclusive */
230         struct tle_event *recv_ev;          /**< recv event to use.  */
231         struct tle_udp_stream_cb recv_cb;   /**< recv callback to use. */
232
233         struct tle_event *send_ev;          /**< send event to use. */
234         struct tle_udp_stream_cb send_cb;   /**< send callback to use. */
235 };
236
237 /**
238  * create a new stream within given UDP context.
239  * @param ctx
240  *   UDP context to create new stream within.
241  * @param prm
242  *   Parameters used to create and initialise the new stream.
243  * @return
244  *   Pointer to UDP stream structure that can be used in future UDP API calls,
245  *   or NULL on error, with error code set in rte_errno.
246  *   Possible rte_errno errors include:
247  *   - EINVAL - invalid parameter passed to function
248  *   - ENOFILE - max limit of open streams reached for that context
249  */
250 struct tle_udp_stream *
251 tle_udp_stream_open(struct tle_udp_ctx *ctx,
252         const struct tle_udp_stream_param *prm);
253
254 /**
255  * close an open stream.
256  * All packets still remaining in stream receive buffer will be freed.
257  * All packets still remaining in stream transmit buffer will be kept
258  * for father transmission.
259  * @param s
260  *   Pointer to the stream to close.
261  * @return
262  *   zero on successful completion.
263  *   - -EINVAL - invalid parameter passed to function
264  */
265 int tle_udp_stream_close(struct tle_udp_stream *s);
266
267 /**
268  * get open stream parameters.
269  * @param s
270  *   Pointer to the stream.
271  * @return
272  *   zero on successful completion.
273  *   - EINVAL - invalid parameter passed to function
274  */
275 int
276 tle_udp_stream_get_param(const struct tle_udp_stream *s,
277         struct tle_udp_stream_param *prm);
278
279 /**
280  * Take input mbufs and distribute them to open UDP streams.
281  * expects that for each input packet:
282  *      - l2_len, l3_len, l4_len are setup correctly
283  *      - (packet_type & (RTE_PTYPE_L3_IPV4 | RTE_PTYPE_L3_IPV6)) != 0,
284  *      - (packet_type & RTE_PTYPE_L4_UDP) != 0,
285  * During delivery L3/L4 checksums will be verified
286  * (either relies on HW offload or in SW).
287  * This function is not multi-thread safe.
288  * @param dev
289  *   UDP device the packets were received from.
290  * @param pkt
291  *   The burst of input packets that need to be processed.
292  * @param rp
293  *   The array that will contain pointers of unprocessed packets at return.
294  *   Should contain at least *num* elements.
295  * @param rc
296  *   The array that will contain error code for corresponding rp[] entry:
297  *   - ENOENT - no open stream matching this packet.
298  *   - ENOBUFS - receive buffer of the destination stream is full.
299  *   Should contain at least *num* elements.
300  * @param num
301  *   Number of elements in the *pkt* input array.
302  * @return
303  *   number of packets delivered to the UDP streams.
304  */
305 uint16_t tle_udp_rx_bulk(struct tle_udp_dev *dev, struct rte_mbuf *pkt[],
306         struct rte_mbuf *rp[], int32_t rc[], uint16_t num);
307
308 /**
309  * Fill *pkt* with pointers to the packets that have to be transmitted
310  * over given UDP device.
311  * Output packets have to be ready to be passed straight to rte_eth_tx_burst()
312  * without any extra processing.
313  * UDP/IPv4 checksum either already calculated or appropriate mbuf fields set
314  * properly for HW offload.
315  * This function is not multi-thread safe.
316  * @param dev
317  *   UDP device the output packets will be transmitted over.
318  * @param pkt
319  *   An array of pointers to *rte_mbuf* structures that
320  *   must be large enough to store up to *num* pointers in it.
321  * @param num
322  *   Number of elements in the *pkt* array.
323  * @return
324  *   number of of entries filled inside *pkt* array.
325  */
326 uint16_t tle_udp_tx_bulk(struct tle_udp_dev *dev, struct rte_mbuf *pkt[],
327         uint16_t num);
328
329 /*
330  * return up to *num* mbufs that was received for given UDP stream.
331  * For each returned mbuf:
332  * data_off set to the start of the packet's UDP data
333  * l2_len, l3_len, l4_len are setup properly
334  * (so user can still extract L2/L3 address info if needed)
335  * packet_type RTE_PTYPE_L2/L3/L4 bits are setup properly.
336  * L3/L4 checksum is verified.
337  * Packets with invalid L3/L4 checksum will be silently dropped.
338  * @param s
339  *   UDP stream to receive packets from.
340  * @param pkt
341  *   An array of pointers to *rte_mbuf* structures that
342  *   must be large enough to store up to *num* pointers in it.
343  * @param num
344  *   Number of elements in the *pkt* array.
345  * @return
346  *   number of of entries filled inside *pkt* array.
347  */
348 uint16_t tle_udp_stream_recv(struct tle_udp_stream *s, struct rte_mbuf *pkt[],
349         uint16_t num);
350
351 /**
352  * Consume and queue up to *num* packets, that will be sent eventually
353  * by tle_udp_tx_bulk().
354  * If *dst_addr* is NULL, then default remote address associated with that
355  * stream (if any) will be used.
356  * The main purpose of that function is to determine over which UDP dev
357  * given packets have to be sent out and do necessary preparations for that.
358  * Based on the *dst_addr* it does route lookup, fills L2/L3/L4 headers,
359  * and, if necessary, fragments packets.
360  * Depending on the underlying device information, it either does
361  * IP/UDP checksum calculations in SW or sets mbuf TX checksum
362  * offload fields properly.
363  * For each input mbuf the following conditions have to be met:
364  *      - data_off point to the start of packet's UDP data.
365  *      - there is enough header space to prepend L2/L3/L4 headers.
366  * @param s
367  *   UDP stream to send packets over.
368  * @param pkt
369  *   The burst of output packets that need to be send.
370  * @param num
371  *   Number of elements in the *pkt* array.
372  * @param dst_addr
373  *   Destination address to send packets to.
374  * @return
375  *   number of packets successfully queued in the stream send buffer.
376  */
377 uint16_t tle_udp_stream_send(struct tle_udp_stream *s, struct rte_mbuf *pkt[],
378         uint16_t num, const struct sockaddr *dst_addr);
379
380 #ifdef __cplusplus
381 }
382 #endif
383
384 #endif /* _TLE_UDP_IMPL_H_ */