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/>.
28 #include "conf-parser.h"
31 int address_new(Network *network, unsigned section, Address **ret) {
32 _cleanup_address_free_ Address *address = NULL;
35 uint64_t key = section;
36 address = hashmap_get(network->addresses_by_section, &key);
45 address = new0(Address, 1);
49 address->network = network;
51 LIST_PREPEND(addresses, network->addresses, address);
54 address->section = section;
55 hashmap_put(network->addresses_by_section, &address->section, address);
64 void address_free(Address *address) {
68 LIST_REMOVE(addresses, address->network->addresses, address);
71 hashmap_remove(address->network->addresses_by_section,
77 int address_configure(Address *address, Link *link,
78 sd_rtnl_message_handler_t callback) {
79 _cleanup_sd_rtnl_message_unref_ sd_rtnl_message *req = NULL;
82 assert(link->manager);
84 r = sd_rtnl_message_addr_new(RTM_NEWADDR, link->ifindex,
85 address->family, address->prefixlen,
86 IFA_F_PERMANENT, RT_SCOPE_UNIVERSE, &req);
88 log_error("Could not allocate RTM_NEWADDR message: %s",
93 r = sd_rtnl_message_append(req, IFA_LOCAL, &address->in_addr);
95 log_error("Could not append IFA_LOCAL attribute: %s",
100 if (address->family == AF_INET) {
101 struct in_addr broadcast;
103 broadcast.s_addr = address->in_addr.in.s_addr | address->netmask.s_addr;
105 r = sd_rtnl_message_append(req, IFA_BROADCAST, &broadcast);
107 log_error("Could not append IFA_BROADCAST attribute: %s",
113 if (address->label) {
114 r = sd_rtnl_message_append(req, IFA_LABEL, address->label);
116 log_error("Could not append IFA_LABEL attribute: %s",
122 r = sd_rtnl_call_async(link->manager->rtnl, req, callback, link, 0, NULL);
124 log_error("Could not send rtnetlink message: %s", strerror(-r));
128 link->rtnl_messages ++;
133 int config_parse_address(const char *unit,
134 const char *filename,
137 unsigned section_line,
143 Network *network = userdata;
144 _cleanup_address_free_ Address *n = NULL;
145 _cleanup_free_ char *address = NULL;
155 r = address_new(network, section_line, &n);
159 /* Address=address/prefixlen */
162 e = strchr(rvalue, '/');
165 r = safe_atou(e + 1, &i);
167 log_syntax(unit, LOG_ERR, filename, line, EINVAL,
168 "Interface prefix length is invalid, "
169 "ignoring assignment: %s", e + 1);
173 n->prefixlen = (unsigned char) i;
174 n->netmask.s_addr = htonl(0xfffffffflu >> n->prefixlen);
176 address = strndup(rvalue, e - rvalue);
180 address = strdup(rvalue);
185 r = net_parse_inaddr(address, &n->family, &n->in_addr);
187 log_syntax(unit, LOG_ERR, filename, line, EINVAL,
188 "Address is invalid, ignoring assignment: %s", address);
197 int config_parse_label(const char *unit,
198 const char *filename,
201 unsigned section_line,
207 Network *network = userdata;
208 _cleanup_address_free_ Address *n = NULL;
218 r = address_new(network, section_line, &n);
222 label = strdup(rvalue);
226 if (!ascii_is_valid(label) || strlen(label) >= IFNAMSIZ) {
227 log_syntax(unit, LOG_ERR, filename, line, EINVAL,
228 "Interface label is not ASCII clean or is too"
229 " long, ignoring assignment: %s", rvalue);