From: Vincent Bernat Date: Tue, 27 Oct 2020 17:31:22 +0000 (+0100) Subject: interfaces: listen to all incoming packets on Linux, not just LLDP ones X-Git-Tag: 1.0.7~1^2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=refs%2Fpull%2F414%2Fhead;p=thirdparty%2Flldpd.git interfaces: listen to all incoming packets on Linux, not just LLDP ones This mostly reverts fc5526dae75f. Listening only on ETH_P_LLDP makes us miss incoming packets on enslaved interfaces to an Open vSwitch. Therefore, prefer listening to ETH_P_ALL instead of ETH_P_LLDP. It is likely that enslaved interfaces do not fully process Ethernet packets and `type` is not correctly filled. Fix #413 --- diff --git a/NEWS b/NEWS index 5596d162..004f2934 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,8 @@ +lldpd (1.0.7) + * Fix: + + Do not listen only to LLDP packets on Linux. When an interface + is enslaved to an Open vSwitch, incoming packets are missed. + lldpd (1.0.6) * Fix: + Do not loose chassis local information when interface status changes. diff --git a/src/daemon/interfaces-bpf.c b/src/daemon/interfaces-bpf.c index 2ad579e7..5237ee75 100644 --- a/src/daemon/interfaces-bpf.c +++ b/src/daemon/interfaces-bpf.c @@ -34,7 +34,7 @@ ifbpf_phys_init(struct lldpd *cfg, log_debug("interfaces", "initialize ethernet device %s", hardware->h_ifname); - if ((fd = priv_iface_init(hardware->h_ifindex, hardware->h_ifname, 0)) == -1) + if ((fd = priv_iface_init(hardware->h_ifindex, hardware->h_ifname)) == -1) return -1; /* Allocate receive buffer */ diff --git a/src/daemon/interfaces-linux.c b/src/daemon/interfaces-linux.c index 72863f9e..5f901e60 100644 --- a/src/daemon/interfaces-linux.c +++ b/src/daemon/interfaces-linux.c @@ -42,21 +42,6 @@ #define MAX_PORTS 1024 #define MAX_BRIDGES 1024 -static int -only_lldp(struct lldpd *cfg) -{ - int lldp_enabled = 0; - int other_enabled = 0; - size_t i; - for (i=0; cfg->g_protocols[i].mode != 0; i++) { - if (cfg->g_protocols[i].mode == LLDPD_MODE_LLDP) - lldp_enabled = cfg->g_protocols[i].enabled; - else other_enabled = other_enabled || cfg->g_protocols[i].enabled; - } - return lldp_enabled && !other_enabled; - -} - static int iflinux_eth_init(struct lldpd *cfg, struct lldpd_hardware *hardware) { @@ -64,8 +49,7 @@ iflinux_eth_init(struct lldpd *cfg, struct lldpd_hardware *hardware) log_debug("interfaces", "initialize ethernet device %s", hardware->h_ifname); - if ((fd = priv_iface_init(hardware->h_ifindex, hardware->h_ifname, - only_lldp(cfg)?ETH_P_LLDP:ETH_P_ALL)) == -1) + if ((fd = priv_iface_init(hardware->h_ifindex, hardware->h_ifname)) == -1) return -1; hardware->h_sendfd = fd; /* Send */ @@ -677,7 +661,6 @@ iface_bond_init(struct lldpd *cfg, struct lldpd_hardware *hardware) struct bond_master *master = hardware->h_data; int fd; int un = 1; - int proto; if (!master) return -1; @@ -685,9 +668,8 @@ iface_bond_init(struct lldpd *cfg, struct lldpd_hardware *hardware) hardware->h_ifname); /* First, we get a socket to the raw physical interface */ - proto = only_lldp(cfg)?ETH_P_LLDP:ETH_P_ALL; if ((fd = priv_iface_init(hardware->h_ifindex, - hardware->h_ifname, proto)) == -1) + hardware->h_ifname)) == -1) return -1; hardware->h_sendfd = fd; interfaces_setup_multicast(cfg, hardware->h_ifname, 0); @@ -695,7 +677,7 @@ iface_bond_init(struct lldpd *cfg, struct lldpd_hardware *hardware) /* Then, we open a raw interface for the master */ log_debug("interfaces", "enslaved device %s has master %s(%d)", hardware->h_ifname, master->name, master->index); - if ((fd = priv_iface_init(master->index, master->name, proto)) == -1) { + if ((fd = priv_iface_init(master->index, master->name)) == -1) { close(hardware->h_sendfd); return -1; } diff --git a/src/daemon/lldpd.h b/src/daemon/lldpd.h index 98977ed4..0d67d7c9 100644 --- a/src/daemon/lldpd.h +++ b/src/daemon/lldpd.h @@ -201,8 +201,8 @@ char *priv_gethostname(void); int priv_open(char*); void asroot_open(void); #endif -int priv_iface_init(int, char *, int); -int asroot_iface_init_os(int, char *, int *, int); +int priv_iface_init(int, char *); +int asroot_iface_init_os(int, char *, int *); int priv_iface_multicast(const char *, const u_int8_t *, int); int priv_iface_description(const char *, const char *); int asroot_iface_description_os(const char *, const char *); diff --git a/src/daemon/priv-bsd.c b/src/daemon/priv-bsd.c index 14085b17..f32f990c 100644 --- a/src/daemon/priv-bsd.c +++ b/src/daemon/priv-bsd.c @@ -27,7 +27,7 @@ #include int -asroot_iface_init_os(int ifindex, char *name, int *fd, int proto) +asroot_iface_init_os(int ifindex, char *name, int *fd) { int enable, required, rc; struct bpf_insn filter[] = { LLDPD_FILTER_F }; diff --git a/src/daemon/priv-linux.c b/src/daemon/priv-linux.c index 43faca3a..6b7d9f4b 100644 --- a/src/daemon/priv-linux.c +++ b/src/daemon/priv-linux.c @@ -115,12 +115,12 @@ asroot_open() } int -asroot_iface_init_os(int ifindex, char *name, int *fd, int proto) +asroot_iface_init_os(int ifindex, char *name, int *fd) { int rc; /* Open listening socket to receive/send frames */ if ((*fd = socket(PF_PACKET, SOCK_RAW, - htons(proto))) < 0) { + htons(ETH_P_ALL))) < 0) { rc = errno; return rc; } diff --git a/src/daemon/priv.c b/src/daemon/priv.c index 05ee355f..ba5ae58c 100644 --- a/src/daemon/priv.c +++ b/src/daemon/priv.c @@ -120,7 +120,7 @@ priv_gethostname() int -priv_iface_init(int index, char *iface, int proto) +priv_iface_init(int index, char *iface) { int rc; char dev[IFNAMSIZ] = {}; @@ -129,7 +129,6 @@ priv_iface_init(int index, char *iface, int proto) must_write(PRIV_UNPRIVILEGED, &index, sizeof(int)); strlcpy(dev, iface, IFNAMSIZ); must_write(PRIV_UNPRIVILEGED, dev, IFNAMSIZ); - must_write(PRIV_UNPRIVILEGED, &proto, sizeof(int)); priv_wait(); must_read(PRIV_UNPRIVILEGED, &rc, sizeof(int)); if (rc != 0) return -1; @@ -251,15 +250,13 @@ asroot_iface_init() { int rc = -1, fd = -1; int ifindex; - int proto; char name[IFNAMSIZ]; must_read(PRIV_PRIVILEGED, &ifindex, sizeof(ifindex)); must_read(PRIV_PRIVILEGED, &name, sizeof(name)); name[sizeof(name) - 1] = '\0'; - must_read(PRIV_PRIVILEGED, &proto, sizeof(proto)); TRACE(LLDPD_PRIV_INTERFACE_INIT(name)); - rc = asroot_iface_init_os(ifindex, name, &fd, proto); + rc = asroot_iface_init_os(ifindex, name, &fd); must_write(PRIV_PRIVILEGED, &rc, sizeof(rc)); if (rc == 0 && fd >=0) send_fd(PRIV_PRIVILEGED, fd); if (fd >= 0) close(fd);