This is a work-in-progress diff that I would like to commit. I can print
a few things, but there is a problem when trying to bring in more
fields. Printing is also ugly, but I can fix that in-tree.
While here, I print the descr's as ints, the same way Juniper does it.
I also had to add RTM_INVALIDATE, to keep the ordering correct.
Am I tying this into route(8) and rtsock.c correctly?
OK?
Index: sbin/route/route.c
===================================================================
RCS file: /cvs/openbsd/src/sbin/route/route.c,v
retrieving revision 1.190
diff -u -p -u -p -r1.190 route.c
--- sbin/route/route.c 4 Sep 2016 09:41:03 -0000 1.190
+++ sbin/route/route.c 14 Sep 2016 10:20:04 -0000
@@ -41,6 +41,10 @@
#include <netinet/in.h>
#include <netmpls/mpls.h>
+#include <sys/task.h>
+#include <sys/timeout.h>
+#include <net/bfd.h>
+
#include <arpa/inet.h>
#include <netdb.h>
@@ -90,6 +94,7 @@ void sodump(sup, char *);
char *priorityname(uint8_t);
uint8_t getpriority(char *);
void print_getmsg(struct rt_msghdr *, int);
+void print_bfdmsg(struct bfd_msghdr *);
const char *get_linkstate(int, int);
void print_rtmsg(struct rt_msghdr *, int);
void pmsg_common(struct rt_msghdr *);
@@ -1240,6 +1245,7 @@ char *msgtypes[] = {
"RTM_IFINFO: iface status change",
"RTM_IFANNOUNCE: iface arrival/departure",
"RTM_DESYNC: route socket overflow",
+ "RTM_INVALIDATE: invalidate cache of L2 route",
"RTM_BFD: bidirectional forwarding detection",
};
@@ -1277,6 +1283,7 @@ print_rtmsg(struct rt_msghdr *rtm, int m
struct if_msghdr *ifm;
struct ifa_msghdr *ifam;
struct if_announcemsghdr *ifan;
+ struct bfd_msghdr *bfd;
char ifname[IF_NAMESIZE];
if (verbose == 0)
@@ -1333,7 +1340,9 @@ print_rtmsg(struct rt_msghdr *rtm, int m
printf("\n");
break;
case RTM_BFD:
- printf("bfd\n"); /* XXX - expand*/
+ bfd = (struct bfd_msghdr *)rtm;
+ printf(", BFD ");
+ print_bfdmsg(bfd);
break;
default:
printf(", priority %d, table %u, ifidx %u, ",
@@ -1524,6 +1533,48 @@ print_getmsg(struct rt_msghdr *rtm, int
putchar('\n');
}
#undef RTA_IGN
+}
+
+void
+print_bfdmsg(struct bfd_msghdr *bfd)
+{
+ printf("mode ");
+ switch (bfd->mode) {
+ case BFD_MODE_ASYNC:
+ printf("ASYNC");
+ break;
+ case BFD_MODE_DEMAND:
+ printf("DEMAND");
+ break;
+ }
+ printf(" state ");
+ switch (bfd->state) {
+ case BFD_STATE_ADMINDOWN:
+ printf("AdminDown");
+ break;
+ case BFD_STATE_DOWN:
+ printf("Down");
+ break;
+ case BFD_STATE_INIT:
+ printf("Init");
+ break;
+ case BFD_STATE_UP:
+ printf("Up");
+ break;
+ }
+ printf(" error %d", bfd->error);
+ printf(" localdiscr %u", bfd->localdiscr);
+ printf(" remotediscr %u", bfd->remotediscr);
+ printf(" localdiag %u", bfd->localdiag);
+ printf(" remotediag %u", bfd->remotediag);
+ printf(" uptime %lld", bfd->uptime);
+ printf(" lastuptime %lld", bfd->lastuptime);
+
+ printf(" mintx %ums", bfd->mintx / 1000);
+ printf(" minrx %ums", bfd->minrx / 1000);
+ printf(" multiplier %ux", bfd->multiplier);
+
+ printf("\n");
}
void
Index: sys/net/bfd.c
===================================================================
RCS file: /cvs/openbsd/src/sys/net/bfd.c,v
retrieving revision 1.24
diff -u -p -u -p -r1.24 bfd.c
--- sys/net/bfd.c 13 Sep 2016 07:56:05 -0000 1.24
+++ sys/net/bfd.c 14 Sep 2016 10:48:39 -0000
@@ -161,7 +161,7 @@ struct bfd_state {
uint32_t AuthSeqKnown;
};
-struct pool bfd_pool, bfd_pool_peer, bfd_pool_time;
+struct pool bfd_pool, bfd_pool_peer, bfd_pool_time, bfd_pool_msghdr;
struct taskq *bfdtq;
struct socket *bfd_listener(struct bfd_softc *, unsigned int);
@@ -182,6 +182,7 @@ void bfd_senddown(struct bfd_softc *);
void bfd_reset(struct bfd_softc *);
void bfd_set_uptime(struct bfd_softc *);
+void bfd_prepmsg(struct bfd_softc *);
void bfd_debug(struct bfd_softc *);
TAILQ_HEAD(bfd_queue, bfd_softc) bfd_queue;
@@ -224,9 +225,38 @@ bfd_rtalloc(struct rtentry *rt)
TAILQ_INSERT_TAIL(&bfd_queue, sc, bfd_next);
+ bfd_prepmsg(sc);
return (0);
}
+void
+bfd_prepmsg(struct bfd_softc *sc)
+{
+ struct bfd_msghdr *bfd;
+
+ bfd = pool_get(&bfd_pool_msghdr, PR_WAITOK | PR_ZERO);
+
+ bfd->mode = sc->mode;
+ bfd->mintx = sc->mintx;
+ bfd->minrx = sc->minrx;
+ bfd->multiplier = sc->multiplier;
+
+ bfd->uptime = sc->sc_time->tv_sec;
+ bfd->lastuptime = sc->lastuptime;
+ bfd->state = sc->state;
+ bfd->laststate = sc->laststate;
+ bfd->error = sc->error;
+
+ bfd->localdiscr = sc->sc_peer->LocalDiscr;
+ bfd->localdiag = sc->sc_peer->LocalDiag;
+ bfd->remotediscr = sc->sc_peer->RemoteDiscr;
+ bfd->remotediag = sc->sc_peer->RemoteDiag;
+
+ bfd_msg(bfd);
+
+ pool_put(&bfd_pool, bfd);
+}
+
/*
* remove and free a bfd session
*/
@@ -283,6 +313,9 @@ bfdinit(void)
pool_init(&bfd_pool_time, sizeof(struct timeval), 0, 0, 0,
"bfd_softc_time", NULL);
pool_setipl(&bfd_pool_time, IPL_SOFTNET);
+ pool_init(&bfd_pool_msghdr, sizeof(struct bfd_msghdr), 0, 0, 0,
+ "bfd_msghdr", NULL);
+ pool_setipl(&bfd_pool_msghdr, IPL_SOFTNET);
bfdtq = taskq_create("bfd", 1, IPL_SOFTNET, 0);
if (bfdtq == NULL)
@@ -306,6 +339,7 @@ bfddestroy(void)
}
taskq_destroy(bfdtq);
+ pool_destroy(&bfd_pool_msghdr);
pool_destroy(&bfd_pool_time);
pool_destroy(&bfd_pool_peer);
pool_destroy(&bfd_pool);
@@ -376,6 +410,7 @@ bfd_send_task(void *arg)
bfd_set_state(sc, BFD_STATE_DOWN);
}
}
+bfd_prepmsg(sc);
/* re-add 70%-90% jitter to our transmits, rfc 5880 6.8.7 */
timeout_add_usec(&sc->sc_timo_tx,
@@ -873,7 +908,7 @@ bfd_set_state(struct bfd_softc *sc, int
}
printf("%s: BFD set linkstate %u (oldstate: %u)\n", ifp->if_xname, new_state,
state);
- rt_sendmsg(rt, new_state, ifp->if_rdomain);
+ bfd_prepmsg(sc);
if_put(ifp);
@@ -970,8 +1005,8 @@ bfd_debug(struct bfd_softc *sc)
printf("local diag: %u ", sc->sc_peer->LocalDiag);
printf("\n");
printf("\t");
- printf("remote discriminator: 0x%x ", sc->sc_peer->RemoteDiscr);
- printf("local discriminator: 0x%x ", sc->sc_peer->LocalDiscr);
+ printf("remote discriminator: %u ", sc->sc_peer->RemoteDiscr);
+ printf("local discriminator: %u ", sc->sc_peer->LocalDiscr);
printf("\n");
printf("\t");
printf("remote session state: %u ", sc->sc_peer->RemoteSessionState);
Index: sys/net/route.h
===================================================================
RCS file: /cvs/openbsd/src/sys/net/route.h,v
retrieving revision 1.147
diff -u -p -u -p -r1.147 route.h
--- sys/net/route.h 4 Sep 2016 10:32:01 -0000 1.147
+++ sys/net/route.h 14 Sep 2016 09:09:29 -0000
@@ -356,6 +356,7 @@ struct mbuf;
struct socket;
struct ifnet;
struct sockaddr_in6;
+struct bfd_msghdr;
void route_init(void);
int route_output(struct mbuf *, ...);
@@ -363,6 +364,7 @@ int route_usrreq(struct socket *, int,
struct mbuf *, struct mbuf *, struct proc *);
void rt_ifmsg(struct ifnet *);
void rt_ifannouncemsg(struct ifnet *, int);
+void bfd_msg(struct bfd_msghdr *);
void rt_maskedcopy(struct sockaddr *,
struct sockaddr *, struct sockaddr *);
struct sockaddr *rt_plen2mask(struct rtentry *, struct sockaddr_in6 *);
Index: sys/net/rtsock.c
===================================================================
RCS file: /cvs/openbsd/src/sys/net/rtsock.c,v
retrieving revision 1.204
diff -u -p -u -p -r1.204 rtsock.c
--- sys/net/rtsock.c 7 Sep 2016 09:36:49 -0000 1.204
+++ sys/net/rtsock.c 14 Sep 2016 13:37:04 -0000
@@ -1100,6 +1100,9 @@ rt_msg1(int type, struct rt_addrinfo *rt
case RTM_IFANNOUNCE:
len = sizeof(struct if_announcemsghdr);
break;
+ case RTM_BFD:
+ len = sizeof(struct bfd_msghdr);
+ break;
default:
len = sizeof(struct rt_msghdr);
break;
@@ -1329,6 +1332,27 @@ rt_ifannouncemsg(struct ifnet *ifp, int
ifan->ifan_index = ifp->if_index;
strlcpy(ifan->ifan_name, ifp->if_xname, sizeof(ifan->ifan_name));
ifan->ifan_what = what;
+ route_proto.sp_protocol = 0;
+ route_input(m, &route_proto, &route_src, &route_dst);
+}
+
+void
+bfd_msg(struct bfd_msghdr *bfd0)
+{
+ struct bfd_msghdr *bfd;
+ struct mbuf *m;
+
+ if (route_cb.any_count == 0)
+ return;
+ m = rt_msg1(RTM_BFD, NULL);
+ if (m == NULL)
+ return;
+ bfd = mtod(m, struct bfd_msghdr *);
+
+ bfd->mode = bfd0->mode;
+ bfd->localdiscr = bfd0->localdiscr;
+ bfd->state = bfd0->state;
+
route_proto.sp_protocol = 0;
route_input(m, &route_proto, &route_src, &route_dst);
}
--
The algorithm to do that is extremely nasty. You might want to mug
someone with it.
-- M. Devine, Computer Science 340