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 /* update timestamp */
87 paths_check_timestamp(manager->network_dirs, &manager->network_dirs_ts_usec, true);
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 bool network_should_reload(Manager *manager) {
107 return paths_check_timestamp(manager->network_dirs, &manager->network_dirs_ts_usec, false);
110 void network_free(Network *network) {
117 free(network->filename);
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);
125 free(network->description);
127 while ((route = network->routes))
130 while ((address = network->addresses))
131 address_free(address);
133 hashmap_free(network->addresses_by_section);
134 hashmap_free(network->routes_by_section);
136 LIST_REMOVE(networks, network->manager->networks, network);
141 int network_get(Manager *manager, struct udev_device *device, Network **ret) {
148 if (network_should_reload(manager))
149 network_load(manager);
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,
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",
162 udev_device_get_sysname(device));
173 int network_apply(Manager *manager, Network *network, Link *link) {
176 log_info("Network '%s' being applied to link '%u'",
177 network->description, (unsigned) link->ifindex);
179 link->network = network;
181 r = link_configure(link);