loopback-setup.c revision e95e909d820429ba34fa6f6f1b0109ac22743b47
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen/***
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen This file is part of systemd.
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen Copyright 2010 Lennart Poettering
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen systemd is free software; you can redistribute it and/or modify it
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen under the terms of the GNU Lesser General Public License as published by
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen the Free Software Foundation; either version 2.1 of the License, or
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen (at your option) any later version.
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen systemd is distributed in the hope that it will be useful, but
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen WITHOUT ANY WARRANTY; without even the implied warranty of
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen Lesser General Public License for more details.
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen You should have received a copy of the GNU Lesser General Public License
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen along with systemd; If not, see <http://www.gnu.org/licenses/>.
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen***/
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen
43b3a5ef61859f06cdbaf26765cab8e1adac4296Tom Gundersen#include <sys/socket.h>
7eb08da4b388b920c8a894b1500c9cc7dc1f31efTom Gundersen#include <net/if.h>
43b3a5ef61859f06cdbaf26765cab8e1adac4296Tom Gundersen#include <asm/types.h>
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include <netinet/in.h>
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen#include <string.h>
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include <stdlib.h>
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include <unistd.h>
a501033335ed402c8f7e86fe41a15531ba69abd7Tom Gundersen
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering#include "util.h"
43b3a5ef61859f06cdbaf26765cab8e1adac4296Tom Gundersen#include "macro.h"
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include "loopback-setup.h"
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen#include "socket-util.h"
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include "sd-rtnl.h"
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen#include "rtnl-util.h"
c6f7c917a1b494d4455800823472227463f87438Tom Gundersen
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering/* this is hardcoded in the kernel, so don't look it up */
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#define LOOPBACK_IFINDEX 1
3df3e884ae1237ef0d4d23b0e80f4ffda95ac135Ronny Chevalier
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poetteringstatic int start_loopback(sd_rtnl *rtnl) {
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering int r;
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen r = sd_rtnl_message_new_link(rtnl, &req, RTM_SETLINK, LOOPBACK_IFINDEX);
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen if (r < 0)
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen return r;
a501033335ed402c8f7e86fe41a15531ba69abd7Tom Gundersen
a501033335ed402c8f7e86fe41a15531ba69abd7Tom Gundersen r = sd_rtnl_message_link_set_flags(req, IFF_UP, IFF_UP);
f61942250a43a123580d7bbe5d7873dc5118ed97Tom Gundersen if (r < 0)
f61942250a43a123580d7bbe5d7873dc5118ed97Tom Gundersen return r;
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen
43b3a5ef61859f06cdbaf26765cab8e1adac4296Tom Gundersen r = sd_rtnl_call(rtnl, req, 0, NULL);
97f2d76d4f4dfab8b0629c09926a05a1e5621125Tom Gundersen if (r < 0)
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen return r;
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen
2ad8416dd057e7e3185169609ca3006e7649f576Zbigniew Jędrzejewski-Szmek return 0;
2ad8416dd057e7e3185169609ca3006e7649f576Zbigniew Jędrzejewski-Szmek}
2ad8416dd057e7e3185169609ca3006e7649f576Zbigniew Jędrzejewski-Szmek
2ad8416dd057e7e3185169609ca3006e7649f576Zbigniew Jędrzejewski-Szmekstatic bool check_loopback(sd_rtnl *rtnl) {
2ad8416dd057e7e3185169609ca3006e7649f576Zbigniew Jędrzejewski-Szmek _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL, *reply = NULL;
2ad8416dd057e7e3185169609ca3006e7649f576Zbigniew Jędrzejewski-Szmek unsigned flags;
2ad8416dd057e7e3185169609ca3006e7649f576Zbigniew Jędrzejewski-Szmek int r;
2ad8416dd057e7e3185169609ca3006e7649f576Zbigniew Jędrzejewski-Szmek
2ad8416dd057e7e3185169609ca3006e7649f576Zbigniew Jędrzejewski-Szmek r = sd_rtnl_message_new_link(rtnl, &req, RTM_GETLINK, LOOPBACK_IFINDEX);
9a4b012e43f23516373bf398dd9a458439d19939Tom Gundersen if (r < 0)
9a4b012e43f23516373bf398dd9a458439d19939Tom Gundersen return r;
9a4b012e43f23516373bf398dd9a458439d19939Tom Gundersen
5b9d4dc05560ddda89e48b6b39365824b15e1300Tom Gundersen r = sd_rtnl_call(rtnl, req, 0, &reply);
9a4b012e43f23516373bf398dd9a458439d19939Tom Gundersen if (r < 0)
9a4b012e43f23516373bf398dd9a458439d19939Tom Gundersen return r;
9a4b012e43f23516373bf398dd9a458439d19939Tom Gundersen
43d60b77a83b3185e37c65c4f2649d24c227c7f0Tom Gundersen r = sd_rtnl_message_link_get_flags(reply, &flags);
43d60b77a83b3185e37c65c4f2649d24c227c7f0Tom Gundersen if (r < 0)
43d60b77a83b3185e37c65c4f2649d24c227c7f0Tom Gundersen return r;
9a4b012e43f23516373bf398dd9a458439d19939Tom Gundersen
9a4b012e43f23516373bf398dd9a458439d19939Tom Gundersen return flags & IFF_UP;
9a4b012e43f23516373bf398dd9a458439d19939Tom Gundersen}
9a4b012e43f23516373bf398dd9a458439d19939Tom Gundersen
9a4b012e43f23516373bf398dd9a458439d19939Tom Gundersenint loopback_setup(void) {
9a4b012e43f23516373bf398dd9a458439d19939Tom Gundersen _cleanup_rtnl_unref_ sd_rtnl *rtnl = NULL;
9a4b012e43f23516373bf398dd9a458439d19939Tom Gundersen int r;
9a4b012e43f23516373bf398dd9a458439d19939Tom Gundersen
9a4b012e43f23516373bf398dd9a458439d19939Tom Gundersen r = sd_rtnl_open(&rtnl, 0);
9a4b012e43f23516373bf398dd9a458439d19939Tom Gundersen if (r < 0)
9a4b012e43f23516373bf398dd9a458439d19939Tom Gundersen return r;
9a4b012e43f23516373bf398dd9a458439d19939Tom Gundersen
9a4b012e43f23516373bf398dd9a458439d19939Tom Gundersen r = start_loopback(rtnl);
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen if (r == -EPERM) {
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen if (!check_loopback(rtnl))
9a4b012e43f23516373bf398dd9a458439d19939Tom Gundersen return log_warning_errno(EPERM, "Failed to configure loopback device: %m");
9a4b012e43f23516373bf398dd9a458439d19939Tom Gundersen } else if (r < 0)
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen return log_warning_errno(r, "Failed to configure loopback device: %m");
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen return 0;
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen}
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen