]> git.ipfire.org Git - thirdparty/lldpd.git/commitdiff
Simplify multiprotocols handling.
authorVincent Bernat <bernat@luffy.cx>
Sat, 23 May 2009 13:04:22 +0000 (15:04 +0200)
committerVincent Bernat <bernat@luffy.cx>
Sun, 24 May 2009 19:29:22 +0000 (21:29 +0200)
Remove probing. This is not very usable for now but this will be
enhanced when we will support multiple systems on the same port.

man/lldpd.8
src/lldp.c
src/lldpd.c
src/lldpd.h

index 6f0007377de5ff05ac19e3135c8e98c5b5c05135..243e1d903d4932ec31c2271a3b25746f9d92415c 100644 (file)
@@ -23,7 +23,6 @@
 .Nm
 .Op Fl dxcsei
 .Op Fl m Ar management
-.Op Fl p Ar probe time
 .Op Fl M Ar class
 .Sh DESCRIPTION
 .Nm
@@ -79,13 +78,6 @@ Specify the management address of this system.
 only sends one management address. It will use the first one that it
 finds or the one that you specify with this option. This option can
 use wildcards.
-.It Fl p Ar probe time
-Specify the time to wait (in seconds) before accepting a given
-protocol. This time will be used by
-.Nm
-to detect false positives like SONMP frames running through a switch
-only supporting CDP. This value is only used when multiple protocols
-are enabled.
 .It Fl M Ar class
 Enable emission of LLDP-MED frame. The class should be one of the
 following value:
index d03e955df28adef528f71eb250d8cb1107b389d1..5efce357c91e83bd0d91ce5ed0f0ec63599aa6e3 100644 (file)
@@ -263,21 +263,16 @@ lldp_send(struct lldpd *global, struct lldpd_chassis *chassis,
              POKE_END_LLDP_TLV))
                goto toobig;
 
-       if (!global->g_multi ||
-           (hardware->h_mode == LLDPD_MODE_ANY) ||
-           (hardware->h_mode == LLDPD_MODE_LLDP)) {
-               
-               if (write(hardware->h_raw, packet, 
-                       pos - packet) == -1) {
-                       LLOG_WARN("unable to send packet on real device for %s",
-                           hardware->h_ifname);
-                       free(packet);
-                       return ENETDOWN;
-               }
-
-               hardware->h_tx_cnt++;
+       if (write(hardware->h_raw, packet,
+               pos - packet) == -1) {
+               LLOG_WARN("unable to send packet on real device for %s",
+                   hardware->h_ifname);
+               free(packet);
+               return ENETDOWN;
        }
 
+       hardware->h_tx_cnt++;
+
        /* We assume that LLDP frame is the reference */
        if ((frame = (struct lldpd_frame*)malloc(
                        sizeof(int) + pos - packet)) != NULL) {
index 577613e6a5a8377d4d860c6a2505c23c72d5dd9b..1b8214252fc65ceb6904f9b9925dfc1ef1a46cc4 100644 (file)
@@ -53,62 +53,12 @@ static void          lldpd_iface_init_mtu(struct lldpd *, struct lldpd_hardware *);
 static int              lldpd_iface_close(struct lldpd *, struct lldpd_hardware *);
 static void             lldpd_iface_multicast(struct lldpd *, const char *, int);
 
-/* "ether proto 0x88cc and ether dst 01:80:c2:00:00:0e" */
-#define LLDPD_FILTER_LLDP_F                                            \
-       { 0x28, 0, 0, 0x0000000c },                                     \
-        { 0x15, 0, 5, 0x000088cc },                                    \
-        { 0x20, 0, 0, 0x00000002 },                                    \
-        { 0x15, 0, 3, 0xc200000e },                                    \
-        { 0x28, 0, 0, 0x00000000 },                                    \
-        { 0x15, 0, 1, 0x00000180 },                                    \
-        { 0x6, 0, 0, 0x0000ffff },                                     \
-        { 0x6, 0, 0, 0x00000000 },
-static struct sock_filter lldpd_filter_lldp_f[] = { LLDPD_FILTER_LLDP_F };
-#ifdef ENABLE_FDP
-/* "ether dst 01:e0:52:cc:cc:cc" */
-#define LLDPD_FILTER_FDP_F                     \
-        { 0x20, 0, 0, 0x00000002 },            \
-        { 0x15, 0, 3, 0x52cccccc },            \
-        { 0x28, 0, 0, 0x00000000 },            \
-        { 0x15, 0, 1, 0x000001e0 },            \
-        { 0x6, 0, 0, 0x0000ffff },             \
-        { 0x6, 0, 0, 0x00000000 },
-static struct sock_filter lldpd_filter_fdp_f[] = { LLDPD_FILTER_FDP_F };
-#endif /* ENABLE_FDP */
-#ifdef ENABLE_CDP
-/* "ether dst 01:00:0c:cc:cc:cc" */
-#define LLDPD_FILTER_CDP_F                     \
-        { 0x20, 0, 0, 0x00000002 },            \
-        { 0x15, 0, 3, 0x0ccccccc },            \
-        { 0x28, 0, 0, 0x00000000 },            \
-        { 0x15, 0, 1, 0x00000100 },            \
-        { 0x6, 0, 0, 0x0000ffff },             \
-        { 0x6, 0, 0, 0x00000000 },
-static struct sock_filter lldpd_filter_cdp_f[] = { LLDPD_FILTER_CDP_F };
-#endif /* ENABLE_CDP */
-#ifdef ENABLE_SONMP
-/* "ether dst 01:00:81:00:01:00" */
-#define LLDPD_FILTER_SONMP_F                   \
-        { 0x20, 0, 0, 0x00000002 },            \
-        { 0x15, 0, 3, 0x81000100 },            \
-        { 0x28, 0, 0, 0x00000000 },            \
-        { 0x15, 0, 1, 0x00000100 },            \
-        { 0x6, 0, 0, 0x0000ffff },             \
-        { 0x6, 0, 0, 0x00000000 },
-static struct sock_filter lldpd_filter_sonmp_f[] = { LLDPD_FILTER_SONMP_F };
-#endif /* ENABLE_SONMP */
-#ifdef ENABLE_EDP
-/* "ether dst 00:e0:2b:00:00:00" */
-#define LLDPD_FILTER_EDP_F              \
-       { 0x20, 0, 0, 0x00000002 },     \
-       { 0x15, 0, 3, 0x2b000000 },     \
-       { 0x28, 0, 0, 0x00000000 },     \
-       { 0x15, 0, 1, 0x000000e0 },     \
-       { 0x6, 0, 0, 0x0000ffff },      \
-       { 0x6, 0, 0, 0x00000000 },
-static struct sock_filter lldpd_filter_edp_f[] = { LLDPD_FILTER_EDP_F };
-#endif /* ENABLE_EDP */
-#define LLDPD_FILTER_ANY_F             \
+/* LLDP: "ether proto 0x88cc and ether dst 01:80:c2:00:00:0e" */
+/* FDP: "ether dst 01:e0:52:cc:cc:cc" */
+/* CDP: "ether dst 01:00:0c:cc:cc:cc" */
+/* SONMP: "ether dst 01:00:81:00:01:00" */
+/* EDP: "ether dst 00:e0:2b:00:00:00" */
+#define LLDPD_FILTER_F                 \
        { 0x28, 0, 0, 0x0000000c },     \
        { 0x15, 0, 4, 0x000088cc },     \
        { 0x20, 0, 0, 0x00000002 },     \
@@ -128,36 +78,34 @@ static struct sock_filter lldpd_filter_edp_f[] = { LLDPD_FILTER_EDP_F };
        { 0x15, 0, 1, 0x000001e0 },     \
        { 0x6, 0, 0, 0x0000ffff },      \
        { 0x6, 0, 0, 0x00000000 },
-static struct sock_filter lldpd_filter_any_f[] = { LLDPD_FILTER_ANY_F };
+static struct sock_filter lldpd_filter_f[] = { LLDPD_FILTER_F };
 
 static struct protocol protos[] =
 {
        { LLDPD_MODE_LLDP, 1, "LLDP", ' ', lldp_send, lldp_decode, NULL,
-         LLDP_MULTICAST_ADDR, lldpd_filter_lldp_f, sizeof(lldpd_filter_lldp_f) },
+         LLDP_MULTICAST_ADDR },
 #ifdef ENABLE_CDP
        { LLDPD_MODE_CDPV1, 0, "CDPv1", 'c', cdpv1_send, cdp_decode, cdpv1_guess,
-         CDP_MULTICAST_ADDR, lldpd_filter_cdp_f, sizeof(lldpd_filter_cdp_f) },
+         CDP_MULTICAST_ADDR },
        { LLDPD_MODE_CDPV2, 0, "CDPv2", 'c', cdpv2_send, cdp_decode, cdpv2_guess,
-         CDP_MULTICAST_ADDR, lldpd_filter_cdp_f, sizeof(lldpd_filter_cdp_f) },
+         CDP_MULTICAST_ADDR },
 #endif
 #ifdef ENABLE_SONMP
        { LLDPD_MODE_SONMP, 0, "SONMP", 's', sonmp_send, sonmp_decode, NULL,
-         SONMP_MULTICAST_ADDR, lldpd_filter_sonmp_f, sizeof(lldpd_filter_sonmp_f) },
+         SONMP_MULTICAST_ADDR },
 #endif
 #ifdef ENABLE_EDP
        { LLDPD_MODE_EDP, 0, "EDP", 'e', edp_send, edp_decode, NULL,
-         EDP_MULTICAST_ADDR, lldpd_filter_edp_f, sizeof(lldpd_filter_edp_f) },
+         EDP_MULTICAST_ADDR },
 #endif
 #ifdef ENABLE_FDP
        { LLDPD_MODE_FDP, 0, "FDP", 'f', fdp_send, cdp_decode, NULL,
-         FDP_MULTICAST_ADDR, lldpd_filter_fdp_f, sizeof(lldpd_filter_fdp_f) },
+         FDP_MULTICAST_ADDR },
 #endif
        { 0, 0, "any", ' ', NULL, NULL, NULL,
-         {0,0,0,0,0,0}, lldpd_filter_any_f, sizeof(lldpd_filter_any_f) }
+         {0,0,0,0,0,0} }
 };
 
-static int              lldpd_iface_switchto(struct lldpd *, short int,
-                           struct lldpd_hardware *);
 static
 struct lldpd_hardware  *lldpd_port_add(struct lldpd *, struct ifaddrs *);
 static void             lldpd_loop(struct lldpd *);
@@ -202,19 +150,19 @@ static int
 lldpd_iface_init(struct lldpd *global, struct lldpd_hardware *hardware)
 {
        int status;
-       short int filter;
+       struct sock_fprog prog;
 
        lldpd_iface_init_mtu(global, hardware);
        status = priv_iface_init(hardware, -1);
        if (status != 0)
                return status;
 
-       if (global->g_multi)
-               filter = LLDPD_MODE_ANY;
-       else
-               filter = LLDPD_MODE_LLDP;
-       if (lldpd_iface_switchto(global, filter, hardware) == -1) {
-               LLOG_WARNX("unable to apply filter");
+       /* Set filter */
+       prog.filter = lldpd_filter_f;
+       prog.len = sizeof(lldpd_filter_f) / sizeof(struct sock_filter);
+       if (setsockopt(hardware->h_raw, SOL_SOCKET, SO_ATTACH_FILTER,
+                &prog, sizeof(prog)) < 0) {
+               LLOG_WARN("unable to change filter for %s", hardware->h_ifname);
                return ENETDOWN;
        }
 
@@ -258,28 +206,6 @@ lldpd_iface_close(struct lldpd *global, struct lldpd_hardware *hardware)
        return 0;
 }
 
-static int
-lldpd_iface_switchto(struct lldpd *cfg, short int filter, struct lldpd_hardware *hardware)
-{
-       struct sock_fprog prog;
-       int i;
-
-       memset(&prog, 0, sizeof(prog));
-       for (i=0; cfg->g_protocols[i].mode != 0; i++) {
-               if (!cfg->g_protocols[i].enabled) continue;
-               if (cfg->g_protocols[i].mode == filter)
-                       break;
-       }
-       prog.filter = cfg->g_protocols[i].filter;
-       prog.len = cfg->g_protocols[i].filterlen / sizeof(struct sock_filter);
-       if (setsockopt(hardware->h_raw, SOL_SOCKET, SO_ATTACH_FILTER,
-                &prog, sizeof(prog)) < 0) {
-               LLOG_WARN("unable to change filter for %s", hardware->h_ifname);
-               return -1;
-       }
-       return 0;
-}
-
 #ifdef ENABLE_DOT1
 void
 lldpd_vlan_cleanup(struct lldpd_port *port)
@@ -349,19 +275,12 @@ lldpd_remote_cleanup(struct lldpd *cfg, struct lldpd_hardware *hardware, int res
        hardware->h_rlastchange = hardware->h_rlastupdate = 0;
        free(hardware->h_rlastframe);
        hardware->h_rlastframe = NULL;
-       if (reset && cfg->g_multi) {
-               hardware->h_mode = LLDPD_MODE_ANY;
-               memset(hardware->h_proto_macs, 0, ETH_ALEN*(cfg->g_multi+1));
-               hardware->h_start_probe = 0;
-               lldpd_iface_switchto(cfg, LLDPD_MODE_ANY, hardware);
-       }
 }
 
 void
 lldpd_hardware_cleanup(struct lldpd_hardware *hardware)
 {
        lldpd_port_cleanup(&hardware->h_lport, 1);
-       free(hardware->h_proto_macs);
        free(hardware->h_llastframe);
        free(hardware);
 }
@@ -416,8 +335,6 @@ lldpd_port_add(struct lldpd *cfg, struct ifaddrs *ifa)
                    calloc(1, sizeof(struct lldpd_hardware))) == NULL)
                        return (NULL);
                hardware->h_raw = -1;
-               hardware->h_start_probe = 0;
-               hardware->h_proto_macs = (u_int8_t*)calloc(cfg->g_multi+1, ETH_ALEN);
 #ifdef ENABLE_LLDPMED
                if (cfg->g_lchassis.c_med_cap_available) {
                        hardware->h_lport.p_med_cap_enabled = LLDPMED_CAP_CAP;
@@ -630,93 +547,21 @@ lldpd_decode(struct lldpd *cfg, char *frame, int s,
                return;
        }
 
-       if (cfg->g_multi) {
-               if (hardware->h_mode == LLDPD_MODE_ANY)
-                       guess = lldpd_guess_type(cfg, frame, s);
-               else
-                       guess = hardware->h_mode;
-               for (i=0; cfg->g_protocols[i].mode != 0; i++) {
-                       if (!cfg->g_protocols[i].enabled)
-                               continue;
-                       if (cfg->g_protocols[i].mode == guess) {
-                               if ((result = cfg->g_protocols[i].decode(cfg, frame,
-                                           s, hardware, &chassis, &port)) == -1)
-                                       return;
-                               break;
+       guess = lldpd_guess_type(cfg, frame, s);
+       for (i=0; cfg->g_protocols[i].mode != 0; i++) {
+               if (!cfg->g_protocols[i].enabled)
+                       continue;
+               if (cfg->g_protocols[i].mode == guess) {
+                       if ((result = cfg->g_protocols[i].decode(cfg, frame,
+                                   s, hardware, &chassis, &port)) == -1)
+                               return;
+                       break;
                        }
-               }
-               if (cfg->g_protocols[i].mode == 0) {
-                       LLOG_INFO("unable to guess frame type");
-                       return;
-               }
-       } else if (cfg->g_protocols[0].decode(cfg, frame, s, hardware,
-               &chassis, &port) == -1)
-               /* Nothing has been received */
+       }
+       if (cfg->g_protocols[i].mode == 0) {
+               LLOG_INFO("unable to guess frame type");
                return;
-
-       if (cfg->g_multi &&
-           (hardware->h_mode == LLDPD_MODE_ANY)) {
-               u_int8_t *mac;
-               char *modename;
-               int filter;
-               
-               for (i=j=0; cfg->g_protocols[i].mode != 0; i++) {
-                       if (!cfg->g_protocols[i].enabled)
-                               continue;
-                       if (cfg->g_protocols[i].mode == guess) {
-                               mac = hardware->h_proto_macs + ETH_ALEN*j;
-                               modename = cfg->g_protocols[i].name;
-                               filter = cfg->g_protocols[i].mode;
-                               break;
-                       }
-                       j++;
-               }
-               if (cfg->g_protocols[i].mode == 0) {
-                       LLOG_WARNX("should not be there");
-                       goto cleanup;
-               }
-
-               if (hardware->h_start_probe == 0)
-                       hardware->h_start_probe = time(NULL) - 1;
-               /* Handle switching respecting probe time */
-               if ((memcmp(mac, frame + ETH_ALEN, ETH_ALEN) == 0) &&
-                   ((time(NULL) - hardware->h_start_probe) > cfg->g_probe_time) &&
-                   /* Don't switch to this protocol if not LLDP and LLDP is
-                    * a valid candidate */
-                   ((filter == LLDPD_MODE_LLDP) ||
-                       (memcmp(hardware->h_proto_macs,
-                           broadcastmac, ETH_ALEN) == 0) ||
-                       (memcmp(hardware->h_proto_macs,
-                           nullmac, ETH_ALEN) == 0))) {
-                       LLOG_INFO("switching to %s on port %s", modename,
-                           hardware->h_ifname);
-                       hardware->h_mode = guess;
-                       lldpd_iface_switchto(cfg, filter, hardware);
-               } else {
-                       /* Wait twice probe time to be able to receive packets of all kind */
-                       if ((time(NULL) - hardware->h_start_probe) > cfg->g_probe_time * 2) {
-                               LLOG_DEBUG("probe expired on %s, retry", hardware->h_ifname);
-                               hardware->h_start_probe = 0;
-                               memset(hardware->h_proto_macs, 0, ETH_ALEN*(cfg->g_multi+1));
-                               goto cleanup;
-                       }
-                       if (memcmp(mac, broadcastmac, ETH_ALEN) == 0)
-                               goto cleanup;
-                       LLOG_INFO("received a %s frame on %s but wait for %d sec",
-                           modename, hardware->h_ifname, cfg->g_probe_time - time(NULL) +
-                           hardware->h_start_probe);
-                       if (memcmp(mac, frame + ETH_ALEN, ETH_ALEN) == 0)
-                               goto cleanup;
-                       if (memcmp(mac, nullmac, ETH_ALEN) == 0) {
-                               memcpy(mac, frame + ETH_ALEN, ETH_ALEN);
-                               goto cleanup;
-                       }
-                       LLOG_INFO("several MAC for %s on %s, discarding %s for this interface",
-                           modename, hardware->h_ifname, modename);
-                       memcpy(mac, broadcastmac, ETH_ALEN);
-                       goto cleanup;
-                }
-        }
+       }
 
        result = 0;
        if ((hardware->h_rchassis == NULL) ||
@@ -927,9 +772,7 @@ lldpd_send_all(struct lldpd *cfg)
                for (i=0; cfg->g_protocols[i].mode != 0; i++) {
                        if (!cfg->g_protocols[i].enabled)
                                continue;
-                       if ((hardware->h_mode == cfg->g_protocols[i].mode) ||
-                           (cfg->g_protocols[i].mode == LLDPD_MODE_LLDP))
-                               cfg->g_protocols[i].send(cfg, &cfg->g_lchassis, hardware);
+                       cfg->g_protocols[i].send(cfg, &cfg->g_lchassis, hardware);
                }
        }
 }
@@ -1103,7 +946,7 @@ main(int argc, char *argv[])
 #endif
        char *mgmtp = NULL;
        char *popt, opts[] = "dxm:p:M:i@                    ";
-       int probe = 0, i, found;
+       int i, found;
 #ifdef ENABLE_LLDPMED
        int lldpmed = 0, noinventory = 0;
 #endif
@@ -1146,9 +989,6 @@ main(int argc, char *argv[])
                        usage();
                        break;
 #endif
-               case 'p':
-                       probe = atoi(optarg);
-                       break;
                case 'x':
 #ifdef USE_SNMP
                        snmp = 1;
@@ -1191,8 +1031,6 @@ main(int argc, char *argv[])
 
        priv_init(PRIVSEP_CHROOT);
 
-       if (probe == 0) probe = LLDPD_TTL;
-
        if ((cfg = (struct lldpd *)
            calloc(1, sizeof(struct lldpd))) == NULL)
                fatal(NULL);
@@ -1223,14 +1061,11 @@ main(int argc, char *argv[])
        cfg->g_lchassis.c_ttl = LLDPD_TTL;
 
        cfg->g_protocols = protos;
-       cfg->g_probe_time = probe;
        for (i=0; protos[i].mode != 0; i++)
                if (protos[i].enabled) {
-                       cfg->g_multi++;
                        LLOG_INFO("protocol %s enabled", protos[i].name);
                } else
                        LLOG_INFO("protocol %s disabled", protos[i].name);
-       cfg->g_multi--;
 
        TAILQ_INIT(&cfg->g_hardware);
 
index baaac1778a569a12a9101d0c7c6c8bab2044913f..31059f08bb7828157b10ea3b0f950f65ba2a2631 100644 (file)
@@ -191,15 +191,6 @@ struct lldpd_hardware {
        
        int                      h_raw;
 
-#define LLDPD_MODE_ANY 0
-#define LLDPD_MODE_LLDP 1
-#define LLDPD_MODE_CDPV1 2
-#define LLDPD_MODE_CDPV2 3
-#define LLDPD_MODE_SONMP 4
-#define LLDPD_MODE_EDP 5
-#define LLDPD_MODE_FDP 6
-       int                      h_mode;
-
        int                      h_flags;
        int                      h_mtu;
        char                     h_ifname[IFNAMSIZ];
@@ -211,9 +202,6 @@ struct lldpd_hardware {
        u_int64_t                h_rx_ageout_cnt;
        u_int64_t                h_rx_unrecognized_cnt;
 
-       u_int8_t                *h_proto_macs;
-       time_t                   h_start_probe;
-
        struct lldpd_port        h_lport;
        time_t                   h_llastchange;
        struct lldpd_frame      *h_llastframe;
@@ -243,6 +231,12 @@ struct lldpd_client {
 
 struct lldpd;
 struct protocol {
+#define LLDPD_MODE_LLDP 1
+#define LLDPD_MODE_CDPV1 2
+#define LLDPD_MODE_CDPV2 3
+#define LLDPD_MODE_SONMP 4
+#define LLDPD_MODE_EDP 5
+#define LLDPD_MODE_FDP 6
        int              mode;          /* > 0 mode identifier (unique per protocol) */
        int              enabled;       /* Is this protocol enabled? */
        char            *name;          /* Name of protocol */
@@ -260,8 +254,6 @@ struct lldpd {
        int                      g_delay;
 
        struct protocol         *g_protocols;
-       int                      g_multi; /* Set to 1 if multiple protocols */
-       int                      g_probe_time;
 #ifdef ENABLE_LLDPMED
        int                      g_noinventory;
 #endif