tap: Fold reset handling into tap_handler_passt()
We call tap_sock_reset() if tap_handler_passt() fails, or if we get an error event on the socket. Fold that logic into tap_handler() passt itself which simplifies the caller. It also makes it clearer that we had a redundant EPOLL_CTL_DEL and close() in one of the reset paths, so fix that too. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
This commit is contained in:
parent
0d870c5da6
commit
e26282b67d
1 changed files with 32 additions and 36 deletions
68
tap.c
68
tap.c
|
@ -891,19 +891,41 @@ append:
|
||||||
return in->count;
|
return in->count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* tap_sock_reset() - Handle closing or failure of connect AF_UNIX socket
|
||||||
|
* @c: Execution context
|
||||||
|
*/
|
||||||
|
static void tap_sock_reset(struct ctx *c)
|
||||||
|
{
|
||||||
|
if (c->one_off) {
|
||||||
|
info("Client closed connection, exiting");
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Close the connected socket, wait for a new connection */
|
||||||
|
epoll_ctl(c->epollfd, EPOLL_CTL_DEL, c->fd_tap, NULL);
|
||||||
|
close(c->fd_tap);
|
||||||
|
c->fd_tap = -1;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* tap_handler_passt() - Packet handler for AF_UNIX file descriptor
|
* tap_handler_passt() - Packet handler for AF_UNIX file descriptor
|
||||||
* @c: Execution context
|
* @c: Execution context
|
||||||
|
* @events: epoll events
|
||||||
* @now: Current timestamp
|
* @now: Current timestamp
|
||||||
*
|
|
||||||
* Return: -ECONNRESET on receive error, 0 otherwise
|
|
||||||
*/
|
*/
|
||||||
static int tap_handler_passt(struct ctx *c, const struct timespec *now)
|
static void tap_handler_passt(struct ctx *c, uint32_t events,
|
||||||
|
const struct timespec *now)
|
||||||
{
|
{
|
||||||
struct ethhdr *eh;
|
struct ethhdr *eh;
|
||||||
ssize_t n, rem;
|
ssize_t n, rem;
|
||||||
char *p;
|
char *p;
|
||||||
|
|
||||||
|
if (events & (EPOLLRDHUP | EPOLLHUP | EPOLLERR)) {
|
||||||
|
tap_sock_reset(c);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
redo:
|
redo:
|
||||||
p = pkt_buf;
|
p = pkt_buf;
|
||||||
rem = 0;
|
rem = 0;
|
||||||
|
@ -913,13 +935,9 @@ redo:
|
||||||
|
|
||||||
n = recv(c->fd_tap, p, TAP_BUF_FILL, MSG_DONTWAIT);
|
n = recv(c->fd_tap, p, TAP_BUF_FILL, MSG_DONTWAIT);
|
||||||
if (n < 0) {
|
if (n < 0) {
|
||||||
if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK)
|
if (errno != EINTR && errno != EAGAIN && errno != EWOULDBLOCK)
|
||||||
return 0;
|
tap_sock_reset(c);
|
||||||
|
return;
|
||||||
epoll_ctl(c->epollfd, EPOLL_CTL_DEL, c->fd_tap, NULL);
|
|
||||||
close(c->fd_tap);
|
|
||||||
|
|
||||||
return -ECONNRESET;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while (n > (ssize_t)sizeof(uint32_t)) {
|
while (n > (ssize_t)sizeof(uint32_t)) {
|
||||||
|
@ -934,7 +952,7 @@ redo:
|
||||||
if (len > n) {
|
if (len > n) {
|
||||||
rem = recv(c->fd_tap, p + n, len - n, 0);
|
rem = recv(c->fd_tap, p + n, len - n, 0);
|
||||||
if ((n += rem) != len)
|
if ((n += rem) != len)
|
||||||
return 0;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Complete the partial read above before discarding a malformed
|
/* Complete the partial read above before discarding a malformed
|
||||||
|
@ -975,8 +993,6 @@ next:
|
||||||
/* We can't use EPOLLET otherwise. */
|
/* We can't use EPOLLET otherwise. */
|
||||||
if (rem)
|
if (rem)
|
||||||
goto redo;
|
goto redo;
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1258,23 +1274,6 @@ void tap_sock_init(struct ctx *c)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* tap_sock_reset() - Handle closing or failure of connect AF_UNIX socket
|
|
||||||
* @c: Execution context
|
|
||||||
*/
|
|
||||||
static void tap_sock_reset(struct ctx *c)
|
|
||||||
{
|
|
||||||
if (c->one_off) {
|
|
||||||
info("Client closed connection, exiting");
|
|
||||||
exit(EXIT_SUCCESS);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Close the connected socket, wait for a new connection */
|
|
||||||
epoll_ctl(c->epollfd, EPOLL_CTL_DEL, c->fd_tap, NULL);
|
|
||||||
close(c->fd_tap);
|
|
||||||
c->fd_tap = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* tap_handler() - Packet handler for AF_UNIX or tuntap file descriptor
|
* tap_handler() - Packet handler for AF_UNIX or tuntap file descriptor
|
||||||
* @c: Execution context
|
* @c: Execution context
|
||||||
|
@ -1290,11 +1289,8 @@ void tap_handler(struct ctx *c, int fd, uint32_t events,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c->mode == MODE_PASST) {
|
if (c->mode == MODE_PASST)
|
||||||
if (tap_handler_passt(c, now) ||
|
tap_handler_passt(c, events, now);
|
||||||
(events & (EPOLLRDHUP | EPOLLHUP | EPOLLERR)))
|
else if (c->mode == MODE_PASTA)
|
||||||
tap_sock_reset(c);
|
|
||||||
} else if (c->mode == MODE_PASTA) {
|
|
||||||
tap_handler_pasta(c, events, now);
|
tap_handler_pasta(c, events, now);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue