summaryrefslogtreecommitdiff
path: root/sys/net/rtsock.c
diff options
context:
space:
mode:
authorClaudio Jeker <claudio@cvs.openbsd.org>2021-05-17 17:06:52 +0000
committerClaudio Jeker <claudio@cvs.openbsd.org>2021-05-17 17:06:52 +0000
commit8e05bf5bedc3674ddc56add11d6bcfd297cb9a47 (patch)
tree3c0899c13866135266e44747351d6a3843c78eca /sys/net/rtsock.c
parent0fd268b1763a02bf853751493d9dce8c253881dd (diff)
Increase the default buffer space using on PF_UNIX sockets to 8k.
Additionally make the values tuneable via sysctl. OK deraadt@ mvs@
Diffstat (limited to 'sys/net/rtsock.c')
-rw-r--r--sys/net/rtsock.c82
1 files changed, 69 insertions, 13 deletions
diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c
index 3a1cf04f8ac..c514629a407 100644
--- a/sys/net/rtsock.c
+++ b/sys/net/rtsock.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rtsock.c,v 1.313 2021/05/16 13:09:39 mvs Exp $ */
+/* $OpenBSD: rtsock.c,v 1.314 2021/05/17 17:06:51 claudio Exp $ */
/* $NetBSD: rtsock.c,v 1.18 1996/03/29 00:32:10 cgd Exp $ */
/*
@@ -124,10 +124,12 @@ int rtm_getifa(struct rt_addrinfo *, unsigned int);
int rtm_output(struct rt_msghdr *, struct rtentry **, struct rt_addrinfo *,
uint8_t, unsigned int);
struct rt_msghdr *rtm_report(struct rtentry *, u_char, int, int);
+int rtm_embedscope(struct sockaddr *);
+void rtm_recoverscope(struct sockaddr *);
+int rtm_xaddrs(caddr_t, caddr_t, struct rt_addrinfo *);
struct mbuf *rtm_msg1(int, struct rt_addrinfo *);
int rtm_msg2(int, int, struct rt_addrinfo *, caddr_t,
struct walkarg *);
-int rtm_xaddrs(caddr_t, caddr_t, struct rt_addrinfo *);
int rtm_validate_proposal(struct rt_addrinfo *);
void rtm_setmetrics(u_long, const struct rt_metrics *,
struct rt_kmetrics *);
@@ -1379,6 +1381,47 @@ rtm_getmetrics(const struct rt_kmetrics *in, struct rt_metrics *out)
out->rmx_pksent = in->rmx_pksent;
}
+int
+rtm_embedscope(struct sockaddr *sa)
+{
+#ifdef INET6
+ struct sockaddr_in6 *sin6;
+ struct in6_addr in6;
+ int error;
+
+ if (sa->sa_family == AF_INET6) {
+ sin6 = satosin6(sa);
+ if (IN6_IS_SCOPE_EMBED(&sin6->sin6_addr)) {
+ error = in6_embedscope(&in6, sin6, NULL);
+ if (error)
+ return error;
+ sin6->sin6_addr = in6;
+ sin6->sin6_scope_id = 0;
+ }
+ }
+#endif
+ return 0;
+}
+void
+rtm_recoverscope(struct sockaddr *sa)
+{
+#ifdef INET6
+ struct sockaddr_in6 *sin6;
+
+ if (sa->sa_family == AF_INET6) {
+ sin6 = satosin6(sa);
+ if (IN6_IS_SCOPE_EMBED(&sin6->sin6_addr) &&
+ sin6->sin6_scope_id == 0) {
+ u_int32_t scopeid = ntohs(sin6->sin6_addr.s6_addr16[1]);
+ if (scopeid) {
+ sin6->sin6_addr.s6_addr16[1] = 0;
+ sin6->sin6_scope_id = scopeid;
+ }
+ }
+ }
+#endif
+}
+
#define ROUNDUP(a) \
((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
#define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))
@@ -1387,7 +1430,7 @@ int
rtm_xaddrs(caddr_t cp, caddr_t cplim, struct rt_addrinfo *rtinfo)
{
struct sockaddr *sa;
- int i;
+ int i, error;
/*
* Parse address bits, split address storage in chunks, and
@@ -1518,8 +1561,9 @@ rtm_xaddrs(caddr_t cp, caddr_t cplim, struct rt_addrinfo *rtinfo)
len = strnlen(sa->sa_data, maxlen);
if (len >= maxlen || 2 + len >= sa->sa_len)
return (EINVAL);
- break;
}
+ if ((error = rtm_embedscope(sa)) != 0)
+ return (error);
}
return (0);
}
@@ -1536,26 +1580,32 @@ rtm_msg1(int type, struct rt_addrinfo *rtinfo)
switch (type) {
case RTM_DELADDR:
case RTM_NEWADDR:
- len = sizeof(struct ifa_msghdr);
+ hlen = sizeof(struct ifa_msghdr);
break;
case RTM_IFINFO:
- len = sizeof(struct if_msghdr);
+ hlen = sizeof(struct if_msghdr);
break;
case RTM_IFANNOUNCE:
- len = sizeof(struct if_announcemsghdr);
+ hlen = sizeof(struct if_announcemsghdr);
break;
#ifdef BFD
case RTM_BFD:
- len = sizeof(struct bfd_msghdr);
+ hlen = sizeof(struct bfd_msghdr);
break;
#endif
case RTM_80211INFO:
- len = sizeof(struct if_ieee80211_msghdr);
+ hlen = sizeof(struct if_ieee80211_msghdr);
break;
default:
- len = sizeof(struct rt_msghdr);
+ hlen = sizeof(struct rt_msghdr);
break;
}
+ len = hlen;
+ for (i = 0; i < RTAX_MAX; i++) {
+ if (rtinfo == NULL || (sa = rtinfo->rti_info[i]) == NULL)
+ continue;
+ len += ROUNDUP(sa->sa_len);
+ }
if (len > MCLBYTES)
panic("rtm_msg1");
m = m_gethdr(M_DONTWAIT, MT_DATA);
@@ -1568,19 +1618,23 @@ rtm_msg1(int type, struct rt_addrinfo *rtinfo)
}
if (m == NULL)
return (m);
- m->m_pkthdr.len = m->m_len = hlen = len;
+ m->m_pkthdr.len = m->m_len = len;
m->m_pkthdr.ph_ifidx = 0;
rtm = mtod(m, struct rt_msghdr *);
bzero(rtm, len);
+ len = hlen;
for (i = 0; i < RTAX_MAX; i++) {
+ caddr_t cp;
if (rtinfo == NULL || (sa = rtinfo->rti_info[i]) == NULL)
continue;
rtinfo->rti_addrs |= (1 << i);
dlen = ROUNDUP(sa->sa_len);
- if (m_copyback(m, len, dlen, sa, M_NOWAIT)) {
+ if (m_copyback(m, len, sa->sa_len, sa, M_NOWAIT)) {
m_freem(m);
return (NULL);
}
+ cp = mtod(m, caddr_t) + len;
+ rtm_recoverscope((struct sockaddr *)cp);
len += dlen;
}
rtm->rtm_msglen = len;
@@ -1623,7 +1677,9 @@ again:
rtinfo->rti_addrs |= (1 << i);
dlen = ROUNDUP(sa->sa_len);
if (cp) {
- bcopy(sa, cp, (size_t)dlen);
+ bcopy(sa, cp, sa->sa_len);
+ bzero(cp + sa->sa_len, dlen - sa->sa_len);
+ rtm_recoverscope((struct sockaddr *)cp);
cp += dlen;
}
len += dlen;