#include "virt.h"
#include "sd-rtnl.h"
+#include "sd-daemon.h"
/* use 8 MB for receive socket kernel queue. */
#define RCVBUF_SIZE (8*1024*1024)
return 0;
}
+static int systemd_netlink_fd(void) {
+ int n, fd, rtnl_fd = -EINVAL;
+
+ n = sd_listen_fds(true);
+ if (n <= 0)
+ return -EINVAL;
+
+ for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++) {
+ if (sd_is_socket(fd, AF_NETLINK, SOCK_RAW, -1) > 0) {
+ if (rtnl_fd >= 0)
+ return -EINVAL;
+
+ rtnl_fd = fd;
+ }
+ }
+
+ return rtnl_fd;
+}
+
int manager_new(Manager **ret) {
_cleanup_manager_free_ Manager *m = NULL;
- int r;
+ int r, fd;
m = new0(Manager, 1);
if (!m)
sd_event_add_signal(m->event, NULL, SIGTERM, NULL, NULL);
sd_event_add_signal(m->event, NULL, SIGINT, NULL, NULL);
- r = sd_rtnl_open(&m->rtnl, 3, RTNLGRP_LINK, RTNLGRP_IPV4_IFADDR,
- RTNLGRP_IPV6_IFADDR);
+ fd = systemd_netlink_fd();
+ if (fd < 0)
+ r = sd_rtnl_open(&m->rtnl, 3, RTNLGRP_LINK, RTNLGRP_IPV4_IFADDR, RTNLGRP_IPV6_IFADDR);
+ else
+ r = sd_rtnl_new_from_netlink(&m->rtnl, fd);
if (r < 0)
return r;
return 0;
}
+
+const char *address_family_boolean_to_string(AddressFamilyBoolean b) {
+ if (b == ADDRESS_FAMILY_YES ||
+ b == ADDRESS_FAMILY_NO)
+ return yes_no(b == ADDRESS_FAMILY_YES);
+
+ if (b == ADDRESS_FAMILY_IPV4)
+ return "ipv4";
+ if (b == ADDRESS_FAMILY_IPV6)
+ return "ipv6";
+
+ return NULL;
+}
+
+AddressFamilyBoolean address_family_boolean_from_string(const char *s) {
+ int r;
+
+ /* Make this a true superset of a boolean */
+
+ r = parse_boolean(s);
+ if (r > 0)
+ return ADDRESS_FAMILY_YES;
+ if (r == 0)
+ return ADDRESS_FAMILY_NO;
+
+ if (streq(s, "ipv4"))
+ return ADDRESS_FAMILY_IPV4;
+ if (streq(s, "ipv6"))
+ return ADDRESS_FAMILY_IPV6;
+
+ return _ADDRESS_FAMILY_BOOLEAN_INVALID;
+}
+
+DEFINE_CONFIG_PARSE_ENUM(config_parse_address_family_boolean, address_family_boolean, AddressFamilyBoolean, "Failed to parse option");