1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2014 Susant Sahani <susant@redhat.com>
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.
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.
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/>.
22 #include <netinet/ether.h>
23 #include <arpa/inet.h>
26 #include <linux/if_tunnel.h>
30 #include "network-internal.h"
33 #include "conf-parser.h"
36 static int netdev_fill_ipip_rtnl_message(Link *link, sd_rtnl_message *m) {
41 assert(link->network);
42 assert(link->network->tunnel);
45 netdev = link->network->tunnel;
47 assert(netdev->family == AF_INET);
49 r = sd_rtnl_message_append_string(m, IFLA_IFNAME, netdev->ifname);
51 log_error_netdev(netdev,
52 "Could not append IFLA_IFNAME, attribute: %s",
58 r = sd_rtnl_message_append_u32(m, IFLA_MTU, netdev->mtu);
60 log_error_netdev(netdev,
61 "Could not append IFLA_MTU attribute: %s",
68 r = sd_rtnl_message_append_ether_addr(m, IFLA_ADDRESS, netdev->mac);
70 log_error_netdev(netdev,
71 "Colud not append IFLA_ADDRESS attribute: %s",
77 r = sd_rtnl_message_open_container(m, IFLA_LINKINFO);
79 log_error_netdev(netdev,
80 "Could not append IFLA_LINKINFO attribute: %s",
85 r = sd_rtnl_message_open_container_union(m, IFLA_INFO_DATA,
86 netdev_kind_to_string(netdev->kind));
88 log_error_netdev(netdev,
89 "Could not append IFLA_INFO_DATA attribute: %s",
94 r = sd_rtnl_message_append_u32(m, IFLA_IPTUN_LINK, link->ifindex);
96 log_error_netdev(netdev,
97 "Could not append IFLA_IPTUN_LINK attribute: %s",
102 r = sd_rtnl_message_append_in_addr(m, IFLA_IPTUN_LOCAL, &netdev->local.in);
104 log_error_netdev(netdev,
105 "Could not append IFLA_IPTUN_LOCAL attribute: %s",
110 r = sd_rtnl_message_append_in_addr(m, IFLA_IPTUN_REMOTE, &netdev->remote.in);
112 log_error_netdev(netdev,
113 "Could not append IFLA_IPTUN_REMOTE attribute: %s",
118 r = sd_rtnl_message_append_u8(m, IFLA_IPTUN_TTL, netdev->ttl);
120 log_error_netdev(netdev,
121 "Could not append IFLA_IPTUN_TTL attribute: %s",
126 r = sd_rtnl_message_close_container(m);
128 log_error_netdev(netdev,
129 "Could not append IFLA_INFO_DATA attribute: %s",
134 r = sd_rtnl_message_close_container(m);
136 log_error_netdev(netdev,
137 "Could not append IFLA_LINKINFO attribute: %s",
145 static int netdev_fill_sit_rtnl_message(Link *link, sd_rtnl_message *m) {
150 assert(link->network);
151 assert(link->network->tunnel);
154 netdev = link->network->tunnel;
156 assert(netdev->family == AF_INET);
158 r = sd_rtnl_message_append_string(m, IFLA_IFNAME, netdev->ifname);
160 log_error_netdev(netdev,
161 "Could not append IFLA_IFNAME, attribute: %s",
167 r = sd_rtnl_message_append_u32(m, IFLA_MTU, netdev->mtu);
169 log_error_netdev(netdev,
170 "Could not append IFLA_MTU attribute: %s",
177 r = sd_rtnl_message_append_ether_addr(m, IFLA_ADDRESS, netdev->mac);
179 log_error_netdev(netdev,
180 "Colud not append IFLA_ADDRESS attribute: %s",
186 r = sd_rtnl_message_open_container(m, IFLA_LINKINFO);
188 log_error_netdev(netdev,
189 "Could not append IFLA_LINKINFO attribute: %s",
194 r = sd_rtnl_message_open_container_union(m, IFLA_INFO_DATA,
195 netdev_kind_to_string(netdev->kind));
197 log_error_netdev(netdev,
198 "Could not append IFLA_INFO_DATA attribute: %s",
203 r = sd_rtnl_message_append_u32(m, IFLA_IPTUN_LINK, link->ifindex);
205 log_error_netdev(netdev,
206 "Could not append IFLA_IPTUN_LINK attribute: %s",
211 r = sd_rtnl_message_append_in_addr(m, IFLA_IPTUN_LOCAL, &netdev->local.in);
213 log_error_netdev(netdev,
214 "Could not append IFLA_IPTUN_LOCAL attribute: %s",
219 r = sd_rtnl_message_append_in_addr(m, IFLA_IPTUN_REMOTE, &netdev->remote.in);
221 log_error_netdev(netdev,
222 "Could not append IFLA_IPTUN_REMOTE attribute: %s",
227 r = sd_rtnl_message_append_u8(m, IFLA_IPTUN_TOS, netdev->tos);
229 log_error_netdev(netdev,
230 "Could not append IFLA_IPTUN_TOS attribute: %s",
235 r = sd_rtnl_message_append_u8(m, IFLA_IPTUN_PMTUDISC, netdev->tunnel_pmtudisc);
237 log_error_netdev(netdev,
238 "Could not append IFLA_IPTUN_PMTUDISC attribute: %s",
243 r = sd_rtnl_message_close_container(m);
245 log_error_netdev(netdev,
246 "Could not append IFLA_INFO_DATA attribute: %s",
251 r = sd_rtnl_message_close_container(m);
253 log_error_netdev(netdev,
254 "Could not append IFLA_LINKINFO attribute: %s",
262 static int netdev_fill_ipgre_rtnl_message(Link *link, sd_rtnl_message *m) {
267 assert(link->network);
268 assert(link->network->tunnel);
271 netdev = link->network->tunnel;
273 assert(netdev->family == AF_INET);
275 r = sd_rtnl_message_append_string(m, IFLA_IFNAME, netdev->ifname);
277 log_error_netdev(netdev,
278 "Could not append IFLA_IFNAME, attribute: %s",
284 r = sd_rtnl_message_append_u32(m, IFLA_MTU, netdev->mtu);
286 log_error_netdev(netdev,
287 "Could not append IFLA_MTU attribute: %s",
294 r = sd_rtnl_message_append_ether_addr(m, IFLA_ADDRESS, netdev->mac);
296 log_error_netdev(netdev,
297 "Colud not append IFLA_ADDRESS attribute: %s",
303 r = sd_rtnl_message_open_container(m, IFLA_LINKINFO);
305 log_error_netdev(netdev,
306 "Could not append IFLA_LINKINFO attribute: %s",
311 r = sd_rtnl_message_open_container_union(m, IFLA_INFO_DATA,
312 netdev_kind_to_string(netdev->kind));
314 log_error_netdev(netdev,
315 "Could not append IFLA_INFO_DATA attribute: %s",
320 r = sd_rtnl_message_append_u32(m, IFLA_GRE_LINK, link->ifindex);
322 log_error_netdev(netdev,
323 "Could not append IFLA_GRE_LINK attribute: %s",
328 r = sd_rtnl_message_append_in_addr(m, IFLA_GRE_LOCAL, &netdev->local.in);
330 log_error_netdev(netdev,
331 "Could not append IFLA_GRE_LOCAL attribute: %s",
336 r = sd_rtnl_message_append_in_addr(m, IFLA_GRE_REMOTE, &netdev->remote.in);
338 log_error_netdev(netdev,
339 "Could not append IFLA_GRE_REMOTE attribute: %s",
344 r = sd_rtnl_message_append_u8(m, IFLA_GRE_TTL, netdev->ttl);
346 log_error_netdev(netdev,
347 "Could not append IFLA_GRE_TTL attribute: %s",
352 r = sd_rtnl_message_append_u8(m, IFLA_GRE_TOS, netdev->tos);
354 log_error_netdev(netdev,
355 "Could not append IFLA_GRE_TOS attribute: %s",
360 r = sd_rtnl_message_close_container(m);
362 log_error_netdev(netdev,
363 "Could not append IFLA_INFO_DATA attribute: %s",
368 r = sd_rtnl_message_close_container(m);
370 log_error_netdev(netdev,
371 "Could not append IFLA_LINKINFO attribute: %s",
379 static int netdev_fill_vti_rtnl_message(Link *link, sd_rtnl_message *m) {
384 assert(link->network);
385 assert(link->network->tunnel);
388 netdev = link->network->tunnel;
390 assert(netdev->family == AF_INET);
392 r = sd_rtnl_message_append_string(m, IFLA_IFNAME, netdev->ifname);
394 log_error_netdev(netdev,
395 "Could not append IFLA_IFNAME, attribute: %s",
401 r = sd_rtnl_message_append_u32(m, IFLA_MTU, netdev->mtu);
403 log_error_netdev(netdev,
404 "Could not append IFLA_MTU attribute: %s",
411 r = sd_rtnl_message_append_ether_addr(m, IFLA_ADDRESS, netdev->mac);
413 log_error_netdev(netdev,
414 "Colud not append IFLA_ADDRESS attribute: %s",
420 r = sd_rtnl_message_open_container(m, IFLA_LINKINFO);
422 log_error_netdev(netdev,
423 "Could not append IFLA_LINKINFO attribute: %s",
428 r = sd_rtnl_message_open_container_union(m, IFLA_INFO_DATA,
429 netdev_kind_to_string(netdev->kind));
431 log_error_netdev(netdev,
432 "Could not append IFLA_INFO_DATA attribute: %s",
437 r = sd_rtnl_message_append_u32(m, IFLA_VTI_LINK, link->ifindex);
439 log_error_netdev(netdev,
440 "Could not append IFLA_IPTUN_LINK attribute: %s",
445 r = sd_rtnl_message_append_in_addr(m, IFLA_VTI_LOCAL, &netdev->local.in);
447 log_error_netdev(netdev,
448 "Could not append IFLA_IPTUN_LOCAL attribute: %s",
453 r = sd_rtnl_message_append_in_addr(m, IFLA_VTI_REMOTE, &netdev->remote.in);
455 log_error_netdev(netdev,
456 "Could not append IFLA_IPTUN_REMOTE attribute: %s",
461 r = sd_rtnl_message_close_container(m);
463 log_error_netdev(netdev,
464 "Could not append IFLA_INFO_DATA attribute: %s",
469 r = sd_rtnl_message_close_container(m);
471 log_error_netdev(netdev,
472 "Could not append IFLA_LINKINFO attribute: %s",
480 int netdev_create_tunnel(NetDev *netdev, Link *link, sd_rtnl_message_handler_t callback) {
481 _cleanup_rtnl_message_unref_ sd_rtnl_message *m = NULL;
485 assert(netdev->ifname);
486 assert(netdev->manager);
487 assert(netdev->manager->rtnl);
489 assert(link->network);
490 assert(link->network->tunnel == netdev);
492 r = sd_rtnl_message_new_link(netdev->manager->rtnl, &m, RTM_NEWLINK, 0);
494 log_error_netdev(netdev,
495 "Could not allocate RTM_NEWLINK message: %s",
500 switch(netdev->kind) {
501 case NETDEV_KIND_IPIP:
502 r = netdev_fill_ipip_rtnl_message(link, m);
506 case NETDEV_KIND_SIT:
507 r = netdev_fill_sit_rtnl_message(link, m);
511 case NETDEV_KIND_VTI:
512 netdev_fill_vti_rtnl_message(link, m);
516 case NETDEV_KIND_GRE:
517 r = netdev_fill_ipgre_rtnl_message(link, m);
525 r = sd_rtnl_call_async(netdev->manager->rtnl, m, callback, link, 0, NULL);
527 log_error_netdev(netdev,
528 "Could not send rtnetlink message: %s", strerror(-r));
534 log_debug_netdev(netdev, "Creating tunnel netdev: %s",
535 netdev_kind_to_string(netdev->kind));
537 netdev->state = NETDEV_STATE_CREATING;
542 int config_parse_tunnel_address(const char *unit,
543 const char *filename,
546 unsigned section_line,
552 NetDev *n = userdata;
553 union in_addr_union *addr = data;
561 r = net_parse_inaddr(rvalue, &n->family, addr);
563 log_syntax(unit, LOG_ERR, filename, line, EINVAL,
564 "Tunnel address is invalid, ignoring assignment: %s", rvalue);