--- zzzz-none-000/linux-3.10.107/net/sctp/input.c 2017-06-27 09:49:32.000000000 +0000
+++ scorpion-7490-727/linux-3.10.107/net/sctp/input.c 2021-02-04 17:41:59.000000000 +0000
@@ -23,16 +23,12 @@
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with GNU CC; see the file COPYING. If not, write to
- * the Free Software Foundation, 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * along with GNU CC; see the file COPYING. If not, see
+ * .
*
* Please send any bug reports or fixes you make to the
* email address(es):
- * lksctp developers
- *
- * Or submit a bug report through the following website:
- * http://www.sf.net/projects/lksctp
+ * lksctp developers
*
* Written or modified by:
* La Monte H.P. Yarroll
@@ -43,9 +39,6 @@
* Daisy Chang
* Sridhar Samudrala
* Ardelle Fan
- *
- * Any bugs reported given to us we will try to fix... any fixes shared will
- * be incorporated into the next SCTP release.
*/
#include
@@ -87,15 +80,7 @@
{
struct sctphdr *sh = sctp_hdr(skb);
__le32 cmp = sh->checksum;
- struct sk_buff *list;
- __le32 val;
- __u32 tmp = sctp_start_cksum((__u8 *)sh, skb_headlen(skb));
-
- skb_walk_frags(skb, list)
- tmp = sctp_update_cksum((__u8 *)list->data, skb_headlen(list),
- tmp);
-
- val = sctp_end_cksum(tmp);
+ __le32 val = sctp_compute_cksum(skb, 0);
if (val != cmp) {
/* CRC failure, dump it. */
@@ -134,7 +119,7 @@
struct sctp_af *af;
struct net *net = dev_net(skb->dev);
- if (skb->pkt_type!=PACKET_HOST)
+ if (skb->pkt_type != PACKET_HOST)
goto discard_it;
SCTP_INC_STATS_BH(net, SCTP_MIB_INSCTPPACKS);
@@ -148,9 +133,13 @@
__skb_pull(skb, skb_transport_offset(skb));
if (skb->len < sizeof(struct sctphdr))
goto discard_it;
- if (!sctp_checksum_disable && !skb_csum_unnecessary(skb) &&
- sctp_rcv_checksum(net, skb) < 0)
+
+ skb->csum_valid = 0; /* Previous value not applicable */
+ if (skb_csum_unnecessary(skb))
+ __skb_decr_checksum_unnecessary(skb);
+ else if (!sctp_checksum_disable && sctp_rcv_checksum(net, skb) < 0)
goto discard_it;
+ skb->csum_valid = 1;
skb_pull(skb, sizeof(struct sctphdr));
@@ -195,8 +184,7 @@
* If a frame arrives on an interface and the receiving socket is
* bound to another interface, via SO_BINDTODEVICE, treat it as OOTB
*/
- if (sk->sk_bound_dev_if && (sk->sk_bound_dev_if != af->skb_iif(skb)))
- {
+ if (sk->sk_bound_dev_if && (sk->sk_bound_dev_if != af->skb_iif(skb))) {
if (asoc) {
sctp_association_put(asoc);
asoc = NULL;
@@ -254,7 +242,7 @@
* bottom halves on this lock, but a user may be in the lock too,
* so check if it is busy.
*/
- sctp_bh_lock_sock(sk);
+ bh_lock_sock(sk);
if (sk != rcvr->sk) {
/* Our cached sk is different from the rcvr->sk. This is
@@ -264,14 +252,14 @@
* be doing something with the new socket. Switch our veiw
* of the current sk.
*/
- sctp_bh_unlock_sock(sk);
+ bh_unlock_sock(sk);
sk = rcvr->sk;
- sctp_bh_lock_sock(sk);
+ bh_lock_sock(sk);
}
if (sock_owned_by_user(sk)) {
if (sctp_add_backlog(sk, skb)) {
- sctp_bh_unlock_sock(sk);
+ bh_unlock_sock(sk);
sctp_chunk_free(chunk);
skb = NULL; /* sctp_chunk_free already freed the skb */
goto discard_release;
@@ -282,7 +270,7 @@
sctp_inq_push(&chunk->rcvr->inqueue, chunk);
}
- sctp_bh_unlock_sock(sk);
+ bh_unlock_sock(sk);
/* Release the asoc/ep ref we took in the lookup calls. */
if (asoc)
@@ -343,7 +331,7 @@
*/
sk = rcvr->sk;
- sctp_bh_lock_sock(sk);
+ bh_lock_sock(sk);
if (sock_owned_by_user(sk)) {
if (sk_add_backlog(sk, skb, sk->sk_rcvbuf))
@@ -353,7 +341,7 @@
} else
sctp_inq_push(inqueue, chunk);
- sctp_bh_unlock_sock(sk);
+ bh_unlock_sock(sk);
/* If the chunk was backloged again, don't drop refs */
if (backloged)
@@ -454,8 +442,6 @@
struct sctp_association *asoc,
struct sctp_transport *t)
{
- SCTP_DEBUG_PRINTK("%s\n", __func__);
-
if (sock_owned_by_user(sk)) {
if (timer_pending(&t->proto_unreach_timer))
return;
@@ -464,10 +450,12 @@
jiffies + (HZ/20)))
sctp_association_hold(asoc);
}
-
} else {
struct net *net = sock_net(sk);
+ pr_debug("%s: unrecognized next header type "
+ "encountered!\n", __func__);
+
if (del_timer(&t->proto_unreach_timer))
sctp_association_put(asoc);
@@ -538,7 +526,7 @@
goto out;
}
- sctp_bh_lock_sock(sk);
+ bh_lock_sock(sk);
/* If too many ICMPs get dropped on busy
* servers this needs to be solved differently.
@@ -551,17 +539,15 @@
return sk;
out:
- if (asoc)
- sctp_association_put(asoc);
+ sctp_association_put(asoc);
return NULL;
}
/* Common cleanup code for icmp/icmpv6 error handler. */
void sctp_err_finish(struct sock *sk, struct sctp_association *asoc)
{
- sctp_bh_unlock_sock(sk);
- if (asoc)
- sctp_association_put(asoc);
+ bh_unlock_sock(sk);
+ sctp_association_put(asoc);
}
/*
@@ -589,15 +575,10 @@
struct sctp_association *asoc = NULL;
struct sctp_transport *transport;
struct inet_sock *inet;
- sk_buff_data_t saveip, savesctp;
+ __u16 saveip, savesctp;
int err;
struct net *net = dev_net(skb->dev);
- if (skb->len < ihlen + 8) {
- ICMP_INC_STATS_BH(net, ICMP_MIB_INERRORS);
- return;
- }
-
/* Fix up skb to look at the embedded net header. */
saveip = skb->network_header;
savesctp = skb->transport_header;
@@ -627,8 +608,7 @@
if (ICMP_FRAG_NEEDED == code) {
sctp_icmp_frag_needed(sk, asoc, transport, info);
goto out_unlock;
- }
- else {
+ } else {
if (ICMP_PROT_UNREACH == code) {
sctp_icmp_proto_unreachable(sk, asoc,
transport);
@@ -737,17 +717,17 @@
epb->hashent = sctp_ep_hashfn(net, epb->bind_addr.port);
head = &sctp_ep_hashtable[epb->hashent];
- sctp_write_lock(&head->lock);
+ write_lock(&head->lock);
hlist_add_head(&epb->node, &head->chain);
- sctp_write_unlock(&head->lock);
+ write_unlock(&head->lock);
}
/* Add an endpoint to the hash. Local BH-safe. */
void sctp_hash_endpoint(struct sctp_endpoint *ep)
{
- sctp_local_bh_disable();
+ local_bh_disable();
__sctp_hash_endpoint(ep);
- sctp_local_bh_enable();
+ local_bh_enable();
}
/* Remove endpoint from the hash table. */
@@ -763,17 +743,17 @@
head = &sctp_ep_hashtable[epb->hashent];
- sctp_write_lock(&head->lock);
+ write_lock(&head->lock);
hlist_del_init(&epb->node);
- sctp_write_unlock(&head->lock);
+ write_unlock(&head->lock);
}
/* Remove endpoint from the hash. Local BH-safe. */
void sctp_unhash_endpoint(struct sctp_endpoint *ep)
{
- sctp_local_bh_disable();
+ local_bh_disable();
__sctp_unhash_endpoint(ep);
- sctp_local_bh_enable();
+ local_bh_enable();
}
/* Look up an endpoint. */
@@ -817,9 +797,9 @@
head = &sctp_assoc_hashtable[epb->hashent];
- sctp_write_lock(&head->lock);
+ write_lock(&head->lock);
hlist_add_head(&epb->node, &head->chain);
- sctp_write_unlock(&head->lock);
+ write_unlock(&head->lock);
}
/* Add an association to the hash. Local BH-safe. */
@@ -828,9 +808,9 @@
if (asoc->temp)
return;
- sctp_local_bh_disable();
+ local_bh_disable();
__sctp_hash_established(asoc);
- sctp_local_bh_enable();
+ local_bh_enable();
}
/* Remove association from the hash table. */
@@ -847,9 +827,9 @@
head = &sctp_assoc_hashtable[epb->hashent];
- sctp_write_lock(&head->lock);
+ write_lock(&head->lock);
hlist_del_init(&epb->node);
- sctp_write_unlock(&head->lock);
+ write_unlock(&head->lock);
}
/* Remove association from the hash table. Local BH-safe. */
@@ -858,9 +838,9 @@
if (asoc->temp)
return;
- sctp_local_bh_disable();
+ local_bh_disable();
__sctp_unhash_established(asoc);
- sctp_local_bh_enable();
+ local_bh_enable();
}
/* Look up an association. */
@@ -902,17 +882,17 @@
}
/* Look up an association. BH-safe. */
-SCTP_STATIC
+static
struct sctp_association *sctp_lookup_association(struct net *net,
const union sctp_addr *laddr,
const union sctp_addr *paddr,
- struct sctp_transport **transportp)
+ struct sctp_transport **transportp)
{
struct sctp_association *asoc;
- sctp_local_bh_disable();
+ local_bh_disable();
asoc = __sctp_lookup_association(net, laddr, paddr, transportp);
- sctp_local_bh_enable();
+ local_bh_enable();
return asoc;
}
@@ -1072,31 +1052,31 @@
if (ch_end > skb_tail_pointer(skb))
break;
- switch(ch->type) {
- case SCTP_CID_AUTH:
- have_auth = chunk_num;
- break;
-
- case SCTP_CID_COOKIE_ECHO:
- /* If a packet arrives containing an AUTH chunk as
- * a first chunk, a COOKIE-ECHO chunk as the second
- * chunk, and possibly more chunks after them, and
- * the receiver does not have an STCB for that
- * packet, then authentication is based on
- * the contents of the COOKIE- ECHO chunk.
- */
- if (have_auth == 1 && chunk_num == 2)
- return NULL;
- break;
-
- case SCTP_CID_ASCONF:
- if (have_auth || net->sctp.addip_noauth)
- asoc = __sctp_rcv_asconf_lookup(
- net, ch, laddr,
- sctp_hdr(skb)->source,
- transportp);
- default:
- break;
+ switch (ch->type) {
+ case SCTP_CID_AUTH:
+ have_auth = chunk_num;
+ break;
+
+ case SCTP_CID_COOKIE_ECHO:
+ /* If a packet arrives containing an AUTH chunk as
+ * a first chunk, a COOKIE-ECHO chunk as the second
+ * chunk, and possibly more chunks after them, and
+ * the receiver does not have an STCB for that
+ * packet, then authentication is based on
+ * the contents of the COOKIE- ECHO chunk.
+ */
+ if (have_auth == 1 && chunk_num == 2)
+ return NULL;
+ break;
+
+ case SCTP_CID_ASCONF:
+ if (have_auth || net->sctp.addip_noauth)
+ asoc = __sctp_rcv_asconf_lookup(
+ net, ch, laddr,
+ sctp_hdr(skb)->source,
+ transportp);
+ default:
+ break;
}
if (asoc)
@@ -1133,19 +1113,10 @@
return NULL;
/* If this is INIT/INIT-ACK look inside the chunk too. */
- switch (ch->type) {
- case SCTP_CID_INIT:
- case SCTP_CID_INIT_ACK:
+ if (ch->type == SCTP_CID_INIT || ch->type == SCTP_CID_INIT_ACK)
return __sctp_rcv_init_lookup(net, skb, laddr, transportp);
- break;
- default:
- return __sctp_rcv_walk_lookup(net, skb, laddr, transportp);
- break;
- }
-
-
- return NULL;
+ return __sctp_rcv_walk_lookup(net, skb, laddr, transportp);
}
/* Lookup an association for an inbound skb. */