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 LIST_HEAD_INIT(network->addresses);
47 r = config_parse(NULL, filename, file, "Match\0Network\0", config_item_perf_lookup,
48 (void*) network_gperf_lookup, false, false, network);
50 log_warning("Could not parse config file %s: %s", filename, strerror(-r));
53 log_debug("Parsed configuration file %s", filename);
55 network->filename = strdup(filename);
56 if (!network->filename)
59 LIST_PREPEND(networks, manager->networks, network);
65 int network_load(Manager *manager) {
72 while ((network = manager->networks))
73 network_free(network);
75 /* update timestamp */
76 paths_check_timestamp(manager->network_dirs, &manager->network_dirs_ts_usec, true);
78 r = conf_files_list_strv(&files, ".network", NULL, (const char **)manager->network_dirs);
80 log_error("failed to enumerate network files: %s", strerror(-r));
84 STRV_FOREACH_BACKWARDS(f, files) {
85 r = network_load_one(manager, *f);
95 bool network_should_reload(Manager *manager) {
96 return paths_check_timestamp(manager->network_dirs, &manager->network_dirs_ts_usec, false);
99 void network_free(Network *network) {
106 free(network->filename);
108 free(network->match_mac);
109 free(network->match_path);
110 free(network->match_driver);
111 free(network->match_type);
112 free(network->match_name);
114 free(network->description);
116 while ((route = network->routes))
119 while ((address = network->addresses))
120 address_free(address);
122 LIST_REMOVE(networks, network->manager->networks, network);
127 int network_get(Manager *manager, struct udev_device *device, Network **ret) {
134 if (network_should_reload(manager))
135 network_load(manager);
137 LIST_FOREACH(networks, network, manager->networks) {
138 if (net_match_config(network->match_mac, network->match_path,
139 network->match_driver, network->match_type,
141 udev_device_get_sysattr_value(device, "address"),
142 udev_device_get_property_value(device, "ID_PATH"),
143 udev_device_get_driver(device),
144 udev_device_get_devtype(device),
145 udev_device_get_sysname(device))) {
146 log_debug("Network file %s applies to link %s",
148 udev_device_get_sysname(device));
159 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 LIST_FOREACH(addresses, address, network->addresses) {
170 r = address_configure(manager, address, link);
175 r = link_up(manager, link);
179 LIST_FOREACH(routes, route, network->routes) {
180 r = route_configure(manager, route, link);