]>
Commit | Line | Data |
---|---|---|
4b292b55 VB |
1 | /* -*- mode: c; c-file-style: "openbsd" -*- */ |
2 | /* | |
3 | * Copyright (c) 2008 Vincent Bernat <bernat@luffy.cx> | |
4 | * | |
5 | * Permission to use, copy, modify, and/or distribute this software for any | |
6 | * purpose with or without fee is hereby granted, provided that the above | |
7 | * copyright notice and this permission notice appear in all copies. | |
8 | * | |
9 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |
10 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
11 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | |
12 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
13 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | |
14 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | |
15 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
16 | */ | |
17 | ||
18 | #include <stdlib.h> | |
19 | #include <unistd.h> | |
20 | #include <time.h> | |
21 | #include "lldpd-structs.h" | |
6f8925be | 22 | #include "log.h" |
4b292b55 VB |
23 | |
24 | void | |
25 | lldpd_chassis_mgmt_cleanup(struct lldpd_chassis *chassis) | |
26 | { | |
27 | struct lldpd_mgmt *mgmt, *mgmt_next; | |
6f8925be VB |
28 | |
29 | log_debug("alloc", "cleanup management addresses for chassis %s", | |
aed91d90 | 30 | chassis->c_name ? chassis->c_name : "(unknown)"); |
6f8925be | 31 | |
4b292b55 VB |
32 | for (mgmt = TAILQ_FIRST(&chassis->c_mgmt); |
33 | mgmt != NULL; | |
34 | mgmt = mgmt_next) { | |
35 | mgmt_next = TAILQ_NEXT(mgmt, m_entries); | |
36 | free(mgmt); | |
37 | } | |
38 | TAILQ_INIT(&chassis->c_mgmt); | |
39 | } | |
40 | ||
41 | void | |
42 | lldpd_chassis_cleanup(struct lldpd_chassis *chassis, int all) | |
43 | { | |
e12c2365 | 44 | lldpd_chassis_mgmt_cleanup(chassis); |
6f8925be | 45 | log_debug("alloc", "cleanup chassis %s", |
aed91d90 | 46 | chassis->c_name ? chassis->c_name : "(unknown)"); |
4b292b55 VB |
47 | #ifdef ENABLE_LLDPMED |
48 | free(chassis->c_med_hw); | |
49 | free(chassis->c_med_sw); | |
50 | free(chassis->c_med_fw); | |
51 | free(chassis->c_med_sn); | |
52 | free(chassis->c_med_manuf); | |
53 | free(chassis->c_med_model); | |
54 | free(chassis->c_med_asset); | |
55 | #endif | |
56 | free(chassis->c_id); | |
57 | free(chassis->c_name); | |
58 | free(chassis->c_descr); | |
4b292b55 VB |
59 | if (all) |
60 | free(chassis); | |
61 | } | |
62 | ||
63 | #ifdef ENABLE_DOT1 | |
64 | void | |
65 | lldpd_vlan_cleanup(struct lldpd_port *port) | |
66 | { | |
67 | struct lldpd_vlan *vlan, *vlan_next; | |
68 | for (vlan = TAILQ_FIRST(&port->p_vlans); | |
69 | vlan != NULL; | |
70 | vlan = vlan_next) { | |
71 | free(vlan->v_name); | |
72 | vlan_next = TAILQ_NEXT(vlan, v_entries); | |
73 | free(vlan); | |
74 | } | |
75 | TAILQ_INIT(&port->p_vlans); | |
76 | } | |
77 | ||
78 | void | |
79 | lldpd_ppvid_cleanup(struct lldpd_port *port) | |
80 | { | |
81 | struct lldpd_ppvid *ppvid, *ppvid_next; | |
82 | for (ppvid = TAILQ_FIRST(&port->p_ppvids); | |
83 | ppvid != NULL; | |
84 | ppvid = ppvid_next) { | |
85 | ppvid_next = TAILQ_NEXT(ppvid, p_entries); | |
86 | free(ppvid); | |
87 | } | |
88 | TAILQ_INIT(&port->p_ppvids); | |
89 | } | |
90 | ||
91 | void | |
92 | lldpd_pi_cleanup(struct lldpd_port *port) | |
93 | { | |
94 | struct lldpd_pi *pi, *pi_next; | |
95 | for (pi = TAILQ_FIRST(&port->p_pids); | |
96 | pi != NULL; | |
97 | pi = pi_next) { | |
98 | free(pi->p_pi); | |
99 | pi_next = TAILQ_NEXT(pi, p_entries); | |
100 | free(pi); | |
101 | } | |
102 | TAILQ_INIT(&port->p_pids); | |
103 | } | |
104 | #endif | |
105 | ||
fb1b78bb | 106 | #ifdef ENABLE_CUSTOM |
7c26c8b4 | 107 | void |
108 | lldpd_custom_tlv_add(struct lldpd_port *port, struct lldpd_custom *curr) | |
109 | { | |
110 | struct lldpd_custom *custom; | |
111 | ||
112 | if ((custom = malloc(sizeof(struct lldpd_custom)))) { | |
113 | memcpy(custom, curr, sizeof(struct lldpd_custom)); | |
114 | if ((custom->oui_info = malloc(custom->oui_info_len))) { | |
115 | memcpy(custom->oui_info, curr->oui_info, custom->oui_info_len); | |
116 | TAILQ_INSERT_TAIL(&port->p_custom_list, custom, next); | |
117 | } else { | |
118 | free(custom); | |
119 | log_warn("rpc", "could not allocate memory for custom TLV info"); | |
120 | } | |
121 | } | |
122 | } | |
123 | ||
124 | void | |
125 | lldpd_custom_tlv_cleanup(struct lldpd_port *port, struct lldpd_custom *curr) | |
126 | { | |
127 | struct lldpd_custom *custom, *custom_next; | |
128 | for (custom = TAILQ_FIRST(&port->p_custom_list); | |
129 | custom != NULL; | |
130 | custom = custom_next) { | |
131 | custom_next = TAILQ_NEXT(custom, next); | |
132 | if (!memcmp(curr->oui, custom->oui, sizeof(curr->oui)) && | |
133 | curr->subtype == custom->subtype) { | |
134 | TAILQ_REMOVE(&port->p_custom_list, custom, next); | |
135 | free(custom->oui_info); | |
136 | free(custom); | |
137 | } | |
138 | } | |
139 | } | |
140 | ||
141 | void | |
cd5de7a2 AA |
142 | lldpd_custom_list_cleanup(struct lldpd_port *port) |
143 | { | |
144 | struct lldpd_custom *custom, *custom_next; | |
145 | for (custom = TAILQ_FIRST(&port->p_custom_list); | |
146 | custom != NULL; | |
147 | custom = custom_next) { | |
148 | custom_next = TAILQ_NEXT(custom, next); | |
8caf4341 | 149 | free(custom->oui_info); |
cd5de7a2 AA |
150 | free(custom); |
151 | } | |
152 | TAILQ_INIT(&port->p_custom_list); | |
153 | } | |
fb1b78bb | 154 | #endif |
cd5de7a2 | 155 | |
ef3707da VB |
156 | /* Cleanup a remote port. The before last argument, `expire` is a function that |
157 | * should be called when a remote port is removed. If the last argument is 1, | |
158 | * all remote ports are removed. | |
159 | */ | |
4b292b55 | 160 | void |
4e90a9e0 | 161 | lldpd_remote_cleanup(struct lldpd_hardware *hardware, |
ef3707da VB |
162 | void(*expire)(struct lldpd_hardware *, struct lldpd_port *), |
163 | int all) | |
4b292b55 VB |
164 | { |
165 | struct lldpd_port *port, *port_next; | |
166 | int del; | |
3333d2a8 | 167 | time_t now = time(NULL); |
6f8925be VB |
168 | |
169 | log_debug("alloc", "cleanup remote port on %s", | |
170 | hardware->h_ifname); | |
4b292b55 VB |
171 | for (port = TAILQ_FIRST(&hardware->h_rports); |
172 | port != NULL; | |
173 | port = port_next) { | |
174 | port_next = TAILQ_NEXT(port, p_entries); | |
ef3707da | 175 | del = all; |
42ea638d | 176 | if (!all && expire && |
78346c89 | 177 | (now >= port->p_lastupdate + port->p_ttl)) { |
14052b61 VB |
178 | hardware->h_ageout_cnt++; |
179 | hardware->h_delete_cnt++; | |
4b292b55 VB |
180 | del = 1; |
181 | } | |
182 | if (del) { | |
41e57d5a | 183 | if (expire) expire(hardware, port); |
4e97a0bf VB |
184 | /* This TAILQ_REMOVE is dangerous. It should not be |
185 | * called while in liblldpctl because we don't have a | |
186 | * real list. It is only needed to be called when we | |
187 | * don't delete the entire list. */ | |
188 | if (!all) TAILQ_REMOVE(&hardware->h_rports, port, p_entries); | |
4b292b55 VB |
189 | lldpd_port_cleanup(port, 1); |
190 | free(port); | |
191 | } | |
192 | } | |
ef3707da | 193 | if (all) TAILQ_INIT(&hardware->h_rports); |
4b292b55 VB |
194 | } |
195 | ||
196 | /* If `all' is true, clear all information, including information that | |
197 | are not refreshed periodically. Port should be freed manually. */ | |
198 | void | |
199 | lldpd_port_cleanup(struct lldpd_port *port, int all) | |
200 | { | |
201 | #ifdef ENABLE_LLDPMED | |
202 | int i; | |
203 | if (all) | |
204 | for (i=0; i < LLDP_MED_LOCFORMAT_LAST; i++) | |
205 | free(port->p_med_location[i].data); | |
206 | #endif | |
207 | #ifdef ENABLE_DOT1 | |
208 | lldpd_vlan_cleanup(port); | |
209 | lldpd_ppvid_cleanup(port); | |
210 | lldpd_pi_cleanup(port); | |
211 | #endif | |
8fbd3195 ST |
212 | /* will set these to NULL so we don't free wrong memory */ |
213 | ||
4b292b55 | 214 | if (all) { |
8e46010c AA |
215 | free(port->p_id); |
216 | port->p_id = NULL; | |
c267d0f2 AA |
217 | free(port->p_descr); |
218 | port->p_descr = NULL; | |
4b292b55 VB |
219 | free(port->p_lastframe); |
220 | if (port->p_chassis) { /* chassis may not have been attributed, yet */ | |
221 | port->p_chassis->c_refcount--; | |
222 | port->p_chassis = NULL; | |
223 | } | |
fb1b78bb | 224 | #ifdef ENABLE_CUSTOM |
cd5de7a2 | 225 | lldpd_custom_list_cleanup(port); |
fb1b78bb | 226 | #endif |
4b292b55 VB |
227 | } |
228 | } | |
8ec333bd VB |
229 | |
230 | void | |
231 | lldpd_config_cleanup(struct lldpd_config *config) | |
232 | { | |
6f8925be | 233 | log_debug("alloc", "general configuration cleanup"); |
8ec333bd VB |
234 | free(config->c_mgmt_pattern); |
235 | free(config->c_cid_pattern); | |
5660759b | 236 | free(config->c_cid_string); |
8ec333bd | 237 | free(config->c_iface_pattern); |
0a78e14f | 238 | free(config->c_perm_ifaces); |
ce347d29 | 239 | free(config->c_hostname); |
8ec333bd VB |
240 | free(config->c_platform); |
241 | free(config->c_description); | |
242 | } |