chiark / gitweb /
delete unused variables
[elogind.git] / src / network / networkd-address.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4   This file is part of systemd.
5
6   Copyright 2013 Tom Gundersen <teg@jklm.no>
7
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.
12
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.
17
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/>.
20 ***/
21
22 #include <net/if.h>
23
24 #include "networkd.h"
25
26 #include "utf8.h"
27 #include "util.h"
28 #include "conf-parser.h"
29 #include "net-util.h"
30
31 int address_new(Network *network, unsigned section, Address **ret) {
32         _cleanup_address_free_ Address *address = NULL;
33
34         if (section) {
35                 uint64_t key = section;
36                 address = hashmap_get(network->addresses_by_section, &key);
37                 if (address) {
38                         *ret = address;
39                         address = NULL;
40
41                         return 0;
42                 }
43         }
44
45         address = new0(Address, 1);
46         if (!address)
47                 return -ENOMEM;
48
49         address->network = network;
50
51         LIST_PREPEND(addresses, network->addresses, address);
52
53         if (section) {
54                 address->section = section;
55                 hashmap_put(network->addresses_by_section, &address->section, address);
56         }
57
58         *ret = address;
59         address = NULL;
60
61         return 0;
62 }
63
64 void address_free(Address *address) {
65         if (!address)
66                 return;
67
68         LIST_REMOVE(addresses, address->network->addresses, address);
69
70         if (address->section)
71                 hashmap_remove(address->network->addresses_by_section,
72                                &address->section);
73
74         free(address);
75 }
76
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;
80         int r;
81
82         assert(link->manager);
83
84         r = sd_rtnl_message_addr_new(RTM_NEWADDR, link->ifindex,
85                         address->family, address->prefixlen,
86                         IFA_F_PERMANENT, RT_SCOPE_UNIVERSE, &req);
87         if (r < 0) {
88                 log_error("Could not allocate RTM_NEWADDR message: %s",
89                           strerror(-r));
90                 return r;
91         }
92
93         r = sd_rtnl_message_append(req, IFA_LOCAL, &address->in_addr);
94         if (r < 0) {
95                 log_error("Could not append IFA_LOCAL attribute: %s",
96                           strerror(-r));
97                 return r;
98         }
99
100         if (address->family == AF_INET) {
101                 struct in_addr broadcast;
102
103                 broadcast.s_addr = address->in_addr.in.s_addr | address->netmask.s_addr;
104
105                 r = sd_rtnl_message_append(req, IFA_BROADCAST, &broadcast);
106                 if (r < 0) {
107                         log_error("Could not append IFA_BROADCAST attribute: %s",
108                                   strerror(-r));
109                         return r;
110                 }
111         }
112
113         if (address->label) {
114                 r = sd_rtnl_message_append(req, IFA_LABEL, address->label);
115                 if (r < 0) {
116                         log_error("Could not append IFA_LABEL attribute: %s",
117                                   strerror(-r));
118                         return r;
119                 }
120         }
121
122         r = sd_rtnl_call_async(link->manager->rtnl, req, callback, link, 0, NULL);
123         if (r < 0) {
124                 log_error("Could not send rtnetlink message: %s", strerror(-r));
125                 return r;
126         }
127
128         link->rtnl_messages ++;
129
130         return 0;
131 }
132
133 int config_parse_address(const char *unit,
134                 const char *filename,
135                 unsigned line,
136                 const char *section,
137                 unsigned section_line,
138                 const char *lvalue,
139                 int ltype,
140                 const char *rvalue,
141                 void *data,
142                 void *userdata) {
143         Network *network = userdata;
144         _cleanup_address_free_ Address *n = NULL;
145         _cleanup_free_ char *address = NULL;
146         const char *e;
147         int r;
148
149         assert(filename);
150         assert(section);
151         assert(lvalue);
152         assert(rvalue);
153         assert(data);
154
155         r = address_new(network, section_line, &n);
156         if (r < 0)
157                 return r;
158
159         /* Address=address/prefixlen */
160
161         /* prefixlen */
162         e = strchr(rvalue, '/');
163         if (e) {
164                 unsigned i;
165                 r = safe_atou(e + 1, &i);
166                 if (r < 0) {
167                         log_syntax(unit, LOG_ERR, filename, line, EINVAL,
168                                    "Interface prefix length is invalid, "
169                                    "ignoring assignment: %s", e + 1);
170                         return 0;
171                 }
172
173                 n->prefixlen = (unsigned char) i;
174                 n->netmask.s_addr = htonl(0xfffffffflu >> n->prefixlen);
175
176                 address = strndup(rvalue, e - rvalue);
177                 if (!address)
178                         return log_oom();
179         } else {
180                 address = strdup(rvalue);
181                 if (!address)
182                         return log_oom();
183         }
184
185         r = net_parse_inaddr(address, &n->family, &n->in_addr);
186         if (r < 0) {
187                 log_syntax(unit, LOG_ERR, filename, line, EINVAL,
188                            "Address is invalid, ignoring assignment: %s", address);
189                 return 0;
190         }
191
192         n = NULL;
193
194         return 0;
195 }
196
197 int config_parse_label(const char *unit,
198                 const char *filename,
199                 unsigned line,
200                 const char *section,
201                 unsigned section_line,
202                 const char *lvalue,
203                 int ltype,
204                 const char *rvalue,
205                 void *data,
206                 void *userdata) {
207         Network *network = userdata;
208         _cleanup_address_free_ Address *n = NULL;
209         char *label;
210         int r;
211
212         assert(filename);
213         assert(section);
214         assert(lvalue);
215         assert(rvalue);
216         assert(data);
217
218         r = address_new(network, section_line, &n);
219         if (r < 0)
220                 return r;
221
222         label = strdup(rvalue);
223         if (!label)
224                 return log_oom();
225
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);
230                 free(label);
231                 return 0;
232         }
233
234         free(n->label);
235         if (*label)
236                 n->label = label;
237         else {
238                 free(label);
239                 n->label = NULL;
240         }
241
242         n = NULL;
243
244         return 0;
245 }