|
Packit |
e9ba0d |
/* -*- mode: c; c-file-style: "openbsd" -*- */
|
|
Packit |
e9ba0d |
/*
|
|
Packit |
e9ba0d |
* Copyright (c) 2008 Vincent Bernat <bernat@luffy.cx>
|
|
Packit |
e9ba0d |
*
|
|
Packit |
e9ba0d |
* Permission to use, copy, modify, and/or distribute this software for any
|
|
Packit |
e9ba0d |
* purpose with or without fee is hereby granted, provided that the above
|
|
Packit |
e9ba0d |
* copyright notice and this permission notice appear in all copies.
|
|
Packit |
e9ba0d |
*
|
|
Packit |
e9ba0d |
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
Packit |
e9ba0d |
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
Packit |
e9ba0d |
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
Packit |
e9ba0d |
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
Packit |
e9ba0d |
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
Packit |
e9ba0d |
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
Packit |
e9ba0d |
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
Packit |
e9ba0d |
*/
|
|
Packit |
e9ba0d |
|
|
Packit |
e9ba0d |
#include <stdlib.h>
|
|
Packit |
e9ba0d |
#include <unistd.h>
|
|
Packit |
e9ba0d |
#include <time.h>
|
|
Packit |
e9ba0d |
#include "lldpd-structs.h"
|
|
Packit |
e9ba0d |
#include "log.h"
|
|
Packit |
e9ba0d |
|
|
Packit |
e9ba0d |
void
|
|
Packit |
e9ba0d |
lldpd_chassis_mgmt_cleanup(struct lldpd_chassis *chassis)
|
|
Packit |
e9ba0d |
{
|
|
Packit |
e9ba0d |
struct lldpd_mgmt *mgmt, *mgmt_next;
|
|
Packit |
e9ba0d |
|
|
Packit |
e9ba0d |
log_debug("alloc", "cleanup management addresses for chassis %s",
|
|
Packit |
e9ba0d |
chassis->c_name ? chassis->c_name : "(unknown)");
|
|
Packit |
e9ba0d |
|
|
Packit |
e9ba0d |
for (mgmt = TAILQ_FIRST(&chassis->c_mgmt);
|
|
Packit |
e9ba0d |
mgmt != NULL;
|
|
Packit |
e9ba0d |
mgmt = mgmt_next) {
|
|
Packit |
e9ba0d |
mgmt_next = TAILQ_NEXT(mgmt, m_entries);
|
|
Packit |
e9ba0d |
free(mgmt);
|
|
Packit |
e9ba0d |
}
|
|
Packit |
e9ba0d |
TAILQ_INIT(&chassis->c_mgmt);
|
|
Packit |
e9ba0d |
}
|
|
Packit |
e9ba0d |
|
|
Packit |
e9ba0d |
void
|
|
Packit |
e9ba0d |
lldpd_chassis_cleanup(struct lldpd_chassis *chassis, int all)
|
|
Packit |
e9ba0d |
{
|
|
Packit |
e9ba0d |
lldpd_chassis_mgmt_cleanup(chassis);
|
|
Packit |
e9ba0d |
log_debug("alloc", "cleanup chassis %s",
|
|
Packit |
e9ba0d |
chassis->c_name ? chassis->c_name : "(unknown)");
|
|
Packit |
e9ba0d |
#ifdef ENABLE_LLDPMED
|
|
Packit |
e9ba0d |
free(chassis->c_med_hw);
|
|
Packit |
e9ba0d |
free(chassis->c_med_sw);
|
|
Packit |
e9ba0d |
free(chassis->c_med_fw);
|
|
Packit |
e9ba0d |
free(chassis->c_med_sn);
|
|
Packit |
e9ba0d |
free(chassis->c_med_manuf);
|
|
Packit |
e9ba0d |
free(chassis->c_med_model);
|
|
Packit |
e9ba0d |
free(chassis->c_med_asset);
|
|
Packit |
e9ba0d |
#endif
|
|
Packit |
e9ba0d |
free(chassis->c_id);
|
|
Packit |
e9ba0d |
free(chassis->c_name);
|
|
Packit |
e9ba0d |
free(chassis->c_descr);
|
|
Packit |
e9ba0d |
if (all)
|
|
Packit |
e9ba0d |
free(chassis);
|
|
Packit |
e9ba0d |
}
|
|
Packit |
e9ba0d |
|
|
Packit |
e9ba0d |
#ifdef ENABLE_DOT1
|
|
Packit |
e9ba0d |
void
|
|
Packit |
e9ba0d |
lldpd_vlan_cleanup(struct lldpd_port *port)
|
|
Packit |
e9ba0d |
{
|
|
Packit |
e9ba0d |
struct lldpd_vlan *vlan, *vlan_next;
|
|
Packit |
e9ba0d |
for (vlan = TAILQ_FIRST(&port->p_vlans);
|
|
Packit |
e9ba0d |
vlan != NULL;
|
|
Packit |
e9ba0d |
vlan = vlan_next) {
|
|
Packit |
e9ba0d |
free(vlan->v_name);
|
|
Packit |
e9ba0d |
vlan_next = TAILQ_NEXT(vlan, v_entries);
|
|
Packit |
e9ba0d |
free(vlan);
|
|
Packit |
e9ba0d |
}
|
|
Packit |
e9ba0d |
TAILQ_INIT(&port->p_vlans);
|
|
Packit |
e9ba0d |
}
|
|
Packit |
e9ba0d |
|
|
Packit |
e9ba0d |
void
|
|
Packit |
e9ba0d |
lldpd_ppvid_cleanup(struct lldpd_port *port)
|
|
Packit |
e9ba0d |
{
|
|
Packit |
e9ba0d |
struct lldpd_ppvid *ppvid, *ppvid_next;
|
|
Packit |
e9ba0d |
for (ppvid = TAILQ_FIRST(&port->p_ppvids);
|
|
Packit |
e9ba0d |
ppvid != NULL;
|
|
Packit |
e9ba0d |
ppvid = ppvid_next) {
|
|
Packit |
e9ba0d |
ppvid_next = TAILQ_NEXT(ppvid, p_entries);
|
|
Packit |
e9ba0d |
free(ppvid);
|
|
Packit |
e9ba0d |
}
|
|
Packit |
e9ba0d |
TAILQ_INIT(&port->p_ppvids);
|
|
Packit |
e9ba0d |
}
|
|
Packit |
e9ba0d |
|
|
Packit |
e9ba0d |
void
|
|
Packit |
e9ba0d |
lldpd_pi_cleanup(struct lldpd_port *port)
|
|
Packit |
e9ba0d |
{
|
|
Packit |
e9ba0d |
struct lldpd_pi *pi, *pi_next;
|
|
Packit |
e9ba0d |
for (pi = TAILQ_FIRST(&port->p_pids);
|
|
Packit |
e9ba0d |
pi != NULL;
|
|
Packit |
e9ba0d |
pi = pi_next) {
|
|
Packit |
e9ba0d |
free(pi->p_pi);
|
|
Packit |
e9ba0d |
pi_next = TAILQ_NEXT(pi, p_entries);
|
|
Packit |
e9ba0d |
free(pi);
|
|
Packit |
e9ba0d |
}
|
|
Packit |
e9ba0d |
TAILQ_INIT(&port->p_pids);
|
|
Packit |
e9ba0d |
}
|
|
Packit |
e9ba0d |
#endif
|
|
Packit |
e9ba0d |
|
|
Packit |
e9ba0d |
#ifdef ENABLE_CUSTOM
|
|
Packit |
e9ba0d |
void
|
|
Packit |
e9ba0d |
lldpd_custom_tlv_add(struct lldpd_port *port, struct lldpd_custom *curr)
|
|
Packit |
e9ba0d |
{
|
|
Packit |
e9ba0d |
struct lldpd_custom *custom;
|
|
Packit |
e9ba0d |
|
|
Packit |
e9ba0d |
if ((custom = malloc(sizeof(struct lldpd_custom)))) {
|
|
Packit |
e9ba0d |
memcpy(custom, curr, sizeof(struct lldpd_custom));
|
|
Packit |
e9ba0d |
if ((custom->oui_info = malloc(custom->oui_info_len))) {
|
|
Packit |
e9ba0d |
memcpy(custom->oui_info, curr->oui_info, custom->oui_info_len);
|
|
Packit |
e9ba0d |
TAILQ_INSERT_TAIL(&port->p_custom_list, custom, next);
|
|
Packit |
e9ba0d |
} else {
|
|
Packit |
e9ba0d |
free(custom);
|
|
Packit |
e9ba0d |
log_warn("rpc", "could not allocate memory for custom TLV info");
|
|
Packit |
e9ba0d |
}
|
|
Packit |
e9ba0d |
}
|
|
Packit |
e9ba0d |
}
|
|
Packit |
e9ba0d |
|
|
Packit |
e9ba0d |
void
|
|
Packit |
e9ba0d |
lldpd_custom_tlv_cleanup(struct lldpd_port *port, struct lldpd_custom *curr)
|
|
Packit |
e9ba0d |
{
|
|
Packit |
e9ba0d |
struct lldpd_custom *custom, *custom_next;
|
|
Packit |
e9ba0d |
for (custom = TAILQ_FIRST(&port->p_custom_list);
|
|
Packit |
e9ba0d |
custom != NULL;
|
|
Packit |
e9ba0d |
custom = custom_next) {
|
|
Packit |
e9ba0d |
custom_next = TAILQ_NEXT(custom, next);
|
|
Packit |
e9ba0d |
if (!memcmp(curr->oui, custom->oui, sizeof(curr->oui)) &&
|
|
Packit |
e9ba0d |
curr->subtype == custom->subtype) {
|
|
Packit |
e9ba0d |
TAILQ_REMOVE(&port->p_custom_list, custom, next);
|
|
Packit |
e9ba0d |
free(custom->oui_info);
|
|
Packit |
e9ba0d |
free(custom);
|
|
Packit |
e9ba0d |
}
|
|
Packit |
e9ba0d |
}
|
|
Packit |
e9ba0d |
}
|
|
Packit |
e9ba0d |
|
|
Packit |
e9ba0d |
void
|
|
Packit |
e9ba0d |
lldpd_custom_list_cleanup(struct lldpd_port *port)
|
|
Packit |
e9ba0d |
{
|
|
Packit |
e9ba0d |
struct lldpd_custom *custom, *custom_next;
|
|
Packit |
e9ba0d |
for (custom = TAILQ_FIRST(&port->p_custom_list);
|
|
Packit |
e9ba0d |
custom != NULL;
|
|
Packit |
e9ba0d |
custom = custom_next) {
|
|
Packit |
e9ba0d |
custom_next = TAILQ_NEXT(custom, next);
|
|
Packit |
e9ba0d |
free(custom->oui_info);
|
|
Packit |
e9ba0d |
free(custom);
|
|
Packit |
e9ba0d |
}
|
|
Packit |
e9ba0d |
TAILQ_INIT(&port->p_custom_list);
|
|
Packit |
e9ba0d |
}
|
|
Packit |
e9ba0d |
#endif
|
|
Packit |
e9ba0d |
|
|
Packit |
e9ba0d |
/* Cleanup a remote port. The before last argument, `expire` is a function that
|
|
Packit |
e9ba0d |
* should be called when a remote port is removed. If the last argument is 1,
|
|
Packit |
e9ba0d |
* all remote ports are removed.
|
|
Packit |
e9ba0d |
*/
|
|
Packit |
e9ba0d |
void
|
|
Packit |
e9ba0d |
lldpd_remote_cleanup(struct lldpd_hardware *hardware,
|
|
Packit |
e9ba0d |
void(*expire)(struct lldpd_hardware *, struct lldpd_port *),
|
|
Packit |
e9ba0d |
int all)
|
|
Packit |
e9ba0d |
{
|
|
Packit |
e9ba0d |
struct lldpd_port *port, *port_next;
|
|
Packit |
e9ba0d |
int del;
|
|
Packit |
e9ba0d |
time_t now = time(NULL);
|
|
Packit |
e9ba0d |
|
|
Packit |
e9ba0d |
log_debug("alloc", "cleanup remote port on %s",
|
|
Packit |
e9ba0d |
hardware->h_ifname);
|
|
Packit |
e9ba0d |
for (port = TAILQ_FIRST(&hardware->h_rports);
|
|
Packit |
e9ba0d |
port != NULL;
|
|
Packit |
e9ba0d |
port = port_next) {
|
|
Packit |
e9ba0d |
port_next = TAILQ_NEXT(port, p_entries);
|
|
Packit |
e9ba0d |
del = all;
|
|
Packit |
e9ba0d |
if (!all && expire &&
|
|
Packit |
e9ba0d |
(now >= port->p_lastupdate + port->p_ttl)) {
|
|
Packit |
e9ba0d |
hardware->h_ageout_cnt++;
|
|
Packit |
e9ba0d |
del = 1;
|
|
Packit |
e9ba0d |
}
|
|
Packit |
e9ba0d |
if (del) {
|
|
Packit |
e9ba0d |
if (expire) expire(hardware, port);
|
|
Packit |
e9ba0d |
/* This TAILQ_REMOVE is dangerous. It should not be
|
|
Packit |
e9ba0d |
* called while in liblldpctl because we don't have a
|
|
Packit |
e9ba0d |
* real list. It is only needed to be called when we
|
|
Packit |
e9ba0d |
* don't delete the entire list. */
|
|
Packit |
e9ba0d |
if (!all) TAILQ_REMOVE(&hardware->h_rports, port, p_entries);
|
|
Packit |
e9ba0d |
|
|
Packit |
e9ba0d |
hardware->h_delete_cnt++;
|
|
Packit |
e9ba0d |
/* Register last removal to be able to report lldpStatsRemTablesLastChangeTime */
|
|
Packit |
e9ba0d |
hardware->h_lport.p_lastremove = time(NULL);
|
|
Packit |
e9ba0d |
lldpd_port_cleanup(port, 1);
|
|
Packit |
e9ba0d |
free(port);
|
|
Packit |
e9ba0d |
}
|
|
Packit |
e9ba0d |
}
|
|
Packit |
e9ba0d |
if (all) TAILQ_INIT(&hardware->h_rports);
|
|
Packit |
e9ba0d |
}
|
|
Packit |
e9ba0d |
|
|
Packit |
e9ba0d |
/* If `all' is true, clear all information, including information that
|
|
Packit |
e9ba0d |
are not refreshed periodically. Port should be freed manually. */
|
|
Packit |
e9ba0d |
void
|
|
Packit |
e9ba0d |
lldpd_port_cleanup(struct lldpd_port *port, int all)
|
|
Packit |
e9ba0d |
{
|
|
Packit |
e9ba0d |
#ifdef ENABLE_LLDPMED
|
|
Packit |
e9ba0d |
int i;
|
|
Packit |
e9ba0d |
if (all)
|
|
Packit |
e9ba0d |
for (i=0; i < LLDP_MED_LOCFORMAT_LAST; i++)
|
|
Packit |
e9ba0d |
free(port->p_med_location[i].data);
|
|
Packit |
e9ba0d |
#endif
|
|
Packit |
e9ba0d |
#ifdef ENABLE_DOT1
|
|
Packit |
e9ba0d |
lldpd_vlan_cleanup(port);
|
|
Packit |
e9ba0d |
lldpd_ppvid_cleanup(port);
|
|
Packit |
e9ba0d |
lldpd_pi_cleanup(port);
|
|
Packit |
e9ba0d |
#endif
|
|
Packit |
e9ba0d |
/* will set these to NULL so we don't free wrong memory */
|
|
Packit |
e9ba0d |
|
|
Packit |
e9ba0d |
if (all) {
|
|
Packit |
e9ba0d |
free(port->p_id);
|
|
Packit |
e9ba0d |
port->p_id = NULL;
|
|
Packit |
e9ba0d |
free(port->p_descr);
|
|
Packit |
e9ba0d |
port->p_descr = NULL;
|
|
Packit |
e9ba0d |
free(port->p_lastframe);
|
|
Packit |
e9ba0d |
if (port->p_chassis) { /* chassis may not have been attributed, yet */
|
|
Packit |
e9ba0d |
port->p_chassis->c_refcount--;
|
|
Packit |
e9ba0d |
port->p_chassis = NULL;
|
|
Packit |
e9ba0d |
}
|
|
Packit |
e9ba0d |
#ifdef ENABLE_CUSTOM
|
|
Packit |
e9ba0d |
lldpd_custom_list_cleanup(port);
|
|
Packit |
e9ba0d |
#endif
|
|
Packit |
e9ba0d |
}
|
|
Packit |
e9ba0d |
}
|
|
Packit |
e9ba0d |
|
|
Packit |
e9ba0d |
void
|
|
Packit |
e9ba0d |
lldpd_config_cleanup(struct lldpd_config *config)
|
|
Packit |
e9ba0d |
{
|
|
Packit |
e9ba0d |
log_debug("alloc", "general configuration cleanup");
|
|
Packit |
e9ba0d |
free(config->c_mgmt_pattern);
|
|
Packit |
e9ba0d |
free(config->c_cid_pattern);
|
|
Packit |
e9ba0d |
free(config->c_cid_string);
|
|
Packit |
e9ba0d |
free(config->c_iface_pattern);
|
|
Packit |
e9ba0d |
free(config->c_perm_ifaces);
|
|
Packit |
e9ba0d |
free(config->c_hostname);
|
|
Packit |
e9ba0d |
free(config->c_platform);
|
|
Packit |
e9ba0d |
free(config->c_description);
|
|
Packit |
e9ba0d |
}
|