]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/network/networkd-network-bus.c
network: make MACAddress= takes hardware address with its length is INFINIBAND_ALEN
[thirdparty/systemd.git] / src / network / networkd-network-bus.c
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
10 static int property_get_ether_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 ether_addr *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", ETHER_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_ether_addrs, offsetof(Network, match.mac), 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
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
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
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 };