Blame src/lldpd-structs.c

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
}