summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/net/bfd.c493
-rw-r--r--sys/net/bfd.h111
-rw-r--r--sys/net/route.c4
-rw-r--r--sys/net/rtsock.c6
4 files changed, 308 insertions, 306 deletions
diff --git a/sys/net/bfd.c b/sys/net/bfd.c
index d7b44b56710..1301b67d616 100644
--- a/sys/net/bfd.c
+++ b/sys/net/bfd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: bfd.c,v 1.26 2016/09/15 08:39:44 phessler Exp $ */
+/* $OpenBSD: bfd.c,v 1.27 2016/09/17 07:35:05 phessler Exp $ */
/*
* Copyright (c) 2016 Peter Hessler <phessler@openbsd.org>
@@ -140,36 +140,19 @@ struct bfd_auth_header {
#define BFD_MINIMUM 10000 /* 10,000 us == 10 ms */
-/* These spellings and capitalizations match RFC 5880 6.8.1*/
-/* Do not change */
-struct bfd_state {
- uint32_t SessionState;
- uint32_t RemoteSessionState;
- uint32_t LocalDiscr; /* Unique identifier */
- uint32_t RemoteDiscr; /* Unique identifier */
- uint32_t LocalDiag;
- uint32_t RemoteDiag;
- uint32_t DesiredMinTxInterval;
- uint32_t RequiredMinRxInterval;
- uint32_t RemoteMinRxInterval;
- uint32_t DemandMode;
- uint32_t RemoteDemandMode;
- uint32_t DetectMult; /* Detection Time Multiplier*/
- uint32_t AuthType;
- uint32_t RcvAuthSeq;
- uint32_t XmitAuthSeq;
- uint32_t AuthSeqKnown;
-};
-
-struct pool bfd_pool, bfd_pool_peer, bfd_pool_time;
+struct pool bfd_pool, bfd_pool_neigh, bfd_pool_time;
struct taskq *bfdtq;
-struct socket *bfd_listener(struct bfd_softc *, unsigned int);
-struct socket *bfd_sender(struct bfd_softc *, unsigned int);
-void bfd_input(struct bfd_softc *, struct mbuf *);
-void bfd_set_state(struct bfd_softc *, int);
-int bfd_send(struct bfd_softc *, struct mbuf *);
+struct bfd_config *bfd_lookup(struct rtentry *);
+void bfddestroy(void);
+
+struct socket *bfd_listener(struct bfd_config *, unsigned int);
+struct socket *bfd_sender(struct bfd_config *, unsigned int);
+void bfd_input(struct bfd_config *, struct mbuf *);
+void bfd_set_state(struct bfd_config *, int);
+
+int bfd_send(struct bfd_config *, struct mbuf *);
void bfd_send_control(void *);
void bfd_start_task(void *);
@@ -178,21 +161,21 @@ void bfd_timeout_rx(void *);
void bfd_timeout_tx(void *);
void bfd_upcall(struct socket *, caddr_t, int);
-void bfd_senddown(struct bfd_softc *);
-void bfd_reset(struct bfd_softc *);
-void bfd_set_uptime(struct bfd_softc *);
+void bfd_senddown(struct bfd_config *);
+void bfd_reset(struct bfd_config *);
+void bfd_set_uptime(struct bfd_config *);
-void bfd_debug(struct bfd_softc *);
+void bfd_debug(struct bfd_config *);
-TAILQ_HEAD(bfd_queue, bfd_softc) bfd_queue;
+TAILQ_HEAD(bfd_queue, bfd_config) bfd_queue;
/*
* allocate a new bfd session
*/
int
-bfd_rtalloc(struct rtentry *rt)
+bfdset(struct rtentry *rt)
{
- struct bfd_softc *sc;
+ struct bfd_config *bfd;
/* at the moment it is not allowed to run BFD on indirect routes */
if (ISSET(rt->rt_flags, RTF_GATEWAY) || !ISSET(rt->rt_flags, RTF_HOST))
@@ -203,26 +186,26 @@ bfd_rtalloc(struct rtentry *rt)
return (EADDRINUSE);
/* Do our necessary memory allocations upfront */
- sc = pool_get(&bfd_pool, PR_WAITOK | PR_ZERO);
- sc->sc_peer = pool_get(&bfd_pool_peer, PR_WAITOK | PR_ZERO);
- sc->sc_time = pool_get(&bfd_pool_time, PR_WAITOK | PR_ZERO);
+ bfd = pool_get(&bfd_pool, PR_WAITOK | PR_ZERO);
+ bfd->bc_neighbor = pool_get(&bfd_pool_neigh, PR_WAITOK | PR_ZERO);
+ bfd->bc_time = pool_get(&bfd_pool_time, PR_WAITOK | PR_ZERO);
- sc->sc_rt = rt;
- rtref(sc->sc_rt); /* we depend on this route not going away */
+ bfd->bc_rt = rt;
+ rtref(bfd->bc_rt); /* we depend on this route not going away */
- microtime(sc->sc_time);
- bfd_reset(sc);
- sc->sc_peer->LocalDiscr = arc4random(); /* XXX - MUST be globally unique */
+ microtime(bfd->bc_time);
+ bfd_reset(bfd);
+ bfd->bc_neighbor->bn_ldiscr = arc4random(); /* XXX - MUST be globally unique */
- if (!timeout_initialized(&sc->sc_timo_rx))
- timeout_set(&sc->sc_timo_rx, bfd_timeout_rx, sc);
- if (!timeout_initialized(&sc->sc_timo_tx))
- timeout_set(&sc->sc_timo_tx, bfd_timeout_tx, sc);
+ if (!timeout_initialized(&bfd->bc_timo_rx))
+ timeout_set(&bfd->bc_timo_rx, bfd_timeout_rx, bfd);
+ if (!timeout_initialized(&bfd->bc_timo_tx))
+ timeout_set(&bfd->bc_timo_tx, bfd_timeout_tx, bfd);
- task_set(&sc->sc_bfd_task, bfd_start_task, sc);
- task_add(bfdtq, &sc->sc_bfd_task);
+ task_set(&bfd->bc_bfd_task, bfd_start_task, bfd);
+ task_add(bfdtq, &bfd->bc_bfd_task);
- TAILQ_INSERT_TAIL(&bfd_queue, sc, bfd_next);
+ TAILQ_INSERT_TAIL(&bfd_queue, bfd, bc_entry);
return (0);
}
@@ -231,41 +214,41 @@ bfd_rtalloc(struct rtentry *rt)
* remove and free a bfd session
*/
void
-bfd_rtfree(struct rtentry *rt)
+bfdclear(struct rtentry *rt)
{
- struct bfd_softc *sc;
+ struct bfd_config *bfd;
- if ((sc = bfd_lookup(rt)) == NULL)
+ if ((bfd = bfd_lookup(rt)) == NULL)
return;
- timeout_del(&sc->sc_timo_rx);
- timeout_del(&sc->sc_timo_tx);
- task_del(bfdtq, &sc->sc_bfd_send_task);
+ timeout_del(&bfd->bc_timo_rx);
+ timeout_del(&bfd->bc_timo_tx);
+ task_del(bfdtq, &bfd->bc_bfd_send_task);
/* XXX - punt this off to a task */
- TAILQ_REMOVE(&bfd_queue, sc, bfd_next);
+ TAILQ_REMOVE(&bfd_queue, bfd, bc_entry);
/* send suicide packets immediately */
- if (rtisvalid(sc->sc_rt))
- bfd_senddown(sc);
+ if (rtisvalid(bfd->bc_rt))
+ bfd_senddown(bfd);
- if (sc->sc_so) {
+ if (bfd->bc_so) {
/* remove upcall before calling soclose or it will be called */
- sc->sc_so->so_upcall = NULL;
- soclose(sc->sc_so);
+ bfd->bc_so->so_upcall = NULL;
+ soclose(bfd->bc_so);
}
- if (sc->sc_soecho) {
- sc->sc_soecho->so_upcall = NULL;
- soclose(sc->sc_soecho);
+ if (bfd->bc_soecho) {
+ bfd->bc_soecho->so_upcall = NULL;
+ soclose(bfd->bc_soecho);
}
- if (sc->sc_sosend)
- soclose(sc->sc_sosend);
+ if (bfd->bc_sosend)
+ soclose(bfd->bc_sosend);
- rtfree(sc->sc_rt);
+ rtfree(bfd->bc_rt);
- pool_put(&bfd_pool_time, sc->sc_time);
- pool_put(&bfd_pool_peer, sc->sc_peer);
- pool_put(&bfd_pool, sc);
+ pool_put(&bfd_pool_time, bfd->bc_time);
+ pool_put(&bfd_pool_neigh, bfd->bc_neighbor);
+ pool_put(&bfd_pool, bfd);
}
/*
@@ -274,12 +257,12 @@ bfd_rtfree(struct rtentry *rt)
void
bfdinit(void)
{
- pool_init(&bfd_pool, sizeof(struct bfd_softc), 0,
- IPL_SOFTNET, 0, "bfd_softc", NULL);
- pool_init(&bfd_pool_peer, sizeof(struct bfd_state), 0,
- IPL_SOFTNET, 0, "bfd_softc_peer", NULL);
+ pool_init(&bfd_pool, sizeof(struct bfd_config), 0,
+ IPL_SOFTNET, 0, "bfd_config", NULL);
+ pool_init(&bfd_pool_neigh, sizeof(struct bfd_neighbor), 0,
+ IPL_SOFTNET, 0, "bfd_config_peer", NULL);
pool_init(&bfd_pool_time, sizeof(struct timeval), 0,
- IPL_SOFTNET, 0, "bfd_softc_time", NULL);
+ IPL_SOFTNET, 0, "bfd_config_time", NULL);
bfdtq = taskq_create("bfd", 1, IPL_SOFTNET, 0);
if (bfdtq == NULL)
@@ -295,30 +278,30 @@ bfdinit(void)
void
bfddestroy(void)
{
- struct bfd_softc *sc;
+ struct bfd_config *bfd;
/* send suicide packets immediately */
- while ((sc = TAILQ_FIRST(&bfd_queue))) {
- bfd_rtfree(sc->sc_rt);
+ while ((bfd = TAILQ_FIRST(&bfd_queue))) {
+ bfdclear(bfd->bc_rt);
}
taskq_destroy(bfdtq);
pool_destroy(&bfd_pool_time);
- pool_destroy(&bfd_pool_peer);
+ pool_destroy(&bfd_pool_neigh);
pool_destroy(&bfd_pool);
}
/*
* Return the matching bfd
*/
-struct bfd_softc *
+struct bfd_config *
bfd_lookup(struct rtentry *rt)
{
- struct bfd_softc *sc;
+ struct bfd_config *bfd;
- TAILQ_FOREACH(sc, &bfd_queue, bfd_next) {
- if (sc->sc_rt == rt)
- return (sc);
+ TAILQ_FOREACH(bfd, &bfd_queue, bc_entry) {
+ if (bfd->bc_rt == rt)
+ return (bfd);
}
return (NULL);
}
@@ -335,23 +318,23 @@ bfd_lookup(struct rtentry *rt)
void
bfd_start_task(void *arg)
{
- struct bfd_softc *sc = (struct bfd_softc *)arg;
+ struct bfd_config *bfd = (struct bfd_config *)arg;
/* start listeners */
- sc->sc_so = bfd_listener(sc, BFD_UDP_PORT_CONTROL);
- if (!sc->sc_so)
+ bfd->bc_so = bfd_listener(bfd, BFD_UDP_PORT_CONTROL);
+ if (!bfd->bc_so)
printf("bfd_listener(%d) failed\n",
BFD_UDP_PORT_CONTROL);
- sc->sc_soecho = bfd_listener(sc, BFD_UDP_PORT_ECHO);
- if (!sc->sc_soecho)
+ bfd->bc_soecho = bfd_listener(bfd, BFD_UDP_PORT_ECHO);
+ if (!bfd->bc_soecho)
printf("bfd_listener(%d) failed\n",
BFD_UDP_PORT_ECHO);
/* start sending */
- sc->sc_sosend = bfd_sender(sc, BFD_UDP_PORT_CONTROL);
- if (sc->sc_sosend) {
- task_set(&sc->sc_bfd_send_task, bfd_send_task, sc);
- task_add(bfdtq, &sc->sc_bfd_send_task);
+ bfd->bc_sosend = bfd_sender(bfd, BFD_UDP_PORT_CONTROL);
+ if (bfd->bc_sosend) {
+ task_set(&bfd->bc_bfd_send_task, bfd_send_task, bfd);
+ task_add(bfdtq, &bfd->bc_bfd_send_task);
}
return;
@@ -360,33 +343,33 @@ bfd_start_task(void *arg)
void
bfd_send_task(void *arg)
{
- struct bfd_softc *sc = (struct bfd_softc *)arg;
- struct rtentry *rt = sc->sc_rt;
+ struct bfd_config *bfd = (struct bfd_config *)arg;
+ struct rtentry *rt = bfd->bc_rt;
if (ISSET(rt->rt_flags, RTF_UP)) {
- bfd_send_control(sc);
+ bfd_send_control(bfd);
} else {
- sc->error++;
- sc->sc_peer->LocalDiag = BFD_DIAG_ADMIN_DOWN;
- if (sc->sc_peer->SessionState > BFD_STATE_DOWN) {
- bfd_reset(sc);
- bfd_set_state(sc, BFD_STATE_DOWN);
+ bfd->bc_error++;
+ bfd->bc_neighbor->bn_ldiag = BFD_DIAG_ADMIN_DOWN;
+ if (bfd->bc_neighbor->bn_lstate > BFD_STATE_DOWN) {
+ bfd_reset(bfd);
+ bfd_set_state(bfd, BFD_STATE_DOWN);
}
}
/* re-add 70%-90% jitter to our transmits, rfc 5880 6.8.7 */
- timeout_add_usec(&sc->sc_timo_tx,
- sc->mintx * (arc4random_uniform(20) + 70) / 100);
+ timeout_add_usec(&bfd->bc_timo_tx,
+ bfd->bc_mintx * (arc4random_uniform(20) + 70) / 100);
}
/*
* Setup a bfd listener socket
*/
struct socket *
-bfd_listener(struct bfd_softc *sc, unsigned int port)
+bfd_listener(struct bfd_config *bfd, unsigned int port)
{
struct proc *p = curproc;
- struct rtentry *rt = sc->sc_rt;
+ struct rtentry *rt = bfd->bc_rt;
struct sockaddr *src = rt->rt_ifa->ifa_addr;
struct sockaddr *dst = rt_key(rt);
struct sockaddr *sa;
@@ -441,7 +424,7 @@ bfd_listener(struct bfd_softc *sc, unsigned int port)
__func__, error);
goto close;
}
- so->so_upcallarg = (caddr_t)sc;
+ so->so_upcallarg = (caddr_t)bfd;
so->so_upcall = bfd_upcall;
return (so);
@@ -457,10 +440,10 @@ bfd_listener(struct bfd_softc *sc, unsigned int port)
* Setup the bfd sending process
*/
struct socket *
-bfd_sender(struct bfd_softc *sc, unsigned int port)
+bfd_sender(struct bfd_config *bfd, unsigned int port)
{
struct socket *so;
- struct rtentry *rt = sc->sc_rt;
+ struct rtentry *rt = bfd->bc_rt;
struct proc *p = curproc;
struct mbuf *m = NULL, *mopt = NULL;
struct sockaddr *src = rt->rt_ifa->ifa_addr;
@@ -563,7 +546,7 @@ bfd_sender(struct bfd_softc *sc, unsigned int port)
void
bfd_upcall(struct socket *so, caddr_t arg, int waitflag)
{
- struct bfd_softc *sc = (struct bfd_softc *)arg;
+ struct bfd_config *bfd = (struct bfd_config *)arg;
struct mbuf *m;
struct uio uio;
int flags, error;
@@ -574,11 +557,11 @@ bfd_upcall(struct socket *so, caddr_t arg, int waitflag)
flags = MSG_DONTWAIT;
error = soreceive(so, NULL, &uio, &m, NULL, &flags, 0);
if (error && error != EAGAIN) {
- sc->error++;
+ bfd->bc_error++;
return;
}
if (m != NULL)
- bfd_input(sc, m);
+ bfd_input(bfd, m);
} while (m != NULL);
return;
@@ -588,8 +571,8 @@ bfd_upcall(struct socket *so, caddr_t arg, int waitflag)
void
bfd_timeout_tx(void *v)
{
- struct bfd_softc *sc = v;
- task_add(bfdtq, &sc->sc_bfd_send_task);
+ struct bfd_config *bfd = v;
+ task_add(bfdtq, &bfd->bc_bfd_send_task);
}
/*
@@ -598,37 +581,37 @@ bfd_timeout_tx(void *v)
void
bfd_timeout_rx(void *v)
{
- struct bfd_softc *sc = v;
+ struct bfd_config *bfd = v;
- if ((sc->sc_peer->SessionState > BFD_STATE_DOWN) &&
- (++sc->error >= sc->sc_peer->DetectMult)) {
- sc->sc_peer->LocalDiag = BFD_DIAG_EXPIRED;
-printf("%s: failed, sc->error %u\n", __func__, sc->error);
- bfd_reset(sc);
- bfd_set_state(sc, BFD_STATE_DOWN);
+ if ((bfd->bc_neighbor->bn_lstate > BFD_STATE_DOWN) &&
+ (++bfd->bc_error >= bfd->bc_neighbor->bn_mult)) {
+ bfd->bc_neighbor->bn_ldiag = BFD_DIAG_EXPIRED;
+printf("%s: failed, bfd->bc_error %u\n", __func__, bfd->bc_error);
+ bfd_reset(bfd);
+ bfd_set_state(bfd, BFD_STATE_DOWN);
return;
}
- timeout_add_usec(&sc->sc_timo_rx, sc->minrx);
+ timeout_add_usec(&bfd->bc_timo_rx, bfd->bc_minrx);
}
/*
* Tell our neighbor that we are going down
*/
void
-bfd_senddown(struct bfd_softc *sc)
+bfd_senddown(struct bfd_config *bfd)
{
/* If we are down, return early */
- if (sc->state < BFD_STATE_INIT)
+ if (bfd->bc_state < BFD_STATE_INIT)
return;
- sc->sc_peer->SessionState = BFD_STATE_ADMINDOWN;
- if (sc->sc_peer->LocalDiag == 0)
- sc->sc_peer->LocalDiag = BFD_DIAG_ADMIN_DOWN;
+ bfd->bc_neighbor->bn_lstate = BFD_STATE_ADMINDOWN;
+ if (bfd->bc_neighbor->bn_ldiag == 0)
+ bfd->bc_neighbor->bn_ldiag = BFD_DIAG_ADMIN_DOWN;
- bfd_send_control(sc);
+ bfd_send_control(bfd);
return;
}
@@ -637,44 +620,44 @@ bfd_senddown(struct bfd_softc *sc)
* Clean a BFD peer to defaults
*/
void
-bfd_reset(struct bfd_softc *sc)
+bfd_reset(struct bfd_config *bfd)
{
-if (sc->error)
-printf("%s: error=%u\n", __func__, sc->error);
+if (bfd->bc_error)
+printf("%s: error=%u\n", __func__, bfd->bc_error);
/* Clean */
- sc->sc_peer->RemoteDiscr = 0;
- sc->sc_peer->DemandMode = 0;
- sc->sc_peer->RemoteDemandMode = 0;
- sc->sc_peer->AuthType = 0;
- sc->sc_peer->RcvAuthSeq = 0;
- sc->sc_peer->XmitAuthSeq = 0;
- sc->sc_peer->AuthSeqKnown = 0;
- sc->sc_peer->LocalDiag = 0;
-
- sc->mode = BFD_MODE_ASYNC;
- sc->state = BFD_STATE_DOWN;
+ bfd->bc_neighbor->bn_rdiscr = 0;
+ bfd->bc_neighbor->bn_demand = 0;
+ bfd->bc_neighbor->bn_rdemand = 0;
+ bfd->bc_neighbor->bn_authtype = 0;
+ bfd->bc_neighbor->bn_rauthseq = 0;
+ bfd->bc_neighbor->bn_lauthseq = 0;
+ bfd->bc_neighbor->bn_authseqknown = 0;
+ bfd->bc_neighbor->bn_ldiag = 0;
+
+ bfd->bc_mode = BFD_MODE_ASYNC;
+ bfd->bc_state = BFD_STATE_DOWN;
/* Set RFC mandated values */
- sc->sc_peer->SessionState = BFD_STATE_DOWN;
- sc->sc_peer->RemoteSessionState = BFD_STATE_DOWN;
- sc->sc_peer->DesiredMinTxInterval = BFD_SECOND;
- sc->sc_peer->RequiredMinRxInterval = BFD_SECOND; /* rfc5880 6.8.18 */
- sc->sc_peer->RemoteMinRxInterval = 1;
- sc->sc_peer->DetectMult = 3; /* XXX - MUST be nonzero */
+ bfd->bc_neighbor->bn_lstate = BFD_STATE_DOWN;
+ bfd->bc_neighbor->bn_rstate = BFD_STATE_DOWN;
+ bfd->bc_neighbor->bn_mintx = BFD_SECOND;
+ bfd->bc_neighbor->bn_req_minrx = BFD_SECOND; /* rfc5880 6.8.18 */
+ bfd->bc_neighbor->bn_rminrx = 1;
+ bfd->bc_neighbor->bn_mult = 3; /* XXX - MUST be nonzero */
- sc->mintx = sc->sc_peer->DesiredMinTxInterval;
- sc->minrx = sc->sc_peer->RemoteMinRxInterval;
- sc->multiplier = sc->sc_peer->DetectMult;
+ bfd->bc_mintx = bfd->bc_neighbor->bn_mintx;
+ bfd->bc_minrx = bfd->bc_neighbor->bn_rminrx;
+ bfd->bc_multiplier = bfd->bc_neighbor->bn_mult;
- bfd_set_uptime(sc);
-printf("%s: localdiscr: %u\n", __func__, sc->sc_peer->LocalDiscr);
+ bfd_set_uptime(bfd);
+printf("%s: localdiscr: %u\n", __func__, bfd->bc_neighbor->bn_ldiscr);
return;
}
void
-bfd_input(struct bfd_softc *sc, struct mbuf *m)
+bfd_input(struct bfd_config *bfd, struct mbuf *m)
{
struct bfd_header *peer;
struct bfd_auth_header *auth;
@@ -709,18 +692,18 @@ bfd_input(struct bfd_softc *sc, struct mbuf *m)
BFD_STATE(peer->bfd_sta_flags) > BFD_STATE_DOWN)
goto discard;
if ((ntohl(peer->bfd_your_discriminator) != 0) &&
- (ntohl(peer->bfd_your_discriminator) != sc->sc_peer->LocalDiscr)) {
- sc->error++;
+ (ntohl(peer->bfd_your_discriminator) != bfd->bc_neighbor->bn_ldiscr)) {
+ bfd->bc_error++;
printf("%s: peer your discr %u != local %u\n",
- __func__, ntohl(peer->bfd_your_discriminator), sc->sc_peer->LocalDiscr);
- sc->sc_peer->LocalDiag = BFD_DIAG_EXPIRED;
- bfd_senddown(sc);
+ __func__, ntohl(peer->bfd_your_discriminator), bfd->bc_neighbor->bn_ldiscr);
+ bfd->bc_neighbor->bn_ldiag = BFD_DIAG_EXPIRED;
+ bfd_senddown(bfd);
goto discard;
}
- if ((flags & BFD_FLAG_A) && sc->sc_peer->AuthType == 0)
+ if ((flags & BFD_FLAG_A) && bfd->bc_neighbor->bn_authtype == 0)
goto discard;
- if (!(flags & BFD_FLAG_A) && sc->sc_peer->AuthType != 0)
+ if (!(flags & BFD_FLAG_A) && bfd->bc_neighbor->bn_authtype != 0)
goto discard;
if (flags & BFD_FLAG_A) {
mp0 = m_pulldown(mp, 0, sizeof(*auth), &offp);
@@ -728,130 +711,130 @@ printf("%s: peer your discr %u != local %u\n",
goto discard;
auth = (struct bfd_auth_header *)(mp0->m_data + offp);
#if 0
- if (bfd_process_auth(sc, auth) != 0) {
+ if (bfd_process_auth(bfd, auth) != 0) {
m_free(mp0);
goto discard;
}
#endif
}
- if ((sc->sc_peer->RemoteDiscr == 0) &&
+ if ((bfd->bc_neighbor->bn_rdiscr == 0) &&
(ntohl(peer->bfd_my_discriminator) != 0))
- sc->sc_peer->RemoteDiscr = ntohl(peer->bfd_my_discriminator);
+ bfd->bc_neighbor->bn_rdiscr = ntohl(peer->bfd_my_discriminator);
- if (sc->sc_peer->RemoteDiscr != ntohl(peer->bfd_my_discriminator))
+ if (bfd->bc_neighbor->bn_rdiscr != ntohl(peer->bfd_my_discriminator))
goto discard;
- sc->sc_peer->RemoteSessionState = state;
+ bfd->bc_neighbor->bn_rstate = state;
- sc->sc_peer->RemoteMinRxInterval =
+ bfd->bc_neighbor->bn_rminrx =
ntohl(peer->bfd_required_min_rx_interval);
/* Local change to the algorithm, we don't accept below 10ms */
- if (sc->sc_peer->RequiredMinRxInterval < BFD_MINIMUM)
+ if (bfd->bc_neighbor->bn_req_minrx < BFD_MINIMUM)
goto discard;
/*
* Local change to the algorithm, we can't use larger than signed
* 32bits for a timeout.
* That is Too Long(tm) anyways.
*/
- if (sc->sc_peer->RequiredMinRxInterval > INT32_MAX)
+ if (bfd->bc_neighbor->bn_req_minrx > INT32_MAX)
goto discard;
- sc->minrx = sc->sc_peer->RequiredMinRxInterval;
+ bfd->bc_minrx = bfd->bc_neighbor->bn_req_minrx;
- sc->sc_peer->DesiredMinTxInterval =
+ bfd->bc_neighbor->bn_mintx =
htonl(peer->bfd_desired_min_tx_interval);
- if (sc->sc_peer->SessionState != BFD_STATE_UP)
- sc->sc_peer->DesiredMinTxInterval = BFD_SECOND;
+ if (bfd->bc_neighbor->bn_lstate != BFD_STATE_UP)
+ bfd->bc_neighbor->bn_mintx = BFD_SECOND;
- sc->sc_peer->RequiredMinRxInterval =
+ bfd->bc_neighbor->bn_req_minrx =
ntohl(peer->bfd_required_min_rx_interval);
/* rfc5880 6.8.7 */
- sc->mintx = max(sc->sc_peer->RemoteMinRxInterval,
- sc->sc_peer->DesiredMinTxInterval);
-
- if (sc->sc_peer->RemoteSessionState == BFD_STATE_ADMINDOWN) {
- if (sc->sc_peer->SessionState != BFD_STATE_DOWN) {
- sc->sc_peer->LocalDiag = BFD_DIAG_NEIGHBOR_SIGDOWN;
- sc->sc_peer->SessionState = BFD_STATE_DOWN;
- bfd_set_state(sc, BFD_STATE_DOWN);
+ bfd->bc_mintx = max(bfd->bc_neighbor->bn_rminrx,
+ bfd->bc_neighbor->bn_mintx);
+
+ if (bfd->bc_neighbor->bn_rstate == BFD_STATE_ADMINDOWN) {
+ if (bfd->bc_neighbor->bn_lstate != BFD_STATE_DOWN) {
+ bfd->bc_neighbor->bn_ldiag = BFD_DIAG_NEIGHBOR_SIGDOWN;
+ bfd->bc_neighbor->bn_lstate = BFD_STATE_DOWN;
+ bfd_set_state(bfd, BFD_STATE_DOWN);
}
goto discard;
}
/* According the to pseudo-code RFC 5880 page 34 */
- if (sc->sc_peer->SessionState == BFD_STATE_DOWN) {
+ if (bfd->bc_neighbor->bn_lstate == BFD_STATE_DOWN) {
printf("%s: BFD_STATE_DOWN remote 0x%x ", __func__, ntohl(peer->bfd_my_discriminator));
printf("local 0x%x\n", ntohl(peer->bfd_your_discriminator));
-bfd_debug(sc);
- if (sc->sc_peer->RemoteSessionState == BFD_STATE_DOWN)
- sc->sc_peer->SessionState = BFD_STATE_INIT;
- else if (sc->sc_peer->RemoteSessionState == BFD_STATE_INIT) {
+bfd_debug(bfd);
+ if (bfd->bc_neighbor->bn_rstate == BFD_STATE_DOWN)
+ bfd->bc_neighbor->bn_lstate = BFD_STATE_INIT;
+ else if (bfd->bc_neighbor->bn_rstate == BFD_STATE_INIT) {
printf("%s: set BFD_STATE_UP\n", __func__);
- sc->sc_peer->LocalDiag = 0;
- bfd_set_state(sc, BFD_STATE_UP);
+ bfd->bc_neighbor->bn_ldiag = 0;
+ bfd_set_state(bfd, BFD_STATE_UP);
}
- } else if (sc->sc_peer->SessionState == BFD_STATE_INIT) {
+ } else if (bfd->bc_neighbor->bn_lstate == BFD_STATE_INIT) {
printf("%s: BFD_STATE_INIT remote 0x%x ", __func__, ntohl(peer->bfd_my_discriminator));
printf("local 0x%x\n", ntohl(peer->bfd_your_discriminator));
- if (sc->sc_peer->RemoteSessionState >= BFD_STATE_INIT) {
+ if (bfd->bc_neighbor->bn_rstate >= BFD_STATE_INIT) {
printf("%s: set BFD_STATE_UP\n", __func__);
- sc->sc_peer->LocalDiag = 0;
- bfd_set_state(sc, BFD_STATE_UP);
+ bfd->bc_neighbor->bn_ldiag = 0;
+ bfd_set_state(bfd, BFD_STATE_UP);
} else {
goto discard;
}
} else {
- if (sc->sc_peer->RemoteSessionState == BFD_STATE_DOWN) {
+ if (bfd->bc_neighbor->bn_rstate == BFD_STATE_DOWN) {
printf("%s: set BFD_STATE_DOWN\n", __func__);
- sc->sc_peer->LocalDiag = BFD_DIAG_NEIGHBOR_SIGDOWN;
- bfd_set_state(sc, BFD_STATE_DOWN);
+ bfd->bc_neighbor->bn_ldiag = BFD_DIAG_NEIGHBOR_SIGDOWN;
+ bfd_set_state(bfd, BFD_STATE_DOWN);
goto discard;
}
}
- if (sc->sc_peer->SessionState == BFD_STATE_UP) {
- sc->sc_peer->LocalDiag = 0;
- sc->sc_peer->DemandMode = 1;
- sc->sc_peer->RemoteDemandMode = (flags & BFD_FLAG_D);
+ if (bfd->bc_neighbor->bn_lstate == BFD_STATE_UP) {
+ bfd->bc_neighbor->bn_ldiag = 0;
+ bfd->bc_neighbor->bn_demand = 1;
+ bfd->bc_neighbor->bn_rdemand = (flags & BFD_FLAG_D);
}
- sc->error = 0;
+ bfd->bc_error = 0;
discard:
m_free(m);
- //XXX task_add(bfdtq, &sc->sc_bfd_send_task);
- timeout_add_usec(&sc->sc_timo_rx, sc->minrx);
+ //XXX task_add(bfdtq, &bfd->bc_bfd_send_task);
+ timeout_add_usec(&bfd->bc_timo_rx, bfd->bc_minrx);
return;
}
void
-bfd_set_state(struct bfd_softc *sc, int state)
+bfd_set_state(struct bfd_config *bfd, int state)
{
struct ifnet *ifp;
- struct rtentry *rt = sc->sc_rt;
+ struct rtentry *rt = bfd->bc_rt;
int new_state;
ifp = if_get(rt->rt_ifidx);
if (ifp == NULL) {
printf("%s: cannot find interface index %u\n",
__func__, rt->rt_ifidx);
- sc->error++;
- bfd_reset(sc);
+ bfd->bc_error++;
+ bfd_reset(bfd);
return;
}
- bfd_set_uptime(sc);
+ bfd_set_uptime(bfd);
- sc->state = sc->sc_peer->SessionState = state;
+ bfd->bc_state = bfd->bc_neighbor->bn_lstate = state;
if (!rtisvalid(rt))
- sc->sc_peer->SessionState = BFD_STATE_ADMINDOWN;
+ bfd->bc_neighbor->bn_lstate = BFD_STATE_ADMINDOWN;
- switch (sc->sc_peer->SessionState) {
+ switch (bfd->bc_neighbor->bn_lstate) {
case BFD_STATE_ADMINDOWN:
new_state = RTM_BFD;
// rt->rt_flags &= ~RTF_BFDUP;
@@ -878,47 +861,47 @@ printf("%s: BFD set linkstate %u (oldstate: %u)\n", ifp->if_xname, new_state, st
}
void
-bfd_set_uptime(struct bfd_softc *sc)
+bfd_set_uptime(struct bfd_config *bfd)
{
struct timeval tv;
microtime(&tv);
- sc->lastuptime = tv.tv_sec - sc->sc_time->tv_sec;
- sc->laststate = sc->state;
- memcpy(sc->sc_time, &tv, sizeof(tv));
+ bfd->bc_lastuptime = tv.tv_sec - bfd->bc_time->tv_sec;
+ bfd->bc_laststate = bfd->bc_state;
+ memcpy(bfd->bc_time, &tv, sizeof(tv));
}
void
bfd_send_control(void *x)
{
- struct bfd_softc *sc = x;
+ struct bfd_config *bfd = x;
struct mbuf *m;
- struct bfd_header *bfd;
+ struct bfd_header *h;
int error;
MGETHDR(m, M_WAIT, MT_DATA);
MCLGET(m, M_WAIT);
m->m_len = m->m_pkthdr.len = sizeof(*bfd);
- bfd = mtod(m, struct bfd_header *);
+ h = mtod(m, struct bfd_header *);
- memset(bfd, 0xff, sizeof(*bfd)); /* canary */
+ memset(bfd, 0xff, sizeof(*h)); /* canary */
- bfd->bfd_ver_diag = ((BFD_VERSION << 5) | (sc->sc_peer->LocalDiag));
- bfd->bfd_sta_flags = (sc->sc_peer->SessionState << 6);
- bfd->bfd_detect_multi = sc->sc_peer->DetectMult;
- bfd->bfd_length = BFD_HDRLEN;
- bfd->bfd_my_discriminator = htonl(sc->sc_peer->LocalDiscr);
- bfd->bfd_your_discriminator = htonl(sc->sc_peer->RemoteDiscr);
+ h->bfd_ver_diag = ((BFD_VERSION << 5) | (bfd->bc_neighbor->bn_ldiag));
+ h->bfd_sta_flags = (bfd->bc_neighbor->bn_lstate << 6);
+ h->bfd_detect_multi = bfd->bc_neighbor->bn_mult;
+ h->bfd_length = BFD_HDRLEN;
+ h->bfd_my_discriminator = htonl(bfd->bc_neighbor->bn_ldiscr);
+ h->bfd_your_discriminator = htonl(bfd->bc_neighbor->bn_rdiscr);
- bfd->bfd_desired_min_tx_interval =
- htonl(sc->sc_peer->DesiredMinTxInterval);
- bfd->bfd_required_min_rx_interval =
- htonl(sc->sc_peer->RequiredMinRxInterval);
- bfd->bfd_required_min_echo_interval =
- htonl(sc->sc_peer->RemoteMinRxInterval);
+ h->bfd_desired_min_tx_interval =
+ htonl(bfd->bc_neighbor->bn_mintx);
+ h->bfd_required_min_rx_interval =
+ htonl(bfd->bc_neighbor->bn_req_minrx);
+ h->bfd_required_min_echo_interval =
+ htonl(bfd->bc_neighbor->bn_rminrx);
- error = bfd_send(sc, m);
+ error = bfd_send(bfd, m);
if (error) {
if (!(error == EHOSTDOWN || error == ECONNREFUSED)) {
@@ -928,25 +911,25 @@ bfd_send_control(void *x)
}
int
-bfd_send(struct bfd_softc *sc, struct mbuf *m)
+bfd_send(struct bfd_config *bfd, struct mbuf *m)
{
- struct rtentry *rt = sc->sc_rt;
+ struct rtentry *rt = bfd->bc_rt;
if (!ISSET(rt->rt_flags, RTF_UP)) {
m_freem(m);
return (EHOSTDOWN);
}
- return (sosend(sc->sc_sosend, NULL, NULL, m, NULL, MSG_DONTWAIT));
+ return (sosend(bfd->bc_sosend, NULL, NULL, m, NULL, MSG_DONTWAIT));
}
/*
* Print debug information about this bfd instance
*/
void
-bfd_debug(struct bfd_softc *sc)
+bfd_debug(struct bfd_config *bfd)
{
- struct rtentry *rt = sc->sc_rt;
+ struct rtentry *rt = bfd->bc_rt;
struct timeval tv;
char buf[64];
@@ -955,32 +938,32 @@ bfd_debug(struct bfd_softc *sc)
sizeof(buf)));
printf("\n");
printf("\t");
- printf("session state: %u ", sc->state);
- printf("mode: %u ", sc->mode);
- printf("error: %u ", sc->error);
- printf("minrx: %u ", sc->minrx);
- printf("mintx: %u ", sc->mintx);
- printf("multiplier: %u ", sc->multiplier);
+ printf("session state: %u ", bfd->bc_state);
+ printf("mode: %u ", bfd->bc_mode);
+ printf("error: %u ", bfd->bc_error);
+ printf("minrx: %u ", bfd->bc_minrx);
+ printf("mintx: %u ", bfd->bc_mintx);
+ printf("multiplier: %u ", bfd->bc_multiplier);
printf("\n");
printf("\t");
- printf("local session state: %u ", sc->sc_peer->SessionState);
- printf("local diag: %u ", sc->sc_peer->LocalDiag);
+ printf("local session state: %u ", bfd->bc_neighbor->bn_lstate);
+ printf("local diag: %u ", bfd->bc_neighbor->bn_ldiag);
printf("\n");
printf("\t");
- printf("remote discriminator: %u ", sc->sc_peer->RemoteDiscr);
- printf("local discriminator: %u ", sc->sc_peer->LocalDiscr);
+ printf("remote discriminator: %u ", bfd->bc_neighbor->bn_rdiscr);
+ printf("local discriminator: %u ", bfd->bc_neighbor->bn_ldiscr);
printf("\n");
printf("\t");
- printf("remote session state: %u ", sc->sc_peer->RemoteSessionState);
- printf("remote diag: %u ", sc->sc_peer->RemoteDiag);
- printf("remote min rx: %u ", sc->sc_peer->RemoteMinRxInterval);
+ printf("remote session state: %u ", bfd->bc_neighbor->bn_rstate);
+ printf("remote diag: %u ", bfd->bc_neighbor->bn_rdiag);
+ printf("remote min rx: %u ", bfd->bc_neighbor->bn_rminrx);
printf("\n");
printf("\t");
- printf("last state: %u ", sc->laststate);
+ printf("last state: %u ", bfd->bc_laststate);
getmicrotime(&tv);
- printf("uptime %llds ", tv.tv_sec - sc->sc_time->tv_sec);
- printf("time started %lld.%06ld ", sc->sc_time->tv_sec,
- sc->sc_time->tv_usec);
- printf("last uptime %llds ", sc->lastuptime);
+ printf("uptime %llds ", tv.tv_sec - bfd->bc_time->tv_sec);
+ printf("time started %lld.%06ld ", bfd->bc_time->tv_sec,
+ bfd->bc_time->tv_usec);
+ printf("last uptime %llds ", bfd->bc_lastuptime);
printf("\n");
}
diff --git a/sys/net/bfd.h b/sys/net/bfd.h
index 26031dabd9d..b36f7948cac 100644
--- a/sys/net/bfd.h
+++ b/sys/net/bfd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: bfd.h,v 1.6 2016/09/15 13:09:44 phessler Exp $ */
+/* $OpenBSD: bfd.h,v 1.7 2016/09/17 07:35:05 phessler Exp $ */
/*
* Copyright (c) 2016 Peter Hessler <phessler@openbsd.org>
@@ -54,57 +54,76 @@
#define BFD_FLAG_M 0x01
struct bfd_msghdr {
- unsigned short rtm_msglen; /* to skip over non-understood msgs */
- unsigned char rtm_version; /* future binary compatibility */
- unsigned char rtm_type; /* message type */
- unsigned short rtm_hdrlen; /* to skip over the header */
-
- uint16_t mode; /* */
- uint32_t mintx; /* minimum time (us) to send */
- uint32_t minrx; /* minimum window (us) to receive */
- uint16_t multiplier; /* Retry backoff multiplier */
-
- time_t uptime;
- time_t lastuptime;
- int state;
- int laststate;
- int error;
-
- uint32_t localdiscr;
- uint32_t localdiag;
- uint32_t remotediscr;
- uint32_t remotediag;
+ unsigned short bm_msglen;
+ unsigned char bm_version;
+ unsigned char bm_type;
+ unsigned short bm_hdrlen;
+ /* above matches rtm_msghdr */
+
+ uint16_t bm_mode;
+ uint32_t bm_mintx;
+ uint32_t bm_minrx;
+ uint16_t bm_multiplier;
+
+ time_t bm_uptime;
+ time_t bm_lastuptime;
+ int bm_state;
+ int bm_laststate;
+ int bm_error;
+
+ uint32_t bm_localdiscr;
+ uint32_t bm_localdiag;
+ uint32_t bm_remotediscr;
+ uint32_t bm_remotediag;
};
#ifdef _KERNEL
-struct bfd_softc {
- TAILQ_ENTRY(bfd_softc) bfd_next;
- struct socket *sc_so;
- struct socket *sc_soecho;
- struct socket *sc_sosend;
- struct rtentry *sc_rt;
- struct bfd_state *sc_peer;
- struct timeval *sc_time;
- struct task sc_bfd_task;
- struct task sc_bfd_send_task;
- struct timeout sc_timo_rx;
- struct timeout sc_timo_tx;
- time_t lastuptime;
- int laststate;
- int state;
- int mode;
- int error;
- int minrx;
- int mintx;
- int multiplier;
+/* state machine from RFC 5880 6.8.1*/
+struct bfd_neighbor {
+ uint32_t bn_lstate; /* SessionState */
+ uint32_t bn_rstate; /* RemoteSessionState */
+ uint32_t bn_ldiscr; /* LocalDiscr */
+ uint32_t bn_rdiscr; /* RemoteDiscr */
+ uint32_t bn_ldiag; /* LocalDiag */
+ uint32_t bn_rdiag; /* RemoteDiag */
+ uint32_t bn_mintx; /* DesiredMinTxInterval */
+ uint32_t bn_req_minrx; /* RequiredMinRxInterval */
+ uint32_t bn_rminrx; /* RemoteMinRxInterval */
+ uint32_t bn_demand; /* DemandMode */
+ uint32_t bn_rdemand; /* RemoteDemandMode */
+ uint32_t bn_mult; /* DetectMult */
+ uint32_t bn_authtype; /* AuthType */
+ uint32_t bn_rauthseq; /* RcvAuthSeq */
+ uint32_t bn_lauthseq; /* XmitAuthSeq */
+ uint32_t bn_authseqknown; /* AuthSeqKnown */
+};
+
+struct bfd_config {
+ TAILQ_ENTRY(bfd_config) bc_entry;
+ struct socket *bc_so;
+ struct socket *bc_soecho;
+ struct socket *bc_sosend;
+ struct rtentry *bc_rt;
+ struct bfd_neighbor *bc_neighbor;
+ struct timeval *bc_time;
+ struct task bc_bfd_task;
+ struct task bc_bfd_send_task;
+ struct timeout bc_timo_rx;
+ struct timeout bc_timo_tx;
+ time_t bc_lastuptime;
+ int bc_laststate;
+ int bc_state;
+ int bc_mode;
+ int bc_error;
+ int bc_minrx;
+ int bc_mintx;
+ int bc_multiplier;
};
-#endif /* _KERNEL */
-int bfd_rtalloc(struct rtentry *);
-void bfd_rtfree(struct rtentry *);
+int bfdset(struct rtentry *);
+void bfdclear(struct rtentry *);
void bfdinit(void);
-void bfddestroy(void);
-struct bfd_softc *bfd_lookup(struct rtentry *);
+#endif /* _KERNEL */
#endif /* _NET_BFD_H_ */
diff --git a/sys/net/route.c b/sys/net/route.c
index d15074e92cb..b80fbc459a8 100644
--- a/sys/net/route.c
+++ b/sys/net/route.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: route.c,v 1.329 2016/09/15 02:00:18 dlg Exp $ */
+/* $OpenBSD: route.c,v 1.330 2016/09/17 07:35:05 phessler Exp $ */
/* $NetBSD: route.c,v 1.14 1996/02/13 22:00:46 christos Exp $ */
/*
@@ -889,7 +889,7 @@ rtrequest_delete(struct rt_addrinfo *info, u_int8_t prio, struct ifnet *ifp,
#ifdef BFD
if (ISSET(rt->rt_flags, RTF_BFD))
- bfd_rtfree(rt);
+ bfdclear(rt);
#endif
/* Release next hop cache before flushing cloned entries. */
diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c
index 014d46c82e8..9e0b4ef8087 100644
--- a/sys/net/rtsock.c
+++ b/sys/net/rtsock.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rtsock.c,v 1.204 2016/09/07 09:36:49 mpi Exp $ */
+/* $OpenBSD: rtsock.c,v 1.205 2016/09/17 07:35:05 phessler Exp $ */
/* $NetBSD: rtsock.c,v 1.18 1996/03/29 00:32:10 cgd Exp $ */
/*
@@ -885,11 +885,11 @@ change:
#ifdef BFD
if (ISSET(rtm->rtm_flags, RTF_BFD)) {
- if ((error = bfd_rtalloc(rt)))
+ if ((error = bfdset(rt)))
goto flush;
} else if (!ISSET(rtm->rtm_flags, RTF_BFD) &&
ISSET(rtm->rtm_fmask, RTF_BFD)) {
- bfd_rtfree(rt);
+ bfdclear(rt);
}
#endif