2 This file is part of systemd.
4 Copyright 2017 Susant Sahani
6 systemd is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
9 (at your option) any later version.
11 systemd is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public License
17 along with systemd; If not, see <http://www.gnu.org/licenses/>.
21 #include <linux/if_addrlabel.h>
23 #include "alloc-util.h"
24 #include "conf-parser.h"
25 #include "networkd-address-label.h"
26 #include "netlink-util.h"
27 #include "networkd-manager.h"
28 #include "parse-util.h"
29 #include "socket-util.h"
31 int address_label_new(AddressLabel
**ret
) {
32 _cleanup_address_label_free_ AddressLabel
*addrlabel
= NULL
;
34 addrlabel
= new0(AddressLabel
, 1);
44 void address_label_free(AddressLabel
*label
) {
49 LIST_REMOVE(labels
, label
->network
->address_labels
, label
);
50 assert(label
->network
->n_address_labels
> 0);
51 label
->network
->n_address_labels
--;
54 hashmap_remove(label
->network
->address_labels_by_section
, label
->section
);
55 network_config_section_free(label
->section
);
62 static int address_label_new_static(Network
*network
, const char *filename
, unsigned section_line
, AddressLabel
**ret
) {
63 _cleanup_network_config_section_free_ NetworkConfigSection
*n
= NULL
;
64 _cleanup_address_label_free_ AddressLabel
*label
= NULL
;
69 assert(!!filename
== (section_line
> 0));
71 r
= network_config_section_new(filename
, section_line
, &n
);
75 label
= hashmap_get(network
->address_labels_by_section
, n
);
83 r
= address_label_new(&label
);
90 r
= hashmap_put(network
->address_labels_by_section
, label
->section
, label
);
94 label
->network
= network
;
95 LIST_APPEND(labels
, network
->address_labels
, label
);
96 network
->n_address_labels
++;
104 int address_label_configure(
107 sd_netlink_message_handler_t callback
,
110 _cleanup_(sd_netlink_message_unrefp
) sd_netlink_message
*req
= NULL
;
115 assert(link
->ifindex
> 0);
116 assert(link
->manager
);
117 assert(link
->manager
->rtnl
);
119 r
= sd_rtnl_message_new_addrlabel(link
->manager
->rtnl
, &req
, RTM_NEWADDRLABEL
,
120 link
->ifindex
, AF_INET6
);
122 return log_error_errno(r
, "Could not allocate RTM_NEWADDR message: %m");
124 r
= sd_rtnl_message_addrlabel_set_prefixlen(req
, label
->prefixlen
);
126 return log_error_errno(r
, "Could not set prefixlen: %m");
128 r
= sd_netlink_message_append_u32(req
, IFAL_LABEL
, label
->label
);
130 return log_error_errno(r
, "Could not append IFAL_LABEL attribute: %m");
132 r
= sd_netlink_message_append_in6_addr(req
, IFA_ADDRESS
, &label
->in_addr
.in6
);
134 return log_error_errno(r
, "Could not append IFA_ADDRESS attribute: %m");
136 r
= sd_netlink_call_async(link
->manager
->rtnl
, req
, callback
, link
, 0, NULL
);
138 return log_error_errno(r
, "Could not send rtnetlink message: %m");
145 int config_parse_address_label_prefix(const char *unit
,
146 const char *filename
,
149 unsigned section_line
,
156 _cleanup_address_label_free_ AddressLabel
*n
= NULL
;
157 Network
*network
= userdata
;
166 r
= address_label_new_static(network
, filename
, section_line
, &n
);
170 r
= in_addr_prefix_from_string(rvalue
, AF_INET6
, &n
->in_addr
, &n
->prefixlen
);
172 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Address label is invalid, ignoring assignment: %s", rvalue
);
181 int config_parse_address_label(
183 const char *filename
,
186 unsigned section_line
,
193 _cleanup_address_label_free_ AddressLabel
*n
= NULL
;
194 Network
*network
= userdata
;
204 r
= address_label_new_static(network
, filename
, section_line
, &n
);
208 r
= safe_atou32(rvalue
, &k
);
210 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Failed to parse address label, ignoring: %s", rvalue
);
214 if (k
== 0xffffffffUL
) {
215 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Adress label is invalid, ignoring: %s", rvalue
);