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>
29 #include "networkd-netdev-tunnel.h"
30 #include "networkd-link.h"
31 #include "network-internal.h"
34 #include "conf-parser.h"
36 static int netdev_ipip_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_message *m) {
37 Tunnel *t = IPIP(netdev);
44 assert(t->family == AF_INET);
46 r = sd_rtnl_message_append_u32(m, IFLA_IPTUN_LINK, link->ifindex);
48 log_error_netdev(netdev,
49 "Could not append IFLA_IPTUN_LINK attribute: %s",
54 r = sd_rtnl_message_append_in_addr(m, IFLA_IPTUN_LOCAL, &t->local.in);
56 log_error_netdev(netdev,
57 "Could not append IFLA_IPTUN_LOCAL attribute: %s",
62 r = sd_rtnl_message_append_in_addr(m, IFLA_IPTUN_REMOTE, &t->remote.in);
64 log_error_netdev(netdev,
65 "Could not append IFLA_IPTUN_REMOTE attribute: %s",
70 r = sd_rtnl_message_append_u8(m, IFLA_IPTUN_TTL, t->ttl);
72 log_error_netdev(netdev,
73 "Could not append IFLA_IPTUN_TTL attribute: %s",
78 r = sd_rtnl_message_append_u8(m, IFLA_IPTUN_PMTUDISC, t->pmtudisc);
80 log_error_netdev(netdev,
81 "Could not append IFLA_IPTUN_PMTUDISC attribute: %s",
89 static int netdev_sit_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_message *m) {
90 Tunnel *t = SIT(netdev);
97 assert(t->family == AF_INET);
99 r = sd_rtnl_message_append_u32(m, IFLA_IPTUN_LINK, link->ifindex);
101 log_error_netdev(netdev,
102 "Could not append IFLA_IPTUN_LINK attribute: %s",
107 r = sd_rtnl_message_append_in_addr(m, IFLA_IPTUN_LOCAL, &t->local.in);
109 log_error_netdev(netdev,
110 "Could not append IFLA_IPTUN_LOCAL attribute: %s",
115 r = sd_rtnl_message_append_in_addr(m, IFLA_IPTUN_REMOTE, &t->remote.in);
117 log_error_netdev(netdev,
118 "Could not append IFLA_IPTUN_REMOTE attribute: %s",
123 r = sd_rtnl_message_append_u8(m, IFLA_IPTUN_TTL, t->ttl);
125 log_error_netdev(netdev,
126 "Could not append IFLA_IPTUN_TTL attribute: %s",
131 r = sd_rtnl_message_append_u8(m, IFLA_IPTUN_PMTUDISC, t->pmtudisc);
133 log_error_netdev(netdev,
134 "Could not append IFLA_IPTUN_PMTUDISC attribute: %s",
142 static int netdev_gre_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_message *m) {
143 Tunnel *t = GRE(netdev);
150 assert(t->family == AF_INET);
152 r = sd_rtnl_message_append_u32(m, IFLA_GRE_LINK, link->ifindex);
154 log_error_netdev(netdev,
155 "Could not append IFLA_GRE_LINK attribute: %s",
160 r = sd_rtnl_message_append_in_addr(m, IFLA_GRE_LOCAL, &t->local.in);
162 log_error_netdev(netdev,
163 "Could not append IFLA_GRE_LOCAL attribute: %s",
168 r = sd_rtnl_message_append_in_addr(m, IFLA_GRE_REMOTE, &t->remote.in);
170 log_error_netdev(netdev,
171 "Could not append IFLA_GRE_REMOTE attribute: %s",
176 r = sd_rtnl_message_append_u8(m, IFLA_GRE_TTL, t->ttl);
178 log_error_netdev(netdev,
179 "Could not append IFLA_GRE_TTL attribute: %s",
184 r = sd_rtnl_message_append_u8(m, IFLA_GRE_TOS, t->tos);
186 log_error_netdev(netdev,
187 "Could not append IFLA_GRE_TOS attribute: %s",
192 r = sd_rtnl_message_append_u8(m, IFLA_GRE_PMTUDISC, t->pmtudisc);
194 log_error_netdev(netdev,
195 "Could not append IFLA_GRE_PMTUDISC attribute: %s",
203 static int netdev_vti_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_message *m) {
204 Tunnel *t = VTI(netdev);
211 assert(t->family == AF_INET);
213 r = sd_rtnl_message_append_u32(m, IFLA_VTI_LINK, link->ifindex);
215 log_error_netdev(netdev,
216 "Could not append IFLA_IPTUN_LINK attribute: %s",
221 r = sd_rtnl_message_append_in_addr(m, IFLA_VTI_LOCAL, &t->local.in);
223 log_error_netdev(netdev,
224 "Could not append IFLA_IPTUN_LOCAL attribute: %s",
229 r = sd_rtnl_message_append_in_addr(m, IFLA_VTI_REMOTE, &t->remote.in);
231 log_error_netdev(netdev,
232 "Could not append IFLA_IPTUN_REMOTE attribute: %s",
240 static int netdev_tunnel_verify(NetDev *netdev, const char *filename) {
246 switch (netdev->kind) {
247 case NETDEV_KIND_IPIP:
250 case NETDEV_KIND_SIT:
253 case NETDEV_KIND_GRE:
256 case NETDEV_KIND_VTI:
260 assert_not_reached("Invalid tunnel kind");
265 if (t->local.in.s_addr == INADDR_ANY) {
266 log_warning("Tunnel without local address configured in %s. Ignoring", filename);
270 if (t->remote.in.s_addr == INADDR_ANY) {
271 log_warning("Tunnel without remote address configured in %s. Ignoring", filename);
275 if (t->family != AF_INET) {
276 log_warning("Tunnel with invalid address family configured in %s. Ignoring", filename);
283 int config_parse_tunnel_address(const char *unit,
284 const char *filename,
287 unsigned section_line,
293 Tunnel *t = userdata;
294 union in_addr_union *addr = data, buffer;
302 r = in_addr_from_string_auto(rvalue, &f, &buffer);
304 log_syntax(unit, LOG_ERR, filename, line, EINVAL, "Tunnel address is invalid, ignoring assignment: %s", rvalue);
308 if (t->family != AF_UNSPEC && t->family != f) {
309 log_syntax(unit, LOG_ERR, filename, line, EINVAL, "Tunnel addresses incompatible, ignoring assignment: %s", rvalue);
319 static void ipip_init(NetDev *n) {
328 static void sit_init(NetDev *n) {
337 static void vti_init(NetDev *n) {
346 static void gre_init(NetDev *n) {
355 const NetDevVTable ipip_vtable = {
356 .object_size = sizeof(Tunnel),
358 .sections = "Match\0NetDev\0Tunnel\0",
359 .fill_message_create = netdev_ipip_fill_message_create,
360 .create_type = NETDEV_CREATE_STACKED,
361 .config_verify = netdev_tunnel_verify,
364 const NetDevVTable sit_vtable = {
365 .object_size = sizeof(Tunnel),
367 .sections = "Match\0NetDev\0Tunnel\0",
368 .fill_message_create = netdev_sit_fill_message_create,
369 .create_type = NETDEV_CREATE_STACKED,
370 .config_verify = netdev_tunnel_verify,
373 const NetDevVTable vti_vtable = {
374 .object_size = sizeof(Tunnel),
376 .sections = "Match\0NetDev\0Tunnel\0",
377 .fill_message_create = netdev_vti_fill_message_create,
378 .create_type = NETDEV_CREATE_STACKED,
379 .config_verify = netdev_tunnel_verify,
382 const NetDevVTable gre_vtable = {
383 .object_size = sizeof(Tunnel),
385 .sections = "Match\0NetDev\0Tunnel\0",
386 .fill_message_create = netdev_gre_fill_message_create,
387 .create_type = NETDEV_CREATE_STACKED,
388 .config_verify = netdev_tunnel_verify,