]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/libsystemd/sd-network/sd-network.c
sd-network: rename operstates 'down' -> 'off' and 'up' -> 'no-carrier'
[thirdparty/systemd.git] / src / libsystemd / sd-network / sd-network.c
CommitLineData
fe8db0c5
TG
1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3/***
4 This file is part of systemd.
5
6 Copyright 2011 Lennart Poettering
7 Copyright 2014 Tom Gundersen
8
9 systemd is free software; you can redistribute it and/or modify it
10 under the terms of the GNU Lesser General Public License as published by
11 the Free Software Foundation; either version 2.1 of the License, or
12 (at your option) any later version.
13
14 systemd is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Lesser General Public License for more details.
18
19 You should have received a copy of the GNU Lesser General Public License
20 along with systemd; If not, see <http://www.gnu.org/licenses/>.
21***/
22
23#include <unistd.h>
24#include <string.h>
25#include <errno.h>
26#include <sys/inotify.h>
27#include <sys/poll.h>
deb2e523 28#include <net/if.h>
fe8db0c5
TG
29
30#include "util.h"
31#include "macro.h"
32#include "strv.h"
33#include "fileio.h"
34#include "sd-network.h"
7dbf94a9 35#include "network-internal.h"
fe8db0c5 36
03cc0fd1
LP
37_public_ int sd_network_get_operational_state(char **state) {
38 _cleanup_free_ char *s = NULL;
deb2e523
TG
39 int r;
40
fe8db0c5
TG
41 assert_return(state, -EINVAL);
42
03cc0fd1 43 r = parse_env_file("/run/systemd/netif/state", NEWLINE, "OPER_STATE", &s, NULL);
cb6fa44c
TG
44 if (r == -ENOENT)
45 return -ENODATA;
03cc0fd1 46 if (r < 0)
fe8db0c5 47 return r;
03cc0fd1
LP
48 if (isempty(s))
49 return -ENODATA;
deb2e523
TG
50
51 *state = s;
52 s = NULL;
53
54 return 0;
55}
56
03cc0fd1
LP
57static int network_get_strv(const char *key, char ***ret) {
58 _cleanup_strv_free_ char **a = NULL;
bbf7c048
TG
59 _cleanup_free_ char *s = NULL;
60 int r;
61
03cc0fd1
LP
62 assert_return(ret, -EINVAL);
63
64 r = parse_env_file("/run/systemd/netif/state", NEWLINE, key, &s, NULL);
65 if (r == -ENOENT)
66 return -ENODATA;
67 if (r < 0)
68 return r;
69 if (isempty(s)) {
70 *ret = NULL;
71 return 0;
72 }
73
74 a = strv_split(s, " ");
75 if (!a)
76 return -ENOMEM;
77
78 strv_uniq(a);
79 r = strv_length(a);
80
81 *ret = a;
82 a = NULL;
83
84 return r;
85}
86
87_public_ int sd_network_get_dns(char ***ret) {
88 return network_get_strv("DNS", ret);
89}
90
91_public_ int sd_network_get_ntp(char ***ret) {
92 return network_get_strv("NTP", ret);
93}
94
d6731e4c 95_public_ int sd_network_link_get_state(int ifindex, char **state) {
03cc0fd1
LP
96 _cleanup_free_ char *s = NULL, *p = NULL;
97 int r;
98
99 assert_return(ifindex > 0, -EINVAL);
bbf7c048
TG
100 assert_return(state, -EINVAL);
101
03cc0fd1
LP
102 if (asprintf(&p, "/run/systemd/netif/links/%d", ifindex) < 0)
103 return -ENOMEM;
104
105 r = parse_env_file(p, NEWLINE, "ADMIN_STATE", &s, NULL);
bbf7c048
TG
106 if (r == -ENOENT)
107 return -ENODATA;
03cc0fd1 108 if (r < 0)
bbf7c048 109 return r;
03cc0fd1
LP
110 if (isempty(s))
111 return -ENODATA;
bbf7c048
TG
112
113 *state = s;
114 s = NULL;
115
116 return 0;
117}
118
d6731e4c 119_public_ int sd_network_link_get_operational_state(int ifindex, char **state) {
deb2e523
TG
120 _cleanup_free_ char *s = NULL, *p = NULL;
121 int r;
122
6dcaa6f5 123 assert_return(ifindex > 0, -EINVAL);
deb2e523
TG
124 assert_return(state, -EINVAL);
125
6dcaa6f5 126 if (asprintf(&p, "/run/systemd/netif/links/%d", ifindex) < 0)
deb2e523
TG
127 return -ENOMEM;
128
129 r = parse_env_file(p, NEWLINE, "OPER_STATE", &s, NULL);
130 if (r == -ENOENT)
131 return -ENODATA;
03cc0fd1 132 if (r < 0)
deb2e523 133 return r;
03cc0fd1
LP
134 if (isempty(s))
135 return -ENODATA;
cb6fa44c 136
fe8db0c5 137 *state = s;
cb6fa44c
TG
138 s = NULL;
139
fe8db0c5
TG
140 return 0;
141}
142
d6731e4c 143_public_ int sd_network_link_get_llmnr(int ifindex, char **llmnr) {
bd8f6538
TG
144 _cleanup_free_ char *s = NULL, *p = NULL;
145 int r;
146
147 assert_return(ifindex > 0, -EINVAL);
148 assert_return(llmnr, -EINVAL);
149
2cd666f8
LP
150 if (asprintf(&p, "/run/systemd/netif/links/%d", ifindex) < 0)
151 return -ENOMEM;
152
bd8f6538
TG
153 r = parse_env_file(p, NEWLINE, "LLMNR", &s, NULL);
154 if (r == -ENOENT)
155 return -ENODATA;
03cc0fd1 156 if (r < 0)
bd8f6538 157 return r;
03cc0fd1 158 if (isempty(s))
b3df0b34 159 return -ENODATA;
bd8f6538
TG
160
161 *llmnr = s;
162 s = NULL;
163
164 return 0;
165}
166
6436165d 167static int network_get_link_strv(const char *key, int ifindex, char ***ret) {
7dbf94a9 168 _cleanup_free_ char *p = NULL, *s = NULL;
6f4dedb2 169 _cleanup_strv_free_ char **a = NULL;
7dbf94a9
TG
170 int r;
171
6dcaa6f5 172 assert_return(ifindex > 0, -EINVAL);
6f4dedb2 173 assert_return(ret, -EINVAL);
7dbf94a9 174
6dcaa6f5 175 if (asprintf(&p, "/run/systemd/netif/links/%d", ifindex) < 0)
7dbf94a9
TG
176 return -ENOMEM;
177
bcb7a07e 178 r = parse_env_file(p, NEWLINE, key, &s, NULL);
03cc0fd1
LP
179 if (r == -ENOENT)
180 return -ENODATA;
7dbf94a9
TG
181 if (r < 0)
182 return r;
03cc0fd1 183 if (isempty(s)) {
6f4dedb2 184 *ret = NULL;
6f4dedb2
TG
185 return 0;
186 }
7dbf94a9 187
6f4dedb2
TG
188 a = strv_split(s, " ");
189 if (!a)
7dbf94a9
TG
190 return -ENOMEM;
191
6f4dedb2
TG
192 strv_uniq(a);
193 r = strv_length(a);
7dbf94a9 194
6f4dedb2
TG
195 *ret = a;
196 a = NULL;
7dbf94a9 197
6f4dedb2 198 return r;
7dbf94a9
TG
199}
200
d6731e4c 201_public_ int sd_network_link_get_dns(int ifindex, char ***ret) {
6436165d 202 return network_get_link_strv("DNS", ifindex, ret);
bcb7a07e
TG
203}
204
d6731e4c 205_public_ int sd_network_link_get_ntp(int ifindex, char ***ret) {
6436165d 206 return network_get_link_strv("NTP", ifindex, ret);
bcb7a07e
TG
207}
208
fe8db0c5
TG
209static inline int MONITOR_TO_FD(sd_network_monitor *m) {
210 return (int) (unsigned long) m - 1;
211}
212
213static inline sd_network_monitor* FD_TO_MONITOR(int fd) {
214 return (sd_network_monitor*) (unsigned long) (fd + 1);
215}
216
0014a4ad 217_public_ int sd_network_monitor_new(sd_network_monitor **m, const char *category) {
fe8db0c5
TG
218 int fd, k;
219 bool good = false;
220
221 assert_return(m, -EINVAL);
222
223 fd = inotify_init1(IN_NONBLOCK|IN_CLOEXEC);
224 if (fd < 0)
225 return -errno;
226
7e141e49 227 if (!category || streq(category, "links")) {
85b5673b 228 k = inotify_add_watch(fd, "/run/systemd/netif/links/", IN_MOVED_TO|IN_DELETE);
fe8db0c5 229 if (k < 0) {
03e334a1 230 safe_close(fd);
fe8db0c5
TG
231 return -errno;
232 }
233
234 good = true;
235 }
236
237 if (!good) {
238 close_nointr(fd);
239 return -EINVAL;
240 }
241
242 *m = FD_TO_MONITOR(fd);
243 return 0;
244}
245
246_public_ sd_network_monitor* sd_network_monitor_unref(sd_network_monitor *m) {
247 int fd;
248
249 assert_return(m, NULL);
250
251 fd = MONITOR_TO_FD(m);
252 close_nointr(fd);
253
254 return NULL;
255}
256
257_public_ int sd_network_monitor_flush(sd_network_monitor *m) {
258
259 assert_return(m, -EINVAL);
260
261 return flush_fd(MONITOR_TO_FD(m));
262}
263
264_public_ int sd_network_monitor_get_fd(sd_network_monitor *m) {
265
266 assert_return(m, -EINVAL);
267
268 return MONITOR_TO_FD(m);
269}
270
271_public_ int sd_network_monitor_get_events(sd_network_monitor *m) {
272
273 assert_return(m, -EINVAL);
274
275 /* For now we will only return POLLIN here, since we don't
276 * need anything else ever for inotify. However, let's have
277 * this API to keep our options open should we later on need
278 * it. */
279 return POLLIN;
280}
281
282_public_ int sd_network_monitor_get_timeout(sd_network_monitor *m, uint64_t *timeout_usec) {
283
284 assert_return(m, -EINVAL);
285 assert_return(timeout_usec, -EINVAL);
286
287 /* For now we will only return (uint64_t) -1, since we don't
288 * need any timeout. However, let's have this API to keep our
289 * options open should we later on need it. */
290 *timeout_usec = (uint64_t) -1;
291 return 0;
292}