summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorkrw <krw@openbsd.org>2017-03-02 17:09:21 +0000
committerkrw <krw@openbsd.org>2017-03-02 17:09:21 +0000
commit46c62a11c36c34beb2d403777db75ed08acd9022 (patch)
tree6aa06affaea28162af8970ce25f884c2f1644156 /sys
parentDocument some installation quirks for the EdgeRouter Lite in INSTALL.octeon: (diff)
downloadwireguard-openbsd-46c62a11c36c34beb2d403777db75ed08acd9022.tar.xz
wireguard-openbsd-46c62a11c36c34beb2d403777db75ed08acd9022.zip
Implement a new routing message RTM_PROPOSAL that communicates
information that can be used to configure an interface and related network components. ok bluhm@, ok for various older versions mpi@ florian@ claudio@
Diffstat (limited to 'sys')
-rw-r--r--sys/net/route.h38
-rw-r--r--sys/net/rtsock.c107
2 files changed, 140 insertions, 5 deletions
diff --git a/sys/net/route.h b/sys/net/route.h
index 8e5ee2d7ba2..a67f3af27a5 100644
--- a/sys/net/route.h
+++ b/sys/net/route.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: route.h,v 1.156 2017/01/23 00:59:22 krw Exp $ */
+/* $OpenBSD: route.h,v 1.157 2017/03/02 17:09:21 krw Exp $ */
/* $NetBSD: route.h,v 1.9 1996/02/13 22:00:49 christos Exp $ */
/*
@@ -168,6 +168,9 @@ struct rtentry {
#define RTP_RIP 40 /* RIP routes */
#define RTP_BGP 48 /* BGP routes */
#define RTP_DEFAULT 56 /* routes that have nothing set */
+#define RTP_PROPOSAL_STATIC 57
+#define RTP_PROPOSAL_DHCLIENT 58
+#define RTP_PROPOSAL_SLAAC 59
#define RTP_MAX 63 /* maximum priority */
#define RTP_ANY 64 /* any of the above */
#define RTP_MASK 0x7f
@@ -237,6 +240,7 @@ struct rt_msghdr {
#define RTM_DESYNC 0x10 /* route socket buffer overflow */
#define RTM_INVALIDATE 0x11 /* Invalidate cache of L2 route */
#define RTM_BFD 0x12 /* bidirectional forwarding detection */
+#define RTM_PROPOSAL 0x13 /* proposal for netconfigd */
#define RTV_MTU 0x1 /* init or lock _mtu */
#define RTV_HOPCOUNT 0x2 /* init or lock _hopcount */
@@ -262,6 +266,9 @@ struct rt_msghdr {
#define RTA_SRCMASK 0x200 /* source netmask present */
#define RTA_LABEL 0x400 /* route label present */
#define RTA_BFD 0x800 /* bfd present */
+#define RTA_DNS 0x1000 /* DNS Servers sockaddr present */
+#define RTA_STATIC 0x2000 /* RFC 3442 encoded static routes present */
+#define RTA_SEARCH 0x4000 /* RFC 3397 encoded search path present */
/*
* Index offsets for sockaddr array for alternate internal encoding.
@@ -278,7 +285,10 @@ struct rt_msghdr {
#define RTAX_SRCMASK 9 /* source netmask present */
#define RTAX_LABEL 10 /* route label present */
#define RTAX_BFD 11 /* bfd present */
-#define RTAX_MAX 12 /* size of array to allocate */
+#define RTAX_DNS 12 /* DNS Server(s) sockaddr present */
+#define RTAX_STATIC 13 /* RFC 3442 encoded static routes present */
+#define RTAX_SEARCH 14 /* RFC 3397 encoded search path present */
+#define RTAX_MAX 15 /* size of array to allocate */
/*
* setsockopt defines used for the filtering.
@@ -299,6 +309,30 @@ struct sockaddr_rtlabel {
char sr_label[RTLABEL_LEN];
};
+#define RTDNS_LEN 128
+
+struct sockaddr_rtdns {
+ u_int8_t sr_len; /* total length */
+ sa_family_t sr_family; /* address family */
+ char sr_dns[RTDNS_LEN];
+};
+
+#define RTSTATIC_LEN 128
+
+struct sockaddr_rtstatic {
+ u_int8_t sr_len; /* total length */
+ sa_family_t sr_family; /* address family */
+ char sr_static[RTSTATIC_LEN];
+};
+
+#define RTSEARCH_LEN 128
+
+struct sockaddr_rtsearch {
+ u_int8_t sr_len; /* total length */
+ sa_family_t sr_family; /* address family */
+ char sr_search[RTSEARCH_LEN];
+};
+
/*
* A route consists of a destination address and a reference
* to a routing entry. These are often held by protocols
diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c
index 89c6a0bef0d..27338b49e35 100644
--- a/sys/net/rtsock.c
+++ b/sys/net/rtsock.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rtsock.c,v 1.225 2017/03/02 09:37:04 mpi Exp $ */
+/* $OpenBSD: rtsock.c,v 1.226 2017/03/02 17:09:21 krw Exp $ */
/* $NetBSD: rtsock.c,v 1.18 1996/03/29 00:32:10 cgd Exp $ */
/*
@@ -108,10 +108,14 @@ int rt_msg2(int, int, struct rt_addrinfo *, caddr_t,
struct walkarg *);
void rt_xaddrs(caddr_t, caddr_t, struct rt_addrinfo *);
+void rt_proposalmsg(struct rt_msghdr *, struct rt_addrinfo *);
+
int sysctl_iflist(int, struct walkarg *);
int sysctl_ifnames(struct walkarg *);
int sysctl_rtable_rtstat(void *, size_t *, void *);
+int validate_proposal(struct rt_addrinfo *);
+
struct routecb {
struct rawcb rcb;
struct timeout timeout;
@@ -597,6 +601,7 @@ route_output(struct mbuf *m, ...)
case RTM_GET:
case RTM_CHANGE:
case RTM_LOCK:
+ case RTM_PROPOSAL:
break;
default:
error = EOPNOTSUPP;
@@ -652,11 +657,12 @@ route_output(struct mbuf *m, ...)
info.rti_addrs = rtm->rtm_addrs;
rt_xaddrs(rtm->rtm_hdrlen + (caddr_t)rtm, len + (caddr_t)rtm, &info);
info.rti_flags = rtm->rtm_flags;
- if (info.rti_info[RTAX_DST] == NULL ||
+ if (rtm->rtm_type != RTM_PROPOSAL &&
+ (info.rti_info[RTAX_DST] == NULL ||
info.rti_info[RTAX_DST]->sa_family >= AF_MAX ||
(info.rti_info[RTAX_GATEWAY] != NULL &&
info.rti_info[RTAX_GATEWAY]->sa_family >= AF_MAX) ||
- info.rti_info[RTAX_GENMASK] != NULL) {
+ info.rti_info[RTAX_GENMASK] != NULL)) {
error = EINVAL;
goto fail;
}
@@ -675,6 +681,18 @@ route_output(struct mbuf *m, ...)
* may be not consistent and could cause unexpected behaviour in other
* userland clients. Use goto fail instead.
*/
+
+ /*
+ * Validate RTM_PROPOSAL and pass it along or error out.
+ */
+ if (rtm->rtm_type == RTM_PROPOSAL) {
+ if (validate_proposal(&info) == -1) {
+ error = EINVAL;
+ goto fail;
+ }
+ goto flush;
+ }
+
switch (rtm->rtm_type) {
case RTM_ADD:
if (info.rti_info[RTAX_GATEWAY] == NULL) {
@@ -1642,6 +1660,89 @@ sysctl_rtable_rtstat(void *oldp, size_t *oldlenp, void *newp)
return (sysctl_rdstruct(oldp, oldlenp, newp, &rtstat, sizeof(rtstat)));
}
+int
+validate_proposal(struct rt_addrinfo *info)
+{
+ if (info->rti_addrs & ~(RTA_NETMASK | RTA_IFA | RTA_DNS | RTA_STATIC |
+ RTA_SEARCH)) {
+ return -1;
+ }
+
+ if (ISSET(info->rti_addrs, RTA_NETMASK)) {
+ struct sockaddr *sa = info->rti_info[RTAX_NETMASK];
+ if (sa == NULL)
+ return -1;
+ switch (sa->sa_family) {
+ case AF_INET:
+ if (sa->sa_len != sizeof(struct sockaddr_in))
+ return -1;
+ break;
+ case AF_INET6:
+ if (sa->sa_len != sizeof(struct sockaddr_in6))
+ return -1;
+ break;
+ default:
+ return -1;
+ }
+ }
+
+ if (ISSET(info->rti_addrs, RTA_IFA)) {
+ struct sockaddr *sa = info->rti_info[RTAX_IFA];
+ if (sa == NULL)
+ return -1;
+ switch (sa->sa_family) {
+ case AF_INET:
+ if (sa->sa_len != sizeof(struct sockaddr_in))
+ return -1;
+ break;
+ case AF_INET6:
+ if (sa->sa_len != sizeof(struct sockaddr_in6))
+ return -1;
+ break;
+ default:
+ return -1;
+ }
+ }
+
+ if (ISSET(info->rti_addrs, RTA_DNS)) {
+ struct sockaddr_rtdns *rtdns =
+ (struct sockaddr_rtdns *)info->rti_info[RTAX_DNS];
+ if (rtdns == NULL)
+ return -1;
+ if (rtdns->sr_len > sizeof(*rtdns))
+ return -1;
+ if (rtdns->sr_len <=
+ offsetof(struct sockaddr_rtdns, sr_dns))
+ return -1;
+ }
+
+ if (ISSET(info->rti_addrs, RTA_STATIC)) {
+ struct sockaddr_rtstatic *rtstatic =
+ (struct sockaddr_rtstatic *)info->rti_info[RTAX_STATIC];
+ if (rtstatic == NULL)
+ return -1;
+ if (rtstatic->sr_len > sizeof(*rtstatic))
+ return -1;
+ if (rtstatic->sr_len <=
+ offsetof(struct sockaddr_rtstatic, sr_static))
+ return -1;
+ }
+
+ if (ISSET(info->rti_addrs, RTA_SEARCH)) {
+ struct sockaddr_rtsearch *rtsearch =
+ (struct sockaddr_rtsearch *)info->rti_info[RTAX_SEARCH];
+ if (rtsearch == NULL)
+ return -1;
+ if (rtsearch->sr_len > sizeof(*rtsearch))
+ return -1;
+ if (rtsearch->sr_len <=
+ offsetof(struct sockaddr_rtsearch, sr_search))
+ return -1;
+ }
+
+ return 0;
+}
+
/*
* Definitions of protocols supported in the ROUTE domain.
*/