Author: tuexen
Date: Mon Jul  2 16:44:09 2012
New Revision: 238003
URL: http://svn.freebsd.org/changeset/base/238003

Log:
  Move common code parts to sctp_common_input_processing().
  
  MFC after: 3 days

Modified:
  head/sys/netinet/sctp_input.c
  head/sys/netinet/sctp_input.h
  head/sys/netinet6/sctp6_usrreq.c

Modified: head/sys/netinet/sctp_input.c
==============================================================================
--- head/sys/netinet/sctp_input.c       Mon Jul  2 16:40:11 2012        
(r238002)
+++ head/sys/netinet/sctp_input.c       Mon Jul  2 16:44:09 2012        
(r238003)
@@ -5590,26 +5590,141 @@ void
 sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int 
length,
     struct sockaddr *src, struct sockaddr *dst,
     struct sctphdr *sh, struct sctp_chunkhdr *ch,
-    struct sctp_inpcb *inp, struct sctp_tcb *stcb,
-    struct sctp_nets *net, uint8_t ecn_bits,
+#if !defined(SCTP_WITH_NO_CSUM)
+    uint8_t compute_crc,
+#endif
+    uint8_t ecn_bits,
     uint8_t use_mflowid, uint32_t mflowid,
     uint32_t vrf_id, uint16_t port)
 {
-       /*
-        * Control chunk processing
-        */
        uint32_t high_tsn;
        int fwd_tsn_seen = 0, data_processed = 0;
        struct mbuf *m = *mm;
        int un_sent;
        int cnt_ctrl_ready = 0;
+       struct sctp_inpcb *inp, *inp_decr = NULL;
+       struct sctp_tcb *stcb = NULL;
+       struct sctp_nets *net;
 
        SCTP_STAT_INCR(sctps_recvdatagrams);
 #ifdef SCTP_AUDITING_ENABLED
        sctp_audit_log(0xE0, 1);
        sctp_auditing(0, inp, stcb, net);
 #endif
+#if !defined(SCTP_WITH_NO_CSUM)
+       if (compute_crc != 0) {
+               uint32_t check, calc_check;
 
+               check = sh->checksum;
+               sh->checksum = 0;
+               calc_check = sctp_calculate_cksum(m, iphlen);
+               sh->checksum = check;
+               if (calc_check != check) {
+                       SCTPDBG(SCTP_DEBUG_INPUT1, "Bad CSUM on SCTP packet 
calc_check:%x check:%x  m:%p mlen:%d iphlen:%d\n",
+                           calc_check, check, m, length, iphlen);
+                       stcb = sctp_findassociation_addr(m, offset, src, dst,
+                           sh, ch, &inp, &net, vrf_id);
+                       if ((net != NULL) && (port != 0)) {
+                               if (net->port == 0) {
+                                       sctp_pathmtu_adjustment(stcb, net->mtu 
- sizeof(struct udphdr));
+                               }
+                               net->port = port;
+                       }
+                       if ((net != NULL) && (use_mflowid != 0)) {
+                               net->flowid = mflowid;
+#ifdef INVARIANTS
+                               net->flowidset = 1;
+#endif
+                       }
+                       if ((inp != NULL) && (stcb != NULL)) {
+                               sctp_send_packet_dropped(stcb, net, m, length, 
iphlen, 1);
+                               sctp_chunk_output(inp, stcb, 
SCTP_OUTPUT_FROM_INPUT_ERROR, SCTP_SO_NOT_LOCKED);
+                       } else if ((inp != NULL) && (stcb == NULL)) {
+                               inp_decr = inp;
+                       }
+                       SCTP_STAT_INCR(sctps_badsum);
+                       SCTP_STAT_INCR_COUNTER32(sctps_checksumerrors);
+                       goto out;
+               }
+       }
+#endif
+       /* Destination port of 0 is illegal, based on RFC4960. */
+       if (sh->dest_port == 0) {
+               SCTP_STAT_INCR(sctps_hdrops);
+               goto out;
+       }
+       stcb = sctp_findassociation_addr(m, offset, src, dst,
+           sh, ch, &inp, &net, vrf_id);
+       if ((net != NULL) && (port != 0)) {
+               if (net->port == 0) {
+                       sctp_pathmtu_adjustment(stcb, net->mtu - sizeof(struct 
udphdr));
+               }
+               net->port = port;
+       }
+       if ((net != NULL) && (use_mflowid != 0)) {
+               net->flowid = mflowid;
+#ifdef INVARIANTS
+               net->flowidset = 1;
+#endif
+       }
+       if (inp == NULL) {
+               SCTP_STAT_INCR(sctps_noport);
+               if (badport_bandlim(BANDLIM_SCTP_OOTB) < 0) {
+                       goto out;
+               }
+               if (ch->chunk_type == SCTP_SHUTDOWN_ACK) {
+                       sctp_send_shutdown_complete2(src, dst, sh,
+                           use_mflowid, mflowid,
+                           vrf_id, port);
+                       goto out;
+               }
+               if (ch->chunk_type == SCTP_SHUTDOWN_COMPLETE) {
+                       goto out;
+               }
+               if (ch->chunk_type != SCTP_ABORT_ASSOCIATION) {
+                       if ((SCTP_BASE_SYSCTL(sctp_blackhole) == 0) ||
+                           ((SCTP_BASE_SYSCTL(sctp_blackhole) == 1) &&
+                           (ch->chunk_type != SCTP_INIT))) {
+                               sctp_send_abort(m, iphlen, src, dst,
+                                   sh, 0, NULL,
+                                   use_mflowid, mflowid,
+                                   vrf_id, port);
+                       }
+               }
+               goto out;
+       } else if (stcb == NULL) {
+               inp_decr = inp;
+       }
+#ifdef IPSEC
+       /*-
+        * I very much doubt any of the IPSEC stuff will work but I have no
+        * idea, so I will leave it in place.
+        */
+       if (inp != NULL) {
+               switch (dst->sa_family) {
+#ifdef INET
+               case AF_INET:
+                       if (ipsec4_in_reject(m, &inp->ip_inp.inp)) {
+                               MODULE_GLOBAL(ipsec4stat).in_polvio++;
+                               SCTP_STAT_INCR(sctps_hdrops);
+                               goto out;
+                       }
+                       break;
+#endif
+#ifdef INET6
+               case AF_INET6:
+                       if (ipsec6_in_reject(m, &inp->ip_inp.inp)) {
+                               MODULE_GLOBAL(ipsec6stat).in_polvio++;
+                               SCTP_STAT_INCR(sctps_hdrops);
+                               goto out;
+                       }
+                       break;
+#endif
+               default:
+                       break;
+               }
+       }
+#endif
        SCTPDBG(SCTP_DEBUG_INPUT1, "Ok, Common input processing called, m:%p 
iphlen:%d offset:%d length:%d stcb:%p\n",
            m, iphlen, offset, length, stcb);
        if (stcb) {
@@ -5628,10 +5743,11 @@ sctp_common_input_processing(struct mbuf
                         * NOT respond to any packet.. its OOTB.
                         */
                        SCTP_TCB_UNLOCK(stcb);
+                       stcb = NULL;
                        sctp_handle_ootb(m, iphlen, offset, src, dst, sh, inp,
                            use_mflowid, mflowid,
                            vrf_id, port);
-                       goto out_now;
+                       goto out;
                }
        }
        if (IS_SCTP_CONTROL(ch)) {
@@ -5671,21 +5787,19 @@ sctp_common_input_processing(struct mbuf
                    sctp_auth_is_required_chunk(SCTP_DATA, 
stcb->asoc.local_auth_chunks)) {
                        /* "silently" ignore */
                        SCTP_STAT_INCR(sctps_recvauthmissing);
-                       SCTP_TCB_UNLOCK(stcb);
-                       goto out_now;
+                       goto out;
                }
                if (stcb == NULL) {
                        /* out of the blue DATA chunk */
                        sctp_handle_ootb(m, iphlen, offset, src, dst, sh, inp,
                            use_mflowid, mflowid,
                            vrf_id, port);
-                       goto out_now;
+                       goto out;
                }
                if (stcb->asoc.my_vtag != ntohl(sh->v_tag)) {
                        /* v_tag mismatch! */
                        SCTP_STAT_INCR(sctps_badvtag);
-                       SCTP_TCB_UNLOCK(stcb);
-                       goto out_now;
+                       goto out;
                }
        }
 
@@ -5695,7 +5809,7 @@ sctp_common_input_processing(struct mbuf
                 * packet while processing control, or we're done with this
                 * packet (done or skip rest of data), so we drop it...
                 */
-               goto out_now;
+               goto out;
        }
        /*
         * DATA chunk processing
@@ -5749,8 +5863,7 @@ sctp_common_input_processing(struct mbuf
                        sctp_handle_ootb(m, iphlen, offset, src, dst, sh, inp,
                            use_mflowid, mflowid,
                            vrf_id, port);
-                       SCTP_TCB_UNLOCK(stcb);
-                       goto out_now;
+                       goto out;
                        /* sa_ignore NOTREACHED */
                        break;
                case SCTP_STATE_EMPTY:  /* should not happen */
@@ -5758,8 +5871,7 @@ sctp_common_input_processing(struct mbuf
                case SCTP_STATE_SHUTDOWN_RECEIVED:      /* This is a peer error 
*/
                case SCTP_STATE_SHUTDOWN_ACK_SENT:
                default:
-                       SCTP_TCB_UNLOCK(stcb);
-                       goto out_now;
+                       goto out;
                        /* sa_ignore NOTREACHED */
                        break;
                case SCTP_STATE_OPEN:
@@ -5777,7 +5889,8 @@ sctp_common_input_processing(struct mbuf
                         * The association aborted, NO UNLOCK needed since
                         * the association is destroyed.
                         */
-                       goto out_now;
+                       stcb = NULL;
+                       goto out;
                }
                data_processed = 1;
                /*
@@ -5834,10 +5947,20 @@ trigger_send:
        sctp_audit_log(0xE0, 3);
        sctp_auditing(2, inp, stcb, net);
 #endif
-       SCTP_TCB_UNLOCK(stcb);
-out_now:
+out:
+       if (stcb != NULL) {
+               SCTP_TCB_UNLOCK(stcb);
+       }
+       if (inp_decr != NULL) {
+               /* reduce ref-count */
+               SCTP_INP_WLOCK(inp_decr);
+               SCTP_INP_DECR_REF(inp_decr);
+               SCTP_INP_WUNLOCK(inp_decr);
+       }
 #ifdef INVARIANTS
-       sctp_validate_no_locks(inp);
+       if (inp != NULL) {
+               sctp_validate_no_locks(inp);
+       }
 #endif
        return;
 }
@@ -5867,18 +5990,14 @@ sctp_input_with_port(struct mbuf *i_pak,
        struct ip *ip;
        struct sctphdr *sh;
        struct sctp_chunkhdr *ch;
-       struct sctp_inpcb *inp = NULL;
-       struct sctp_tcb *stcb = NULL;
-       struct sctp_nets *net = NULL;
-       int refcount_up = 0;
        int length, offset;
-       uint32_t mflowid;
-       uint8_t use_mflowid;
 
 #if !defined(SCTP_WITH_NO_CSUM)
-       uint32_t check, calc_check;
+       uint8_t compute_crc;
 
 #endif
+       uint32_t mflowid;
+       uint8_t use_mflowid;
 
        iphlen = off;
        if (SCTP_GET_PKT_VRFID(i_pak, vrf_id)) {
@@ -5903,6 +6022,11 @@ sctp_input_with_port(struct mbuf *i_pak,
                sctp_packet_log(m);
        }
 #endif
+       SCTPDBG(SCTP_DEBUG_CRCOFFLOAD,
+           "sctp_input(): Packet of length %d received on %s with csum_flags 
0x%x.\n",
+           m->m_pkthdr.len,
+           if_name(m->m_pkthdr.rcvif),
+           m->m_pkthdr.csum_flags);
        if (m->m_flags & M_FLOWID) {
                mflowid = m->m_pkthdr.flowid;
                use_mflowid = 1;
@@ -5936,161 +6060,42 @@ sctp_input_with_port(struct mbuf *i_pak,
        dst.sin_addr = ip->ip_dst;
        length = ip->ip_len + iphlen;
        /* Validate mbuf chain length with IP payload length. */
-       if (SCTP_HEADER_LEN(i_pak) != length) {
+       if (SCTP_HEADER_LEN(m) != length) {
                SCTPDBG(SCTP_DEBUG_INPUT1,
-                   "sctp_input() length:%d reported length:%d\n", length, 
SCTP_HEADER_LEN(i_pak));
+                   "sctp_input() length:%d reported length:%d\n", length, 
SCTP_HEADER_LEN(m));
                SCTP_STAT_INCR(sctps_hdrops);
-               goto bad;
+               goto out;
        }
        /* SCTP does not allow broadcasts or multicasts */
        if (IN_MULTICAST(ntohl(dst.sin_addr.s_addr))) {
-               goto bad;
+               goto out;
        }
        if (SCTP_IS_IT_BROADCAST(dst.sin_addr, m)) {
-               goto bad;
+               goto out;
        }
-       SCTPDBG(SCTP_DEBUG_INPUT1,
-           "sctp_input() length:%d iphlen:%d\n", length, iphlen);
-       SCTPDBG(SCTP_DEBUG_CRCOFFLOAD,
-           "sctp_input(): Packet of length %d received on %s with csum_flags 
0x%x.\n",
-           m->m_pkthdr.len,
-           if_name(m->m_pkthdr.rcvif),
-           m->m_pkthdr.csum_flags);
+       ecn_bits = ip->ip_tos;
 #if defined(SCTP_WITH_NO_CSUM)
        SCTP_STAT_INCR(sctps_recvnocrc);
 #else
        if (m->m_pkthdr.csum_flags & CSUM_SCTP_VALID) {
                SCTP_STAT_INCR(sctps_recvhwcrc);
-               goto sctp_skip_csum;
-       }
-       check = sh->checksum;
-       sh->checksum = 0;
-       calc_check = sctp_calculate_cksum(m, iphlen);
-       sh->checksum = check;
-       SCTP_STAT_INCR(sctps_recvswcrc);
-       if (calc_check != check) {
-               SCTPDBG(SCTP_DEBUG_INPUT1, "Bad CSUM on SCTP packet 
calc_check:%x check:%x  m:%p mlen:%d iphlen:%d\n",
-                   calc_check, check, m, length, iphlen);
-               stcb = sctp_findassociation_addr(m, offset,
-                   (struct sockaddr *)&src,
-                   (struct sockaddr *)&dst,
-                   sh, ch, &inp, &net, vrf_id);
-               if ((net) && (port)) {
-                       if (net->port == 0) {
-                               sctp_pathmtu_adjustment(stcb, net->mtu - 
sizeof(struct udphdr));
-                       }
-                       net->port = port;
-               }
-               if ((net != NULL) && (use_mflowid != 0)) {
-                       net->flowid = mflowid;
-#ifdef INVARIANTS
-                       net->flowidset = 1;
-#endif
-               }
-               if ((inp) && (stcb)) {
-                       sctp_send_packet_dropped(stcb, net, m, length, iphlen, 
1);
-                       sctp_chunk_output(inp, stcb, 
SCTP_OUTPUT_FROM_INPUT_ERROR, SCTP_SO_NOT_LOCKED);
-               } else if ((inp != NULL) && (stcb == NULL)) {
-                       refcount_up = 1;
-               }
-               SCTP_STAT_INCR(sctps_badsum);
-               SCTP_STAT_INCR_COUNTER32(sctps_checksumerrors);
-               goto bad;
-       }
-sctp_skip_csum:
-#endif
-       /* destination port of 0 is illegal, based on RFC2960. */
-       if (sh->dest_port == 0) {
-               SCTP_STAT_INCR(sctps_hdrops);
-               goto bad;
-       }
-       stcb = sctp_findassociation_addr(m, offset,
-           (struct sockaddr *)&src,
-           (struct sockaddr *)&dst,
-           sh, ch, &inp, &net, vrf_id);
-       if ((net) && (port)) {
-               if (net->port == 0) {
-                       sctp_pathmtu_adjustment(stcb, net->mtu - sizeof(struct 
udphdr));
-               }
-               net->port = port;
-       }
-       if ((net != NULL) && (use_mflowid != 0)) {
-               net->flowid = mflowid;
-#ifdef INVARIANTS
-               net->flowidset = 1;
-#endif
-       }
-       if (inp == NULL) {
-               SCTP_STAT_INCR(sctps_noport);
-               if (badport_bandlim(BANDLIM_SCTP_OOTB) < 0)
-                       goto bad;
-               if (ch->chunk_type == SCTP_SHUTDOWN_ACK) {
-                       sctp_send_shutdown_complete2((struct sockaddr *)&src,
-                           (struct sockaddr *)&dst,
-                           sh,
-                           use_mflowid, mflowid,
-                           vrf_id, port);
-                       goto bad;
-               }
-               if (ch->chunk_type == SCTP_SHUTDOWN_COMPLETE) {
-                       goto bad;
-               }
-               if (ch->chunk_type != SCTP_ABORT_ASSOCIATION) {
-                       if ((SCTP_BASE_SYSCTL(sctp_blackhole) == 0) ||
-                           ((SCTP_BASE_SYSCTL(sctp_blackhole) == 1) &&
-                           (ch->chunk_type != SCTP_INIT))) {
-                               sctp_send_abort(m, iphlen,
-                                   (struct sockaddr *)&src,
-                                   (struct sockaddr *)&dst,
-                                   sh, 0, NULL,
-                                   use_mflowid, mflowid,
-                                   vrf_id, port);
-                       }
-               }
-               goto bad;
-       } else if (stcb == NULL) {
-               refcount_up = 1;
-       }
-#ifdef IPSEC
-       /*-
-        * I very much doubt any of the IPSEC stuff will work but I have no
-        * idea, so I will leave it in place.
-        */
-       if (inp && ipsec4_in_reject(m, &inp->ip_inp.inp)) {
-               MODULE_GLOBAL(ipsec4stat).in_polvio++;
-               SCTP_STAT_INCR(sctps_hdrops);
-               goto bad;
+               compute_crc = 0;
+       } else {
+               SCTP_STAT_INCR(sctps_recvswcrc);
+               compute_crc = 1;
        }
 #endif
-
-       ecn_bits = ip->ip_tos;
-       /* sa_ignore NO_NULL_CHK */
        sctp_common_input_processing(&m, iphlen, offset, length,
            (struct sockaddr *)&src,
            (struct sockaddr *)&dst,
-           sh, ch, inp, stcb, net, ecn_bits,
+           sh, ch,
+#if !defined(SCTP_WITH_NO_CSUM)
+           compute_crc,
+#endif
+           ecn_bits,
            use_mflowid, mflowid,
            vrf_id, port);
-       if (m) {
-               sctp_m_freem(m);
-       }
-       if ((inp) && (refcount_up)) {
-               /* reduce ref-count */
-               SCTP_INP_WLOCK(inp);
-               SCTP_INP_DECR_REF(inp);
-               SCTP_INP_WUNLOCK(inp);
-       }
-       return;
-bad:
-       if (stcb) {
-               SCTP_TCB_UNLOCK(stcb);
-       }
-       if ((inp) && (refcount_up)) {
-               /* reduce ref-count */
-               SCTP_INP_WLOCK(inp);
-               SCTP_INP_DECR_REF(inp);
-               SCTP_INP_WUNLOCK(inp);
-       }
+out:
        if (m) {
                sctp_m_freem(m);
        }

Modified: head/sys/netinet/sctp_input.h
==============================================================================
--- head/sys/netinet/sctp_input.h       Mon Jul  2 16:40:11 2012        
(r238002)
+++ head/sys/netinet/sctp_input.h       Mon Jul  2 16:44:09 2012        
(r238003)
@@ -41,8 +41,10 @@ void
 sctp_common_input_processing(struct mbuf **, int, int, int,
     struct sockaddr *, struct sockaddr *,
     struct sctphdr *, struct sctp_chunkhdr *,
-    struct sctp_inpcb *, struct sctp_tcb *,
-    struct sctp_nets *, uint8_t,
+#if !defined(SCTP_WITH_NO_CSUM)
+    uint8_t,
+#endif
+    uint8_t,
     uint8_t, uint32_t,
     uint32_t, uint16_t);
 

Modified: head/sys/netinet6/sctp6_usrreq.c
==============================================================================
--- head/sys/netinet6/sctp6_usrreq.c    Mon Jul  2 16:40:11 2012        
(r238002)
+++ head/sys/netinet6/sctp6_usrreq.c    Mon Jul  2 16:44:09 2012        
(r238003)
@@ -69,24 +69,20 @@ sctp6_input(struct mbuf **i_pak, int *of
 {
        struct mbuf *m;
        int iphlen;
-       uint32_t vrf_id = 0;
+       uint32_t vrf_id;
        uint8_t ecn_bits;
        struct sockaddr_in6 src, dst;
        struct ip6_hdr *ip6;
        struct sctphdr *sh;
        struct sctp_chunkhdr *ch;
-       struct sctp_inpcb *inp = NULL;
-       struct sctp_tcb *stcb = NULL;
-       struct sctp_nets *net = NULL;
-       int refcount_up = 0;
        int length, offset;
-       uint32_t mflowid;
-       uint8_t use_mflowid;
 
 #if !defined(SCTP_WITH_NO_CSUM)
-       uint32_t check, calc_check;
+       uint8_t compute_crc;
 
 #endif
+       uint32_t mflowid;
+       uint8_t use_mflowid;
        uint16_t port = 0;
 
        iphlen = *offp;
@@ -112,6 +108,11 @@ sctp6_input(struct mbuf **i_pak, int *of
                sctp_packet_log(m);
        }
 #endif
+       SCTPDBG(SCTP_DEBUG_CRCOFFLOAD,
+           "sctp6_input(): Packet of length %d received on %s with csum_flags 
0x%x.\n",
+           m->m_pkthdr.len,
+           if_name(m->m_pkthdr.rcvif),
+           m->m_pkthdr.csum_flags);
        if (m->m_flags & M_FLOWID) {
                mflowid = m->m_pkthdr.flowid;
                use_mflowid = 1;
@@ -122,8 +123,8 @@ sctp6_input(struct mbuf **i_pak, int *of
        SCTP_STAT_INCR(sctps_recvpackets);
        SCTP_STAT_INCR_COUNTER64(sctps_inpackets);
        /* Get IP, SCTP, and first chunk header together in the first mbuf. */
-       ip6 = mtod(m, struct ip6_hdr *);
        offset = iphlen + sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr);
+       ip6 = mtod(m, struct ip6_hdr *);
        IP6_EXTHDR_GET(sh, struct sctphdr *, m, iphlen,
            (int)(sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr)));
        if (sh == NULL) {
@@ -138,7 +139,7 @@ sctp6_input(struct mbuf **i_pak, int *of
        src.sin6_port = sh->src_port;
        src.sin6_addr = ip6->ip6_src;
        if (in6_setscope(&src.sin6_addr, m->m_pkthdr.rcvif, NULL) != 0) {
-               goto bad;
+               goto out;
        }
        memset(&dst, 0, sizeof(struct sockaddr_in6));
        dst.sin6_family = AF_INET6;
@@ -146,165 +147,46 @@ sctp6_input(struct mbuf **i_pak, int *of
        dst.sin6_port = sh->dest_port;
        dst.sin6_addr = ip6->ip6_dst;
        if (in6_setscope(&dst.sin6_addr, m->m_pkthdr.rcvif, NULL) != 0) {
-               goto bad;
+               goto out;
        }
        if (faithprefix_p != NULL && (*faithprefix_p) (&dst.sin6_addr)) {
                /* XXX send icmp6 host/port unreach? */
-               goto bad;
+               goto out;
        }
        length = ntohs(ip6->ip6_plen) + iphlen;
        /* Validate mbuf chain length with IP payload length. */
-       if (SCTP_HEADER_LEN(*i_pak) != length) {
+       if (SCTP_HEADER_LEN(m) != length) {
                SCTPDBG(SCTP_DEBUG_INPUT1,
-                   "sctp6_input() length:%d reported length:%d\n", length, 
SCTP_HEADER_LEN(*i_pak));
+                   "sctp6_input() length:%d reported length:%d\n", length, 
SCTP_HEADER_LEN(m));
                SCTP_STAT_INCR(sctps_hdrops);
-               goto bad;
+               goto out;
        }
        if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) {
-               goto bad;
+               goto out;
        }
-       SCTPDBG(SCTP_DEBUG_INPUT1,
-           "sctp6_input() length:%d iphlen:%d\n", length, iphlen);
-       SCTPDBG(SCTP_DEBUG_CRCOFFLOAD,
-           "sctp6_input(): Packet of length %d received on %s with csum_flags 
0x%x.\n",
-           m->m_pkthdr.len,
-           if_name(m->m_pkthdr.rcvif),
-           m->m_pkthdr.csum_flags);
+       ecn_bits = ((ntohl(ip6->ip6_flow) >> 20) & 0x000000ff);
 #if defined(SCTP_WITH_NO_CSUM)
        SCTP_STAT_INCR(sctps_recvnocrc);
 #else
        if (m->m_pkthdr.csum_flags & CSUM_SCTP_VALID) {
                SCTP_STAT_INCR(sctps_recvhwcrc);
-               goto sctp_skip_csum;
-       }
-       check = sh->checksum;
-       sh->checksum = 0;
-       calc_check = sctp_calculate_cksum(m, iphlen);
-       sh->checksum = check;
-       SCTP_STAT_INCR(sctps_recvswcrc);
-       if (calc_check != check) {
-               SCTPDBG(SCTP_DEBUG_INPUT1, "Bad CSUM on SCTP packet 
calc_check:%x check:%x  m:%p mlen:%d iphlen:%d\n",
-                   calc_check, check, m, length, iphlen);
-               stcb = sctp_findassociation_addr(m, offset,
-                   (struct sockaddr *)&src,
-                   (struct sockaddr *)&dst,
-                   sh, ch, &inp, &net, vrf_id);
-               if ((net) && (port)) {
-                       if (net->port == 0) {
-                               sctp_pathmtu_adjustment(stcb, net->mtu - 
sizeof(struct udphdr));
-                       }
-                       net->port = port;
-               }
-               if ((net != NULL) && (use_mflowid != 0)) {
-                       net->flowid = mflowid;
-#ifdef INVARIANTS
-                       net->flowidset = 1;
-#endif
-               }
-               if ((inp) && (stcb)) {
-                       sctp_send_packet_dropped(stcb, net, m, length, iphlen, 
1);
-                       sctp_chunk_output(inp, stcb, 
SCTP_OUTPUT_FROM_INPUT_ERROR, SCTP_SO_NOT_LOCKED);
-               } else if ((inp != NULL) && (stcb == NULL)) {
-                       refcount_up = 1;
-               }
-               SCTP_STAT_INCR(sctps_badsum);
-               SCTP_STAT_INCR_COUNTER32(sctps_checksumerrors);
-               goto bad;
-       }
-sctp_skip_csum:
-#endif
-       /* destination port of 0 is illegal, based on RFC2960. */
-       if (sh->dest_port == 0) {
-               SCTP_STAT_INCR(sctps_hdrops);
-               goto bad;
-       }
-       stcb = sctp_findassociation_addr(m, offset,
-           (struct sockaddr *)&src,
-           (struct sockaddr *)&dst,
-           sh, ch, &inp, &net, vrf_id);
-       if ((net) && (port)) {
-               if (net->port == 0) {
-                       sctp_pathmtu_adjustment(stcb, net->mtu - sizeof(struct 
udphdr));
-               }
-               net->port = port;
-       }
-       if ((net != NULL) && (use_mflowid != 0)) {
-               net->flowid = mflowid;
-#ifdef INVARIANTS
-               net->flowidset = 1;
-#endif
-       }
-       if (inp == NULL) {
-               SCTP_STAT_INCR(sctps_noport);
-               if (badport_bandlim(BANDLIM_SCTP_OOTB) < 0)
-                       goto bad;
-               if (ch->chunk_type == SCTP_SHUTDOWN_ACK) {
-                       sctp_send_shutdown_complete2((struct sockaddr *)&src,
-                           (struct sockaddr *)&dst,
-                           sh,
-                           use_mflowid, mflowid,
-                           vrf_id, port);
-                       goto bad;
-               }
-               if (ch->chunk_type == SCTP_SHUTDOWN_COMPLETE) {
-                       goto bad;
-               }
-               if (ch->chunk_type != SCTP_ABORT_ASSOCIATION) {
-                       if ((SCTP_BASE_SYSCTL(sctp_blackhole) == 0) ||
-                           ((SCTP_BASE_SYSCTL(sctp_blackhole) == 1) &&
-                           (ch->chunk_type != SCTP_INIT))) {
-                               sctp_send_abort(m, iphlen,
-                                   (struct sockaddr *)&src,
-                                   (struct sockaddr *)&dst,
-                                   sh, 0, NULL,
-                                   use_mflowid, mflowid,
-                                   vrf_id, port);
-                       }
-               }
-               goto bad;
-       } else if (stcb == NULL) {
-               refcount_up = 1;
-       }
-#ifdef IPSEC
-       /*-
-        * I very much doubt any of the IPSEC stuff will work but I have no
-        * idea, so I will leave it in place.
-        */
-       if (inp && ipsec6_in_reject(m, &inp->ip_inp.inp)) {
-               MODULE_GLOBAL(ipsec6stat).in_polvio++;
-               SCTP_STAT_INCR(sctps_hdrops);
-               goto bad;
+               compute_crc = 0;
+       } else {
+               SCTP_STAT_INCR(sctps_recvswcrc);
+               compute_crc = 1;
        }
 #endif
-
-       ecn_bits = ((ntohl(ip6->ip6_flow) >> 20) & 0x000000ff);
-       /* sa_ignore NO_NULL_CHK */
        sctp_common_input_processing(&m, iphlen, offset, length,
            (struct sockaddr *)&src,
            (struct sockaddr *)&dst,
-           sh, ch, inp, stcb, net, ecn_bits,
+           sh, ch,
+#if !defined(SCTP_WITH_NO_CSUM)
+           compute_crc,
+#endif
+           ecn_bits,
            use_mflowid, mflowid,
            vrf_id, port);
-       if (m) {
-               sctp_m_freem(m);
-       }
-       if ((inp) && (refcount_up)) {
-               /* reduce ref-count */
-               SCTP_INP_WLOCK(inp);
-               SCTP_INP_DECR_REF(inp);
-               SCTP_INP_WUNLOCK(inp);
-       }
-       return (IPPROTO_DONE);
-bad:
-       if (stcb) {
-               SCTP_TCB_UNLOCK(stcb);
-       }
-       if ((inp) && (refcount_up)) {
-               /* reduce ref-count */
-               SCTP_INP_WLOCK(inp);
-               SCTP_INP_DECR_REF(inp);
-               SCTP_INP_WUNLOCK(inp);
-       }
+out:
        if (m) {
                sctp_m_freem(m);
        }
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to