auto-attach: Cleanup i-sid/vlan mappings associated with lldp-enabled port.
[cascardo/ovs.git] / lib / lldp / lldpd-structs.c
1 /* -*- mode: c; c-file-style: "openbsd" -*- */
2 /*
3  * Copyright (c) 2015 Nicira, Inc.
4  * Copyright (c) 2008 Vincent Bernat <bernat@luffy.cx>
5  *
6  * Permission to use, copy, modify, and/or distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18
19 #include <config.h>
20 #include "lldpd-structs.h"
21 #include <stdlib.h>
22 #include <unistd.h>
23 #include "lldpd.h"
24 #include "timeval.h"
25
26 VLOG_DEFINE_THIS_MODULE(lldpd_structs);
27
28 void
29 lldpd_chassis_mgmt_cleanup(struct lldpd_chassis *chassis)
30 {
31     struct lldpd_mgmt *mgmt;
32
33     VLOG_DBG("cleanup management addresses for chassis %s",
34              chassis->c_name ? chassis->c_name : "(unknown)");
35
36     LIST_FOR_EACH_POP (mgmt, m_entries, &chassis->c_mgmt) {
37        free(mgmt);
38     }
39
40     list_init(&chassis->c_mgmt);
41 }
42
43 void
44 lldpd_chassis_cleanup(struct lldpd_chassis *chassis, bool all)
45 {
46     lldpd_chassis_mgmt_cleanup(chassis);
47     VLOG_DBG("cleanup chassis %s",
48              chassis->c_name ? chassis->c_name : "(unknown)");
49     free(chassis->c_id);
50     free(chassis->c_name);
51     free(chassis->c_descr);
52     if (all) {
53         free(chassis);
54     }
55 }
56
57 /* Cleanup a remote port. The before last argument, `expire` is a function that
58  * should be called when a remote port is removed. If the last argument is
59  * true, all remote ports are removed.
60  */
61 void
62 lldpd_remote_cleanup(struct lldpd_hardware *hw,
63                      void(*expire)(struct lldpd_hardware *,
64                                    struct lldpd_port *),
65                      bool all)
66 {
67     struct lldpd_port *port, *port_next;
68     time_t now = time_now();
69
70     VLOG_DBG("cleanup remote port on %s", hw->h_ifname);
71     LIST_FOR_EACH_SAFE (port, port_next, p_entries, &hw->h_rports) {
72         bool del = all;
73         if (!all && expire &&
74             (now >= port->p_lastupdate + port->p_chassis->c_ttl)) {
75             hw->h_ageout_cnt++;
76             hw->h_delete_cnt++;
77             del = true;
78         }
79         if (del) {
80             if (expire) {
81                 expire(hw, port);
82             }
83
84             if (!all) {
85                 list_remove(&port->p_entries);
86             }
87             lldpd_port_cleanup(port, true);
88             free(port);
89         }
90     }
91     if (all) {
92         list_init(&hw->h_rports);
93     }
94 }
95
96 /* Cleanup the auto-attach mappings attached to port.
97  */
98 static void
99 lldpd_aa_maps_cleanup(struct lldpd_port *port)
100 {
101     struct lldpd_aa_isid_vlan_maps_tlv *isid_vlan_map = NULL;
102     struct lldpd_aa_isid_vlan_maps_tlv *isid_vlan_map_next = NULL;
103
104     if (!list_is_empty(&port->p_isid_vlan_maps)) {
105
106         LIST_FOR_EACH_SAFE (isid_vlan_map, isid_vlan_map_next, m_entries,
107                             &port->p_isid_vlan_maps) {
108
109             list_remove(&isid_vlan_map->m_entries);
110             free(isid_vlan_map);
111         }
112
113         list_init(&port->p_isid_vlan_maps);
114     }
115 }
116
117 /* If `all' is true, clear all information, including information that
118    are not refreshed periodically. Port should be freed manually. */
119 void
120 lldpd_port_cleanup(struct lldpd_port *port, bool all)
121 {
122     /* We set these to NULL so we don't free wrong memory */
123     free(port->p_id);
124     port->p_id = NULL;
125     free(port->p_descr);
126     port->p_descr = NULL;
127
128     /* Cleanup auto-attach mappings */
129     lldpd_aa_maps_cleanup(port);
130
131     if (all) {
132         free(port->p_lastframe);
133         /* Chassis may not have been attributed, yet.*/
134         if (port->p_chassis) {
135             port->p_chassis->c_refcount--;
136             port->p_chassis = NULL;
137         }
138     }
139 }
140
141 void
142 lldpd_config_cleanup(struct lldpd_config *config)
143 {
144     VLOG_DBG("general configuration cleanup");
145     free(config->c_mgmt_pattern);
146     free(config->c_cid_pattern);
147     free(config->c_iface_pattern);
148     free(config->c_platform);
149     free(config->c_description);
150 }