On 2016 Sep 17 (Sat) at 12:05:54 +0200 (+0200), Peter Hessler wrote:
:This is a 2nd pass at having BFD send route messages.
:
:I fixed the things pointed out in the first thread, with the following
:comments:
:
: route(8) for the ramdisks is not built with SMALL, so adding SMALL
:won't help.
:
: rt_bfdmsg() is named in the same style, and is in the same place, as
:the other functions that send route messages
:
:OK?
:
SMALL has been added to route(8) for the ramdisks, and I have improved
printing some of the bfd fields.
this diff depends on rev 1.9 of bfd.h I just committed.
OK?
Index: sys/net/rtsock.c
===================================================================
RCS file: /cvs/openbsd/src/sys/net/rtsock.c,v
retrieving revision 1.205
diff -u -p -u -p -r1.205 rtsock.c
--- sys/net/rtsock.c 17 Sep 2016 07:35:05 -0000 1.205
+++ sys/net/rtsock.c 19 Sep 2016 08:15:50 -0000
@@ -1100,6 +1100,11 @@ rt_msg1(int type, struct rt_addrinfo *rt
case RTM_IFANNOUNCE:
len = sizeof(struct if_announcemsghdr);
break;
+#ifdef BFD
+ case RTM_BFD:
+ len = sizeof(struct bfd_msghdr);
+ break;
+#endif
default:
len = sizeof(struct rt_msghdr);
break;
@@ -1332,6 +1337,47 @@ rt_ifannouncemsg(struct ifnet *ifp, int
route_proto.sp_protocol = 0;
route_input(m, &route_proto, &route_src, &route_dst);
}
+
+#ifdef BFD
+/*
+ * This is used to generate routing socket messages indicating
+ * the state of a BFD session.
+ */
+void
+rt_bfdmsg(struct bfd_config *bfd)
+{
+ struct bfd_msghdr *bfdm;
+ struct mbuf *m;
+
+ if (route_cb.any_count == 0)
+ return;
+ m = rt_msg1(RTM_BFD, NULL);
+ if (m == NULL)
+ return;
+ bfdm = mtod(m, struct bfd_msghdr *);
+
+ bfdm->bm_mode = bfd->bc_mode;
+ bfdm->bm_mintx = bfd->bc_mintx;
+ bfdm->bm_minrx = bfd->bc_minrx;
+ bfdm->bm_minecho = bfd->bc_minecho;
+ bfdm->bm_multiplier = bfd->bc_multiplier;
+
+ bfdm->bm_uptime = bfd->bc_time->tv_sec;
+ bfdm->bm_lastuptime = bfd->bc_lastuptime;
+ bfdm->bm_state = bfd->bc_state;
+ bfdm->bm_remotestate = bfd->bc_neighbor->bn_rstate;
+ bfdm->bm_laststate = bfd->bc_laststate;
+ bfdm->bm_error = bfd->bc_error;
+
+ bfdm->bm_localdiscr = bfd->bc_neighbor->bn_ldiscr;
+ bfdm->bm_localdiag = bfd->bc_neighbor->bn_ldiag;
+ bfdm->bm_remotediscr = bfd->bc_neighbor->bn_rdiscr;
+ bfdm->bm_remotediag = bfd->bc_neighbor->bn_rdiag;
+
+ route_proto.sp_protocol = 0;
+ route_input(m, &route_proto, &route_src, &route_dst);
+}
+#endif /* BFD */
/*
* This is used in dumping the kernel table via sysctl().
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 17 Sep 2016 09:33:22 -0000
@@ -356,6 +356,7 @@ struct mbuf;
struct socket;
struct ifnet;
struct sockaddr_in6;
+struct bfd_config;
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 rt_bfdmsg(struct bfd_config *);
void rt_maskedcopy(struct sockaddr *,
struct sockaddr *, struct sockaddr *);
struct sockaddr *rt_plen2mask(struct rtentry *, struct sockaddr_in6 *);
Index: sbin/route/route.c
===================================================================
RCS file: /cvs/openbsd/src/sbin/route/route.c,v
retrieving revision 1.191
diff -u -p -u -p -r1.191 route.c
--- sbin/route/route.c 15 Sep 2016 12:51:20 -0000 1.191
+++ sbin/route/route.c 20 Sep 2016 10:46:16 -0000
@@ -41,6 +41,11 @@
#include <netinet/in.h>
#include <netmpls/mpls.h>
+#ifndef SMALL
+#include <sys/time.h>
+#include <net/bfd.h>
+#endif
+
#include <arpa/inet.h>
#include <netdb.h>
@@ -90,6 +95,12 @@ void sodump(sup, char *);
char *priorityname(uint8_t);
uint8_t getpriority(char *);
void print_getmsg(struct rt_msghdr *, int);
+#ifndef SMALL
+const char *bfd_printstate(unsigned int);
+const char *bfd_printdiag(unsigned int);
+const char *bfd_calc_uptime(time_t);
+void print_bfdmsg(struct rt_msghdr *);
+#endif
const char *get_linkstate(int, int);
void print_rtmsg(struct rt_msghdr *, int);
void pmsg_common(struct rt_msghdr *);
@@ -1334,7 +1345,9 @@ print_rtmsg(struct rt_msghdr *rtm, int m
printf("\n");
break;
case RTM_BFD:
- printf("bfd\n"); /* XXX - expand*/
+#ifndef SMALL
+ print_bfdmsg(rtm);
+#endif
break;
default:
printf(", priority %d, table %u, ifidx %u, ",
@@ -1526,6 +1539,98 @@ print_getmsg(struct rt_msghdr *rtm, int
}
#undef RTA_IGN
}
+
+#ifndef SMALL
+const char *
+bfd_printstate(unsigned int state)
+{
+ switch (state) {
+ case BFD_STATE_ADMINDOWN: return("admindown");
+ case BFD_STATE_DOWN: return("down");
+ case BFD_STATE_INIT: return("init");
+ case BFD_STATE_UP: return("up");
+ }
+ return "invalid";
+}
+
+const char *
+bfd_printdiag(unsigned int diag)
+{
+ switch (diag) {
+ case BFD_DIAG_NONE: return("none");
+ case BFD_DIAG_EXPIRED: return("expired");
+ case BFD_DIAG_ECHO_FAILED: return("echo-failed");
+ case BFD_DIAG_NEIGHBOR_SIGDOWN: return("neighbor-down");
+ case BFD_DIAG_FIB_RESET: return("fib-reset");
+ case BFD_DIAG_PATH_DOWN: return("path-down");
+ case BFD_DIAG_CONCAT_PATH_DOWN: return("concat-path-down");
+ case BFD_DIAG_ADMIN_DOWN: return("admindown");
+ case BFD_DIAG_CONCAT_REVERSE_DOWN: return("concat-reverse-down");
+ }
+ return "invalid";
+}
+
+const char *
+bfd_calc_uptime(time_t time)
+{
+ static char buf[256];
+ struct tm *tp;
+ const char *fmt;
+
+ if (time > 2*86400)
+ fmt = "%dd%kh%Mm%Ss";
+ else if (time > 2*3600)
+ fmt = "%kh%Mm%Ss";
+ else if (time > 2*60)
+ fmt = "%Mm%Ss";
+ else
+ fmt = "%Ss";
+
+ tp = localtime(&time);
+ (void)strftime(buf, sizeof(buf), fmt, tp);
+ return (buf);
+}
+
+void
+print_bfdmsg(struct rt_msghdr *rtm)
+{
+ struct bfd_msghdr *bfdm = (struct bfd_msghdr *)rtm;
+ struct timeval tv;
+
+ gettimeofday(&tv, NULL);
+
+ printf(" mode ");
+ switch (bfdm->bm_mode) {
+ case BFD_MODE_ASYNC:
+ printf("async");
+ break;
+ case BFD_MODE_DEMAND:
+ printf("demand");
+ break;
+ default:
+ printf("unknown %u", bfdm->bm_mode);
+ break;
+ }
+ printf(" state %s", bfd_printstate(bfdm->bm_state));
+ printf(" remotestate %s", bfd_printstate(bfdm->bm_remotestate));
+ printf(" laststate %s", bfd_printstate(bfdm->bm_laststate));
+
+ printf(" error %d", bfdm->bm_error);
+ printf(" localdiscr %u", bfdm->bm_localdiscr);
+ printf(" remotediscr %u", bfdm->bm_remotediscr);
+ printf(" localdiag %s", bfd_printdiag(bfdm->bm_localdiag));
+ printf(" remotediag %s", bfd_printdiag(bfdm->bm_remotediag));
+ printf(" uptime %s", bfd_calc_uptime(tv.tv_sec - bfdm->bm_uptime));
+ printf(" lastuptime %s", bfd_calc_uptime(bfdm->bm_lastuptime));
+
+ printf(" mintx %u", bfdm->bm_mintx);
+ printf(" minrx %u", bfdm->bm_minrx);
+ printf(" minecho %u", bfdm->bm_minecho);
+ printf(" multiplier %u", bfdm->bm_multiplier);
+
+ pmsg_addrs(((char *)rtm + rtm->rtm_hdrlen), rtm->rtm_addrs);
+}
+#endif /* !SMALL */
void
pmsg_common(struct rt_msghdr *rtm)
--
Anybody can win, unless there happens to be a second entry.