switch (vp->magic) {
case LLDP_SNMP_TXINTERVAL:
- long_ret = scfg->g_delay;
+ long_ret = scfg->g_config.c_delay;
return (u_char *)&long_ret;
case LLDP_SNMP_TXMULTIPLIER:
- long_ret = LOCAL_CHASSIS(scfg)->c_ttl / scfg->g_delay;
+ long_ret = LOCAL_CHASSIS(scfg)->c_ttl / scfg->g_config.c_delay;
return (u_char *)&long_ret;
case LLDP_SNMP_REINITDELAY:
long_ret = 1;
goto toobig;
/* Platform */
- if (global && global->g_platform_override) platform = global->g_platform_override;
+ if (global && global->g_config.c_platform) platform = global->g_config.c_platform;
if (!(
POKE_START_CDP_TLV(CDP_TLV_PLATFORM) &&
POKE_BYTES(platform, strlen(platform)) &&
levent_update_and_send(evutil_socket_t fd, short what, void *arg)
{
struct lldpd *cfg = arg;
- struct timeval tv = {cfg->g_delay, 0};
+ struct timeval tv = {cfg->g_config.c_delay, 0};
(void)fd; (void)what;
lldpd_loop(cfg);
event_add(cfg->g_main_loop, &tv);
{
struct ifaddrs *ifa;
- if (!cfg->g_interfaces)
+ if (!cfg->g_config.c_iface_pattern)
return;
for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
if (ifa->ifa_flags == 0) continue; /* Already handled by someone else */
- if (!pattern_match(ifa->ifa_name, cfg->g_interfaces, 0)) {
+ if (!pattern_match(ifa->ifa_name, cfg->g_config.c_iface_pattern, 0)) {
/* This interface was not found. We flag it. */
LLOG_DEBUG("blacklist %s", ifa->ifa_name);
ifa->ifa_flags = 0;
lldpd_chassis_mgmt_cleanup(LOCAL_CHASSIS(cfg));
/* Is the pattern provided all negative? */
- if (cfg->g_mgmt_pattern == NULL) allnegative = 1;
- else if (cfg->g_mgmt_pattern[0] == '!') {
+ if (cfg->g_config.c_mgmt_pattern == NULL) allnegative = 1;
+ else if (cfg->g_config.c_mgmt_pattern[0] == '!') {
/* If each comma is followed by '!', its an all
negative pattern */
- char *sep = cfg->g_mgmt_pattern;
+ char *sep = cfg->g_config.c_mgmt_pattern;
while ((sep = strchr(sep, ',')) &&
(*(++sep) == '!'));
if (sep == NULL) allnegative = 1;
LLOG_WARN("unable to convert IP address to a string");
continue;
}
- if (cfg->g_mgmt_pattern == NULL ||
- pattern_match(addrstrbuf, cfg->g_mgmt_pattern, allnegative)) {
+ if (cfg->g_config.c_mgmt_pattern == NULL ||
+ pattern_match(addrstrbuf, cfg->g_config.c_mgmt_pattern, allnegative)) {
mgmt = lldpd_alloc_mgmt(af, sin_addr_ptr, sin_addr_size,
if_nametoindex(ifa->ifa_name));
if (mgmt == NULL) {
for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
if (ifa->ifa_flags) continue;
- if (cfg->g_cid_pattern &&
- !pattern_match(ifa->ifa_name, cfg->g_cid_pattern, 0)) continue;
+ if (cfg->g_config.c_cid_pattern &&
+ !pattern_match(ifa->ifa_name, cfg->g_config.c_cid_pattern, 0)) continue;
if ((hardware = lldpd_get_hardware(cfg,
ifa->ifa_name,
#ifdef ENABLE_LLDPMED
if (LOCAL_CHASSIS(cfg)->c_med_cap_available) {
hardware->h_lport.p_med_cap_enabled = LLDP_MED_CAP_CAP;
- if (!cfg->g_noinventory)
+ if (!cfg->g_config.c_noinventory)
hardware->h_lport.p_med_cap_enabled |= LLDP_MED_CAP_IV;
}
#endif
if ((protocols[i] == min) && !found) {
/* If we need a tie breaker, we take
the first protocol only */
- if (cfg->g_smart & mask &
+ if (cfg->g_config.c_smart & mask &
(SMART_OUTGOING_ONE_PROTO | SMART_INCOMING_ONE_PROTO))
found = 1;
protocols[i] = 1;
}
/* If we want only one neighbor, we take the first one */
- if (cfg->g_smart & mask &
+ if (cfg->g_config.c_smart & mask &
(SMART_OUTGOING_ONE_NEIGH | SMART_INCOMING_ONE_NEIGH)) {
found = 0;
TAILQ_FOREACH(port, &hardware->h_rports, p_entries) {
{
struct lldpd_hardware *hardware;
- if (!cfg->g_smart)
+ if (!cfg->g_config.c_smart)
return;
TAILQ_FOREACH(hardware, &cfg->g_hardware, h_entries) {
- if (cfg->g_smart & SMART_INCOMING_FILTER)
+ if (cfg->g_config.c_smart & SMART_INCOMING_FILTER)
lldpd_hide_ports(cfg, hardware, SMART_INCOMING);
- if (cfg->g_smart & SMART_OUTGOING_FILTER)
+ if (cfg->g_config.c_smart & SMART_OUTGOING_FILTER)
lldpd_hide_ports(cfg, hardware, SMART_OUTGOING);
}
}
int i, sent;
cfg->g_lastsent = time(NULL);
- if (cfg->g_receiveonly) return;
+ if (cfg->g_config.c_receiveonly) return;
TAILQ_FOREACH(hardware, &cfg->g_hardware, h_entries) {
/* Ignore if interface is down */
if ((hardware->h_flags & IFF_RUNNING) == 0)
free(LOCAL_CHASSIS(cfg)->c_descr);
if ((LOCAL_CHASSIS(cfg)->c_name = strdup(hp)) == NULL)
fatal(NULL);
- if (cfg->g_descr_override) {
+ if (cfg->g_config.c_description) {
if (asprintf(&LOCAL_CHASSIS(cfg)->c_descr, "%s",
- cfg->g_descr_override) == -1)
+ cfg->g_config.c_description) == -1)
fatal("failed to set full system description");
} else {
- if (cfg->g_advertise_version) {
+ if (cfg->g_config.c_advertise_version) {
if (asprintf(&LOCAL_CHASSIS(cfg)->c_descr, "%s %s %s %s %s",
cfg->g_lsb_release?cfg->g_lsb_release:"",
un.sysname, un.release, un.version, un.machine)
LOCAL_CHASSIS(cfg)->c_cap_enabled |= LLDP_CAP_TELEPHONE;
lldpd_med(LOCAL_CHASSIS(cfg));
free(LOCAL_CHASSIS(cfg)->c_med_sw);
- if (cfg->g_advertise_version)
+ if (cfg->g_config.c_advertise_version)
LOCAL_CHASSIS(cfg)->c_med_sw = strdup(un.release);
else
LOCAL_CHASSIS(cfg)->c_med_sw = strdup("Unknown");
fatal(NULL);
cfg->g_ctl = ctl;
- cfg->g_mgmt_pattern = mgmtp;
- cfg->g_cid_pattern = cidp;
- cfg->g_interfaces = interfaces;
- cfg->g_smart = smart;
- cfg->g_receiveonly = receiveonly;
+ cfg->g_config.c_mgmt_pattern = mgmtp;
+ cfg->g_config.c_cid_pattern = cidp;
+ cfg->g_config.c_iface_pattern = interfaces;
+ cfg->g_config.c_smart = smart;
+ cfg->g_config.c_receiveonly = receiveonly;
#ifdef USE_SNMP
cfg->g_snmp = snmp;
cfg->g_snmp_agentx = agentx;
/* Get ioctl socket */
if ((cfg->g_sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
fatal("failed to get ioctl socket");
- cfg->g_delay = LLDPD_TX_DELAY;
+ cfg->g_config.c_delay = LLDPD_TX_DELAY;
/* Description */
- if (!(cfg->g_advertise_version = advertise_version) && lsb_release)
+ if (!(cfg->g_config.c_advertise_version = advertise_version) && lsb_release)
/* Remove the \n */
lsb_release[strlen(lsb_release) - 1] = '\0';
cfg->g_lsb_release = lsb_release;
if (descr_override)
- cfg->g_descr_override = descr_override;
+ cfg->g_config.c_description = descr_override;
if (platform_override)
- cfg->g_platform_override = platform_override;
+ cfg->g_config.c_platform = platform_override;
/* Set system capabilities */
if ((lchassis = (struct lldpd_chassis*)
lchassis->c_med_cap_available = LLDP_MED_CAP_CAP |
LLDP_MED_CAP_IV | LLDP_MED_CAP_LOCATION |
LLDP_MED_CAP_POLICY | LLDP_MED_CAP_MDI_PSE | LLDP_MED_CAP_MDI_PD;
- cfg->g_noinventory = noinventory;
+ cfg->g_config.c_noinventory = noinventory;
} else
- cfg->g_noinventory = 1;
+ cfg->g_config.c_noinventory = 1;
#endif
/* Set TTL */
u_int8_t mac[ETH_ALEN]; /* Destination MAC address used by this protocol */
};
-/* Smart mode / Hide mode */
-#define SMART_INCOMING_FILTER (1<<0) /* Incoming filtering enabled */
-#define SMART_INCOMING_ONE_PROTO (1<<1) /* On reception, keep only one proto */
-#define SMART_INCOMING_ONE_NEIGH (1<<2) /* On reception, keep only one 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)
#define SMART_HIDDEN(port) (port->p_hidden_in)
struct lldpd {
int g_sock;
- int g_delay;
-
struct event_base *g_base;
#ifdef USE_SNMP
#endif
+ struct lldpd_config g_config;
+
struct protocol *g_protocols;
time_t g_lastsent;
int g_lastrid;
- int g_smart;
- int g_receiveonly;
struct event *g_main_loop;
#ifdef USE_SNMP
int g_snmp;
int g_ctl;
struct event *g_ctl_event;
- char *g_mgmt_pattern;
- char *g_cid_pattern;
- char *g_interfaces;
-
- char *g_descr_override;
- char *g_platform_override;
char *g_lsb_release;
- int g_advertise_version;
-#ifdef ENABLE_LLDPMED
- int g_noinventory;
-#endif
#define LOCAL_CHASSIS(cfg) ((struct lldpd_chassis *)(TAILQ_FIRST(&cfg->g_chassis)))
TAILQ_HEAD(, lldpd_chassis) g_chassis;
}
}
}
+
+void
+lldpd_config_cleanup(struct lldpd_config *config)
+{
+ free(config->c_mgmt_pattern);
+ free(config->c_cid_pattern);
+ free(config->c_iface_pattern);
+ free(config->c_platform);
+ free(config->c_description);
+}
#endif
MARSHAL_END;
+/* Smart mode / Hide mode */
+#define SMART_INCOMING_FILTER (1<<0) /* Incoming filtering enabled */
+#define SMART_INCOMING_ONE_PROTO (1<<1) /* On reception, keep only one proto */
+#define SMART_INCOMING_ONE_NEIGH (1<<2) /* On reception, keep only one 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_delay; /* Transmit delay */
+ int c_smart; /* Bitmask for smart configuration (see SMART_*) */
+ int c_receiveonly; /* Receive only mode */
+
+ 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 */
+ int c_advertise_version; /* Should the precise version be advertised? */
+
+#ifdef ENABLE_LLDPMED
+ int c_noinventory; /* Don't send inventory with LLDP-MED */
+#endif
+};
+MARSHAL_BEGIN(lldpd_config)
+MARSHAL_STR(lldpd_config, c_mgmt_pattern)
+MARSHAL_STR(lldpd_config, c_cid_pattern)
+MARSHAL_STR(lldpd_config, c_iface_pattern)
+MARSHAL_STR(lldpd_config, c_platform)
+MARSHAL_STR(lldpd_config, c_description)
+MARSHAL_END;
+
struct lldpd_frame {
int size;
unsigned char frame[1];
void lldpd_remote_cleanup(struct lldpd_hardware *,
void(*expire)(struct lldpd_hardware *, struct lldpd_port *));
void lldpd_port_cleanup(struct lldpd_port *, int);
+void lldpd_config_cleanup(struct lldpd_config *);
#ifdef ENABLE_DOT1
void lldpd_ppvid_cleanup(struct lldpd_port *);
void lldpd_vlan_cleanup(struct lldpd_port *);