On 2016 Sep 30 (Fri) at 10:16:19 +0200 (+0200), Peter Hessler wrote:
:This diff makes route get and route monitor work. sockaddr_bfd is so we
:can play like the other RTAX_* indexes in rti_info of route messages.
:
:OK?
Updated output, requested by Theo. A normal get will show just the bfd
state, use "-bfd" to get all of the information.
OK?
$ route -n get 203.0.113.9
route to: 203.0.113.9
destination: 203.0.113.9
mask: 255.255.255.255
interface: em1
if address: 203.0.113.1
priority: 4 (connected)
flags: <UP,HOST,DONE,LLINFO,CLONED,BFD>
BFD: async state up remote up
use mtu expire
83924 0 133
sockaddrs: <DST,GATEWAY,NETMASK,IFP,IFA>
$ route -n get 203.0.113.9 -bfd
route to: 203.0.113.9
destination: 203.0.113.9
mask: 255.255.255.255
interface: em1
if address: 203.0.113.1
priority: 4 (connected)
flags: <UP,HOST,DONE,LLINFO,CLONED,BFD>
BFD: async state up remote up laststate down error 0
diag none remote neighbor-down
discr 186919089 remote 55
uptime 05d 2h07m29s
mintx 1000000 minrx 1000000 minecho 0 multiplier 3
use mtu expire
83923 0 229
sockaddrs: <DST,GATEWAY,NETMASK,IFP,IFA>
Index: sbin/route/Makefile
===================================================================
RCS file: /cvs/openbsd/src/sbin/route/Makefile,v
retrieving revision 1.13
diff -u -p -u -p -r1.13 Makefile
--- sbin/route/Makefile 19 Jul 2013 14:41:46 -0000 1.13
+++ sbin/route/Makefile 17 Dec 2016 12:47:35 -0000
@@ -4,7 +4,7 @@ PROG= route
MAN= route.8
SRCS= route.c show.c
-CFLAGS+= -Wall
+CFLAGS+= -Wall -DBFD
route.o .depend lint tags: keywords.h
Index: sbin/route/route.c
===================================================================
RCS file: /cvs/openbsd/src/sbin/route/route.c,v
retrieving revision 1.193
diff -u -p -u -p -r1.193 route.c
--- sbin/route/route.c 13 Dec 2016 08:40:54 -0000 1.193
+++ sbin/route/route.c 17 Dec 2016 12:47:35 -0000
@@ -100,6 +100,7 @@ const char *bfd_state(unsigned int);
const char *bfd_diag(unsigned int);
const char *bfd_calc_uptime(time_t);
void print_bfdmsg(struct rt_msghdr *);
+void print_sabfd(struct sockaddr_bfd *, int);
#endif
const char *get_linkstate(int, int);
void print_rtmsg(struct rt_msghdr *, int);
@@ -1443,6 +1444,9 @@ print_getmsg(struct rt_msghdr *rtm, int
struct sockaddr *dst = NULL, *gate = NULL, *mask = NULL, *ifa = NULL;
struct sockaddr_dl *ifp = NULL;
struct sockaddr_rtlabel *sa_rl = NULL;
+#ifdef BFD
+ struct sockaddr_bfd *sa_bfd = NULL;
+#endif
struct sockaddr *mpls = NULL;
struct sockaddr *sa;
char *cp;
@@ -1491,6 +1495,11 @@ print_getmsg(struct rt_msghdr *rtm, int
case RTA_LABEL:
sa_rl = (struct sockaddr_rtlabel *)sa;
break;
+#ifdef BFD
+ case RTA_BFD:
+ sa_bfd = (struct sockaddr_bfd *)sa;
+ break;
+#endif
}
ADVANCE(cp, sa);
}
@@ -1523,6 +1532,10 @@ print_getmsg(struct rt_msghdr *rtm, int
printf("\n");
if (sa_rl != NULL)
printf(" label: %s\n", sa_rl->sr_label);
+#ifdef BFD
+ if (sa_bfd)
+ print_sabfd(sa_bfd, rtm->rtm_fmask);
+#endif
#define lock(f) ((rtm->rtm_rmx.rmx_locks & __CONCAT(RTV_,f)) ? 'L' : '
')
relative_expire = rtm->rtm_rmx.rmx_expire ?
@@ -1625,12 +1638,21 @@ void
print_bfdmsg(struct rt_msghdr *rtm)
{
struct bfd_msghdr *bfdm = (struct bfd_msghdr *)rtm;
+
+ printf("\n");
+ print_sabfd(&bfdm->bm_sa, rtm->rtm_fmask);
+ pmsg_addrs(((char *)rtm + rtm->rtm_hdrlen), rtm->rtm_addrs);
+}
+
+void
+print_sabfd(struct sockaddr_bfd *sa_bfd, int fmask)
+{
struct timeval tv;
gettimeofday(&tv, NULL);
- printf(" mode ");
- switch (bfdm->bm_mode) {
+ printf(" BFD: ");
+ switch (sa_bfd->bs_mode) {
case BFD_MODE_ASYNC:
printf("async");
break;
@@ -1638,27 +1660,36 @@ print_bfdmsg(struct rt_msghdr *rtm)
printf("demand");
break;
default:
- printf("unknown %u", bfdm->bm_mode);
+ printf("unknown %u", sa_bfd->bs_mode);
break;
}
- printf(" state %s", bfd_state(bfdm->bm_state));
- printf(" remotestate %s", bfd_state(bfdm->bm_remotestate));
- printf(" laststate %s", bfd_state(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_diag(bfdm->bm_localdiag));
- printf(" remotediag %s", bfd_diag(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);
+ printf(" state %s", bfd_state(sa_bfd->bs_state));
+ printf(" remote %s", bfd_state(sa_bfd->bs_remotestate));
+ if ((fmask & RTF_BFD) != RTF_BFD) {
+ printf("\n");
+ return;
+ }
+ printf(" laststate %s", bfd_state(sa_bfd->bs_laststate));
+
+ printf(" error %d", sa_bfd->bs_error);
+ printf("\n ");
+ printf(" diag %s", bfd_diag(sa_bfd->bs_localdiag));
+ printf(" remote %s", bfd_diag(sa_bfd->bs_remotediag));
+ printf("\n ");
+ printf(" discr %u", sa_bfd->bs_localdiscr);
+ printf(" remote %u", sa_bfd->bs_remotediscr);
+ printf("\n ");
+ printf(" uptime %s", bfd_calc_uptime(tv.tv_sec - sa_bfd->bs_uptime));
+ if (sa_bfd->bs_lastuptime)
+ printf(" last state time %s",
+ bfd_calc_uptime(sa_bfd->bs_lastuptime));
+ printf("\n ");
+ printf(" mintx %u", sa_bfd->bs_mintx);
+ printf(" minrx %u", sa_bfd->bs_minrx);
+ printf(" minecho %u", sa_bfd->bs_minecho);
+ printf(" multiplier %u", sa_bfd->bs_multiplier);
+ printf("\n");
}
#endif /* BFD */
Index: sys/net/bfd.c
===================================================================
RCS file: /cvs/openbsd/src/sys/net/bfd.c,v
retrieving revision 1.41
diff -u -p -u -p -r1.41 bfd.c
--- sys/net/bfd.c 24 Sep 2016 19:29:55 -0000 1.41
+++ sys/net/bfd.c 17 Dec 2016 12:47:35 -0000
@@ -144,7 +144,6 @@ struct pool bfd_pool, bfd_pool_neigh, b
struct taskq *bfdtq;
-struct bfd_config *bfd_lookup(struct rtentry *);
void bfddestroy(void);
struct socket *bfd_listener(struct bfd_config *, unsigned int);
Index: sys/net/bfd.h
===================================================================
RCS file: /cvs/openbsd/src/sys/net/bfd.h,v
retrieving revision 1.9
diff -u -p -u -p -r1.9 bfd.h
--- sys/net/bfd.h 20 Sep 2016 10:41:43 -0000 1.9
+++ sys/net/bfd.h 17 Dec 2016 12:47:35 -0000
@@ -53,31 +53,44 @@
#define BFD_FLAG_D 0x02
#define BFD_FLAG_M 0x01
+struct sockaddr_bfd {
+ __uint8_t bs_len; /* total length */
+ sa_family_t bs_family; /* address family */
+ /* above matches sockaddr_storage */
+
+ uint16_t bs_mode;
+ uint32_t bs_mintx;
+ uint32_t bs_minrx;
+ uint32_t bs_minecho;
+ uint16_t bs_multiplier;
+
+ time_t bs_uptime;
+ time_t bs_lastuptime;
+ int bs_state;
+ int bs_remotestate;
+ int bs_laststate;
+ int bs_error;
+
+ uint32_t bs_localdiscr;
+ uint32_t bs_localdiag;
+ uint32_t bs_remotediscr;
+ uint32_t bs_remotediag;
+};
+
struct bfd_msghdr {
unsigned short bm_msglen;
unsigned char bm_version;
unsigned char bm_type;
unsigned short bm_hdrlen;
+ u_short bm_index;
+ u_short bm_tableid;
+ u_char bm_priority;
+ u_char bm_mpls;
int bm_addrs;
+ int bm_flags;
/* above matches rtm_msghdr */
- uint16_t bm_mode;
- uint32_t bm_mintx;
- uint32_t bm_minrx;
- uint32_t bm_minecho;
- uint16_t bm_multiplier;
-
- time_t bm_uptime;
- time_t bm_lastuptime;
- int bm_state;
- int bm_remotestate;
- int bm_laststate;
- int bm_error;
-
- uint32_t bm_localdiscr;
- uint32_t bm_localdiag;
- uint32_t bm_remotediscr;
- uint32_t bm_remotediag;
+ struct sockaddr_bfd bm_sa; /* bfd msg for userland */
};
#ifdef _KERNEL
@@ -124,6 +137,8 @@ struct bfd_config {
int bc_minecho;
int bc_multiplier;
};
+
+struct bfd_config *bfd_lookup(struct rtentry *);
int bfdset(struct rtentry *);
void bfdclear(struct rtentry *);
Index: sys/net/route.h
===================================================================
RCS file: /cvs/openbsd/src/sys/net/route.h,v
retrieving revision 1.149
diff -u -p -u -p -r1.149 route.h
--- sys/net/route.h 21 Nov 2016 10:30:42 -0000 1.149
+++ sys/net/route.h 17 Dec 2016 12:47:35 -0000
@@ -259,6 +259,7 @@ struct rt_msghdr {
#define RTA_SRC 0x100 /* source sockaddr present */
#define RTA_SRCMASK 0x200 /* source netmask present */
#define RTA_LABEL 0x400 /* route label present */
+#define RTA_BFD 0x800 /* bfd present */
/*
* Index offsets for sockaddr array for alternate internal encoding.
@@ -274,7 +275,8 @@ struct rt_msghdr {
#define RTAX_SRC 8 /* source sockaddr present */
#define RTAX_SRCMASK 9 /* source netmask present */
#define RTAX_LABEL 10 /* route label present */
-#define RTAX_MAX 11 /* size of array to allocate */
+#define RTAX_BFD 11 /* bfd present */
+#define RTAX_MAX 12 /* size of array to allocate */
/*
* setsockopt defines used for the filtering.
@@ -357,6 +359,7 @@ struct socket;
struct ifnet;
struct sockaddr_in6;
struct bfd_config;
+struct sockaddr_bfd;
void route_init(void);
int route_output(struct mbuf *, ...);
@@ -365,6 +368,7 @@ int route_usrreq(struct socket *, int,
void rt_ifmsg(struct ifnet *);
void rt_ifannouncemsg(struct ifnet *, int);
void rt_bfdmsg(struct bfd_config *);
+struct sockaddr *bfd2sa(struct bfd_config *, struct sockaddr_bfd *);
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.210
diff -u -p -u -p -r1.210 rtsock.c
--- sys/net/rtsock.c 29 Nov 2016 10:22:30 -0000 1.210
+++ sys/net/rtsock.c 17 Dec 2016 12:47:35 -0000
@@ -472,6 +472,9 @@ route_output(struct mbuf *m, ...)
struct rawcb *rp = NULL;
struct sockaddr_rtlabel sa_rl;
struct sockaddr_in6 sa_mask;
+#ifdef BFD
+ struct sockaddr_bfd sa_bfd;
+#endif
#ifdef MPLS
struct sockaddr_mpls sa_mpls, *psa_mpls;
#endif
@@ -705,6 +708,14 @@ report:
rt_plen2mask(rt, &sa_mask);
info.rti_info[RTAX_LABEL] =
rtlabel_id2sa(rt->rt_labelid, &sa_rl);
+#ifdef BFD
+ if (rt->rt_flags & RTF_BFD) {
+ struct bfd_config *bfd;
+ bfd = bfd_lookup(rt);
+ bfd2sa(bfd, &sa_bfd);
+ info.rti_info[RTAX_BFD] = (struct sockaddr *)&sa_bfd;
+ }
+#endif
#ifdef MPLS
if (rt->rt_flags & RTF_MPLS) {
bzero(&sa_mpls, sizeof(sa_mpls));
@@ -1355,6 +1366,7 @@ void
rt_bfdmsg(struct bfd_config *bfd)
{
struct bfd_msghdr *bfdm;
+ struct sockaddr_bfd sa_bfd;
struct mbuf *m;
struct rt_addrinfo info;
@@ -1368,28 +1380,45 @@ rt_bfdmsg(struct bfd_config *bfd)
if (m == NULL)
return;
bfdm = mtod(m, struct bfd_msghdr *);
+ bfdm->bm_addrs = info.rti_addrs;
- 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;
+ bfd2sa(bfd, &sa_bfd);
+ memcpy(&bfdm->bm_sa, &sa_bfd, sizeof(sa_bfd));
- route_proto.sp_protocol = 0;
+ route_proto.sp_protocol = info.rti_info[RTAX_DST]->sa_family;
route_input(m, &route_proto, &route_src, &route_dst);
}
+
+struct sockaddr *
+bfd2sa(struct bfd_config *bfd, struct sockaddr_bfd *sa_bfd)
+{
+ if (bfd == NULL)
+ return (NULL);
+
+ memset(sa_bfd, 0, sizeof(*sa_bfd));
+ sa_bfd->bs_len = sizeof(*sa_bfd);
+ sa_bfd->bs_family = bfd->bc_rt->rt_dest->sa_family;
+
+ sa_bfd->bs_mode = bfd->bc_mode;
+ sa_bfd->bs_mintx = bfd->bc_mintx;
+ sa_bfd->bs_minrx = bfd->bc_minrx;
+ sa_bfd->bs_minecho = bfd->bc_minecho;
+ sa_bfd->bs_multiplier = bfd->bc_multiplier;
+
+ sa_bfd->bs_uptime = bfd->bc_time->tv_sec;
+ sa_bfd->bs_lastuptime = bfd->bc_lastuptime;
+ sa_bfd->bs_state = bfd->bc_state;
+ sa_bfd->bs_remotestate = bfd->bc_neighbor->bn_rstate;
+ sa_bfd->bs_laststate = bfd->bc_laststate;
+ sa_bfd->bs_error = bfd->bc_error;
+
+ sa_bfd->bs_localdiscr = bfd->bc_neighbor->bn_ldiscr;
+ sa_bfd->bs_localdiag = bfd->bc_neighbor->bn_ldiag;
+ sa_bfd->bs_remotediscr = bfd->bc_neighbor->bn_rdiscr;
+ sa_bfd->bs_remotediag = bfd->bc_neighbor->bn_rdiag;
+
+ return ((struct sockaddr *)sa_bfd);
+}
#endif /* BFD */
/*
@@ -1402,6 +1431,10 @@ sysctl_dumpentry(struct rtentry *rt, voi
int error = 0, size;
struct rt_addrinfo info;
struct ifnet *ifp;
+#ifdef BFD
+ struct bfd_config *bfd;
+ struct sockaddr_bfd sa_bfd;
+#endif
#ifdef MPLS
struct sockaddr_mpls sa_mpls;
#endif
@@ -1436,6 +1469,12 @@ sysctl_dumpentry(struct rtentry *rt, voi
}
if_put(ifp);
info.rti_info[RTAX_LABEL] = rtlabel_id2sa(rt->rt_labelid, &sa_rl);
+#ifdef BFD
+ if (rt->rt_flags & RTF_BFD) {
+ bfd = bfd_lookup(rt);
+ info.rti_info[RTAX_BFD] = bfd2sa(bfd, &sa_bfd);
+ }
+#endif
#ifdef MPLS
if (rt->rt_flags & RTF_MPLS) {
bzero(&sa_mpls, sizeof(sa_mpls));
--
Everything should be built top-down, except the first time.