-/*-*- Mode: C; c-basic-offset: 8 -*-*/
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.
#include "util.h"
#include "macro.h"
#include "loopback-setup.h"
-
-enum {
- REQUEST_NONE = 0,
- REQUEST_ADDRESS_IPV4 = 1,
- REQUEST_ADDRESS_IPV6 = 2,
- REQUEST_FLAGS = 4,
- REQUEST_ALL = 7
-};
+#include "socket-util.h"
#define NLMSG_TAIL(nmsg) \
((struct rtattr *) (((uint8_t*) (nmsg)) + NLMSG_ALIGN((nmsg)->nlmsg_len)))
}
}
-static int add_adresses(int fd, int if_loopback) {
+static int add_adresses(int fd, int if_loopback, unsigned *requests) {
union {
struct sockaddr sa;
struct sockaddr_nl nl;
request.header.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
request.header.nlmsg_type = RTM_NEWADDR;
request.header.nlmsg_flags = NLM_F_REQUEST|NLM_F_CREATE|NLM_F_ACK;
- request.header.nlmsg_seq = REQUEST_ADDRESS_IPV4;
+ request.header.nlmsg_seq = *requests + 1;
ifaddrmsg = NLMSG_DATA(&request.header);
ifaddrmsg->ifa_family = AF_INET;
if (sendto_loop(fd, &request, request.header.nlmsg_len, 0, &sa.sa, sizeof(sa)) < 0)
return -errno;
+ (*requests)++;
+
+ if (!socket_ipv6_is_supported())
+ return 0;
request.header.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
- request.header.nlmsg_seq = REQUEST_ADDRESS_IPV6;
+ request.header.nlmsg_seq = *requests + 1;
ifaddrmsg->ifa_family = AF_INET6;
ifaddrmsg->ifa_prefixlen = 128;
if (sendto_loop(fd, &request, request.header.nlmsg_len, 0, &sa.sa, sizeof(sa)) < 0)
return -errno;
+ (*requests)++;
return 0;
}
-static int start_interface(int fd, int if_loopback) {
+static int start_interface(int fd, int if_loopback, unsigned *requests) {
union {
struct sockaddr sa;
struct sockaddr_nl nl;
request.header.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
request.header.nlmsg_type = RTM_NEWLINK;
request.header.nlmsg_flags = NLM_F_REQUEST|NLM_F_ACK;
- request.header.nlmsg_seq = REQUEST_FLAGS;
+ request.header.nlmsg_seq = *requests + 1;
ifinfomsg = NLMSG_DATA(&request.header);
ifinfomsg->ifi_family = AF_UNSPEC;
if (sendto_loop(fd, &request, request.header.nlmsg_len, 0, &sa.sa, sizeof(sa)) < 0)
return -errno;
+ (*requests)++;
+
return 0;
}
-static int read_response(int fd) {
+static int read_response(int fd, unsigned requests_max) {
union {
struct sockaddr sa;
struct sockaddr_nl nl;
if (response.header.nlmsg_type != NLMSG_ERROR ||
(pid_t) response.header.nlmsg_pid != getpid() ||
- response.header.nlmsg_seq >= REQUEST_ALL)
+ response.header.nlmsg_seq >= requests_max)
return 0;
if ((size_t) l < NLMSG_LENGTH(sizeof(struct nlmsgerr)) ||
struct sockaddr_nl nl;
struct sockaddr_storage storage;
} sa;
- int requests = REQUEST_NONE;
-
+ unsigned requests = 0, i;
int fd;
errno = 0;
goto finish;
}
- if ((r = add_adresses(fd, if_loopback)) < 0)
+ if ((r = add_adresses(fd, if_loopback, &requests)) < 0)
goto finish;
- if ((r = start_interface(fd, if_loopback)) < 0)
+ if ((r = start_interface(fd, if_loopback, &requests)) < 0)
goto finish;
- do {
- if ((r = read_response(fd)) < 0)
+ for (i = 0; i < requests; i++) {
+ if ((r = read_response(fd, requests)) < 0)
goto finish;
-
- requests |= r;
-
- } while (requests != REQUEST_ALL);
+ }
r = 0;
finish:
if (r < 0)
- log_error("Failed to configure loopback device: %s", strerror(-r));
+ log_warning("Failed to configure loopback device: %s", strerror(-r));
if (fd >= 0)
close_nointr_nofail(fd);