]> git.ipfire.org Git - thirdparty/lldpd.git/commitdiff
interfaces: listen to all incoming packets on Linux, not just LLDP ones fix/missed-lldp-packets 414/head
authorVincent Bernat <vincent@bernat.ch>
Tue, 27 Oct 2020 17:31:22 +0000 (18:31 +0100)
committerVincent Bernat <vincent@bernat.ch>
Tue, 27 Oct 2020 17:31:22 +0000 (18:31 +0100)
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

NEWS
src/daemon/interfaces-bpf.c
src/daemon/interfaces-linux.c
src/daemon/lldpd.h
src/daemon/priv-bsd.c
src/daemon/priv-linux.c
src/daemon/priv.c

diff --git a/NEWS b/NEWS
index 5596d1628c0a19c19d4791eb35a888005fc1229f..004f29346ed4463b187fbfedfefedae1a3b3a2a2 100644 (file)
--- 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.
index 2ad579e7fe6ef2c4716fcddd39e34075e7bf72c4..5237ee75370e3493b887ef0030d0a607992c2a75 100644 (file)
@@ -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 */
index 72863f9e380c46609cef563b0e4ee0a2ca173443..5f901e607eb1c9c4f1d3e9db871d85420ea5b95c 100644 (file)
 #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;
        }
index 98977ed4d7561c6242527b24d275040a2b82851b..0d67d7c9fa7bbd58020371ef0a772306845c8900 100644 (file)
@@ -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 *);
index 14085b17e3b27ff79f553cac8bde452736b0bb64..f32f990cb15269d1da5b776a86971512691725d3 100644 (file)
@@ -27,7 +27,7 @@
 #include <string.h>
 
 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 };
index 43faca3a3f73ed0296578a9cc245d73b6e44980f..6b7d9f4b16ce199db218645675f36d3eaf752e21 100644 (file)
@@ -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;
        }
index 05ee355fda7ff0b5736c50631d4194db201d7489..ba5ae58c7392476bf13e455f95b7c3ef50a4a8e9 100644 (file)
@@ -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);