chiark / gitweb /
sd-network: when the LLMNR setting is not known for an interface consider that as...
[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 "network-internal.h"
31 #include "util.h"
32 #include "missing.h"
33 #include "conf-parser.h"
34
35 static int netdev_ipip_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_message *m) {
36         Tunnel *t = IPIP(netdev);
37         int r;
38
39         assert(netdev);
40         assert(link);
41         assert(m);
42         assert(t);
43         assert(t->family == AF_INET);
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
53         r = sd_rtnl_message_append_in_addr(m, IFLA_IPTUN_LOCAL, &t->local.in);
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
61         r = sd_rtnl_message_append_in_addr(m, IFLA_IPTUN_REMOTE, &t->remote.in);
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
69         r = sd_rtnl_message_append_u8(m, IFLA_IPTUN_TTL, t->ttl);
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
77         return r;
78 }
79
80 static int netdev_sit_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_message *m) {
81         Tunnel *t = SIT(netdev);
82         int r;
83
84         assert(netdev);
85         assert(link);
86         assert(m);
87         assert(t);
88         assert(t->family == AF_INET);
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
98         r = sd_rtnl_message_append_in_addr(m, IFLA_IPTUN_LOCAL, &t->local.in);
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
106         r = sd_rtnl_message_append_in_addr(m, IFLA_IPTUN_REMOTE, &t->remote.in);
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
114         r = sd_rtnl_message_append_u8(m, IFLA_IPTUN_TTL, t->ttl);
115         if (r < 0) {
116                 log_error_netdev(netdev,
117                                  "Could not append IFLA_IPTUN_TTL  attribute: %s",
118                                  strerror(-r));
119                 return r;
120         }
121
122         return r;
123 }
124
125 static int netdev_gre_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_message *m) {
126         Tunnel *t = GRE(netdev);
127         int r;
128
129         assert(netdev);
130         assert(link);
131         assert(m);
132         assert(t);
133         assert(t->family == AF_INET);
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
143         r = sd_rtnl_message_append_in_addr(m, IFLA_GRE_LOCAL, &t->local.in);
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
151         r = sd_rtnl_message_append_in_addr(m, IFLA_GRE_REMOTE, &t->remote.in);
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
159         r = sd_rtnl_message_append_u8(m, IFLA_GRE_TTL, t->ttl);
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
167         r = sd_rtnl_message_append_u8(m, IFLA_GRE_TOS, t->tos);
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
175         return r;
176 }
177
178 static int netdev_vti_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_message *m) {
179         Tunnel *t = VTI(netdev);
180         int r;
181
182         assert(netdev);
183         assert(link);
184         assert(m);
185         assert(t);
186         assert(t->family == AF_INET);
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
196         r = sd_rtnl_message_append_in_addr(m, IFLA_VTI_LOCAL, &t->local.in);
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
204         r = sd_rtnl_message_append_in_addr(m, IFLA_VTI_REMOTE, &t->remote.in);
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
212         return r;
213 }
214
215 static int netdev_tunnel_verify(NetDev *netdev, const char *filename) {
216         Tunnel *t = NULL;
217
218         assert(netdev);
219         assert(filename);
220
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) {
241                log_warning("Tunnel without local address configured in %s. Ignoring", filename);
242                return -EINVAL;
243         }
244
245         if (t->remote.in.s_addr == INADDR_ANY) {
246                log_warning("Tunnel without remote address configured in %s. Ignoring", filename);
247                return -EINVAL;
248         }
249
250         if (t->family != AF_INET) {
251               log_warning("Tunnel with invalid address family configured in %s. Ignoring", filename);
252               return -EINVAL;
253         }
254
255         return 0;
256 }
257
258 int 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) {
268         Tunnel *t = userdata;
269         union in_addr_union *addr = data;
270         int r;
271
272         assert(filename);
273         assert(lvalue);
274         assert(rvalue);
275         assert(data);
276
277         r = net_parse_inaddr(rvalue, &t->family, addr);
278         if (r < 0) {
279                 log_syntax(unit, LOG_ERR, filename, line, EINVAL,
280                            "Tunnel address is invalid, ignoring assignment: %s", rvalue);
281                 return 0;
282         }
283
284         return 0;
285 }
286
287 static void ipip_init(NetDev *n) {
288         Tunnel *t = IPIP(n);
289
290         assert(n);
291         assert(t);
292
293         t->pmtudisc = true;
294 }
295
296 static void sit_init(NetDev *n) {
297         Tunnel *t = SIT(n);
298
299         assert(n);
300         assert(t);
301
302         t->pmtudisc = true;
303 }
304
305 static void vti_init(NetDev *n) {
306         Tunnel *t = VTI(n);
307
308         assert(n);
309         assert(t);
310
311         t->pmtudisc = true;
312 }
313
314 static void gre_init(NetDev *n) {
315         Tunnel *t = GRE(n);
316
317         assert(n);
318         assert(t);
319
320         t->pmtudisc = true;
321 }
322
323 const NetDevVTable ipip_vtable = {
324         .object_size = sizeof(Tunnel),
325         .init = ipip_init,
326         .sections = "Match\0NetDev\0Tunnel\0",
327         .fill_message_create = netdev_ipip_fill_message_create,
328         .create_type = NETDEV_CREATE_STACKED,
329         .config_verify = netdev_tunnel_verify,
330 };
331
332 const NetDevVTable sit_vtable = {
333         .object_size = sizeof(Tunnel),
334         .init = sit_init,
335         .sections = "Match\0NetDev\0Tunnel\0",
336         .fill_message_create = netdev_sit_fill_message_create,
337         .create_type = NETDEV_CREATE_STACKED,
338         .config_verify = netdev_tunnel_verify,
339 };
340
341 const NetDevVTable vti_vtable = {
342         .object_size = sizeof(Tunnel),
343         .init = vti_init,
344         .sections = "Match\0NetDev\0Tunnel\0",
345         .fill_message_create = netdev_vti_fill_message_create,
346         .create_type = NETDEV_CREATE_STACKED,
347         .config_verify = netdev_tunnel_verify,
348 };
349
350 const NetDevVTable gre_vtable = {
351         .object_size = sizeof(Tunnel),
352         .init = gre_init,
353         .sections = "Match\0NetDev\0Tunnel\0",
354         .fill_message_create = netdev_gre_fill_message_create,
355         .create_type = NETDEV_CREATE_STACKED,
356         .config_verify = netdev_tunnel_verify,
357 };