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