loopback-setup.c revision 5a72317435a39f23520b42731e53bd13d20f489e
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye This file is part of systemd.
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye Copyright 2010 Lennart Poettering
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye systemd is free software; you can redistribute it and/or modify it
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye under the terms of the GNU Lesser General Public License as published by
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye the Free Software Foundation; either version 2.1 of the License, or
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye (at your option) any later version.
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye systemd is distributed in the hope that it will be useful, but
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye WITHOUT ANY WARRANTY; without even the implied warranty of
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye Lesser General Public License for more details.
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye You should have received a copy of the GNU Lesser General Public License
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye along with systemd; If not, see <http://www.gnu.org/licenses/>.
64b763950bf11e9357facbd2b5666631a895c085Trond Norbyestatic int pipe_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye return r == -EEXIST ? 0 : r;
64b763950bf11e9357facbd2b5666631a895c085Trond Norbyestatic int add_addresses(sd_rtnl *rtnl, int if_loopback, struct in_addr *ipv4_address, int *counter) {
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye _cleanup_sd_rtnl_message_unref_ sd_rtnl_message *ipv4 = NULL, *ipv6 = NULL;
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye r = sd_rtnl_message_addr_new(RTM_NEWADDR, if_loopback, AF_INET, &ipv4);
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye r = sd_rtnl_message_addr_set_prefixlen(ipv4, 8);
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye r = sd_rtnl_message_addr_set_flags(ipv4, IFA_F_PERMANENT);
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye r = sd_rtnl_message_addr_set_scope(ipv4, RT_SCOPE_HOST);
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye r = sd_rtnl_message_append_in_addr(ipv4, IFA_LOCAL, ipv4_address);
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye r = sd_rtnl_call_async(rtnl, ipv4, &pipe_handler, counter, 0, NULL);
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye r = sd_rtnl_message_addr_new(RTM_NEWADDR, if_loopback, AF_INET6, &ipv6);
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye r = sd_rtnl_message_addr_set_prefixlen(ipv6, 128);
77e3bcb700604954082585e3d7107004769a9f48Trond Norbye r = sd_rtnl_message_addr_set_flags(ipv6, IFA_F_PERMANENT);
49f592091468eac515dde6139fbc8efa26056b0aJorgen Austvik r = sd_rtnl_message_addr_set_scope(ipv6, RT_SCOPE_HOST);
7ecd52b03dc1f0b03ff8f522b4891c8531896c3dJorgen Austvik r = sd_rtnl_message_append_in6_addr(ipv6, IFA_LOCAL, &in6addr_loopback);
7ecd52b03dc1f0b03ff8f522b4891c8531896c3dJorgen Austvik r = sd_rtnl_call_async(rtnl, ipv6, &pipe_handler, counter, 0, NULL);
49f592091468eac515dde6139fbc8efa26056b0aJorgen Austvikstatic int start_interface(sd_rtnl *rtnl, int if_loopback, struct in_addr *ipv4_address, int *counter) {
49f592091468eac515dde6139fbc8efa26056b0aJorgen Austvik _cleanup_sd_rtnl_message_unref_ sd_rtnl_message *req = NULL;
7ecd52b03dc1f0b03ff8f522b4891c8531896c3dJorgen Austvik r = sd_rtnl_message_link_new(RTM_SETLINK, if_loopback, &req);
1ed6b730409d4740e941142599767d5eac7e7d92Lubos Kosco r = sd_rtnl_message_link_set_flags(req, IFF_UP, IFF_UP);
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye r = sd_rtnl_call_async(rtnl, req, &pipe_handler, counter, 0, NULL);
64b763950bf11e9357facbd2b5666631a895c085Trond Norbyestatic int check_loopback(void) {
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye /* If we failed to set up the loop back device, check whether
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye * it might already be set up */
7b046969a1b2565787df8ae3a8126359e8cd6fafTrond Norbye fd = socket(AF_INET, SOCK_DGRAM|SOCK_NONBLOCK|SOCK_CLOEXEC, 0);
7b046969a1b2565787df8ae3a8126359e8cd6fafTrond Norbye bool eperm = false;
2e3c025fdd5908a27cc82eb1d5346368a8be4e0dJorgen Austvik r = add_addresses(rtnl, if_loopback, &ipv4_address, &counter);
2dbc1835e0ae88ad102e2b9a85e5c7b5298b14b6Knut Anders Hatlen r = start_interface(rtnl, if_loopback, &ipv4_address, &counter);
2dbc1835e0ae88ad102e2b9a85e5c7b5298b14b6Knut Anders Hatlen log_warning("Failed to configure loopback device: %s", strerror(-r));
9cf297d9a579835e9336d587eaee187ca0954767Knut Anders Hatlen log_warning("Failed to configure loopback device: %s", strerror(EPERM));