1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2 
3 #include "alloc-util.h"
4 #include "ether-addr-util.h"
5 #include "networkd-manager.h"
6 #include "networkd-network-bus.h"
7 #include "string-util.h"
8 #include "strv.h"
9 
property_get_hw_addrs(sd_bus * bus,const char * path,const char * interface,const char * property,sd_bus_message * reply,void * userdata,sd_bus_error * error)10 static int property_get_hw_addrs(
11                 sd_bus *bus,
12                 const char *path,
13                 const char *interface,
14                 const char *property,
15                 sd_bus_message *reply,
16                 void *userdata,
17                 sd_bus_error *error) {
18 
19         const struct hw_addr_data *p;
20         Set *s;
21         int r;
22 
23         assert(bus);
24         assert(reply);
25         assert(userdata);
26 
27         s = *(Set **) userdata;
28 
29         r = sd_bus_message_open_container(reply, 'a', "s");
30         if (r < 0)
31                 return r;
32 
33         SET_FOREACH(p, s) {
34                 r = sd_bus_message_append(reply, "s", HW_ADDR_TO_STR(p));
35                 if (r < 0)
36                         return r;
37         }
38 
39         return sd_bus_message_close_container(reply);
40 }
41 
42 static const sd_bus_vtable network_vtable[] = {
43         SD_BUS_VTABLE_START(0),
44 
45         SD_BUS_PROPERTY("Description", "s", NULL, offsetof(Network, description), SD_BUS_VTABLE_PROPERTY_CONST),
46         SD_BUS_PROPERTY("SourcePath", "s", NULL, offsetof(Network, filename), SD_BUS_VTABLE_PROPERTY_CONST),
47         SD_BUS_PROPERTY("MatchMAC", "as", property_get_hw_addrs, offsetof(Network, match.hw_addr), SD_BUS_VTABLE_PROPERTY_CONST),
48         SD_BUS_PROPERTY("MatchPath", "as", NULL, offsetof(Network, match.path), SD_BUS_VTABLE_PROPERTY_CONST),
49         SD_BUS_PROPERTY("MatchDriver", "as", NULL, offsetof(Network, match.driver), SD_BUS_VTABLE_PROPERTY_CONST),
50         SD_BUS_PROPERTY("MatchType", "as", NULL, offsetof(Network, match.iftype), SD_BUS_VTABLE_PROPERTY_CONST),
51         SD_BUS_PROPERTY("MatchName", "as", NULL, offsetof(Network, match.ifname), SD_BUS_VTABLE_PROPERTY_CONST),
52 
53         SD_BUS_VTABLE_END
54 };
55 
network_bus_path(Network * network)56 static char *network_bus_path(Network *network) {
57         _cleanup_free_ char *name = NULL;
58         char *networkname, *d, *path;
59         int r;
60 
61         assert(network);
62         assert(network->filename);
63 
64         name = strdup(network->filename);
65         if (!name)
66                 return NULL;
67 
68         networkname = basename(name);
69 
70         d = strrchr(networkname, '.');
71         if (!d)
72                 return NULL;
73 
74         assert(streq(d, ".network"));
75 
76         *d = '\0';
77 
78         r = sd_bus_path_encode("/org/freedesktop/network1/network", networkname, &path);
79         if (r < 0)
80                 return NULL;
81 
82         return path;
83 }
84 
network_node_enumerator(sd_bus * bus,const char * path,void * userdata,char *** nodes,sd_bus_error * error)85 int network_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
86         _cleanup_strv_free_ char **l = NULL;
87         Manager *m = userdata;
88         Network *network;
89         int r;
90 
91         assert(bus);
92         assert(path);
93         assert(m);
94         assert(nodes);
95 
96         ORDERED_HASHMAP_FOREACH(network, m->networks) {
97                 char *p;
98 
99                 p = network_bus_path(network);
100                 if (!p)
101                         return -ENOMEM;
102 
103                 r = strv_consume(&l, p);
104                 if (r < 0)
105                         return r;
106         }
107 
108         *nodes = TAKE_PTR(l);
109 
110         return 1;
111 }
112 
network_object_find(sd_bus * bus,const char * path,const char * interface,void * userdata,void ** found,sd_bus_error * error)113 int network_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
114         Manager *m = userdata;
115         Network *network;
116         _cleanup_free_ char *name = NULL;
117         int r;
118 
119         assert(bus);
120         assert(path);
121         assert(interface);
122         assert(m);
123         assert(found);
124 
125         r = sd_bus_path_decode(path, "/org/freedesktop/network1/network", &name);
126         if (r < 0)
127                 return 0;
128 
129         r = network_get_by_name(m, name, &network);
130         if (r < 0)
131                 return 0;
132 
133         *found = network;
134 
135         return 1;
136 }
137 
138 const BusObjectImplementation network_object = {
139         "/org/freedesktop/network1/network",
140         "org.freedesktop.network1.Network",
141         .fallback_vtables = BUS_FALLBACK_VTABLES({network_vtable, network_object_find}),
142         .node_enumerator = network_node_enumerator,
143 };
144