summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDonatas Abraitis <donatas@opensourcerouting.org>2023-06-08 19:12:29 +0200
committerGitHub <noreply@github.com>2023-06-08 19:12:29 +0200
commitf158bb770d51cd9ec95bd863aa30aaf6325420f6 (patch)
tree514565c4b3ebdafec5c30edf734f07f528790c50
parentMerge pull request #13650 from opensourcerouting/feature/bgpd_default_origina... (diff)
parentbfd: fix missing Authentication in control pkt (diff)
downloadfrr-f158bb770d51cd9ec95bd863aa30aaf6325420f6.tar.xz
frr-f158bb770d51cd9ec95bd863aa30aaf6325420f6.zip
Merge pull request #13364 from zmw12306/bfd_auth
bfd: fix missing Authentication in control pkt
-rw-r--r--bfdd/bfd.h14
-rw-r--r--bfdd/bfd_packet.c38
2 files changed, 52 insertions, 0 deletions
diff --git a/bfdd/bfd.h b/bfdd/bfd.h
index 5451e66c2..69529aba1 100644
--- a/bfdd/bfd.h
+++ b/bfdd/bfd.h
@@ -32,6 +32,11 @@ DECLARE_MGROUP(BFDD);
DECLARE_MTYPE(BFDD_CONTROL);
DECLARE_MTYPE(BFDD_NOTIFICATION);
+/* bfd Authentication Type. */
+#define BFD_AUTH_NULL 0
+#define BFD_AUTH_SIMPLE 1
+#define BFD_AUTH_CRYPTOGRAPHIC 2
+
struct bfd_timers {
uint32_t desired_min_tx;
uint32_t required_min_rx;
@@ -61,6 +66,15 @@ struct bfd_pkt {
};
/*
+ * Format of authentification.
+ */
+struct bfd_auth {
+ uint8_t type;
+ uint8_t length;
+};
+
+
+/*
* Format of Echo packet.
*/
struct bfd_echo_pkt {
diff --git a/bfdd/bfd_packet.c b/bfdd/bfd_packet.c
index ea7a1038a..0c72ee758 100644
--- a/bfdd/bfd_packet.c
+++ b/bfdd/bfd_packet.c
@@ -768,6 +768,37 @@ static void cp_debug(bool mhop, struct sockaddr_any *peer,
mhop ? "yes" : "no", peerstr, localstr, portstr, vrfstr);
}
+static bool bfd_check_auth(const struct bfd_session *bfd,
+ const struct bfd_pkt *cp)
+{
+ if (CHECK_FLAG(cp->flags, BFD_ABIT)) {
+ /* RFC5880 4.1: Authentication Section is present. */
+ struct bfd_auth *auth = (struct bfd_auth *)(cp + 1);
+ uint16_t pkt_auth_type = ntohs(auth->type);
+
+ if (cp->len < BFD_PKT_LEN + sizeof(struct bfd_auth))
+ return false;
+
+ if (cp->len < BFD_PKT_LEN + auth->length)
+ return false;
+
+ switch (pkt_auth_type) {
+ case BFD_AUTH_NULL:
+ return false;
+ case BFD_AUTH_SIMPLE:
+ /* RFC5880 6.7: To be finshed. */
+ return false;
+ case BFD_AUTH_CRYPTOGRAPHIC:
+ /* RFC5880 6.7: To be finshed. */
+ return false;
+ default:
+ /* RFC5880 6.7: To be finshed. */
+ return false;
+ }
+ }
+ return true;
+}
+
void bfd_recv_cb(struct event *t)
{
int sd = EVENT_FD(t);
@@ -932,6 +963,13 @@ void bfd_recv_cb(struct event *t)
bfd->discrs.remote_discr = ntohl(cp->discrs.my_discr);
+ /* Check authentication. */
+ if (!bfd_check_auth(bfd, cp)) {
+ cp_debug(is_mhop, &peer, &local, ifindex, vrfid,
+ "Authentication failed");
+ return;
+ }
+
/* Save remote diagnostics before state switch. */
bfd->remote_diag = cp->diag & BFD_DIAGMASK;