chiark / gitweb /
networkd: netdev - reduce chance of race when receiving netdev's ifindex
[elogind.git] / src / network / networkd.h
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"
29 #include "sd-bus.h"
30 #include "sd-dhcp-client.h"
31 #include "udev.h"
32
33 #include "rtnl-util.h"
34 #include "hashmap.h"
35 #include "list.h"
36
37 typedef struct Netdev Netdev;
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
44 typedef struct netdev_enslave_callback netdev_enslave_callback;
45
46 struct netdev_enslave_callback {
47         sd_rtnl_message_handler_t callback;
48         Link *link;
49
50         LIST_FIELDS(netdev_enslave_callback, callbacks);
51 };
52
53 typedef enum NetdevKind {
54         NETDEV_KIND_BRIDGE,
55         NETDEV_KIND_BOND,
56         NETDEV_KIND_VLAN,
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 {
70         Manager *manager;
71
72         char *filename;
73
74         char *description;
75         char *name;
76         NetdevKind kind;
77
78         int vlanid;
79
80         int ifindex;
81         NetdevState state;
82
83         LIST_HEAD(netdev_enslave_callback, callbacks);
84 };
85
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;
98         Netdev *bridge;
99         Netdev *bond;
100         Netdev *vlan;
101         bool dhcp;
102         bool dhcp_dns;
103         bool dhcp_mtu;
104         bool dhcp_hostname;
105         bool dhcp_domainname;
106         bool dhcp_critical;
107
108         LIST_HEAD(Address, static_addresses);
109         LIST_HEAD(Route, static_routes);
110         Address *dns;
111
112         Hashmap *addresses_by_section;
113         Hashmap *routes_by_section;
114
115         LIST_FIELDS(Network, networks);
116 };
117
118 struct Address {
119         Network *network;
120         uint64_t section;
121
122         unsigned char family;
123         unsigned char prefixlen;
124         char *label;
125
126         struct in_addr broadcast;
127
128         union {
129                 struct in_addr in;
130                 struct in6_addr in6;
131         } in_addr;
132
133         LIST_FIELDS(Address, static_addresses);
134 };
135
136 struct Route {
137         Network *network;
138         uint64_t section;
139
140         unsigned char family;
141         unsigned char dst_prefixlen;
142
143         union {
144                 struct in_addr in;
145                 struct in6_addr in6;
146         } in_addr;
147
148         union {
149                 struct in_addr in;
150                 struct in6_addr in6;
151         } dst_addr;
152
153         LIST_FIELDS(Route, static_routes);
154 };
155
156 typedef enum LinkState {
157         LINK_STATE_ENSLAVING,
158         LINK_STATE_SETTING_ADDRESSES,
159         LINK_STATE_SETTING_ROUTES,
160         LINK_STATE_CONFIGURED,
161         LINK_STATE_FAILED,
162         _LINK_STATE_MAX,
163         _LINK_STATE_INVALID = -1
164 } LinkState;
165
166 struct Link {
167         Manager *manager;
168
169         uint64_t ifindex;
170         char *ifname;
171         struct ether_addr mac;
172
173         unsigned flags;
174
175         Network *network;
176
177         Route *dhcp_route;
178         Address *dhcp_address;
179         Address *dns;
180         uint16_t original_mtu;
181
182         LinkState state;
183
184         unsigned addr_messages;
185         unsigned route_messages;
186         unsigned enslaving;
187
188         sd_dhcp_client *dhcp;
189 };
190
191 struct Manager {
192         sd_rtnl *rtnl;
193         sd_event *event;
194         sd_bus *bus;
195         struct udev *udev;
196         struct udev_monitor *udev_monitor;
197         sd_event_source *udev_event_source;
198
199         Hashmap *links;
200         Hashmap *netdevs;
201         LIST_HEAD(Network, networks);
202
203         usec_t network_dirs_ts_usec;
204 };
205
206 extern const char* const network_dirs[];
207
208 /* Manager */
209
210 int manager_new(Manager **ret);
211 void manager_free(Manager *m);
212
213 int manager_load_config(Manager *m);
214 bool manager_should_reload(Manager *m);
215
216 int manager_udev_enumerate_links(Manager *m);
217 int manager_udev_listen(Manager *m);
218
219 int manager_rtnl_listen(Manager *m);
220 int manager_bus_listen(Manager *m);
221
222 int manager_update_resolv_conf(Manager *m);
223
224 DEFINE_TRIVIAL_CLEANUP_FUNC(Manager*, manager_free);
225 #define _cleanup_manager_free_ _cleanup_(manager_freep)
226
227 /* Netdev */
228
229 int netdev_load(Manager *manager);
230
231 void netdev_free(Netdev *netdev);
232
233 DEFINE_TRIVIAL_CLEANUP_FUNC(Netdev*, netdev_free);
234 #define _cleanup_netdev_free_ _cleanup_(netdev_freep)
235
236 int netdev_get(Manager *manager, const char *name, Netdev **ret);
237 int netdev_set_ifindex(Netdev *netdev, int ifindex);
238 int netdev_enslave(Netdev *netdev, Link *link, sd_rtnl_message_handler_t cb);
239
240 const char *netdev_kind_to_string(NetdevKind d) _const_;
241 NetdevKind netdev_kind_from_string(const char *d) _pure_;
242
243 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);
244
245 /* Network */
246
247 int network_load(Manager *manager);
248
249 void network_free(Network *network);
250
251 DEFINE_TRIVIAL_CLEANUP_FUNC(Network*, network_free);
252 #define _cleanup_network_free_ _cleanup_(network_freep)
253
254 int network_get(Manager *manager, struct udev_device *device, Network **ret);
255 int network_apply(Manager *manager, Network *network, Link *link);
256
257 int config_parse_bridge(const char *unit, const char *filename, unsigned line,
258                         const char *section, unsigned section_line, const char *lvalue,
259                         int ltype, const char *rvalue, void *data, void *userdata);
260
261 int config_parse_bond(const char *unit, const char *filename, unsigned line,
262                       const char *section, unsigned section_line, const char *lvalue,
263                       int ltype, const char *rvalue, void *data, void *userdata);
264
265 int config_parse_vlan(const char *unit, const char *filename, unsigned line,
266                       const char *section, unsigned section_line, const char *lvalue,
267                       int ltype, const char *rvalue, void *data, void *userdata);
268
269 /* gperf */
270
271 const struct ConfigPerfItem* network_gperf_lookup(const char *key, unsigned length);
272
273 /* Route */
274 int route_new_static(Network *network, unsigned section, Route **ret);
275 int route_new_dynamic(Route **ret);
276 void route_free(Route *route);
277 int route_configure(Route *route, Link *link, sd_rtnl_message_handler_t callback);
278
279 DEFINE_TRIVIAL_CLEANUP_FUNC(Route*, route_free);
280 #define _cleanup_route_free_ _cleanup_(route_freep)
281
282 int config_parse_gateway(const char *unit, const char *filename, unsigned line,
283                          const char *section, unsigned section_line, const char *lvalue,
284                          int ltype, const char *rvalue, void *data, void *userdata);
285
286 int config_parse_destination(const char *unit, const char *filename, unsigned line,
287                              const char *section, unsigned section_line, const char *lvalue,
288                              int ltype, const char *rvalue, void *data, void *userdata);
289
290 /* Address */
291 int address_new_static(Network *network, unsigned section, Address **ret);
292 int address_new_dynamic(Address **ret);
293 void address_free(Address *address);
294 int address_configure(Address *address, Link *link, sd_rtnl_message_handler_t callback);
295 int address_drop(Address *address, Link *link, sd_rtnl_message_handler_t callback);
296
297 DEFINE_TRIVIAL_CLEANUP_FUNC(Address*, address_free);
298 #define _cleanup_address_free_ _cleanup_(address_freep)
299
300 int config_parse_dns(const char *unit, const char *filename, unsigned line,
301                      const char *section, unsigned section_line, const char *lvalue,
302                      int ltype, const char *rvalue, void *data, void *userdata);
303
304 int config_parse_address(const char *unit, const char *filename, unsigned line,
305                          const char *section, unsigned section_line, const char *lvalue,
306                          int ltype, const char *rvalue, void *data, void *userdata);
307
308 int config_parse_broadcast(const char *unit, const char *filename, unsigned line,
309                            const char *section, unsigned section_line, const char *lvalue,
310                            int ltype, const char *rvalue, void *data, void *userdata);
311
312 int config_parse_label(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
316 /* Link */
317
318 int link_new(Manager *manager, struct udev_device *device, Link **ret);
319 void link_free(Link *link);
320 int link_add(Manager *manager, struct udev_device *device, Link **ret);
321 int link_configure(Link *link);
322
323 int link_update(Link *link, sd_rtnl_message *message);
324
325 DEFINE_TRIVIAL_CLEANUP_FUNC(Link*, link_free);
326 #define _cleanup_link_free_ _cleanup_(link_freep)
327
328 /* Macros which append INTERFACE= to the message */
329
330 #define log_full_link(level, link, fmt, ...) log_meta_object(level, __FILE__, __LINE__, __func__, "INTERFACE=", link->ifname, "%s: " fmt, link->ifname, ##__VA_ARGS__)
331 #define log_debug_link(link, ...)       log_full_link(LOG_DEBUG, link, ##__VA_ARGS__)
332 #define log_info_link(link, ...)        log_full_link(LOG_INFO, link, ##__VA_ARGS__)
333 #define log_notice_link(link, ...)      log_full_link(LOG_NOTICE, link, ##__VA_ARGS__)
334 #define log_warning_link(link, ...)     log_full_link(LOG_WARNING, link, ##__VA_ARGS__)
335 #define log_error_link(link, ...)       log_full_link(LOG_ERR, link, ##__VA_ARGS__)
336
337 #define log_struct_link(level, link, ...) log_struct(level, "INTERFACE=%s", link->ifname, __VA_ARGS__)
338
339 /* More macros which append INTERFACE= to the message */
340
341 #define log_full_netdev(level, netdev, fmt, ...) log_meta_object(level, __FILE__, __LINE__, __func__, "INTERFACE=", netdev->name, "%s: " fmt, netdev->name, ##__VA_ARGS__)
342 #define log_debug_netdev(netdev, ...)       log_full_netdev(LOG_DEBUG, netdev, ##__VA_ARGS__)
343 #define log_info_netdev(netdev, ...)        log_full_netdev(LOG_INFO, netdev, ##__VA_ARGS__)
344 #define log_notice_netdev(netdev, ...)      log_full_netdev(LOG_NOTICE, netdev, ##__VA_ARGS__)
345 #define log_warning_netdev(netdev, ...)     log_full_netdev(LOG_WARNING, netdev,## __VA_ARGS__)
346 #define log_error_netdev(netdev, ...)       log_full_netdev(LOG_ERR, netdev, ##__VA_ARGS__)
347
348 #define log_struct_netdev(level, netdev, ...) log_struct(level, "INTERFACE=%s", netdev->name, __VA_ARGS__)
349
350 #define NETDEV(netdev) "INTERFACE=%s", netdev->name
351 #define ADDRESS_FMT_VAL(address)            \
352         (address).s_addr & 0xFF,            \
353         ((address).s_addr >> 8) & 0xFF,     \
354         ((address).s_addr >> 16) & 0xFF,    \
355         (address).s_addr >> 24