Merge "tldk_test: added copy command to makefile to make test_scapy_gen.py visible"
[tldk.git] / lib / libtle_l4p / tcp_tx_seg.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 _TCP_TX_SEG_H_
17 #define _TCP_TX_SEG_H_
18
19 #ifdef __cplusplus
20 extern "C" {
21 #endif
22
23 static inline void
24 free_segments(struct rte_mbuf *mb[], uint32_t num)
25 {
26         uint32_t i;
27
28         for (i = 0; i != num; i++)
29                 rte_pktmbuf_free(mb[i]);
30 }
31
32 static inline int32_t
33 tcp_segmentation(struct rte_mbuf *mbin, struct rte_mbuf *mbout[], uint16_t num,
34         const struct tle_dest *dst, uint16_t mss)
35 {
36         struct rte_mbuf *in_seg = NULL;
37         uint32_t nbseg, in_seg_data_pos;
38         uint32_t more_in_segs;
39
40         in_seg = mbin;
41         in_seg_data_pos = 0;
42         nbseg = 0;
43
44         /* Check that pkts_out is big enough to hold all fragments */
45         if (mss * num < (uint16_t)mbin->pkt_len)
46                 return -ENOSPC;
47
48         more_in_segs = 1;
49         while (more_in_segs) {
50                 struct rte_mbuf *out_pkt = NULL, *out_seg_prev = NULL;
51                 uint32_t more_out_segs;
52
53                 /* Allocate direct buffer */
54                 out_pkt = rte_pktmbuf_alloc(dst->head_mp);
55                 if (out_pkt == NULL) {
56                         free_segments(mbout, nbseg);
57                         return -ENOMEM;
58                 }
59
60                 out_seg_prev = out_pkt;
61                 more_out_segs = 1;
62                 while (more_out_segs && more_in_segs) {
63                         struct rte_mbuf *out_seg = NULL;
64                         uint32_t len;
65
66                         /* Allocate indirect buffer */
67                         out_seg = rte_pktmbuf_alloc(dst->head_mp);
68                         if (out_seg == NULL) {
69                                 rte_pktmbuf_free(out_pkt);
70                                 free_segments(mbout, nbseg);
71                                 return -ENOMEM;
72                         }
73                         out_seg_prev->next = out_seg;
74                         out_seg_prev = out_seg;
75
76                         /* Prepare indirect buffer */
77                         rte_pktmbuf_attach(out_seg, in_seg);
78                         len = mss;
79                         if (len > (in_seg->data_len - in_seg_data_pos))
80                                 len = in_seg->data_len - in_seg_data_pos;
81
82                         out_seg->data_off = in_seg->data_off + in_seg_data_pos;
83                         out_seg->data_len = (uint16_t)len;
84                         out_pkt->pkt_len = (uint16_t)(len + out_pkt->pkt_len);
85                         out_pkt->nb_segs += 1;
86                         in_seg_data_pos += len;
87
88                         /* Current output packet (i.e. fragment) done ? */
89                         if (out_pkt->pkt_len >= mss)
90                                 more_out_segs = 0;
91
92                         /* Current input segment done ? */
93                         if (in_seg_data_pos == in_seg->data_len) {
94                                 in_seg = in_seg->next;
95                                 in_seg_data_pos = 0;
96
97                                 if (in_seg == NULL)
98                                         more_in_segs = 0;
99                         }
100                 }
101
102                 /* Write the segment to the output list */
103                 mbout[nbseg] = out_pkt;
104                 nbseg++;
105         }
106
107         return nbseg;
108 }
109
110 #ifdef __cplusplus
111 }
112 #endif
113
114 #endif /* _TCP_TX_SEG_H_ */