chiark / gitweb /
networkd: bus - expose MatchMAC
[elogind.git] / src / network / networkd-network-bus.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4   This file is part of systemd.
5
6   Copyright 2015 Tom Gundersen
7
8   systemd is free software; you can redistribute it and/or modify it
9   under the terms of the GNU Lesser General Public License as published by
10   the Free Software Foundation; either version 2.1 of the License, or
11   (at your option) any later version.
12
13   systemd is distributed in the hope that it will be useful, but
14   WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16   Lesser General Public License for more details.
17
18   You should have received a copy of the GNU Lesser General Public License
19   along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include "bus-util.h"
23 #include "bus-label.h"
24 #include "strv.h"
25
26 #include "networkd.h"
27
28 static int property_get_ether_addrs(
29                 sd_bus *bus,
30                 const char *path,
31                 const char *interface,
32                 const char *property,
33                 sd_bus_message *reply,
34                 void *userdata,
35                 sd_bus_error *error) {
36
37         Network *n = userdata;
38         const char *ether = NULL;
39         int r;
40
41         assert(bus);
42         assert(reply);
43         assert(n);
44
45         if (n->match_mac)
46                 ether = ether_ntoa(n->match_mac);
47
48         r = sd_bus_message_open_container(reply, 'a', "s");
49         if (r < 0)
50                 return r;
51
52         if (ether) {
53                 r = sd_bus_message_append(reply, "s", strempty(ether));
54                 if (r < 0)
55                         return r;
56         }
57
58         r = sd_bus_message_close_container(reply);
59         if (r < 0)
60                 return r;
61
62         return 1;
63 }
64
65 const sd_bus_vtable network_vtable[] = {
66         SD_BUS_VTABLE_START(0),
67
68         SD_BUS_PROPERTY("Description", "s", NULL, offsetof(Network, description), SD_BUS_VTABLE_PROPERTY_CONST),
69         SD_BUS_PROPERTY("SourcePath", "s", NULL, offsetof(Network, filename), SD_BUS_VTABLE_PROPERTY_CONST),
70         SD_BUS_PROPERTY("MatchMAC", "as", property_get_ether_addrs, offsetof(Network, match_mac), SD_BUS_VTABLE_PROPERTY_CONST),
71         SD_BUS_PROPERTY("MatchPath", "s", NULL, offsetof(Network, match_path), SD_BUS_VTABLE_PROPERTY_CONST),
72         SD_BUS_PROPERTY("MatchDriver", "s", NULL, offsetof(Network, match_driver), SD_BUS_VTABLE_PROPERTY_CONST),
73         SD_BUS_PROPERTY("MatchType", "s", NULL, offsetof(Network, match_type), SD_BUS_VTABLE_PROPERTY_CONST),
74         SD_BUS_PROPERTY("MatchName", "s", NULL, offsetof(Network, match_name), SD_BUS_VTABLE_PROPERTY_CONST),
75
76         SD_BUS_VTABLE_END
77 };
78
79 static char *network_bus_path(Network *network) {
80         _cleanup_free_ char *name = NULL;
81         char *networkname, *d, *path;
82         int r;
83
84         assert(network);
85         assert(network->filename);
86
87         name = strdup(network->filename);
88         if (!name)
89                 return NULL;
90
91         networkname = basename(name);
92
93         d = strrchr(networkname, '.');
94         if (!d)
95                 return NULL;
96
97         assert(streq(d, ".network"));
98
99         *d = '\0';
100
101         r = sd_bus_path_encode("/org/freedesktop/network1/network", networkname, &path);
102         if (r < 0)
103                 return NULL;
104
105         return path;
106 }
107
108 int network_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
109         _cleanup_strv_free_ char **l = NULL;
110         Manager *m = userdata;
111         Network *network;
112         int r;
113
114         assert(bus);
115         assert(path);
116         assert(m);
117         assert(nodes);
118
119         LIST_FOREACH(networks, network, m->networks) {
120                 char *p;
121
122                 p = network_bus_path(network);
123                 if (!p)
124                         return -ENOMEM;
125
126                 r = strv_consume(&l, p);
127                 if (r < 0)
128                         return r;
129         }
130
131         *nodes = l;
132         l = NULL;
133
134         return 1;
135 }
136
137 int network_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
138         Manager *m = userdata;
139         Network *network;
140         _cleanup_free_ char *name = NULL;
141         int r;
142
143         assert(bus);
144         assert(path);
145         assert(interface);
146         assert(m);
147         assert(found);
148
149         r = sd_bus_path_decode(path, "/org/freedesktop/network1/network", &name);
150         if (r < 0)
151                 return 0;
152
153         r = network_get_by_name(m, name, &network);
154         if (r < 0)
155                 return 0;
156
157         *found = network;
158
159         return 1;
160 }