]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/network/networkd-tunnel.c
networkd: netdev - rework load_one
[thirdparty/systemd.git] / src / network / networkd-tunnel.c
CommitLineData
7951dea2
SS
1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3/***
4 This file is part of systemd.
5
6 Copyright 2014 Susant Sahani <susant@redhat.com>
7
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20***/
21
22#include <netinet/ether.h>
23#include <arpa/inet.h>
24#include <net/if.h>
25#include <linux/ip.h>
26#include <linux/if_tunnel.h>
7951dea2
SS
27
28#include "sd-rtnl.h"
29#include "networkd.h"
30#include "network-internal.h"
31#include "util.h"
81577dc2 32#include "missing.h"
6ef892fc 33#include "conf-parser.h"
7951dea2
SS
34
35
36static int netdev_fill_ipip_rtnl_message(Link *link, sd_rtnl_message *m) {
37 NetDev *netdev;
38 int r;
39
40 assert(link);
41 assert(link->network);
42 assert(link->network->tunnel);
43 assert(m);
44
45 netdev = link->network->tunnel;
46
4826dd68
TG
47 assert(netdev->family == AF_INET);
48
af4e9e2c 49 r = sd_rtnl_message_append_string(m, IFLA_IFNAME, netdev->ifname);
7951dea2
SS
50 if (r < 0) {
51 log_error_netdev(netdev,
52 "Could not append IFLA_IFNAME, attribute: %s",
53 strerror(-r));
54 return r;
55 }
56
57 if(netdev->mtu) {
58 r = sd_rtnl_message_append_u32(m, IFLA_MTU, netdev->mtu);
59 if (r < 0) {
60 log_error_netdev(netdev,
61 "Could not append IFLA_MTU attribute: %s",
62 strerror(-r));
63 return r;
64 }
65 }
66
96c90742
TG
67 if (netdev->mac) {
68 r = sd_rtnl_message_append_ether_addr(m, IFLA_ADDRESS, netdev->mac);
69 if (r < 0) {
70 log_error_netdev(netdev,
71 "Colud not append IFLA_ADDRESS attribute: %s",
72 strerror(-r));
73 return r;
74 }
75 }
76
7951dea2
SS
77 r = sd_rtnl_message_open_container(m, IFLA_LINKINFO);
78 if (r < 0) {
79 log_error_netdev(netdev,
80 "Could not append IFLA_LINKINFO attribute: %s",
81 strerror(-r));
82 return r;
83 }
84
85 r = sd_rtnl_message_open_container_union(m, IFLA_INFO_DATA,
86 netdev_kind_to_string(netdev->kind));
87 if (r < 0) {
88 log_error_netdev(netdev,
89 "Could not append IFLA_INFO_DATA attribute: %s",
90 strerror(-r));
91 return r;
92 }
93
94 r = sd_rtnl_message_append_u32(m, IFLA_IPTUN_LINK, link->ifindex);
95 if (r < 0) {
96 log_error_netdev(netdev,
97 "Could not append IFLA_IPTUN_LINK attribute: %s",
98 strerror(-r));
99 return r;
100 }
101
4826dd68 102 r = sd_rtnl_message_append_in_addr(m, IFLA_IPTUN_LOCAL, &netdev->local.in);
7951dea2
SS
103 if (r < 0) {
104 log_error_netdev(netdev,
105 "Could not append IFLA_IPTUN_LOCAL attribute: %s",
106 strerror(-r));
107 return r;
108 }
109
4826dd68 110 r = sd_rtnl_message_append_in_addr(m, IFLA_IPTUN_REMOTE, &netdev->remote.in);
7951dea2
SS
111 if (r < 0) {
112 log_error_netdev(netdev,
113 "Could not append IFLA_IPTUN_REMOTE attribute: %s",
114 strerror(-r));
115 return r;
116 }
117
1324e3ae 118 r = sd_rtnl_message_append_u8(m, IFLA_IPTUN_TTL, netdev->ttl);
9ae70211
SS
119 if (r < 0) {
120 log_error_netdev(netdev,
121 "Could not append IFLA_IPTUN_TTL attribute: %s",
122 strerror(-r));
123 return r;
124 }
125
7951dea2
SS
126 r = sd_rtnl_message_close_container(m);
127 if (r < 0) {
128 log_error_netdev(netdev,
129 "Could not append IFLA_INFO_DATA attribute: %s",
130 strerror(-r));
131 return r;
132 }
133
134 r = sd_rtnl_message_close_container(m);
135 if (r < 0) {
136 log_error_netdev(netdev,
137 "Could not append IFLA_LINKINFO attribute: %s",
138 strerror(-r));
139 return r;
140 }
141
142 return r;
143}
144
abf446af
SS
145static int netdev_fill_sit_rtnl_message(Link *link, sd_rtnl_message *m) {
146 NetDev *netdev;
147 int r;
148
149 assert(link);
150 assert(link->network);
151 assert(link->network->tunnel);
152 assert(m);
153
154 netdev = link->network->tunnel;
155
4826dd68
TG
156 assert(netdev->family == AF_INET);
157
abf446af
SS
158 r = sd_rtnl_message_append_string(m, IFLA_IFNAME, netdev->ifname);
159 if (r < 0) {
160 log_error_netdev(netdev,
161 "Could not append IFLA_IFNAME, attribute: %s",
162 strerror(-r));
163 return r;
164 }
165
166 if(netdev->mtu) {
167 r = sd_rtnl_message_append_u32(m, IFLA_MTU, netdev->mtu);
168 if (r < 0) {
169 log_error_netdev(netdev,
170 "Could not append IFLA_MTU attribute: %s",
171 strerror(-r));
172 return r;
173 }
174 }
175
96c90742
TG
176 if (netdev->mac) {
177 r = sd_rtnl_message_append_ether_addr(m, IFLA_ADDRESS, netdev->mac);
178 if (r < 0) {
179 log_error_netdev(netdev,
180 "Colud not append IFLA_ADDRESS attribute: %s",
181 strerror(-r));
182 return r;
183 }
184 }
185
abf446af
SS
186 r = sd_rtnl_message_open_container(m, IFLA_LINKINFO);
187 if (r < 0) {
188 log_error_netdev(netdev,
189 "Could not append IFLA_LINKINFO attribute: %s",
190 strerror(-r));
191 return r;
192 }
193
194 r = sd_rtnl_message_open_container_union(m, IFLA_INFO_DATA,
195 netdev_kind_to_string(netdev->kind));
196 if (r < 0) {
197 log_error_netdev(netdev,
198 "Could not append IFLA_INFO_DATA attribute: %s",
199 strerror(-r));
200 return r;
201 }
202
203 r = sd_rtnl_message_append_u32(m, IFLA_IPTUN_LINK, link->ifindex);
204 if (r < 0) {
205 log_error_netdev(netdev,
206 "Could not append IFLA_IPTUN_LINK attribute: %s",
207 strerror(-r));
208 return r;
209 }
210
4826dd68 211 r = sd_rtnl_message_append_in_addr(m, IFLA_IPTUN_LOCAL, &netdev->local.in);
abf446af
SS
212 if (r < 0) {
213 log_error_netdev(netdev,
214 "Could not append IFLA_IPTUN_LOCAL attribute: %s",
215 strerror(-r));
216 return r;
217 }
218
4826dd68 219 r = sd_rtnl_message_append_in_addr(m, IFLA_IPTUN_REMOTE, &netdev->remote.in);
abf446af
SS
220 if (r < 0) {
221 log_error_netdev(netdev,
222 "Could not append IFLA_IPTUN_REMOTE attribute: %s",
223 strerror(-r));
224 return r;
225 }
226
1324e3ae 227 r = sd_rtnl_message_append_u8(m, IFLA_IPTUN_TOS, netdev->tos);
abf446af
SS
228 if (r < 0) {
229 log_error_netdev(netdev,
230 "Could not append IFLA_IPTUN_TOS attribute: %s",
231 strerror(-r));
232 return r;
233 }
234
a9f434cf
SS
235 r = sd_rtnl_message_append_u8(m, IFLA_IPTUN_PMTUDISC, netdev->tunnel_pmtudisc);
236 if (r < 0) {
237 log_error_netdev(netdev,
238 "Could not append IFLA_IPTUN_PMTUDISC attribute: %s",
239 strerror(-r));
240 return r;
241 }
242
abf446af
SS
243 r = sd_rtnl_message_close_container(m);
244 if (r < 0) {
245 log_error_netdev(netdev,
246 "Could not append IFLA_INFO_DATA attribute: %s",
247 strerror(-r));
248 return r;
249 }
250
251 r = sd_rtnl_message_close_container(m);
252 if (r < 0) {
253 log_error_netdev(netdev,
254 "Could not append IFLA_LINKINFO attribute: %s",
255 strerror(-r));
256 return r;
257 }
258
259 return r;
260}
261
8bb088c5
SS
262static int netdev_fill_ipgre_rtnl_message(Link *link, sd_rtnl_message *m) {
263 NetDev *netdev;
264 int r;
265
266 assert(link);
267 assert(link->network);
268 assert(link->network->tunnel);
269 assert(m);
270
271 netdev = link->network->tunnel;
272
4826dd68
TG
273 assert(netdev->family == AF_INET);
274
8bb088c5
SS
275 r = sd_rtnl_message_append_string(m, IFLA_IFNAME, netdev->ifname);
276 if (r < 0) {
277 log_error_netdev(netdev,
278 "Could not append IFLA_IFNAME, attribute: %s",
279 strerror(-r));
280 return r;
281 }
282
283 if(netdev->mtu) {
284 r = sd_rtnl_message_append_u32(m, IFLA_MTU, netdev->mtu);
285 if (r < 0) {
286 log_error_netdev(netdev,
287 "Could not append IFLA_MTU attribute: %s",
288 strerror(-r));
289 return r;
290 }
291 }
292
96c90742
TG
293 if (netdev->mac) {
294 r = sd_rtnl_message_append_ether_addr(m, IFLA_ADDRESS, netdev->mac);
295 if (r < 0) {
296 log_error_netdev(netdev,
297 "Colud not append IFLA_ADDRESS attribute: %s",
298 strerror(-r));
299 return r;
300 }
301 }
302
8bb088c5
SS
303 r = sd_rtnl_message_open_container(m, IFLA_LINKINFO);
304 if (r < 0) {
305 log_error_netdev(netdev,
306 "Could not append IFLA_LINKINFO attribute: %s",
307 strerror(-r));
308 return r;
309 }
310
311 r = sd_rtnl_message_open_container_union(m, IFLA_INFO_DATA,
312 netdev_kind_to_string(netdev->kind));
313 if (r < 0) {
314 log_error_netdev(netdev,
315 "Could not append IFLA_INFO_DATA attribute: %s",
316 strerror(-r));
317 return r;
318 }
319
320 r = sd_rtnl_message_append_u32(m, IFLA_GRE_LINK, link->ifindex);
321 if (r < 0) {
322 log_error_netdev(netdev,
323 "Could not append IFLA_GRE_LINK attribute: %s",
324 strerror(-r));
325 return r;
326 }
327
4826dd68 328 r = sd_rtnl_message_append_in_addr(m, IFLA_GRE_LOCAL, &netdev->local.in);
8bb088c5
SS
329 if (r < 0) {
330 log_error_netdev(netdev,
331 "Could not append IFLA_GRE_LOCAL attribute: %s",
332 strerror(-r));
333 return r;
334 }
335
4826dd68 336 r = sd_rtnl_message_append_in_addr(m, IFLA_GRE_REMOTE, &netdev->remote.in);
8bb088c5
SS
337 if (r < 0) {
338 log_error_netdev(netdev,
339 "Could not append IFLA_GRE_REMOTE attribute: %s",
340 strerror(-r));
341 return r;
342 }
343
1324e3ae 344 r = sd_rtnl_message_append_u8(m, IFLA_GRE_TTL, netdev->ttl);
8bb088c5
SS
345 if (r < 0) {
346 log_error_netdev(netdev,
347 "Could not append IFLA_GRE_TTL attribute: %s",
348 strerror(-r));
349 return r;
350 }
351
1324e3ae 352 r = sd_rtnl_message_append_u8(m, IFLA_GRE_TOS, netdev->tos);
8bb088c5
SS
353 if (r < 0) {
354 log_error_netdev(netdev,
355 "Could not append IFLA_GRE_TOS attribute: %s",
356 strerror(-r));
357 return r;
358 }
359
360 r = sd_rtnl_message_close_container(m);
361 if (r < 0) {
362 log_error_netdev(netdev,
363 "Could not append IFLA_INFO_DATA attribute: %s",
364 strerror(-r));
365 return r;
366 }
367
368 r = sd_rtnl_message_close_container(m);
369 if (r < 0) {
370 log_error_netdev(netdev,
371 "Could not append IFLA_LINKINFO attribute: %s",
372 strerror(-r));
373 return r;
374 }
375
376 return r;
377}
378
a613382b
SS
379static int netdev_fill_vti_rtnl_message(Link *link, sd_rtnl_message *m) {
380 NetDev *netdev;
381 int r;
382
383 assert(link);
384 assert(link->network);
385 assert(link->network->tunnel);
386 assert(m);
387
388 netdev = link->network->tunnel;
389
4826dd68
TG
390 assert(netdev->family == AF_INET);
391
a613382b
SS
392 r = sd_rtnl_message_append_string(m, IFLA_IFNAME, netdev->ifname);
393 if (r < 0) {
394 log_error_netdev(netdev,
395 "Could not append IFLA_IFNAME, attribute: %s",
396 strerror(-r));
397 return r;
398 }
399
400 if(netdev->mtu) {
401 r = sd_rtnl_message_append_u32(m, IFLA_MTU, netdev->mtu);
402 if (r < 0) {
403 log_error_netdev(netdev,
404 "Could not append IFLA_MTU attribute: %s",
405 strerror(-r));
406 return r;
407 }
408 }
409
96c90742
TG
410 if (netdev->mac) {
411 r = sd_rtnl_message_append_ether_addr(m, IFLA_ADDRESS, netdev->mac);
412 if (r < 0) {
413 log_error_netdev(netdev,
414 "Colud not append IFLA_ADDRESS attribute: %s",
415 strerror(-r));
416 return r;
417 }
418 }
419
a613382b
SS
420 r = sd_rtnl_message_open_container(m, IFLA_LINKINFO);
421 if (r < 0) {
422 log_error_netdev(netdev,
423 "Could not append IFLA_LINKINFO attribute: %s",
424 strerror(-r));
425 return r;
426 }
427
428 r = sd_rtnl_message_open_container_union(m, IFLA_INFO_DATA,
429 netdev_kind_to_string(netdev->kind));
430 if (r < 0) {
431 log_error_netdev(netdev,
432 "Could not append IFLA_INFO_DATA attribute: %s",
433 strerror(-r));
434 return r;
435 }
436
437 r = sd_rtnl_message_append_u32(m, IFLA_VTI_LINK, link->ifindex);
438 if (r < 0) {
439 log_error_netdev(netdev,
440 "Could not append IFLA_IPTUN_LINK attribute: %s",
441 strerror(-r));
442 return r;
443 }
444
4826dd68 445 r = sd_rtnl_message_append_in_addr(m, IFLA_VTI_LOCAL, &netdev->local.in);
a613382b
SS
446 if (r < 0) {
447 log_error_netdev(netdev,
448 "Could not append IFLA_IPTUN_LOCAL attribute: %s",
449 strerror(-r));
450 return r;
451 }
452
4826dd68 453 r = sd_rtnl_message_append_in_addr(m, IFLA_VTI_REMOTE, &netdev->remote.in);
a613382b
SS
454 if (r < 0) {
455 log_error_netdev(netdev,
456 "Could not append IFLA_IPTUN_REMOTE attribute: %s",
457 strerror(-r));
458 return r;
459 }
460
461 r = sd_rtnl_message_close_container(m);
462 if (r < 0) {
463 log_error_netdev(netdev,
464 "Could not append IFLA_INFO_DATA attribute: %s",
465 strerror(-r));
466 return r;
467 }
468
469 r = sd_rtnl_message_close_container(m);
470 if (r < 0) {
471 log_error_netdev(netdev,
472 "Could not append IFLA_LINKINFO attribute: %s",
473 strerror(-r));
474 return r;
475 }
476
477 return r;
478}
8bb088c5 479
d5b3d845 480int netdev_create_tunnel(NetDev *netdev, Link *link, sd_rtnl_message_handler_t callback) {
7951dea2 481 _cleanup_rtnl_message_unref_ sd_rtnl_message *m = NULL;
7951dea2
SS
482 int r;
483
7951dea2 484 assert(netdev);
af4e9e2c 485 assert(netdev->ifname);
7951dea2
SS
486 assert(netdev->manager);
487 assert(netdev->manager->rtnl);
d5b3d845
TG
488 assert(link);
489 assert(link->network);
490 assert(link->network->tunnel == netdev);
7951dea2
SS
491
492 r = sd_rtnl_message_new_link(netdev->manager->rtnl, &m, RTM_NEWLINK, 0);
493 if (r < 0) {
494 log_error_netdev(netdev,
495 "Could not allocate RTM_NEWLINK message: %s",
496 strerror(-r));
497 return r;
498 }
499
500 switch(netdev->kind) {
501 case NETDEV_KIND_IPIP:
502 r = netdev_fill_ipip_rtnl_message(link, m);
503 if(r < 0)
504 return r;
505 break;
7951dea2 506 case NETDEV_KIND_SIT:
abf446af
SS
507 r = netdev_fill_sit_rtnl_message(link, m);
508 if(r < 0)
509 return r;
510 break;
a613382b
SS
511 case NETDEV_KIND_VTI:
512 netdev_fill_vti_rtnl_message(link, m);
513 if(r < 0)
514 return r;
515 break;
abf446af 516 case NETDEV_KIND_GRE:
8bb088c5
SS
517 r = netdev_fill_ipgre_rtnl_message(link, m);
518 if(r < 0)
519 return r;
520 break;
7951dea2
SS
521 default:
522 return -ENOTSUP;
523 }
524
d5b3d845 525 r = sd_rtnl_call_async(netdev->manager->rtnl, m, callback, link, 0, NULL);
7951dea2
SS
526 if (r < 0) {
527 log_error_netdev(netdev,
528 "Could not send rtnetlink message: %s", strerror(-r));
529 return r;
530 }
531
e04468de
TG
532 link_ref(link);
533
7951dea2
SS
534 log_debug_netdev(netdev, "Creating tunnel netdev: %s",
535 netdev_kind_to_string(netdev->kind));
536
537 netdev->state = NETDEV_STATE_CREATING;
538
539 return 0;
540}
6ef892fc
TG
541
542int config_parse_tunnel_address(const char *unit,
543 const char *filename,
544 unsigned line,
545 const char *section,
546 unsigned section_line,
547 const char *lvalue,
548 int ltype,
549 const char *rvalue,
550 void *data,
551 void *userdata) {
552 NetDev *n = userdata;
553 union in_addr_union *addr = data;
554 int r;
555
556 assert(filename);
557 assert(lvalue);
558 assert(rvalue);
559 assert(data);
560
561 r = net_parse_inaddr(rvalue, &n->family, addr);
562 if (r < 0) {
563 log_syntax(unit, LOG_ERR, filename, line, EINVAL,
564 "Tunnel address is invalid, ignoring assignment: %s", rvalue);
565 return 0;
566 }
567
568 return 0;
569}