summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.am2
-rw-r--r--src/libsystemd-network/lldp-port.c116
-rw-r--r--src/libsystemd-network/lldp-port.h69
-rw-r--r--src/libsystemd-network/sd-lldp.c100
-rw-r--r--src/libsystemd-network/test-lldp.c2
-rw-r--r--src/network/networkd-link.c5
-rw-r--r--src/systemd/sd-lldp.h4
7 files changed, 58 insertions, 240 deletions
diff --git a/Makefile.am b/Makefile.am
index 03341fcd28..06ca3532b4 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -3303,8 +3303,6 @@ libsystemd_network_la_SOURCES = \
src/libsystemd-network/lldp-tlv.c \
src/libsystemd-network/lldp-network.h \
src/libsystemd-network/lldp-network.c \
- src/libsystemd-network/lldp-port.h \
- src/libsystemd-network/lldp-port.c \
src/libsystemd-network/lldp-internal.h \
src/libsystemd-network/lldp-internal.c \
src/libsystemd-network/sd-lldp.c
diff --git a/src/libsystemd-network/lldp-port.c b/src/libsystemd-network/lldp-port.c
deleted file mode 100644
index c86f62a6c2..0000000000
--- a/src/libsystemd-network/lldp-port.c
+++ /dev/null
@@ -1,116 +0,0 @@
-/***
- This file is part of systemd.
-
- Copyright (C) 2014 Tom Gundersen
- Copyright (C) 2014 Susant Sahani
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include "alloc-util.h"
-#include "async.h"
-#include "lldp-internal.h"
-#include "lldp-network.h"
-#include "lldp-port.h"
-
-int lldp_port_start(lldp_port *p) {
- int r;
-
- assert_return(p, -EINVAL);
-
- r = lldp_network_bind_raw_socket(p->ifindex);
- if (r < 0)
- return r;
-
- p->rawfd = r;
-
- r = sd_event_add_io(p->event, &p->lldp_port_rx,
- p->rawfd, EPOLLIN, lldp_receive_packet, p);
- if (r < 0) {
- log_debug_errno(r, "Failed to allocate event source: %m");
- goto fail;
- }
-
- r = sd_event_source_set_priority(p->lldp_port_rx, p->event_priority);
- if (r < 0) {
- log_debug_errno(r, "Failed to set event priority: %m");
- goto fail;
- }
-
- r = sd_event_source_set_description(p->lldp_port_rx, "lldp-port-rx");
- if (r < 0) {
- log_debug_errno(r, "Failed to set event name: %m");
- goto fail;
- }
-
- return 0;
-
-fail:
- lldp_port_stop(p);
-
- return r;
-}
-
-int lldp_port_stop(lldp_port *p) {
-
- assert_return(p, -EINVAL);
-
- p->rawfd = asynchronous_close(p->rawfd);
- p->lldp_port_rx = sd_event_source_unref(p->lldp_port_rx);
-
- return 0;
-}
-
-void lldp_port_free(lldp_port *p) {
- if (!p)
- return;
-
- lldp_port_stop(p);
-
- free(p->ifname);
- free(p);
-}
-
-int lldp_port_new(int ifindex,
- const char *ifname,
- const struct ether_addr *addr,
- void *userdata,
- lldp_port **ret) {
- _cleanup_free_ lldp_port *p = NULL;
-
- assert_return(ifindex, -EINVAL);
- assert_return(ifname, -EINVAL);
- assert_return(addr, -EINVAL);
-
- p = new0(lldp_port, 1);
- if (!p)
- return -ENOMEM;
-
- p->rawfd = -1;
- p->ifindex = ifindex;
-
- p->ifname = strdup(ifname);
- if (!p->ifname)
- return -ENOMEM;
-
- memcpy(&p->mac, addr, ETH_ALEN);
-
- p->userdata = userdata;
-
- *ret = p;
-
- p = NULL;
-
- return 0;
-}
diff --git a/src/libsystemd-network/lldp-port.h b/src/libsystemd-network/lldp-port.h
deleted file mode 100644
index 96092f8df9..0000000000
--- a/src/libsystemd-network/lldp-port.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/***
- This file is part of systemd.
-
- Copyright (C) 2014 Tom Gundersen
- Copyright (C) 2014 Susant Sahani
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#pragma once
-
-#include <net/ethernet.h>
-
-#include "sd-event.h"
-#include "sd-lldp.h"
-
-#include "util.h"
-
-typedef struct lldp_port lldp_port;
-
-typedef enum LLDPPortStatus {
- LLDP_PORT_STATUS_NONE,
- LLDP_PORT_STATUS_ENABLED,
- LLDP_PORT_STATUS_DISABLED,
- _LLDP_PORT_STATUS_MAX,
- _LLDP_PORT_STATUS_INVALID = -1,
-} LLDPPortStatus;
-
-struct lldp_port {
- LLDPPortStatus status;
-
- int ifindex;
- char *ifname;
-
- struct ether_addr mac;
-
- int rawfd;
-
- sd_event *event;
- sd_event_source *lldp_port_rx;
-
- int event_priority;
-
- void *userdata;
-};
-
-int lldp_port_new(int ifindex,
- const char *ifname,
- const struct ether_addr *addr,
- void *userdata,
- lldp_port **ret);
-void lldp_port_free(lldp_port *p);
-
-DEFINE_TRIVIAL_CLEANUP_FUNC(lldp_port*, lldp_port_free);
-#define _cleanup_lldp_port_free_ _cleanup_(lldp_port_freep)
-
-int lldp_port_start(lldp_port *p);
-int lldp_port_stop(lldp_port *p);
diff --git a/src/libsystemd-network/sd-lldp.c b/src/libsystemd-network/sd-lldp.c
index 2663e235f3..34117cc205 100644
--- a/src/libsystemd-network/sd-lldp.c
+++ b/src/libsystemd-network/sd-lldp.c
@@ -27,20 +27,24 @@
#include "fileio.h"
#include "hashmap.h"
#include "lldp-internal.h"
-#include "lldp-port.h"
+#include "lldp-network.h"
#include "lldp-tlv.h"
#include "prioq.h"
#include "siphash24.h"
#include "string-util.h"
struct sd_lldp {
- lldp_port *port;
+ int ifindex;
+ int fd;
+
+ sd_event *event;
+ int64_t event_priority;
+ sd_event_source *event_source;
Prioq *by_expiry;
Hashmap *neighbour_mib;
sd_lldp_callback_t callback;
-
void *userdata;
};
@@ -112,7 +116,6 @@ int lldp_handle_packet(tlv_packet *tlv, uint16_t length) {
bool system_description = false, system_name = false, chassis_id = false;
bool port_id = false, ttl = false, end = false;
uint16_t type, len, i, l, t;
- lldp_port *port;
uint8_t *p, *q;
sd_lldp *lldp;
int r;
@@ -120,13 +123,7 @@ int lldp_handle_packet(tlv_packet *tlv, uint16_t length) {
assert(tlv);
assert(length > 0);
- port = (lldp_port *) tlv->userdata;
- lldp = (sd_lldp *) port->userdata;
-
- if (lldp->port->status == LLDP_PORT_STATUS_DISABLED) {
- log_lldp("Port: %s is disabled. Dropping.", lldp->port->ifname);
- goto out;
- }
+ lldp = tlv->userdata;
p = tlv->pdu;
p += sizeof(struct ether_header);
@@ -508,54 +505,67 @@ int sd_lldp_start(sd_lldp *lldp) {
int r;
assert_return(lldp, -EINVAL);
- assert_return(lldp->port, -EINVAL);
- lldp->port->status = LLDP_PORT_STATUS_ENABLED;
+ if (lldp->fd >= 0)
+ return 0;
- r = lldp_port_start(lldp->port);
- if (r < 0) {
- log_lldp("Failed to start Port : %s , %s",
- lldp->port->ifname,
- strerror(-r));
+ assert(!lldp->event_source);
- return r;
+ lldp->fd = lldp_network_bind_raw_socket(lldp->ifindex);
+ if (lldp->fd < 0)
+ return lldp->fd;
+
+ if (lldp->event) {
+ r = sd_event_add_io(lldp->event, &lldp->event_source, lldp->fd, EPOLLIN, lldp_receive_packet, lldp);
+ if (r < 0)
+ goto fail;
+
+ r = sd_event_source_set_priority(lldp->event_source, lldp->event_priority);
+ if (r < 0)
+ goto fail;
+
+ (void) sd_event_source_set_description(lldp->event_source, "lldp");
}
- return 0;
+ return 1;
+
+fail:
+ lldp->event_source = sd_event_source_unref(lldp->event_source);
+ lldp->fd = safe_close(lldp->fd);
+
+ return r;
}
int sd_lldp_stop(sd_lldp *lldp) {
- int r;
-
assert_return(lldp, -EINVAL);
- assert_return(lldp->port, -EINVAL);
- lldp->port->status = LLDP_PORT_STATUS_DISABLED;
+ if (lldp->fd < 0)
+ return 0;
- r = lldp_port_stop(lldp->port);
- if (r < 0)
- return r;
+ lldp->event_source = sd_event_source_unref(lldp->event_source);
+ lldp->fd = safe_close(lldp->fd);
lldp_mib_objects_flush(lldp);
- return 0;
+ return 1;
}
-int sd_lldp_attach_event(sd_lldp *lldp, sd_event *event, int priority) {
+int sd_lldp_attach_event(sd_lldp *lldp, sd_event *event, int64_t priority) {
int r;
assert_return(lldp, -EINVAL);
- assert_return(!lldp->port->event, -EBUSY);
+ assert_return(lldp->fd < 0, -EBUSY);
+ assert_return(!lldp->event, -EBUSY);
if (event)
- lldp->port->event = sd_event_ref(event);
+ lldp->event = sd_event_ref(event);
else {
- r = sd_event_default(&lldp->port->event);
+ r = sd_event_default(&lldp->event);
if (r < 0)
return r;
}
- lldp->port->event_priority = priority;
+ lldp->event_priority = priority;
return 0;
}
@@ -563,8 +573,9 @@ int sd_lldp_attach_event(sd_lldp *lldp, sd_event *event, int priority) {
int sd_lldp_detach_event(sd_lldp *lldp) {
assert_return(lldp, -EINVAL);
+ assert_return(lldp->fd < 0, -EBUSY);
- lldp->port->event = sd_event_unref(lldp->port->event);
+ lldp->event = sd_event_unref(lldp->event);
return 0;
}
@@ -586,41 +597,36 @@ sd_lldp* sd_lldp_unref(sd_lldp *lldp) {
/* Drop all packets */
lldp_mib_objects_flush(lldp);
- lldp_port_free(lldp->port);
-
hashmap_free(lldp->neighbour_mib);
prioq_free(lldp->by_expiry);
+ sd_event_source_unref(lldp->event_source);
+ sd_event_unref(lldp->event);
+ safe_close(lldp->fd);
+
free(lldp);
return NULL;
}
-int sd_lldp_new(int ifindex,
- const char *ifname,
- const struct ether_addr *mac,
- sd_lldp **ret) {
+int sd_lldp_new(int ifindex, sd_lldp **ret) {
_cleanup_(sd_lldp_unrefp) sd_lldp *lldp = NULL;
int r;
assert_return(ret, -EINVAL);
assert_return(ifindex > 0, -EINVAL);
- assert_return(ifname, -EINVAL);
- assert_return(mac, -EINVAL);
lldp = new0(sd_lldp, 1);
if (!lldp)
return -ENOMEM;
- r = lldp_port_new(ifindex, ifname, mac, lldp, &lldp->port);
- if (r < 0)
- return r;
+ lldp->fd = -1;
+ lldp->ifindex = ifindex;
lldp->neighbour_mib = hashmap_new(&chassis_id_hash_ops);
if (!lldp->neighbour_mib)
return -ENOMEM;
- r = prioq_ensure_allocated(&lldp->by_expiry,
- ttl_expiry_item_prioq_compare_func);
+ r = prioq_ensure_allocated(&lldp->by_expiry, ttl_expiry_item_prioq_compare_func);
if (r < 0)
return r;
diff --git a/src/libsystemd-network/test-lldp.c b/src/libsystemd-network/test-lldp.c
index ed923d5cb3..7b8dd0ad88 100644
--- a/src/libsystemd-network/test-lldp.c
+++ b/src/libsystemd-network/test-lldp.c
@@ -259,7 +259,7 @@ static void lldp_handler (sd_lldp *lldp, int event, void *userdata) {
static int start_lldp(sd_lldp **lldp, sd_event *e, sd_lldp_callback_t cb, void *cb_data) {
int r;
- r = sd_lldp_new(42, "dummy", &mac_addr, lldp);
+ r = sd_lldp_new(42, lldp);
if (r)
return r;
diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c
index 692c0bf63d..1711436b48 100644
--- a/src/network/networkd-link.c
+++ b/src/network/networkd-link.c
@@ -2109,7 +2109,7 @@ static int link_configure(Link *link) {
}
if (link_lldp_enabled(link)) {
- r = sd_lldp_new(link->ifindex, link->ifname, &link->mac, &link->lldp);
+ r = sd_lldp_new(link->ifindex, &link->lldp);
if (r < 0)
return r;
@@ -2117,8 +2117,7 @@ static int link_configure(Link *link) {
if (r < 0)
return r;
- r = sd_lldp_set_callback(link->lldp,
- lldp_handler, link);
+ r = sd_lldp_set_callback(link->lldp, lldp_handler, link);
if (r < 0)
return r;
}
diff --git a/src/systemd/sd-lldp.h b/src/systemd/sd-lldp.h
index dd8548e3d3..4c896e7fc0 100644
--- a/src/systemd/sd-lldp.h
+++ b/src/systemd/sd-lldp.h
@@ -45,13 +45,13 @@ typedef struct sd_lldp_packet sd_lldp_packet;
typedef void (*sd_lldp_callback_t)(sd_lldp *lldp, int event, void *userdata);
-int sd_lldp_new(int ifindex, const char *ifname, const struct ether_addr *mac, sd_lldp **ret);
+int sd_lldp_new(int ifindex, sd_lldp **ret);
sd_lldp* sd_lldp_unref(sd_lldp *lldp);
int sd_lldp_start(sd_lldp *lldp);
int sd_lldp_stop(sd_lldp *lldp);
-int sd_lldp_attach_event(sd_lldp *lldp, sd_event *event, int priority);
+int sd_lldp_attach_event(sd_lldp *lldp, sd_event *event, int64_t priority);
int sd_lldp_detach_event(sd_lldp *lldp);
int sd_lldp_set_callback(sd_lldp *lldp, sd_lldp_callback_t cb, void *userdata);