tcp: Return consumed packet count from tcp_data_from_tap()
Currently tcp_data_from_tap() is assumed to consume all packets remaining in the packet pool it is given. However there are some edge cases where that's not correct. In preparation for fixing those, change it to return a count of packets consumed and use that in its caller. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
This commit is contained in:
parent
5fb376de6e
commit
60d3915ea3
1 changed files with 15 additions and 10 deletions
25
tcp.c
25
tcp.c
|
@ -2297,8 +2297,10 @@ err:
|
||||||
* @idx: Index of first data packet in pool
|
* @idx: Index of first data packet in pool
|
||||||
*
|
*
|
||||||
* #syscalls sendmsg
|
* #syscalls sendmsg
|
||||||
|
*
|
||||||
|
* Return: count of consumed packets
|
||||||
*/
|
*/
|
||||||
static void tcp_data_from_tap(struct ctx *c, struct tcp_tap_conn *conn,
|
static int tcp_data_from_tap(struct ctx *c, struct tcp_tap_conn *conn,
|
||||||
const struct pool *p, int idx)
|
const struct pool *p, int idx)
|
||||||
{
|
{
|
||||||
int i, iov_i, ack = 0, fin = 0, retr = 0, keep = -1, partial_send = 0;
|
int i, iov_i, ack = 0, fin = 0, retr = 0, keep = -1, partial_send = 0;
|
||||||
|
@ -2310,7 +2312,7 @@ static void tcp_data_from_tap(struct ctx *c, struct tcp_tap_conn *conn,
|
||||||
ssize_t n;
|
ssize_t n;
|
||||||
|
|
||||||
if (conn->events == CLOSED)
|
if (conn->events == CLOSED)
|
||||||
return;
|
return p->count - idx;
|
||||||
|
|
||||||
ASSERT(conn->events & ESTABLISHED);
|
ASSERT(conn->events & ESTABLISHED);
|
||||||
|
|
||||||
|
@ -2323,19 +2325,19 @@ static void tcp_data_from_tap(struct ctx *c, struct tcp_tap_conn *conn,
|
||||||
th = packet_get(p, i, 0, sizeof(*th), &len);
|
th = packet_get(p, i, 0, sizeof(*th), &len);
|
||||||
if (!th) {
|
if (!th) {
|
||||||
tcp_rst(c, conn);
|
tcp_rst(c, conn);
|
||||||
return;
|
return p->count - idx;
|
||||||
}
|
}
|
||||||
len += sizeof(*th);
|
len += sizeof(*th);
|
||||||
|
|
||||||
off = th->doff * 4UL;
|
off = th->doff * 4UL;
|
||||||
if (off < sizeof(*th) || off > len) {
|
if (off < sizeof(*th) || off > len) {
|
||||||
tcp_rst(c, conn);
|
tcp_rst(c, conn);
|
||||||
return;
|
return p->count - idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (th->rst) {
|
if (th->rst) {
|
||||||
conn_event(c, conn, CLOSED);
|
conn_event(c, conn, CLOSED);
|
||||||
return;
|
return p->count - idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
len -= off;
|
len -= off;
|
||||||
|
@ -2446,10 +2448,10 @@ eintr:
|
||||||
|
|
||||||
if (errno == EAGAIN || errno == EWOULDBLOCK) {
|
if (errno == EAGAIN || errno == EWOULDBLOCK) {
|
||||||
tcp_send_flag(c, conn, ACK_IF_NEEDED);
|
tcp_send_flag(c, conn, ACK_IF_NEEDED);
|
||||||
return;
|
return p->count - idx;
|
||||||
}
|
}
|
||||||
tcp_rst(c, conn);
|
tcp_rst(c, conn);
|
||||||
return;
|
return p->count - idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (n < (int)(seq_from_tap - conn->seq_from_tap)) {
|
if (n < (int)(seq_from_tap - conn->seq_from_tap)) {
|
||||||
|
@ -2470,7 +2472,7 @@ out:
|
||||||
conn->seq_dup_ack_approx = conn->seq_from_tap & 0xff;
|
conn->seq_dup_ack_approx = conn->seq_from_tap & 0xff;
|
||||||
tcp_send_flag(c, conn, DUP_ACK);
|
tcp_send_flag(c, conn, DUP_ACK);
|
||||||
}
|
}
|
||||||
return;
|
return p->count - idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ack && conn->events & TAP_FIN_SENT &&
|
if (ack && conn->events & TAP_FIN_SENT &&
|
||||||
|
@ -2484,6 +2486,8 @@ out:
|
||||||
} else {
|
} else {
|
||||||
tcp_send_flag(c, conn, ACK_IF_NEEDED);
|
tcp_send_flag(c, conn, ACK_IF_NEEDED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return p->count - idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2540,6 +2544,7 @@ int tcp_tap_handler(struct ctx *c, int af, const void *saddr, const void *daddr,
|
||||||
struct tcphdr *th;
|
struct tcphdr *th;
|
||||||
int ack_due = 0;
|
int ack_due = 0;
|
||||||
char *opts;
|
char *opts;
|
||||||
|
int count;
|
||||||
|
|
||||||
th = packet_get(p, idx, 0, sizeof(*th), &len);
|
th = packet_get(p, idx, 0, sizeof(*th), &len);
|
||||||
if (!th)
|
if (!th)
|
||||||
|
@ -2627,7 +2632,7 @@ int tcp_tap_handler(struct ctx *c, int af, const void *saddr, const void *daddr,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Established connections accepting data from tap */
|
/* Established connections accepting data from tap */
|
||||||
tcp_data_from_tap(c, conn, p, idx);
|
count = tcp_data_from_tap(c, conn, p, idx);
|
||||||
if (conn->seq_ack_to_tap != conn->seq_from_tap)
|
if (conn->seq_ack_to_tap != conn->seq_from_tap)
|
||||||
ack_due = 1;
|
ack_due = 1;
|
||||||
|
|
||||||
|
@ -2641,7 +2646,7 @@ int tcp_tap_handler(struct ctx *c, int af, const void *saddr, const void *daddr,
|
||||||
if (ack_due)
|
if (ack_due)
|
||||||
conn_flag(c, conn, ACK_TO_TAP_DUE);
|
conn_flag(c, conn, ACK_TO_TAP_DUE);
|
||||||
|
|
||||||
return p->count - idx;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in a new issue