]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/network/networkd-netdev-tunnel.c
update TODO
[thirdparty/systemd.git] / src / network / networkd-netdev-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"
3be1d7e0 29#include "networkd-netdev-tunnel.h"
7951dea2
SS
30#include "network-internal.h"
31#include "util.h"
81577dc2 32#include "missing.h"
6ef892fc 33#include "conf-parser.h"
7951dea2 34
3be1d7e0 35static int netdev_ipip_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_message *m) {
aa9f1140 36 Tunnel *t = IPIP(netdev);
7951dea2
SS
37 int r;
38
3be1d7e0 39 assert(netdev);
7951dea2 40 assert(link);
7951dea2 41 assert(m);
aa9f1140
TG
42 assert(t);
43 assert(t->family == AF_INET);
7951dea2
SS
44
45 r = sd_rtnl_message_append_u32(m, IFLA_IPTUN_LINK, link->ifindex);
46 if (r < 0) {
47 log_error_netdev(netdev,
48 "Could not append IFLA_IPTUN_LINK attribute: %s",
49 strerror(-r));
50 return r;
51 }
52
aa9f1140 53 r = sd_rtnl_message_append_in_addr(m, IFLA_IPTUN_LOCAL, &t->local.in);
7951dea2
SS
54 if (r < 0) {
55 log_error_netdev(netdev,
56 "Could not append IFLA_IPTUN_LOCAL attribute: %s",
57 strerror(-r));
58 return r;
59 }
60
aa9f1140 61 r = sd_rtnl_message_append_in_addr(m, IFLA_IPTUN_REMOTE, &t->remote.in);
7951dea2
SS
62 if (r < 0) {
63 log_error_netdev(netdev,
64 "Could not append IFLA_IPTUN_REMOTE attribute: %s",
65 strerror(-r));
66 return r;
67 }
68
aa9f1140 69 r = sd_rtnl_message_append_u8(m, IFLA_IPTUN_TTL, t->ttl);
9ae70211
SS
70 if (r < 0) {
71 log_error_netdev(netdev,
72 "Could not append IFLA_IPTUN_TTL attribute: %s",
73 strerror(-r));
74 return r;
75 }
76
7951dea2
SS
77 return r;
78}
79
3be1d7e0 80static int netdev_sit_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_message *m) {
aa9f1140 81 Tunnel *t = SIT(netdev);
abf446af
SS
82 int r;
83
3be1d7e0 84 assert(netdev);
abf446af 85 assert(link);
abf446af 86 assert(m);
aa9f1140
TG
87 assert(t);
88 assert(t->family == AF_INET);
abf446af
SS
89
90 r = sd_rtnl_message_append_u32(m, IFLA_IPTUN_LINK, link->ifindex);
91 if (r < 0) {
92 log_error_netdev(netdev,
93 "Could not append IFLA_IPTUN_LINK attribute: %s",
94 strerror(-r));
95 return r;
96 }
97
aa9f1140 98 r = sd_rtnl_message_append_in_addr(m, IFLA_IPTUN_LOCAL, &t->local.in);
abf446af
SS
99 if (r < 0) {
100 log_error_netdev(netdev,
101 "Could not append IFLA_IPTUN_LOCAL attribute: %s",
102 strerror(-r));
103 return r;
104 }
105
aa9f1140 106 r = sd_rtnl_message_append_in_addr(m, IFLA_IPTUN_REMOTE, &t->remote.in);
abf446af
SS
107 if (r < 0) {
108 log_error_netdev(netdev,
109 "Could not append IFLA_IPTUN_REMOTE attribute: %s",
110 strerror(-r));
111 return r;
112 }
113
aa9f1140 114 r = sd_rtnl_message_append_u8(m, IFLA_IPTUN_TTL, t->ttl);
a9f434cf
SS
115 if (r < 0) {
116 log_error_netdev(netdev,
6436165d 117 "Could not append IFLA_IPTUN_TTL attribute: %s",
a9f434cf
SS
118 strerror(-r));
119 return r;
120 }
121
abf446af
SS
122 return r;
123}
124
3be1d7e0 125static int netdev_gre_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_message *m) {
aa9f1140 126 Tunnel *t = GRE(netdev);
8bb088c5
SS
127 int r;
128
3be1d7e0 129 assert(netdev);
8bb088c5 130 assert(link);
8bb088c5 131 assert(m);
aa9f1140
TG
132 assert(t);
133 assert(t->family == AF_INET);
8bb088c5
SS
134
135 r = sd_rtnl_message_append_u32(m, IFLA_GRE_LINK, link->ifindex);
136 if (r < 0) {
137 log_error_netdev(netdev,
138 "Could not append IFLA_GRE_LINK attribute: %s",
139 strerror(-r));
140 return r;
141 }
142
aa9f1140 143 r = sd_rtnl_message_append_in_addr(m, IFLA_GRE_LOCAL, &t->local.in);
8bb088c5
SS
144 if (r < 0) {
145 log_error_netdev(netdev,
146 "Could not append IFLA_GRE_LOCAL attribute: %s",
147 strerror(-r));
148 return r;
149 }
150
aa9f1140 151 r = sd_rtnl_message_append_in_addr(m, IFLA_GRE_REMOTE, &t->remote.in);
8bb088c5
SS
152 if (r < 0) {
153 log_error_netdev(netdev,
154 "Could not append IFLA_GRE_REMOTE attribute: %s",
155 strerror(-r));
156 return r;
157 }
158
aa9f1140 159 r = sd_rtnl_message_append_u8(m, IFLA_GRE_TTL, t->ttl);
8bb088c5
SS
160 if (r < 0) {
161 log_error_netdev(netdev,
162 "Could not append IFLA_GRE_TTL attribute: %s",
163 strerror(-r));
164 return r;
165 }
166
aa9f1140 167 r = sd_rtnl_message_append_u8(m, IFLA_GRE_TOS, t->tos);
8bb088c5
SS
168 if (r < 0) {
169 log_error_netdev(netdev,
170 "Could not append IFLA_GRE_TOS attribute: %s",
171 strerror(-r));
172 return r;
173 }
174
8bb088c5
SS
175 return r;
176}
177
3be1d7e0 178static int netdev_vti_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_message *m) {
aa9f1140 179 Tunnel *t = VTI(netdev);
a613382b
SS
180 int r;
181
3be1d7e0 182 assert(netdev);
a613382b 183 assert(link);
a613382b 184 assert(m);
aa9f1140
TG
185 assert(t);
186 assert(t->family == AF_INET);
a613382b
SS
187
188 r = sd_rtnl_message_append_u32(m, IFLA_VTI_LINK, link->ifindex);
189 if (r < 0) {
190 log_error_netdev(netdev,
191 "Could not append IFLA_IPTUN_LINK attribute: %s",
192 strerror(-r));
193 return r;
194 }
195
aa9f1140 196 r = sd_rtnl_message_append_in_addr(m, IFLA_VTI_LOCAL, &t->local.in);
a613382b
SS
197 if (r < 0) {
198 log_error_netdev(netdev,
199 "Could not append IFLA_IPTUN_LOCAL attribute: %s",
200 strerror(-r));
201 return r;
202 }
203
aa9f1140 204 r = sd_rtnl_message_append_in_addr(m, IFLA_VTI_REMOTE, &t->remote.in);
a613382b
SS
205 if (r < 0) {
206 log_error_netdev(netdev,
207 "Could not append IFLA_IPTUN_REMOTE attribute: %s",
208 strerror(-r));
209 return r;
210 }
211
a613382b
SS
212 return r;
213}
8bb088c5 214
3be1d7e0 215static int netdev_tunnel_verify(NetDev *netdev, const char *filename) {
aa9f1140
TG
216 Tunnel *t = NULL;
217
7951dea2 218 assert(netdev);
3be1d7e0 219 assert(filename);
7951dea2 220
aa9f1140
TG
221 switch (netdev->kind) {
222 case NETDEV_KIND_IPIP:
223 t = IPIP(netdev);
224 break;
225 case NETDEV_KIND_SIT:
226 t = SIT(netdev);
227 break;
228 case NETDEV_KIND_GRE:
229 t = GRE(netdev);
230 break;
231 case NETDEV_KIND_VTI:
232 t = VTI(netdev);
233 break;
234 default:
235 assert_not_reached("Invalid tunnel kind");
236 }
237
238 assert(t);
239
240 if (t->local.in.s_addr == INADDR_ANY) {
3be1d7e0
TG
241 log_warning("Tunnel without local address configured in %s. Ignoring", filename);
242 return -EINVAL;
7951dea2
SS
243 }
244
aa9f1140 245 if (t->remote.in.s_addr == INADDR_ANY) {
3be1d7e0
TG
246 log_warning("Tunnel without remote address configured in %s. Ignoring", filename);
247 return -EINVAL;
7951dea2
SS
248 }
249
aa9f1140 250 if (t->family != AF_INET) {
3be1d7e0
TG
251 log_warning("Tunnel with invalid address family configured in %s. Ignoring", filename);
252 return -EINVAL;
7951dea2
SS
253 }
254
7951dea2
SS
255 return 0;
256}
6ef892fc
TG
257
258int config_parse_tunnel_address(const char *unit,
259 const char *filename,
260 unsigned line,
261 const char *section,
262 unsigned section_line,
263 const char *lvalue,
264 int ltype,
265 const char *rvalue,
266 void *data,
267 void *userdata) {
aa9f1140 268 Tunnel *t = userdata;
44e7b949
LP
269 union in_addr_union *addr = data, buffer;
270 int r, f;
6ef892fc
TG
271
272 assert(filename);
273 assert(lvalue);
274 assert(rvalue);
275 assert(data);
276
44e7b949 277 r = in_addr_from_string_auto(rvalue, &f, &buffer);
6ef892fc 278 if (r < 0) {
44e7b949 279 log_syntax(unit, LOG_ERR, filename, line, EINVAL, "Tunnel address is invalid, ignoring assignment: %s", rvalue);
6ef892fc
TG
280 return 0;
281 }
282
44e7b949
LP
283 if (t->family != AF_UNSPEC && t->family != f) {
284 log_syntax(unit, LOG_ERR, filename, line, EINVAL, "Tunnel addresses incompatible, ignoring assignment: %s", rvalue);
285 return 0;
286 }
287
288 t->family = f;
289 *addr = buffer;
290
6ef892fc
TG
291 return 0;
292}
3be1d7e0 293
aa9f1140
TG
294static void ipip_init(NetDev *n) {
295 Tunnel *t = IPIP(n);
296
297 assert(n);
298 assert(t);
299
300 t->pmtudisc = true;
301}
302
303static void sit_init(NetDev *n) {
304 Tunnel *t = SIT(n);
305
306 assert(n);
307 assert(t);
308
309 t->pmtudisc = true;
310}
311
312static void vti_init(NetDev *n) {
313 Tunnel *t = VTI(n);
314
315 assert(n);
316 assert(t);
317
318 t->pmtudisc = true;
319}
320
321static void gre_init(NetDev *n) {
322 Tunnel *t = GRE(n);
323
324 assert(n);
325 assert(t);
326
327 t->pmtudisc = true;
328}
329
3be1d7e0 330const NetDevVTable ipip_vtable = {
aa9f1140
TG
331 .object_size = sizeof(Tunnel),
332 .init = ipip_init,
333 .sections = "Match\0NetDev\0Tunnel\0",
334 .fill_message_create = netdev_ipip_fill_message_create,
335 .create_type = NETDEV_CREATE_STACKED,
3be1d7e0
TG
336 .config_verify = netdev_tunnel_verify,
337};
338
339const NetDevVTable sit_vtable = {
aa9f1140
TG
340 .object_size = sizeof(Tunnel),
341 .init = sit_init,
342 .sections = "Match\0NetDev\0Tunnel\0",
343 .fill_message_create = netdev_sit_fill_message_create,
344 .create_type = NETDEV_CREATE_STACKED,
3be1d7e0
TG
345 .config_verify = netdev_tunnel_verify,
346};
347
348const NetDevVTable vti_vtable = {
aa9f1140
TG
349 .object_size = sizeof(Tunnel),
350 .init = vti_init,
351 .sections = "Match\0NetDev\0Tunnel\0",
352 .fill_message_create = netdev_vti_fill_message_create,
353 .create_type = NETDEV_CREATE_STACKED,
3be1d7e0
TG
354 .config_verify = netdev_tunnel_verify,
355};
356
357const NetDevVTable gre_vtable = {
aa9f1140
TG
358 .object_size = sizeof(Tunnel),
359 .init = gre_init,
360 .sections = "Match\0NetDev\0Tunnel\0",
361 .fill_message_create = netdev_gre_fill_message_create,
362 .create_type = NETDEV_CREATE_STACKED,
3be1d7e0
TG
363 .config_verify = netdev_tunnel_verify,
364};