Revert "l4p/tcp: introduce tle_tcp_stream_establish() API"
[tldk.git] / lib / libtle_l4p / stream.h
1 /*
2  * Copyright (c) 2016-2017  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 _STREAM_H_
17 #define _STREAM_H_
18
19 #include "ctx.h"
20
21 #ifdef __cplusplus
22 extern "C" {
23 #endif
24
25 /*
26  * Common structure that must be present as first field in all partcular
27  * L4 (UDP/TCP, etc.) stream implementations.
28  */
29 struct tle_stream {
30
31         STAILQ_ENTRY(tle_stream) link;
32         struct tle_ctx *ctx;
33
34         uint8_t type;          /* TLE_V4 or TLE_V6 */
35
36         /* Stream address information. */
37         union l4_ports port;
38         union l4_ports pmsk;
39
40         union {
41                 struct {
42                         union ipv4_addrs addr;
43                         union ipv4_addrs mask;
44                 } ipv4;
45                 struct {
46                         union ipv6_addrs addr;
47                         union ipv6_addrs mask;
48                 } ipv6;
49         };
50 };
51
52 static inline uint32_t
53 get_streams(struct tle_ctx *ctx, struct tle_stream *s[], uint32_t num)
54 {
55         struct tle_stream *p;
56         uint32_t i, n;
57
58         rte_spinlock_lock(&ctx->streams.lock);
59
60         n = RTE_MIN(ctx->streams.nb_free, num);
61         for (i = 0, p = STAILQ_FIRST(&ctx->streams.free);
62                         i != n;
63                         i++, p = STAILQ_NEXT(p, link))
64                 s[i] = p;
65
66         if (p == NULL)
67                 /* we retrieved all free entries */
68                 STAILQ_INIT(&ctx->streams.free);
69         else
70                 STAILQ_FIRST(&ctx->streams.free) = p;
71
72         ctx->streams.nb_free -= n;
73         rte_spinlock_unlock(&ctx->streams.lock);
74         return n;
75 }
76
77 static inline struct tle_stream *
78 get_stream(struct tle_ctx *ctx)
79 {
80         struct tle_stream *s;
81
82         s = NULL;
83         if (ctx->streams.nb_free == 0)
84                 return s;
85
86         get_streams(ctx, &s, 1);
87         return s;
88 }
89
90 static inline void
91 put_stream(struct tle_ctx *ctx, struct tle_stream *s, int32_t head)
92 {
93         s->type = TLE_VNUM;
94         rte_spinlock_lock(&ctx->streams.lock);
95         if (head != 0)
96                 STAILQ_INSERT_HEAD(&ctx->streams.free, s, link);
97         else
98                 STAILQ_INSERT_TAIL(&ctx->streams.free, s, link);
99         ctx->streams.nb_free++;
100         rte_spinlock_unlock(&ctx->streams.lock);
101 }
102
103 /* calculate number of drbs per stream. */
104 static inline uint32_t
105 calc_stream_drb_num(const struct tle_ctx *ctx, uint32_t obj_num)
106 {
107         uint32_t num;
108
109         num = (ctx->prm.max_stream_sbufs + obj_num - 1) / obj_num;
110         num = num + num / 2;
111         num = RTE_MAX(num, RTE_DIM(ctx->dev) + 1);
112         return num;
113 }
114
115 static inline uint32_t
116 drb_nb_elem(const struct tle_ctx *ctx)
117 {
118         return (ctx->prm.send_bulk_size != 0) ?
119                 ctx->prm.send_bulk_size : MAX_PKT_BURST;
120 }
121
122 static inline int32_t
123 stream_get_dest(struct tle_stream *s, const void *dst_addr,
124         struct tle_dest *dst)
125 {
126         int32_t rc;
127         const struct in_addr *d4;
128         const struct in6_addr *d6;
129         struct tle_ctx *ctx;
130         struct tle_dev *dev;
131
132         ctx = s->ctx;
133
134         /* it is here just to keep gcc happy. */
135         d4 = NULL;
136         d6 = NULL;
137
138         if (s->type == TLE_V4) {
139                 d4 = dst_addr;
140                 rc = ctx->prm.lookup4(ctx->prm.lookup4_data, d4, dst);
141         } else if (s->type == TLE_V6) {
142                 d6 = dst_addr;
143                 rc = ctx->prm.lookup6(ctx->prm.lookup6_data, d6, dst);
144         } else
145                 rc = -ENOENT;
146
147         if (rc < 0 || dst->dev == NULL || dst->dev->ctx != ctx)
148                 return -ENOENT;
149
150         dev = dst->dev;
151         dst->ol_flags = dev->tx.ol_flags[s->type];
152
153         if (s->type == TLE_V4) {
154                 struct rte_ipv4_hdr *l3h;
155                 l3h = (struct rte_ipv4_hdr *)(dst->hdr + dst->l2_len);
156                 l3h->src_addr = dev->prm.local_addr4.s_addr;
157                 l3h->dst_addr = d4->s_addr;
158         } else {
159                 struct rte_ipv6_hdr *l3h;
160                 l3h = (struct rte_ipv6_hdr *)(dst->hdr + dst->l2_len);
161                 rte_memcpy(l3h->src_addr, &dev->prm.local_addr6,
162                         sizeof(l3h->src_addr));
163                 rte_memcpy(l3h->dst_addr, d6, sizeof(l3h->dst_addr));
164         }
165
166         return dev - ctx->dev;
167 }
168
169 #ifdef __cplusplus
170 }
171 #endif
172
173 #endif /* _STREAM_H_ */