diff options
Diffstat (limited to 'bfdd/bfd_packet.c')
| -rw-r--r-- | bfdd/bfd_packet.c | 52 |
1 files changed, 48 insertions, 4 deletions
diff --git a/bfdd/bfd_packet.c b/bfdd/bfd_packet.c index dadf9c25d7..8110f434c2 100644 --- a/bfdd/bfd_packet.c +++ b/bfdd/bfd_packet.c @@ -12,6 +12,11 @@ */ #include <zebra.h> +#include <sys/ioctl.h> + +#ifdef GNU_LINUX +#include <linux/filter.h> +#endif #ifdef BFD_LINUX #include <linux/if_packet.h> @@ -768,6 +773,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); @@ -884,7 +920,7 @@ void bfd_recv_cb(struct event *t) /* * We may have a situation where received packet is on wrong vrf */ - if (bfd && bfd->vrf && bfd->vrf != bvrf->vrf) { + if (bfd && bfd->vrf && bfd->vrf->vrf_id != vrfid) { cp_debug(is_mhop, &peer, &local, ifindex, vrfid, "wrong vrfid."); return; @@ -938,6 +974,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; @@ -1710,9 +1753,10 @@ void bfd_peer_mac_set(int sd, struct bfd_session *bfd, strlcpy(arpreq_.arp_dev, ifp->name, sizeof(arpreq_.arp_dev)); if (ioctl(sd, SIOCGARP, &arpreq_) < 0) { - zlog_warn( - "BFD: getting peer's mac on %s failed error %s", - ifp->name, strerror(errno)); + if (bglobal.debug_network) + zlog_debug( + "BFD: getting peer's mac on %s failed error %s", + ifp->name, strerror(errno)); UNSET_FLAG(bfd->flags, BFD_SESS_FLAG_MAC_SET); memset(bfd->peer_hw_addr, 0, sizeof(bfd->peer_hw_addr)); |
