]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/network/networkd-manager-varlink.c
network: introduce per-interface IP forwarding settings
[thirdparty/systemd.git] / src / network / networkd-manager-varlink.c
CommitLineData
c5c74d85
LP
1/* SPDX-License-Identifier: LGPL-2.1-or-later */
2
3#include <unistd.h>
4
5#include "networkd-manager-varlink.h"
6#include "varlink.h"
7#include "varlink-io.systemd.Network.h"
8
9static int vl_method_get_states(Varlink *link, JsonVariant *parameters, VarlinkMethodFlags flags, void *userdata) {
10 Manager *m = ASSERT_PTR(userdata);
11
12 assert(link);
13
14 if (json_variant_elements(parameters) > 0)
15 return varlink_error_invalid_parameter(link, parameters);
16
17 return varlink_replyb(link,
18 JSON_BUILD_OBJECT(
19 JSON_BUILD_PAIR_STRING("AddressState", link_address_state_to_string(m->address_state)),
20 JSON_BUILD_PAIR_STRING("IPv4AddressState", link_address_state_to_string(m->ipv4_address_state)),
21 JSON_BUILD_PAIR_STRING("IPv6AddressState", link_address_state_to_string(m->ipv6_address_state)),
22 JSON_BUILD_PAIR_STRING("CarrierState", link_carrier_state_to_string(m->carrier_state)),
23 JSON_BUILD_PAIR_CONDITION(m->online_state >= 0, "OnlineState", JSON_BUILD_STRING(link_online_state_to_string(m->online_state))),
24 JSON_BUILD_PAIR_STRING("OperationalState", link_operstate_to_string(m->operational_state))));
25}
26
27static int vl_method_get_namespace_id(Varlink *link, JsonVariant *parameters, VarlinkMethodFlags flags, void *userdata) {
91b34c76
LP
28 uint64_t inode = 0;
29 uint32_t nsid = UINT32_MAX;
30 int r;
c5c74d85
LP
31
32 assert(link);
33
34 if (json_variant_elements(parameters) > 0)
35 return varlink_error_invalid_parameter(link, parameters);
36
91b34c76
LP
37 /* Network namespaces have two identifiers: the inode number (which all namespace types have), and
38 * the "nsid" (aka the "cookie"), which only network namespaces know as a concept, and which is not
39 * assigned by default, but once it is, is fixed. Let's return both, to avoid any confusion which one
40 * this is. */
41
c5c74d85 42 struct stat st;
91b34c76 43 if (stat("/proc/self/ns/net", &st) < 0)
c5c74d85 44 log_warning_errno(errno, "Failed to stat network namespace, ignoring: %m");
91b34c76
LP
45 else
46 inode = st.st_ino;
47
48 r = netns_get_nsid(/* netnsfd= */ -EBADF, &nsid);
49 if (r < 0)
50 log_warning_errno(r, "Failed to query network nsid, ignoring: %m");
c5c74d85
LP
51
52 return varlink_replyb(link,
53 JSON_BUILD_OBJECT(
91b34c76
LP
54 JSON_BUILD_PAIR_UNSIGNED("NamespaceId", inode),
55 JSON_BUILD_PAIR_CONDITION(nsid == UINT32_MAX, "NamespaceNSID", JSON_BUILD_NULL),
56 JSON_BUILD_PAIR_CONDITION(nsid != UINT32_MAX, "NamespaceNSID", JSON_BUILD_UNSIGNED(nsid))));
c5c74d85
LP
57}
58
59int manager_connect_varlink(Manager *m) {
60 _cleanup_(varlink_server_unrefp) VarlinkServer *s = NULL;
61 int r;
62
63 assert(m);
64
65 if (m->varlink_server)
66 return 0;
67
68 r = varlink_server_new(&s, VARLINK_SERVER_ACCOUNT_UID|VARLINK_SERVER_INHERIT_USERDATA);
69 if (r < 0)
70 return log_error_errno(r, "Failed to allocate varlink server object: %m");
71
72 varlink_server_set_userdata(s, m);
73
74 r = varlink_server_add_interface(s, &vl_interface_io_systemd_Network);
75 if (r < 0)
76 return log_error_errno(r, "Failed to add Network interface to varlink server: %m");
77
78 r = varlink_server_bind_method_many(
79 s,
80 "io.systemd.Network.GetStates", vl_method_get_states,
81 "io.systemd.Network.GetNamespaceId", vl_method_get_namespace_id);
82 if (r < 0)
83 return log_error_errno(r, "Failed to register varlink methods: %m");
84
85 r = varlink_server_listen_address(s, "/run/systemd/netif/io.systemd.Network", 0666);
86 if (r < 0)
87 return log_error_errno(r, "Failed to bind to varlink socket: %m");
88
89 r = varlink_server_attach_event(s, m->event, SD_EVENT_PRIORITY_NORMAL);
90 if (r < 0)
91 return log_error_errno(r, "Failed to attach varlink connection to event loop: %m");
92
93 m->varlink_server = TAKE_PTR(s);
94 return 0;
95}
96
97void manager_varlink_done(Manager *m) {
98 assert(m);
99
100 m->varlink_server = varlink_server_unref(m->varlink_server);
101 (void) unlink("/run/systemd/netif/io.systemd.Network");
102}