summaryrefslogtreecommitdiff
path: root/proto/bfd/packets.c
diff options
context:
space:
mode:
authorOndrej Zajicek (work) <santiago@crfreenet.org>2022-04-07 19:33:40 +0200
committerOndrej Zajicek (work) <santiago@crfreenet.org>2022-04-07 19:33:40 +0200
commit692055e3df6cc9f0d428d3b0dd8cdd8e825eb6f4 (patch)
treea7eea92e04722f395f9a2978ae12965d6a4021a5 /proto/bfd/packets.c
parent4b1aa37f931888febfd768309d5e2ef36f5e7194 (diff)
BFD: Add 'strict bind' option
Add BFD protocol option 'strict bind' to use separate listening socket for each BFD interface bound to its address instead of using shared listening sockets.
Diffstat (limited to 'proto/bfd/packets.c')
-rw-r--r--proto/bfd/packets.c36
1 files changed, 35 insertions, 1 deletions
diff --git a/proto/bfd/packets.c b/proto/bfd/packets.c
index 7618e20f..5f10734c 100644
--- a/proto/bfd/packets.c
+++ b/proto/bfd/packets.c
@@ -366,7 +366,9 @@ bfd_rx_hook(sock *sk, uint len)
if (ps > BFD_STATE_DOWN)
DROP("invalid init state", ps);
- uint ifindex = (sk->sport == BFD_CONTROL_PORT) ? sk->lifindex : 0;
+ uint ifindex = (sk->sport == BFD_CONTROL_PORT) ?
+ (sk->iface ? sk->iface->index : sk->lifindex) :
+ 0;
s = bfd_find_session_by_addr(p, sk->faddr, ifindex);
/* FIXME: better session matching and message */
@@ -439,6 +441,38 @@ bfd_open_rx_sk(struct bfd_proto *p, int multihop, int af)
}
sock *
+bfd_open_rx_sk_bound(struct bfd_proto *p, ip_addr local, struct iface *ifa)
+{
+ sock *sk = sk_new(p->tpool);
+ sk->type = SK_UDP;
+ sk->saddr = local;
+ sk->sport = ifa ? BFD_CONTROL_PORT : BFD_MULTI_CTL_PORT;
+ sk->iface = ifa;
+ sk->vrf = p->p.vrf;
+ sk->data = p;
+
+ sk->rbsize = BFD_MAX_LEN;
+ sk->rx_hook = bfd_rx_hook;
+ sk->err_hook = bfd_err_hook;
+
+ /* TODO: configurable ToS and priority */
+ sk->tos = IP_PREC_INTERNET_CONTROL;
+ sk->priority = sk_priority_control;
+ sk->flags = SKF_THREAD | SKF_BIND | (ifa ? SKF_TTL_RX : 0);
+
+ if (sk_open(sk) < 0)
+ goto err;
+
+ sk_start(sk);
+ return sk;
+
+ err:
+ sk_log_error(sk, p->p.name);
+ rfree(sk);
+ return NULL;
+}
+
+sock *
bfd_open_tx_sk(struct bfd_proto *p, ip_addr local, struct iface *ifa)
{
sock *sk = sk_new(p->tpool);