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"
34 static int netdev_fill_ipip_rtnl_message(Link *link, sd_rtnl_message *m) {
39 assert(link->network);
40 assert(link->network->tunnel);
43 netdev = link->network->tunnel;
45 r = sd_rtnl_message_append_string(m, IFLA_IFNAME, netdev->ifname);
47 log_error_netdev(netdev,
48 "Could not append IFLA_IFNAME, attribute: %s",
54 r = sd_rtnl_message_append_u32(m, IFLA_MTU, netdev->mtu);
56 log_error_netdev(netdev,
57 "Could not append IFLA_MTU attribute: %s",
63 r = sd_rtnl_message_open_container(m, IFLA_LINKINFO);
65 log_error_netdev(netdev,
66 "Could not append IFLA_LINKINFO attribute: %s",
71 r = sd_rtnl_message_open_container_union(m, IFLA_INFO_DATA,
72 netdev_kind_to_string(netdev->kind));
74 log_error_netdev(netdev,
75 "Could not append IFLA_INFO_DATA attribute: %s",
80 r = sd_rtnl_message_append_u32(m, IFLA_IPTUN_LINK, link->ifindex);
82 log_error_netdev(netdev,
83 "Could not append IFLA_IPTUN_LINK attribute: %s",
88 r = sd_rtnl_message_append_in_addr(m, IFLA_IPTUN_LOCAL, &netdev->tunnel_local);
90 log_error_netdev(netdev,
91 "Could not append IFLA_IPTUN_LOCAL attribute: %s",
96 r = sd_rtnl_message_append_in_addr(m, IFLA_IPTUN_REMOTE, &netdev->tunnel_remote);
98 log_error_netdev(netdev,
99 "Could not append IFLA_IPTUN_REMOTE attribute: %s",
104 r = sd_rtnl_message_append_u8(m, IFLA_IPTUN_TTL, netdev->tunnel_ttl);
106 log_error_netdev(netdev,
107 "Could not append IFLA_IPTUN_TTL attribute: %s",
112 r = sd_rtnl_message_close_container(m);
114 log_error_netdev(netdev,
115 "Could not append IFLA_INFO_DATA attribute: %s",
120 r = sd_rtnl_message_close_container(m);
122 log_error_netdev(netdev,
123 "Could not append IFLA_LINKINFO attribute: %s",
131 static int netdev_fill_sit_rtnl_message(Link *link, sd_rtnl_message *m) {
136 assert(link->network);
137 assert(link->network->tunnel);
140 netdev = link->network->tunnel;
142 r = sd_rtnl_message_append_string(m, IFLA_IFNAME, netdev->ifname);
144 log_error_netdev(netdev,
145 "Could not append IFLA_IFNAME, attribute: %s",
151 r = sd_rtnl_message_append_u32(m, IFLA_MTU, netdev->mtu);
153 log_error_netdev(netdev,
154 "Could not append IFLA_MTU attribute: %s",
160 r = sd_rtnl_message_open_container(m, IFLA_LINKINFO);
162 log_error_netdev(netdev,
163 "Could not append IFLA_LINKINFO attribute: %s",
168 r = sd_rtnl_message_open_container_union(m, IFLA_INFO_DATA,
169 netdev_kind_to_string(netdev->kind));
171 log_error_netdev(netdev,
172 "Could not append IFLA_INFO_DATA attribute: %s",
177 r = sd_rtnl_message_append_u32(m, IFLA_IPTUN_LINK, link->ifindex);
179 log_error_netdev(netdev,
180 "Could not append IFLA_IPTUN_LINK attribute: %s",
185 r = sd_rtnl_message_append_in_addr(m, IFLA_IPTUN_LOCAL, &netdev->tunnel_local);
187 log_error_netdev(netdev,
188 "Could not append IFLA_IPTUN_LOCAL attribute: %s",
193 r = sd_rtnl_message_append_in_addr(m, IFLA_IPTUN_REMOTE, &netdev->tunnel_remote);
195 log_error_netdev(netdev,
196 "Could not append IFLA_IPTUN_REMOTE attribute: %s",
201 r = sd_rtnl_message_append_u8(m, IFLA_IPTUN_TOS, netdev->tunnel_tos);
203 log_error_netdev(netdev,
204 "Could not append IFLA_IPTUN_TOS attribute: %s",
209 r = sd_rtnl_message_append_u8(m, IFLA_IPTUN_PMTUDISC, netdev->tunnel_pmtudisc);
211 log_error_netdev(netdev,
212 "Could not append IFLA_IPTUN_PMTUDISC attribute: %s",
217 r = sd_rtnl_message_close_container(m);
219 log_error_netdev(netdev,
220 "Could not append IFLA_INFO_DATA attribute: %s",
225 r = sd_rtnl_message_close_container(m);
227 log_error_netdev(netdev,
228 "Could not append IFLA_LINKINFO attribute: %s",
236 static int netdev_fill_ipgre_rtnl_message(Link *link, sd_rtnl_message *m) {
241 assert(link->network);
242 assert(link->network->tunnel);
245 netdev = link->network->tunnel;
247 r = sd_rtnl_message_append_string(m, IFLA_IFNAME, netdev->ifname);
249 log_error_netdev(netdev,
250 "Could not append IFLA_IFNAME, attribute: %s",
256 r = sd_rtnl_message_append_u32(m, IFLA_MTU, netdev->mtu);
258 log_error_netdev(netdev,
259 "Could not append IFLA_MTU attribute: %s",
265 r = sd_rtnl_message_open_container(m, IFLA_LINKINFO);
267 log_error_netdev(netdev,
268 "Could not append IFLA_LINKINFO attribute: %s",
273 r = sd_rtnl_message_open_container_union(m, IFLA_INFO_DATA,
274 netdev_kind_to_string(netdev->kind));
276 log_error_netdev(netdev,
277 "Could not append IFLA_INFO_DATA attribute: %s",
282 r = sd_rtnl_message_append_u32(m, IFLA_GRE_LINK, link->ifindex);
284 log_error_netdev(netdev,
285 "Could not append IFLA_GRE_LINK attribute: %s",
290 r = sd_rtnl_message_append_in_addr(m, IFLA_GRE_LOCAL, &netdev->tunnel_local);
292 log_error_netdev(netdev,
293 "Could not append IFLA_GRE_LOCAL attribute: %s",
298 r = sd_rtnl_message_append_in_addr(m, IFLA_GRE_REMOTE, &netdev->tunnel_remote);
300 log_error_netdev(netdev,
301 "Could not append IFLA_GRE_REMOTE attribute: %s",
306 r = sd_rtnl_message_append_u8(m, IFLA_GRE_TTL, netdev->tunnel_ttl);
308 log_error_netdev(netdev,
309 "Could not append IFLA_GRE_TTL attribute: %s",
314 r = sd_rtnl_message_append_u8(m, IFLA_GRE_TOS, netdev->tunnel_tos);
316 log_error_netdev(netdev,
317 "Could not append IFLA_GRE_TOS attribute: %s",
322 r = sd_rtnl_message_close_container(m);
324 log_error_netdev(netdev,
325 "Could not append IFLA_INFO_DATA attribute: %s",
330 r = sd_rtnl_message_close_container(m);
332 log_error_netdev(netdev,
333 "Could not append IFLA_LINKINFO attribute: %s",
341 static int netdev_fill_vti_rtnl_message(Link *link, sd_rtnl_message *m) {
346 assert(link->network);
347 assert(link->network->tunnel);
350 netdev = link->network->tunnel;
352 r = sd_rtnl_message_append_string(m, IFLA_IFNAME, netdev->ifname);
354 log_error_netdev(netdev,
355 "Could not append IFLA_IFNAME, attribute: %s",
361 r = sd_rtnl_message_append_u32(m, IFLA_MTU, netdev->mtu);
363 log_error_netdev(netdev,
364 "Could not append IFLA_MTU attribute: %s",
370 r = sd_rtnl_message_open_container(m, IFLA_LINKINFO);
372 log_error_netdev(netdev,
373 "Could not append IFLA_LINKINFO attribute: %s",
378 r = sd_rtnl_message_open_container_union(m, IFLA_INFO_DATA,
379 netdev_kind_to_string(netdev->kind));
381 log_error_netdev(netdev,
382 "Could not append IFLA_INFO_DATA attribute: %s",
387 r = sd_rtnl_message_append_u32(m, IFLA_VTI_LINK, link->ifindex);
389 log_error_netdev(netdev,
390 "Could not append IFLA_IPTUN_LINK attribute: %s",
395 r = sd_rtnl_message_append_in_addr(m, IFLA_VTI_LOCAL, &netdev->tunnel_local);
397 log_error_netdev(netdev,
398 "Could not append IFLA_IPTUN_LOCAL attribute: %s",
403 r = sd_rtnl_message_append_in_addr(m, IFLA_VTI_REMOTE, &netdev->tunnel_remote);
405 log_error_netdev(netdev,
406 "Could not append IFLA_IPTUN_REMOTE attribute: %s",
411 r = sd_rtnl_message_close_container(m);
413 log_error_netdev(netdev,
414 "Could not append IFLA_INFO_DATA attribute: %s",
419 r = sd_rtnl_message_close_container(m);
421 log_error_netdev(netdev,
422 "Could not append IFLA_LINKINFO attribute: %s",
430 int netdev_create_tunnel(Link *link, sd_rtnl_message_handler_t callback) {
431 _cleanup_rtnl_message_unref_ sd_rtnl_message *m = NULL;
436 assert(link->network);
437 assert(link->network->tunnel);
439 netdev = link->network->tunnel;
442 assert(netdev->ifname);
443 assert(netdev->manager);
444 assert(netdev->manager->rtnl);
446 r = sd_rtnl_message_new_link(netdev->manager->rtnl, &m, RTM_NEWLINK, 0);
448 log_error_netdev(netdev,
449 "Could not allocate RTM_NEWLINK message: %s",
454 switch(netdev->kind) {
455 case NETDEV_KIND_IPIP:
456 r = netdev_fill_ipip_rtnl_message(link, m);
460 case NETDEV_KIND_SIT:
461 r = netdev_fill_sit_rtnl_message(link, m);
465 case NETDEV_KIND_VTI:
466 netdev_fill_vti_rtnl_message(link, m);
470 case NETDEV_KIND_GRE:
471 r = netdev_fill_ipgre_rtnl_message(link, m);
479 r = sd_rtnl_call_async(netdev->manager->rtnl, m, callback, netdev, 0, NULL);
481 log_error_netdev(netdev,
482 "Could not send rtnetlink message: %s", strerror(-r));
486 log_debug_netdev(netdev, "Creating tunnel netdev: %s",
487 netdev_kind_to_string(netdev->kind));
489 netdev->state = NETDEV_STATE_CREATING;