mirror of
https://gitlab.labs.nic.cz/labs/bird.git
synced 2024-05-11 16:54:54 +00:00
Fixes some BFD bugs and makes logging thread-safe.
This commit is contained in:
@@ -20,8 +20,8 @@ struct bfd_ctl_packet
|
||||
u32 req_min_echo_rx_int;
|
||||
};
|
||||
|
||||
#define BFD_BASE_LEN sizeof(struct bfd_ctl_packet)
|
||||
|
||||
#define BFD_BASE_LEN sizeof(struct bfd_ctl_packet)
|
||||
#define BFD_MAX_LEN 64
|
||||
|
||||
static inline u8 bfd_pack_vdiag(u8 version, u8 diag)
|
||||
{ return (version << 5) | diag; }
|
||||
@@ -43,11 +43,28 @@ static inline void bfd_pkt_set_state(struct bfd_ctl_packet *pkt, u8 val)
|
||||
{ pkt->flags = val << 6; }
|
||||
|
||||
|
||||
char *
|
||||
bfd_format_flags(u8 flags, char *buf)
|
||||
{
|
||||
char *bp = buf;
|
||||
if (flags & BFD_FLAGS) *bp++ = ' ';
|
||||
if (flags & BFD_FLAG_POLL) *bp++ = 'P';
|
||||
if (flags & BFD_FLAG_FINAL) *bp++ = 'F';
|
||||
if (flags & BFD_FLAG_CPI) *bp++ = 'C';
|
||||
if (flags & BFD_FLAG_AP) *bp++ = 'A';
|
||||
if (flags & BFD_FLAG_DEMAND) *bp++ = 'D';
|
||||
if (flags & BFD_FLAG_MULTIPOINT) *bp++ = 'M';
|
||||
*bp = 0;
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
void
|
||||
bfd_send_ctl(struct bfd_proto *p, struct bfd_session *s, int final)
|
||||
{
|
||||
sock *sk = s->bsock->sk;
|
||||
struct bfd_ctl_packet *pkt = (struct bfd_ctl_packet *) sk->tbuf;
|
||||
char fb[8];
|
||||
|
||||
pkt->vdiag = bfd_pack_vdiag(1, s->loc_diag);
|
||||
pkt->flags = bfd_pack_flags(s->loc_state, 0);
|
||||
@@ -65,7 +82,10 @@ bfd_send_ctl(struct bfd_proto *p, struct bfd_session *s, int final)
|
||||
pkt->flags |= BFD_FLAG_POLL;
|
||||
|
||||
if (sk->tbuf != sk->tpos)
|
||||
log(L_ERR "%s: old packet was overwritten in TX buffer", p->p.name);
|
||||
log(L_WARN "%s: Old packet overwritten in TX buffer", p->p.name);
|
||||
|
||||
TRACE(D_PACKETS, "Sending CTL to %I [%s%s]", s->addr,
|
||||
bfd_state_names[s->loc_state], bfd_format_flags(pkt->flags, fb));
|
||||
|
||||
sk_send_to(sk, pkt->length, s->addr, sk->dport);
|
||||
}
|
||||
@@ -79,6 +99,10 @@ bfd_rx_hook(sock *sk, int len)
|
||||
struct bfd_ctl_packet *pkt = (struct bfd_ctl_packet *) sk->rbuf;
|
||||
const char *err_dsc = NULL;
|
||||
uint err_val = 0;
|
||||
char fb[8];
|
||||
|
||||
if ((sk->sport == BFD_CONTROL_PORT) && (sk->ttl < 255))
|
||||
DROP("wrong TTL", sk->ttl);
|
||||
|
||||
if (len < BFD_BASE_LEN)
|
||||
DROP("too short", len);
|
||||
@@ -93,7 +117,8 @@ bfd_rx_hook(sock *sk, int len)
|
||||
if (pkt->detect_mult == 0)
|
||||
DROP("invalid detect mult", 0);
|
||||
|
||||
if (pkt->flags & BFD_FLAG_MULTIPOINT)
|
||||
if ((pkt->flags & BFD_FLAG_MULTIPOINT) ||
|
||||
((pkt->flags & BFD_FLAG_POLL) && (pkt->flags & BFD_FLAG_FINAL)))
|
||||
DROP("invalid flags", pkt->flags);
|
||||
|
||||
if (pkt->snd_id == 0)
|
||||
@@ -107,7 +132,7 @@ bfd_rx_hook(sock *sk, int len)
|
||||
s = bfd_find_session_by_id(p, id);
|
||||
|
||||
if (!s)
|
||||
DROP("unknown session", id);
|
||||
DROP("unknown session id", id);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -138,11 +163,14 @@ bfd_rx_hook(sock *sk, int len)
|
||||
s->rem_min_rx_int = ntohl(pkt->req_min_rx_int);
|
||||
s->rem_detect_mult = pkt->detect_mult;
|
||||
|
||||
TRACE(D_PACKETS, "CTL received from %I [%s%s]", sk->faddr,
|
||||
bfd_state_names[s->rem_state], bfd_format_flags(pkt->flags, fb));
|
||||
|
||||
bfd_session_process_ctl(s, pkt->flags, old_tx_int, old_rx_int);
|
||||
return 1;
|
||||
|
||||
drop:
|
||||
// log(L_WARN "%s: Bad packet from %I - %s (%u)", p->p.name, sk->faddr, err_dsc, err_val);
|
||||
log(L_REMOTE "%s: Bad packet from %I - %s (%u)", p->p.name, sk->faddr, err_dsc, err_val);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -161,7 +189,7 @@ bfd_open_rx_sk(struct bfd_proto *p, int multihop)
|
||||
sk->sport = !multihop ? BFD_CONTROL_PORT : BFD_MULTI_CTL_PORT;
|
||||
sk->data = p;
|
||||
|
||||
sk->rbsize = 64; // XXX
|
||||
sk->rbsize = BFD_MAX_LEN;
|
||||
sk->rx_hook = bfd_rx_hook;
|
||||
sk->err_hook = bfd_err_hook;
|
||||
|
||||
@@ -195,7 +223,7 @@ bfd_open_tx_sk(struct bfd_proto *p, ip_addr local, struct iface *ifa)
|
||||
sk->iface = ifa;
|
||||
sk->data = p;
|
||||
|
||||
sk->tbsize = 64; // XXX
|
||||
sk->tbsize = BFD_MAX_LEN;
|
||||
sk->err_hook = bfd_err_hook;
|
||||
|
||||
/* TODO: configurable ToS, priority and TTL security */
|
||||
|
Reference in New Issue
Block a user