]> git.ipfire.org Git - thirdparty/lldpd.git/blob - src/lldpd-structs.h
lldpd: add proper insert/delete/ageout counters
[thirdparty/lldpd.git] / src / lldpd-structs.h
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 #ifndef _LLDPD_STRUCTS_H
19 #define _LLDPD_STRUCTS_H
20
21 #if HAVE_CONFIG_H
22 # include <config.h>
23 #endif
24
25 #include <sys/types.h>
26 #include <sys/socket.h>
27 #ifndef INCLUDE_LINUX_IF_H
28 # include <net/if.h>
29 #else
30 # include <arpa/inet.h>
31 # include <linux/if.h>
32 #endif
33 #include <net/ethernet.h>
34 #include <netinet/in.h>
35 #include <sys/queue.h>
36
37 #include "compat/compat.h"
38 #include "marshal.h"
39 #include "lldp-const.h"
40
41 #ifdef ENABLE_DOT1
42 struct lldpd_ppvid {
43 TAILQ_ENTRY(lldpd_ppvid) p_entries;
44 u_int8_t p_cap_status;
45 u_int16_t p_ppvid;
46 };
47 MARSHAL_BEGIN(lldpd_ppvid)
48 MARSHAL_TQE(lldpd_ppvid, p_entries)
49 MARSHAL_END;
50
51 struct lldpd_vlan {
52 TAILQ_ENTRY(lldpd_vlan) v_entries;
53 char *v_name;
54 u_int16_t v_vid;
55 };
56 MARSHAL_BEGIN(lldpd_vlan)
57 MARSHAL_TQE(lldpd_vlan, v_entries)
58 MARSHAL_STR(lldpd_vlan, v_name)
59 MARSHAL_END;
60
61 struct lldpd_pi {
62 TAILQ_ENTRY(lldpd_pi) p_entries;
63 char *p_pi;
64 int p_pi_len;
65 };
66 MARSHAL_BEGIN(lldpd_pi)
67 MARSHAL_TQE(lldpd_pi, p_entries)
68 MARSHAL_FSTR(lldpd_pi, p_pi, p_pi_len)
69 MARSHAL_END;
70 #endif
71
72 #ifdef ENABLE_LLDPMED
73 struct lldpd_med_policy {
74 u_int8_t index; /* Not used. */
75 u_int8_t type;
76 u_int8_t unknown;
77 u_int8_t tagged;
78 u_int16_t vid;
79 u_int8_t priority;
80 u_int8_t dscp;
81 };
82 MARSHAL(lldpd_med_policy);
83
84 struct lldpd_med_loc {
85 u_int8_t index; /* Not used. */
86 u_int8_t format;
87 char *data;
88 int data_len;
89 };
90 MARSHAL_BEGIN(lldpd_med_loc)
91 MARSHAL_FSTR(lldpd_med_loc, data, data_len)
92 MARSHAL_END;
93
94 struct lldpd_med_power {
95 u_int8_t devicetype; /* PD or PSE */
96 u_int8_t source;
97 u_int8_t priority;
98 u_int16_t val;
99 };
100 MARSHAL(lldpd_med_power);
101 #endif
102
103 #ifdef ENABLE_DOT3
104 struct lldpd_dot3_macphy {
105 u_int8_t autoneg_support;
106 u_int8_t autoneg_enabled;
107 u_int16_t autoneg_advertised;
108 u_int16_t mau_type;
109 };
110
111 struct lldpd_dot3_power {
112 u_int8_t devicetype;
113 u_int8_t supported;
114 u_int8_t enabled;
115 u_int8_t paircontrol;
116 u_int8_t pairs;
117 u_int8_t class;
118 u_int8_t powertype; /* If set to LLDP_DOT3_POWER_8023AT_OFF,
119 following fields have no meaning */
120 u_int8_t source;
121 u_int8_t priority;
122 u_int16_t requested;
123 u_int16_t allocated;
124 };
125 MARSHAL(lldpd_dot3_power);
126 #endif
127
128 enum {
129 LLDPD_AF_UNSPEC = 0,
130 LLDPD_AF_IPV4,
131 LLDPD_AF_IPV6,
132 LLDPD_AF_LAST
133 };
134
135 inline static int
136 lldpd_af(int af)
137 {
138 switch (af) {
139 case LLDPD_AF_IPV4: return AF_INET;
140 case LLDPD_AF_IPV6: return AF_INET6;
141 case LLDPD_AF_LAST: return AF_MAX;
142 default: return AF_UNSPEC;
143 }
144 }
145
146 #define LLDPD_MGMT_MAXADDRSIZE 16 /* sizeof(struct in6_addr) */
147 struct lldpd_mgmt {
148 TAILQ_ENTRY(lldpd_mgmt) m_entries;
149 int m_family;
150 union {
151 struct in_addr inet;
152 struct in6_addr inet6;
153 u_int8_t octets[LLDPD_MGMT_MAXADDRSIZE];
154 } m_addr;
155 size_t m_addrsize;
156 u_int32_t m_iface;
157 };
158 MARSHAL_BEGIN(lldpd_mgmt)
159 MARSHAL_TQE(lldpd_mgmt, m_entries)
160 MARSHAL_END;
161
162 struct lldpd_chassis {
163 TAILQ_ENTRY(lldpd_chassis) c_entries;
164 u_int16_t c_refcount; /* Reference count by ports */
165 u_int16_t c_index; /* Monotonic index */
166 u_int8_t c_protocol; /* Protocol used to get this chassis */
167 u_int8_t c_id_subtype;
168 char *c_id;
169 int c_id_len;
170 char *c_name;
171 char *c_descr;
172
173 u_int16_t c_cap_available;
174 u_int16_t c_cap_enabled;
175
176 u_int16_t c_ttl;
177
178 TAILQ_HEAD(, lldpd_mgmt) c_mgmt;
179
180 #ifdef ENABLE_LLDPMED
181 u_int16_t c_med_cap_available;
182 u_int8_t c_med_type;
183 char *c_med_hw;
184 char *c_med_fw;
185 char *c_med_sw;
186 char *c_med_sn;
187 char *c_med_manuf;
188 char *c_med_model;
189 char *c_med_asset;
190 #endif
191
192 };
193 /* WARNING: any change to this structure should also be reflected into
194 `lldpd_copy_chassis()` which is not using marshaling. */
195 MARSHAL_BEGIN(lldpd_chassis)
196 MARSHAL_IGNORE(lldpd_chassis, c_entries.tqe_next)
197 MARSHAL_IGNORE(lldpd_chassis, c_entries.tqe_prev)
198 MARSHAL_FSTR(lldpd_chassis, c_id, c_id_len)
199 MARSHAL_STR(lldpd_chassis, c_name)
200 MARSHAL_STR(lldpd_chassis, c_descr)
201 MARSHAL_SUBTQ(lldpd_chassis, lldpd_mgmt, c_mgmt)
202 #ifdef ENABLE_LLDPMED
203 MARSHAL_STR(lldpd_chassis, c_med_hw)
204 MARSHAL_STR(lldpd_chassis, c_med_fw)
205 MARSHAL_STR(lldpd_chassis, c_med_sw)
206 MARSHAL_STR(lldpd_chassis, c_med_sn)
207 MARSHAL_STR(lldpd_chassis, c_med_manuf)
208 MARSHAL_STR(lldpd_chassis, c_med_model)
209 MARSHAL_STR(lldpd_chassis, c_med_asset)
210 #endif
211 MARSHAL_END;
212
213
214 struct lldpd_port {
215 TAILQ_ENTRY(lldpd_port) p_entries;
216 struct lldpd_chassis *p_chassis; /* Attached chassis */
217 time_t p_lastchange; /* Time of last change of values */
218 time_t p_lastupdate; /* Time of last update received */
219 struct lldpd_frame *p_lastframe; /* Frame received during last update */
220 u_int8_t p_protocol; /* Protocol used to get this port */
221 u_int8_t p_id_subtype;
222 char *p_id;
223 int p_id_len;
224 char *p_descr;
225 u_int16_t p_mfs;
226 u_int8_t p_hidden_in:1; /* Considered as hidden for reception */
227 u_int8_t p_hidden_out:2; /* Considered as hidden for emission */
228
229 #ifdef ENABLE_DOT3
230 /* Dot3 stuff */
231 u_int32_t p_aggregid;
232 struct lldpd_dot3_macphy p_macphy;
233 struct lldpd_dot3_power p_power;
234 #endif
235
236 #ifdef ENABLE_LLDPMED
237 u_int16_t p_med_cap_enabled;
238 struct lldpd_med_policy p_med_policy[LLDP_MED_APPTYPE_LAST];
239 struct lldpd_med_loc p_med_location[LLDP_MED_LOCFORMAT_LAST];
240 struct lldpd_med_power p_med_power;
241 #endif
242
243 #ifdef ENABLE_DOT1
244 u_int16_t p_pvid;
245 TAILQ_HEAD(, lldpd_vlan) p_vlans;
246 TAILQ_HEAD(, lldpd_ppvid) p_ppvids;
247 TAILQ_HEAD(, lldpd_pi) p_pids;
248 #endif
249 };
250 MARSHAL_BEGIN(lldpd_port)
251 MARSHAL_TQE(lldpd_port, p_entries)
252 MARSHAL_POINTER(lldpd_port, lldpd_chassis, p_chassis)
253 MARSHAL_IGNORE(lldpd_port, p_lastframe)
254 MARSHAL_FSTR(lldpd_port, p_id, p_id_len)
255 MARSHAL_STR(lldpd_port, p_descr)
256 #ifdef ENABLE_LLDPMED
257 MARSHAL_SUBSTRUCT(lldpd_port, lldpd_med_loc, p_med_location[0])
258 MARSHAL_SUBSTRUCT(lldpd_port, lldpd_med_loc, p_med_location[1])
259 MARSHAL_SUBSTRUCT(lldpd_port, lldpd_med_loc, p_med_location[2])
260 #endif
261 #ifdef ENABLE_DOT1
262 MARSHAL_SUBTQ(lldpd_port, lldpd_vlan, p_vlans)
263 MARSHAL_SUBTQ(lldpd_port, lldpd_ppvid, p_ppvids)
264 MARSHAL_SUBTQ(lldpd_port, lldpd_pi, p_pids)
265 #endif
266 MARSHAL_END;
267
268 /* Used to modify some port related settings */
269 struct lldpd_port_set {
270 char *ifname;
271 #ifdef ENABLE_LLDPMED
272 struct lldpd_med_policy *med_policy;
273 struct lldpd_med_loc *med_location;
274 struct lldpd_med_power *med_power;
275 #endif
276 #ifdef ENABLE_DOT3
277 struct lldpd_dot3_power *dot3_power;
278 #endif
279 };
280 MARSHAL_BEGIN(lldpd_port_set)
281 MARSHAL_STR(lldpd_port_set, ifname)
282 #ifdef ENABLE_LLDPMED
283 MARSHAL_POINTER(lldpd_port_set, lldpd_med_policy, med_policy)
284 MARSHAL_POINTER(lldpd_port_set, lldpd_med_loc, med_location)
285 MARSHAL_POINTER(lldpd_port_set, lldpd_med_power, med_power)
286 #endif
287 #ifdef ENABLE_DOT3
288 MARSHAL_POINTER(lldpd_port_set, lldpd_dot3_power, dot3_power)
289 #endif
290 MARSHAL_END;
291
292 /* Smart mode / Hide mode */
293 #define SMART_INCOMING_FILTER (1<<0) /* Incoming filtering enabled */
294 #define SMART_INCOMING_ONE_PROTO (1<<1) /* On reception, keep only one proto */
295 #define SMART_INCOMING_ONE_NEIGH (1<<2) /* On reception, keep only one neighbor */
296 #define SMART_OUTGOING_FILTER (1<<3) /* Outgoing filtering enabled */
297 #define SMART_OUTGOING_ONE_PROTO (1<<4) /* On emission, keep only one proto */
298 #define SMART_OUTGOING_ONE_NEIGH (1<<5) /* On emission, consider only one neighbor */
299 #define SMART_INCOMING (SMART_INCOMING_FILTER | \
300 SMART_INCOMING_ONE_PROTO | \
301 SMART_INCOMING_ONE_NEIGH)
302 #define SMART_OUTGOING (SMART_OUTGOING_FILTER | \
303 SMART_OUTGOING_ONE_PROTO | \
304 SMART_OUTGOING_ONE_NEIGH)
305
306 struct lldpd_config {
307 int c_tx_interval; /* Transmit interval */
308 int c_smart; /* Bitmask for smart configuration (see SMART_*) */
309 int c_receiveonly; /* Receive only mode */
310
311 char *c_mgmt_pattern; /* Pattern to match a management address */
312 char *c_cid_pattern; /* Pattern to match interfaces to use for chassis ID */
313 char *c_iface_pattern; /* Pattern to match interfaces to use */
314
315 char *c_platform; /* Override platform description (for CDP) */
316 char *c_description; /* Override chassis description */
317 int c_advertise_version; /* Should the precise version be advertised? */
318
319 #ifdef ENABLE_LLDPMED
320 int c_noinventory; /* Don't send inventory with LLDP-MED */
321 #endif
322 };
323 MARSHAL_BEGIN(lldpd_config)
324 MARSHAL_STR(lldpd_config, c_mgmt_pattern)
325 MARSHAL_STR(lldpd_config, c_cid_pattern)
326 MARSHAL_STR(lldpd_config, c_iface_pattern)
327 MARSHAL_STR(lldpd_config, c_platform)
328 MARSHAL_STR(lldpd_config, c_description)
329 MARSHAL_END;
330
331 struct lldpd_frame {
332 int size;
333 unsigned char frame[1];
334 };
335
336 struct lldpd_hardware;
337 struct lldpd;
338 struct lldpd_ops {
339 int(*send)(struct lldpd *,
340 struct lldpd_hardware*,
341 char *, size_t); /* Function to send a frame */
342 int(*recv)(struct lldpd *,
343 struct lldpd_hardware*,
344 int, char *, size_t); /* Function to receive a frame */
345 int(*cleanup)(struct lldpd *, struct lldpd_hardware *); /* Cleanup function. */
346 };
347
348 /* An interface is uniquely identified by h_ifindex, h_ifname and h_ops. This
349 * means if an interface becomes enslaved, it will be considered as a new
350 * interface. The same applies for renaming and we include the index in case of
351 * renaming to an existing interface. */
352 struct lldpd_hardware {
353 TAILQ_ENTRY(lldpd_hardware) h_entries;
354
355 struct lldpd *h_cfg; /* Pointer to main configuration */
356 void *h_recv; /* FD for reception */
357 int h_sendfd; /* FD for sending, only used by h_ops */
358 struct lldpd_ops *h_ops; /* Hardware-dependent functions */
359 void *h_data; /* Hardware-dependent data */
360
361 int h_mtu;
362 int h_flags; /* Packets will be sent only
363 if IFF_RUNNING. Will be
364 removed if this is left
365 to 0. */
366 int h_ifindex; /* Interface index, used by SNMP */
367 char h_ifname[IFNAMSIZ]; /* Should be unique */
368 u_int8_t h_lladdr[ETHER_ADDR_LEN];
369
370 u_int64_t h_tx_cnt;
371 u_int64_t h_rx_cnt;
372 u_int64_t h_rx_discarded_cnt;
373 u_int64_t h_rx_unrecognized_cnt;
374 u_int64_t h_ageout_cnt;
375 u_int64_t h_insert_cnt;
376 u_int64_t h_delete_cnt;
377
378 struct lldpd_port h_lport; /* Port attached to this hardware port */
379 TAILQ_HEAD(, lldpd_port) h_rports; /* Remote ports */
380 };
381 MARSHAL_BEGIN(lldpd_hardware)
382 MARSHAL_IGNORE(lldpd_hardware, h_entries.tqe_next)
383 MARSHAL_IGNORE(lldpd_hardware, h_entries.tqe_prev)
384 MARSHAL_IGNORE(lldpd_hardware, h_ops)
385 MARSHAL_IGNORE(lldpd_hardware, h_data)
386 MARSHAL_IGNORE(lldpd_hardware, h_cfg)
387 MARSHAL_SUBSTRUCT(lldpd_hardware, lldpd_port, h_lport)
388 MARSHAL_SUBTQ(lldpd_hardware, lldpd_port, h_rports)
389 MARSHAL_END;
390
391 struct lldpd_interface {
392 TAILQ_ENTRY(lldpd_interface) next;
393 char *name;
394 };
395 MARSHAL_BEGIN(lldpd_interface)
396 MARSHAL_TQE(lldpd_interface, next)
397 MARSHAL_STR(lldpd_interface, name)
398 MARSHAL_END;
399 TAILQ_HEAD(lldpd_interface_list, lldpd_interface);
400 MARSHAL_TQ(lldpd_interface_list, lldpd_interface);
401
402 struct lldpd_neighbor_change {
403 char *ifname;
404 #define NEIGHBOR_CHANGE_DELETED -1
405 #define NEIGHBOR_CHANGE_ADDED 1
406 #define NEIGHBOR_CHANGE_UPDATED 0
407 int state;
408 struct lldpd_port *neighbor;
409 };
410 MARSHAL_BEGIN(lldpd_neighbor_change)
411 MARSHAL_STR(lldpd_neighbor_change, ifname)
412 MARSHAL_POINTER(lldpd_neighbor_change, lldpd_port, neighbor)
413 MARSHAL_END;
414
415 /* Cleanup functions */
416 void lldpd_chassis_mgmt_cleanup(struct lldpd_chassis *);
417 void lldpd_chassis_cleanup(struct lldpd_chassis *, int);
418 void lldpd_remote_cleanup(struct lldpd_hardware *,
419 void(*expire)(struct lldpd_hardware *, struct lldpd_port *));
420 void lldpd_port_cleanup(struct lldpd_port *, int);
421 void lldpd_config_cleanup(struct lldpd_config *);
422 #ifdef ENABLE_DOT1
423 void lldpd_ppvid_cleanup(struct lldpd_port *);
424 void lldpd_vlan_cleanup(struct lldpd_port *);
425 void lldpd_pi_cleanup(struct lldpd_port *);
426 #endif
427
428 #endif