lldp-port.c revision e53fc357a9bb9d0a5362ccc4246d598cb0febd5e
3133N/A/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
3133N/A
261N/A/***
261N/A This file is part of systemd.
261N/A
261N/A Copyright (C) 2014 Tom Gundersen
261N/A Copyright (C) 2014 Susant Sahani
261N/A
261N/A systemd is free software; you can redistribute it and/or modify it
261N/A under the terms of the GNU Lesser General Public License as published by
261N/A the Free Software Foundation; either version 2.1 of the License, or
261N/A (at your option) any later version.
261N/A
261N/A systemd is distributed in the hope that it will be useful, but
261N/A WITHOUT ANY WARRANTY; without even the implied warranty of
261N/A MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
261N/A Lesser General Public License for more details.
261N/A
261N/A You should have received a copy of the GNU Lesser General Public License
261N/A along with systemd; If not, see <http://www.gnu.org/licenses/>.
261N/A***/
261N/A
261N/A#include "async.h"
261N/A#include "lldp-port.h"
261N/A#include "lldp-network.h"
261N/A
261N/Aint lldp_port_start(lldp_port *p) {
261N/A int r;
261N/A
261N/A assert_return(p, -EINVAL);
261N/A
261N/A r = lldp_network_bind_raw_socket(p->ifindex);
261N/A if (r < 0)
261N/A return r;
261N/A
261N/A p->rawfd = r;
261N/A
261N/A r = sd_event_add_io(p->event, &p->lldp_port_rx,
261N/A p->rawfd, EPOLLIN, lldp_receive_packet, p);
261N/A if (r < 0) {
261N/A log_debug_errno(r, "Failed to allocate event source: %m");
261N/A goto fail;
261N/A }
261N/A
261N/A r = sd_event_source_set_priority(p->lldp_port_rx, p->event_priority);
261N/A if (r < 0) {
261N/A log_debug_errno(r, "Failed to set event priority: %m");
261N/A goto fail;
261N/A }
261N/A
261N/A r = sd_event_source_set_description(p->lldp_port_rx, "lldp-port-rx");
261N/A if (r < 0) {
261N/A log_debug_errno(r, "Failed to set event name: %m");
261N/A goto fail;
261N/A }
261N/A
261N/A return 0;
261N/A
261N/Afail:
261N/A lldp_port_stop(p);
261N/A
261N/A return r;
261N/A}
261N/A
261N/Aint lldp_port_stop(lldp_port *p) {
261N/A
261N/A assert_return(p, -EINVAL);
261N/A
261N/A p->rawfd = asynchronous_close(p->rawfd);
261N/A p->lldp_port_rx = sd_event_source_unref(p->lldp_port_rx);
261N/A
261N/A return 0;
261N/A}
261N/A
261N/Avoid lldp_port_free(lldp_port *p) {
261N/A if (!p)
261N/A return;
261N/A
261N/A lldp_port_stop(p);
261N/A
261N/A free(p->ifname);
261N/A free(p);
261N/A}
261N/A
261N/Aint lldp_port_new(int ifindex,
261N/A const char *ifname,
261N/A const struct ether_addr *addr,
261N/A void *userdata,
261N/A lldp_port **ret) {
261N/A _cleanup_free_ lldp_port *p = NULL;
261N/A
261N/A assert_return(ifindex, -EINVAL);
261N/A assert_return(ifname, -EINVAL);
261N/A assert_return(addr, -EINVAL);
261N/A
261N/A p = new0(lldp_port, 1);
261N/A if (!p)
261N/A return -ENOMEM;
261N/A
261N/A p->rawfd = -1;
261N/A p->ifindex = ifindex;
261N/A
261N/A p->ifname = strdup(ifname);
261N/A if (!p->ifname)
261N/A return -ENOMEM;
261N/A
261N/A memcpy(&p->mac, addr, ETH_ALEN);
261N/A
261N/A p->userdata = userdata;
261N/A
261N/A *ret = p;
261N/A
261N/A p = NULL;
261N/A
261N/A return 0;
261N/A}
261N/A