udp: Fold checking of splice flag into udp_mmh_splice_port()
udp_mmh_splice_port() is used to determine if a UDP datagram can be "spliced" (forwarded via a socket instead of tap). We only invoke it if the origin socket has the 'splice' flag set. Fold the checking of the flag into the helper itself, which makes the caller simpler. It does mean we have a loop looking for a batch of spliceable or non-spliceable packets even in the case where the flag is clear. This shouldn't be that expensive though, since each call to udp_mmh_splice_port() will return without accessing memory in that case. In any case we're going to need a similar loop in more cases with upcoming flow table work. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
This commit is contained in:
parent
523fbc5af7
commit
63db7dcdbf
1 changed files with 16 additions and 15 deletions
23
udp.c
23
udp.c
|
@ -466,21 +466,25 @@ static int udp_splice_new_ns(void *arg)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* udp_mmh_splice_port() - Is source address of message suitable for splicing?
|
* udp_mmh_splice_port() - Is source address of message suitable for splicing?
|
||||||
* @v6: Is @sa a sockaddr_in6 (otherwise sockaddr_in)?
|
* @uref: UDP epoll reference for incoming message's origin socket
|
||||||
* @mmh: mmsghdr of incoming message
|
* @mmh: mmsghdr of incoming message
|
||||||
*
|
*
|
||||||
* Return: if @sa refers to localhost (127.0.0.1 or ::1) the port from
|
* Return: if source address of message in @mmh refers to localhost (127.0.0.1
|
||||||
* @sa in host order, otherwise -1.
|
* or ::1) its source port (host order), otherwise -1.
|
||||||
*/
|
*/
|
||||||
static int udp_mmh_splice_port(bool v6, const struct mmsghdr *mmh)
|
static int udp_mmh_splice_port(union udp_epoll_ref uref,
|
||||||
|
const struct mmsghdr *mmh)
|
||||||
{
|
{
|
||||||
const struct sockaddr_in6 *sa6 = mmh->msg_hdr.msg_name;
|
const struct sockaddr_in6 *sa6 = mmh->msg_hdr.msg_name;
|
||||||
const struct sockaddr_in *sa4 = mmh->msg_hdr.msg_name;
|
const struct sockaddr_in *sa4 = mmh->msg_hdr.msg_name;
|
||||||
|
|
||||||
if (v6 && IN6_IS_ADDR_LOOPBACK(&sa6->sin6_addr))
|
if (!uref.splice)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (uref.v6 && IN6_IS_ADDR_LOOPBACK(&sa6->sin6_addr))
|
||||||
return ntohs(sa6->sin6_port);
|
return ntohs(sa6->sin6_port);
|
||||||
|
|
||||||
if (!v6 && IN4_IS_ADDR_LOOPBACK(&sa4->sin_addr))
|
if (!uref.v6 && IN4_IS_ADDR_LOOPBACK(&sa4->sin_addr))
|
||||||
return ntohs(sa4->sin_port);
|
return ntohs(sa4->sin_port);
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -775,19 +779,16 @@ void udp_buf_sock_handler(const struct ctx *c, union epoll_ref ref, uint32_t eve
|
||||||
|
|
||||||
for (i = 0; i < n; i += m) {
|
for (i = 0; i < n; i += m) {
|
||||||
int splicefrom = -1;
|
int splicefrom = -1;
|
||||||
m = n;
|
|
||||||
|
|
||||||
if (ref.udp.splice) {
|
splicefrom = udp_mmh_splice_port(ref.udp, mmh_recv + i);
|
||||||
splicefrom = udp_mmh_splice_port(v6, mmh_recv + i);
|
|
||||||
|
|
||||||
for (m = 1; i + m < n; m++) {
|
for (m = 1; i + m < n; m++) {
|
||||||
int p;
|
int p;
|
||||||
|
|
||||||
p = udp_mmh_splice_port(v6, mmh_recv + i + m);
|
p = udp_mmh_splice_port(ref.udp, mmh_recv + i + m);
|
||||||
if (p != splicefrom)
|
if (p != splicefrom)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (splicefrom >= 0)
|
if (splicefrom >= 0)
|
||||||
udp_splice_sendfrom(c, i, m, splicefrom, dstport,
|
udp_splice_sendfrom(c, i, m, splicefrom, dstport,
|
||||||
|
|
Loading…
Reference in a new issue