]>
Commit | Line | Data |
---|---|---|
f579559b TG |
1 | /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ |
2 | ||
3 | /*** | |
4 | This file is part of systemd. | |
5 | ||
6 | Copyright 2013 Tom Gundersen <teg@jklm.no> | |
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 | #pragma once | |
23 | ||
24 | #include <arpa/inet.h> | |
25 | #include <linux/rtnetlink.h> | |
26 | ||
27 | #include "sd-event.h" | |
28 | #include "sd-rtnl.h" | |
1346b1f0 | 29 | #include "sd-bus.h" |
f5be5601 | 30 | #include "sd-dhcp-client.h" |
f579559b TG |
31 | #include "udev.h" |
32 | ||
33 | #include "rtnl-util.h" | |
34 | #include "hashmap.h" | |
35 | #include "list.h" | |
36 | ||
52433f6b | 37 | typedef struct Netdev Netdev; |
f579559b TG |
38 | typedef struct Network Network; |
39 | typedef struct Link Link; | |
40 | typedef struct Address Address; | |
41 | typedef struct Route Route; | |
42 | typedef struct Manager Manager; | |
43 | ||
52433f6b | 44 | typedef struct netdev_enslave_callback netdev_enslave_callback; |
02b59d57 | 45 | |
52433f6b | 46 | struct netdev_enslave_callback { |
02b59d57 TG |
47 | sd_rtnl_message_handler_t callback; |
48 | Link *link; | |
49 | ||
52433f6b | 50 | LIST_FIELDS(netdev_enslave_callback, callbacks); |
02b59d57 TG |
51 | }; |
52 | ||
52433f6b TG |
53 | typedef enum NetdevKind { |
54 | NETDEV_KIND_BRIDGE, | |
55 | NETDEV_KIND_BOND, | |
54abf461 | 56 | NETDEV_KIND_VLAN, |
52433f6b TG |
57 | _NETDEV_KIND_MAX, |
58 | _NETDEV_KIND_INVALID = -1 | |
59 | } NetdevKind; | |
60 | ||
61 | typedef enum NetdevState { | |
62 | NETDEV_STATE_FAILED, | |
63 | NETDEV_STATE_CREATING, | |
64 | NETDEV_STATE_READY, | |
65 | _NETDEV_STATE_MAX, | |
66 | _NETDEV_STATE_INVALID = -1, | |
67 | } NetdevState; | |
68 | ||
69 | struct Netdev { | |
02b59d57 TG |
70 | Manager *manager; |
71 | ||
72 | char *filename; | |
73 | ||
74 | char *description; | |
75 | char *name; | |
52433f6b | 76 | NetdevKind kind; |
02b59d57 | 77 | |
54abf461 TG |
78 | int vlanid; |
79 | ||
50add290 | 80 | int ifindex; |
52433f6b | 81 | NetdevState state; |
02b59d57 | 82 | |
52433f6b | 83 | LIST_HEAD(netdev_enslave_callback, callbacks); |
02b59d57 TG |
84 | }; |
85 | ||
f579559b TG |
86 | struct Network { |
87 | Manager *manager; | |
88 | ||
89 | char *filename; | |
90 | ||
91 | struct ether_addr *match_mac; | |
92 | char *match_path; | |
93 | char *match_driver; | |
94 | char *match_type; | |
95 | char *match_name; | |
96 | ||
97 | char *description; | |
52433f6b TG |
98 | Netdev *bridge; |
99 | Netdev *bond; | |
54abf461 | 100 | Netdev *vlan; |
f5be5601 | 101 | bool dhcp; |
5be4d38e | 102 | bool dhcp_dns; |
4f882b2a | 103 | bool dhcp_mtu; |
1346b1f0 | 104 | bool dhcp_hostname; |
039ebe6a | 105 | bool dhcp_domainname; |
eb27aeca | 106 | bool dhcp_critical; |
f579559b | 107 | |
f048a16b TG |
108 | LIST_HEAD(Address, static_addresses); |
109 | LIST_HEAD(Route, static_routes); | |
3bef724f | 110 | Address *dns; |
f579559b | 111 | |
6ae115c1 TG |
112 | Hashmap *addresses_by_section; |
113 | Hashmap *routes_by_section; | |
114 | ||
f579559b TG |
115 | LIST_FIELDS(Network, networks); |
116 | }; | |
117 | ||
118 | struct Address { | |
119 | Network *network; | |
6ae115c1 | 120 | uint64_t section; |
f579559b TG |
121 | |
122 | unsigned char family; | |
123 | unsigned char prefixlen; | |
124 | char *label; | |
125 | ||
eb0ea358 | 126 | struct in_addr broadcast; |
8cd11a0f | 127 | |
f579559b TG |
128 | union { |
129 | struct in_addr in; | |
130 | struct in6_addr in6; | |
131 | } in_addr; | |
132 | ||
f048a16b | 133 | LIST_FIELDS(Address, static_addresses); |
f579559b TG |
134 | }; |
135 | ||
136 | struct Route { | |
137 | Network *network; | |
6ae115c1 | 138 | uint64_t section; |
f579559b TG |
139 | |
140 | unsigned char family; | |
6ae115c1 | 141 | unsigned char dst_prefixlen; |
f579559b TG |
142 | |
143 | union { | |
144 | struct in_addr in; | |
145 | struct in6_addr in6; | |
146 | } in_addr; | |
147 | ||
6ae115c1 TG |
148 | union { |
149 | struct in_addr in; | |
150 | struct in6_addr in6; | |
151 | } dst_addr; | |
152 | ||
f048a16b | 153 | LIST_FIELDS(Route, static_routes); |
f579559b TG |
154 | }; |
155 | ||
f882c247 | 156 | typedef enum LinkState { |
52433f6b | 157 | LINK_STATE_ENSLAVING, |
ef1ba606 TG |
158 | LINK_STATE_SETTING_ADDRESSES, |
159 | LINK_STATE_SETTING_ROUTES, | |
f882c247 TG |
160 | LINK_STATE_CONFIGURED, |
161 | LINK_STATE_FAILED, | |
162 | _LINK_STATE_MAX, | |
163 | _LINK_STATE_INVALID = -1 | |
164 | } LinkState; | |
165 | ||
f579559b TG |
166 | struct Link { |
167 | Manager *manager; | |
168 | ||
0617ffab | 169 | uint64_t ifindex; |
c166a070 | 170 | char *ifname; |
8cd11a0f | 171 | struct ether_addr mac; |
f579559b TG |
172 | |
173 | unsigned flags; | |
174 | ||
175 | Network *network; | |
f882c247 TG |
176 | |
177 | LinkState state; | |
178 | ||
f5be5601 TG |
179 | unsigned addr_messages; |
180 | unsigned route_messages; | |
52433f6b | 181 | unsigned enslaving; |
f5be5601 | 182 | |
a6cc569e TG |
183 | sd_dhcp_client *dhcp_client; |
184 | sd_dhcp_lease *dhcp_lease; | |
185 | uint16_t original_mtu; | |
f579559b TG |
186 | }; |
187 | ||
188 | struct Manager { | |
189 | sd_rtnl *rtnl; | |
190 | sd_event *event; | |
1346b1f0 | 191 | sd_bus *bus; |
f579559b TG |
192 | struct udev *udev; |
193 | struct udev_monitor *udev_monitor; | |
194 | sd_event_source *udev_event_source; | |
195 | ||
196 | Hashmap *links; | |
52433f6b | 197 | Hashmap *netdevs; |
f579559b TG |
198 | LIST_HEAD(Network, networks); |
199 | ||
f579559b TG |
200 | usec_t network_dirs_ts_usec; |
201 | }; | |
202 | ||
2ad8416d ZJS |
203 | extern const char* const network_dirs[]; |
204 | ||
f579559b TG |
205 | /* Manager */ |
206 | ||
207 | int manager_new(Manager **ret); | |
208 | void manager_free(Manager *m); | |
209 | ||
02b59d57 TG |
210 | int manager_load_config(Manager *m); |
211 | bool manager_should_reload(Manager *m); | |
212 | ||
f579559b TG |
213 | int manager_udev_enumerate_links(Manager *m); |
214 | int manager_udev_listen(Manager *m); | |
215 | ||
f882c247 | 216 | int manager_rtnl_listen(Manager *m); |
1346b1f0 | 217 | int manager_bus_listen(Manager *m); |
f882c247 | 218 | |
3bef724f TG |
219 | int manager_update_resolv_conf(Manager *m); |
220 | ||
f579559b TG |
221 | DEFINE_TRIVIAL_CLEANUP_FUNC(Manager*, manager_free); |
222 | #define _cleanup_manager_free_ _cleanup_(manager_freep) | |
223 | ||
52433f6b TG |
224 | /* Netdev */ |
225 | ||
226 | int netdev_load(Manager *manager); | |
02b59d57 | 227 | |
52433f6b | 228 | void netdev_free(Netdev *netdev); |
02b59d57 | 229 | |
52433f6b TG |
230 | DEFINE_TRIVIAL_CLEANUP_FUNC(Netdev*, netdev_free); |
231 | #define _cleanup_netdev_free_ _cleanup_(netdev_freep) | |
02b59d57 | 232 | |
52433f6b | 233 | int netdev_get(Manager *manager, const char *name, Netdev **ret); |
50add290 | 234 | int netdev_set_ifindex(Netdev *netdev, int ifindex); |
52433f6b | 235 | int netdev_enslave(Netdev *netdev, Link *link, sd_rtnl_message_handler_t cb); |
02b59d57 | 236 | |
52433f6b TG |
237 | const char *netdev_kind_to_string(NetdevKind d) _const_; |
238 | NetdevKind netdev_kind_from_string(const char *d) _pure_; | |
239 | ||
240 | int config_parse_netdev_kind(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); | |
02b59d57 | 241 | |
f579559b TG |
242 | /* Network */ |
243 | ||
244 | int network_load(Manager *manager); | |
f579559b TG |
245 | |
246 | void network_free(Network *network); | |
247 | ||
248 | DEFINE_TRIVIAL_CLEANUP_FUNC(Network*, network_free); | |
249 | #define _cleanup_network_free_ _cleanup_(network_freep) | |
250 | ||
251 | int network_get(Manager *manager, struct udev_device *device, Network **ret); | |
252 | int network_apply(Manager *manager, Network *network, Link *link); | |
253 | ||
02b59d57 TG |
254 | int config_parse_bridge(const char *unit, const char *filename, unsigned line, |
255 | const char *section, unsigned section_line, const char *lvalue, | |
256 | int ltype, const char *rvalue, void *data, void *userdata); | |
257 | ||
52433f6b TG |
258 | int config_parse_bond(const char *unit, const char *filename, unsigned line, |
259 | const char *section, unsigned section_line, const char *lvalue, | |
260 | int ltype, const char *rvalue, void *data, void *userdata); | |
261 | ||
54abf461 TG |
262 | int config_parse_vlan(const char *unit, const char *filename, unsigned line, |
263 | const char *section, unsigned section_line, const char *lvalue, | |
264 | int ltype, const char *rvalue, void *data, void *userdata); | |
265 | ||
02b59d57 TG |
266 | /* gperf */ |
267 | ||
f579559b TG |
268 | const struct ConfigPerfItem* network_gperf_lookup(const char *key, unsigned length); |
269 | ||
270 | /* Route */ | |
f048a16b TG |
271 | int route_new_static(Network *network, unsigned section, Route **ret); |
272 | int route_new_dynamic(Route **ret); | |
f579559b | 273 | void route_free(Route *route); |
f882c247 | 274 | int route_configure(Route *route, Link *link, sd_rtnl_message_handler_t callback); |
f579559b TG |
275 | |
276 | DEFINE_TRIVIAL_CLEANUP_FUNC(Route*, route_free); | |
277 | #define _cleanup_route_free_ _cleanup_(route_freep) | |
278 | ||
279 | int config_parse_gateway(const char *unit, const char *filename, unsigned line, | |
71a61510 TG |
280 | const char *section, unsigned section_line, const char *lvalue, |
281 | int ltype, const char *rvalue, void *data, void *userdata); | |
f579559b | 282 | |
6ae115c1 TG |
283 | int config_parse_destination(const char *unit, const char *filename, unsigned line, |
284 | const char *section, unsigned section_line, const char *lvalue, | |
285 | int ltype, const char *rvalue, void *data, void *userdata); | |
286 | ||
f579559b | 287 | /* Address */ |
f048a16b TG |
288 | int address_new_static(Network *network, unsigned section, Address **ret); |
289 | int address_new_dynamic(Address **ret); | |
f579559b | 290 | void address_free(Address *address); |
f882c247 | 291 | int address_configure(Address *address, Link *link, sd_rtnl_message_handler_t callback); |
407fe036 | 292 | int address_drop(Address *address, Link *link, sd_rtnl_message_handler_t callback); |
f579559b TG |
293 | |
294 | DEFINE_TRIVIAL_CLEANUP_FUNC(Address*, address_free); | |
295 | #define _cleanup_address_free_ _cleanup_(address_freep) | |
296 | ||
3bef724f TG |
297 | int config_parse_dns(const char *unit, const char *filename, unsigned line, |
298 | const char *section, unsigned section_line, const char *lvalue, | |
299 | int ltype, const char *rvalue, void *data, void *userdata); | |
300 | ||
f579559b | 301 | int config_parse_address(const char *unit, const char *filename, unsigned line, |
71a61510 TG |
302 | const char *section, unsigned section_line, const char *lvalue, |
303 | int ltype, const char *rvalue, void *data, void *userdata); | |
f579559b | 304 | |
eb0ea358 TG |
305 | int config_parse_broadcast(const char *unit, const char *filename, unsigned line, |
306 | const char *section, unsigned section_line, const char *lvalue, | |
307 | int ltype, const char *rvalue, void *data, void *userdata); | |
308 | ||
6ae115c1 TG |
309 | int config_parse_label(const char *unit, const char *filename, unsigned line, |
310 | const char *section, unsigned section_line, const char *lvalue, | |
311 | int ltype, const char *rvalue, void *data, void *userdata); | |
312 | ||
f579559b TG |
313 | /* Link */ |
314 | ||
315 | int link_new(Manager *manager, struct udev_device *device, Link **ret); | |
316 | void link_free(Link *link); | |
aa3437a5 | 317 | int link_add(Manager *manager, struct udev_device *device, Link **ret); |
f882c247 | 318 | int link_configure(Link *link); |
f579559b | 319 | |
22936833 | 320 | int link_update(Link *link, sd_rtnl_message *message); |
dd3efc09 | 321 | |
f579559b TG |
322 | DEFINE_TRIVIAL_CLEANUP_FUNC(Link*, link_free); |
323 | #define _cleanup_link_free_ _cleanup_(link_freep) | |
3333d748 ZJS |
324 | |
325 | /* Macros which append INTERFACE= to the message */ | |
326 | ||
39032b87 ZJS |
327 | #define log_full_link(level, link, fmt, ...) log_meta_object(level, __FILE__, __LINE__, __func__, "INTERFACE=", link->ifname, "%s: " fmt, link->ifname, ##__VA_ARGS__) |
328 | #define log_debug_link(link, ...) log_full_link(LOG_DEBUG, link, ##__VA_ARGS__) | |
329 | #define log_info_link(link, ...) log_full_link(LOG_INFO, link, ##__VA_ARGS__) | |
330 | #define log_notice_link(link, ...) log_full_link(LOG_NOTICE, link, ##__VA_ARGS__) | |
331 | #define log_warning_link(link, ...) log_full_link(LOG_WARNING, link, ##__VA_ARGS__) | |
332 | #define log_error_link(link, ...) log_full_link(LOG_ERR, link, ##__VA_ARGS__) | |
3333d748 ZJS |
333 | |
334 | #define log_struct_link(level, link, ...) log_struct(level, "INTERFACE=%s", link->ifname, __VA_ARGS__) | |
335 | ||
336 | /* More macros which append INTERFACE= to the message */ | |
337 | ||
52433f6b TG |
338 | #define log_full_netdev(level, netdev, fmt, ...) log_meta_object(level, __FILE__, __LINE__, __func__, "INTERFACE=", netdev->name, "%s: " fmt, netdev->name, ##__VA_ARGS__) |
339 | #define log_debug_netdev(netdev, ...) log_full_netdev(LOG_DEBUG, netdev, ##__VA_ARGS__) | |
340 | #define log_info_netdev(netdev, ...) log_full_netdev(LOG_INFO, netdev, ##__VA_ARGS__) | |
341 | #define log_notice_netdev(netdev, ...) log_full_netdev(LOG_NOTICE, netdev, ##__VA_ARGS__) | |
342 | #define log_warning_netdev(netdev, ...) log_full_netdev(LOG_WARNING, netdev,## __VA_ARGS__) | |
343 | #define log_error_netdev(netdev, ...) log_full_netdev(LOG_ERR, netdev, ##__VA_ARGS__) | |
3333d748 | 344 | |
52433f6b | 345 | #define log_struct_netdev(level, netdev, ...) log_struct(level, "INTERFACE=%s", netdev->name, __VA_ARGS__) |
3333d748 | 346 | |
52433f6b | 347 | #define NETDEV(netdev) "INTERFACE=%s", netdev->name |
62870613 ZJS |
348 | #define ADDRESS_FMT_VAL(address) \ |
349 | (address).s_addr & 0xFF, \ | |
350 | ((address).s_addr >> 8) & 0xFF, \ | |
351 | ((address).s_addr >> 16) & 0xFF, \ | |
352 | (address).s_addr >> 24 |