summaryrefslogtreecommitdiff
path: root/lib/lldp/lldpd-structs.h
blob: 6a3ffb8d33f00760491322c7c5a6b56e6080d51d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
/* -*- mode: c; c-file-style: "openbsd" -*- */
/*
 * Copyright (c) 2015 Nicira, Inc.
 * Copyright (c) 2008 Vincent Bernat <bernat@luffy.cx>
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#ifndef _LLDPD_STRUCTS_H
#define _LLDPD_STRUCTS_H

#include <net/if.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include "aa-structs.h"
#include "lldp-const.h"
#include "packets.h"

enum {
    LLDPD_AF_UNSPEC = 0,
    LLDPD_AF_IPV4,
    LLDPD_AF_IPV6,
    LLDPD_AF_LAST
};

inline static int
lldpd_af(int af)
{
    switch (af) {
    case LLDPD_AF_IPV4: return AF_INET;
    case LLDPD_AF_IPV6: return AF_INET6;
    case LLDPD_AF_LAST: return AF_MAX;
    default: return AF_UNSPEC;
    }
}

#define LLDPD_MGMT_MAXADDRSIZE 16 /* sizeof(struct in6_addr) */
struct lldpd_mgmt {
    struct ovs_list m_entries;
    int             m_family;
    union {
        struct in_addr  inet;
        struct in6_addr inet6;
        u_int8_t        octets[LLDPD_MGMT_MAXADDRSIZE];
    } m_addr;
    size_t    m_addrsize;
    u_int32_t m_iface;
};

struct lldpd_chassis {
    struct ovs_list list;
    u_int16_t       c_refcount;   /* Reference count by ports */
    u_int16_t       c_index;      /* Monotonic index */
    u_int8_t        c_protocol;   /* Protocol used to get this chassis */
    u_int8_t        c_id_subtype;
    uint8_t         *c_id;        /* Typically an Ethernet address. */
    int             c_id_len;
    char            *c_name;
    char            *c_descr;

    u_int16_t       c_cap_available;
    u_int16_t       c_cap_enabled;

    u_int16_t       c_ttl;

    struct ovs_list c_mgmt;     /* Contains "struct lldp_mgmt"s. */
};
/* WARNING: any change to this structure should also be reflected into
   `lldpd_copy_chassis()` which is not using marshaling. */

struct lldpd_port {
    struct ovs_list      p_entries;
    struct lldpd_chassis *p_chassis; /* Attached chassis */
    time_t               p_lastchange; /* Time of last change of values */
    time_t               p_lastupdate; /* Time of last update received */
    struct lldpd_frame   *p_lastframe; /* Frame received during last update */
    u_int8_t             p_protocol;   /* Protocol used to get this port */
    u_int8_t             p_hidden_in:1; /* Considered hidden for reception */
    u_int8_t             p_hidden_out:1; /* Considered hidden for emission */
    /* Important: all fields that should be ignored to check if a port has
     * been changed should be before p_id_subtype. Check
     * `lldpd_reset_timer()`.
     */
    u_int8_t             p_id_subtype;
    char                 *p_id;
    int                  p_id_len;
    char                 *p_descr;
    u_int16_t            p_mfs;
    struct lldpd_aa_element_tlv        p_element;
    struct ovs_list p_isid_vlan_maps; /* Contains "struct lldpd_aa_isid_vlan_maps_tlv"s. */
};

/* Smart mode / Hide mode */
#define SMART_INCOMING_FILTER     (1<<0) /* Incoming filtering enabled */
#define SMART_INCOMING_ONE_PROTO  (1<<1) /* On reception, keep only 1 proto */
#define SMART_INCOMING_ONE_NEIGH  (1<<2) /* On recep., keep only 1 neighbor */
#define SMART_OUTGOING_FILTER     (1<<3) /* Outgoing filtering enabled */
#define SMART_OUTGOING_ONE_PROTO  (1<<4) /* On emission, keep only one proto */
#define SMART_OUTGOING_ONE_NEIGH  (1<<5) /* On emission, consider only
                                            one neighbor */
#define SMART_INCOMING (SMART_INCOMING_FILTER | \
             SMART_INCOMING_ONE_PROTO |         \
             SMART_INCOMING_ONE_NEIGH)
#define SMART_OUTGOING (SMART_OUTGOING_FILTER | \
            SMART_OUTGOING_ONE_PROTO |          \
            SMART_OUTGOING_ONE_NEIGH)

struct lldpd_config {
    int c_paused;           /* lldpd is paused */
    int c_tx_interval;      /* Transmit interval */
    int c_smart;            /* Bitmask for smart configuration (see SMART_*) */
    int c_receiveonly;      /* Receive only mode */
    int c_max_neighbors;    /* Maximum number of neighbors (per protocol) */

    char *c_mgmt_pattern;   /* Pattern to match a management address */
    char *c_cid_pattern;    /* Pattern to match interfaces to use for chassis
                             * ID */
    char *c_iface_pattern;  /* Pattern to match interfaces to use */

    char *c_platform;       /* Override platform description (for CDP) */
    char *c_description;    /* Override chassis description */
    char *c_hostname;       /* Override system name */
    int c_advertise_version; /* Should the precise version be advertised? */
    int c_set_ifdescr;      /* Set interface description */
    int c_promisc;          /* Interfaces should be in promiscuous mode */
    int c_tx_hold;          /* Transmit hold */
    int c_bond_slave_src_mac_type; /* Src mac type in lldp frames over bond
                                    * slaves */
    int c_lldp_portid_type; /* The PortID type */
};

struct lldpd_frame {
    int size;
    unsigned char frame[];
};

struct lldpd_hardware;
struct lldpd;
struct lldpd_ops {
    int (*send)(struct lldpd *,
                struct lldpd_hardware *,
                char *, size_t); /* Function to send a frame */
    int (*recv)(struct lldpd *,
                struct lldpd_hardware *,
                int, char *, size_t); /* Function to receive a frame */
    int (*cleanup)(struct lldpd *, struct lldpd_hardware *); /* Cleanup */
};

/* An interface is uniquely identified by h_ifindex, h_ifname and h_ops. This
 * means if an interface becomes enslaved, it will be considered as a new
 * interface. The same applies for renaming and we include the index in case of
 * renaming to an existing interface.
 */
struct lldpd_hardware {
    struct ovs_list   h_entries;

    struct lldpd      *h_cfg;     /* Pointer to main configuration */
    void              *h_recv;    /* FD for reception */
    int               h_sendfd;   /* FD for sending, only used by h_ops */
    int               h_mangle;   /* 1 if we have to mangle the MAC address */
    struct lldpd_ops  *h_ops;     /* Hardware-dependent functions */
    void              *h_data;    /* Hardware-dependent data */
    void              *h_timer;   /* Timer for this port */

    int               h_mtu;
    int               h_flags;    /* Packets will be sent only
                                   * if IFF_RUNNING. Will be
                                   * removed if this is left
                                   * to 0. */
    int               h_ifindex;  /* Interface index, used by SNMP */
    char              h_ifname[IFNAMSIZ]; /* Should be unique */
    struct eth_addr   h_lladdr;

    u_int64_t         h_tx_cnt;
    u_int64_t         h_rx_cnt;
    u_int64_t         h_rx_discarded_cnt;
    u_int64_t         h_rx_unrecognized_cnt;
    u_int64_t         h_ageout_cnt;
    u_int64_t         h_insert_cnt;
    u_int64_t         h_delete_cnt;
    u_int64_t         h_drop_cnt;

    u_int16_t         h_lport_cksum; /* Checksum on local port to see if there
                                      * is a change
                                      */
    struct lldpd_port h_lport;  /* Port attached to this hardware port */
    struct ovs_list h_rports;   /* Contains "struct lldp_port"s. */
};

struct lldpd_interface;
struct lldpd_interface_list;

struct lldpd_neighbor_change {
    char              *ifname;
#define NEIGHBOR_CHANGE_DELETED -1
#define NEIGHBOR_CHANGE_ADDED    1
#define NEIGHBOR_CHANGE_UPDATED  0
    int               state;
    struct lldpd_port *neighbor;
};

/* Cleanup functions */
void lldpd_chassis_mgmt_cleanup(struct lldpd_chassis *);
void lldpd_chassis_cleanup(struct lldpd_chassis *, bool all);
void lldpd_remote_cleanup(struct lldpd_hardware *,
    void (*expire)(struct lldpd_hardware *, struct lldpd_port *), bool all);
void lldpd_port_cleanup(struct lldpd_port *, bool all);
void lldpd_config_cleanup(struct lldpd_config *);

#endif