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