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:
7 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 #ifndef _TCP_TX_SEG_H_
17 #define _TCP_TX_SEG_H_
24 free_segments(struct rte_mbuf *mb[], uint32_t num)
28 for (i = 0; i != num; i++)
29 rte_pktmbuf_free(mb[i]);
33 tcp_segmentation(struct rte_mbuf *mbin, struct rte_mbuf *mbout[], uint16_t num,
34 const struct tle_dest *dst, uint16_t mss)
36 struct rte_mbuf *in_seg = NULL;
37 uint32_t nbseg, in_seg_data_pos;
38 uint32_t more_in_segs;
44 /* Check that pkts_out is big enough to hold all fragments */
45 if (mss * num < (uint16_t)mbin->pkt_len)
49 while (more_in_segs) {
50 struct rte_mbuf *out_pkt = NULL, *out_seg_prev = NULL;
51 uint32_t more_out_segs;
53 /* Allocate direct buffer */
54 out_pkt = rte_pktmbuf_alloc(dst->head_mp);
55 if (out_pkt == NULL) {
56 free_segments(mbout, nbseg);
60 out_seg_prev = out_pkt;
62 while (more_out_segs && more_in_segs) {
63 struct rte_mbuf *out_seg = NULL;
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);
73 out_seg_prev->next = out_seg;
74 out_seg_prev = out_seg;
76 /* Prepare indirect buffer */
77 rte_pktmbuf_attach(out_seg, in_seg);
79 if (len > (in_seg->data_len - in_seg_data_pos))
80 len = in_seg->data_len - in_seg_data_pos;
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;
88 /* Current output packet (i.e. fragment) done ? */
89 if (out_pkt->pkt_len >= mss)
92 /* Current input segment done ? */
93 if (in_seg_data_pos == in_seg->data_len) {
94 in_seg = in_seg->next;
102 /* Write the segment to the output list */
103 mbout[nbseg] = out_pkt;
114 #endif /* _TCP_TX_SEG_H_ */