]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/network/networkd-address-label.c
Correct a number of trivial typos.
[thirdparty/systemd.git] / src / network / networkd-address-label.c
CommitLineData
53e1b683 1/* SPDX-License-Identifier: LGPL-2.1+ */
95b74ef6 2/***
96b2fb93 3 Copyright © 2017 Susant Sahani
95b74ef6
SS
4***/
5
6#include <net/if.h>
7#include <linux/if_addrlabel.h>
8
9#include "alloc-util.h"
10#include "conf-parser.h"
11#include "networkd-address-label.h"
12#include "netlink-util.h"
13#include "networkd-manager.h"
14#include "parse-util.h"
15#include "socket-util.h"
16
17int address_label_new(AddressLabel **ret) {
8e766630 18 _cleanup_(address_label_freep) AddressLabel *addrlabel = NULL;
95b74ef6
SS
19
20 addrlabel = new0(AddressLabel, 1);
21 if (!addrlabel)
22 return -ENOMEM;
23
1cc6c93a 24 *ret = TAKE_PTR(addrlabel);
95b74ef6
SS
25
26 return 0;
27}
28
29void address_label_free(AddressLabel *label) {
30 if (!label)
31 return;
32
33 if (label->network) {
34 LIST_REMOVE(labels, label->network->address_labels, label);
35 assert(label->network->n_address_labels > 0);
36 label->network->n_address_labels--;
37
38 if (label->section) {
39 hashmap_remove(label->network->address_labels_by_section, label->section);
40 network_config_section_free(label->section);
41 }
42 }
43
44 free(label);
45}
46
47static int address_label_new_static(Network *network, const char *filename, unsigned section_line, AddressLabel **ret) {
8e766630
LP
48 _cleanup_(network_config_section_freep) NetworkConfigSection *n = NULL;
49 _cleanup_(address_label_freep) AddressLabel *label = NULL;
95b74ef6
SS
50 int r;
51
52 assert(network);
53 assert(ret);
54 assert(!!filename == (section_line > 0));
55
56 r = network_config_section_new(filename, section_line, &n);
57 if (r < 0)
58 return r;
59
60 label = hashmap_get(network->address_labels_by_section, n);
61 if (label) {
1cc6c93a 62 *ret = TAKE_PTR(label);
95b74ef6
SS
63
64 return 0;
65 }
66
67 r = address_label_new(&label);
68 if (r < 0)
69 return r;
70
1cc6c93a 71 label->section = TAKE_PTR(n);
95b74ef6
SS
72
73 r = hashmap_put(network->address_labels_by_section, label->section, label);
74 if (r < 0)
75 return r;
76
77 label->network = network;
78 LIST_APPEND(labels, network->address_labels, label);
79 network->n_address_labels++;
80
1cc6c93a 81 *ret = TAKE_PTR(label);
95b74ef6
SS
82
83 return 0;
84}
85
86int address_label_configure(
87 AddressLabel *label,
88 Link *link,
89 sd_netlink_message_handler_t callback,
90 bool update) {
91
92 _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
93 int r;
94
95 assert(label);
96 assert(link);
97 assert(link->ifindex > 0);
98 assert(link->manager);
99 assert(link->manager->rtnl);
100
101 r = sd_rtnl_message_new_addrlabel(link->manager->rtnl, &req, RTM_NEWADDRLABEL,
f7bf1abe 102 link->ifindex, AF_INET6);
95b74ef6
SS
103 if (r < 0)
104 return log_error_errno(r, "Could not allocate RTM_NEWADDR message: %m");
105
106 r = sd_rtnl_message_addrlabel_set_prefixlen(req, label->prefixlen);
107 if (r < 0)
108 return log_error_errno(r, "Could not set prefixlen: %m");
109
110 r = sd_netlink_message_append_u32(req, IFAL_LABEL, label->label);
111 if (r < 0)
112 return log_error_errno(r, "Could not append IFAL_LABEL attribute: %m");
113
114 r = sd_netlink_message_append_in6_addr(req, IFA_ADDRESS, &label->in_addr.in6);
115 if (r < 0)
116 return log_error_errno(r, "Could not append IFA_ADDRESS attribute: %m");
117
118 r = sd_netlink_call_async(link->manager->rtnl, req, callback, link, 0, NULL);
119 if (r < 0)
120 return log_error_errno(r, "Could not send rtnetlink message: %m");
121
122 link_ref(link);
123
124 return 0;
125}
126
127int config_parse_address_label_prefix(const char *unit,
128 const char *filename,
129 unsigned line,
130 const char *section,
131 unsigned section_line,
132 const char *lvalue,
133 int ltype,
134 const char *rvalue,
135 void *data,
136 void *userdata) {
137
8e766630 138 _cleanup_(address_label_freep) AddressLabel *n = NULL;
95b74ef6 139 Network *network = userdata;
f7bf1abe 140 int r;
95b74ef6
SS
141
142 assert(filename);
143 assert(section);
144 assert(lvalue);
145 assert(rvalue);
146 assert(data);
147
148 r = address_label_new_static(network, filename, section_line, &n);
149 if (r < 0)
150 return r;
151
f7bf1abe 152 r = in_addr_prefix_from_string(rvalue, AF_INET6, &n->in_addr, &n->prefixlen);
95b74ef6 153 if (r < 0) {
f7bf1abe 154 log_syntax(unit, LOG_ERR, filename, line, r, "Address label is invalid, ignoring assignment: %s", rvalue);
95b74ef6
SS
155 return 0;
156 }
157
95b74ef6
SS
158 n = NULL;
159
160 return 0;
161}
162
163int config_parse_address_label(
164 const char *unit,
165 const char *filename,
166 unsigned line,
167 const char *section,
168 unsigned section_line,
169 const char *lvalue,
170 int ltype,
171 const char *rvalue,
172 void *data,
173 void *userdata) {
174
8e766630 175 _cleanup_(address_label_freep) AddressLabel *n = NULL;
95b74ef6
SS
176 Network *network = userdata;
177 uint32_t k;
178 int r;
179
180 assert(filename);
181 assert(section);
182 assert(lvalue);
183 assert(rvalue);
184 assert(data);
185
186 r = address_label_new_static(network, filename, section_line, &n);
187 if (r < 0)
188 return r;
189
190 r = safe_atou32(rvalue, &k);
191 if (r < 0) {
192 log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse address label, ignoring: %s", rvalue);
193 return 0;
194 }
195
196 if (k == 0xffffffffUL) {
3fe91079 197 log_syntax(unit, LOG_ERR, filename, line, r, "Address label is invalid, ignoring: %s", rvalue);
95b74ef6
SS
198 return 0;
199 }
200
201 n->label = k;
202 n = NULL;
203
204 return 0;
205}