summaryrefslogtreecommitdiffstats
path: root/src/network/networkd.c
blob: 5f5697c8701a5ed9e64f4e22bd30e880381f556f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
/* SPDX-License-Identifier: LGPL-2.1+ */
/***
  Copyright 2013 Tom Gundersen <teg@jklm.no>
***/

#include "sd-daemon.h"
#include "sd-event.h"

#include "capability-util.h"
#include "networkd-conf.h"
#include "networkd-manager.h"
#include "signal-util.h"
#include "user-util.h"

int main(int argc, char *argv[]) {
        sd_event *event = NULL;
        _cleanup_(manager_freep) Manager *m = NULL;
        const char *user = "systemd-network";
        uid_t uid;
        gid_t gid;
        int r;

        log_set_target(LOG_TARGET_AUTO);
        log_parse_environment();
        log_open();

        umask(0022);

        if (argc != 1) {
                log_error("This program takes no arguments.");
                r = -EINVAL;
                goto out;
        }

        r = get_user_creds(&user, &uid, &gid, NULL, NULL);
        if (r < 0) {
                log_error_errno(r, "Cannot resolve user name %s: %m", user);
                goto out;
        }

        /* Create runtime directory. This is not necessary when networkd is
         * started with "RuntimeDirectory=systemd/netif", or after
         * systemd-tmpfiles-setup.service. */
        r = mkdir_safe_label("/run/systemd/netif", 0755, uid, gid, MKDIR_WARN_MODE);
        if (r < 0)
                log_warning_errno(r, "Could not create runtime directory: %m");

        /* Drop privileges, but only if we have been started as root. If we are not running as root we assume all
         * privileges are already dropped. */
        if (geteuid() == 0) {
                r = drop_privileges(uid, gid,
                                    (1ULL << CAP_NET_ADMIN) |
                                    (1ULL << CAP_NET_BIND_SERVICE) |
                                    (1ULL << CAP_NET_BROADCAST) |
                                    (1ULL << CAP_NET_RAW));
                if (r < 0)
                        goto out;
        }

        /* Always create the directories people can create inotify watches in.
         * It is necessary to create the following subdirectories after drop_privileges()
         * to support old kernels not supporting AmbientCapabilities=. */
        r = mkdir_safe_label("/run/systemd/netif/links", 0755, uid, gid, MKDIR_WARN_MODE);
        if (r < 0)
                log_warning_errno(r, "Could not create runtime directory 'links': %m");

        r = mkdir_safe_label("/run/systemd/netif/leases", 0755, uid, gid, MKDIR_WARN_MODE);
        if (r < 0)
                log_warning_errno(r, "Could not create runtime directory 'leases': %m");

        r = mkdir_safe_label("/run/systemd/netif/lldp", 0755, uid, gid, MKDIR_WARN_MODE);
        if (r < 0)
                log_warning_errno(r, "Could not create runtime directory 'lldp': %m");

        assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGTERM, SIGINT, -1) >= 0);

        r = sd_event_default(&event);
        if (r < 0)
                goto out;

        sd_event_set_watchdog(event, true);
        sd_event_add_signal(event, NULL, SIGTERM, NULL, NULL);
        sd_event_add_signal(event, NULL, SIGINT, NULL, NULL);

        r = manager_new(&m, event);
        if (r < 0) {
                log_error_errno(r, "Could not create manager: %m");
                goto out;
        }

        r = manager_connect_bus(m);
        if (r < 0) {
                log_error_errno(r, "Could not connect to bus: %m");
                goto out;
        }

        r = manager_parse_config_file(m);
        if (r < 0)
                log_warning_errno(r, "Failed to parse configuration file: %m");

        r = manager_load_config(m);
        if (r < 0) {
                log_error_errno(r, "Could not load configuration files: %m");
                goto out;
        }

        r = manager_rtnl_enumerate_links(m);
        if (r < 0) {
                log_error_errno(r, "Could not enumerate links: %m");
                goto out;
        }

        r = manager_rtnl_enumerate_addresses(m);
        if (r < 0) {
                log_error_errno(r, "Could not enumerate addresses: %m");
                goto out;
        }

        r = manager_rtnl_enumerate_routes(m);
        if (r < 0) {
                log_error_errno(r, "Could not enumerate routes: %m");
                goto out;
        }

        r = manager_rtnl_enumerate_rules(m);
        if (r < 0) {
                log_error_errno(r, "Could not enumerate rules: %m");
                goto out;
        }

        r = manager_start(m);
        if (r < 0) {
                log_error_errno(r, "Could not start manager: %m");
                goto out;
        }

        log_info("Enumeration completed");

        sd_notify(false,
                  "READY=1\n"
                  "STATUS=Processing requests...");

        r = sd_event_loop(event);
        if (r < 0) {
                log_error_errno(r, "Event loop failed: %m");
                goto out;
        }
out:
        sd_notify(false,
                  "STOPPING=1\n"
                  "STATUS=Shutting down...");

        sd_event_unref(event);

        return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}