]>
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> | |
f579559b TG |
25 | |
26 | #include "sd-event.h" | |
27 | #include "sd-rtnl.h" | |
1346b1f0 | 28 | #include "sd-bus.h" |
f5be5601 | 29 | #include "sd-dhcp-client.h" |
dd43110f | 30 | #include "sd-dhcp-server.h" |
5c1d3fc9 | 31 | #include "sd-ipv4ll.h" |
4138fb2c PF |
32 | #include "sd-icmp6-nd.h" |
33 | #include "sd-dhcp6-client.h" | |
f579559b TG |
34 | #include "udev.h" |
35 | ||
36 | #include "rtnl-util.h" | |
37 | #include "hashmap.h" | |
38 | #include "list.h" | |
06f021a8 | 39 | #include "set.h" |
2cc412b5 | 40 | #include "condition-util.h" |
3b653205 | 41 | #include "in-addr-util.h" |
f579559b | 42 | |
aba496a5 | 43 | #define CACHE_INFO_INFINITY_LIFE_TIME 0xFFFFFFFFU |
4faefc7f LP |
44 | #define DHCP_ROUTE_METRIC 1024 |
45 | #define IPV4LL_ROUTE_METRIC 2048 | |
aba496a5 | 46 | |
1a436809 | 47 | typedef struct NetDev NetDev; |
f579559b TG |
48 | typedef struct Network Network; |
49 | typedef struct Link Link; | |
50 | typedef struct Address Address; | |
51 | typedef struct Route Route; | |
52 | typedef struct Manager Manager; | |
11bf3cce | 53 | typedef struct AddressPool AddressPool; |
f579559b | 54 | |
ed942a9e TG |
55 | typedef enum DHCPSupport { |
56 | DHCP_SUPPORT_NONE, | |
57 | DHCP_SUPPORT_BOTH, | |
58 | DHCP_SUPPORT_V4, | |
59 | DHCP_SUPPORT_V6, | |
60 | _DHCP_SUPPORT_MAX, | |
61 | _DHCP_SUPPORT_INVALID = -1, | |
62 | } DHCPSupport; | |
63 | ||
bd8f6538 TG |
64 | typedef enum LLMNRSupport { |
65 | LLMNR_SUPPORT_NO, | |
66 | LLMNR_SUPPORT_YES, | |
67 | LLMNR_SUPPORT_RESOLVE, | |
68 | _LLMNR_SUPPORT_MAX, | |
69 | _LLMNR_SUPPORT_INVALID = -1, | |
70 | } LLMNRSupport; | |
71 | ||
f579559b TG |
72 | struct Network { |
73 | Manager *manager; | |
74 | ||
75 | char *filename; | |
76 | ||
77 | struct ether_addr *match_mac; | |
78 | char *match_path; | |
79 | char *match_driver; | |
80 | char *match_type; | |
81 | char *match_name; | |
edb85f0d SS |
82 | char *dhcp_vendor_class_identifier; |
83 | ||
2cc412b5 TG |
84 | Condition *match_host; |
85 | Condition *match_virt; | |
86 | Condition *match_kernel; | |
edbb03e9 | 87 | Condition *match_arch; |
f579559b TG |
88 | |
89 | char *description; | |
1a436809 TG |
90 | NetDev *bridge; |
91 | NetDev *bond; | |
6a0a2f86 | 92 | Hashmap *stacked_netdevs; |
ed942a9e | 93 | DHCPSupport dhcp; |
5be4d38e | 94 | bool dhcp_dns; |
bcb7a07e | 95 | bool dhcp_ntp; |
4f882b2a | 96 | bool dhcp_mtu; |
1346b1f0 | 97 | bool dhcp_hostname; |
039ebe6a | 98 | bool dhcp_domainname; |
4cc7a82c | 99 | bool dhcp_sendhost; |
f5de5b00 | 100 | bool dhcp_broadcast; |
eb27aeca | 101 | bool dhcp_critical; |
e1ea665e | 102 | bool dhcp_routes; |
5c1d3fc9 | 103 | bool ipv4ll; |
bfa695b5 | 104 | bool ipv4ll_route; |
f579559b | 105 | |
dd43110f TG |
106 | bool dhcp_server; |
107 | ||
f048a16b TG |
108 | LIST_HEAD(Address, static_addresses); |
109 | LIST_HEAD(Route, static_routes); | |
f579559b | 110 | |
6ae115c1 TG |
111 | Hashmap *addresses_by_section; |
112 | Hashmap *routes_by_section; | |
113 | ||
b0e39c82 | 114 | char **dns, **ntp; |
06f021a8 | 115 | |
bd8f6538 TG |
116 | LLMNRSupport llmnr; |
117 | ||
f579559b TG |
118 | LIST_FIELDS(Network, networks); |
119 | }; | |
120 | ||
121 | struct Address { | |
122 | Network *network; | |
16aa63a0 | 123 | unsigned section; |
f579559b | 124 | |
0dd25fb9 | 125 | int family; |
f579559b | 126 | unsigned char prefixlen; |
5c1d3fc9 | 127 | unsigned char scope; |
f579559b TG |
128 | char *label; |
129 | ||
eb0ea358 | 130 | struct in_addr broadcast; |
aba496a5 | 131 | struct ifa_cacheinfo cinfo; |
8cd11a0f | 132 | |
5d3de3fe | 133 | union in_addr_union in_addr; |
c081882f | 134 | union in_addr_union in_addr_peer; |
f579559b | 135 | |
3d3d4255 | 136 | LIST_FIELDS(Address, addresses); |
f579559b TG |
137 | }; |
138 | ||
139 | struct Route { | |
140 | Network *network; | |
16aa63a0 | 141 | unsigned section; |
f579559b | 142 | |
0dd25fb9 | 143 | int family; |
6ae115c1 | 144 | unsigned char dst_prefixlen; |
5c1d3fc9 UTL |
145 | unsigned char scope; |
146 | uint32_t metrics; | |
28cc555d | 147 | unsigned char protocol; /* RTPROT_* */ |
f579559b | 148 | |
5d3de3fe LP |
149 | union in_addr_union in_addr; |
150 | union in_addr_union dst_addr; | |
6ae115c1 | 151 | |
3d3d4255 | 152 | LIST_FIELDS(Route, routes); |
f579559b TG |
153 | }; |
154 | ||
11bf3cce LP |
155 | struct AddressPool { |
156 | Manager *manager; | |
157 | ||
0dd25fb9 | 158 | int family; |
11bf3cce LP |
159 | unsigned prefixlen; |
160 | ||
161 | union in_addr_union in_addr; | |
162 | ||
163 | LIST_FIELDS(AddressPool, address_pools); | |
164 | }; | |
165 | ||
f579559b TG |
166 | struct Manager { |
167 | sd_rtnl *rtnl; | |
168 | sd_event *event; | |
1346b1f0 | 169 | sd_bus *bus; |
f579559b TG |
170 | struct udev *udev; |
171 | struct udev_monitor *udev_monitor; | |
172 | sd_event_source *udev_event_source; | |
0c2f9b84 TG |
173 | sd_event_source *sigterm_event_source; |
174 | sd_event_source *sigint_event_source; | |
f579559b | 175 | |
bbf7c048 TG |
176 | char *state_file; |
177 | ||
f579559b | 178 | Hashmap *links; |
52433f6b | 179 | Hashmap *netdevs; |
f579559b | 180 | LIST_HEAD(Network, networks); |
11bf3cce | 181 | LIST_HEAD(AddressPool, address_pools); |
f579559b | 182 | |
f579559b TG |
183 | usec_t network_dirs_ts_usec; |
184 | }; | |
185 | ||
2ad8416d ZJS |
186 | extern const char* const network_dirs[]; |
187 | ||
f579559b TG |
188 | /* Manager */ |
189 | ||
190 | int manager_new(Manager **ret); | |
191 | void manager_free(Manager *m); | |
192 | ||
02b59d57 TG |
193 | int manager_load_config(Manager *m); |
194 | bool manager_should_reload(Manager *m); | |
195 | ||
505f8da7 | 196 | int manager_rtnl_enumerate_links(Manager *m); |
f579559b | 197 | |
f882c247 | 198 | int manager_rtnl_listen(Manager *m); |
505f8da7 | 199 | int manager_udev_listen(Manager *m); |
1346b1f0 | 200 | int manager_bus_listen(Manager *m); |
f882c247 | 201 | |
bbf7c048 | 202 | int manager_save(Manager *m); |
3bef724f | 203 | |
0dd25fb9 | 204 | int manager_address_pool_acquire(Manager *m, int family, unsigned prefixlen, union in_addr_union *found); |
11bf3cce | 205 | |
f579559b TG |
206 | DEFINE_TRIVIAL_CLEANUP_FUNC(Manager*, manager_free); |
207 | #define _cleanup_manager_free_ _cleanup_(manager_freep) | |
208 | ||
209 | /* Network */ | |
210 | ||
211 | int network_load(Manager *manager); | |
f579559b TG |
212 | |
213 | void network_free(Network *network); | |
214 | ||
215 | DEFINE_TRIVIAL_CLEANUP_FUNC(Network*, network_free); | |
216 | #define _cleanup_network_free_ _cleanup_(network_freep) | |
217 | ||
505f8da7 TG |
218 | int network_get(Manager *manager, struct udev_device *device, |
219 | const char *ifname, const struct ether_addr *mac, | |
220 | Network **ret); | |
f579559b TG |
221 | int network_apply(Manager *manager, Network *network, Link *link); |
222 | ||
69a93e7d | 223 | int config_parse_netdev(const char *unit, const char *filename, unsigned line, |
02b59d57 TG |
224 | const char *section, unsigned section_line, const char *lvalue, |
225 | int ltype, const char *rvalue, void *data, void *userdata); | |
226 | ||
7951dea2 SS |
227 | int config_parse_tunnel(const char *unit, |
228 | const char *filename, | |
229 | unsigned line, | |
230 | const char *section, | |
231 | unsigned section_line, | |
232 | const char *lvalue, | |
233 | int ltype, | |
234 | const char *rvalue, | |
235 | void *data, | |
236 | void *userdata); | |
237 | ||
238 | int config_parse_tunnel_address(const char *unit, | |
239 | const char *filename, | |
240 | unsigned line, | |
241 | const char *section, | |
242 | unsigned section_line, | |
243 | const char *lvalue, | |
244 | int ltype, | |
245 | const char *rvalue, | |
246 | void *data, | |
247 | void *userdata); | |
248 | ||
02b59d57 | 249 | /* gperf */ |
c0dda186 | 250 | const struct ConfigPerfItem* network_network_gperf_lookup(const char *key, unsigned length); |
f579559b TG |
251 | |
252 | /* Route */ | |
f048a16b | 253 | int route_new_static(Network *network, unsigned section, Route **ret); |
28cc555d | 254 | int route_new_dynamic(Route **ret, unsigned char rtm_protocol); |
f579559b | 255 | void route_free(Route *route); |
f882c247 | 256 | int route_configure(Route *route, Link *link, sd_rtnl_message_handler_t callback); |
5c1d3fc9 UTL |
257 | int route_drop(Route *route, Link *link, sd_rtnl_message_handler_t callback); |
258 | ||
f579559b TG |
259 | |
260 | DEFINE_TRIVIAL_CLEANUP_FUNC(Route*, route_free); | |
261 | #define _cleanup_route_free_ _cleanup_(route_freep) | |
262 | ||
263 | int config_parse_gateway(const char *unit, const char *filename, unsigned line, | |
71a61510 TG |
264 | const char *section, unsigned section_line, const char *lvalue, |
265 | int ltype, const char *rvalue, void *data, void *userdata); | |
f579559b | 266 | |
6ae115c1 TG |
267 | int config_parse_destination(const char *unit, const char *filename, unsigned line, |
268 | const char *section, unsigned section_line, const char *lvalue, | |
269 | int ltype, const char *rvalue, void *data, void *userdata); | |
270 | ||
5d8e593d SS |
271 | int config_parse_route_priority(const char *unit, const char *filename, unsigned line, |
272 | const char *section, unsigned section_line, const char *lvalue, | |
273 | int ltype, const char *rvalue, void *data, void *userdata); | |
f579559b | 274 | /* Address */ |
f048a16b TG |
275 | int address_new_static(Network *network, unsigned section, Address **ret); |
276 | int address_new_dynamic(Address **ret); | |
f579559b | 277 | void address_free(Address *address); |
f882c247 | 278 | int address_configure(Address *address, Link *link, sd_rtnl_message_handler_t callback); |
aba496a5 | 279 | int address_update(Address *address, Link *link, sd_rtnl_message_handler_t callback); |
407fe036 | 280 | int address_drop(Address *address, Link *link, sd_rtnl_message_handler_t callback); |
9505d3c6 | 281 | bool address_equal(Address *a1, Address *a2); |
f579559b TG |
282 | |
283 | DEFINE_TRIVIAL_CLEANUP_FUNC(Address*, address_free); | |
284 | #define _cleanup_address_free_ _cleanup_(address_freep) | |
285 | ||
286 | int config_parse_address(const char *unit, const char *filename, unsigned line, | |
71a61510 TG |
287 | const char *section, unsigned section_line, const char *lvalue, |
288 | int ltype, const char *rvalue, void *data, void *userdata); | |
f579559b | 289 | |
eb0ea358 TG |
290 | int config_parse_broadcast(const char *unit, const char *filename, unsigned line, |
291 | const char *section, unsigned section_line, const char *lvalue, | |
292 | int ltype, const char *rvalue, void *data, void *userdata); | |
293 | ||
6ae115c1 TG |
294 | int config_parse_label(const char *unit, const char *filename, unsigned line, |
295 | const char *section, unsigned section_line, const char *lvalue, | |
296 | int ltype, const char *rvalue, void *data, void *userdata); | |
297 | ||
ed942a9e TG |
298 | /* DHCP support */ |
299 | ||
300 | const char* dhcp_support_to_string(DHCPSupport i) _const_; | |
301 | DHCPSupport dhcp_support_from_string(const char *s) _pure_; | |
302 | ||
303 | int config_parse_dhcp(const char *unit, const char *filename, unsigned line, | |
304 | const char *section, unsigned section_line, const char *lvalue, | |
305 | int ltype, const char *rvalue, void *data, void *userdata); | |
306 | ||
bd8f6538 TG |
307 | /* LLMNR support */ |
308 | ||
309 | const char* llmnr_support_to_string(LLMNRSupport i) _const_; | |
310 | LLMNRSupport llmnr_support_from_string(const char *s) _pure_; | |
311 | ||
312 | int config_parse_llmnr(const char *unit, const char *filename, unsigned line, | |
313 | const char *section, unsigned section_line, const char *lvalue, | |
314 | int ltype, const char *rvalue, void *data, void *userdata); | |
315 | ||
11bf3cce LP |
316 | /* Address Pool */ |
317 | ||
0dd25fb9 LP |
318 | int address_pool_new(Manager *m, AddressPool **ret, int family, const union in_addr_union *u, unsigned prefixlen); |
319 | int address_pool_new_from_string(Manager *m, AddressPool **ret, int family, const char *p, unsigned prefixlen); | |
11bf3cce LP |
320 | void address_pool_free(AddressPool *p); |
321 | ||
322 | int address_pool_acquire(AddressPool *p, unsigned prefixlen, union in_addr_union *found); | |
323 | ||
3333d748 ZJS |
324 | /* Macros which append INTERFACE= to the message */ |
325 | ||
97578344 | 326 | #define log_full_link(level, link, fmt, ...) log_meta_object(level, __FILE__, __LINE__, __func__, "INTERFACE=", link->ifname, "%-*s: " fmt, IFNAMSIZ, link->ifname, ##__VA_ARGS__) |
39032b87 ZJS |
327 | #define log_debug_link(link, ...) log_full_link(LOG_DEBUG, link, ##__VA_ARGS__) |
328 | #define log_info_link(link, ...) log_full_link(LOG_INFO, link, ##__VA_ARGS__) | |
329 | #define log_notice_link(link, ...) log_full_link(LOG_NOTICE, link, ##__VA_ARGS__) | |
330 | #define log_warning_link(link, ...) log_full_link(LOG_WARNING, link, ##__VA_ARGS__) | |
331 | #define log_error_link(link, ...) log_full_link(LOG_ERR, link, ##__VA_ARGS__) | |
3333d748 ZJS |
332 | |
333 | #define log_struct_link(level, link, ...) log_struct(level, "INTERFACE=%s", link->ifname, __VA_ARGS__) | |
334 | ||
62870613 ZJS |
335 | #define ADDRESS_FMT_VAL(address) \ |
336 | (address).s_addr & 0xFF, \ | |
337 | ((address).s_addr >> 8) & 0xFF, \ | |
338 | ((address).s_addr >> 16) & 0xFF, \ | |
339 | (address).s_addr >> 24 |