Skip to content

Commit 359a5bc

Browse files
committed
core: add AF_VSOCK support to socket units
Accept AF_VSOCK listen addresses in socket unit files. Both guest and host can now take advantage of socket activation. The QEMU guest agent has recently been modified to support socket activation and can run over AF_VSOCK with this patch.
1 parent 0fc0f14 commit 359a5bc

File tree

3 files changed

+28
-3
lines changed

3 files changed

+28
-3
lines changed

man/systemd.socket.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,14 @@
216216
<varname>BindIPv6Only=</varname> setting (see below).
217217
</para>
218218

219+
<para>If the address string is a string in the format
220+
<literal>vsock:x:y</literal>, it is read as CID <literal>x</literal> on
221+
a port <literal>y</literal> address in the
222+
<constant>AF_VSOCK</constant> family. The CID is a unique 32-bit
223+
integer identifier in <constant>AF_VSOCK</constant> analogous to an IP
224+
address. Specifying the CID is optional, and may be set to the empty
225+
string.</para>
226+
219227
<para>Note that <constant>SOCK_SEQPACKET</constant> (i.e.
220228
<varname>ListenSequentialPacket=</varname>) is only available
221229
for <constant>AF_UNIX</constant> sockets.

src/core/service.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1292,7 +1292,7 @@ static int service_spawn(
12921292
return r;
12931293
}
12941294

1295-
if (r == 0 && IN_SET(sa.sa.sa_family, AF_INET, AF_INET6)) {
1295+
if (r == 0 && IN_SET(sa.sa.sa_family, AF_INET, AF_INET6, AF_VSOCK)) {
12961296
_cleanup_free_ char *addr = NULL;
12971297
char *t;
12981298
unsigned port;

src/core/socket.c

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -485,12 +485,13 @@ static void peer_address_hash_func(const void *p, struct siphash *state) {
485485
const SocketPeer *s = p;
486486

487487
assert(s);
488-
assert(IN_SET(s->peer.sa.sa_family, AF_INET, AF_INET6));
489488

490489
if (s->peer.sa.sa_family == AF_INET)
491490
siphash24_compress(&s->peer.in.sin_addr, sizeof(s->peer.in.sin_addr), state);
492491
else if (s->peer.sa.sa_family == AF_INET6)
493492
siphash24_compress(&s->peer.in6.sin6_addr, sizeof(s->peer.in6.sin6_addr), state);
493+
else if (s->peer.sa.sa_family == AF_VSOCK)
494+
siphash24_compress(&s->peer.vm.svm_cid, sizeof(s->peer.vm.svm_cid), state);
494495
else
495496
assert_not_reached("Unknown address family.");
496497
}
@@ -508,6 +509,12 @@ static int peer_address_compare_func(const void *a, const void *b) {
508509
return memcmp(&x->peer.in.sin_addr, &y->peer.in.sin_addr, sizeof(x->peer.in.sin_addr));
509510
case AF_INET6:
510511
return memcmp(&x->peer.in6.sin6_addr, &y->peer.in6.sin6_addr, sizeof(x->peer.in6.sin6_addr));
512+
case AF_VSOCK:
513+
if (x->peer.vm.svm_cid < y->peer.vm.svm_cid)
514+
return -1;
515+
if (x->peer.vm.svm_cid > y->peer.vm.svm_cid)
516+
return 1;
517+
return 0;
511518
}
512519
assert_not_reached("Black sheep in the family!");
513520
}
@@ -594,7 +601,7 @@ int socket_acquire_peer(Socket *s, int fd, SocketPeer **p) {
594601
if (r < 0)
595602
return log_error_errno(errno, "getpeername failed: %m");
596603

597-
if (!IN_SET(sa.peer.sa.sa_family, AF_INET, AF_INET6)) {
604+
if (!IN_SET(sa.peer.sa.sa_family, AF_INET, AF_INET6, AF_VSOCK)) {
598605
*p = NULL;
599606
return 0;
600607
}
@@ -941,6 +948,16 @@ static int instance_from_socket(int fd, unsigned nr, char **instance) {
941948
break;
942949
}
943950

951+
case AF_VSOCK:
952+
if (asprintf(&r,
953+
"%u-%u:%u-%u:%u",
954+
nr,
955+
local.vm.svm_cid, local.vm.svm_port,
956+
remote.vm.svm_cid, remote.vm.svm_port) < 0)
957+
return -ENOMEM;
958+
959+
break;
960+
944961
default:
945962
assert_not_reached("Unhandled socket type.");
946963
}

0 commit comments

Comments
 (0)