]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/network/networkd-network.c
networkd: use correct printf formatter
[thirdparty/systemd.git] / src / network / networkd-network.c
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 #include "networkd.h"
23 #include "net-util.h"
24 #include "path-util.h"
25 #include "conf-files.h"
26 #include "conf-parser.h"
27
28 static int network_load_one(Manager *manager, const char *filename) {
29 _cleanup_network_free_ Network *network = NULL;
30 _cleanup_fclose_ FILE *file = NULL;
31 int r;
32
33 file = fopen(filename, "re");
34 if (!file) {
35 if (errno == ENOENT)
36 return 0;
37 else
38 return errno;
39 }
40
41 network = new0(Network, 1);
42 if (!network)
43 return log_oom();
44
45 network->manager = manager;
46
47 LIST_HEAD_INIT(network->addresses);
48 LIST_HEAD_INIT(network->routes);
49
50 network->addresses_by_section = hashmap_new(uint64_hash_func, uint64_compare_func);
51 if (!network->addresses_by_section)
52 return log_oom();
53
54 network->routes_by_section = hashmap_new(uint64_hash_func, uint64_compare_func);
55 if (!network->routes_by_section)
56 return log_oom();
57
58 network->filename = strdup(filename);
59 if (!network->filename)
60 return log_oom();
61
62 r = config_parse(NULL, filename, file, "Match\0Network\0Address\0Route\0", config_item_perf_lookup,
63 (void*) network_gperf_lookup, false, false, network);
64 if (r < 0) {
65 log_warning("Could not parse config file %s: %s", filename, strerror(-r));
66 return r;
67 } else
68 log_debug("Parsed configuration file %s", filename);
69
70 LIST_PREPEND(networks, manager->networks, network);
71 network = NULL;
72
73 return 0;
74 }
75
76 int network_load(Manager *manager) {
77 Network *network;
78 char **files, **f;
79 int r;
80
81 assert(manager);
82
83 while ((network = manager->networks))
84 network_free(network);
85
86 /* update timestamp */
87 paths_check_timestamp(manager->network_dirs, &manager->network_dirs_ts_usec, true);
88
89 r = conf_files_list_strv(&files, ".network", NULL, (const char **)manager->network_dirs);
90 if (r < 0) {
91 log_error("failed to enumerate network files: %s", strerror(-r));
92 return r;
93 }
94
95 STRV_FOREACH_BACKWARDS(f, files) {
96 r = network_load_one(manager, *f);
97 if (r < 0)
98 return r;
99 }
100
101 strv_free(files);
102
103 return 0;
104 }
105
106 bool network_should_reload(Manager *manager) {
107 return paths_check_timestamp(manager->network_dirs, &manager->network_dirs_ts_usec, false);
108 }
109
110 void network_free(Network *network) {
111 Route *route;
112 Address *address;
113
114 if (!network)
115 return;
116
117 free(network->filename);
118
119 free(network->match_mac);
120 free(network->match_path);
121 free(network->match_driver);
122 free(network->match_type);
123 free(network->match_name);
124
125 free(network->description);
126
127 while ((route = network->routes))
128 route_free(route);
129
130 while ((address = network->addresses))
131 address_free(address);
132
133 hashmap_free(network->addresses_by_section);
134 hashmap_free(network->routes_by_section);
135
136 LIST_REMOVE(networks, network->manager->networks, network);
137
138 free(network);
139 }
140
141 int network_get(Manager *manager, struct udev_device *device, Network **ret) {
142 Network *network;
143
144 assert(manager);
145 assert(device);
146 assert(ret);
147
148 if (network_should_reload(manager))
149 network_load(manager);
150
151 LIST_FOREACH(networks, network, manager->networks) {
152 if (net_match_config(network->match_mac, network->match_path,
153 network->match_driver, network->match_type,
154 network->match_name,
155 udev_device_get_sysattr_value(device, "address"),
156 udev_device_get_property_value(device, "ID_PATH"),
157 udev_device_get_driver(device),
158 udev_device_get_devtype(device),
159 udev_device_get_sysname(device))) {
160 log_debug("Network file %s applies to link %s",
161 network->filename,
162 udev_device_get_sysname(device));
163 *ret = network;
164 return 0;
165 }
166 }
167
168 *ret = NULL;
169
170 return -ENOENT;
171 }
172
173 int network_apply(Manager *manager, Network *network, Link *link) {
174 int r;
175
176 log_info("Network '%s' being applied to link '%ju'",
177 network->description, link->ifindex);
178
179 link->network = network;
180
181 r = link_configure(link);
182 if (r < 0)
183 return r;
184
185 return 0;
186 }