]> git.ipfire.org Git - thirdparty/lldpd.git/commitdiff
lldpd: decrease probability of collisions on port checksums
authorVincent Bernat <vincent@bernat.im>
Thu, 4 Dec 2014 00:02:29 +0000 (01:02 +0100)
committerVincent Bernat <vincent@bernat.im>
Thu, 4 Dec 2014 00:02:29 +0000 (01:02 +0100)
Instead of a 16-bit checksum, we use two 16-bit checkums, one for each
half of the serialized port. We now need more than 70000 ports to get a
50% chance of collision while we previously needed only 300 ports.

src/daemon/lldpd.c
src/lldpd-structs.h

index 8de5187b4fa1a7112c06546bd0f383f2c89ccec0..e658e564639b7f0230932144f2e686d63cb5708b 100644 (file)
@@ -296,7 +296,7 @@ lldpd_reset_timer(struct lldpd *cfg)
                 * we zero out fields that are not significant, marshal the
                 * port, compute the checksum, then restore. */
                struct lldpd_port *port = &hardware->h_lport;
-               u_int16_t cksum;
+               u_int32_t cksum;
                u_int8_t *output = NULL;
                ssize_t output_len;
                char save[offsetof(struct lldpd_port, p_id_subtype)];
@@ -314,7 +314,9 @@ lldpd_reset_timer(struct lldpd *cfg)
                }
                /* Port change is detected by computing a checksum. 0 means the
                 * checksum never was computed (new interface). */
-               cksum  = frame_checksum(output, output_len, 0);
+               cksum  = frame_checksum(output, output_len/2, 0) << 16;
+               cksum += frame_checksum(output + output_len/2,
+                   output_len - output_len/2, 0);
                cksum  = cksum?cksum:1;
                free(output);
                if (cksum != hardware->h_lport_cksum) {
index de134dbfc09cb0e94915e3f563668dc2ec7f3466..5455e9cc382ee98ebd5ef674a47f6798271bb936 100644 (file)
@@ -398,7 +398,7 @@ struct lldpd_hardware {
        u_int64_t                h_delete_cnt;
        u_int64_t                h_drop_cnt;
 
-       u_int16_t                h_lport_cksum; /* Checksum on local port to see if there is a change */
+       u_int32_t                h_lport_cksum; /* Checksum on local port to see if there is a change */
        struct lldpd_port        h_lport;  /* Port attached to this hardware port */
        TAILQ_HEAD(, lldpd_port) h_rports; /* Remote ports */