teach BFD how to send route messages, again

classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

teach BFD how to send route messages, again

phessler
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?



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 17 Sep 2016 09:42:17 -0000
@@ -40,6 +40,7 @@
 #include <net/route.h>
 #include <netinet/in.h>
 #include <netmpls/mpls.h>
+#include <net/bfd.h>
 
 #include <arpa/inet.h>
 #include <netdb.h>
@@ -90,6 +91,8 @@ void sodump(sup, char *);
 char *priorityname(uint8_t);
 uint8_t getpriority(char *);
 void print_getmsg(struct rt_msghdr *, int);
+const char *bfd_printstate(unsigned int);
+void print_bfdmsg(struct rt_msghdr *);
 const char *get_linkstate(int, int);
 void print_rtmsg(struct rt_msghdr *, int);
 void pmsg_common(struct rt_msghdr *);
@@ -1334,7 +1337,7 @@ print_rtmsg(struct rt_msghdr *rtm, int m
  printf("\n");
  break;
  case RTM_BFD:
- printf("bfd\n"); /* XXX - expand*/
+ print_bfdmsg(rtm);
  break;
  default:
  printf(", priority %d, table %u, ifidx %u, ",
@@ -1525,6 +1528,51 @@ print_getmsg(struct rt_msghdr *rtm, int
  putchar('\n');
  }
 #undef RTA_IGN
+}
+
+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";
+}
+
+void
+print_bfdmsg(struct rt_msghdr *rtm)
+{
+ struct bfd_msghdr *bfdm = (struct bfd_msghdr *)rtm;
+
+ printf(" mode ");
+ switch (bfdm->bm_mode) {
+ case BFD_MODE_ASYNC:
+ printf("async");
+ break;
+ case BFD_MODE_DEMAND:
+ printf("demand");
+ 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 %u", bfdm->bm_localdiag);
+ printf(" remotediag %u", bfdm->bm_remotediag);
+ printf(" uptime %lld", bfdm->bm_uptime);
+ printf(" lastuptime %lld", bfdm->bm_lastuptime);
+
+ printf(" mintx %u", bfdm->bm_mintx);
+ printf(" minrx %u", bfdm->bm_minrx);
+ printf(" multiplier %u", bfdm->bm_multiplier);
+
+ pmsg_addrs(((char *)rtm + rtm->rtm_hdrlen), rtm->rtm_addrs);
 }
 
 void
Index: sys/net/bfd.h
===================================================================
RCS file: /cvs/openbsd/src/sys/net/bfd.h,v
retrieving revision 1.7
diff -u -p -u -p -r1.7 bfd.h
--- sys/net/bfd.h 17 Sep 2016 07:35:05 -0000 1.7
+++ sys/net/bfd.h 17 Sep 2016 09:38:24 -0000
@@ -68,6 +68,7 @@ struct bfd_msghdr {
  time_t bm_uptime;
  time_t bm_lastuptime;
  int bm_state;
+ int bm_remotestate;
  int bm_laststate;
  int bm_error;
 
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: 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 17 Sep 2016 09:37:15 -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,46 @@ 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_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().



--
What garlic is to salad, insanity is to art.

Reply | Threaded
Open this post in threaded view
|

Re: teach BFD how to send route messages, again

Theo de Raadt-2
>  route(8) for the ramdisks is not built with SMALL, so adding SMALL
> won't help.

Then you'll help it.   By compiling them SMALL.  Otherwise they
won't fit, and bfd gets ripped out.

Reply | Threaded
Open this post in threaded view
|

Re: teach BFD how to send route messages, again

phessler
On 2016 Sep 17 (Sat) at 04:50:29 -0600 (-0600), Theo de Raadt wrote:
:>  route(8) for the ramdisks is not built with SMALL, so adding SMALL
:> won't help.
:
:Then you'll help it.   By compiling them SMALL.

Happilly.

Tested on an amd64 bsd.rd. dhclient, route add, route del, route show,
all still work, and it's slightly smaller.

text    data    bss     dec     hex
213397  8896    36896   259189  3f475 obj/route
212677  8896    36896   258469  3f1a5 obj/route-SMALL


OK?

Index: distrib/special/route/Makefile
===================================================================
RCS file: /cvs/openbsd/src/distrib/special/route/Makefile,v
retrieving revision 1.1
diff -u -p -u -p -r1.1 Makefile
--- distrib/special/route/Makefile 23 Dec 2014 17:16:03 -0000 1.1
+++ distrib/special/route/Makefile 17 Sep 2016 11:09:59 -0000
@@ -4,7 +4,7 @@ PROG= route
 MAN= route.8
 SRCS= route.c show.c
 
-CFLAGS+= -Wall
+CFLAGS+= -Wall -DSMALL
 
 route.o .depend lint tags: keywords.h
 

Reply | Threaded
Open this post in threaded view
|

Re: teach BFD how to send route messages, again

phessler
On 2016 Sep 17 (Sat) at 13:15:56 +0200 (+0200), Peter Hessler wrote:
:On 2016 Sep 17 (Sat) at 04:50:29 -0600 (-0600), Theo de Raadt wrote:
::>  route(8) for the ramdisks is not built with SMALL, so adding SMALL
::> won't help.
::
::Then you'll help it.   By compiling them SMALL.
:
:Happilly.
:
:Tested on an amd64 bsd.rd. dhclient, route add, route del, route show,
:all still work, and it's slightly smaller.
:
:text    data    bss     dec     hex
:213397  8896    36896   259189  3f475 obj/route
:212677  8896    36896   258469  3f1a5 obj/route-SMALL
:
:
:OK?
:
:Index: distrib/special/route/Makefile
:===================================================================
:RCS file: /cvs/openbsd/src/distrib/special/route/Makefile,v
:retrieving revision 1.1
:diff -u -p -u -p -r1.1 Makefile
:--- distrib/special/route/Makefile 23 Dec 2014 17:16:03 -0000 1.1
:+++ distrib/special/route/Makefile 17 Sep 2016 11:09:59 -0000
:@@ -4,7 +4,7 @@ PROG= route
: MAN= route.8
: SRCS= route.c show.c
:
:-CFLAGS+= -Wall
:+CFLAGS+= -Wall -DSMALL
:
: route.o .depend lint tags: keywords.h
:
:

And with sbin/route/route.c updated to use SMALL

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 17 Sep 2016 10:57:02 -0000
@@ -41,6 +41,10 @@
 #include <netinet/in.h>
 #include <netmpls/mpls.h>
 
+#ifndef SMALL
+#include <net/bfd.h>
+#endif
+
 #include <arpa/inet.h>
 #include <netdb.h>
 
@@ -90,6 +94,10 @@ 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);
+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 +1342,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 +1536,53 @@ 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";
+}
+
+void
+print_bfdmsg(struct rt_msghdr *rtm)
+{
+ struct bfd_msghdr *bfdm = (struct bfd_msghdr *)rtm;
+
+ printf(" mode ");
+ switch (bfdm->bm_mode) {
+ case BFD_MODE_ASYNC:
+ printf("async");
+ break;
+ case BFD_MODE_DEMAND:
+ printf("demand");
+ 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 %u", bfdm->bm_localdiag);
+ printf(" remotediag %u", bfdm->bm_remotediag);
+ printf(" uptime %lld", bfdm->bm_uptime);
+ printf(" lastuptime %lld", bfdm->bm_lastuptime);
+
+ printf(" mintx %u", bfdm->bm_mintx);
+ printf(" minrx %u", bfdm->bm_minrx);
+ 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)

Reply | Threaded
Open this post in threaded view
|

Re: teach BFD how to send route messages, again

phessler
In reply to this post by phessler
On 2016 Sep 17 (Sat) at 13:15:56 +0200 (+0200), Peter Hessler wrote:
:On 2016 Sep 17 (Sat) at 04:50:29 -0600 (-0600), Theo de Raadt wrote:
::>  route(8) for the ramdisks is not built with SMALL, so adding SMALL
::> won't help.
::
::Then you'll help it.   By compiling them SMALL.
:
:Happilly.
:
:Tested on an amd64 bsd.rd. dhclient, route add, route del, route show,
:all still work, and it's slightly smaller.
:

All options, commands, modifiers, and special names for networks have
been tested.  Some modifiers are already disabled in a SMALL kernel (esp
mpath and mpls).


:text    data    bss     dec     hex
:213397  8896    36896   259189  3f475 obj/route
:212677  8896    36896   258469  3f1a5 obj/route-SMALL
:
:
:OK?
:
:Index: distrib/special/route/Makefile
:===================================================================
:RCS file: /cvs/openbsd/src/distrib/special/route/Makefile,v
:retrieving revision 1.1
:diff -u -p -u -p -r1.1 Makefile
:--- distrib/special/route/Makefile 23 Dec 2014 17:16:03 -0000 1.1
:+++ distrib/special/route/Makefile 17 Sep 2016 11:09:59 -0000
:@@ -4,7 +4,7 @@ PROG= route
: MAN= route.8
: SRCS= route.c show.c
:
:-CFLAGS+= -Wall
:+CFLAGS+= -Wall -DSMALL
:
: route.o .depend lint tags: keywords.h
:
:

--
If A = B and B = C, then A = C, except where void or prohibited by law.
                -- Roy Santoro

Reply | Threaded
Open this post in threaded view
|

Re: teach BFD how to send route messages, again

phessler
On 2016 Sep 18 (Sun) at 20:29:57 +0200 (+0200), Peter Hessler wrote:
:On 2016 Sep 17 (Sat) at 13:15:56 +0200 (+0200), Peter Hessler wrote:
::Tested on an amd64 bsd.rd. dhclient, route add, route del, route show,
::all still work, and it's slightly smaller.
::
:
:All options, commands, modifiers, and special names for networks have
:been tested.  Some modifiers are already disabled in a SMALL kernel (esp
:mpath and mpls).
:

ping.  OK?


:
::text    data    bss     dec     hex
::213397  8896    36896   259189  3f475 obj/route
::212677  8896    36896   258469  3f1a5 obj/route-SMALL
::
::
::OK?
::
::Index: distrib/special/route/Makefile
::===================================================================
::RCS file: /cvs/openbsd/src/distrib/special/route/Makefile,v
::retrieving revision 1.1
::diff -u -p -u -p -r1.1 Makefile
::--- distrib/special/route/Makefile 23 Dec 2014 17:16:03 -0000 1.1
::+++ distrib/special/route/Makefile 17 Sep 2016 11:09:59 -0000
::@@ -4,7 +4,7 @@ PROG= route
:: MAN= route.8
:: SRCS= route.c show.c
::
::-CFLAGS+= -Wall
::+CFLAGS+= -Wall -DSMALL
::
:: route.o .depend lint tags: keywords.h
::
::

Reply | Threaded
Open this post in threaded view
|

Re: teach BFD how to send route messages, again

phessler
In reply to this post by phessler
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.