+ vu_set_vnethdr(vdev, flags_elem[0].in_sg[0].iov_base, 1);
+
+ eh = vu_eth(flags_elem[0].in_sg[0].iov_base);
+
+ memcpy(eh->h_dest, c->guest_mac, sizeof(eh->h_dest));
+ memcpy(eh->h_source, c->our_tap_mac, sizeof(eh->h_source));
+
+ if (CONN_V4(conn)) {
+ struct tcp_payload_t *payload;
+ struct iphdr *iph;
+ uint32_t seq;
+
+ eh->h_proto = htons(ETH_P_IP);
+
+ iph = vu_ip(flags_elem[0].in_sg[0].iov_base);
+ *iph = (struct iphdr)L2_BUF_IP4_INIT(IPPROTO_TCP);
+
+ payload = vu_payloadv4(flags_elem[0].in_sg[0].iov_base);
+ memset(&payload->th, 0, sizeof(payload->th));
+ payload->th.doff = offsetof(struct tcp_payload_t, data) / 4;
+ payload->th.ack = 1;
+
+ seq = conn->seq_to_tap;
+ ret = tcp_prepare_flags(c, conn, flags, &payload->th,
+ (struct tcp_syn_opts *)payload->data,
+ &optlen);
+ if (ret <= 0) {
+ vu_queue_rewind(vq, 1);
+ return ret;
+ }
+
+ l4len = tcp_fill_headers4(conn, NULL, iph, payload, optlen,
+ NULL, seq, true);
+ l2len = sizeof(*iph);
Much of the above duplicates tcp_vu_prepare(). Any
chance you could
call into it instead?
I tried but tcp_fill_headersX() needs the length computed in tcp_prepare_flags() but
tcp_prepare_flags() needs to be after tcp_vu_prepare() because tcp_vu_prepare() resets the
TCP header and tcp_prepare_flags() updates it with the flags.
tcp_prepare_flags() should be called in the middle of tcp_vu_prepare().
It's really simpler to duplicate the code of tcp_vu_prepare() in tcp_vu_send_flag()
rather
than to call tcp_vu_prepare() from tcp_vu_send_flag().
Thanks,
Laurent