diff options
author | 2017-03-02 17:09:21 +0000 | |
---|---|---|
committer | 2017-03-02 17:09:21 +0000 | |
commit | 46c62a11c36c34beb2d403777db75ed08acd9022 (patch) | |
tree | 6aa06affaea28162af8970ce25f884c2f1644156 /sys | |
parent | Document some installation quirks for the EdgeRouter Lite in INSTALL.octeon: (diff) | |
download | wireguard-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.h | 38 | ||||
-rw-r--r-- | sys/net/rtsock.c | 107 |
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. */ |