Vincent Bernat [Fri, 8 Nov 2013 13:26:34 +0000 (14:26 +0100)]
lldpd: tell `lldpcli` to use the appropriate control socket
When using a non-default control socket, lldpd was not providing the
appropriate name to lldpcli which was then not able to configure lldpd
during startup.
Vincent Bernat [Wed, 23 Oct 2013 08:01:12 +0000 (10:01 +0200)]
privsep: put /etc/localtime in chroot
The chroot directory was created by lldpd if missing. We also copy
`/etc/localtime` in it if not already present. This allows us to
remove duplicate code in many init scripts. Since this file is not
essential, we don't make a fuzz for some edge cases.
Vincent Bernat [Tue, 22 Oct 2013 19:24:19 +0000 (21:24 +0200)]
systemd: also read /etc/sysconfig/lldpd
While systemd's author says that we should get rid of those
pseudo-configuration files, keeping compatibility with previous ways
to configure daemons seem a valid reason to keep them. `/etc/default`
is Debian specific. We also read the equivalent one for RedHat to
ensure that everything will also continue to work here.
Vincent Bernat [Sun, 13 Oct 2013 10:19:01 +0000 (12:19 +0200)]
tests: only test if we have `check` installed
There should have been a good reason to put `TESTS` outside the
conditional but I don't remember it. It works by putting `TESTS`
inside the conditional and avoid an odd error message when trying to
execute tests without check installed.
Vincent Bernat [Sat, 12 Oct 2013 15:29:26 +0000 (17:29 +0200)]
lib: fix a segfault introduced in ef3707 when freeing an atom
In the change "lldpd: make notifications work when a port goes down",
a regression was introduced. It is important to never call
`TAILQ_REMOVE` on a marshalled struct, like when we are in
liblldpctl. This is because the marshalling process does not keep a
real list (prev pointer is incorrect).
The change ef3707 did introduce a regression by calling TAILQ_REMOVE
in a case where it is useless. We only need to call TAILQ_REMOVE if we
won't empty the whole list. So when we call `lldpd_remote_cleanup()`
with `all` set to `1`, we don't need to call TAILQ_REMOVE.
Vincent Bernat [Sat, 12 Oct 2013 14:00:40 +0000 (16:00 +0200)]
seccomp: add support for seccomp through libseccomp
The support is only for the monitor process (running as root). It is
enabled when the monitor has been initiliazed, before the event loop.
The monitor has to open a lot of files and read them (files in /proc,
/sys). Moreover, for some files, it has to write to them (for example,
stdout, /dev/log and for writing interface aliases). Therefore, there
are many registered syscalls. It should be possible to filter more but
this would require some efforts.
Becuase it is difficult to reliably report errors to the user and we
may have to execute arbitrary code because we need to resolve
hostnames (and therefore, connect to nscd, LDAP or anything else
handled by NSS), this does not seem to be reliable enough, yet.
Moreover, displaying failed syscall is a bit hackhish.
Maybe we could enable it by default if we change the default behaviour
from killing the offending process to just return a failed errno. Or
just logging the problem.
Vincent Bernat [Sat, 28 Sep 2013 10:26:03 +0000 (12:26 +0200)]
dtrace: add systemtap/DTrace support
Let's dive into what is hot today. The support was mostly just tested
with systemtap but should works just fine with dtrace as well. We
should provide a tapset to help use all this.
Vincent Bernat [Sun, 15 Sep 2013 10:24:43 +0000 (12:24 +0200)]
configure: use a convenience library for fixed point arithmetic
automake >= 1.14 does not like building binaries from source in other
directories. To avoid a warning, `subdir-objects` option has to be
passed to `AM_INIT_AUTOMAKE`. Unfortunately, this breaks what worked
before. Fixed point tests are using `fixedpoint.c` from
`src/lib`. This seems to confuse dependency tracking. See:
In fact, we still have limitations on how stacking is done. Bonds are
expected to be done on physical devices. Bonds on bonds are not
supported. In fact, there are some setups that cannot work
correctly. For example, let's assume the following:
On paper, we can still retrieve the real MAC addresses of various
stuff. However, Linux will alter the MAC addresses of the
VLAN. Moreover, depending on how bond1 is built, it can have the same
MAC address than bond0 or a different one. If MAC addresses are
propagated to the root, there may or may not have conflicts.
Putting bonds on physical interfaces should be the only sane thing to
do. While we could accomodate more complex setup, let's not try to do
something quite complex that nobody will use.
Vincent Bernat [Sun, 15 Sep 2013 09:29:46 +0000 (11:29 +0200)]
linux: fix a regression in how enslaved devices' MAC addresses are retrieved
The MAC address of an enslaved device was not retrieved
correctly. `iflinux_get_permanent_mac()` was called with the master
device instead of the enslaved device. Most of the time, no warning
was issued except when the master device was a slave of another
device (for example, a bridge). This closes #45.
We don't use delegated requests and therefore, this call is not
necessary. It was put here out of safety but it seems that it can
trigger spurious alarms and microseconds timeout. This makes lldpd
consume a lot of CPU. We just remove this call from the event loop.
Vincent Bernat [Thu, 15 Aug 2013 09:08:39 +0000 (11:08 +0200)]
systemd: install service file using `systemdsystemunit_DATA`
When there is an autoconf variable `somethingdir`, we can use
`something_DATA` in automake to install things to this directory. This
is more convenient than using local targets We still have to protect
the use of those variables with conditional macros since they can be
empty or set to no. There is also a drawback about distcheck trying to
set prefix and not expecting things to be installed outside of prefix.
Do the same thing for OS X launchd daemon configuration file.
Vincent Bernat [Wed, 14 Aug 2013 17:17:23 +0000 (19:17 +0200)]
lib: fix notification by reading one byte at a time from Unix socket
Internally, several bytes will be read at once and the notification
should be detected earlier. This fixes a regression introduced in 5aeda65433fd41b7bb67f908d8c4741f045ce508 because we relied on datagram
boundary semantics. This was not important when pulling information
but we still used this semantic when pushing information. Closes: #43.
Vincent Bernat [Tue, 13 Aug 2013 19:33:29 +0000 (21:33 +0200)]
lldpd: make notifications work when a port goes down
We need to refactor a bit `lldpd_remote_cleanup()` to separate the
expiration process (checking each remote port to check if it is still
current) and the removal of remote port (which triggers the expire
function because we want to be notified when a neighbor disappear this
way).
Vincent Bernat [Sun, 11 Aug 2013 20:07:57 +0000 (22:07 +0200)]
interfaces: abstract a bit MAC address mangling for bonding devices
A variable in `struct lldpd_hardware` control the mangling. On the
other end, `hardware->h_ops->send()` should not be called directly
anymore. Instead, `interfaces_helper_send()` should be used instead.
Vincent Bernat [Thu, 25 Jul 2013 08:24:30 +0000 (10:24 +0200)]
linux: mangle MAC address for enslaved devices
With enslaved devices, we may end up with in a situation where we send
a packet with a source MAC address that may confuse switches. For
example:
1. eth0, MAC X connected to switch A.
2. eth1, MAC Y connected to switch B.
3. Active/backup bond is created, MAC X.
4. eth1 is active, eth0 is backup.
If we use the real MAC, eth0 will send LLDP packets with MAC X to
switch A that will learn this MAC and send packets on backup port eth0
and they will be discarded.
The solution until then was to use a zero MAC address in those
cases. However, it seems that some switches may be confused by such a
move. See #26.
Instead, we set the "local" bit to 1 if not already set. Otherwise, we
just use some arbitrary MAC address that I have on an unused 3Com
"Tornado" card. It is unlikely to be reused (100 MBps and it is in a
basement). If you happen to have an even older MAC address and are
willing to give it for lldpd, feel free to tell me. The later case
does not handle all problems but allievate the problem with switches
discarding or complaining about zero MAC address as a source.
Vincent Bernat [Wed, 24 Jul 2013 20:20:50 +0000 (22:20 +0200)]
lib: introduce proper fixed point parsing and representation module
This additional modules isolates the complexity of parsing and
representing fixed point numbers. This is uses for coordinates in
LLDP-MED.
The previous version was using an incorrect precision. When parsing
user input, the precision is now derivated from the number of digits
provided. When displaying a value, the precision is used to add
additional 0 if needed.
Moreover, the previous version was a bit buggy with some values and
with negative numbers. This change contains unittest to tackle most
issues.
It relies on presence of __builtin_clzll() function, available in GCC
and others. Maybe this will become a portability issue.
Vincent Bernat [Mon, 15 Jul 2013 18:56:00 +0000 (20:56 +0200)]
event: replace `evutil_make_socket_nonblocking()` by an idempotent version
Once a file descriptor is locked with `BIOCLOCK`, it is not possible
to make it non-blocking. Therefore, we need to make it non-blocking
before locking it. Unfortunately, `evutil_make_socket_nonblocking()`
does not check the current value of the flag to see if there is
anything to do and we get a spurious warning. Just provide our version
of this function for this purpose.
Vincent Bernat [Fri, 12 Jul 2013 22:07:16 +0000 (00:07 +0200)]
configure: check for `res_init()` before trying other forms.
On OSX, `res_init()` is a symbol of `libsystem_info` (a dependency of
`libSystem`). So, AC_SEARCH_LIBS directly finds this symbol without an
additional library. However, once you include `resolv.h`, this becomes
a macro to `res_9_init` which is a symbol of `libresolv`. So you need
to link to `libresolv`. This is why we test first for `res_9_init` and
only after for `res_init`.
See more info about this here:
http://blog.achernya.com/2013/03/os-x-has-silly-libsystem.html
However, on other systems, this will link to libbind while this is not
needed because `res_9_init` is a symbol of libbind while `res_init` is
correctly defined in `libc` and no odd redefinition.
So, the solution is to force `AC_SEARCH_LIBS` to include `resolv.h`
and only test for `res_init` (as a symbol or a macro, we don't
care). This is done by redefining `AC_LANG_CALL(C)` to include
`resolv.h`.
Vincent Bernat [Thu, 11 Jul 2013 21:13:10 +0000 (23:13 +0200)]
priv: correctly declare `priv_cmd` type
`enum {} priv_cmd` was the declaration of a variable `priv_cmd` as an
anonymous enum. This is not what was expected. Instead, we want `enum
priv_cmd` to be a declaration of a named enum: `enum priv_cmd {}` (we
could also use `typedef enum {} priv_cmd`, but in lldpd, `typedef` is
seldomly used).
When `priv_cmd` was moved out of `priv.c`, its symbol was defined in
several objects. It seems that recent versions of gcc are able to cope
with that (because `priv_cmd` variable was not used, so it was
optimized out I think, not sure). However, some older versions like
4.2.1 complained about duplicate objects during the link phase.
Vincent Bernat [Tue, 2 Jul 2013 22:18:41 +0000 (00:18 +0200)]
interfaces: overwrite interface description with neighbor found
If no neighbor is found, interface name is `lldpd: no neighbor
found`. If one neighbor is found, this is `lldpd: connected to XXXXX`
and if several neighbors are found, this is `lldpd: XXX
neighbors`. Smart filter is used to count neighbors.
Currently, this is not possible to disable this. Works with FreeBSD,
OpenBSD and Linux.
Vincent Bernat [Tue, 2 Jul 2013 20:38:16 +0000 (22:38 +0200)]
privsep: separate OS specific code to dedicated files
Linux only stuff goes in `priv-linux.c`. This includes interface
handling, ethtool and ability to open files (which is not Linux
specific but only Linux requires this).
BSD stuff goes in `priv-bpf.c` since it only includes interface
handling.
Moreover, `privsep_fdpass.c` is merged into `privsep_io.c`, a new file
for almost everything about IO (read/write and passing FD). The global
`remote` object is put into this file.
This commit is mostly moving stuff around. This will enable the
ability to write interface aliases without putting too much #ifdef.
Vincent Bernat [Mon, 24 Jun 2013 23:25:04 +0000 (01:25 +0200)]
osx: don't try to build universal binaries
The use of multiple arch is not safe with autotools. I believe that
libevent compute some arch-dependent stuff at configure-time. Just say
in README.md that the package will only work for the same version of
OSX and the same architecture.
For the future:
- real universal binaries can be built by configuring and building
each arch into a separate directory, then merge the result with
`lipo`.
- building a package for an older versions of Max OS X can be done
by using `-mmacosx-version-min=10.6` and `-isysroot
/Developer/SDKs/MacOSX10.5.sdk` on both `CFLAGS` and `LDFLAGS`.
Vincent Bernat [Sun, 23 Jun 2013 21:26:05 +0000 (23:26 +0200)]
osx: add a target to build an OSX package
We use pkgbuild and productbuild (which seem to have superseded
PackageMaker). Those tools are shipped from OSX 10.6.6. There are only
a few examples of how to use those tools with daemons. You may also
look at Jenkins or ngircd.
See `README.md` for more information on how to invoke the build of a
package.
Vincent Bernat [Sun, 23 Jun 2013 12:26:53 +0000 (14:26 +0200)]
compat: include config.h in compat.h
Without this inclusion, no `HAVE_*` macro was defined. This was
triggered because with some libc, `strndup()` is defined by a macro
and therefore cannot be redefined as a function.
Vincent Bernat [Sat, 22 Jun 2013 10:15:47 +0000 (12:15 +0200)]
bpf: on OpenBSD, invert the filter direction
From the manual page:
> Sets or gets the status of the `direction filter` flag. If
> non-zero, packets matching the specified direction (either
> `BPF_DIRECTION_IN` or `BPF_DIRECTION_OUT`) will be ignored.