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);
49 r = config_parse(NULL, filename, file, "Match\0Network\0", config_item_perf_lookup,
50 (void*) network_gperf_lookup, false, false, network);
52 log_warning("Could not parse config file %s: %s", filename, strerror(-r));
55 log_debug("Parsed configuration file %s", filename);
57 network->filename = strdup(filename);
58 if (!network->filename)
61 LIST_PREPEND(networks, manager->networks, network);
67 int network_load(Manager *manager) {
74 while ((network = manager->networks))
75 network_free(network);
77 /* update timestamp */
78 paths_check_timestamp(manager->network_dirs, &manager->network_dirs_ts_usec, true);
80 r = conf_files_list_strv(&files, ".network", NULL, (const char **)manager->network_dirs);
82 log_error("failed to enumerate network files: %s", strerror(-r));
86 STRV_FOREACH_BACKWARDS(f, files) {
87 r = network_load_one(manager, *f);
97 bool network_should_reload(Manager *manager) {
98 return paths_check_timestamp(manager->network_dirs, &manager->network_dirs_ts_usec, false);
101 void network_free(Network *network) {
108 free(network->filename);
110 free(network->match_mac);
111 free(network->match_path);
112 free(network->match_driver);
113 free(network->match_type);
114 free(network->match_name);
116 free(network->description);
118 while ((route = network->routes))
121 while ((address = network->addresses))
122 address_free(address);
124 LIST_REMOVE(networks, network->manager->networks, network);
129 int network_get(Manager *manager, struct udev_device *device, Network **ret) {
136 if (network_should_reload(manager))
137 network_load(manager);
139 LIST_FOREACH(networks, network, manager->networks) {
140 if (net_match_config(network->match_mac, network->match_path,
141 network->match_driver, network->match_type,
143 udev_device_get_sysattr_value(device, "address"),
144 udev_device_get_property_value(device, "ID_PATH"),
145 udev_device_get_driver(device),
146 udev_device_get_devtype(device),
147 udev_device_get_sysname(device))) {
148 log_debug("Network file %s applies to link %s",
150 udev_device_get_sysname(device));
161 int network_apply(Manager *manager, Network *network, Link *link) {
164 log_info("Network '%s' being applied to link '%u'",
165 network->description, (unsigned) link->ifindex);
167 link->network = network;
169 r = link_configure(link);