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;
33 file = fopen(filename, "re");
41 network = new0(Network, 1);
45 network->manager = manager;
47 LIST_HEAD_INIT(network->addresses);
48 LIST_HEAD_INIT(network->routes);
50 network->addresses_by_section = hashmap_new(uint64_hash_func, uint64_compare_func);
51 if (!network->addresses_by_section)
54 network->routes_by_section = hashmap_new(uint64_hash_func, uint64_compare_func);
55 if (!network->routes_by_section)
58 network->filename = strdup(filename);
59 if (!network->filename)
62 r = config_parse(NULL, filename, file, "Match\0Network\0Address\0Route\0", config_item_perf_lookup,
63 (void*) network_gperf_lookup, false, false, network);
65 log_warning("Could not parse config file %s: %s", filename, strerror(-r));
68 log_debug("Parsed configuration file %s", filename);
70 LIST_PREPEND(networks, manager->networks, network);
76 int network_load(Manager *manager) {
83 while ((network = manager->networks))
84 network_free(network);
86 r = conf_files_list_strv(&files, ".network", NULL, (const char **)manager->network_dirs);
88 log_error("failed to enumerate network files: %s", strerror(-r));
92 STRV_FOREACH_BACKWARDS(f, files) {
93 r = network_load_one(manager, *f);
103 void network_free(Network *network) {
110 free(network->filename);
112 free(network->match_mac);
113 free(network->match_path);
114 free(network->match_driver);
115 free(network->match_type);
116 free(network->match_name);
118 free(network->description);
120 while ((route = network->routes))
123 while ((address = network->addresses))
124 address_free(address);
126 hashmap_free(network->addresses_by_section);
127 hashmap_free(network->routes_by_section);
129 LIST_REMOVE(networks, network->manager->networks, network);
134 int network_get(Manager *manager, struct udev_device *device, Network **ret) {
141 if (manager_should_reload(manager))
142 manager_load_config(manager);
144 LIST_FOREACH(networks, network, manager->networks) {
145 if (net_match_config(network->match_mac, network->match_path,
146 network->match_driver, network->match_type,
148 udev_device_get_sysattr_value(device, "address"),
149 udev_device_get_property_value(device, "ID_PATH"),
150 udev_device_get_driver(device),
151 udev_device_get_devtype(device),
152 udev_device_get_sysname(device))) {
153 log_debug("Network file %s applies to link %s",
155 udev_device_get_sysname(device));
166 int network_apply(Manager *manager, Network *network, Link *link) {
169 log_info("Network '%s' being applied to link '%s'",
170 network->description, link->ifname);
172 link->network = network;
174 r = link_configure(link);
181 int config_parse_bridge(const char *unit,
182 const char *filename,
185 unsigned section_line,
191 Network *network = userdata;
200 r = bridge_get(network->manager, rvalue, &bridge);
202 log_syntax(unit, LOG_ERR, filename, line, EINVAL,
203 "Bridge is invalid, ignoring assignment: %s", rvalue);
207 network->bridge = bridge;