On Mon, Jun 03, 2019 at 08:37:17PM +1000, Mitchell Krome wrote:
> Hi,
>
> Testing bfd against frr on linux, their bfd implementation sends polls
> as soon as the session is up even if the session timers haven't
> changed from what it was advertising while it was in the down state.
> Currently openbsd bfd doesn't respond to polls, so this diff adds that
> support. tcpdump output during session setup (.9 is openbsd):
>
> 14:56:31.225339 10.10.20.9.58974 > 10.10.20.10.bfd-control: [udp sum ok] BFD
> v1 length 24 state down flags [] diag none my-discrim 3396727743 your-discrim
> 0 mintx 1000000 minrx 1000000 minecho 0 multiplier 3 [to s 0xc0] (ttl 255, id
> 48014, len 52)
> 14:56:31.533645 10.10.20.10.49143 > 10.10.20.9.bfd-control: [udp sum ok] BFD
> v1 length 24 state init flags [] diag neighbor-down my-discrim 2 your-discrim
> 3396727743 mintx 1500000 minrx 1500000 minecho 50000 mul tiplier 3 (DF) [tos
> 0xc0] (ttl 255, id 36838, len 52)
> 14:56:32.022601 10.10.20.9.58974 > 10.10.20.10.bfd-control: [udp sum ok] BFD
> v1 length 24 state up flags [] diag none my-discrim 3396727743 your-discrim 2
> mintx 1000000 minrx 1500000 minecho 0 multiplier 3 [tos 0xc0] (ttl 255, id
> 21474, len 52)
> 14:56:32.023134 10.10.20.10.49143 > 10.10.20.9.bfd-control: [udp sum ok] BFD
> v1 length 24 state up flags [P] diag none my-discrim 2 your-discrim
> 3396727743 mintx 1500000 minrx 1500000 minecho 50000 multiplier 3 (DF) [tos
> 0xc0] (ttl 255, id 36952, len 52)
> 14:56:32.023207 10.10.20.9.58974 > 10.10.20.10.bfd-control: [udp sum ok] BFD
> v1 length 24 state up flags [F] diag none my-discrim 3396727743 your-discrim
> 2 mintx 1500000 minrx 1500000 minecho 0 multiplier 3 [tos 0xc0] (ttl 255, id
> 23805, len 52)
> 14:56:32.997091 10.10.20.10.49143 > 10.10.20.9.bfd-control: [udp sum ok] BFD
> v1 length 24 state up flags [] diag none my-discrim 2 your-discrim 3396727743
> mintx 1500000 minrx 1500000 minecho 50000 multiplier 3 ( DF) [tos 0xc0] (ttl
> 255, id 36991, len 52)
>
> I also added some handling for generating polls and receiving finals while
> in there, but there isn't any code to actually start our own poll
> sequence just yet.
>
> I only have frr and openbsd peers to test with - if anybody has
> something else hooked up would be good to check what they do.
>
Diff is OK claudio@. I would probably pass the BFD_FLAG_P as argument to
bfd_send_control() instead of storing that in struct bfd_config.
But that is just a minor detail.
> diff --git sys/net/bfd.c sys/net/bfd.c
> index 42995531a8a..2ae287a15bb 100644
> --- sys/net/bfd.c
> +++ sys/net/bfd.c
> @@ -741,6 +741,8 @@ bfd_reset(struct bfd_config *bfd)
>
> bfd->bc_mode = BFD_MODE_ASYNC;
> bfd->bc_state = BFD_STATE_DOWN;
> + bfd->bc_poll_seq = 0;
> + bfd->bc_poll_rcvd = 0;
>
> /* rfc5880 6.8.18 */
> bfd->bc_neighbor->bn_lstate = BFD_STATE_DOWN;
> @@ -825,7 +827,10 @@ bfd_input(struct bfd_config *bfd, struct mbuf *m)
> bfd->bc_neighbor->bn_rdiscr = ntohl(peer->bfd_my_discriminator);
> bfd->bc_neighbor->bn_rstate = state;
> bfd->bc_neighbor->bn_rdemand = (flags & BFD_FLAG_D);
> - bfd->bc_poll = (flags & BFD_FLAG_F);
> +
> + if (flags & BFD_FLAG_F && bfd->bc_poll_seq) {
> + bfd->bc_poll_seq = 0;
> + }
>
> /* Local change to the algorithm, we don't accept below 50ms */
> if (ntohl(peer->bfd_required_min_rx_interval) < BFD_MINIMUM)
> @@ -891,6 +896,12 @@ bfd_input(struct bfd_config *bfd, struct mbuf *m)
>
> bfd->bc_error = 0;
>
> + /* Reply to poll if we aren't down */
> + if (flags & BFD_FLAG_P && bfd->bc_state > BFD_STATE_DOWN) {
> + bfd->bc_poll_rcvd = 1;
> + bfd_send_control(bfd);
> + }
> +
> discard:
> bfd->bc_neighbor->bn_rdiag = diag;
> m_free(m);
> @@ -979,6 +990,13 @@ bfd_send_control(void *x)
>
> h->bfd_ver_diag = ((BFD_VERSION << 5) | (bfd->bc_neighbor->bn_ldiag));
> h->bfd_sta_flags = (bfd->bc_state << 6);
> + /* Can't send a poll and a final in the same packet. */
> + if (bfd->bc_poll_rcvd) {
> + h->bfd_sta_flags |= BFD_FLAG_F;
> + bfd->bc_poll_rcvd = 0;
> + } else if (bfd->bc_poll_seq) {
> + h->bfd_sta_flags |= BFD_FLAG_P;
> + }
> h->bfd_detect_multi = bfd->bc_neighbor->bn_mult;
> h->bfd_length = BFD_HDRLEN;
> h->bfd_my_discriminator = htonl(bfd->bc_neighbor->bn_ldiscr);
> diff --git sys/net/bfd.h sys/net/bfd.h
> index 3e8da45086f..8ee372faa5d 100644
> --- sys/net/bfd.h
> +++ sys/net/bfd.h
> @@ -143,7 +143,8 @@ struct bfd_config {
> time_t bc_lastuptime;
> unsigned int bc_laststate;
> unsigned int bc_state;
> - unsigned int bc_poll;
> + unsigned int bc_poll_seq;
> + unsigned int bc_poll_rcvd;
> unsigned int bc_error;
> uint32_t bc_minrx;
> uint32_t bc_mintx;
>
--
:wq Claudio