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",
126 static int netdev_gre_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_message *m) {
127 Tunnel *t = GRE(netdev);
134 assert(t->family == AF_INET);
136 r = sd_rtnl_message_append_u32(m, IFLA_GRE_LINK, link->ifindex);
138 log_error_netdev(netdev,
139 "Could not append IFLA_GRE_LINK attribute: %s",
144 r = sd_rtnl_message_append_in_addr(m, IFLA_GRE_LOCAL, &t->local.in);
146 log_error_netdev(netdev,
147 "Could not append IFLA_GRE_LOCAL attribute: %s",
152 r = sd_rtnl_message_append_in_addr(m, IFLA_GRE_REMOTE, &t->remote.in);
154 log_error_netdev(netdev,
155 "Could not append IFLA_GRE_REMOTE attribute: %s",
160 r = sd_rtnl_message_append_u8(m, IFLA_GRE_TTL, t->ttl);
162 log_error_netdev(netdev,
163 "Could not append IFLA_GRE_TTL attribute: %s",
168 r = sd_rtnl_message_append_u8(m, IFLA_GRE_TOS, t->tos);
170 log_error_netdev(netdev,
171 "Could not append IFLA_GRE_TOS attribute: %s",
179 static int netdev_vti_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_message *m) {
180 Tunnel *t = VTI(netdev);
187 assert(t->family == AF_INET);
189 r = sd_rtnl_message_append_u32(m, IFLA_VTI_LINK, link->ifindex);
191 log_error_netdev(netdev,
192 "Could not append IFLA_IPTUN_LINK attribute: %s",
197 r = sd_rtnl_message_append_in_addr(m, IFLA_VTI_LOCAL, &t->local.in);
199 log_error_netdev(netdev,
200 "Could not append IFLA_IPTUN_LOCAL attribute: %s",
205 r = sd_rtnl_message_append_in_addr(m, IFLA_VTI_REMOTE, &t->remote.in);
207 log_error_netdev(netdev,
208 "Could not append IFLA_IPTUN_REMOTE attribute: %s",
216 static int netdev_tunnel_verify(NetDev *netdev, const char *filename) {
222 switch (netdev->kind) {
223 case NETDEV_KIND_IPIP:
226 case NETDEV_KIND_SIT:
229 case NETDEV_KIND_GRE:
232 case NETDEV_KIND_VTI:
236 assert_not_reached("Invalid tunnel kind");
241 if (t->local.in.s_addr == INADDR_ANY) {
242 log_warning("Tunnel without local address configured in %s. Ignoring", filename);
246 if (t->remote.in.s_addr == INADDR_ANY) {
247 log_warning("Tunnel without remote address configured in %s. Ignoring", filename);
251 if (t->family != AF_INET) {
252 log_warning("Tunnel with invalid address family configured in %s. Ignoring", filename);
259 int config_parse_tunnel_address(const char *unit,
260 const char *filename,
263 unsigned section_line,
269 Tunnel *t = userdata;
270 union in_addr_union *addr = data, buffer;
278 r = in_addr_from_string_auto(rvalue, &f, &buffer);
280 log_syntax(unit, LOG_ERR, filename, line, EINVAL, "Tunnel address is invalid, ignoring assignment: %s", rvalue);
284 if (t->family != AF_UNSPEC && t->family != f) {
285 log_syntax(unit, LOG_ERR, filename, line, EINVAL, "Tunnel addresses incompatible, ignoring assignment: %s", rvalue);
295 static void ipip_init(NetDev *n) {
304 static void sit_init(NetDev *n) {
313 static void vti_init(NetDev *n) {
322 static void gre_init(NetDev *n) {
331 const NetDevVTable ipip_vtable = {
332 .object_size = sizeof(Tunnel),
334 .sections = "Match\0NetDev\0Tunnel\0",
335 .fill_message_create = netdev_ipip_fill_message_create,
336 .create_type = NETDEV_CREATE_STACKED,
337 .config_verify = netdev_tunnel_verify,
340 const NetDevVTable sit_vtable = {
341 .object_size = sizeof(Tunnel),
343 .sections = "Match\0NetDev\0Tunnel\0",
344 .fill_message_create = netdev_sit_fill_message_create,
345 .create_type = NETDEV_CREATE_STACKED,
346 .config_verify = netdev_tunnel_verify,
349 const NetDevVTable vti_vtable = {
350 .object_size = sizeof(Tunnel),
352 .sections = "Match\0NetDev\0Tunnel\0",
353 .fill_message_create = netdev_vti_fill_message_create,
354 .create_type = NETDEV_CREATE_STACKED,
355 .config_verify = netdev_tunnel_verify,
358 const NetDevVTable gre_vtable = {
359 .object_size = sizeof(Tunnel),
361 .sections = "Match\0NetDev\0Tunnel\0",
362 .fill_message_create = netdev_gre_fill_message_create,
363 .create_type = NETDEV_CREATE_STACKED,
364 .config_verify = netdev_tunnel_verify,