-/* $OpenBSD: uipc_usrreq.c,v 1.145 2021/04/29 20:13:25 mvs Exp $ */
+/* $OpenBSD: uipc_usrreq.c,v 1.146 2021/05/17 17:06:51 claudio Exp $ */
/* $NetBSD: uipc_usrreq.c,v 1.18 1996/02/09 19:00:50 christos Exp $ */
/*
#include <sys/pledge.h>
#include <sys/pool.h>
#include <sys/rwlock.h>
+#include <sys/sysctl.h>
/*
* Locks used to protect global data and struct members:
* and don't really want to reserve the sendspace. Their recvspace should
* be large enough for at least one max-size datagram plus address.
*/
-#define PIPSIZ 4096
-u_long unpst_sendspace = PIPSIZ;
-u_long unpst_recvspace = PIPSIZ;
-u_long unpdg_sendspace = 2*1024; /* really max datagram size */
-u_long unpdg_recvspace = 4*1024;
+#define PIPSIZ 8192
+u_int unpst_sendspace = PIPSIZ;
+u_int unpst_recvspace = PIPSIZ;
+u_int unpsq_sendspace = PIPSIZ;
+u_int unpsq_recvspace = PIPSIZ;
+u_int unpdg_sendspace = 2*1024; /* really max datagram size */
+u_int unpdg_recvspace = 16*1024;
+
+const struct sysctl_bounded_args unpstctl_vars[] = {
+ { UNPCTL_RECVSPACE, &unpst_recvspace, 0, SB_MAX },
+ { UNPCTL_SENDSPACE, &unpst_sendspace, 0, SB_MAX },
+};
+const struct sysctl_bounded_args unpsqctl_vars[] = {
+ { UNPCTL_RECVSPACE, &unpsq_recvspace, 0, SB_MAX },
+ { UNPCTL_SENDSPACE, &unpsq_sendspace, 0, SB_MAX },
+};
+const struct sysctl_bounded_args unpdgctl_vars[] = {
+ { UNPCTL_RECVSPACE, &unpdg_recvspace, 0, SB_MAX },
+ { UNPCTL_SENDSPACE, &unpdg_sendspace, 0, SB_MAX },
+};
int
uipc_attach(struct socket *so, int proto)
switch (so->so_type) {
case SOCK_STREAM:
- case SOCK_SEQPACKET:
error = soreserve(so, unpst_sendspace, unpst_recvspace);
break;
+ case SOCK_SEQPACKET:
+ error = soreserve(so, unpsq_sendspace, unpsq_recvspace);
+ break;
+
case SOCK_DGRAM:
error = soreserve(so, unpdg_sendspace, unpdg_recvspace);
break;
return (0);
}
+int
+uipc_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
+ size_t newlen)
+{
+ int *valp = &unp_defer;
+
+ /* All sysctl names at this level are terminal. */
+ switch (name[0]) {
+ case SOCK_STREAM:
+ if (namelen != 2)
+ return (ENOTDIR);
+ return sysctl_bounded_arr(unpstctl_vars, nitems(unpstctl_vars),
+ name + 1, namelen - 1, oldp, oldlenp, newp, newlen);
+ case SOCK_SEQPACKET:
+ if (namelen != 2)
+ return (ENOTDIR);
+ return sysctl_bounded_arr(unpsqctl_vars, nitems(unpsqctl_vars),
+ name + 1, namelen - 1, oldp, oldlenp, newp, newlen);
+ case SOCK_DGRAM:
+ if (namelen != 2)
+ return (ENOTDIR);
+ return sysctl_bounded_arr(unpdgctl_vars, nitems(unpdgctl_vars),
+ name + 1, namelen - 1, oldp, oldlenp, newp, newlen);
+ case NET_UNIX_INFLIGHT:
+ valp = &unp_rights;
+ /* FALLTHOUGH */
+ case NET_UNIX_DEFERRED:
+ if (namelen != 1)
+ return (ENOTDIR);
+ return sysctl_rdint(oldp, oldlenp, newp, *valp);
+ default:
+ return (ENOPROTOOPT);
+ }
+}
+
void
unp_detach(struct unpcb *unp)
{
-/* $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 $ */
/*
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 *);
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))
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
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);
}
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);
}
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;
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;