loopback-setup.c revision 81eca919f7cfa88bad8df7d7eac012f367c4c303
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering This file is part of systemd.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering Copyright 2010 Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering systemd is free software; you can redistribute it and/or modify it
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering under the terms of the GNU Lesser General Public License as published by
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering (at your option) any later version.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering systemd is distributed in the hope that it will be useful, but
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering Lesser General Public License for more details.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering You should have received a copy of the GNU Lesser General Public License
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poetteringstatic int pipe_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
160e3793adf2da2bd9ae3fe6b8881bb937e6e71bLennart Poettering return r == -EEXIST ? 0 : r;
160e3793adf2da2bd9ae3fe6b8881bb937e6e71bLennart Poetteringstatic int add_adresses(sd_rtnl *rtnl, int if_loopback, uint32_t ipv4_address, int *counter) {
160e3793adf2da2bd9ae3fe6b8881bb937e6e71bLennart Poettering _cleanup_sd_rtnl_message_unref_ sd_rtnl_message *ipv4 = NULL, *ipv6 = NULL;
160e3793adf2da2bd9ae3fe6b8881bb937e6e71bLennart Poettering r = sd_rtnl_message_addr_new(RTM_NEWADDR, if_loopback, AF_INET, 8, IFA_F_PERMANENT, RT_SCOPE_HOST, &ipv4);
160e3793adf2da2bd9ae3fe6b8881bb937e6e71bLennart Poettering r = sd_rtnl_message_append(ipv4, IFA_LOCAL, &ipv4_address);
160e3793adf2da2bd9ae3fe6b8881bb937e6e71bLennart Poettering r = sd_rtnl_call_async(rtnl, ipv4, &pipe_handler, counter, 0, NULL);
160e3793adf2da2bd9ae3fe6b8881bb937e6e71bLennart Poettering r = sd_rtnl_message_addr_new(RTM_NEWADDR, if_loopback, AF_INET6, 128, 0, 0, &ipv6);
160e3793adf2da2bd9ae3fe6b8881bb937e6e71bLennart Poettering r = sd_rtnl_message_append(ipv6, IFA_LOCAL, &in6addr_loopback);
160e3793adf2da2bd9ae3fe6b8881bb937e6e71bLennart Poettering r = sd_rtnl_call_async(rtnl, ipv6, &pipe_handler, counter, 0, NULL);
160e3793adf2da2bd9ae3fe6b8881bb937e6e71bLennart Poetteringstatic int start_interface(sd_rtnl *rtnl, int if_loopback, uint32_t ipv4_address, int *counter) {
160e3793adf2da2bd9ae3fe6b8881bb937e6e71bLennart Poettering _cleanup_sd_rtnl_message_unref_ sd_rtnl_message *req = NULL;
160e3793adf2da2bd9ae3fe6b8881bb937e6e71bLennart Poettering r = sd_rtnl_message_link_new(RTM_NEWLINK, if_loopback, 0, IFF_UP, &req);
160e3793adf2da2bd9ae3fe6b8881bb937e6e71bLennart Poettering r = sd_rtnl_message_append(req, IFA_LOCAL, &ipv4_address);
160e3793adf2da2bd9ae3fe6b8881bb937e6e71bLennart Poettering r = sd_rtnl_call_async(rtnl, req, &pipe_handler, counter, 0, NULL);
160e3793adf2da2bd9ae3fe6b8881bb937e6e71bLennart Poetteringstatic int check_loopback(void) {
160e3793adf2da2bd9ae3fe6b8881bb937e6e71bLennart Poettering /* If we failed to set up the loop back device, check whether
5bcd08db289cd02aad8a89b37b2a46244a7bd473Lennart Poettering * it might already be set up */
160e3793adf2da2bd9ae3fe6b8881bb937e6e71bLennart Poettering fd = socket(AF_INET, SOCK_DGRAM|SOCK_NONBLOCK|SOCK_CLOEXEC, 0);
160e3793adf2da2bd9ae3fe6b8881bb937e6e71bLennart Poettering if (bind(fd, &sa.sa, sizeof(sa.in)) >= 0)
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering _cleanup_sd_rtnl_unref_ sd_rtnl *rtnl = NULL;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering uint32_t ipv4_address = htonl(INADDR_LOOPBACK);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering if_loopback = (int) if_nametoindex("lo");
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering r = add_adresses(rtnl, if_loopback, ipv4_address, &counter);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering r = start_interface(rtnl, if_loopback, ipv4_address, &counter);
c2ce6a3d82b717c4c1e6245ad8c6ce1173f502d0Lennart Poettering log_warning("Failed to configure loopback device: %s", strerror(-r));
c2ce6a3d82b717c4c1e6245ad8c6ce1173f502d0Lennart Poettering log_warning("Failed to configure loopback device: %s", strerror(EPERM));