diff --git a/proto/bfd/bfd.c b/proto/bfd/bfd.c index 3ba3a5d9..110bf931 100644 --- a/proto/bfd/bfd.c +++ b/proto/bfd/bfd.c @@ -981,8 +981,10 @@ bfd_start(struct proto *P) add_tail(&bfd_proto_list, &p->bfd_node); birdloop_enter(p->loop); - p->rx_1 = bfd_open_rx_sk(p, 0); - p->rx_m = bfd_open_rx_sk(p, 1); + p->rx4_1 = bfd_open_rx_sk(p, 0, 4); + p->rx4_m = bfd_open_rx_sk(p, 1, 4); + p->rx6_1 = bfd_open_rx_sk(p, 0, 6); + p->rx6_m = bfd_open_rx_sk(p, 1, 6); birdloop_leave(p->loop); bfd_take_requests(p); diff --git a/proto/bfd/bfd.h b/proto/bfd/bfd.h index 9b61be64..ce7d665b 100644 --- a/proto/bfd/bfd.h +++ b/proto/bfd/bfd.h @@ -84,8 +84,10 @@ struct bfd_proto sock *notify_ws; list notify_list; - sock *rx_1; - sock *rx_m; + sock *rx4_1; + sock *rx6_1; + sock *rx4_m; + sock *rx6_m; list iface_list; }; @@ -184,7 +186,7 @@ void bfd_show_sessions(struct proto *P); /* packets.c */ void bfd_send_ctl(struct bfd_proto *p, struct bfd_session *s, int final); -sock * bfd_open_rx_sk(struct bfd_proto *p, int multihop); +sock * bfd_open_rx_sk(struct bfd_proto *p, int multihop, int inet_version); sock * bfd_open_tx_sk(struct bfd_proto *p, ip_addr local, struct iface *ifa); diff --git a/proto/bfd/packets.c b/proto/bfd/packets.c index 2200acfa..a28e4c50 100644 --- a/proto/bfd/packets.c +++ b/proto/bfd/packets.c @@ -186,7 +186,7 @@ bfd_err_hook(sock *sk, int err) } sock * -bfd_open_rx_sk(struct bfd_proto *p, int multihop) +bfd_open_rx_sk(struct bfd_proto *p, int multihop, int inet_version) { sock *sk = sk_new(p->tpool); sk->type = SK_UDP; @@ -202,7 +202,18 @@ bfd_open_rx_sk(struct bfd_proto *p, int multihop) sk->priority = sk_priority_control; sk->flags = SKF_THREAD | SKF_LADDR_RX | (!multihop ? SKF_TTL_RX : 0); - sk->af = AF_INET6; + switch (inet_version) { + case 4: + sk->af = AF_INET; + sk->flags |= SKF_V4ONLY; + break; + case 6: + sk->af = AF_INET6; + sk->flags |= SKF_V6ONLY; + break; + default: + ASSERT(0); + } if (sk_open(sk) < 0) goto err; @@ -235,7 +246,13 @@ bfd_open_tx_sk(struct bfd_proto *p, ip_addr local, struct iface *ifa) sk->ttl = ifa ? 255 : -1; sk->flags = SKF_THREAD | SKF_BIND | SKF_HIGH_PORT; - sk->af = AF_INET6; + if (ipa_is_ip4(local)) { + sk->af = AF_INET; + sk->flags |= SKF_V4ONLY; + } else { + sk->af = AF_INET6; + sk->flags |= SKF_V6ONLY; + } if (sk_open(sk) < 0) goto err;