diff options
author | Donatas Abraitis <donatas@opensourcerouting.org> | 2023-06-08 19:12:29 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-06-08 19:12:29 +0200 |
commit | f158bb770d51cd9ec95bd863aa30aaf6325420f6 (patch) | |
tree | 514565c4b3ebdafec5c30edf734f07f528790c50 | |
parent | Merge pull request #13650 from opensourcerouting/feature/bgpd_default_origina... (diff) | |
parent | bfd: fix missing Authentication in control pkt (diff) | |
download | frr-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.h | 14 | ||||
-rw-r--r-- | bfdd/bfd_packet.c | 38 |
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; |