summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorgeorges <none@none>2007-12-14 09:14:59 -0800
committergeorges <none@none>2007-12-14 09:14:59 -0800
commitb043aa6f8fc8283fd7aceec67731256bf626a756 (patch)
treed07857b2a8b5d67c2b0a96a09953b687b31ff11e /usr/src
parent8c81938120fb4fc785845e4215fd40d7242c8077 (diff)
downloadillumos-joyent-b043aa6f8fc8283fd7aceec67731256bf626a756.tar.gz
6576930 Solaris 10 allows SCTP header only with CRC32 checksums and not ADLER32.
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/uts/common/inet/ip.h1
-rw-r--r--usr/src/uts/common/inet/ip/ip.c36
2 files changed, 33 insertions, 4 deletions
diff --git a/usr/src/uts/common/inet/ip.h b/usr/src/uts/common/inet/ip.h
index 7a42f21526..ff78525cca 100644
--- a/usr/src/uts/common/inet/ip.h
+++ b/usr/src/uts/common/inet/ip.h
@@ -322,6 +322,7 @@ typedef struct ipoptp_s
#define IP6_IN_LLMCAST 0x1000 /* Multicast */
#define IP_FF_LOOPBACK 0x2000 /* Loopback fanout */
+#define IP_FF_SCTP_CSUM_ERR 0x4000 /* sctp pkt has failed chksum */
#ifndef IRE_DB_TYPE
#define IRE_DB_TYPE M_SIG
diff --git a/usr/src/uts/common/inet/ip/ip.c b/usr/src/uts/common/inet/ip/ip.c
index 31e5085376..82458d2c46 100644
--- a/usr/src/uts/common/inet/ip/ip.c
+++ b/usr/src/uts/common/inet/ip/ip.c
@@ -13414,6 +13414,7 @@ ip_sctp_input(mblk_t *mp, ipha_t *ipha, ill_t *recv_ill, boolean_t mctl_present,
ill_t *ill = (ill_t *)q->q_ptr;
ip_stack_t *ipst;
sctp_stack_t *sctps;
+ boolean_t sctp_csum_err = B_FALSE;
ASSERT(recv_ill != NULL);
ipst = recv_ill->ill_ipst;
@@ -13495,11 +13496,9 @@ find_sctp_client:
pktsum = sctph->sh_chksum;
sctph->sh_chksum = 0;
calcsum = sctp_cksum(mp, u1);
- if (calcsum != pktsum) {
- BUMP_MIB(&sctps->sctps_mib, sctpChecksumError);
- goto error;
- }
sctph->sh_chksum = pktsum;
+ if (calcsum != pktsum)
+ sctp_csum_err = B_TRUE;
#ifdef DEBUG /* skip_sctp_cksum */
}
#endif
@@ -13509,6 +13508,19 @@ find_sctp_client:
IRE_REFRELE(ire);
IN6_IPADDR_TO_V4MAPPED(ipha->ipha_dst, &map_dst);
IN6_IPADDR_TO_V4MAPPED(ipha->ipha_src, &map_src);
+ if (sctp_csum_err) {
+ /*
+ * No potential sctp checksum errors go to the Sun
+ * sctp stack however they might be Adler-32 summed
+ * packets a userland stack bound to a raw IP socket
+ * could reasonably use. Note though that Adler-32 is
+ * a long deprecated algorithm and customer sctp
+ * networks should eventually migrate to CRC-32 at
+ * which time this facility should be removed.
+ */
+ flags |= IP_FF_SCTP_CSUM_ERR;
+ goto no_conn;
+ }
if ((connp = sctp_fanout(&map_src, &map_dst, ports, zoneid, mp,
sctps)) == NULL) {
/* Check for raw socket or OOTB handling */
@@ -29603,6 +29615,13 @@ ip_fanout_sctp_raw(mblk_t *mp, ill_t *recv_ill, ipha_t *ipha, boolean_t isv4,
ip6_t *ip6h;
ip_stack_t *ipst = recv_ill->ill_ipst;
ipsec_stack_t *ipss = ipst->ips_netstack->netstack_ipsec;
+ sctp_stack_t *sctps = ipst->ips_netstack->netstack_sctp;
+ boolean_t sctp_csum_err = B_FALSE;
+
+ if (flags & IP_FF_SCTP_CSUM_ERR) {
+ sctp_csum_err = B_TRUE;
+ flags &= ~IP_FF_SCTP_CSUM_ERR;
+ }
first_mp = mp;
if (mctl_present) {
@@ -29616,6 +29635,15 @@ ip_fanout_sctp_raw(mblk_t *mp, ill_t *recv_ill, ipha_t *ipha, boolean_t isv4,
connp = ipcl_classify_raw(mp, IPPROTO_SCTP, zoneid, ports, ipha, ipst);
if (connp == NULL) {
+ /*
+ * Although raw sctp is not summed, OOB chunks must be.
+ * Drop the packet here if the sctp checksum failed.
+ */
+ if (sctp_csum_err) {
+ BUMP_MIB(&sctps->sctps_mib, sctpChecksumError);
+ freemsg(first_mp);
+ return;
+ }
sctp_ootb_input(first_mp, recv_ill, zoneid, mctl_present);
return;
}