blob: 95bb683c4b5a5d02d94c8769903fcd7142cc449b [file] [log] [blame]
From 2196678308d40ac4bb236776f5d9c23b87480759 Mon Sep 17 00:00:00 2001
From: Tomas Pecka <peckato1@users.noreply.github.com>
Date: Wed, 1 Sep 2021 08:30:20 +0200
Subject: [PATCH 3/9] network: Add LLDP neighbors method to varlink server
Add a method to varlink server that will allow streaming the list of
LLDP neighbors on a particular link. The method's argument is the ifindex
of a link. The method then streams the JSONs representing individual
neighbors as discovered by the LLDP protocol.
---
src/network/networkd-varlink.c | 77 ++++++++++++++++++++++++++++++++++
1 file changed, 77 insertions(+)
diff --git a/src/network/networkd-varlink.c b/src/network/networkd-varlink.c
index 57d8acb967..5bc65c39b7 100644
--- a/src/network/networkd-varlink.c
+++ b/src/network/networkd-varlink.c
@@ -1,6 +1,76 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
+#include "alloc-util.h"
+#include "fd-util.h"
+#include "json.h"
#include "networkd-varlink.h"
+#include "sd-lldp.h"
+#include "varlink.h"
+
+typedef struct LookupParameters {
+ int ifindex;
+} LookupParameters;
+
+static int vl_method_network_lldp_neighbors(Varlink *link, JsonVariant *parameters, VarlinkMethodFlags flags, void *userdata) {
+ static const JsonDispatch dispatch_table[] = {
+ { "ifindex", JSON_VARIANT_INTEGER, json_dispatch_int, offsetof(LookupParameters, ifindex), JSON_MANDATORY },
+ {}
+ };
+
+ int r, i, n;
+ Manager *m;
+ Link *l;
+ LookupParameters p;
+ JsonVariant **neighbors;
+
+ assert(link);
+
+ m = varlink_server_get_userdata(varlink_get_server(link));
+ assert(m);
+
+ if (FLAGS_SET(flags, VARLINK_METHOD_ONEWAY))
+ return -EINVAL;
+
+ if (!FLAGS_SET(flags, VARLINK_METHOD_MORE))
+ return -EINVAL;
+
+ r = json_dispatch(parameters, dispatch_table, NULL, 0, &p);
+ if (r < 0)
+ return r;
+
+ if (p.ifindex <= 0)
+ return varlink_error_invalid_parameter(link, JSON_VARIANT_STRING_CONST("ifindex"));
+
+ r = link_get_by_index(m, p.ifindex, &l);
+ if (r < 0)
+ return varlink_error_invalid_parameter(link, JSON_VARIANT_STRING_CONST("ifindex"));
+
+ r = sd_lldp_rx_get_neighbors_json(l->lldp_rx, &neighbors);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ return varlink_error(link, "io.systemd.Network.NoNeighborFound", NULL);
+
+ n = r;
+ for (i = 0; i < n - 1; i++) {
+ r = varlink_notify(link, neighbors[i]);
+ if (r < 0)
+ goto clear;
+ }
+
+ r = varlink_reply(link, neighbors[i]);
+ if (r < 0)
+ goto clear;
+
+ r = 0;
+
+clear:
+ for (i = 0; i < n; i++)
+ json_variant_unref(neighbors[i]);
+ free(neighbors);
+
+ return r;
+}
int manager_varlink_init(Manager *m) {
_cleanup_(varlink_server_unrefp) VarlinkServer *s = NULL;
@@ -15,6 +85,10 @@ int manager_varlink_init(Manager *m) {
if (r < 0)
return log_error_errno(r, "Failed to allocate varlink server object: %m");
+ r = varlink_server_bind_method(s, "io.systemd.Network.LLDPNeighbors", vl_method_network_lldp_neighbors);
+ if (r < 0)
+ return log_error_errno(r, "Failed to register varlink method: %m");
+
r = varlink_server_listen_address(s, "/run/systemd/netif/io.systemd.Network", 0666);
if (r < 0)
return log_error_errno(r, "Failed to bind to varlink socket: %m");
@@ -24,6 +98,9 @@ int manager_varlink_init(Manager *m) {
return log_error_errno(r, "Failed to attach varlink connection to event loop: %m");
m->varlink_server = TAKE_PTR(s);
+
+ varlink_server_set_userdata(m->varlink_server, m);
+
return 0;
}
--
2.35.1