]>
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 | ||
b98b483b AR |
86 | struct FdbEntry { |
87 | Network *network; | |
88 | unsigned section; | |
89 | ||
90 | struct ether_addr *mac_addr; | |
91 | uint16_t vlan_id; | |
92 | ||
93 | LIST_FIELDS(FdbEntry, static_fdb_entries); | |
94 | }; | |
95 | ||
f579559b TG |
96 | struct Network { |
97 | Manager *manager; | |
98 | ||
99 | char *filename; | |
100 | ||
101 | struct ether_addr *match_mac; | |
102 | char *match_path; | |
103 | char *match_driver; | |
104 | char *match_type; | |
105 | char *match_name; | |
edb85f0d SS |
106 | char *dhcp_vendor_class_identifier; |
107 | ||
2cc412b5 TG |
108 | Condition *match_host; |
109 | Condition *match_virt; | |
110 | Condition *match_kernel; | |
edbb03e9 | 111 | Condition *match_arch; |
f579559b TG |
112 | |
113 | char *description; | |
1a436809 TG |
114 | NetDev *bridge; |
115 | NetDev *bond; | |
6a0a2f86 | 116 | Hashmap *stacked_netdevs; |
cb9fc36a | 117 | AddressFamilyBoolean dhcp; |
5be4d38e | 118 | bool dhcp_dns; |
bcb7a07e | 119 | bool dhcp_ntp; |
4f882b2a | 120 | bool dhcp_mtu; |
1346b1f0 | 121 | bool dhcp_hostname; |
ad0734e8 | 122 | bool dhcp_domains; |
4cc7a82c | 123 | bool dhcp_sendhost; |
f5de5b00 | 124 | bool dhcp_broadcast; |
eb27aeca | 125 | bool dhcp_critical; |
e1ea665e | 126 | bool dhcp_routes; |
84b5b79a | 127 | unsigned dhcp_route_metric; |
5c1d3fc9 | 128 | bool ipv4ll; |
bfa695b5 | 129 | bool ipv4ll_route; |
f579559b | 130 | |
dd43110f TG |
131 | bool dhcp_server; |
132 | ||
e1853b00 SS |
133 | unsigned cost; |
134 | ||
769d324c | 135 | AddressFamilyBoolean ip_forward; |
5a8bcb67 | 136 | bool ip_masquerade; |
5a8bcb67 | 137 | |
c106cc36 TG |
138 | struct ether_addr *mac; |
139 | unsigned mtu; | |
140 | ||
ce43e484 SS |
141 | bool lldp; |
142 | ||
f048a16b TG |
143 | LIST_HEAD(Address, static_addresses); |
144 | LIST_HEAD(Route, static_routes); | |
b98b483b | 145 | LIST_HEAD(FdbEntry, static_fdb_entries); |
f579559b | 146 | |
6ae115c1 TG |
147 | Hashmap *addresses_by_section; |
148 | Hashmap *routes_by_section; | |
b98b483b | 149 | Hashmap *fdb_entries_by_section; |
6ae115c1 | 150 | |
67272d15 | 151 | bool wildcard_domain; |
6192b846 | 152 | char **domains, **dns, **ntp; |
06f021a8 | 153 | |
bd8f6538 TG |
154 | LLMNRSupport llmnr; |
155 | ||
f579559b TG |
156 | LIST_FIELDS(Network, networks); |
157 | }; | |
158 | ||
159 | struct Address { | |
160 | Network *network; | |
16aa63a0 | 161 | unsigned section; |
f579559b | 162 | |
0dd25fb9 | 163 | int family; |
f579559b | 164 | unsigned char prefixlen; |
5c1d3fc9 | 165 | unsigned char scope; |
81163121 | 166 | unsigned char flags; |
f579559b TG |
167 | char *label; |
168 | ||
eb0ea358 | 169 | struct in_addr broadcast; |
aba496a5 | 170 | struct ifa_cacheinfo cinfo; |
8cd11a0f | 171 | |
5d3de3fe | 172 | union in_addr_union in_addr; |
c081882f | 173 | union in_addr_union in_addr_peer; |
f579559b | 174 | |
fd6d906c | 175 | bool ip_masquerade_done; |
5a8bcb67 | 176 | |
3d3d4255 | 177 | LIST_FIELDS(Address, addresses); |
f579559b TG |
178 | }; |
179 | ||
180 | struct Route { | |
181 | Network *network; | |
16aa63a0 | 182 | unsigned section; |
f579559b | 183 | |
0dd25fb9 | 184 | int family; |
6ae115c1 | 185 | unsigned char dst_prefixlen; |
9e7e4408 | 186 | unsigned char src_prefixlen; |
5c1d3fc9 UTL |
187 | unsigned char scope; |
188 | uint32_t metrics; | |
28cc555d | 189 | unsigned char protocol; /* RTPROT_* */ |
f579559b | 190 | |
5d3de3fe LP |
191 | union in_addr_union in_addr; |
192 | union in_addr_union dst_addr; | |
9e7e4408 | 193 | union in_addr_union src_addr; |
46b0c76e | 194 | union in_addr_union prefsrc_addr; |
6ae115c1 | 195 | |
3d3d4255 | 196 | LIST_FIELDS(Route, routes); |
f579559b TG |
197 | }; |
198 | ||
11bf3cce LP |
199 | struct AddressPool { |
200 | Manager *manager; | |
201 | ||
0dd25fb9 | 202 | int family; |
11bf3cce LP |
203 | unsigned prefixlen; |
204 | ||
205 | union in_addr_union in_addr; | |
206 | ||
207 | LIST_FIELDS(AddressPool, address_pools); | |
208 | }; | |
209 | ||
f579559b TG |
210 | struct Manager { |
211 | sd_rtnl *rtnl; | |
212 | sd_event *event; | |
9c0a72f9 | 213 | sd_event_source *bus_retry_event_source; |
1346b1f0 | 214 | sd_bus *bus; |
9c0a72f9 | 215 | sd_bus_slot *prepare_for_sleep_slot; |
f579559b TG |
216 | struct udev *udev; |
217 | struct udev_monitor *udev_monitor; | |
218 | sd_event_source *udev_event_source; | |
219 | ||
6a24f148 TG |
220 | bool enumerating; |
221 | ||
bbf7c048 | 222 | char *state_file; |
e331e246 | 223 | LinkOperationalState operational_state; |
bbf7c048 | 224 | |
f579559b | 225 | Hashmap *links; |
52433f6b | 226 | Hashmap *netdevs; |
f579559b | 227 | LIST_HEAD(Network, networks); |
11bf3cce | 228 | LIST_HEAD(AddressPool, address_pools); |
f579559b | 229 | |
f579559b TG |
230 | usec_t network_dirs_ts_usec; |
231 | }; | |
232 | ||
2ad8416d ZJS |
233 | extern const char* const network_dirs[]; |
234 | ||
f579559b TG |
235 | /* Manager */ |
236 | ||
e331e246 TG |
237 | extern const sd_bus_vtable manager_vtable[]; |
238 | ||
f579559b TG |
239 | int manager_new(Manager **ret); |
240 | void manager_free(Manager *m); | |
241 | ||
02b59d57 TG |
242 | int manager_load_config(Manager *m); |
243 | bool manager_should_reload(Manager *m); | |
244 | ||
505f8da7 | 245 | int manager_rtnl_enumerate_links(Manager *m); |
45af44d4 | 246 | int manager_rtnl_enumerate_addresses(Manager *m); |
f579559b | 247 | |
e331e246 | 248 | int manager_send_changed(Manager *m, const char *property, ...) _sentinel_; |
bbf7c048 | 249 | int manager_save(Manager *m); |
3bef724f | 250 | |
0dd25fb9 | 251 | int manager_address_pool_acquire(Manager *m, int family, unsigned prefixlen, union in_addr_union *found); |
11bf3cce | 252 | |
f579559b TG |
253 | DEFINE_TRIVIAL_CLEANUP_FUNC(Manager*, manager_free); |
254 | #define _cleanup_manager_free_ _cleanup_(manager_freep) | |
255 | ||
256 | /* Network */ | |
257 | ||
258 | int network_load(Manager *manager); | |
f579559b TG |
259 | |
260 | void network_free(Network *network); | |
261 | ||
262 | DEFINE_TRIVIAL_CLEANUP_FUNC(Network*, network_free); | |
263 | #define _cleanup_network_free_ _cleanup_(network_freep) | |
264 | ||
505f8da7 TG |
265 | int network_get(Manager *manager, struct udev_device *device, |
266 | const char *ifname, const struct ether_addr *mac, | |
267 | Network **ret); | |
f579559b TG |
268 | int network_apply(Manager *manager, Network *network, Link *link); |
269 | ||
69a93e7d | 270 | int config_parse_netdev(const char *unit, const char *filename, unsigned line, |
02b59d57 TG |
271 | const char *section, unsigned section_line, const char *lvalue, |
272 | int ltype, const char *rvalue, void *data, void *userdata); | |
273 | ||
6192b846 TG |
274 | int config_parse_domains(const char *unit, |
275 | const char *filename, | |
276 | unsigned line, | |
277 | const char *section, | |
278 | unsigned section_line, | |
279 | const char *lvalue, | |
280 | int ltype, | |
281 | const char *rvalue, | |
282 | void *data, | |
283 | void *userdata); | |
284 | ||
7951dea2 SS |
285 | int config_parse_tunnel(const char *unit, |
286 | const char *filename, | |
287 | unsigned line, | |
288 | const char *section, | |
289 | unsigned section_line, | |
290 | const char *lvalue, | |
291 | int ltype, | |
292 | const char *rvalue, | |
293 | void *data, | |
294 | void *userdata); | |
295 | ||
296 | int config_parse_tunnel_address(const char *unit, | |
297 | const char *filename, | |
298 | unsigned line, | |
299 | const char *section, | |
300 | unsigned section_line, | |
301 | const char *lvalue, | |
302 | int ltype, | |
303 | const char *rvalue, | |
304 | void *data, | |
305 | void *userdata); | |
306 | ||
85a8eeee SS |
307 | int config_parse_vxlan_group_address(const char *unit, |
308 | const char *filename, | |
309 | unsigned line, | |
310 | const char *section, | |
311 | unsigned section_line, | |
312 | const char *lvalue, | |
313 | int ltype, | |
314 | const char *rvalue, | |
315 | void *data, | |
316 | void *userdata); | |
317 | ||
02b59d57 | 318 | /* gperf */ |
c0dda186 | 319 | const struct ConfigPerfItem* network_network_gperf_lookup(const char *key, unsigned length); |
f579559b TG |
320 | |
321 | /* Route */ | |
f048a16b | 322 | int route_new_static(Network *network, unsigned section, Route **ret); |
28cc555d | 323 | int route_new_dynamic(Route **ret, unsigned char rtm_protocol); |
f579559b | 324 | void route_free(Route *route); |
f882c247 | 325 | int route_configure(Route *route, Link *link, sd_rtnl_message_handler_t callback); |
5c1d3fc9 UTL |
326 | int route_drop(Route *route, Link *link, sd_rtnl_message_handler_t callback); |
327 | ||
f579559b TG |
328 | |
329 | DEFINE_TRIVIAL_CLEANUP_FUNC(Route*, route_free); | |
330 | #define _cleanup_route_free_ _cleanup_(route_freep) | |
331 | ||
332 | int config_parse_gateway(const char *unit, const char *filename, unsigned line, | |
71a61510 TG |
333 | const char *section, unsigned section_line, const char *lvalue, |
334 | int ltype, const char *rvalue, void *data, void *userdata); | |
f579559b | 335 | |
6ae115c1 TG |
336 | int config_parse_destination(const char *unit, const char *filename, unsigned line, |
337 | const char *section, unsigned section_line, const char *lvalue, | |
338 | int ltype, const char *rvalue, void *data, void *userdata); | |
339 | ||
5d8e593d SS |
340 | int config_parse_route_priority(const char *unit, const char *filename, unsigned line, |
341 | const char *section, unsigned section_line, const char *lvalue, | |
342 | int ltype, const char *rvalue, void *data, void *userdata); | |
f579559b | 343 | /* Address */ |
f048a16b TG |
344 | int address_new_static(Network *network, unsigned section, Address **ret); |
345 | int address_new_dynamic(Address **ret); | |
f579559b | 346 | void address_free(Address *address); |
f882c247 | 347 | int address_configure(Address *address, Link *link, sd_rtnl_message_handler_t callback); |
aba496a5 | 348 | int address_update(Address *address, Link *link, sd_rtnl_message_handler_t callback); |
407fe036 | 349 | int address_drop(Address *address, Link *link, sd_rtnl_message_handler_t callback); |
5a8bcb67 LP |
350 | int address_establish(Address *address, Link *link); |
351 | int address_release(Address *address, Link *link); | |
9505d3c6 | 352 | bool address_equal(Address *a1, Address *a2); |
f579559b TG |
353 | |
354 | DEFINE_TRIVIAL_CLEANUP_FUNC(Address*, address_free); | |
355 | #define _cleanup_address_free_ _cleanup_(address_freep) | |
356 | ||
357 | int config_parse_address(const char *unit, const char *filename, unsigned line, | |
71a61510 TG |
358 | const char *section, unsigned section_line, const char *lvalue, |
359 | int ltype, const char *rvalue, void *data, void *userdata); | |
f579559b | 360 | |
eb0ea358 TG |
361 | int config_parse_broadcast(const char *unit, const char *filename, unsigned line, |
362 | const char *section, unsigned section_line, const char *lvalue, | |
363 | int ltype, const char *rvalue, void *data, void *userdata); | |
364 | ||
6ae115c1 TG |
365 | int config_parse_label(const char *unit, const char *filename, unsigned line, |
366 | const char *section, unsigned section_line, const char *lvalue, | |
367 | int ltype, const char *rvalue, void *data, void *userdata); | |
368 | ||
b98b483b AR |
369 | /* Forwarding database table. */ |
370 | int fdb_entry_configure(sd_rtnl *const rtnl, FdbEntry *const fdb_entry, const int ifindex); | |
371 | void fdb_entry_free(FdbEntry *fdb_entry); | |
372 | int fdb_entry_new_static(Network *const network, const unsigned section, FdbEntry **ret); | |
373 | ||
374 | DEFINE_TRIVIAL_CLEANUP_FUNC(FdbEntry*, fdb_entry_free); | |
375 | #define _cleanup_fdbentry_free_ _cleanup_(fdb_entry_freep) | |
376 | ||
377 | int config_parse_fdb_hwaddr(const char *unit, const char *filename, unsigned line, | |
378 | const char *section, unsigned section_line, const char *lvalue, | |
379 | int ltype, const char *rvalue, void *data, void *userdata); | |
380 | ||
381 | int config_parse_fdb_vlan_id(const char *unit, const char *filename, unsigned line, | |
382 | const char *section, unsigned section_line, const char *lvalue, | |
383 | int ltype, const char *rvalue, void *data, void *userdata); | |
384 | ||
ed942a9e TG |
385 | /* DHCP support */ |
386 | ||
ed942a9e TG |
387 | int config_parse_dhcp(const char *unit, const char *filename, unsigned line, |
388 | const char *section, unsigned section_line, const char *lvalue, | |
389 | int ltype, const char *rvalue, void *data, void *userdata); | |
390 | ||
bd8f6538 TG |
391 | /* LLMNR support */ |
392 | ||
393 | const char* llmnr_support_to_string(LLMNRSupport i) _const_; | |
394 | LLMNRSupport llmnr_support_from_string(const char *s) _pure_; | |
395 | ||
396 | int config_parse_llmnr(const char *unit, const char *filename, unsigned line, | |
397 | const char *section, unsigned section_line, const char *lvalue, | |
398 | int ltype, const char *rvalue, void *data, void *userdata); | |
399 | ||
11bf3cce LP |
400 | /* Address Pool */ |
401 | ||
0dd25fb9 LP |
402 | int address_pool_new(Manager *m, AddressPool **ret, int family, const union in_addr_union *u, unsigned prefixlen); |
403 | int address_pool_new_from_string(Manager *m, AddressPool **ret, int family, const char *p, unsigned prefixlen); | |
11bf3cce LP |
404 | void address_pool_free(AddressPool *p); |
405 | ||
406 | int address_pool_acquire(AddressPool *p, unsigned prefixlen, union in_addr_union *found); | |
cb9fc36a LP |
407 | |
408 | const char *address_family_boolean_to_string(AddressFamilyBoolean b) _const_; | |
409 | AddressFamilyBoolean address_family_boolean_from_string(const char *s) _const_; | |
769d324c LP |
410 | |
411 | 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 TG |
412 | |
413 | /* Opeartional State */ | |
414 | ||
415 | const char* link_operstate_to_string(LinkOperationalState s) _const_; | |
416 | LinkOperationalState link_operstate_from_string(const char *s) _pure_; |