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 assert(netdev->family == AF_INET);
48 r = sd_rtnl_message_append_string(m, IFLA_IFNAME, netdev->ifname);
50 log_error_netdev(netdev,
51 "Could not append IFLA_IFNAME, attribute: %s",
57 r = sd_rtnl_message_append_u32(m, IFLA_MTU, netdev->mtu);
59 log_error_netdev(netdev,
60 "Could not append IFLA_MTU attribute: %s",
67 r = sd_rtnl_message_append_ether_addr(m, IFLA_ADDRESS, netdev->mac);
69 log_error_netdev(netdev,
70 "Colud not append IFLA_ADDRESS attribute: %s",
76 r = sd_rtnl_message_open_container(m, IFLA_LINKINFO);
78 log_error_netdev(netdev,
79 "Could not append IFLA_LINKINFO attribute: %s",
84 r = sd_rtnl_message_open_container_union(m, IFLA_INFO_DATA,
85 netdev_kind_to_string(netdev->kind));
87 log_error_netdev(netdev,
88 "Could not append IFLA_INFO_DATA attribute: %s",
93 r = sd_rtnl_message_append_u32(m, IFLA_IPTUN_LINK, link->ifindex);
95 log_error_netdev(netdev,
96 "Could not append IFLA_IPTUN_LINK attribute: %s",
101 r = sd_rtnl_message_append_in_addr(m, IFLA_IPTUN_LOCAL, &netdev->local.in);
103 log_error_netdev(netdev,
104 "Could not append IFLA_IPTUN_LOCAL attribute: %s",
109 r = sd_rtnl_message_append_in_addr(m, IFLA_IPTUN_REMOTE, &netdev->remote.in);
111 log_error_netdev(netdev,
112 "Could not append IFLA_IPTUN_REMOTE attribute: %s",
117 r = sd_rtnl_message_append_u8(m, IFLA_IPTUN_TTL, netdev->ttl);
119 log_error_netdev(netdev,
120 "Could not append IFLA_IPTUN_TTL attribute: %s",
125 r = sd_rtnl_message_close_container(m);
127 log_error_netdev(netdev,
128 "Could not append IFLA_INFO_DATA attribute: %s",
133 r = sd_rtnl_message_close_container(m);
135 log_error_netdev(netdev,
136 "Could not append IFLA_LINKINFO attribute: %s",
144 static int netdev_fill_sit_rtnl_message(Link *link, sd_rtnl_message *m) {
149 assert(link->network);
150 assert(link->network->tunnel);
153 netdev = link->network->tunnel;
155 assert(netdev->family == AF_INET);
157 r = sd_rtnl_message_append_string(m, IFLA_IFNAME, netdev->ifname);
159 log_error_netdev(netdev,
160 "Could not append IFLA_IFNAME, attribute: %s",
166 r = sd_rtnl_message_append_u32(m, IFLA_MTU, netdev->mtu);
168 log_error_netdev(netdev,
169 "Could not append IFLA_MTU attribute: %s",
176 r = sd_rtnl_message_append_ether_addr(m, IFLA_ADDRESS, netdev->mac);
178 log_error_netdev(netdev,
179 "Colud not append IFLA_ADDRESS attribute: %s",
185 r = sd_rtnl_message_open_container(m, IFLA_LINKINFO);
187 log_error_netdev(netdev,
188 "Could not append IFLA_LINKINFO attribute: %s",
193 r = sd_rtnl_message_open_container_union(m, IFLA_INFO_DATA,
194 netdev_kind_to_string(netdev->kind));
196 log_error_netdev(netdev,
197 "Could not append IFLA_INFO_DATA attribute: %s",
202 r = sd_rtnl_message_append_u32(m, IFLA_IPTUN_LINK, link->ifindex);
204 log_error_netdev(netdev,
205 "Could not append IFLA_IPTUN_LINK attribute: %s",
210 r = sd_rtnl_message_append_in_addr(m, IFLA_IPTUN_LOCAL, &netdev->local.in);
212 log_error_netdev(netdev,
213 "Could not append IFLA_IPTUN_LOCAL attribute: %s",
218 r = sd_rtnl_message_append_in_addr(m, IFLA_IPTUN_REMOTE, &netdev->remote.in);
220 log_error_netdev(netdev,
221 "Could not append IFLA_IPTUN_REMOTE attribute: %s",
226 r = sd_rtnl_message_append_u8(m, IFLA_IPTUN_TOS, netdev->tos);
228 log_error_netdev(netdev,
229 "Could not append IFLA_IPTUN_TOS attribute: %s",
234 r = sd_rtnl_message_append_u8(m, IFLA_IPTUN_PMTUDISC, netdev->tunnel_pmtudisc);
236 log_error_netdev(netdev,
237 "Could not append IFLA_IPTUN_PMTUDISC attribute: %s",
242 r = sd_rtnl_message_close_container(m);
244 log_error_netdev(netdev,
245 "Could not append IFLA_INFO_DATA attribute: %s",
250 r = sd_rtnl_message_close_container(m);
252 log_error_netdev(netdev,
253 "Could not append IFLA_LINKINFO attribute: %s",
261 static int netdev_fill_ipgre_rtnl_message(Link *link, sd_rtnl_message *m) {
266 assert(link->network);
267 assert(link->network->tunnel);
270 netdev = link->network->tunnel;
272 assert(netdev->family == AF_INET);
274 r = sd_rtnl_message_append_string(m, IFLA_IFNAME, netdev->ifname);
276 log_error_netdev(netdev,
277 "Could not append IFLA_IFNAME, attribute: %s",
283 r = sd_rtnl_message_append_u32(m, IFLA_MTU, netdev->mtu);
285 log_error_netdev(netdev,
286 "Could not append IFLA_MTU attribute: %s",
293 r = sd_rtnl_message_append_ether_addr(m, IFLA_ADDRESS, netdev->mac);
295 log_error_netdev(netdev,
296 "Colud not append IFLA_ADDRESS attribute: %s",
302 r = sd_rtnl_message_open_container(m, IFLA_LINKINFO);
304 log_error_netdev(netdev,
305 "Could not append IFLA_LINKINFO attribute: %s",
310 r = sd_rtnl_message_open_container_union(m, IFLA_INFO_DATA,
311 netdev_kind_to_string(netdev->kind));
313 log_error_netdev(netdev,
314 "Could not append IFLA_INFO_DATA attribute: %s",
319 r = sd_rtnl_message_append_u32(m, IFLA_GRE_LINK, link->ifindex);
321 log_error_netdev(netdev,
322 "Could not append IFLA_GRE_LINK attribute: %s",
327 r = sd_rtnl_message_append_in_addr(m, IFLA_GRE_LOCAL, &netdev->local.in);
329 log_error_netdev(netdev,
330 "Could not append IFLA_GRE_LOCAL attribute: %s",
335 r = sd_rtnl_message_append_in_addr(m, IFLA_GRE_REMOTE, &netdev->remote.in);
337 log_error_netdev(netdev,
338 "Could not append IFLA_GRE_REMOTE attribute: %s",
343 r = sd_rtnl_message_append_u8(m, IFLA_GRE_TTL, netdev->ttl);
345 log_error_netdev(netdev,
346 "Could not append IFLA_GRE_TTL attribute: %s",
351 r = sd_rtnl_message_append_u8(m, IFLA_GRE_TOS, netdev->tos);
353 log_error_netdev(netdev,
354 "Could not append IFLA_GRE_TOS attribute: %s",
359 r = sd_rtnl_message_close_container(m);
361 log_error_netdev(netdev,
362 "Could not append IFLA_INFO_DATA attribute: %s",
367 r = sd_rtnl_message_close_container(m);
369 log_error_netdev(netdev,
370 "Could not append IFLA_LINKINFO attribute: %s",
378 static int netdev_fill_vti_rtnl_message(Link *link, sd_rtnl_message *m) {
383 assert(link->network);
384 assert(link->network->tunnel);
387 netdev = link->network->tunnel;
389 assert(netdev->family == AF_INET);
391 r = sd_rtnl_message_append_string(m, IFLA_IFNAME, netdev->ifname);
393 log_error_netdev(netdev,
394 "Could not append IFLA_IFNAME, attribute: %s",
400 r = sd_rtnl_message_append_u32(m, IFLA_MTU, netdev->mtu);
402 log_error_netdev(netdev,
403 "Could not append IFLA_MTU attribute: %s",
410 r = sd_rtnl_message_append_ether_addr(m, IFLA_ADDRESS, netdev->mac);
412 log_error_netdev(netdev,
413 "Colud not append IFLA_ADDRESS attribute: %s",
419 r = sd_rtnl_message_open_container(m, IFLA_LINKINFO);
421 log_error_netdev(netdev,
422 "Could not append IFLA_LINKINFO attribute: %s",
427 r = sd_rtnl_message_open_container_union(m, IFLA_INFO_DATA,
428 netdev_kind_to_string(netdev->kind));
430 log_error_netdev(netdev,
431 "Could not append IFLA_INFO_DATA attribute: %s",
436 r = sd_rtnl_message_append_u32(m, IFLA_VTI_LINK, link->ifindex);
438 log_error_netdev(netdev,
439 "Could not append IFLA_IPTUN_LINK attribute: %s",
444 r = sd_rtnl_message_append_in_addr(m, IFLA_VTI_LOCAL, &netdev->local.in);
446 log_error_netdev(netdev,
447 "Could not append IFLA_IPTUN_LOCAL attribute: %s",
452 r = sd_rtnl_message_append_in_addr(m, IFLA_VTI_REMOTE, &netdev->remote.in);
454 log_error_netdev(netdev,
455 "Could not append IFLA_IPTUN_REMOTE attribute: %s",
460 r = sd_rtnl_message_close_container(m);
462 log_error_netdev(netdev,
463 "Could not append IFLA_INFO_DATA attribute: %s",
468 r = sd_rtnl_message_close_container(m);
470 log_error_netdev(netdev,
471 "Could not append IFLA_LINKINFO attribute: %s",
479 int netdev_create_tunnel(NetDev *netdev, Link *link, sd_rtnl_message_handler_t callback) {
480 _cleanup_rtnl_message_unref_ sd_rtnl_message *m = NULL;
484 assert(netdev->ifname);
485 assert(netdev->manager);
486 assert(netdev->manager->rtnl);
488 assert(link->network);
489 assert(link->network->tunnel == netdev);
491 r = sd_rtnl_message_new_link(netdev->manager->rtnl, &m, RTM_NEWLINK, 0);
493 log_error_netdev(netdev,
494 "Could not allocate RTM_NEWLINK message: %s",
499 switch(netdev->kind) {
500 case NETDEV_KIND_IPIP:
501 r = netdev_fill_ipip_rtnl_message(link, m);
505 case NETDEV_KIND_SIT:
506 r = netdev_fill_sit_rtnl_message(link, m);
510 case NETDEV_KIND_VTI:
511 netdev_fill_vti_rtnl_message(link, m);
515 case NETDEV_KIND_GRE:
516 r = netdev_fill_ipgre_rtnl_message(link, m);
524 r = sd_rtnl_call_async(netdev->manager->rtnl, m, callback, link, 0, NULL);
526 log_error_netdev(netdev,
527 "Could not send rtnetlink message: %s", strerror(-r));
531 log_debug_netdev(netdev, "Creating tunnel netdev: %s",
532 netdev_kind_to_string(netdev->kind));
534 netdev->state = NETDEV_STATE_CREATING;