Tomáš Pecka | ae30176 | 2021-10-13 10:50:37 +0200 | [diff] [blame] | 1 | From 3ee0693ac819543610120542f8e60fb95fe6f0d4 Mon Sep 17 00:00:00 2001 |
| 2 | From: Tomas Pecka <peckato1@users.noreply.github.com> |
| 3 | Date: Wed, 1 Sep 2021 08:30:20 +0200 |
| 4 | Subject: [PATCH 3/9] network: Add LLDP neighbors method to varlink server |
| 5 | |
| 6 | Add a method to varlink server that will allow streaming the list of |
| 7 | LLDP neighbors on a particular link. The method's argument is the ifindex |
| 8 | of a link. The method then streams the JSONs representing individual |
| 9 | neighbors as discovered by the LLDP protocol. |
| 10 | --- |
| 11 | src/network/networkd-varlink.c | 77 ++++++++++++++++++++++++++++++++++ |
| 12 | 1 file changed, 77 insertions(+) |
| 13 | |
| 14 | diff --git a/src/network/networkd-varlink.c b/src/network/networkd-varlink.c |
| 15 | index 57d8acb967..f86be4e903 100644 |
| 16 | --- 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 | + |
| 66 | + r = sd_lldp_get_neighbors_json(l->lldp, &neighbors); |
| 67 | + 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 | -- |
| 117 | 2.33.0 |
| 118 | |