static struct protocol protos[] =
{
{ LLDPD_MODE_LLDP, 1, "LLDP", 'l', lldp_send, lldp_decode, NULL,
- LLDP_MULTICAST_ADDR },
+ LLDP_ADDR_NEAREST_BRIDGE,
+ LLDP_ADDR_NEAREST_NONTPMR_BRIDGE,
+ LLDP_ADDR_NEAREST_CUSTOMER_BRIDGE },
#ifdef ENABLE_CDP
{ LLDPD_MODE_CDPV1, 0, "CDPv1", 'c', cdpv1_send, cdp_decode, cdpv1_guess,
CDP_MULTICAST_ADDR },
if (!cfg->g_protocols[i].enabled)
continue;
if (cfg->g_protocols[i].guess == NULL) {
- if (memcmp(frame, cfg->g_protocols[i].mac, ETHER_ADDR_LEN) == 0) {
+ if (memcmp(frame, cfg->g_protocols[i].mac1, ETHER_ADDR_LEN) == 0 ||
+ memcmp(frame, cfg->g_protocols[i].mac2, ETHER_ADDR_LEN) == 0 ||
+ memcmp(frame, cfg->g_protocols[i].mac3, ETHER_ADDR_LEN) == 0) {
log_debug("decode", "guessed protocol is %s (from MAC address)",
cfg->g_protocols[i].name);
return cfg->g_protocols[i].mode;
log_debug("decode", "decode a received frame on %s",
hardware->h_ifname);
- if (s < sizeof(struct ether_header) + 4)
+ if (s < sizeof(struct ether_header) + 4) {
/* Too short, just discard it */
+ hardware->h_rx_discarded_cnt++;
return;
+ }
/* Decapsulate VLAN frames */
struct ether_header eheader;
s, hardware, &chassis, &port) == -1) {
log_debug("decode", "function for %s protocol did not decode this frame",
cfg->g_protocols[i].name);
+ hardware->h_rx_discarded_cnt++;
return;
}
chassis->c_protocol = port->p_protocol =
lldpd_all_chassis_cleanup(cfg);
free(cfg->g_default_local_port);
free(cfg->g_config.c_platform);
+ levent_shutdown(cfg);
}
/**
execl(path, "lldpcli", sdebug,
"-u", ctlname,
- "-c", SYSCONFDIR "/lldpd.conf",
- "-c", SYSCONFDIR "/lldpd.d",
+ "-C", SYSCONFDIR "/lldpd.conf",
+ "-C", SYSCONFDIR "/lldpd.d",
"resume",
(char *)NULL);
log_warn("main", "unable to execute %s", path);
version_convert(MIN_LINUX_KERNEL_VERSION, version_min, 3);
if (version_min[0] > version_cur[0] ||
(version_min[0] == version_cur[0] && version_min[1] > version_cur[1]) ||
- (version_min[1] == version_cur[1] && version_min[2] > version_cur[2])) {
+ (version_min[0] == version_cur[0] && version_min[1] == version_cur[1] &&
+ version_min[2] > version_cur[2])) {
log_warnx("lldpd", "minimal kernel version required is %s, got %s",
MIN_LINUX_KERNEL_VERSION, uts.release);
log_warnx("lldpd", "lldpd may be unable to detect bonds and bridges correctly");
struct lldpd *cfg;
struct lldpd_chassis *lchassis;
int ch, debug = 0, use_syslog = 1, daemonize = 1;
+ const char *errstr;
#ifdef USE_SNMP
int snmp = 0;
const char *agentx = NULL; /* AgentX socket */
* unless there is a very good reason. Most command-line options will
* get deprecated at some point. */
char *popt, opts[] =
- "H:vhkrdD:xX:m:u:4:6:I:C:p:M:P:S:iL:@ ";
+ "H:vhkrdD:p:xX:m:u:4:6:I:C:p:M:P:S:iL:@ ";
int i, found, advertise_version = 1;
#ifdef ENABLE_LLDPMED
int lldpmed = 0, noinventory = 0;
char *platform_override = NULL;
char *lsb_release = NULL;
const char *lldpcli = LLDPCLI_PATH;
+ const char *pidfile = LLDPD_PID_FILE;
int smart = 15;
int receiveonly = 0, version = 0;
int ctl;
case 'D':
log_accept(optarg);
break;
+ case 'p':
+ pidfile = optarg;
+ break;
case 'r':
receiveonly = 1;
break;
break;
#ifdef ENABLE_LLDPMED
case 'M':
- lldpmed = atoi(optarg);
- if ((lldpmed < 1) || (lldpmed > 4)) {
+ lldpmed = strtonum(optarg, 1, 4, &errstr);
+ if (errstr) {
fprintf(stderr, "-M requires an argument between 1 and 4\n");
usage();
}
platform_override = strdup(optarg);
break;
case 'H':
- smart = atoi(optarg);
+ smart = strtonum(optarg, 0, sizeof(filters)/sizeof(filters[0]),
+ &errstr);
+ if (errstr) {
+ fprintf(stderr, "-H requires an int between 0 and %zu\n",
+ sizeof(filters)/sizeof(filters[0]));
+ usage();
+ }
break;
default:
found = 0;
log_init(use_syslog, debug, __progname);
tzset(); /* Get timezone info before chroot */
-
+ if (use_syslog && daemonize) {
+ /* So, we use syslog and we daemonize (or we are started by
+ * upstart/systemd). No need to continue writing to stdout. */
+ int fd;
+ if ((fd = open("/dev/null", O_RDWR, 0)) != -1) {
+ dup2(fd, STDIN_FILENO);
+ dup2(fd, STDOUT_FILENO);
+ dup2(fd, STDERR_FILENO);
+ if (fd > 2) close(fd);
+ }
+ }
log_debug("main", "lldpd " PACKAGE_VERSION " starting...");
version_check();
/* Grab uid and gid to use for priv sep */
#ifdef ENABLE_PRIVSEP
if ((user = getpwnam(PRIVSEP_USER)) == NULL)
- fatal("main", "no " PRIVSEP_USER " user for privilege separation");
+ fatalx("main", "no " PRIVSEP_USER " user for privilege separation, please create it");
uid = user->pw_uid;
if ((group = getgrnam(PRIVSEP_GROUP)) == NULL)
- fatal("main", "no " PRIVSEP_GROUP " group for privilege separation");
+ fatalx("main", "no " PRIVSEP_GROUP " group for privilege separation, please create it");
gid = group->gr_gid;
#endif
log_warn("main", "cannot determine if another daemon is already running");
fatalx("main", "giving up");
}
- log_warn("main", "unable to create control socket");
+ log_warn("main", "unable to create control socket at %s", ctlname);
fatalx("main", "giving up");
}
#ifdef ENABLE_PRIVSEP
/* Disable SIGHUP, until handlers are installed */
signal(SIGHUP, SIG_IGN);
- /* Configuration with lldpcli */
- if (lldpcli) {
- log_debug("main", "invoking lldpcli for configuration");
- if (lldpd_configure(use_syslog, debug, lldpcli, ctlname) == -1)
- fatal("main", "unable to spawn lldpcli");
- }
-
/* Daemonization, unless started by upstart, systemd or launchd or debug */
#ifndef HOST_OS_OSX
if (daemonize &&
!lldpd_started_by_upstart() && !lldpd_started_by_systemd()) {
int pid;
char *spid;
- log_debug("main", "daemonize");
- if (daemon(0, 0) != 0)
+ log_info("main", "going into background");
+ if (daemon(0, 1) != 0)
fatal("main", "failed to detach daemon");
- if ((pid = open(LLDPD_PID_FILE,
+ if ((pid = open(pidfile,
O_TRUNC | O_CREAT | O_WRONLY, 0666)) == -1)
- fatal("main", "unable to open pid file " LLDPD_PID_FILE);
+ fatal("main", "unable to open pid file " LLDPD_PID_FILE
+ " (or the specified one)");
if (asprintf(&spid, "%d\n", getpid()) == -1)
- fatal("main", "unable to create pid file " LLDPD_PID_FILE);
+ fatal("main", "unable to create pid file " LLDPD_PID_FILE
+ " (or the specified one)");
if (write(pid, spid, strlen(spid)) == -1)
- fatal("main", "unable to write pid file " LLDPD_PID_FILE);
+ fatal("main", "unable to write pid file " LLDPD_PID_FILE
+ " (or the specified one)");
free(spid);
close(pid);
}
#endif
+ /* Configuration with lldpcli */
+ if (lldpcli) {
+ log_debug("main", "invoking lldpcli for configuration");
+ if (lldpd_configure(use_syslog, debug, lldpcli, ctlname) == -1)
+ fatal("main", "unable to spawn lldpcli");
+ }
+
/* Try to read system information from /etc/os-release if possible.
Fall back to lsb_release for compatibility. */
log_debug("main", "get OS/LSB release information");
cfg->g_config.c_receiveonly = receiveonly;
cfg->g_config.c_tx_interval = LLDPD_TX_INTERVAL;
cfg->g_config.c_tx_hold = LLDPD_TX_HOLD;
+ cfg->g_config.c_ttl = cfg->g_config.c_tx_interval * cfg->g_config.c_tx_hold;
cfg->g_config.c_max_neighbors = LLDPD_MAX_NEIGHBORS;
#ifdef ENABLE_LLDPMED
cfg->g_config.c_enable_fast_start = enable_fast_start;
cfg->g_config.c_noinventory = 1;
#endif
- /* Set TTL */
- lchassis->c_ttl = cfg->g_config.c_tx_interval * cfg->g_config.c_tx_hold;
-
log_debug("main", "initialize protocols");
cfg->g_protocols = protos;
for (i=0; protos[i].mode != 0; i++) {