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",
64 r = sd_rtnl_message_append_ether_addr(m, IFLA_ADDRESS, netdev->mac);
66 log_error_netdev(netdev,
67 "Colud not append IFLA_ADDRESS attribute: %s",
73 r = sd_rtnl_message_open_container(m, IFLA_LINKINFO);
75 log_error_netdev(netdev,
76 "Could not append IFLA_LINKINFO attribute: %s",
81 r = sd_rtnl_message_open_container_union(m, IFLA_INFO_DATA,
82 netdev_kind_to_string(netdev->kind));
84 log_error_netdev(netdev,
85 "Could not append IFLA_INFO_DATA attribute: %s",
90 r = sd_rtnl_message_append_u32(m, IFLA_IPTUN_LINK, link->ifindex);
92 log_error_netdev(netdev,
93 "Could not append IFLA_IPTUN_LINK attribute: %s",
98 r = sd_rtnl_message_append_in_addr(m, IFLA_IPTUN_LOCAL, &netdev->local);
100 log_error_netdev(netdev,
101 "Could not append IFLA_IPTUN_LOCAL attribute: %s",
106 r = sd_rtnl_message_append_in_addr(m, IFLA_IPTUN_REMOTE, &netdev->remote);
108 log_error_netdev(netdev,
109 "Could not append IFLA_IPTUN_REMOTE attribute: %s",
114 r = sd_rtnl_message_append_u8(m, IFLA_IPTUN_TTL, netdev->ttl);
116 log_error_netdev(netdev,
117 "Could not append IFLA_IPTUN_TTL attribute: %s",
122 r = sd_rtnl_message_close_container(m);
124 log_error_netdev(netdev,
125 "Could not append IFLA_INFO_DATA attribute: %s",
130 r = sd_rtnl_message_close_container(m);
132 log_error_netdev(netdev,
133 "Could not append IFLA_LINKINFO attribute: %s",
141 static int netdev_fill_sit_rtnl_message(Link *link, sd_rtnl_message *m) {
146 assert(link->network);
147 assert(link->network->tunnel);
150 netdev = link->network->tunnel;
152 r = sd_rtnl_message_append_string(m, IFLA_IFNAME, netdev->ifname);
154 log_error_netdev(netdev,
155 "Could not append IFLA_IFNAME, attribute: %s",
161 r = sd_rtnl_message_append_u32(m, IFLA_MTU, netdev->mtu);
163 log_error_netdev(netdev,
164 "Could not append IFLA_MTU attribute: %s",
171 r = sd_rtnl_message_append_ether_addr(m, IFLA_ADDRESS, netdev->mac);
173 log_error_netdev(netdev,
174 "Colud not append IFLA_ADDRESS attribute: %s",
180 r = sd_rtnl_message_open_container(m, IFLA_LINKINFO);
182 log_error_netdev(netdev,
183 "Could not append IFLA_LINKINFO attribute: %s",
188 r = sd_rtnl_message_open_container_union(m, IFLA_INFO_DATA,
189 netdev_kind_to_string(netdev->kind));
191 log_error_netdev(netdev,
192 "Could not append IFLA_INFO_DATA attribute: %s",
197 r = sd_rtnl_message_append_u32(m, IFLA_IPTUN_LINK, link->ifindex);
199 log_error_netdev(netdev,
200 "Could not append IFLA_IPTUN_LINK attribute: %s",
205 r = sd_rtnl_message_append_in_addr(m, IFLA_IPTUN_LOCAL, &netdev->local);
207 log_error_netdev(netdev,
208 "Could not append IFLA_IPTUN_LOCAL attribute: %s",
213 r = sd_rtnl_message_append_in_addr(m, IFLA_IPTUN_REMOTE, &netdev->remote);
215 log_error_netdev(netdev,
216 "Could not append IFLA_IPTUN_REMOTE attribute: %s",
221 r = sd_rtnl_message_append_u8(m, IFLA_IPTUN_TOS, netdev->tos);
223 log_error_netdev(netdev,
224 "Could not append IFLA_IPTUN_TOS attribute: %s",
229 r = sd_rtnl_message_append_u8(m, IFLA_IPTUN_PMTUDISC, netdev->tunnel_pmtudisc);
231 log_error_netdev(netdev,
232 "Could not append IFLA_IPTUN_PMTUDISC attribute: %s",
237 r = sd_rtnl_message_close_container(m);
239 log_error_netdev(netdev,
240 "Could not append IFLA_INFO_DATA attribute: %s",
245 r = sd_rtnl_message_close_container(m);
247 log_error_netdev(netdev,
248 "Could not append IFLA_LINKINFO attribute: %s",
256 static int netdev_fill_ipgre_rtnl_message(Link *link, sd_rtnl_message *m) {
261 assert(link->network);
262 assert(link->network->tunnel);
265 netdev = link->network->tunnel;
267 r = sd_rtnl_message_append_string(m, IFLA_IFNAME, netdev->ifname);
269 log_error_netdev(netdev,
270 "Could not append IFLA_IFNAME, attribute: %s",
276 r = sd_rtnl_message_append_u32(m, IFLA_MTU, netdev->mtu);
278 log_error_netdev(netdev,
279 "Could not append IFLA_MTU attribute: %s",
286 r = sd_rtnl_message_append_ether_addr(m, IFLA_ADDRESS, netdev->mac);
288 log_error_netdev(netdev,
289 "Colud not append IFLA_ADDRESS attribute: %s",
295 r = sd_rtnl_message_open_container(m, IFLA_LINKINFO);
297 log_error_netdev(netdev,
298 "Could not append IFLA_LINKINFO attribute: %s",
303 r = sd_rtnl_message_open_container_union(m, IFLA_INFO_DATA,
304 netdev_kind_to_string(netdev->kind));
306 log_error_netdev(netdev,
307 "Could not append IFLA_INFO_DATA attribute: %s",
312 r = sd_rtnl_message_append_u32(m, IFLA_GRE_LINK, link->ifindex);
314 log_error_netdev(netdev,
315 "Could not append IFLA_GRE_LINK attribute: %s",
320 r = sd_rtnl_message_append_in_addr(m, IFLA_GRE_LOCAL, &netdev->local);
322 log_error_netdev(netdev,
323 "Could not append IFLA_GRE_LOCAL attribute: %s",
328 r = sd_rtnl_message_append_in_addr(m, IFLA_GRE_REMOTE, &netdev->remote);
330 log_error_netdev(netdev,
331 "Could not append IFLA_GRE_REMOTE attribute: %s",
336 r = sd_rtnl_message_append_u8(m, IFLA_GRE_TTL, netdev->ttl);
338 log_error_netdev(netdev,
339 "Could not append IFLA_GRE_TTL attribute: %s",
344 r = sd_rtnl_message_append_u8(m, IFLA_GRE_TOS, netdev->tos);
346 log_error_netdev(netdev,
347 "Could not append IFLA_GRE_TOS attribute: %s",
352 r = sd_rtnl_message_close_container(m);
354 log_error_netdev(netdev,
355 "Could not append IFLA_INFO_DATA attribute: %s",
360 r = sd_rtnl_message_close_container(m);
362 log_error_netdev(netdev,
363 "Could not append IFLA_LINKINFO attribute: %s",
371 static int netdev_fill_vti_rtnl_message(Link *link, sd_rtnl_message *m) {
376 assert(link->network);
377 assert(link->network->tunnel);
380 netdev = link->network->tunnel;
382 r = sd_rtnl_message_append_string(m, IFLA_IFNAME, netdev->ifname);
384 log_error_netdev(netdev,
385 "Could not append IFLA_IFNAME, attribute: %s",
391 r = sd_rtnl_message_append_u32(m, IFLA_MTU, netdev->mtu);
393 log_error_netdev(netdev,
394 "Could not append IFLA_MTU attribute: %s",
401 r = sd_rtnl_message_append_ether_addr(m, IFLA_ADDRESS, netdev->mac);
403 log_error_netdev(netdev,
404 "Colud not append IFLA_ADDRESS attribute: %s",
410 r = sd_rtnl_message_open_container(m, IFLA_LINKINFO);
412 log_error_netdev(netdev,
413 "Could not append IFLA_LINKINFO attribute: %s",
418 r = sd_rtnl_message_open_container_union(m, IFLA_INFO_DATA,
419 netdev_kind_to_string(netdev->kind));
421 log_error_netdev(netdev,
422 "Could not append IFLA_INFO_DATA attribute: %s",
427 r = sd_rtnl_message_append_u32(m, IFLA_VTI_LINK, link->ifindex);
429 log_error_netdev(netdev,
430 "Could not append IFLA_IPTUN_LINK attribute: %s",
435 r = sd_rtnl_message_append_in_addr(m, IFLA_VTI_LOCAL, &netdev->local);
437 log_error_netdev(netdev,
438 "Could not append IFLA_IPTUN_LOCAL attribute: %s",
443 r = sd_rtnl_message_append_in_addr(m, IFLA_VTI_REMOTE, &netdev->remote);
445 log_error_netdev(netdev,
446 "Could not append IFLA_IPTUN_REMOTE attribute: %s",
451 r = sd_rtnl_message_close_container(m);
453 log_error_netdev(netdev,
454 "Could not append IFLA_INFO_DATA attribute: %s",
459 r = sd_rtnl_message_close_container(m);
461 log_error_netdev(netdev,
462 "Could not append IFLA_LINKINFO attribute: %s",
470 int netdev_create_tunnel(Link *link, sd_rtnl_message_handler_t callback) {
471 _cleanup_rtnl_message_unref_ sd_rtnl_message *m = NULL;
476 assert(link->network);
477 assert(link->network->tunnel);
479 netdev = link->network->tunnel;
482 assert(netdev->ifname);
483 assert(netdev->manager);
484 assert(netdev->manager->rtnl);
486 r = sd_rtnl_message_new_link(netdev->manager->rtnl, &m, RTM_NEWLINK, 0);
488 log_error_netdev(netdev,
489 "Could not allocate RTM_NEWLINK message: %s",
494 switch(netdev->kind) {
495 case NETDEV_KIND_IPIP:
496 r = netdev_fill_ipip_rtnl_message(link, m);
500 case NETDEV_KIND_SIT:
501 r = netdev_fill_sit_rtnl_message(link, m);
505 case NETDEV_KIND_VTI:
506 netdev_fill_vti_rtnl_message(link, m);
510 case NETDEV_KIND_GRE:
511 r = netdev_fill_ipgre_rtnl_message(link, m);
519 r = sd_rtnl_call_async(netdev->manager->rtnl, m, callback, netdev, 0, NULL);
521 log_error_netdev(netdev,
522 "Could not send rtnetlink message: %s", strerror(-r));
526 log_debug_netdev(netdev, "Creating tunnel netdev: %s",
527 netdev_kind_to_string(netdev->kind));
529 netdev->state = NETDEV_STATE_CREATING;