]> git.ipfire.org Git - thirdparty/lldpd.git/commitdiff
Do not try to catch CDP frame inside VLAN tagged frame.
authorVincent Bernat <vbernat@wanadooportails.com>
Mon, 20 Oct 2008 09:12:02 +0000 (11:12 +0200)
committerVincent Bernat <vbernat@wanadooportails.com>
Mon, 20 Oct 2008 09:12:02 +0000 (11:12 +0200)
With hardware accelerated VLAN supported by some cards like e1000,
this does not work. We need to listen on the corresponding VLAN
instead.

This reverts commit dc1539a44534a36fa8683ecfaddbbd6b34466b96.

src/cdp.c
src/edp.c
src/llc.h
src/lldpd.c
src/sonmp.c

index bd2d6fae7fa040eba277eec31df34cf7a897ae6a..d2fb90e325724a56eaab71bc59ae71fd45697592 100644 (file)
--- a/src/cdp.c
+++ b/src/cdp.c
@@ -48,10 +48,10 @@ cdp_send(struct lldpd *global, struct lldpd_chassis *chassis,
            sizeof(llc.ether.shost));
        memcpy(&llc.ether.dhost, &mcastaddr,
            sizeof(llc.ether.dhost));
-       llc.llc.dsap = llc.llc.ssap = 0xaa;
-       llc.llc.control = 0x03;
-       memcpy(llc.llc.org, llcorg, sizeof(llc.llc.org));
-       llc.llc.protoid = htons(LLC_PID_CDP);
+       llc.dsap = llc.ssap = 0xaa;
+       llc.control = 0x03;
+       memcpy(llc.org, llcorg, sizeof(llc.org));
+       llc.protoid = htons(LLC_PID_CDP);
        IOV_NEW;
        iov[c].iov_base = &llc;
        iov[c].iov_len = sizeof(llc);
@@ -172,8 +172,7 @@ cdp_decode(struct lldpd *cfg, char *frame, int s,
 {
        struct lldpd_chassis *chassis;
        struct lldpd_port *port;
-       struct ieee8023 *ether;
-       struct llc *llc;
+       struct ethllc *llc;
        struct cdp_header *ch;
        struct cdp_tlv_head *tlv;
        struct cdp_tlv_address_head *ah;
@@ -196,46 +195,21 @@ cdp_decode(struct lldpd *cfg, char *frame, int s,
        }
        TAILQ_INIT(&port->p_vlans);
 
-       if (s < sizeof(struct ieee8023)) {
+       if (s < sizeof(struct ethllc) + sizeof(struct cdp_header)) {
                LLOG_WARNX("too short frame received on %s", hardware->h_ifname);
                goto malformed;
        }
 
-       ether = (struct ieee8023*)frame;
-       if (memcmp(&ether->dhost, cdpaddr, sizeof(cdpaddr)) != 0) {
+       llc = (struct ethllc *)frame;
+       if (memcmp(&llc->ether.dhost, cdpaddr, sizeof(cdpaddr)) != 0) {
                LLOG_INFO("frame not targeted at CDP multicast address received on %s",
                    hardware->h_ifname);
                goto malformed;
        }
-
-       /* Is it a CDP frame encapsulated into a VLAN? */
-       if (ether->size == htons(ETHERTYPE_VLAN)) {
-               if (s < sizeof(struct ieee8023) + sizeof(struct ieee8021q) +
-                   sizeof(struct llc) + sizeof(struct cdp_header)) {
-                       LLOG_WARNX("too short frame received on %s", hardware->h_ifname);
-                       goto malformed;
-               }
-               if (ntohs(((struct ieee8021q*)(frame +
-                               sizeof(struct ieee8023)))->size) >
-                   s - sizeof(struct ieee8023) - sizeof(struct ieee8021q)) {
-                       LLOG_WARNX("incorrect 802.3/802.1q frame size reported on %s",
-                           hardware->h_ifname);
-                       goto malformed;
-               }
-               llc = (struct llc*)(frame + sizeof(struct ieee8023) +
-                   sizeof(struct ieee8021q));
-       } else {
-               if (s < sizeof(struct ethllc) + sizeof(struct cdp_header)) {
-                       LLOG_WARNX("too short frame received on %s", hardware->h_ifname);
-                       goto malformed;
-               }
-
-               if (ntohs(ether->size) > s - sizeof(struct ieee8023)) {
-                       LLOG_WARNX("incorrect 802.3 frame size reported on %s",
-                           hardware->h_ifname);
-                       goto malformed;
-               }
-               llc = (struct llc*)(frame + sizeof(struct ieee8023));
+       if (ntohs(llc->ether.size) > s - sizeof(struct ieee8023)) {
+               LLOG_WARNX("incorrect 802.3 frame size reported on %s",
+                   hardware->h_ifname);
+               goto malformed;
        }
        if (llc->protoid != htons(LLC_PID_CDP)) {
                if ((llc->protoid != htons(LLC_PID_DRIP)) &&
@@ -249,7 +223,7 @@ cdp_decode(struct lldpd *cfg, char *frame, int s,
                            hardware->h_ifname);
                goto malformed;
        }
-       f = (void*)llc - (void*)frame + sizeof(struct llc);
+       f = sizeof(struct ethllc);
        ch = (struct cdp_header *)(frame + f);
        if ((ch->version != 1) && (ch->version != 2)) {
                LLOG_WARNX("incorrect CDP version (%d) for frame received on %s",
@@ -353,7 +327,7 @@ cdp_decode(struct lldpd *cfg, char *frame, int s,
                                LLOG_WARN("unable to allocate memory for port ID");
                                goto malformed;
                        }
-                       memcpy(port->p_id, ether->shost, ETH_ALEN);
+                       memcpy(port->p_id, llc->ether.shost, ETH_ALEN);
                        port->p_id_len = ETH_ALEN;
                        f += len;
                        break;
@@ -466,25 +440,11 @@ cdp_guess(char *frame, int len, int version)
 {
        const u_int8_t mcastaddr[] = CDP_MULTICAST_ADDR;
        struct cdp_header *ch;
-       if (len < sizeof(struct ieee8023))
+       if (len < sizeof(struct ethllc) + sizeof(struct cdp_header))
                return 0;
        if (memcmp(frame, mcastaddr, ETH_ALEN) != 0)
                return 0;
-       /* Maybe this is encapsulated into a VLAN */
-       if (((struct ieee8023*)frame)->size != htons(ETHERTYPE_VLAN)) {
-               /* Not a 802.1q frame */
-               if (len < sizeof(struct ethllc) +
-                   sizeof(struct cdp_header))
-                       return 0;
-               ch = (struct cdp_header *)(frame + sizeof(struct ethllc));
-       } else {
-               /* 802.1q frame */
-               if (len < sizeof(struct ieee8023) + sizeof(struct ieee8021q) +
-                   sizeof(struct llc) + sizeof(struct cdp_header))
-                       return 0;
-               ch = (struct cdp_header *)(frame + sizeof(struct ieee8023) +
-                   sizeof(struct ieee8021q) + sizeof(struct llc));
-       }
+       ch = (struct cdp_header *)(frame + sizeof(struct ethllc));
        return (ch->version == version);
 }
 
index ecc8546d042ddbc9eb361336a20bb62192cb7a86..0275074d92cf3522929df41b88ee1d26c7fa5d3d 100644 (file)
--- a/src/edp.c
+++ b/src/edp.c
@@ -60,10 +60,10 @@ edp_send(struct lldpd *global, struct lldpd_chassis *chassis,
                    sizeof(llc.ether.shost));
                memcpy(&llc.ether.dhost, &mcastaddr,
                    sizeof(llc.ether.dhost));
-               llc.llc.dsap = llc.llc.ssap = 0xaa;
-               llc.llc.control = 0x03;
-               memcpy(llc.llc.org, llcorg, sizeof(llc.llc.org));
-               llc.llc.protoid = htons(LLC_PID_EDP);
+               llc.dsap = llc.ssap = 0xaa;
+               llc.control = 0x03;
+               memcpy(llc.org, llcorg, sizeof(llc.org));
+               llc.protoid = htons(LLC_PID_EDP);
                IOV_NEW;
                iov[c].iov_base = &llc;
                iov[c].iov_len = sizeof(llc);
@@ -241,7 +241,7 @@ edp_decode(struct lldpd *cfg, char *frame, int s,
                    hardware->h_ifname);
                goto malformed;
        }
-       if (llc->llc.protoid != htons(LLC_PID_EDP)) {
+       if (llc->protoid != htons(LLC_PID_EDP)) {
                LLOG_DEBUG("incorrect LLC protocol ID received on %s",
                    hardware->h_ifname);
                goto malformed;
index 0ca0651f22e909631065c087cc6f7fd1cf3019fb..002ccf1817c164032acd7d48908916d5536c292c 100644 (file)
--- a/src/llc.h
+++ b/src/llc.h
@@ -23,12 +23,8 @@ struct ieee8023 {
        u_int16_t size;         /* packet type ID field */
 } __attribute__ ((__packed__));
 
-struct ieee8021q {
-       u_int16_t vid;
-       u_int16_t size;
-} __attribute__ ((__packed__));
-
-struct llc {
+struct ethllc {
+       struct ieee8023 ether;
        u_int8_t  dsap;         /* destination SAP */
        u_int8_t  ssap;         /* source SAP */
        u_int8_t  control;              /* LLC control field */
@@ -36,10 +32,4 @@ struct llc {
        u_int16_t protoid;
 } __attribute__ ((__packed__));
 
-/* IEEE 802.3 + LLC */
-struct ethllc {
-       struct ieee8023 ether;
-       struct llc llc;
-} __attribute__ ((__packed__));
-
 #endif
index c4e48fddbd874c20ceda8b279b5117799e864cfa..e4161b5f37f5f9ee0bc53f31e2bf75ceac7c806d 100644 (file)
@@ -64,20 +64,14 @@ void                         lldpd_iface_multicast(struct lldpd *, const char *, int);
         { 0x6, 0, 0, 0x0000ffff },                                     \
         { 0x6, 0, 0, 0x00000000 },
 struct sock_filter lldpd_filter_lldp_f[] = { LLDPD_FILTER_LLDP_F };
-/* "(ether dst 01:00:0c:cc:cc:cc) or (vlan and ether dst 01:00:0c:cc:cc:cc)" */
+/* "ether dst 01:00:0c:cc:cc:cc" */
 #define LLDPD_FILTER_CDP_F                     \
-       { 0x20, 0, 0, 0x00000002 },             \
-       { 0x15, 0, 2, 0x0ccccccc },             \
-       { 0x28, 0, 0, 0x00000000 },             \
-       { 0x15, 6, 0, 0x00000100 },             \
-       { 0x28, 0, 0, 0x0000000c },             \
-       { 0x15, 0, 5, 0x00008100 },             \
-       { 0x20, 0, 0, 0x00000002 },             \
-       { 0x15, 0, 3, 0x0ccccccc },             \
-       { 0x28, 0, 0, 0x00000000 },             \
-       { 0x15, 0, 1, 0x00000100 },             \
-       { 0x6, 0, 0, 0x0000ffff },              \
-       { 0x6, 0, 0, 0x00000000 },
+        { 0x20, 0, 0, 0x00000002 },            \
+        { 0x15, 0, 3, 0x0ccccccc },            \
+        { 0x28, 0, 0, 0x00000000 },            \
+        { 0x15, 0, 1, 0x00000100 },            \
+        { 0x6, 0, 0, 0x0000ffff },             \
+        { 0x6, 0, 0, 0x00000000 },
 struct sock_filter lldpd_filter_cdp_f[] = { LLDPD_FILTER_CDP_F };
 /* "ether dst 01:00:81:00:01:00" */
 #define LLDPD_FILTER_SONMP_F                   \
index 19f9caa455da93a76103e9d713cd5f385ce6d9c0..19067c70850a4ec30a5c866837603c09fd3e443a 100644 (file)
@@ -190,10 +190,10 @@ sonmp_send(struct lldpd *global, struct lldpd_chassis *chassis,
            sizeof(frame.llc.ether.dhost));
        frame.llc.ether.size = htons(sizeof(struct sonmp) -
            sizeof(struct ieee8023));
-       frame.llc.llc.dsap = frame.llc.llc.ssap = 0xaa;
-       frame.llc.llc.control = 0x03;
-       memcpy(frame.llc.llc.org, llcorg, sizeof(frame.llc.llc.org));
-       frame.llc.llc.protoid = htons(LLC_PID_SONMP_HELLO);
+       frame.llc.dsap = frame.llc.ssap = 0xaa;
+       frame.llc.control = 0x03;
+       memcpy(frame.llc.org, llcorg, sizeof(frame.llc.org));
+       frame.llc.protoid = htons(LLC_PID_SONMP_HELLO);
        memcpy(&frame.addr, &chassis->c_mgmt, sizeof(struct in_addr));
        frame.seg[2] = if_nametoindex(hardware->h_ifname);
        frame.chassis = 1;      /* Other */
@@ -208,7 +208,7 @@ sonmp_send(struct lldpd *global, struct lldpd_chassis *chassis,
                return ENETDOWN;
        }
 
-       frame.llc.llc.protoid = htons(LLC_PID_SONMP_FLATNET);
+       frame.llc.protoid = htons(LLC_PID_SONMP_FLATNET);
        frame.llc.ether.dhost[ETH_ALEN-1] = 1;
 
        if (write((hardware->h_raw_real > 0) ? hardware->h_raw_real :
@@ -255,7 +255,7 @@ sonmp_decode(struct lldpd *cfg, char *frame, int s,
                 * them. */
                goto malformed;
        }
-       if (f->llc.llc.protoid != htons(LLC_PID_SONMP_HELLO)) {
+       if (f->llc.protoid != htons(LLC_PID_SONMP_HELLO)) {
                LLOG_DEBUG("incorrect LLC protocol ID received on %s",
                    hardware->h_ifname);
                goto malformed;