/src/lldpd/src/lldpd-structs.c
Line | Count | Source (jump to first uncovered line) |
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" |
22 | | #include "log.h" |
23 | | |
24 | | void |
25 | | lldpd_chassis_mgmt_cleanup(struct lldpd_chassis *chassis) |
26 | 2.27k | { |
27 | 2.27k | struct lldpd_mgmt *mgmt, *mgmt_next; |
28 | | |
29 | 2.27k | log_debug("alloc", "cleanup management addresses for chassis %s", |
30 | 2.27k | chassis->c_name ? chassis->c_name : "(unknown)"); |
31 | | |
32 | 3.28k | for (mgmt = TAILQ_FIRST(&chassis->c_mgmt); mgmt != NULL; mgmt = mgmt_next) { |
33 | 1.01k | mgmt_next = TAILQ_NEXT(mgmt, m_entries); |
34 | 1.01k | free(mgmt); |
35 | 1.01k | } |
36 | 2.27k | TAILQ_INIT(&chassis->c_mgmt); |
37 | 2.27k | } |
38 | | |
39 | | void |
40 | | lldpd_chassis_cleanup(struct lldpd_chassis *chassis, int all) |
41 | 2.27k | { |
42 | 2.27k | lldpd_chassis_mgmt_cleanup(chassis); |
43 | 2.27k | log_debug("alloc", "cleanup chassis %s", |
44 | 2.27k | chassis->c_name ? chassis->c_name : "(unknown)"); |
45 | 2.27k | #ifdef ENABLE_LLDPMED |
46 | 2.27k | free(chassis->c_med_hw); |
47 | 2.27k | free(chassis->c_med_sw); |
48 | 2.27k | free(chassis->c_med_fw); |
49 | 2.27k | free(chassis->c_med_sn); |
50 | 2.27k | free(chassis->c_med_manuf); |
51 | 2.27k | free(chassis->c_med_model); |
52 | 2.27k | free(chassis->c_med_asset); |
53 | 2.27k | #endif |
54 | 2.27k | free(chassis->c_id); |
55 | 2.27k | free(chassis->c_name); |
56 | 2.27k | free(chassis->c_descr); |
57 | 2.27k | if (all) free(chassis); |
58 | 2.27k | } |
59 | | |
60 | | #ifdef ENABLE_DOT1 |
61 | | void |
62 | | lldpd_vlan_cleanup(struct lldpd_port *port) |
63 | 2.27k | { |
64 | 2.27k | struct lldpd_vlan *vlan, *vlan_next; |
65 | 3.25k | for (vlan = TAILQ_FIRST(&port->p_vlans); vlan != NULL; vlan = vlan_next) { |
66 | 984 | free(vlan->v_name); |
67 | 984 | vlan_next = TAILQ_NEXT(vlan, v_entries); |
68 | 984 | free(vlan); |
69 | 984 | } |
70 | 2.27k | TAILQ_INIT(&port->p_vlans); |
71 | 2.27k | port->p_pvid = 0; |
72 | 2.27k | } |
73 | | |
74 | | void |
75 | | lldpd_ppvid_cleanup(struct lldpd_port *port) |
76 | 2.27k | { |
77 | 2.27k | struct lldpd_ppvid *ppvid, *ppvid_next; |
78 | 2.66k | for (ppvid = TAILQ_FIRST(&port->p_ppvids); ppvid != NULL; ppvid = ppvid_next) { |
79 | 394 | ppvid_next = TAILQ_NEXT(ppvid, p_entries); |
80 | 394 | free(ppvid); |
81 | 394 | } |
82 | 2.27k | TAILQ_INIT(&port->p_ppvids); |
83 | 2.27k | } |
84 | | |
85 | | void |
86 | | lldpd_pi_cleanup(struct lldpd_port *port) |
87 | 2.27k | { |
88 | 2.27k | struct lldpd_pi *pi, *pi_next; |
89 | 2.67k | for (pi = TAILQ_FIRST(&port->p_pids); pi != NULL; pi = pi_next) { |
90 | 405 | free(pi->p_pi); |
91 | 405 | pi_next = TAILQ_NEXT(pi, p_entries); |
92 | 405 | free(pi); |
93 | 405 | } |
94 | 2.27k | TAILQ_INIT(&port->p_pids); |
95 | 2.27k | } |
96 | | #endif |
97 | | |
98 | | #ifdef ENABLE_CUSTOM |
99 | | void |
100 | | lldpd_custom_tlv_add(struct lldpd_port *port, struct lldpd_custom *curr) |
101 | 0 | { |
102 | 0 | struct lldpd_custom *custom; |
103 | |
|
104 | 0 | if ((custom = malloc(sizeof(struct lldpd_custom)))) { |
105 | 0 | memcpy(custom, curr, sizeof(struct lldpd_custom)); |
106 | 0 | if ((custom->oui_info = malloc(custom->oui_info_len))) { |
107 | 0 | memcpy(custom->oui_info, curr->oui_info, custom->oui_info_len); |
108 | 0 | TAILQ_INSERT_TAIL(&port->p_custom_list, custom, next); |
109 | 0 | } else { |
110 | 0 | free(custom); |
111 | 0 | log_warn("rpc", |
112 | 0 | "could not allocate memory for custom TLV info"); |
113 | 0 | } |
114 | 0 | } |
115 | 0 | } |
116 | | |
117 | | void |
118 | | lldpd_custom_tlv_cleanup(struct lldpd_port *port, struct lldpd_custom *curr) |
119 | 0 | { |
120 | 0 | struct lldpd_custom *custom, *custom_next; |
121 | 0 | for (custom = TAILQ_FIRST(&port->p_custom_list); custom != NULL; |
122 | 0 | custom = custom_next) { |
123 | 0 | custom_next = TAILQ_NEXT(custom, next); |
124 | 0 | if (!memcmp(curr->oui, custom->oui, sizeof(curr->oui)) && |
125 | 0 | curr->subtype == custom->subtype) { |
126 | 0 | TAILQ_REMOVE(&port->p_custom_list, custom, next); |
127 | 0 | free(custom->oui_info); |
128 | 0 | free(custom); |
129 | 0 | } |
130 | 0 | } |
131 | 0 | } |
132 | | |
133 | | void |
134 | | lldpd_custom_list_cleanup(struct lldpd_port *port) |
135 | 2.27k | { |
136 | 2.27k | struct lldpd_custom *custom, *custom_next; |
137 | 3.60k | for (custom = TAILQ_FIRST(&port->p_custom_list); custom != NULL; |
138 | 2.27k | custom = custom_next) { |
139 | 1.32k | custom_next = TAILQ_NEXT(custom, next); |
140 | 1.32k | free(custom->oui_info); |
141 | 1.32k | free(custom); |
142 | 1.32k | } |
143 | 2.27k | TAILQ_INIT(&port->p_custom_list); |
144 | 2.27k | } |
145 | | #endif |
146 | | |
147 | | /* Cleanup a remote port. The before last argument, `expire` is a function that |
148 | | * should be called when a remote port is removed. If the last argument is 1, |
149 | | * all remote ports are removed. |
150 | | */ |
151 | | void |
152 | | lldpd_remote_cleanup(struct lldpd_hardware *hardware, |
153 | | void (*expire)(struct lldpd_hardware *, struct lldpd_port *), int all) |
154 | 0 | { |
155 | 0 | struct lldpd_port *port, *port_next; |
156 | 0 | int del; |
157 | 0 | time_t now = time(NULL); |
158 | |
|
159 | 0 | log_debug("alloc", "cleanup remote port on %s", hardware->h_ifname); |
160 | 0 | for (port = TAILQ_FIRST(&hardware->h_rports); port != NULL; port = port_next) { |
161 | 0 | port_next = TAILQ_NEXT(port, p_entries); |
162 | 0 | del = all; |
163 | 0 | if (!all && expire && (now >= port->p_lastupdate + port->p_ttl)) { |
164 | 0 | if (port->p_ttl > 0) hardware->h_ageout_cnt++; |
165 | 0 | del = 1; |
166 | 0 | } |
167 | 0 | if (del) { |
168 | 0 | if (expire) expire(hardware, port); |
169 | | /* This TAILQ_REMOVE is dangerous. It should not be |
170 | | * called while in liblldpctl because we don't have a |
171 | | * real list. It is only needed to be called when we |
172 | | * don't delete the entire list. */ |
173 | 0 | if (!all) TAILQ_REMOVE(&hardware->h_rports, port, p_entries); |
174 | |
|
175 | 0 | hardware->h_delete_cnt++; |
176 | | /* Register last removal to be able to report |
177 | | * lldpStatsRemTablesLastChangeTime */ |
178 | 0 | hardware->h_lport.p_lastremove = time(NULL); |
179 | 0 | lldpd_port_cleanup(port, 1); |
180 | 0 | free(port); |
181 | 0 | } |
182 | 0 | } |
183 | 0 | if (all) TAILQ_INIT(&hardware->h_rports); |
184 | 0 | } |
185 | | |
186 | | /* If `all' is true, clear all information, including information that |
187 | | are not refreshed periodically. Port should be freed manually. */ |
188 | | void |
189 | | lldpd_port_cleanup(struct lldpd_port *port, int all) |
190 | 2.27k | { |
191 | 2.27k | #ifdef ENABLE_LLDPMED |
192 | 2.27k | int i; |
193 | 2.27k | if (all) |
194 | 9.09k | for (i = 0; i < LLDP_MED_LOCFORMAT_LAST; i++) |
195 | 6.82k | free(port->p_med_location[i].data); |
196 | 2.27k | #endif |
197 | 2.27k | #ifdef ENABLE_DOT1 |
198 | 2.27k | lldpd_vlan_cleanup(port); |
199 | 2.27k | lldpd_ppvid_cleanup(port); |
200 | 2.27k | lldpd_pi_cleanup(port); |
201 | 2.27k | #endif |
202 | | /* will set these to NULL so we don't free wrong memory */ |
203 | | |
204 | 2.27k | if (all) { |
205 | 2.27k | free(port->p_id); |
206 | 2.27k | port->p_id = NULL; |
207 | 2.27k | free(port->p_descr); |
208 | 2.27k | port->p_descr = NULL; |
209 | 2.27k | free(port->p_lastframe); |
210 | 2.27k | if (port->p_chassis) { /* chassis may not have been attributed, yet */ |
211 | 0 | port->p_chassis->c_refcount--; |
212 | 0 | port->p_chassis = NULL; |
213 | 0 | } |
214 | 2.27k | #ifdef ENABLE_CUSTOM |
215 | 2.27k | lldpd_custom_list_cleanup(port); |
216 | 2.27k | #endif |
217 | 2.27k | } |
218 | 2.27k | } |
219 | | |
220 | | void |
221 | | lldpd_config_cleanup(struct lldpd_config *config) |
222 | 0 | { |
223 | 0 | log_debug("alloc", "general configuration cleanup"); |
224 | 0 | free(config->c_mgmt_pattern); |
225 | 0 | free(config->c_cid_pattern); |
226 | 0 | free(config->c_cid_string); |
227 | 0 | free(config->c_iface_pattern); |
228 | 0 | free(config->c_perm_ifaces); |
229 | 0 | free(config->c_hostname); |
230 | 0 | free(config->c_platform); |
231 | 0 | free(config->c_description); |
232 | 0 | } |