summaryrefslogtreecommitdiffstats
path: root/bfdd
diff options
context:
space:
mode:
authorIgor Ryzhov <iryzhov@nfware.com>2021-06-01 19:30:13 +0200
committerIgor Ryzhov <iryzhov@nfware.com>2021-06-02 19:58:35 +0200
commit03e3333b110e737c49f97113ef0baab679488019 (patch)
treea96306b756a5faa0f5ebfec9aff282fbf567c429 /bfdd
parentMerge pull request #8748 from idryzhov/ospf6-vrf-unlink (diff)
downloadfrr-03e3333b110e737c49f97113ef0baab679488019.tar.xz
frr-03e3333b110e737c49f97113ef0baab679488019.zip
bfdd: fix bfd key structure
There's a padding byte between "mhop" and "peer" fields in this structure. This structure is sometimes passed by value to functions and used in assignments. The standard doesn't guarantee that the padding bytes are copied on assignments. As this structure is used as a hash key, having this padding byte with unspecified value can lead to unwanted behavior. Fix the possible issue by making the "mhop" field to be 2 bytes. Also make the struct packed as a precaution for future changes. Signed-off-by: Igor Ryzhov <iryzhov@nfware.com>
Diffstat (limited to 'bfdd')
-rw-r--r--bfdd/bfd.h17
1 files changed, 14 insertions, 3 deletions
diff --git a/bfdd/bfd.h b/bfdd/bfd.h
index d9d5d8cb5..7d5b7887c 100644
--- a/bfdd/bfd.h
+++ b/bfdd/bfd.h
@@ -173,15 +173,26 @@ enum bfd_session_flags {
BFD_SESS_FLAG_PASSIVE = 1 << 10, /* Passive mode */
};
-/* BFD session hash keys */
+/*
+ * BFD session hash key.
+ *
+ * This structure must not have any padding bytes because their value is
+ * unspecified after the struct assignment. Even when all fields of two keys
+ * are the same, if the padding bytes are different, then the calculated hash
+ * value is different, and the hash lookup will fail.
+ *
+ * Currently, the structure fields are correctly aligned, and the "packed"
+ * attribute is added as a precaution. "family" and "mhop" fields are two-bytes
+ * to eliminate unaligned memory access to "peer" and "local".
+ */
struct bfd_key {
uint16_t family;
- uint8_t mhop;
+ uint16_t mhop;
struct in6_addr peer;
struct in6_addr local;
char ifname[MAXNAMELEN];
char vrfname[MAXNAMELEN];
-};
+} __attribute__((packed));
struct bfd_session_stats {
uint64_t rx_ctrl_pkt;