void lldpd_chassis_cleanup(struct lldpd_chassis *chassis, int all) { lldpd_chassis_mgmt_cleanup(chassis); log_debug("alloc", "cleanup chassis %s", chassis->c_name ? chassis->c_name : "(unknwon)"); #ifdef ENABLE_LLDPMED free(chassis->c_med_hw); free(chassis->c_med_sw); free(chassis->c_med_fw); free(chassis->c_med_sn); free(chassis->c_med_manuf); free(chassis->c_med_model); free(chassis->c_med_asset); #endif free(chassis->c_id); free(chassis->c_name); free(chassis->c_descr); if (all) free(chassis); }
/* Find a management address in all available interfaces, even those that were already handled. This is a special interface handler because it does not really handle interface related information (management address is attached to the local chassis). */ void interfaces_helper_mgmt(struct lldpd *cfg, struct interfaces_address_list *addrs) { struct interfaces_address *addr; char addrstrbuf[INET6_ADDRSTRLEN]; struct lldpd_mgmt *mgmt; void *sin_addr_ptr; size_t sin_addr_size; int af; int allnegative = 0; lldpd_chassis_mgmt_cleanup(LOCAL_CHASSIS(cfg)); /* Is the pattern provided all negative? */ 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_config.c_mgmt_pattern; while ((sep = strchr(sep, ',')) && (*(++sep) == '!')); if (sep == NULL) allnegative = 1; } /* Find management addresses */ for (af = LLDPD_AF_UNSPEC + 1; af != LLDPD_AF_LAST; af++) { /* We only take one of each address family, unless a pattern is provided and is not all negative. For example !*:*,!10.* will only blacklist addresses. We will pick the first IPv4 address not matching 10.*. */ TAILQ_FOREACH(addr, addrs, next) { if (addr->address.ss_family != lldpd_af(af)) continue; switch (af) { case LLDPD_AF_IPV4: sin_addr_ptr = &((struct sockaddr_in *)&addr->address)->sin_addr; sin_addr_size = sizeof(struct in_addr); if (!IN_IS_ADDR_GLOBAL((struct in_addr *)sin_addr_ptr)) continue; break; case LLDPD_AF_IPV6: sin_addr_ptr = &((struct sockaddr_in6 *)&addr->address)->sin6_addr; sin_addr_size = sizeof(struct in6_addr); if (!IN6_IS_ADDR_GLOBAL((struct in6_addr *)sin_addr_ptr)) continue; break; default: assert(0); continue; } if (inet_ntop(lldpd_af(af), sin_addr_ptr, addrstrbuf, sizeof(addrstrbuf)) == NULL) { log_warn("interfaces", "unable to convert IP address to a string"); continue; } 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, addr->index); if (mgmt == NULL) { assert(errno == ENOMEM); /* anything else is a bug */ log_warn("interfaces", "out of memory error"); return; } log_debug("interfaces", "add management address %s", addrstrbuf); TAILQ_INSERT_TAIL(&LOCAL_CHASSIS(cfg)->c_mgmt, mgmt, m_entries); /* Don't take additional address if the pattern is all negative. */ if (allnegative) break; } } } }