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_netdev_error(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_netdev_error(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_netdev_error(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_netdev_error(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_netdev_error(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_netdev_error(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_netdev_error(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_netdev_error(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_netdev_error(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_netdev_error(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) {
148 if (netdev->kind == NETDEV_KIND_GRE)
154 assert(t->family == AF_INET);
158 r = sd_rtnl_message_append_u32(m, IFLA_GRE_LINK, link->ifindex);
160 log_netdev_error(netdev,
161 "Could not append IFLA_GRE_LINK attribute: %s",
166 r = sd_rtnl_message_append_in_addr(m, IFLA_GRE_LOCAL, &t->local.in);
168 log_netdev_error(netdev,
169 "Could not append IFLA_GRE_LOCAL attribute: %s",
174 r = sd_rtnl_message_append_in_addr(m, IFLA_GRE_REMOTE, &t->remote.in);
176 log_netdev_error(netdev,
177 "Could not append IFLA_GRE_REMOTE attribute: %s",
182 r = sd_rtnl_message_append_u8(m, IFLA_GRE_TTL, t->ttl);
184 log_netdev_error(netdev,
185 "Could not append IFLA_GRE_TTL attribute: %s",
190 r = sd_rtnl_message_append_u8(m, IFLA_GRE_TOS, t->tos);
192 log_netdev_error(netdev,
193 "Could not append IFLA_GRE_TOS attribute: %s",
198 r = sd_rtnl_message_append_u8(m, IFLA_GRE_PMTUDISC, t->pmtudisc);
200 log_netdev_error(netdev,
201 "Could not append IFLA_GRE_PMTUDISC attribute: %s",
209 static int netdev_vti_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_message *m) {
210 Tunnel *t = VTI(netdev);
217 assert(t->family == AF_INET);
219 r = sd_rtnl_message_append_u32(m, IFLA_VTI_LINK, link->ifindex);
221 log_netdev_error(netdev,
222 "Could not append IFLA_IPTUN_LINK attribute: %s",
227 r = sd_rtnl_message_append_in_addr(m, IFLA_VTI_LOCAL, &t->local.in);
229 log_netdev_error(netdev,
230 "Could not append IFLA_IPTUN_LOCAL attribute: %s",
235 r = sd_rtnl_message_append_in_addr(m, IFLA_VTI_REMOTE, &t->remote.in);
237 log_netdev_error(netdev,
238 "Could not append IFLA_IPTUN_REMOTE attribute: %s",
246 static int netdev_tunnel_verify(NetDev *netdev, const char *filename) {
252 switch (netdev->kind) {
253 case NETDEV_KIND_IPIP:
256 case NETDEV_KIND_SIT:
259 case NETDEV_KIND_GRE:
262 case NETDEV_KIND_GRETAP:
265 case NETDEV_KIND_VTI:
269 assert_not_reached("Invalid tunnel kind");
274 if (t->remote.in.s_addr == INADDR_ANY) {
275 log_warning("Tunnel without remote address configured in %s. Ignoring", filename);
279 if (t->family != AF_INET) {
280 log_warning("Tunnel with invalid address family configured in %s. Ignoring", filename);
287 int config_parse_tunnel_address(const char *unit,
288 const char *filename,
291 unsigned section_line,
297 Tunnel *t = userdata;
298 union in_addr_union *addr = data, buffer;
306 r = in_addr_from_string_auto(rvalue, &f, &buffer);
308 log_syntax(unit, LOG_ERR, filename, line, EINVAL, "Tunnel address is invalid, ignoring assignment: %s", rvalue);
312 if (t->family != AF_UNSPEC && t->family != f) {
313 log_syntax(unit, LOG_ERR, filename, line, EINVAL, "Tunnel addresses incompatible, ignoring assignment: %s", rvalue);
323 static void ipip_init(NetDev *n) {
332 static void sit_init(NetDev *n) {
341 static void vti_init(NetDev *n) {
350 static void gre_init(NetDev *n) {
355 if (n->kind == NETDEV_KIND_GRE)
365 const NetDevVTable ipip_vtable = {
366 .object_size = sizeof(Tunnel),
368 .sections = "Match\0NetDev\0Tunnel\0",
369 .fill_message_create = netdev_ipip_fill_message_create,
370 .create_type = NETDEV_CREATE_STACKED,
371 .config_verify = netdev_tunnel_verify,
374 const NetDevVTable sit_vtable = {
375 .object_size = sizeof(Tunnel),
377 .sections = "Match\0NetDev\0Tunnel\0",
378 .fill_message_create = netdev_sit_fill_message_create,
379 .create_type = NETDEV_CREATE_STACKED,
380 .config_verify = netdev_tunnel_verify,
383 const NetDevVTable vti_vtable = {
384 .object_size = sizeof(Tunnel),
386 .sections = "Match\0NetDev\0Tunnel\0",
387 .fill_message_create = netdev_vti_fill_message_create,
388 .create_type = NETDEV_CREATE_STACKED,
389 .config_verify = netdev_tunnel_verify,
392 const NetDevVTable gre_vtable = {
393 .object_size = sizeof(Tunnel),
395 .sections = "Match\0NetDev\0Tunnel\0",
396 .fill_message_create = netdev_gre_fill_message_create,
397 .create_type = NETDEV_CREATE_STACKED,
398 .config_verify = netdev_tunnel_verify,
401 const NetDevVTable gretap_vtable = {
402 .object_size = sizeof(Tunnel),
404 .sections = "Match\0NetDev\0Tunnel\0",
405 .fill_message_create = netdev_gre_fill_message_create,
406 .create_type = NETDEV_CREATE_STACKED,
407 .config_verify = netdev_tunnel_verify,