1 # lldpd: implementation of IEEE 802.1ab (LLDP)
3 ![Build Status](https://github.com/lldpd/lldpd/workflows/CI/badge.svg)
5 https://lldpd.github.io/
9 LLDP (Link Layer Discovery Protocol) is an industry standard protocol
10 designed to supplant proprietary Link-Layer protocols such as
11 Extreme's EDP (Extreme Discovery Protocol) and CDP (Cisco Discovery
12 Protocol). The goal of LLDP is to provide an inter-vendor compatible
13 mechanism to deliver Link-Layer notifications to adjacent network
16 lldpd implements both reception and sending. It also implements an
17 SNMP subagent for net-snmp to get local and remote LLDP
18 information. The LLDP-MIB is partially implemented but the most useful
19 tables are here. lldpd also partially implements LLDP-MED.
21 lldpd supports bridge, vlan and bonding.
23 The following OS are supported:
32 Windows is not supported but you can use
33 [WinLLDPService](https://github.com/raspi/WinLLDPService/) as a
38 For general instructions [prefer the
39 website](https://lldpd.github.io/installation.html),
40 including building from released tarballs.
42 To compile lldpd from Git, use the following commands:
49 lldpd uses privilege separation to increase its security. Two
50 processes, one running as root and doing minimal stuff and the other
51 running as an unprivileged user into a chroot doing most of the stuff,
52 are cooperating. You need to create a user called `_lldpd` in a group
53 `_lldpd` (this can be change with `./configure`). You also need to
54 create an empty directory `/usr/local/var/run/lldpd` (it needs to be
55 owned by root, not `_lldpd`!). If you get fuzzy timestamps from
56 syslog, copy `/etc/locatime` into the chroot.
58 `lldpcli` lets one query information collected through the command
59 line. If you don't want to run it as root, just install it setuid or
62 ## Installation (Docker)
64 You can use Docker to run `lldpd`:
66 docker run --rm --net=host --uts=host \
67 -v /etc/os-release:/etc/os-release \
68 --cap-add=NET_RAW --cap-add=NET_ADMIN \
70 ghcr.io/lldpd/lldpd:latest
72 In place of `latest` which provides you with the latest stable
73 version, you may use `1`, `1.0`, `1.0.12` to match specific versions,
74 or `master` to get the development version.
76 To execute `lldpcli`, use:
78 docker exec lldpd lldpcli show neighbors
80 Or to get the command-line:
82 docker exec -it lldpd lldpcli
84 ## Installation (macOS)
86 The same procedure as above applies for macOS. However, there are
89 1. Use [Homebrew](https://brew.sh):
92 # Or, for the latest version:
93 brew install https://raw.github.com/lldpd/lldpd/master/osx/lldpd.rb
95 2. Build an OS X installer package which should work on the same
96 version of OS X (it is important to use a separate build
99 mkdir build && cd build
100 ../configure --prefix=/usr/local --localstatedir=/var --sysconfdir=/private/etc --with-embedded-libevent \
104 If you want to compile for an older version of macOS, you need
107 mkdir build && cd build
108 ../configure --prefix=/usr/local --localstatedir=/var --sysconfdir=/private/etc --with-embedded-libevent \
110 CFLAGS="-mmacosx-version-min=11.1" \
111 LDFLAGS="-mmacosx-version-min=11.1"
114 You can check with `otool -l` that you got what you expected in
115 term of supported versions. If you are running on ARM64, you can
116 configure a binary supporting both architectures by adding
117 `ARCHS="arm64 x86_64"` to the arguments of the `make` command.
119 If you don't follow the above procedures, you will have to create the
120 user/group `_lldpd`. Have a look at how this is done in
121 `osx/scripts/postinstall`.
123 ## Installation (Android)
125 1. Don't clone the repo or download the master branch from GitHub. Instead, download the official release from the website [https://lldpd.github.io/](https://lldpd.github.io/installation.html#install-from-source). Unpack into a working directory.
127 2. Download the [Android NDK](https://developer.android.com/ndk/downloads#stable-downloads) (version 22 or later). Unpack into a working directory next to the `lldpd` directory.
129 3. Install `automake`, `libtool`, and `pkg-config`. (`sudo apt-get install automake libtool pkg-config`)
131 4. In the root of the `lldpd` directory, make a `compile.sh` file containing this script:
133 export TOOLCHAIN=$PWD/android-ndk/toolchains/llvm/prebuilt/linux-x86_64
134 export TARGET=armv7a-linux-androideabi
137 export AR=$TOOLCHAIN/bin/llvm-ar
138 export CC=$TOOLCHAIN/bin/$TARGET$API-clang
139 export CXX=$TOOLCHAIN/bin/$TARGET$API-clang++
140 export LD=$TOOLCHAIN/bin/ld
141 export RANLIB=$TOOLCHAIN/bin/llvm-ranlib
142 export STRIP=$TOOLCHAIN/bin/llvm-strip
145 mkdir -p build && cd build
148 --with-sysroot=$TOOLCHAIN/sysroot \
150 --sbindir=/system/bin \
151 --runstatedir=/data/data/lldpd \
152 --with-privsep-user=root \
153 --with-privsep-group=root \
154 PKG_CONFIG=/bin/false
156 make install DESTDIR=$PWD/install
159 5. In the **Android NDK** directory, locate the `toolchains/llvm/prebuilt/linux-x86_64` directory and change the `TOOLCHAIN` variable of the above script to match the path where the `linux-x86_64` directory resides.
162 export TOOLCHAIN=$PWD/android-ndk-r22b-linux-x86_64/android-ndk-r22b/toolchains/llvm/prebuilt/linux-x86_64
165 6. Determine the CPU architecture target (`adb shell getprop ro.product.cpu.abi`). Change the `TARGET` variable in the above script to match the target architecture. The target name will not exactly match the output of the `adb` command as there will be a trailing suffix to the target name, so look in the `linux-x86_64/bin` directory for the `clang` file that starts with the CPU architecture target. Don't include the API version in the target name.
167 $ adb shell getprop ro.product.cpu.abi
171 linux-x86_64/bin$ ls *-clang
172 aarch64-linux-android21-clang armv7a-linux-androideabi23-clang i686-linux-android26-clang
173 aarch64-linux-android22-clang armv7a-linux-androideabi24-clang i686-linux-android27-clang
174 aarch64-linux-android23-clang armv7a-linux-androideabi26-clang i686-linux-android28-clang
175 aarch64-linux-android24-clang armv7a-linux-androideabi27-clang i686-linux-android29-clang
176 aarch64-linux-android26-clang armv7a-linux-androideabi28-clang i686-linux-android30-clang
177 aarch64-linux-android27-clang armv7a-linux-androideabi29-clang x86_64-linux-android21-clang
178 aarch64-linux-android28-clang armv7a-linux-androideabi30-clang x86_64-linux-android22-clang
179 aarch64-linux-android29-clang i686-linux-android16-clang x86_64-linux-android23-clang
180 aarch64-linux-android30-clang i686-linux-android17-clang x86_64-linux-android24-clang
181 armv7a-linux-androideabi16-clang i686-linux-android18-clang x86_64-linux-android26-clang
182 armv7a-linux-androideabi17-clang i686-linux-android19-clang x86_64-linux-android27-clang
183 armv7a-linux-androideabi18-clang i686-linux-android21-clang x86_64-linux-android28-clang
184 armv7a-linux-androideabi19-clang i686-linux-android22-clang x86_64-linux-android29-clang
185 armv7a-linux-androideabi21-clang i686-linux-android23-clang x86_64-linux-android30-clang
186 armv7a-linux-androideabi22-clang i686-linux-android24-clang
189 export TARGET=armv7a-linux-androideabi
192 7. Set the `API` variable in the script above to your target API version. Check in the same `linux-x86_64/bin` to ensure the API you are targeting has a supported `clang` file for that CPU architecture and version. As of this writing, there is support for API `21-30` included for all architectures and some CPU architectures supported back to version `16`.
197 8. Run the compile script (`./compile.sh`).
199 9. Copy the `./bin/*` and `./lib/*.so` files from `lldpd/build/install/system` to the target system (`./bin/*` to `/system/bin`, `./lib/*.so` to `/system/lib64`):
201 # Push files to target
202 cd build/install/system
203 adb shell mkdir -p /sdcard/Download/lldpd/bin
204 adb push bin/lldpcli /sdcard/Download/lldpd/bin/lldpcli
205 adb push bin/lldpd /sdcard/Download/lldpd/bin/lldpd
206 adb shell mkdir -p /sdcard/Download/lldpd/lib64
207 adb push lib/liblldpctl.so /sdcard/Download/lldpd/lib64/liblldpctl.so
209 # Enter target shell and move files
211 # Run as root for all commands
213 # Make /system writeable
214 $ mount -o rw,remount /system
215 $ mv /sdcard/Download/lldpd/bin/lldpcli /system/bin/lldpcli
216 $ chmod 755 /system/bin/lldpcli
217 $ chown root:shell /system/bin/lldpcli
218 $ mv /sdcard/Download/lldpd/bin/lldpd /system/bin/lldpd
219 $ chmod 755 /system/bin/lldpd
220 $ chown root:shell /system/bin/lldpd
221 # $ touch /system/bin/lldpctl
222 # $ chmod 755 /system/bin/lldpctl
223 # $ chown root:shell /system/bin/lldpctl
224 $ mv /sdcard/Download/lldpd/lib64/liblldpctl.so /system/lib64/liblldpctl.so
225 $ chmod 644 /system/lib64/liblldpctl.so
226 $ chown root:root /system/lib64/liblldpctl.so
227 # Make /system readonly again
228 $ mount -o ro,remount /system
229 # Might not be necessary on some systems
230 $ mkdir /data/data/lldpd
231 $ chmod 700 /data/data/lldpd
232 $ chown shell:shell /data/data/lldpd
234 $ rm -rf /sdcard/Download/lldpd
239 lldpd also implements CDP (Cisco Discovery Protocol), FDP (Foundry
240 Discovery Protocol), SONMP (Nortel Discovery Protocol) and EDP
241 (Extreme Discovery Protocol). However, recent versions of IOS should
242 support LLDP and most Extreme stuff support LLDP. When a EDP, CDP or
243 SONMP frame is received on a given interface, lldpd starts sending
244 EDP, CDP, FDP or SONMP frame on this interface. Informations collected
245 through EDP/CDP/FDP/SONMP are integrated with other informations and
246 can be queried with `lldpcli` or through SNMP.
249 * http://en.wikipedia.org/wiki/Link_Layer_Discovery_Protocol
250 * http://standards.ieee.org/getieee802/download/802.1AB-2005.pdf
251 * https://gitlab.com/wireshark/wireshark/-/wikis/LinkLayerDiscoveryProtocol
253 ## Compatibility with older kernels
255 If you have a kernel older than Linux 2.6.39, you need to compile
256 lldpd with `--enable-oldies` to enable some compatibility functions:
257 otherwise, lldpd will only rely on Netlink to receive bridge, bond and
260 For bonding, you need 2.6.24 (in previous version, PACKET_ORIGDEV
261 affected only non multicast packets). See:
263 * http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=80feaacb8a6400a9540a961b6743c69a5896b937
264 * http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=8032b46489e50ef8f3992159abd0349b5b8e476c
266 Otherwise, a packet received on a bond will be affected to all
267 interfaces of the bond. In this case, lldpd will affect a received
268 randomly to one of the interface (so a neighbor may be affected to the
271 On 2.6.27, we are able to receive packets on real interface for enslaved
272 devices. This allows one to get neighbor information on active/backup
273 bonds. Without the 2.6.27, lldpd won't receive any information on
274 inactive slaves. Here are the patchs (thanks to Joe Eykholt):
276 * http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=0d7a3681232f545c6a59f77e60f7667673ef0e93
277 * http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=cc9bd5cebc0825e0fabc0186ab85806a0891104f
278 * http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=f982307f22db96201e41540295f24e8dcc10c78f
280 On FreeBSD, only a recent 9 kernel (9.1 or more recent) will allow to
281 send LLDP frames on enslaved devices. See this bug report for more
284 * http://www.freebsd.org/cgi/query-pr.cgi?pr=138620
286 Some devices (notably Cisco IOS) send frames tagged with the native
287 VLAN while they should send them untagged. If your network card does
288 not support accelerated VLAN, you will receive those frames as long as
289 the corresponding interface exists (see below). However, if your
290 network card handles VLAN encapsulation/decapsulation (check with
291 `ethtool -k`), you need a recent kernel to be able to receive those
292 frames without listening on all available VLAN. Starting from Linux
293 2.6.27, lldpd is able to capture VLAN frames when VLAN acceleration is
294 supported by the network card. Here is the patch:
296 * http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=bc1d0411b804ad190cdadabac48a10067f17b9e6
298 On some other versions, frames are sent on VLAN 1. If this is not the
299 native VLAN and if your network card support accelerated VLAN, you
300 need to subscribe to this VLAN as well. The Linux kernel does not
301 provide any interface for this. The easiest way is to create the VLAN
304 ip link add link eth0 name eth0.1 type vlan id 1
305 ip link set up dev eth0.1
307 You can check both cases using tcpdump:
309 tcpdump -epni eth0 ether host 01:80:c2:00:00:0e
310 tcpdump -eni eth0 ether host 01:80:c2:00:00:0e
312 If the first command does not display received LLDP packets but the
313 second one does, LLDP packets are likely encapsulated into a VLAN:
315 10:54:06.431154 f0:29:29:1d:7c:01 > 01:80:c2:00:00:0e, ethertype 802.1Q (0x8100), length 363: vlan 1, p 7, ethertype LLDP, LLDP, name SW-APP-D07.VTY, length 345
317 In this case, just create VLAN 1 will fix the situation. There are
320 1. Disable VLAN acceleration on the receive side (`ethtool -K eth0
321 rxvlan off`) but this may or may not work. Check if there are
322 similar properties that could apply with `ethtool -k eth0`.
323 2. Put the interface in promiscuous mode with `ip link set
324 promisc on dev eth0`.
326 The last solution can be done directly by `lldpd` (on Linux only) by
327 using the option `configure system interface promiscuous`.
329 On modern networks, the performance impact should be nonexistent.
333 During development, you may want to execute lldpd at its current
334 location instead of doing `make install`. The correct way to do this is
335 to issue the following command:
337 sudo libtool execute src/daemon/lldpd -L $PWD/src/client/lldpcli -d
339 You can append any further arguments. If lldpd is unable to find
340 `lldpcli` it will start in an unconfigured mode and won't send or
343 There is a general test suite with `make check`. It's also possible to
344 run integration tests. They need [pytest](http://pytest.org/latest/)
345 and rely on Linux containers to be executed.
347 To enable code coverage, use:
349 ../configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var \
350 --enable-sanitizers --enable-gcov --with-snmp \
354 # maybe, run integration tests
355 lcov --base-directory $PWD/src/lib \
356 --directory src --capture --output-file gcov.info
357 genhtml gcov.info --output-directory coverage
364 ./tests/fuzzer/build.sh ASan
365 ./tests/fuzzer/build.sh run
370 You can use [afl](http://lcamtuf.coredump.cx/afl/) to test some
371 aspects of lldpd. To test frame decoding, you can do something like
374 export AFL_USE_ASAN=1 # only on 32bit arch
375 ./configure CC=afl-gcc
380 afl-fuzz -i inputs -o outputs ./decode @@
384 To embed lldpd into an existing system, there are two point of entries:
386 1. If your system does not use standard Linux interface, you can
387 support additional interfaces by implementing the appropriate
388 `struct lldpd_ops`. You can look at
389 `src/daemon/interfaces-linux.c` for examples. Also, have a look at
390 `interfaces_update()` which is responsible for discovering and
391 registering interfaces.
393 2. `lldpcli` provides a convenient way to query `lldpd`. It also
394 comes with various outputs, including XML which allows one to
395 parse its output for integration and automation purpose. Another
396 way is to use SNMP support. A third way is to write your own
397 controller using `liblldpctl.so`. Its API is described in
398 `src/lib/lldpctl.h`. The custom binary protocol between
399 `liblldpctl.so` and `lldpd` is not stable. Therefore, the library
400 should always be shipped with `lldpd`. On the other hand, programs
401 using `liblldpctl.so` can rely on the classic ABI rules.
405 You can use `tcpdump` to look after the packets received and send by
406 `lldpd`. To look after LLDPU, use:
408 tcpdump -s0 -vv -pni eth0 ether dst 01:80:c2:00:00:0e
410 Intel X710 cards may handle LLDP themselves, intercepting any incoming
411 packets. If you don't see anything through `tcpdump`, check if you
412 have such a card (with `lspci`) and stop the embedded LLDP daemon:
414 for f in /sys/kernel/debug/i40e/*/command; do
418 This may also apply to the `ice` (Intel E8xx cards) driver. These
419 steps are not necessary with a recent version of `lldpd` (1.0.11+).
423 lldpd is distributed under the ISC license:
425 > Permission to use, copy, modify, and/or distribute this software for any
426 > purpose with or without fee is hereby granted, provided that the above
427 > copyright notice and this permission notice appear in all copies.
429 > THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
430 > WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
431 > MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
432 > ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
433 > WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
434 > ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
435 > OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
437 Also, `lldpcli` will be linked to GNU Readline (which is GPL licensed)
438 if available. To avoid this, use `--without-readline` as a configure