blob: 95bb683c4b5a5d02d94c8769903fcd7142cc449b [file] [log] [blame]
Tomáš Pecka5e070252022-05-20 20:41:21 +02001From 2196678308d40ac4bb236776f5d9c23b87480759 Mon Sep 17 00:00:00 2001
Tomáš Peckaae301762021-10-13 10:50:37 +02002From: Tomas Pecka <peckato1@users.noreply.github.com>
3Date: Wed, 1 Sep 2021 08:30:20 +0200
4Subject: [PATCH 3/9] network: Add LLDP neighbors method to varlink server
5
6Add a method to varlink server that will allow streaming the list of
7LLDP neighbors on a particular link. The method's argument is the ifindex
8of a link. The method then streams the JSONs representing individual
9neighbors as discovered by the LLDP protocol.
10---
11 src/network/networkd-varlink.c | 77 ++++++++++++++++++++++++++++++++++
12 1 file changed, 77 insertions(+)
13
14diff --git a/src/network/networkd-varlink.c b/src/network/networkd-varlink.c
Václav Kubernát8cd61562021-12-08 13:27:31 +010015index 57d8acb967..5bc65c39b7 100644
Tomáš Peckaae301762021-10-13 10:50:37 +020016--- a/src/network/networkd-varlink.c
17+++ b/src/network/networkd-varlink.c
18@@ -1,6 +1,76 @@
19 /* SPDX-License-Identifier: LGPL-2.1-or-later */
20
21+#include "alloc-util.h"
22+#include "fd-util.h"
23+#include "json.h"
24 #include "networkd-varlink.h"
25+#include "sd-lldp.h"
26+#include "varlink.h"
27+
28+typedef struct LookupParameters {
29+ int ifindex;
30+} LookupParameters;
31+
32+static int vl_method_network_lldp_neighbors(Varlink *link, JsonVariant *parameters, VarlinkMethodFlags flags, void *userdata) {
33+ static const JsonDispatch dispatch_table[] = {
34+ { "ifindex", JSON_VARIANT_INTEGER, json_dispatch_int, offsetof(LookupParameters, ifindex), JSON_MANDATORY },
35+ {}
36+ };
37+
38+ int r, i, n;
39+ Manager *m;
40+ Link *l;
41+ LookupParameters p;
42+ JsonVariant **neighbors;
43+
44+ assert(link);
45+
46+ m = varlink_server_get_userdata(varlink_get_server(link));
47+ assert(m);
48+
49+ if (FLAGS_SET(flags, VARLINK_METHOD_ONEWAY))
50+ return -EINVAL;
51+
52+ if (!FLAGS_SET(flags, VARLINK_METHOD_MORE))
53+ return -EINVAL;
54+
55+ r = json_dispatch(parameters, dispatch_table, NULL, 0, &p);
56+ if (r < 0)
57+ return r;
58+
59+ if (p.ifindex <= 0)
60+ return varlink_error_invalid_parameter(link, JSON_VARIANT_STRING_CONST("ifindex"));
61+
62+ r = link_get_by_index(m, p.ifindex, &l);
63+ if (r < 0)
64+ return varlink_error_invalid_parameter(link, JSON_VARIANT_STRING_CONST("ifindex"));
65+
Václav Kubernát8cd61562021-12-08 13:27:31 +010066+ r = sd_lldp_rx_get_neighbors_json(l->lldp_rx, &neighbors);
Tomáš Peckaae301762021-10-13 10:50:37 +020067+ if (r < 0)
68+ return r;
69+ if (r == 0)
70+ return varlink_error(link, "io.systemd.Network.NoNeighborFound", NULL);
71+
72+ n = r;
73+ for (i = 0; i < n - 1; i++) {
74+ r = varlink_notify(link, neighbors[i]);
75+ if (r < 0)
76+ goto clear;
77+ }
78+
79+ r = varlink_reply(link, neighbors[i]);
80+ if (r < 0)
81+ goto clear;
82+
83+ r = 0;
84+
85+clear:
86+ for (i = 0; i < n; i++)
87+ json_variant_unref(neighbors[i]);
88+ free(neighbors);
89+
90+ return r;
91+}
92
93 int manager_varlink_init(Manager *m) {
94 _cleanup_(varlink_server_unrefp) VarlinkServer *s = NULL;
95@@ -15,6 +85,10 @@ int manager_varlink_init(Manager *m) {
96 if (r < 0)
97 return log_error_errno(r, "Failed to allocate varlink server object: %m");
98
99+ r = varlink_server_bind_method(s, "io.systemd.Network.LLDPNeighbors", vl_method_network_lldp_neighbors);
100+ if (r < 0)
101+ return log_error_errno(r, "Failed to register varlink method: %m");
102+
103 r = varlink_server_listen_address(s, "/run/systemd/netif/io.systemd.Network", 0666);
104 if (r < 0)
105 return log_error_errno(r, "Failed to bind to varlink socket: %m");
106@@ -24,6 +98,9 @@ int manager_varlink_init(Manager *m) {
107 return log_error_errno(r, "Failed to attach varlink connection to event loop: %m");
108
109 m->varlink_server = TAKE_PTR(s);
110+
111+ varlink_server_set_userdata(m->varlink_server, m);
112+
113 return 0;
114 }
115
116--
Tomáš Pecka5e070252022-05-20 20:41:21 +02001172.35.1
Tomáš Peckaae301762021-10-13 10:50:37 +0200118