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->static_addresses);
51 LIST_HEAD_INIT(network->static_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));
72 LIST_PREPEND(networks, manager->networks, network);
78 int network_load(Manager *manager) {
85 while ((network = manager->networks))
86 network_free(network);
88 r = conf_files_list_strv(&files, ".network", NULL, (const char **)manager->network_dirs);
90 log_error("Failed to enumerate network files: %s", strerror(-r));
94 STRV_FOREACH_BACKWARDS(f, files) {
95 r = network_load_one(manager, *f);
105 void network_free(Network *network) {
112 free(network->filename);
114 free(network->match_mac);
115 free(network->match_path);
116 free(network->match_driver);
117 free(network->match_type);
118 free(network->match_name);
120 free(network->description);
122 while ((route = network->static_routes))
125 while ((address = network->static_addresses))
126 address_free(address);
128 hashmap_free(network->addresses_by_section);
129 hashmap_free(network->routes_by_section);
131 LIST_REMOVE(networks, network->manager->networks, network);
136 int network_get(Manager *manager, struct udev_device *device, Network **ret) {
143 if (manager_should_reload(manager))
144 manager_load_config(manager);
146 LIST_FOREACH(networks, network, manager->networks) {
147 if (net_match_config(network->match_mac, network->match_path,
148 network->match_driver, network->match_type,
150 udev_device_get_sysattr_value(device, "address"),
151 udev_device_get_property_value(device, "ID_PATH"),
152 udev_device_get_driver(device),
153 udev_device_get_devtype(device),
154 udev_device_get_sysname(device))) {
155 log_debug("%s: found matching network '%s'",
156 udev_device_get_sysname(device),
168 int network_apply(Manager *manager, Network *network, Link *link) {
171 link->network = network;
173 r = link_configure(link);
180 int config_parse_bridge(const char *unit,
181 const char *filename,
184 unsigned section_line,
190 Network *network = userdata;
199 r = bridge_get(network->manager, rvalue, &bridge);
201 log_syntax(unit, LOG_ERR, filename, line, EINVAL,
202 "Bridge is invalid, ignoring assignment: %s", rvalue);
206 network->bridge = bridge;