]>
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 | 34 | #include "udev.h" |
ce43e484 | 35 | #include "sd-lldp.h" |
f579559b TG |
36 | |
37 | #include "rtnl-util.h" | |
38 | #include "hashmap.h" | |
39 | #include "list.h" | |
06f021a8 | 40 | #include "set.h" |
134e56dc | 41 | #include "condition.h" |
3b653205 | 42 | #include "in-addr-util.h" |
f579559b | 43 | |
aba496a5 | 44 | #define CACHE_INFO_INFINITY_LIFE_TIME 0xFFFFFFFFU |
4faefc7f LP |
45 | #define DHCP_ROUTE_METRIC 1024 |
46 | #define IPV4LL_ROUTE_METRIC 2048 | |
aba496a5 | 47 | |
1a436809 | 48 | typedef struct NetDev NetDev; |
f579559b TG |
49 | typedef struct Network Network; |
50 | typedef struct Link Link; | |
51 | typedef struct Address Address; | |
52 | typedef struct Route Route; | |
53 | typedef struct Manager Manager; | |
11bf3cce | 54 | typedef struct AddressPool AddressPool; |
b98b483b | 55 | typedef struct FdbEntry FdbEntry; |
f579559b | 56 | |
cb9fc36a | 57 | typedef enum AddressFamilyBoolean { |
769d324c LP |
58 | /* This is a bitmask, though it usually doesn't feel that way! */ |
59 | ADDRESS_FAMILY_NO = 0, | |
60 | ADDRESS_FAMILY_IPV4 = 1, | |
61 | ADDRESS_FAMILY_IPV6 = 2, | |
62 | ADDRESS_FAMILY_YES = 3, | |
cb9fc36a LP |
63 | _ADDRESS_FAMILY_BOOLEAN_MAX, |
64 | _ADDRESS_FAMILY_BOOLEAN_INVALID = -1, | |
65 | } AddressFamilyBoolean; | |
ed942a9e | 66 | |
bd8f6538 TG |
67 | typedef enum LLMNRSupport { |
68 | LLMNR_SUPPORT_NO, | |
69 | LLMNR_SUPPORT_YES, | |
70 | LLMNR_SUPPORT_RESOLVE, | |
71 | _LLMNR_SUPPORT_MAX, | |
72 | _LLMNR_SUPPORT_INVALID = -1, | |
73 | } LLMNRSupport; | |
74 | ||
e331e246 TG |
75 | typedef enum LinkOperationalState { |
76 | LINK_OPERSTATE_OFF, | |
77 | LINK_OPERSTATE_NO_CARRIER, | |
78 | LINK_OPERSTATE_DORMANT, | |
79 | LINK_OPERSTATE_CARRIER, | |
80 | LINK_OPERSTATE_DEGRADED, | |
81 | LINK_OPERSTATE_ROUTABLE, | |
82 | _LINK_OPERSTATE_MAX, | |
83 | _LINK_OPERSTATE_INVALID = -1 | |
84 | } LinkOperationalState; | |
85 | ||
3e43b2cd JJ |
86 | typedef enum DCHPClientIdentifier { |
87 | DHCP_CLIENT_ID_MAC, | |
88 | DHCP_CLIENT_ID_DUID, | |
89 | _DHCP_CLIENT_ID_MAX, | |
90 | _DHCP_CLIENT_ID_INVALID = -1, | |
91 | } DCHPClientIdentifier; | |
92 | ||
b98b483b AR |
93 | struct FdbEntry { |
94 | Network *network; | |
95 | unsigned section; | |
96 | ||
97 | struct ether_addr *mac_addr; | |
98 | uint16_t vlan_id; | |
99 | ||
100 | LIST_FIELDS(FdbEntry, static_fdb_entries); | |
101 | }; | |
102 | ||
f579559b TG |
103 | struct Network { |
104 | Manager *manager; | |
105 | ||
106 | char *filename; | |
dbffab87 | 107 | char *name; |
f579559b TG |
108 | |
109 | struct ether_addr *match_mac; | |
5256e00e TG |
110 | char **match_path; |
111 | char **match_driver; | |
112 | char **match_type; | |
113 | char **match_name; | |
edb85f0d | 114 | |
2cc412b5 TG |
115 | Condition *match_host; |
116 | Condition *match_virt; | |
117 | Condition *match_kernel; | |
edbb03e9 | 118 | Condition *match_arch; |
f579559b TG |
119 | |
120 | char *description; | |
1a436809 TG |
121 | NetDev *bridge; |
122 | NetDev *bond; | |
6a0a2f86 | 123 | Hashmap *stacked_netdevs; |
cb9fc36a | 124 | AddressFamilyBoolean dhcp; |
3e43b2cd | 125 | DCHPClientIdentifier dhcp_client_identifier; |
3175fcde | 126 | char *dhcp_vendor_class_identifier; |
5be4d38e | 127 | bool dhcp_dns; |
bcb7a07e | 128 | bool dhcp_ntp; |
4f882b2a | 129 | bool dhcp_mtu; |
1346b1f0 | 130 | bool dhcp_hostname; |
ad0734e8 | 131 | bool dhcp_domains; |
4cc7a82c | 132 | bool dhcp_sendhost; |
f5de5b00 | 133 | bool dhcp_broadcast; |
eb27aeca | 134 | bool dhcp_critical; |
e1ea665e | 135 | bool dhcp_routes; |
84b5b79a | 136 | unsigned dhcp_route_metric; |
d0d6a4cd | 137 | AddressFamilyBoolean link_local; |
bfa695b5 | 138 | bool ipv4ll_route; |
7f77697a | 139 | union in_addr_union ipv6_token; |
f579559b | 140 | |
dd43110f TG |
141 | bool dhcp_server; |
142 | ||
e1853b00 SS |
143 | unsigned cost; |
144 | ||
769d324c | 145 | AddressFamilyBoolean ip_forward; |
5a8bcb67 | 146 | bool ip_masquerade; |
5a8bcb67 | 147 | |
c106cc36 TG |
148 | struct ether_addr *mac; |
149 | unsigned mtu; | |
150 | ||
ce43e484 SS |
151 | bool lldp; |
152 | ||
f048a16b TG |
153 | LIST_HEAD(Address, static_addresses); |
154 | LIST_HEAD(Route, static_routes); | |
b98b483b | 155 | LIST_HEAD(FdbEntry, static_fdb_entries); |
f579559b | 156 | |
6ae115c1 TG |
157 | Hashmap *addresses_by_section; |
158 | Hashmap *routes_by_section; | |
b98b483b | 159 | Hashmap *fdb_entries_by_section; |
6ae115c1 | 160 | |
67272d15 | 161 | bool wildcard_domain; |
0d4ad91d | 162 | char **domains, **dns, **ntp, **bind_carrier; |
06f021a8 | 163 | |
bd8f6538 TG |
164 | LLMNRSupport llmnr; |
165 | ||
f579559b TG |
166 | LIST_FIELDS(Network, networks); |
167 | }; | |
168 | ||
169 | struct Address { | |
170 | Network *network; | |
16aa63a0 | 171 | unsigned section; |
f579559b | 172 | |
0dd25fb9 | 173 | int family; |
f579559b | 174 | unsigned char prefixlen; |
5c1d3fc9 | 175 | unsigned char scope; |
851c9f82 | 176 | uint32_t flags; |
f579559b TG |
177 | char *label; |
178 | ||
eb0ea358 | 179 | struct in_addr broadcast; |
aba496a5 | 180 | struct ifa_cacheinfo cinfo; |
8cd11a0f | 181 | |
5d3de3fe | 182 | union in_addr_union in_addr; |
c081882f | 183 | union in_addr_union in_addr_peer; |
f579559b | 184 | |
fd6d906c | 185 | bool ip_masquerade_done; |
5a8bcb67 | 186 | |
3d3d4255 | 187 | LIST_FIELDS(Address, addresses); |
f579559b TG |
188 | }; |
189 | ||
190 | struct Route { | |
191 | Network *network; | |
16aa63a0 | 192 | unsigned section; |
f579559b | 193 | |
0dd25fb9 | 194 | int family; |
6ae115c1 | 195 | unsigned char dst_prefixlen; |
9e7e4408 | 196 | unsigned char src_prefixlen; |
5c1d3fc9 UTL |
197 | unsigned char scope; |
198 | uint32_t metrics; | |
28cc555d | 199 | unsigned char protocol; /* RTPROT_* */ |
f579559b | 200 | |
5d3de3fe LP |
201 | union in_addr_union in_addr; |
202 | union in_addr_union dst_addr; | |
9e7e4408 | 203 | union in_addr_union src_addr; |
46b0c76e | 204 | union in_addr_union prefsrc_addr; |
6ae115c1 | 205 | |
3d3d4255 | 206 | LIST_FIELDS(Route, routes); |
f579559b TG |
207 | }; |
208 | ||
11bf3cce LP |
209 | struct AddressPool { |
210 | Manager *manager; | |
211 | ||
0dd25fb9 | 212 | int family; |
11bf3cce LP |
213 | unsigned prefixlen; |
214 | ||
215 | union in_addr_union in_addr; | |
216 | ||
217 | LIST_FIELDS(AddressPool, address_pools); | |
218 | }; | |
219 | ||
f579559b TG |
220 | struct Manager { |
221 | sd_rtnl *rtnl; | |
222 | sd_event *event; | |
9c0a72f9 | 223 | sd_event_source *bus_retry_event_source; |
1346b1f0 | 224 | sd_bus *bus; |
9c0a72f9 | 225 | sd_bus_slot *prepare_for_sleep_slot; |
f579559b TG |
226 | struct udev *udev; |
227 | struct udev_monitor *udev_monitor; | |
228 | sd_event_source *udev_event_source; | |
229 | ||
6a24f148 TG |
230 | bool enumerating; |
231 | ||
bbf7c048 | 232 | char *state_file; |
e331e246 | 233 | LinkOperationalState operational_state; |
bbf7c048 | 234 | |
f579559b | 235 | Hashmap *links; |
52433f6b | 236 | Hashmap *netdevs; |
dbffab87 | 237 | Hashmap *networks_by_name; |
f579559b | 238 | LIST_HEAD(Network, networks); |
11bf3cce | 239 | LIST_HEAD(AddressPool, address_pools); |
f579559b | 240 | |
f579559b TG |
241 | usec_t network_dirs_ts_usec; |
242 | }; | |
243 | ||
2ad8416d ZJS |
244 | extern const char* const network_dirs[]; |
245 | ||
f579559b TG |
246 | /* Manager */ |
247 | ||
e331e246 TG |
248 | extern const sd_bus_vtable manager_vtable[]; |
249 | ||
f579559b TG |
250 | int manager_new(Manager **ret); |
251 | void manager_free(Manager *m); | |
252 | ||
8f203c16 | 253 | int manager_connect_bus(Manager *m); |
a97dcc12 TG |
254 | int manager_run(Manager *m); |
255 | ||
02b59d57 TG |
256 | int manager_load_config(Manager *m); |
257 | bool manager_should_reload(Manager *m); | |
258 | ||
505f8da7 | 259 | int manager_rtnl_enumerate_links(Manager *m); |
45af44d4 | 260 | int manager_rtnl_enumerate_addresses(Manager *m); |
f579559b | 261 | |
e331e246 | 262 | int manager_send_changed(Manager *m, const char *property, ...) _sentinel_; |
bbf7c048 | 263 | int manager_save(Manager *m); |
3bef724f | 264 | |
0dd25fb9 | 265 | int manager_address_pool_acquire(Manager *m, int family, unsigned prefixlen, union in_addr_union *found); |
11bf3cce | 266 | |
f579559b TG |
267 | DEFINE_TRIVIAL_CLEANUP_FUNC(Manager*, manager_free); |
268 | #define _cleanup_manager_free_ _cleanup_(manager_freep) | |
269 | ||
270 | /* Network */ | |
271 | ||
272 | int network_load(Manager *manager); | |
f579559b TG |
273 | |
274 | void network_free(Network *network); | |
275 | ||
276 | DEFINE_TRIVIAL_CLEANUP_FUNC(Network*, network_free); | |
277 | #define _cleanup_network_free_ _cleanup_(network_freep) | |
278 | ||
dbffab87 | 279 | int network_get_by_name(Manager *manager, const char *name, Network **ret); |
505f8da7 TG |
280 | int network_get(Manager *manager, struct udev_device *device, |
281 | const char *ifname, const struct ether_addr *mac, | |
282 | Network **ret); | |
f579559b TG |
283 | int network_apply(Manager *manager, Network *network, Link *link); |
284 | ||
69a93e7d | 285 | int config_parse_netdev(const char *unit, const char *filename, unsigned line, |
02b59d57 TG |
286 | const char *section, unsigned section_line, const char *lvalue, |
287 | int ltype, const char *rvalue, void *data, void *userdata); | |
288 | ||
6192b846 TG |
289 | int config_parse_domains(const char *unit, |
290 | const char *filename, | |
291 | unsigned line, | |
292 | const char *section, | |
293 | unsigned section_line, | |
294 | const char *lvalue, | |
295 | int ltype, | |
296 | const char *rvalue, | |
297 | void *data, | |
298 | void *userdata); | |
299 | ||
7951dea2 SS |
300 | int config_parse_tunnel(const char *unit, |
301 | const char *filename, | |
302 | unsigned line, | |
303 | const char *section, | |
304 | unsigned section_line, | |
305 | const char *lvalue, | |
306 | int ltype, | |
307 | const char *rvalue, | |
308 | void *data, | |
309 | void *userdata); | |
310 | ||
311 | int config_parse_tunnel_address(const char *unit, | |
312 | const char *filename, | |
313 | unsigned line, | |
314 | const char *section, | |
315 | unsigned section_line, | |
316 | const char *lvalue, | |
317 | int ltype, | |
318 | const char *rvalue, | |
319 | void *data, | |
320 | void *userdata); | |
321 | ||
85a8eeee SS |
322 | int config_parse_vxlan_group_address(const char *unit, |
323 | const char *filename, | |
324 | unsigned line, | |
325 | const char *section, | |
326 | unsigned section_line, | |
327 | const char *lvalue, | |
328 | int ltype, | |
329 | const char *rvalue, | |
330 | void *data, | |
331 | void *userdata); | |
332 | ||
3175fcde TG |
333 | extern const sd_bus_vtable network_vtable[]; |
334 | ||
335 | int network_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error); | |
336 | int network_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error); | |
337 | ||
02b59d57 | 338 | /* gperf */ |
c0dda186 | 339 | const struct ConfigPerfItem* network_network_gperf_lookup(const char *key, unsigned length); |
f579559b TG |
340 | |
341 | /* Route */ | |
f048a16b | 342 | int route_new_static(Network *network, unsigned section, Route **ret); |
28cc555d | 343 | int route_new_dynamic(Route **ret, unsigned char rtm_protocol); |
f579559b | 344 | void route_free(Route *route); |
f882c247 | 345 | int route_configure(Route *route, Link *link, sd_rtnl_message_handler_t callback); |
5c1d3fc9 UTL |
346 | int route_drop(Route *route, Link *link, sd_rtnl_message_handler_t callback); |
347 | ||
f579559b TG |
348 | |
349 | DEFINE_TRIVIAL_CLEANUP_FUNC(Route*, route_free); | |
350 | #define _cleanup_route_free_ _cleanup_(route_freep) | |
351 | ||
352 | int config_parse_gateway(const char *unit, const char *filename, unsigned line, | |
71a61510 TG |
353 | const char *section, unsigned section_line, const char *lvalue, |
354 | int ltype, const char *rvalue, void *data, void *userdata); | |
f579559b | 355 | |
6ae115c1 TG |
356 | int config_parse_destination(const char *unit, const char *filename, unsigned line, |
357 | const char *section, unsigned section_line, const char *lvalue, | |
358 | int ltype, const char *rvalue, void *data, void *userdata); | |
359 | ||
5d8e593d SS |
360 | int config_parse_route_priority(const char *unit, const char *filename, unsigned line, |
361 | const char *section, unsigned section_line, const char *lvalue, | |
362 | int ltype, const char *rvalue, void *data, void *userdata); | |
769b56a3 TG |
363 | |
364 | int config_parse_route_scope(const char *unit, const char *filename, unsigned line, | |
365 | const char *section, unsigned section_line, const char *lvalue, | |
366 | int ltype, const char *rvalue, void *data, void *userdata); | |
f579559b | 367 | /* Address */ |
f048a16b TG |
368 | int address_new_static(Network *network, unsigned section, Address **ret); |
369 | int address_new_dynamic(Address **ret); | |
f579559b | 370 | void address_free(Address *address); |
f882c247 | 371 | int address_configure(Address *address, Link *link, sd_rtnl_message_handler_t callback); |
aba496a5 | 372 | int address_update(Address *address, Link *link, sd_rtnl_message_handler_t callback); |
407fe036 | 373 | int address_drop(Address *address, Link *link, sd_rtnl_message_handler_t callback); |
5a8bcb67 LP |
374 | int address_establish(Address *address, Link *link); |
375 | int address_release(Address *address, Link *link); | |
9505d3c6 | 376 | bool address_equal(Address *a1, Address *a2); |
f579559b TG |
377 | |
378 | DEFINE_TRIVIAL_CLEANUP_FUNC(Address*, address_free); | |
379 | #define _cleanup_address_free_ _cleanup_(address_freep) | |
380 | ||
381 | int config_parse_address(const char *unit, const char *filename, unsigned line, | |
71a61510 TG |
382 | const char *section, unsigned section_line, const char *lvalue, |
383 | int ltype, const char *rvalue, void *data, void *userdata); | |
f579559b | 384 | |
eb0ea358 TG |
385 | int config_parse_broadcast(const char *unit, const char *filename, unsigned line, |
386 | const char *section, unsigned section_line, const char *lvalue, | |
387 | int ltype, const char *rvalue, void *data, void *userdata); | |
388 | ||
6ae115c1 TG |
389 | int config_parse_label(const char *unit, const char *filename, unsigned line, |
390 | const char *section, unsigned section_line, const char *lvalue, | |
391 | int ltype, const char *rvalue, void *data, void *userdata); | |
392 | ||
b98b483b | 393 | /* Forwarding database table. */ |
a245ced0 | 394 | int fdb_entry_configure(Link *const link, FdbEntry *const fdb_entry); |
b98b483b AR |
395 | void fdb_entry_free(FdbEntry *fdb_entry); |
396 | int fdb_entry_new_static(Network *const network, const unsigned section, FdbEntry **ret); | |
397 | ||
398 | DEFINE_TRIVIAL_CLEANUP_FUNC(FdbEntry*, fdb_entry_free); | |
399 | #define _cleanup_fdbentry_free_ _cleanup_(fdb_entry_freep) | |
400 | ||
401 | int config_parse_fdb_hwaddr(const char *unit, const char *filename, unsigned line, | |
402 | const char *section, unsigned section_line, const char *lvalue, | |
403 | int ltype, const char *rvalue, void *data, void *userdata); | |
404 | ||
405 | int config_parse_fdb_vlan_id(const char *unit, const char *filename, unsigned line, | |
406 | const char *section, unsigned section_line, const char *lvalue, | |
407 | int ltype, const char *rvalue, void *data, void *userdata); | |
408 | ||
ed942a9e TG |
409 | /* DHCP support */ |
410 | ||
ed942a9e TG |
411 | int config_parse_dhcp(const char *unit, const char *filename, unsigned line, |
412 | const char *section, unsigned section_line, const char *lvalue, | |
413 | int ltype, const char *rvalue, void *data, void *userdata); | |
3e43b2cd JJ |
414 | int config_parse_dhcp_client_identifier(const char *unit, const char *filename, unsigned line, |
415 | const char *section, unsigned section_line, const char *lvalue, | |
416 | int ltype, const char *rvalue, void *data, void *userdata); | |
ed942a9e | 417 | |
d0d6a4cd TG |
418 | /* IPv4LL support (legacy) */ |
419 | ||
420 | int config_parse_ipv4ll(const char *unit, const char *filename, unsigned line, | |
421 | const char *section, unsigned section_line, const char *lvalue, | |
422 | int ltype, const char *rvalue, void *data, void *userdata); | |
423 | ||
7f77697a | 424 | /* IPv6 support */ |
60c35566 TG |
425 | int config_parse_ipv6token(const char *unit, const char *filename, unsigned line, |
426 | const char *section, unsigned section_line, const char *lvalue, | |
427 | int ltype, const char *rvalue, void *data, void *userdata); | |
7f77697a | 428 | |
bd8f6538 TG |
429 | /* LLMNR support */ |
430 | ||
431 | const char* llmnr_support_to_string(LLMNRSupport i) _const_; | |
432 | LLMNRSupport llmnr_support_from_string(const char *s) _pure_; | |
433 | ||
434 | int config_parse_llmnr(const char *unit, const char *filename, unsigned line, | |
435 | const char *section, unsigned section_line, const char *lvalue, | |
436 | int ltype, const char *rvalue, void *data, void *userdata); | |
437 | ||
11bf3cce LP |
438 | /* Address Pool */ |
439 | ||
0dd25fb9 LP |
440 | int address_pool_new(Manager *m, AddressPool **ret, int family, const union in_addr_union *u, unsigned prefixlen); |
441 | int address_pool_new_from_string(Manager *m, AddressPool **ret, int family, const char *p, unsigned prefixlen); | |
11bf3cce LP |
442 | void address_pool_free(AddressPool *p); |
443 | ||
444 | int address_pool_acquire(AddressPool *p, unsigned prefixlen, union in_addr_union *found); | |
cb9fc36a LP |
445 | |
446 | const char *address_family_boolean_to_string(AddressFamilyBoolean b) _const_; | |
447 | AddressFamilyBoolean address_family_boolean_from_string(const char *s) _const_; | |
769d324c LP |
448 | |
449 | int config_parse_address_family_boolean(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); | |
e331e246 | 450 | |
8add5f79 NO |
451 | /* IPForwarding parser */ |
452 | int config_parse_address_family_boolean_with_kernel(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); | |
453 | ||
6a7a4e4d | 454 | /* Operational State */ |
e331e246 TG |
455 | |
456 | const char* link_operstate_to_string(LinkOperationalState s) _const_; | |
457 | LinkOperationalState link_operstate_from_string(const char *s) _pure_; |