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