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",
81 static int netdev_sit_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_message *m) {
82 Tunnel *t = SIT(netdev);
89 assert(t->family == AF_INET);
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, &t->local.in);
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, &t->remote.in);
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, t->ttl);
117 log_error_netdev(netdev,
118 "Could not append IFLA_IPTUN_TTL attribute: %s",
123 r = sd_rtnl_message_append_u8(m, IFLA_IPTUN_PMTUDISC, t->pmtudisc);
125 log_error_netdev(netdev,
126 "Could not append IFLA_IPTUN_PMTUDISC attribute: %s",
134 static int netdev_gre_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_message *m) {
135 Tunnel *t = GRE(netdev);
142 assert(t->family == AF_INET);
144 r = sd_rtnl_message_append_u32(m, IFLA_GRE_LINK, link->ifindex);
146 log_error_netdev(netdev,
147 "Could not append IFLA_GRE_LINK attribute: %s",
152 r = sd_rtnl_message_append_in_addr(m, IFLA_GRE_LOCAL, &t->local.in);
154 log_error_netdev(netdev,
155 "Could not append IFLA_GRE_LOCAL attribute: %s",
160 r = sd_rtnl_message_append_in_addr(m, IFLA_GRE_REMOTE, &t->remote.in);
162 log_error_netdev(netdev,
163 "Could not append IFLA_GRE_REMOTE attribute: %s",
168 r = sd_rtnl_message_append_u8(m, IFLA_GRE_TTL, t->ttl);
170 log_error_netdev(netdev,
171 "Could not append IFLA_GRE_TTL attribute: %s",
176 r = sd_rtnl_message_append_u8(m, IFLA_GRE_TOS, t->tos);
178 log_error_netdev(netdev,
179 "Could not append IFLA_GRE_TOS attribute: %s",
187 static int netdev_vti_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_message *m) {
188 Tunnel *t = VTI(netdev);
195 assert(t->family == AF_INET);
197 r = sd_rtnl_message_append_u32(m, IFLA_VTI_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_VTI_LOCAL, &t->local.in);
207 log_error_netdev(netdev,
208 "Could not append IFLA_IPTUN_LOCAL attribute: %s",
213 r = sd_rtnl_message_append_in_addr(m, IFLA_VTI_REMOTE, &t->remote.in);
215 log_error_netdev(netdev,
216 "Could not append IFLA_IPTUN_REMOTE attribute: %s",
224 static int netdev_tunnel_verify(NetDev *netdev, const char *filename) {
230 switch (netdev->kind) {
231 case NETDEV_KIND_IPIP:
234 case NETDEV_KIND_SIT:
237 case NETDEV_KIND_GRE:
240 case NETDEV_KIND_VTI:
244 assert_not_reached("Invalid tunnel kind");
249 if (t->local.in.s_addr == INADDR_ANY) {
250 log_warning("Tunnel without local address configured in %s. Ignoring", filename);
254 if (t->remote.in.s_addr == INADDR_ANY) {
255 log_warning("Tunnel without remote address configured in %s. Ignoring", filename);
259 if (t->family != AF_INET) {
260 log_warning("Tunnel with invalid address family configured in %s. Ignoring", filename);
267 int config_parse_tunnel_address(const char *unit,
268 const char *filename,
271 unsigned section_line,
277 Tunnel *t = userdata;
278 union in_addr_union *addr = data, buffer;
286 r = in_addr_from_string_auto(rvalue, &f, &buffer);
288 log_syntax(unit, LOG_ERR, filename, line, EINVAL, "Tunnel address is invalid, ignoring assignment: %s", rvalue);
292 if (t->family != AF_UNSPEC && t->family != f) {
293 log_syntax(unit, LOG_ERR, filename, line, EINVAL, "Tunnel addresses incompatible, ignoring assignment: %s", rvalue);
303 static void ipip_init(NetDev *n) {
312 static void sit_init(NetDev *n) {
321 static void vti_init(NetDev *n) {
330 static void gre_init(NetDev *n) {
339 const NetDevVTable ipip_vtable = {
340 .object_size = sizeof(Tunnel),
342 .sections = "Match\0NetDev\0Tunnel\0",
343 .fill_message_create = netdev_ipip_fill_message_create,
344 .create_type = NETDEV_CREATE_STACKED,
345 .config_verify = netdev_tunnel_verify,
348 const NetDevVTable sit_vtable = {
349 .object_size = sizeof(Tunnel),
351 .sections = "Match\0NetDev\0Tunnel\0",
352 .fill_message_create = netdev_sit_fill_message_create,
353 .create_type = NETDEV_CREATE_STACKED,
354 .config_verify = netdev_tunnel_verify,
357 const NetDevVTable vti_vtable = {
358 .object_size = sizeof(Tunnel),
360 .sections = "Match\0NetDev\0Tunnel\0",
361 .fill_message_create = netdev_vti_fill_message_create,
362 .create_type = NETDEV_CREATE_STACKED,
363 .config_verify = netdev_tunnel_verify,
366 const NetDevVTable gre_vtable = {
367 .object_size = sizeof(Tunnel),
369 .sections = "Match\0NetDev\0Tunnel\0",
370 .fill_message_create = netdev_gre_fill_message_create,
371 .create_type = NETDEV_CREATE_STACKED,
372 .config_verify = netdev_tunnel_verify,