sd-lldp: drop "port" object

Let's just keep the few parts we actually need of it in the main sd_lldp
object, so that we can simplify things quite a bit.

While we are at it, remove ifname and mac fields which we make no use of
whatsoever.
This commit is contained in:
Lennart Poettering 2016-02-16 19:26:40 +01:00
parent 2139d247bd
commit 032b27f534
7 changed files with 58 additions and 240 deletions

View File

@ -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

View File

@ -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;
}

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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;
}

View File

@ -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);