tcp_l2_buf_fill_headers() is always followed by updating the payload IOV entry to the correct length of the frame. It already needs knowledge of the frame/IOV layout, so we might as well perform that update inside the function. Rename it to tcp_buf_make_frame() to reflect its expanded duties. While we're there use some temporaries to make our dissection of the IOV a bit clearer. Signed-off-by: David Gibson <david(a)gibson.dropbear.id.au> --- tcp_buf.c | 46 +++++++++++++++++++++------------------------- 1 file changed, 21 insertions(+), 25 deletions(-) diff --git a/tcp_buf.c b/tcp_buf.c index dbe565c..deb7be4 100644 --- a/tcp_buf.c +++ b/tcp_buf.c @@ -257,35 +257,38 @@ void tcp_payload_flush(const struct ctx *c) } /** - * tcp_buf_fill_headers() - Fill 802.3, IP, TCP headers in pre-cooked buffers + * tcp_buf_make_frame() - Adjust IOV, complete headers to build a TCP frame * @conn: Connection pointer * @iov: Pointer to an array of iovec of TCP pre-cooked buffers * @dlen: TCP payload length * @check: Checksum, if already known * @seq: Sequence number for this segment * @no_tcp_csum: Do not set TCP checksum - * - * Return: IP payload length, host order */ -static size_t tcp_l2_buf_fill_headers(const struct tcp_tap_conn *conn, - struct iovec *iov, size_t dlen, - const uint16_t *check, uint32_t seq, - bool no_tcp_csum) +static void tcp_buf_make_frame(const struct tcp_tap_conn *conn, + struct iovec *iov, size_t dlen, + const uint16_t *check, uint32_t seq, + bool no_tcp_csum) { + struct tcp_payload_t *payload = iov[TCP_IOV_PAYLOAD].iov_base; + struct tap_hdr *taph = iov[TCP_IOV_TAP].iov_base; const struct flowside *tapside = TAPFLOW(conn); const struct in_addr *a4 = inany_v4(&tapside->oaddr); + size_t l4len; if (a4) { - return tcp_fill_headers4(conn, iov[TCP_IOV_TAP].iov_base, - iov[TCP_IOV_IP].iov_base, - iov[TCP_IOV_PAYLOAD].iov_base, dlen, - check, seq, no_tcp_csum); + struct iphdr *iph = iov[TCP_IOV_IP].iov_base; + + l4len = tcp_fill_headers4(conn, taph, iph, payload, dlen, + check, seq, no_tcp_csum); + } else { + struct ipv6hdr *ip6h = iov[TCP_IOV_IP].iov_base; + + l4len = tcp_fill_headers6(conn, taph, ip6h, payload, dlen, + seq, no_tcp_csum); } - return tcp_fill_headers6(conn, iov[TCP_IOV_TAP].iov_base, - iov[TCP_IOV_IP].iov_base, - iov[TCP_IOV_PAYLOAD].iov_base, dlen, - seq, no_tcp_csum); + iov[TCP_IOV_PAYLOAD].iov_len = l4len; } /** @@ -301,7 +304,6 @@ int tcp_buf_send_flag(const struct ctx *c, struct tcp_tap_conn *conn, int flags) struct tcp_flags_t *payload; struct iovec *iov; size_t optlen; - size_t l4len; uint32_t seq; int ret; @@ -323,8 +325,7 @@ int tcp_buf_send_flag(const struct ctx *c, struct tcp_tap_conn *conn, int flags) return ret; } - l4len = tcp_l2_buf_fill_headers(conn, iov, optlen, NULL, seq, false); - iov[TCP_IOV_PAYLOAD].iov_len = l4len; + tcp_buf_make_frame(conn, iov, optlen, NULL, seq, false); if (flags & DUP_ACK) { struct iovec *dup_iov; @@ -368,7 +369,6 @@ static void tcp_data_to_tap(const struct ctx *c, struct tcp_tap_conn *conn, ssize_t dlen, int no_csum, uint32_t seq) { struct iovec *iov; - size_t l4len; conn->seq_to_tap = seq + dlen; @@ -384,18 +384,14 @@ static void tcp_data_to_tap(const struct ctx *c, struct tcp_tap_conn *conn, tcp4_frame_conns[tcp4_payload_used] = conn; iov = tcp4_l2_iov[tcp4_payload_used++]; - l4len = tcp_l2_buf_fill_headers(conn, iov, dlen, check, seq, - false); - iov[TCP_IOV_PAYLOAD].iov_len = l4len; + tcp_buf_make_frame(conn, iov, dlen, check, seq, false); if (tcp4_payload_used > TCP_FRAMES_MEM - 1) tcp_payload_flush(c); } else if (CONN_V6(conn)) { tcp6_frame_conns[tcp6_payload_used] = conn; iov = tcp6_l2_iov[tcp6_payload_used++]; - l4len = tcp_l2_buf_fill_headers(conn, iov, dlen, NULL, seq, - false); - iov[TCP_IOV_PAYLOAD].iov_len = l4len; + tcp_buf_make_frame(conn, iov, dlen, NULL, seq, false); if (tcp6_payload_used > TCP_FRAMES_MEM - 1) tcp_payload_flush(c); } -- 2.47.0