loopback-setup.c revision 08e1fb68d78b4adf26cce8387fc428b9e370bcf4
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak This file is part of systemd.
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak Copyright 2010 Lennart Poettering
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak systemd is free software; you can redistribute it and/or modify it
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak under the terms of the GNU Lesser General Public License as published by
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak the Free Software Foundation; either version 2.1 of the License, or
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak (at your option) any later version.
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak systemd is distributed in the hope that it will be useful, but
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak WITHOUT ANY WARRANTY; without even the implied warranty of
27e52281f1522522b170cafc76b08b58aa70ccaand MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak Lesser General Public License for more details.
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak You should have received a copy of the GNU Lesser General Public License
4b5981e276e93df97c34e4da05ca5cf8bbd937dand along with systemd; If not, see <http://www.gnu.org/licenses/>.
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak ((struct rtattr *) (((uint8_t*) (nmsg)) + NLMSG_ALIGN((nmsg)->nlmsg_len)))
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniakstatic int add_rtattr(struct nlmsghdr *n, size_t max_length, int type, const void *data, size_t data_length) {
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak if (NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(length) > max_length)
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(length);
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniakstatic ssize_t sendto_loop(int fd, const void *buf, size_t buf_len, int flags, const struct sockaddr *sa, socklen_t sa_len) {
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak if ((l = sendto(fd, buf, buf_len, flags, sa, sa_len)) >= 0)
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniakstatic ssize_t recvfrom_loop(int fd, void *buf, size_t buf_len, int flags, struct sockaddr *sa, socklen_t *sa_len) {
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak if ((l = recvfrom(fd, buf, buf_len, flags, sa, sa_len)) >= 0)
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniakstatic int add_adresses(int fd, int if_loopback, unsigned *requests) {
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak request.header.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak request.header.nlmsg_flags = NLM_F_REQUEST|NLM_F_CREATE|NLM_F_ACK;
if ((r = add_rtattr(&request.header, sizeof(request), IFA_LOCAL, &ipv4_address, sizeof(ipv4_address))) < 0)
return -errno;
(*requests)++;
if (!socket_ipv6_is_supported())
if ((r = add_rtattr(&request.header, sizeof(request), IFA_LOCAL, &in6addr_loopback, sizeof(in6addr_loopback))) < 0)
return -errno;
(*requests)++;
} sa;
} request;
return -errno;
(*requests)++;
} sa;
} response;
ssize_t l;
return -errno;
return -EIO;
return -EIO;
return -EIO;
log_warning("Netlink failure for request %i: %s", response.header.nlmsg_seq, strerror(-nlmsgerr->error));
int loopback_setup(void) {
int r, if_loopback;
} sa;
unsigned requests = 0, i;
int fd;
errno = 0;
return -errno;
r = -errno;
goto finish;
goto finish;
goto finish;
for (i = 0; i < requests; i++) {
goto finish;
if (fd >= 0)