aboutsummaryrefslogtreecommitdiff
path: root/third_party/usrsctp/usrsctplib/usrsctplib/netinet6/sctp6_usrreq.c
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/usrsctp/usrsctplib/usrsctplib/netinet6/sctp6_usrreq.c')
-rw-r--r--third_party/usrsctp/usrsctplib/usrsctplib/netinet6/sctp6_usrreq.c62
1 files changed, 57 insertions, 5 deletions
diff --git a/third_party/usrsctp/usrsctplib/usrsctplib/netinet6/sctp6_usrreq.c b/third_party/usrsctp/usrsctplib/usrsctplib/netinet6/sctp6_usrreq.c
index 5a931dd5a2..aa0c0051a5 100644
--- a/third_party/usrsctp/usrsctplib/usrsctplib/netinet6/sctp6_usrreq.c
+++ b/third_party/usrsctp/usrsctplib/usrsctplib/netinet6/sctp6_usrreq.c
@@ -34,7 +34,7 @@
#if defined(__FreeBSD__) && !defined(__Userspace__)
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/netinet6/sctp6_usrreq.c 365071 2020-09-01 21:19:14Z mjg $");
+__FBSDID("$FreeBSD$");
#endif
#include <netinet/sctp_os.h>
@@ -259,13 +259,14 @@ sctp6_input(struct mbuf **i_pak, int *offp, int proto)
if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) {
goto out;
}
- ecn_bits = ((ntohl(ip6->ip6_flow) >> 20) & 0x000000ff);
#if defined(__FreeBSD__)
+ ecn_bits = IPV6_TRAFFIC_CLASS(ip6);
if (m->m_pkthdr.csum_flags & CSUM_SCTP_VALID) {
SCTP_STAT_INCR(sctps_recvhwcrc);
compute_crc = 0;
} else {
#else
+ ecn_bits = ((ntohl(ip6->ip6_flow) >> 20) & 0x000000ff);
if (SCTP_BASE_SYSCTL(sctp_no_csum_on_loopback) &&
(IN6_ARE_ADDR_EQUAL(&src.sin6_addr, &dst.sin6_addr))) {
SCTP_STAT_INCR(sctps_recvhwcrc);
@@ -654,9 +655,10 @@ out:
return (error);
}
-SYSCTL_PROC(_net_inet6_sctp6, OID_AUTO, getcred, CTLTYPE_OPAQUE | CTLFLAG_RW,
- 0, 0,
- sctp6_getcred, "S,ucred", "Get the ucred of a SCTP6 connection");
+SYSCTL_PROC(_net_inet6_sctp6, OID_AUTO, getcred,
+ CTLTYPE_OPAQUE | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
+ 0, 0, sctp6_getcred, "S,ucred",
+ "Get the ucred of a SCTP6 connection");
#endif
/* This is the same as the sctp_abort() could be made common */
@@ -1007,6 +1009,46 @@ sctp6_send(struct socket *so, int flags, struct mbuf *m, struct mbuf *nam,
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EDESTADDRREQ);
return (EDESTADDRREQ);
}
+ switch (addr->sa_family) {
+#ifdef INET
+ case AF_INET:
+#if defined(HAVE_SA_LEN)
+ if (addr->sa_len != sizeof(struct sockaddr_in)) {
+ if (control) {
+ SCTP_RELEASE_PKT(control);
+ control = NULL;
+ }
+ SCTP_RELEASE_PKT(m);
+ SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
+ return (EINVAL);
+ }
+#endif
+ break;
+#endif
+#ifdef INET6
+ case AF_INET6:
+#if defined(HAVE_SA_LEN)
+ if (addr->sa_len != sizeof(struct sockaddr_in6)) {
+ if (control) {
+ SCTP_RELEASE_PKT(control);
+ control = NULL;
+ }
+ SCTP_RELEASE_PKT(m);
+ SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
+ return (EINVAL);
+ }
+#endif
+ break;
+#endif
+ default:
+ if (control) {
+ SCTP_RELEASE_PKT(control);
+ control = NULL;
+ }
+ SCTP_RELEASE_PKT(m);
+ SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
+ return (EINVAL);
+ }
#ifdef INET
sin6 = (struct sockaddr_in6 *)addr;
if (SCTP_IPV6_V6ONLY(inp)) {
@@ -1015,10 +1057,20 @@ sctp6_send(struct socket *so, int flags, struct mbuf *m, struct mbuf *nam,
* v4 addr or v4-mapped addr
*/
if (addr->sa_family == AF_INET) {
+ if (control) {
+ SCTP_RELEASE_PKT(control);
+ control = NULL;
+ }
+ SCTP_RELEASE_PKT(m);
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
return (EINVAL);
}
if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
+ if (control) {
+ SCTP_RELEASE_PKT(control);
+ control = NULL;
+ }
+ SCTP_RELEASE_PKT(m);
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
return (EINVAL);
}