1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2013 Tom Gundersen <teg@jklm.no>
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.
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.
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/>.
24 #include "path-util.h"
25 #include "conf-files.h"
26 #include "conf-parser.h"
28 static int network_load_one(Manager *manager, const char *filename) {
29 _cleanup_network_free_ Network *network = NULL;
30 _cleanup_fclose_ FILE *file = NULL;
36 file = fopen(filename, "re");
44 network = new0(Network, 1);
48 network->manager = manager;
50 LIST_HEAD_INIT(network->addresses);
51 LIST_HEAD_INIT(network->routes);
53 network->addresses_by_section = hashmap_new(uint64_hash_func, uint64_compare_func);
54 if (!network->addresses_by_section)
57 network->routes_by_section = hashmap_new(uint64_hash_func, uint64_compare_func);
58 if (!network->routes_by_section)
61 network->filename = strdup(filename);
62 if (!network->filename)
65 r = config_parse(NULL, filename, file, "Match\0Network\0Address\0Route\0", config_item_perf_lookup,
66 (void*) network_gperf_lookup, false, false, network);
68 log_warning("Could not parse config file %s: %s", filename, strerror(-r));
71 log_debug("Parsed configuration file %s", filename);
73 LIST_PREPEND(networks, manager->networks, network);
79 int network_load(Manager *manager) {
86 while ((network = manager->networks))
87 network_free(network);
89 r = conf_files_list_strv(&files, ".network", NULL, (const char **)manager->network_dirs);
91 log_error("failed to enumerate network files: %s", strerror(-r));
95 STRV_FOREACH_BACKWARDS(f, files) {
96 r = network_load_one(manager, *f);
106 void network_free(Network *network) {
113 free(network->filename);
115 free(network->match_mac);
116 free(network->match_path);
117 free(network->match_driver);
118 free(network->match_type);
119 free(network->match_name);
121 free(network->description);
123 while ((route = network->routes))
126 while ((address = network->addresses))
127 address_free(address);
129 hashmap_free(network->addresses_by_section);
130 hashmap_free(network->routes_by_section);
132 LIST_REMOVE(networks, network->manager->networks, network);
137 int network_get(Manager *manager, struct udev_device *device, Network **ret) {
144 if (manager_should_reload(manager))
145 manager_load_config(manager);
147 LIST_FOREACH(networks, network, manager->networks) {
148 if (net_match_config(network->match_mac, network->match_path,
149 network->match_driver, network->match_type,
151 udev_device_get_sysattr_value(device, "address"),
152 udev_device_get_property_value(device, "ID_PATH"),
153 udev_device_get_driver(device),
154 udev_device_get_devtype(device),
155 udev_device_get_sysname(device))) {
156 log_debug("Network file %s applies to link %s",
158 udev_device_get_sysname(device));
169 int network_apply(Manager *manager, Network *network, Link *link) {
172 log_info("Network '%s' being applied to link '%s'",
173 network->description, link->ifname);
175 link->network = network;
177 r = link_configure(link);
184 int config_parse_bridge(const char *unit,
185 const char *filename,
188 unsigned section_line,
194 Network *network = userdata;
203 r = bridge_get(network->manager, rvalue, &bridge);
205 log_syntax(unit, LOG_ERR, filename, line, EINVAL,
206 "Bridge is invalid, ignoring assignment: %s", rvalue);
210 network->bridge = bridge;