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"
35 static int netdev_fill_ipip_rtnl_message(Link *link, sd_rtnl_message *m) {
40 assert(link->network);
41 assert(link->network->tunnel);
44 netdev = link->network->tunnel;
46 r = sd_rtnl_message_append_string(m, IFLA_IFNAME, netdev->ifname);
48 log_error_netdev(netdev,
49 "Could not append IFLA_IFNAME, attribute: %s",
55 r = sd_rtnl_message_append_u32(m, IFLA_MTU, netdev->mtu);
57 log_error_netdev(netdev,
58 "Could not append IFLA_MTU attribute: %s",
65 r = sd_rtnl_message_append_ether_addr(m, IFLA_ADDRESS, netdev->mac);
67 log_error_netdev(netdev,
68 "Colud not append IFLA_ADDRESS attribute: %s",
74 r = sd_rtnl_message_open_container(m, IFLA_LINKINFO);
76 log_error_netdev(netdev,
77 "Could not append IFLA_LINKINFO attribute: %s",
82 r = sd_rtnl_message_open_container_union(m, IFLA_INFO_DATA,
83 netdev_kind_to_string(netdev->kind));
85 log_error_netdev(netdev,
86 "Could not append IFLA_INFO_DATA attribute: %s",
91 r = sd_rtnl_message_append_u32(m, IFLA_IPTUN_LINK, link->ifindex);
93 log_error_netdev(netdev,
94 "Could not append IFLA_IPTUN_LINK attribute: %s",
99 r = sd_rtnl_message_append_in_addr(m, IFLA_IPTUN_LOCAL, &netdev->local);
101 log_error_netdev(netdev,
102 "Could not append IFLA_IPTUN_LOCAL attribute: %s",
107 r = sd_rtnl_message_append_in_addr(m, IFLA_IPTUN_REMOTE, &netdev->remote);
109 log_error_netdev(netdev,
110 "Could not append IFLA_IPTUN_REMOTE attribute: %s",
115 r = sd_rtnl_message_append_u8(m, IFLA_IPTUN_TTL, netdev->ttl);
117 log_error_netdev(netdev,
118 "Could not append IFLA_IPTUN_TTL attribute: %s",
123 r = sd_rtnl_message_close_container(m);
125 log_error_netdev(netdev,
126 "Could not append IFLA_INFO_DATA attribute: %s",
131 r = sd_rtnl_message_close_container(m);
133 log_error_netdev(netdev,
134 "Could not append IFLA_LINKINFO attribute: %s",
142 static int netdev_fill_sit_rtnl_message(Link *link, sd_rtnl_message *m) {
147 assert(link->network);
148 assert(link->network->tunnel);
151 netdev = link->network->tunnel;
153 r = sd_rtnl_message_append_string(m, IFLA_IFNAME, netdev->ifname);
155 log_error_netdev(netdev,
156 "Could not append IFLA_IFNAME, attribute: %s",
162 r = sd_rtnl_message_append_u32(m, IFLA_MTU, netdev->mtu);
164 log_error_netdev(netdev,
165 "Could not append IFLA_MTU attribute: %s",
172 r = sd_rtnl_message_append_ether_addr(m, IFLA_ADDRESS, netdev->mac);
174 log_error_netdev(netdev,
175 "Colud not append IFLA_ADDRESS attribute: %s",
181 r = sd_rtnl_message_open_container(m, IFLA_LINKINFO);
183 log_error_netdev(netdev,
184 "Could not append IFLA_LINKINFO attribute: %s",
189 r = sd_rtnl_message_open_container_union(m, IFLA_INFO_DATA,
190 netdev_kind_to_string(netdev->kind));
192 log_error_netdev(netdev,
193 "Could not append IFLA_INFO_DATA attribute: %s",
198 r = sd_rtnl_message_append_u32(m, IFLA_IPTUN_LINK, link->ifindex);
200 log_error_netdev(netdev,
201 "Could not append IFLA_IPTUN_LINK attribute: %s",
206 r = sd_rtnl_message_append_in_addr(m, IFLA_IPTUN_LOCAL, &netdev->local);
208 log_error_netdev(netdev,
209 "Could not append IFLA_IPTUN_LOCAL attribute: %s",
214 r = sd_rtnl_message_append_in_addr(m, IFLA_IPTUN_REMOTE, &netdev->remote);
216 log_error_netdev(netdev,
217 "Could not append IFLA_IPTUN_REMOTE attribute: %s",
222 r = sd_rtnl_message_append_u8(m, IFLA_IPTUN_TOS, netdev->tos);
224 log_error_netdev(netdev,
225 "Could not append IFLA_IPTUN_TOS attribute: %s",
230 r = sd_rtnl_message_append_u8(m, IFLA_IPTUN_PMTUDISC, netdev->tunnel_pmtudisc);
232 log_error_netdev(netdev,
233 "Could not append IFLA_IPTUN_PMTUDISC attribute: %s",
238 r = sd_rtnl_message_close_container(m);
240 log_error_netdev(netdev,
241 "Could not append IFLA_INFO_DATA attribute: %s",
246 r = sd_rtnl_message_close_container(m);
248 log_error_netdev(netdev,
249 "Could not append IFLA_LINKINFO attribute: %s",
257 static int netdev_fill_ipgre_rtnl_message(Link *link, sd_rtnl_message *m) {
262 assert(link->network);
263 assert(link->network->tunnel);
266 netdev = link->network->tunnel;
268 r = sd_rtnl_message_append_string(m, IFLA_IFNAME, netdev->ifname);
270 log_error_netdev(netdev,
271 "Could not append IFLA_IFNAME, attribute: %s",
277 r = sd_rtnl_message_append_u32(m, IFLA_MTU, netdev->mtu);
279 log_error_netdev(netdev,
280 "Could not append IFLA_MTU attribute: %s",
287 r = sd_rtnl_message_append_ether_addr(m, IFLA_ADDRESS, netdev->mac);
289 log_error_netdev(netdev,
290 "Colud not append IFLA_ADDRESS attribute: %s",
296 r = sd_rtnl_message_open_container(m, IFLA_LINKINFO);
298 log_error_netdev(netdev,
299 "Could not append IFLA_LINKINFO attribute: %s",
304 r = sd_rtnl_message_open_container_union(m, IFLA_INFO_DATA,
305 netdev_kind_to_string(netdev->kind));
307 log_error_netdev(netdev,
308 "Could not append IFLA_INFO_DATA attribute: %s",
313 r = sd_rtnl_message_append_u32(m, IFLA_GRE_LINK, link->ifindex);
315 log_error_netdev(netdev,
316 "Could not append IFLA_GRE_LINK attribute: %s",
321 r = sd_rtnl_message_append_in_addr(m, IFLA_GRE_LOCAL, &netdev->local);
323 log_error_netdev(netdev,
324 "Could not append IFLA_GRE_LOCAL attribute: %s",
329 r = sd_rtnl_message_append_in_addr(m, IFLA_GRE_REMOTE, &netdev->remote);
331 log_error_netdev(netdev,
332 "Could not append IFLA_GRE_REMOTE attribute: %s",
337 r = sd_rtnl_message_append_u8(m, IFLA_GRE_TTL, netdev->ttl);
339 log_error_netdev(netdev,
340 "Could not append IFLA_GRE_TTL attribute: %s",
345 r = sd_rtnl_message_append_u8(m, IFLA_GRE_TOS, netdev->tos);
347 log_error_netdev(netdev,
348 "Could not append IFLA_GRE_TOS attribute: %s",
353 r = sd_rtnl_message_close_container(m);
355 log_error_netdev(netdev,
356 "Could not append IFLA_INFO_DATA attribute: %s",
361 r = sd_rtnl_message_close_container(m);
363 log_error_netdev(netdev,
364 "Could not append IFLA_LINKINFO attribute: %s",
372 static int netdev_fill_vti_rtnl_message(Link *link, sd_rtnl_message *m) {
377 assert(link->network);
378 assert(link->network->tunnel);
381 netdev = link->network->tunnel;
383 r = sd_rtnl_message_append_string(m, IFLA_IFNAME, netdev->ifname);
385 log_error_netdev(netdev,
386 "Could not append IFLA_IFNAME, attribute: %s",
392 r = sd_rtnl_message_append_u32(m, IFLA_MTU, netdev->mtu);
394 log_error_netdev(netdev,
395 "Could not append IFLA_MTU attribute: %s",
402 r = sd_rtnl_message_append_ether_addr(m, IFLA_ADDRESS, netdev->mac);
404 log_error_netdev(netdev,
405 "Colud not append IFLA_ADDRESS attribute: %s",
411 r = sd_rtnl_message_open_container(m, IFLA_LINKINFO);
413 log_error_netdev(netdev,
414 "Could not append IFLA_LINKINFO attribute: %s",
419 r = sd_rtnl_message_open_container_union(m, IFLA_INFO_DATA,
420 netdev_kind_to_string(netdev->kind));
422 log_error_netdev(netdev,
423 "Could not append IFLA_INFO_DATA attribute: %s",
428 r = sd_rtnl_message_append_u32(m, IFLA_VTI_LINK, link->ifindex);
430 log_error_netdev(netdev,
431 "Could not append IFLA_IPTUN_LINK attribute: %s",
436 r = sd_rtnl_message_append_in_addr(m, IFLA_VTI_LOCAL, &netdev->local);
438 log_error_netdev(netdev,
439 "Could not append IFLA_IPTUN_LOCAL attribute: %s",
444 r = sd_rtnl_message_append_in_addr(m, IFLA_VTI_REMOTE, &netdev->remote);
446 log_error_netdev(netdev,
447 "Could not append IFLA_IPTUN_REMOTE attribute: %s",
452 r = sd_rtnl_message_close_container(m);
454 log_error_netdev(netdev,
455 "Could not append IFLA_INFO_DATA attribute: %s",
460 r = sd_rtnl_message_close_container(m);
462 log_error_netdev(netdev,
463 "Could not append IFLA_LINKINFO attribute: %s",
471 int netdev_create_tunnel(Link *link, sd_rtnl_message_handler_t callback) {
472 _cleanup_rtnl_message_unref_ sd_rtnl_message *m = NULL;
477 assert(link->network);
478 assert(link->network->tunnel);
480 netdev = link->network->tunnel;
483 assert(netdev->ifname);
484 assert(netdev->manager);
485 assert(netdev->manager->rtnl);
487 r = sd_rtnl_message_new_link(netdev->manager->rtnl, &m, RTM_NEWLINK, 0);
489 log_error_netdev(netdev,
490 "Could not allocate RTM_NEWLINK message: %s",
495 switch(netdev->kind) {
496 case NETDEV_KIND_IPIP:
497 r = netdev_fill_ipip_rtnl_message(link, m);
501 case NETDEV_KIND_SIT:
502 r = netdev_fill_sit_rtnl_message(link, m);
506 case NETDEV_KIND_VTI:
507 netdev_fill_vti_rtnl_message(link, m);
511 case NETDEV_KIND_GRE:
512 r = netdev_fill_ipgre_rtnl_message(link, m);
520 r = sd_rtnl_call_async(netdev->manager->rtnl, m, callback, netdev, 0, NULL);
522 log_error_netdev(netdev,
523 "Could not send rtnetlink message: %s", strerror(-r));
527 log_debug_netdev(netdev, "Creating tunnel netdev: %s",
528 netdev_kind_to_string(netdev->kind));
530 netdev->state = NETDEV_STATE_CREATING;