]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/network/networkd-tunnel.c
networkd: rename NetDev variable for consistency with Link
[thirdparty/systemd.git] / src / network / networkd-tunnel.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4 This file is part of systemd.
5
6 Copyright 2014 Susant Sahani <susant@redhat.com>
7
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.
12
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.
17
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/>.
20 ***/
21
22 #include <netinet/ether.h>
23 #include <arpa/inet.h>
24 #include <net/if.h>
25 #include <linux/ip.h>
26 #include <linux/if_tunnel.h>
27 #include <libkmod.h>
28
29 #include "sd-rtnl.h"
30 #include "networkd.h"
31 #include "network-internal.h"
32 #include "util.h"
33
34
35 static int netdev_fill_ipip_rtnl_message(Link *link, sd_rtnl_message *m) {
36 NetDev *netdev;
37 int r;
38
39 assert(link);
40 assert(link->network);
41 assert(link->network->tunnel);
42 assert(m);
43
44 netdev = link->network->tunnel;
45
46 r = sd_rtnl_message_append_string(m, IFLA_IFNAME, netdev->ifname);
47 if (r < 0) {
48 log_error_netdev(netdev,
49 "Could not append IFLA_IFNAME, attribute: %s",
50 strerror(-r));
51 return r;
52 }
53
54 if(netdev->mtu) {
55 r = sd_rtnl_message_append_u32(m, IFLA_MTU, netdev->mtu);
56 if (r < 0) {
57 log_error_netdev(netdev,
58 "Could not append IFLA_MTU attribute: %s",
59 strerror(-r));
60 return r;
61 }
62 }
63
64 r = sd_rtnl_message_open_container(m, IFLA_LINKINFO);
65 if (r < 0) {
66 log_error_netdev(netdev,
67 "Could not append IFLA_LINKINFO attribute: %s",
68 strerror(-r));
69 return r;
70 }
71
72 r = sd_rtnl_message_open_container_union(m, IFLA_INFO_DATA,
73 netdev_kind_to_string(netdev->kind));
74 if (r < 0) {
75 log_error_netdev(netdev,
76 "Could not append IFLA_INFO_DATA attribute: %s",
77 strerror(-r));
78 return r;
79 }
80
81 r = sd_rtnl_message_append_u32(m, IFLA_IPTUN_LINK, link->ifindex);
82 if (r < 0) {
83 log_error_netdev(netdev,
84 "Could not append IFLA_IPTUN_LINK attribute: %s",
85 strerror(-r));
86 return r;
87 }
88
89 r = sd_rtnl_message_append_in_addr(m, IFLA_IPTUN_LOCAL, &netdev->tunnel_local);
90 if (r < 0) {
91 log_error_netdev(netdev,
92 "Could not append IFLA_IPTUN_LOCAL attribute: %s",
93 strerror(-r));
94 return r;
95 }
96
97 r = sd_rtnl_message_append_in_addr(m, IFLA_IPTUN_REMOTE, &netdev->tunnel_remote);
98 if (r < 0) {
99 log_error_netdev(netdev,
100 "Could not append IFLA_IPTUN_REMOTE attribute: %s",
101 strerror(-r));
102 return r;
103 }
104
105 r = sd_rtnl_message_append_u8(m, IFLA_IPTUN_TTL, netdev->tunnel_ttl);
106 if (r < 0) {
107 log_error_netdev(netdev,
108 "Could not append IFLA_IPTUN_TTL attribute: %s",
109 strerror(-r));
110 return r;
111 }
112
113 r = sd_rtnl_message_close_container(m);
114 if (r < 0) {
115 log_error_netdev(netdev,
116 "Could not append IFLA_INFO_DATA attribute: %s",
117 strerror(-r));
118 return r;
119 }
120
121 r = sd_rtnl_message_close_container(m);
122 if (r < 0) {
123 log_error_netdev(netdev,
124 "Could not append IFLA_LINKINFO attribute: %s",
125 strerror(-r));
126 return r;
127 }
128
129 return r;
130 }
131
132 int netdev_create_tunnel(Link *link, sd_rtnl_message_handler_t callback) {
133 _cleanup_rtnl_message_unref_ sd_rtnl_message *m = NULL;
134 NetDev *netdev;
135 int r;
136
137 assert(link);
138 assert(link->network);
139 assert(link->network->tunnel);
140
141 netdev = link->network->tunnel;
142
143 assert(netdev);
144 assert(netdev->ifname);
145 assert(netdev->manager);
146 assert(netdev->manager->rtnl);
147 assert(netdev->manager->kmod_ctx);
148
149 /* Load kernel module first */
150 switch(netdev->kind) {
151 case NETDEV_KIND_IPIP:
152 case NETDEV_KIND_GRE:
153 case NETDEV_KIND_SIT:
154 r = load_module(netdev->manager->kmod_ctx,
155 netdev_kind_to_string(netdev->kind));
156 if (r < 0) {
157 log_error_netdev(netdev,
158 "Could not load Kernel module: %s . Ignoring",
159 netdev_kind_to_string(netdev->kind));
160 return r;
161 }
162 break;
163 default:
164 return -ENOTSUP;
165 }
166
167 r = sd_rtnl_message_new_link(netdev->manager->rtnl, &m, RTM_NEWLINK, 0);
168 if (r < 0) {
169 log_error_netdev(netdev,
170 "Could not allocate RTM_NEWLINK message: %s",
171 strerror(-r));
172 return r;
173 }
174
175 switch(netdev->kind) {
176 case NETDEV_KIND_IPIP:
177 r = netdev_fill_ipip_rtnl_message(link, m);
178 if(r < 0)
179 return r;
180 break;
181 case NETDEV_KIND_GRE:
182 case NETDEV_KIND_SIT:
183 default:
184 return -ENOTSUP;
185 }
186
187 r = sd_rtnl_call_async(netdev->manager->rtnl, m, callback, netdev, 0, NULL);
188 if (r < 0) {
189 log_error_netdev(netdev,
190 "Could not send rtnetlink message: %s", strerror(-r));
191 return r;
192 }
193
194 log_debug_netdev(netdev, "Creating tunnel netdev: %s",
195 netdev_kind_to_string(netdev->kind));
196
197 netdev->state = NETDEV_STATE_CREATING;
198
199 return 0;
200 }