summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorStefan Hajnoczi <stefanha@redhat.com>2016-12-21 17:02:08 +0000
committerStefan Hajnoczi <stefanha@redhat.com>2017-01-10 15:29:04 +0000
commit359a5bcf78a89626ca9119668c0362f3b7bfe9c3 (patch)
tree4d337b006e3e43b13eafdf80f6dd8cf1666c2be0 /src/core
parent0fc0f14bfd9fdc5156c1930151b30baf4c46fcfb (diff)
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.
Diffstat (limited to 'src/core')
-rw-r--r--src/core/service.c2
-rw-r--r--src/core/socket.c21
2 files changed, 20 insertions, 3 deletions
diff --git a/src/core/service.c b/src/core/service.c
index dc7b685cd3..54074ff7bc 100644
--- a/src/core/service.c
+++ b/src/core/service.c
@@ -1292,7 +1292,7 @@ static int service_spawn(
return r;
}
- if (r == 0 && IN_SET(sa.sa.sa_family, AF_INET, AF_INET6)) {
+ if (r == 0 && IN_SET(sa.sa.sa_family, AF_INET, AF_INET6, AF_VSOCK)) {
_cleanup_free_ char *addr = NULL;
char *t;
unsigned port;
diff --git a/src/core/socket.c b/src/core/socket.c
index 521688bed5..c4ce88c5f4 100644
--- a/src/core/socket.c
+++ b/src/core/socket.c
@@ -485,12 +485,13 @@ static void peer_address_hash_func(const void *p, struct siphash *state) {
const SocketPeer *s = p;
assert(s);
- assert(IN_SET(s->peer.sa.sa_family, AF_INET, AF_INET6));
if (s->peer.sa.sa_family == AF_INET)
siphash24_compress(&s->peer.in.sin_addr, sizeof(s->peer.in.sin_addr), state);
else if (s->peer.sa.sa_family == AF_INET6)
siphash24_compress(&s->peer.in6.sin6_addr, sizeof(s->peer.in6.sin6_addr), state);
+ else if (s->peer.sa.sa_family == AF_VSOCK)
+ siphash24_compress(&s->peer.vm.svm_cid, sizeof(s->peer.vm.svm_cid), state);
else
assert_not_reached("Unknown address family.");
}
@@ -508,6 +509,12 @@ static int peer_address_compare_func(const void *a, const void *b) {
return memcmp(&x->peer.in.sin_addr, &y->peer.in.sin_addr, sizeof(x->peer.in.sin_addr));
case AF_INET6:
return memcmp(&x->peer.in6.sin6_addr, &y->peer.in6.sin6_addr, sizeof(x->peer.in6.sin6_addr));
+ case AF_VSOCK:
+ if (x->peer.vm.svm_cid < y->peer.vm.svm_cid)
+ return -1;
+ if (x->peer.vm.svm_cid > y->peer.vm.svm_cid)
+ return 1;
+ return 0;
}
assert_not_reached("Black sheep in the family!");
}
@@ -594,7 +601,7 @@ int socket_acquire_peer(Socket *s, int fd, SocketPeer **p) {
if (r < 0)
return log_error_errno(errno, "getpeername failed: %m");
- if (!IN_SET(sa.peer.sa.sa_family, AF_INET, AF_INET6)) {
+ if (!IN_SET(sa.peer.sa.sa_family, AF_INET, AF_INET6, AF_VSOCK)) {
*p = NULL;
return 0;
}
@@ -941,6 +948,16 @@ static int instance_from_socket(int fd, unsigned nr, char **instance) {
break;
}
+ case AF_VSOCK:
+ if (asprintf(&r,
+ "%u-%u:%u-%u:%u",
+ nr,
+ local.vm.svm_cid, local.vm.svm_port,
+ remote.vm.svm_cid, remote.vm.svm_port) < 0)
+ return -ENOMEM;
+
+ break;
+
default:
assert_not_reached("Unhandled socket type.");
}