2 This file is part of systemd.
4 Copyright 2015 Tom Gundersen
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/>.
20 #include "alloc-util.h"
22 #include "networkd-link.h"
24 #include "parse-util.h"
26 #include "dhcp-lease-internal.h"
28 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_operational_state
, link_operstate
, LinkOperationalState
);
29 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_administrative_state
, link_state
, LinkState
);
31 const sd_bus_vtable link_vtable
[] = {
32 SD_BUS_VTABLE_START(0),
34 SD_BUS_PROPERTY("OperationalState", "s", property_get_operational_state
, offsetof(Link
, operstate
), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE
),
35 SD_BUS_PROPERTY("AdministrativeState", "s", property_get_administrative_state
, offsetof(Link
, state
), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE
),
40 static int get_private_options(sd_bus
*bus
,
42 const char *interface
,
44 sd_bus_message
*reply
,
46 sd_bus_error
*error
) {
47 sd_dhcp_lease
*lease
= userdata
;
48 struct sd_dhcp_raw_option
*option
= NULL
;
55 r
= sd_bus_message_open_container(reply
, SD_BUS_TYPE_ARRAY
, "{yay}");
59 LIST_FOREACH(options
, option
, lease
->private_options
) {
60 r
= sd_bus_message_open_container(reply
, SD_BUS_TYPE_DICT_ENTRY
, "yay");
63 r
= sd_bus_message_append(reply
, "y", option
->tag
);
66 r
= sd_bus_message_append_array(reply
, 'y', option
->data
, option
->length
);
69 r
= sd_bus_message_close_container(reply
);
73 return sd_bus_message_close_container(reply
);
76 const sd_bus_vtable lease_vtable
[] = {
77 SD_BUS_VTABLE_START(0),
79 SD_BUS_PROPERTY("PrivateOptions", "a{yay}", get_private_options
, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE
),
84 static char *link_bus_path(Link
*link
) {
85 _cleanup_free_
char *ifindex
= NULL
;
90 assert(link
->ifindex
> 0);
92 if (asprintf(&ifindex
, "%d", link
->ifindex
) < 0)
95 r
= sd_bus_path_encode("/org/freedesktop/network1/link", ifindex
, &p
);
102 static char *lease_bus_path(Link
*link
) {
103 _cleanup_free_
char *p
= NULL
;
109 p
= link_bus_path(link
);
113 r
= sd_bus_path_encode(p
, "lease", &ret
);
120 int link_node_enumerator(sd_bus
*bus
, const char *path
, void *userdata
, char ***nodes
, sd_bus_error
*error
) {
121 _cleanup_strv_free_
char **l
= NULL
;
122 Manager
*m
= userdata
;
132 l
= new0(char*, hashmap_size(m
->links
) + 1);
136 HASHMAP_FOREACH(link
, m
->links
, i
) {
139 p
= link_bus_path(link
);
153 int lease_node_enumerator(sd_bus
*bus
, const char *path
, void *userdata
, char ***nodes
, sd_bus_error
*error
) {
154 _cleanup_strv_free_
char **l
= NULL
;
155 Manager
*m
= userdata
;
165 l
= new0(char*, hashmap_size(m
->links
) + 1);
169 HASHMAP_FOREACH(link
, m
->links
, i
) {
172 if (!link
->dhcp_lease
)
175 p
= lease_bus_path(link
);
189 int link_object_find(sd_bus
*bus
, const char *path
, const char *interface
, void *userdata
, void **found
, sd_bus_error
*error
) {
190 _cleanup_free_
char *identifier
= NULL
;
191 Manager
*m
= userdata
;
201 r
= sd_bus_path_decode(path
, "/org/freedesktop/network1/link", &identifier
);
205 r
= parse_ifindex(identifier
, &ifindex
);
209 r
= link_get(m
, ifindex
, &link
);
218 int lease_object_find(sd_bus
*bus
, const char *path
, const char *interface
, void *userdata
, void **found
, sd_bus_error
*error
) {
219 _cleanup_free_
char *identifier
= NULL
;
220 Manager
*m
= userdata
;
230 r
= sd_bus_path_decode_many(path
, "/org/freedesktop/network1/link/%/lease", &identifier
);
234 r
= parse_ifindex(identifier
, &ifindex
);
238 r
= link_get(m
, ifindex
, &link
);
242 if (!link
->dhcp_lease
)
245 *found
= link
->dhcp_lease
;
250 int link_send_changed(Link
*link
, const char *property
, ...) {
251 _cleanup_free_
char *p
= NULL
;
255 assert(link
->manager
);
257 if (!link
->manager
->bus
)
258 return 0; /* replace with assert when we have kdbus */
260 l
= strv_from_stdarg_alloca(property
);
262 p
= link_bus_path(link
);
266 return sd_bus_emit_properties_changed_strv(
269 "org.freedesktop.network1.Link",