From 9067c45d334c282d185d88c9580863316b1f4d50 Mon Sep 17 00:00:00 2001 From: "John W. O'Brien" Date: Sat, 11 May 2024 18:49:42 -0400 Subject: [PATCH] priv: disable LLDP in firmware for Intel X7xx cards on FreeBSD --- NEWS | 1 + README.md | 9 +++++- src/daemon/priv-bsd.c | 70 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 79 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 33076e4f..f0268519 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,7 @@ lldpd (1.0.19) * Changes: + Support of both Apple Silicon and Intel for macOS package. + Add cvlan/svlan/tpmr capabilities. + + Disable LLDP in firmware for Intel X7xx cards on FreeBSD. lldpd (1.0.18) * Changes (breaking): diff --git a/README.md b/README.md index e19bf5cc..c753b669 100644 --- a/README.md +++ b/README.md @@ -449,8 +449,15 @@ for f in /sys/kernel/debug/i40e/*/command; do echo lldp stop > $f done ``` +On FreeBSD, use `sysctl` stop the embedded LLDP daemon: +```sh +for oid in $(sysctl -Nq dev.ixl | grep fw_lldp); do + sysctl $oid=0 +done +``` This may also apply to the `ice` (Intel E8xx cards) driver. These -steps are not necessary with a recent version of `lldpd` (1.0.11+). +steps are not necessary with a recent version of `lldpd` (1.0.11+ for +Linux, 1.0.19+ for FreeBSD). ## License diff --git a/src/daemon/priv-bsd.c b/src/daemon/priv-bsd.c index 61f332a5..b687cbea 100644 --- a/src/daemon/priv-bsd.c +++ b/src/daemon/priv-bsd.c @@ -17,15 +17,82 @@ #include "lldpd.h" +#include #include +#include #include #include #include +#include #include #include #include #include +#if defined HOST_OS_FREEBSD +# include + +/* Quirks needed by some additional interfaces. Currently, this is limited to + * disabling LLDP firmware for ixl. OpenBSD and NetBSD disable the ixl + * firmware LLDP agent upon driver attach. */ +static void +asroot_iface_init_quirks(int ifindex, char *name) +{ + int sysctl_oid[6]; + int fw_lldp = 0; + size_t driver_name_len; + char *driver_name = NULL; + char *sysctl_name = NULL; + + /* Check driver. */ + sysctl_oid[0] = CTL_NET; + sysctl_oid[1] = PF_LINK; + sysctl_oid[2] = NETLINK_GENERIC; + sysctl_oid[3] = IFMIB_IFDATA; + sysctl_oid[4] = ifindex; + sysctl_oid[5] = IFDATA_DRIVERNAME; + + if (sysctl(sysctl_oid, 6, NULL, &driver_name_len, 0, 0) < 0) { + log_warn("interfaces", "unable to get driver name length"); + goto end; + } + + if ((driver_name = malloc(driver_name_len)) == NULL) { + log_warnx("interfaces", "insufficient memory for driver name"); + goto end; + } + + if (sysctl(sysctl_oid, 6, driver_name, &driver_name_len, 0, 0) < 0) { + log_warn("interfaces", "unable to get driver name"); + goto end; + } + + if (driver_name_len < 4 || strncmp("ixl", driver_name, 3) || + !isdigit(driver_name[3])) { + /* Not ixl */ + goto end; + } + + log_info("interfaces", "ixl driver detected for %s, disabling LLDP in firmware", + name); + + if (asprintf(&sysctl_name, "dev.ixl.%s.fw_lldp", driver_name + 3) == -1) { + log_warnx("interfaces", "insufficient memory for sysctl name"); + goto end; + } + if (sysctlbyname(sysctl_name, NULL, NULL, &fw_lldp, sizeof(fw_lldp)) < 0) { + log_warn("interfaces", + "unable to disable LLDP in firmware for %s via %s", name, + sysctl_name); + goto end; + } + +end: + if (driver_name != NULL) free(driver_name); + if (sysctl_name != NULL) free(sysctl_name); +} +#endif /* HOST_OS_FREEBSD */ + int asroot_iface_init_os(int ifindex, char *name, int *fd) { @@ -124,6 +191,9 @@ asroot_iface_init_os(int ifindex, char *name, int *fd) log_info("privsep", "unable to lock BPF interface %s", name); return rc; } +#endif +#if defined HOST_OS_FREEBSD + asroot_iface_init_quirks(ifindex, name); #endif return 0; } -- 2.39.5