160c778b2SVlad Yasevich /* SCTP kernel implementation 21da177e4SLinus Torvalds * Copyright (c) 1999-2000 Cisco, Inc. 31da177e4SLinus Torvalds * Copyright (c) 1999-2001 Motorola, Inc. 41da177e4SLinus Torvalds * Copyright (c) 2001-2003 International Business Machines, Corp. 51da177e4SLinus Torvalds * Copyright (c) 2001 Intel Corp. 61da177e4SLinus Torvalds * Copyright (c) 2001 Nokia, Inc. 71da177e4SLinus Torvalds * Copyright (c) 2001 La Monte H.P. Yarroll 81da177e4SLinus Torvalds * 960c778b2SVlad Yasevich * This file is part of the SCTP kernel implementation 101da177e4SLinus Torvalds * 111da177e4SLinus Torvalds * These functions handle all input from the IP layer into SCTP. 121da177e4SLinus Torvalds * 1360c778b2SVlad Yasevich * This SCTP implementation is free software; 141da177e4SLinus Torvalds * you can redistribute it and/or modify it under the terms of 151da177e4SLinus Torvalds * the GNU General Public License as published by 161da177e4SLinus Torvalds * the Free Software Foundation; either version 2, or (at your option) 171da177e4SLinus Torvalds * any later version. 181da177e4SLinus Torvalds * 1960c778b2SVlad Yasevich * This SCTP implementation is distributed in the hope that it 201da177e4SLinus Torvalds * will be useful, but WITHOUT ANY WARRANTY; without even the implied 211da177e4SLinus Torvalds * ************************ 221da177e4SLinus Torvalds * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 231da177e4SLinus Torvalds * See the GNU General Public License for more details. 241da177e4SLinus Torvalds * 251da177e4SLinus Torvalds * You should have received a copy of the GNU General Public License 264b2f13a2SJeff Kirsher * along with GNU CC; see the file COPYING. If not, see 274b2f13a2SJeff Kirsher * <http://www.gnu.org/licenses/>. 281da177e4SLinus Torvalds * 291da177e4SLinus Torvalds * Please send any bug reports or fixes you make to the 301da177e4SLinus Torvalds * email address(es): 3191705c61SDaniel Borkmann * lksctp developers <linux-sctp@vger.kernel.org> 321da177e4SLinus Torvalds * 331da177e4SLinus Torvalds * Written or modified by: 341da177e4SLinus Torvalds * La Monte H.P. Yarroll <piggy@acm.org> 351da177e4SLinus Torvalds * Karl Knutson <karl@athena.chicago.il.us> 361da177e4SLinus Torvalds * Xingang Guo <xingang.guo@intel.com> 371da177e4SLinus Torvalds * Jon Grimm <jgrimm@us.ibm.com> 381da177e4SLinus Torvalds * Hui Huang <hui.huang@nokia.com> 391da177e4SLinus Torvalds * Daisy Chang <daisyc@us.ibm.com> 401da177e4SLinus Torvalds * Sridhar Samudrala <sri@us.ibm.com> 411da177e4SLinus Torvalds * Ardelle Fan <ardelle.fan@intel.com> 421da177e4SLinus Torvalds */ 431da177e4SLinus Torvalds 441da177e4SLinus Torvalds #include <linux/types.h> 451da177e4SLinus Torvalds #include <linux/list.h> /* For struct list_head */ 461da177e4SLinus Torvalds #include <linux/socket.h> 471da177e4SLinus Torvalds #include <linux/ip.h> 481da177e4SLinus Torvalds #include <linux/time.h> /* For struct timeval */ 495a0e3ad6STejun Heo #include <linux/slab.h> 501da177e4SLinus Torvalds #include <net/ip.h> 511da177e4SLinus Torvalds #include <net/icmp.h> 521da177e4SLinus Torvalds #include <net/snmp.h> 531da177e4SLinus Torvalds #include <net/sock.h> 541da177e4SLinus Torvalds #include <net/xfrm.h> 551da177e4SLinus Torvalds #include <net/sctp/sctp.h> 561da177e4SLinus Torvalds #include <net/sctp/sm.h> 579ad0977fSVlad Yasevich #include <net/sctp/checksum.h> 58dcfc23caSPavel Emelyanov #include <net/net_namespace.h> 591da177e4SLinus Torvalds 601da177e4SLinus Torvalds /* Forward declarations for internal helpers. */ 611da177e4SLinus Torvalds static int sctp_rcv_ootb(struct sk_buff *); 624110cc25SEric W. Biederman static struct sctp_association *__sctp_rcv_lookup(struct net *net, 634110cc25SEric W. Biederman struct sk_buff *skb, 641da177e4SLinus Torvalds const union sctp_addr *paddr, 6557565993SNicolas Dichtel const union sctp_addr *laddr, 661da177e4SLinus Torvalds struct sctp_transport **transportp); 674cdadcbcSEric W. Biederman static struct sctp_endpoint *__sctp_rcv_lookup_endpoint(struct net *net, 684cdadcbcSEric W. Biederman const union sctp_addr *laddr); 691da177e4SLinus Torvalds static struct sctp_association *__sctp_lookup_association( 704110cc25SEric W. Biederman struct net *net, 711da177e4SLinus Torvalds const union sctp_addr *local, 721da177e4SLinus Torvalds const union sctp_addr *peer, 731da177e4SLinus Torvalds struct sctp_transport **pt); 741da177e4SLinus Torvalds 7550b1a782SZhu Yi static int sctp_add_backlog(struct sock *sk, struct sk_buff *skb); 7661c9fed4SVladislav Yasevich 771da177e4SLinus Torvalds 781da177e4SLinus Torvalds /* Calculate the SCTP checksum of an SCTP packet. */ 79b01a2407SEric W. Biederman static inline int sctp_rcv_checksum(struct net *net, struct sk_buff *skb) 801da177e4SLinus Torvalds { 812c0fd387SArnaldo Carvalho de Melo struct sctphdr *sh = sctp_hdr(skb); 824458f04cSVlad Yasevich __le32 cmp = sh->checksum; 83024ec3deSJoe Stringer __le32 val = sctp_compute_cksum(skb, 0); 841da177e4SLinus Torvalds 851da177e4SLinus Torvalds if (val != cmp) { 861da177e4SLinus Torvalds /* CRC failure, dump it. */ 8708e3baefSEric Dumazet __SCTP_INC_STATS(net, SCTP_MIB_CHECKSUMERRORS); 881da177e4SLinus Torvalds return -1; 891da177e4SLinus Torvalds } 901da177e4SLinus Torvalds return 0; 911da177e4SLinus Torvalds } 921da177e4SLinus Torvalds 931da177e4SLinus Torvalds /* 941da177e4SLinus Torvalds * This is the routine which IP calls when receiving an SCTP packet. 951da177e4SLinus Torvalds */ 961da177e4SLinus Torvalds int sctp_rcv(struct sk_buff *skb) 971da177e4SLinus Torvalds { 981da177e4SLinus Torvalds struct sock *sk; 991da177e4SLinus Torvalds struct sctp_association *asoc; 1001da177e4SLinus Torvalds struct sctp_endpoint *ep = NULL; 1011da177e4SLinus Torvalds struct sctp_ep_common *rcvr; 1021da177e4SLinus Torvalds struct sctp_transport *transport = NULL; 1031da177e4SLinus Torvalds struct sctp_chunk *chunk; 1041da177e4SLinus Torvalds union sctp_addr src; 1051da177e4SLinus Torvalds union sctp_addr dest; 1061da177e4SLinus Torvalds int family; 1071da177e4SLinus Torvalds struct sctp_af *af; 1084cdadcbcSEric W. Biederman struct net *net = dev_net(skb->dev); 1091da177e4SLinus Torvalds 1101da177e4SLinus Torvalds if (skb->pkt_type != PACKET_HOST) 1111da177e4SLinus Torvalds goto discard_it; 1121da177e4SLinus Torvalds 11308e3baefSEric Dumazet __SCTP_INC_STATS(net, SCTP_MIB_INSCTPPACKS); 1141da177e4SLinus Torvalds 1153acb50c1SMarcelo Ricardo Leitner /* If packet is too small to contain a single chunk, let's not 1163acb50c1SMarcelo Ricardo Leitner * waste time on it anymore. 1173acb50c1SMarcelo Ricardo Leitner */ 1183acb50c1SMarcelo Ricardo Leitner if (skb->len < sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr) + 1193acb50c1SMarcelo Ricardo Leitner skb_transport_offset(skb)) 12028cd7752SHerbert Xu goto discard_it; 12128cd7752SHerbert Xu 1224c2f2454SMarcelo Ricardo Leitner /* If the packet is fragmented and we need to do crc checking, 1234c2f2454SMarcelo Ricardo Leitner * it's better to just linearize it otherwise crc computing 1244c2f2454SMarcelo Ricardo Leitner * takes longer. 1254c2f2454SMarcelo Ricardo Leitner */ 1264c2f2454SMarcelo Ricardo Leitner if ((!(skb_shinfo(skb)->gso_type & SKB_GSO_SCTP) && 1274c2f2454SMarcelo Ricardo Leitner skb_linearize(skb)) || 1284c2f2454SMarcelo Ricardo Leitner !pskb_may_pull(skb, sizeof(struct sctphdr))) 1293acb50c1SMarcelo Ricardo Leitner goto discard_it; 1301da177e4SLinus Torvalds 1313acb50c1SMarcelo Ricardo Leitner /* Pull up the IP header. */ 132ea2ae17dSArnaldo Carvalho de Melo __skb_pull(skb, skb_transport_offset(skb)); 133202863feSTom Herbert 134202863feSTom Herbert skb->csum_valid = 0; /* Previous value not applicable */ 135202863feSTom Herbert if (skb_csum_unnecessary(skb)) 136202863feSTom Herbert __skb_decr_checksum_unnecessary(skb); 13790017accSMarcelo Ricardo Leitner else if (!sctp_checksum_disable && 13890017accSMarcelo Ricardo Leitner !(skb_shinfo(skb)->gso_type & SKB_GSO_SCTP) && 13990017accSMarcelo Ricardo Leitner sctp_rcv_checksum(net, skb) < 0) 1401da177e4SLinus Torvalds goto discard_it; 141202863feSTom Herbert skb->csum_valid = 1; 1421da177e4SLinus Torvalds 1433acb50c1SMarcelo Ricardo Leitner __skb_pull(skb, sizeof(struct sctphdr)); 1441da177e4SLinus Torvalds 145eddc9ec5SArnaldo Carvalho de Melo family = ipver2af(ip_hdr(skb)->version); 1461da177e4SLinus Torvalds af = sctp_get_af_specific(family); 1471da177e4SLinus Torvalds if (unlikely(!af)) 1481da177e4SLinus Torvalds goto discard_it; 149e7487c86SMarcelo Ricardo Leitner SCTP_INPUT_CB(skb)->af = af; 1501da177e4SLinus Torvalds 1511da177e4SLinus Torvalds /* Initialize local addresses for lookups. */ 1521da177e4SLinus Torvalds af->from_skb(&src, skb, 1); 1531da177e4SLinus Torvalds af->from_skb(&dest, skb, 0); 1541da177e4SLinus Torvalds 1551da177e4SLinus Torvalds /* If the packet is to or from a non-unicast address, 1561da177e4SLinus Torvalds * silently discard the packet. 1571da177e4SLinus Torvalds * 1581da177e4SLinus Torvalds * This is not clearly defined in the RFC except in section 1591da177e4SLinus Torvalds * 8.4 - OOTB handling. However, based on the book "Stream Control 1601da177e4SLinus Torvalds * Transmission Protocol" 2.1, "It is important to note that the 1611da177e4SLinus Torvalds * IP address of an SCTP transport address must be a routable 1621da177e4SLinus Torvalds * unicast address. In other words, IP multicast addresses and 1631da177e4SLinus Torvalds * IP broadcast addresses cannot be used in an SCTP transport 1641da177e4SLinus Torvalds * address." 1651da177e4SLinus Torvalds */ 1665636bef7SVlad Yasevich if (!af->addr_valid(&src, NULL, skb) || 1675636bef7SVlad Yasevich !af->addr_valid(&dest, NULL, skb)) 1681da177e4SLinus Torvalds goto discard_it; 1691da177e4SLinus Torvalds 1704110cc25SEric W. Biederman asoc = __sctp_rcv_lookup(net, skb, &src, &dest, &transport); 1711c7d1fc1SAl Viro 1720fd9a65aSNeil Horman if (!asoc) 1734cdadcbcSEric W. Biederman ep = __sctp_rcv_lookup_endpoint(net, &dest); 1740fd9a65aSNeil Horman 1750fd9a65aSNeil Horman /* Retrieve the common input handling substructure. */ 1760fd9a65aSNeil Horman rcvr = asoc ? &asoc->base : &ep->base; 1770fd9a65aSNeil Horman sk = rcvr->sk; 1780fd9a65aSNeil Horman 1790fd9a65aSNeil Horman /* 1800fd9a65aSNeil Horman * If a frame arrives on an interface and the receiving socket is 1810fd9a65aSNeil Horman * bound to another interface, via SO_BINDTODEVICE, treat it as OOTB 1820fd9a65aSNeil Horman */ 1838d72651dSwangweidong if (sk->sk_bound_dev_if && (sk->sk_bound_dev_if != af->skb_iif(skb))) { 184dae399d7SXin Long if (transport) { 185dae399d7SXin Long sctp_transport_put(transport); 1860fd9a65aSNeil Horman asoc = NULL; 187dae399d7SXin Long transport = NULL; 1880fd9a65aSNeil Horman } else { 1890fd9a65aSNeil Horman sctp_endpoint_put(ep); 1900fd9a65aSNeil Horman ep = NULL; 1910fd9a65aSNeil Horman } 1922ce95503SEric W. Biederman sk = net->sctp.ctl_sock; 1930fd9a65aSNeil Horman ep = sctp_sk(sk)->ep; 1940fd9a65aSNeil Horman sctp_endpoint_hold(ep); 1950fd9a65aSNeil Horman rcvr = &ep->base; 1960fd9a65aSNeil Horman } 1970fd9a65aSNeil Horman 1981da177e4SLinus Torvalds /* 1991da177e4SLinus Torvalds * RFC 2960, 8.4 - Handle "Out of the blue" Packets. 2001da177e4SLinus Torvalds * An SCTP packet is called an "out of the blue" (OOTB) 2011da177e4SLinus Torvalds * packet if it is correctly formed, i.e., passed the 2021da177e4SLinus Torvalds * receiver's checksum check, but the receiver is not 2031da177e4SLinus Torvalds * able to identify the association to which this 2041da177e4SLinus Torvalds * packet belongs. 2051da177e4SLinus Torvalds */ 2061da177e4SLinus Torvalds if (!asoc) { 2071da177e4SLinus Torvalds if (sctp_rcv_ootb(skb)) { 20808e3baefSEric Dumazet __SCTP_INC_STATS(net, SCTP_MIB_OUTOFBLUES); 2091da177e4SLinus Torvalds goto discard_release; 2101da177e4SLinus Torvalds } 2111da177e4SLinus Torvalds } 2121da177e4SLinus Torvalds 2131da177e4SLinus Torvalds if (!xfrm_policy_check(sk, XFRM_POLICY_IN, skb, family)) 2141da177e4SLinus Torvalds goto discard_release; 215b59c2701SPatrick McHardy nf_reset(skb); 2161da177e4SLinus Torvalds 217fda9ef5dSDmitry Mishin if (sk_filter(sk, skb)) 2181da177e4SLinus Torvalds goto discard_release; 2191da177e4SLinus Torvalds 2201da177e4SLinus Torvalds /* Create an SCTP packet structure. */ 221cea8768fSMarcelo Ricardo Leitner chunk = sctp_chunkify(skb, asoc, sk, GFP_ATOMIC); 2222babf9daSHerbert Xu if (!chunk) 2231da177e4SLinus Torvalds goto discard_release; 22479af02c2SDavid S. Miller SCTP_INPUT_CB(skb)->chunk = chunk; 2251da177e4SLinus Torvalds 2261da177e4SLinus Torvalds /* Remember what endpoint is to handle this packet. */ 2271da177e4SLinus Torvalds chunk->rcvr = rcvr; 2281da177e4SLinus Torvalds 2291da177e4SLinus Torvalds /* Remember the SCTP header. */ 2303acb50c1SMarcelo Ricardo Leitner chunk->sctp_hdr = sctp_hdr(skb); 2311da177e4SLinus Torvalds 2321da177e4SLinus Torvalds /* Set the source and destination addresses of the incoming chunk. */ 233d55c41b1SAl Viro sctp_init_addrs(chunk, &src, &dest); 2341da177e4SLinus Torvalds 2351da177e4SLinus Torvalds /* Remember where we came from. */ 2361da177e4SLinus Torvalds chunk->transport = transport; 2371da177e4SLinus Torvalds 2381da177e4SLinus Torvalds /* Acquire access to the sock lock. Note: We are safe from other 2391da177e4SLinus Torvalds * bottom halves on this lock, but a user may be in the lock too, 2401da177e4SLinus Torvalds * so check if it is busy. 2411da177e4SLinus Torvalds */ 2425bc1d1b4Swangweidong bh_lock_sock(sk); 2431da177e4SLinus Torvalds 244ae53b5bdSVlad Yasevich if (sk != rcvr->sk) { 245ae53b5bdSVlad Yasevich /* Our cached sk is different from the rcvr->sk. This is 246ae53b5bdSVlad Yasevich * because migrate()/accept() may have moved the association 247ae53b5bdSVlad Yasevich * to a new socket and released all the sockets. So now we 248ae53b5bdSVlad Yasevich * are holding a lock on the old socket while the user may 249ae53b5bdSVlad Yasevich * be doing something with the new socket. Switch our veiw 250ae53b5bdSVlad Yasevich * of the current sk. 251ae53b5bdSVlad Yasevich */ 2525bc1d1b4Swangweidong bh_unlock_sock(sk); 253ae53b5bdSVlad Yasevich sk = rcvr->sk; 2545bc1d1b4Swangweidong bh_lock_sock(sk); 255ae53b5bdSVlad Yasevich } 256ae53b5bdSVlad Yasevich 257ac0b0462SSridhar Samudrala if (sock_owned_by_user(sk)) { 25850b1a782SZhu Yi if (sctp_add_backlog(sk, skb)) { 2595bc1d1b4Swangweidong bh_unlock_sock(sk); 26050b1a782SZhu Yi sctp_chunk_free(chunk); 26150b1a782SZhu Yi skb = NULL; /* sctp_chunk_free already freed the skb */ 26250b1a782SZhu Yi goto discard_release; 26350b1a782SZhu Yi } 26408e3baefSEric Dumazet __SCTP_INC_STATS(net, SCTP_MIB_IN_PKT_BACKLOG); 265ac0b0462SSridhar Samudrala } else { 26608e3baefSEric Dumazet __SCTP_INC_STATS(net, SCTP_MIB_IN_PKT_SOFTIRQ); 26761c9fed4SVladislav Yasevich sctp_inq_push(&chunk->rcvr->inqueue, chunk); 268ac0b0462SSridhar Samudrala } 2691da177e4SLinus Torvalds 2705bc1d1b4Swangweidong bh_unlock_sock(sk); 27161c9fed4SVladislav Yasevich 27261c9fed4SVladislav Yasevich /* Release the asoc/ep ref we took in the lookup calls. */ 273dae399d7SXin Long if (transport) 274dae399d7SXin Long sctp_transport_put(transport); 27561c9fed4SVladislav Yasevich else 27661c9fed4SVladislav Yasevich sctp_endpoint_put(ep); 2777a48f923SSridhar Samudrala 2782babf9daSHerbert Xu return 0; 2791da177e4SLinus Torvalds 2801da177e4SLinus Torvalds discard_it: 28108e3baefSEric Dumazet __SCTP_INC_STATS(net, SCTP_MIB_IN_PKT_DISCARDS); 2821da177e4SLinus Torvalds kfree_skb(skb); 2832babf9daSHerbert Xu return 0; 2841da177e4SLinus Torvalds 2851da177e4SLinus Torvalds discard_release: 28661c9fed4SVladislav Yasevich /* Release the asoc/ep ref we took in the lookup calls. */ 287dae399d7SXin Long if (transport) 288dae399d7SXin Long sctp_transport_put(transport); 2890fd9a65aSNeil Horman else 2901da177e4SLinus Torvalds sctp_endpoint_put(ep); 2911da177e4SLinus Torvalds 2921da177e4SLinus Torvalds goto discard_it; 2931da177e4SLinus Torvalds } 2941da177e4SLinus Torvalds 29561c9fed4SVladislav Yasevich /* Process the backlog queue of the socket. Every skb on 29661c9fed4SVladislav Yasevich * the backlog holds a ref on an association or endpoint. 29761c9fed4SVladislav Yasevich * We hold this ref throughout the state machine to make 29861c9fed4SVladislav Yasevich * sure that the structure we need is still around. 2991da177e4SLinus Torvalds */ 3001da177e4SLinus Torvalds int sctp_backlog_rcv(struct sock *sk, struct sk_buff *skb) 3011da177e4SLinus Torvalds { 30279af02c2SDavid S. Miller struct sctp_chunk *chunk = SCTP_INPUT_CB(skb)->chunk; 30361c9fed4SVladislav Yasevich struct sctp_inq *inqueue = &chunk->rcvr->inqueue; 304dae399d7SXin Long struct sctp_transport *t = chunk->transport; 3057a48f923SSridhar Samudrala struct sctp_ep_common *rcvr = NULL; 30661c9fed4SVladislav Yasevich int backloged = 0; 3071da177e4SLinus Torvalds 3087a48f923SSridhar Samudrala rcvr = chunk->rcvr; 309c4d2444eSSridhar Samudrala 31061c9fed4SVladislav Yasevich /* If the rcvr is dead then the association or endpoint 31161c9fed4SVladislav Yasevich * has been deleted and we can safely drop the chunk 31261c9fed4SVladislav Yasevich * and refs that we are holding. 31361c9fed4SVladislav Yasevich */ 3147a48f923SSridhar Samudrala if (rcvr->dead) { 3157a48f923SSridhar Samudrala sctp_chunk_free(chunk); 31661c9fed4SVladislav Yasevich goto done; 31761c9fed4SVladislav Yasevich } 31861c9fed4SVladislav Yasevich 31961c9fed4SVladislav Yasevich if (unlikely(rcvr->sk != sk)) { 32061c9fed4SVladislav Yasevich /* In this case, the association moved from one socket to 32161c9fed4SVladislav Yasevich * another. We are currently sitting on the backlog of the 32261c9fed4SVladislav Yasevich * old socket, so we need to move. 32361c9fed4SVladislav Yasevich * However, since we are here in the process context we 32461c9fed4SVladislav Yasevich * need to take make sure that the user doesn't own 32561c9fed4SVladislav Yasevich * the new socket when we process the packet. 32661c9fed4SVladislav Yasevich * If the new socket is user-owned, queue the chunk to the 32761c9fed4SVladislav Yasevich * backlog of the new socket without dropping any refs. 32861c9fed4SVladislav Yasevich * Otherwise, we can safely push the chunk on the inqueue. 32961c9fed4SVladislav Yasevich */ 33061c9fed4SVladislav Yasevich 33161c9fed4SVladislav Yasevich sk = rcvr->sk; 332eefc1b1dSMarcelo Ricardo Leitner local_bh_disable(); 3335bc1d1b4Swangweidong bh_lock_sock(sk); 33461c9fed4SVladislav Yasevich 33561c9fed4SVladislav Yasevich if (sock_owned_by_user(sk)) { 336f545a38fSEric Dumazet if (sk_add_backlog(sk, skb, sk->sk_rcvbuf)) 33750b1a782SZhu Yi sctp_chunk_free(chunk); 33850b1a782SZhu Yi else 33961c9fed4SVladislav Yasevich backloged = 1; 34061c9fed4SVladislav Yasevich } else 34161c9fed4SVladislav Yasevich sctp_inq_push(inqueue, chunk); 34261c9fed4SVladislav Yasevich 3435bc1d1b4Swangweidong bh_unlock_sock(sk); 344eefc1b1dSMarcelo Ricardo Leitner local_bh_enable(); 34561c9fed4SVladislav Yasevich 34661c9fed4SVladislav Yasevich /* If the chunk was backloged again, don't drop refs */ 34761c9fed4SVladislav Yasevich if (backloged) 34861c9fed4SVladislav Yasevich return 0; 3497a48f923SSridhar Samudrala } else { 3501da177e4SLinus Torvalds sctp_inq_push(inqueue, chunk); 3517a48f923SSridhar Samudrala } 3527a48f923SSridhar Samudrala 35361c9fed4SVladislav Yasevich done: 35461c9fed4SVladislav Yasevich /* Release the refs we took in sctp_add_backlog */ 3557a48f923SSridhar Samudrala if (SCTP_EP_TYPE_ASSOCIATION == rcvr->type) 356dae399d7SXin Long sctp_transport_put(t); 35761c9fed4SVladislav Yasevich else if (SCTP_EP_TYPE_SOCKET == rcvr->type) 3587a48f923SSridhar Samudrala sctp_endpoint_put(sctp_ep(rcvr)); 35961c9fed4SVladislav Yasevich else 36061c9fed4SVladislav Yasevich BUG(); 3617a48f923SSridhar Samudrala 3621da177e4SLinus Torvalds return 0; 3631da177e4SLinus Torvalds } 3641da177e4SLinus Torvalds 36550b1a782SZhu Yi static int sctp_add_backlog(struct sock *sk, struct sk_buff *skb) 366c4d2444eSSridhar Samudrala { 36761c9fed4SVladislav Yasevich struct sctp_chunk *chunk = SCTP_INPUT_CB(skb)->chunk; 368dae399d7SXin Long struct sctp_transport *t = chunk->transport; 36961c9fed4SVladislav Yasevich struct sctp_ep_common *rcvr = chunk->rcvr; 37050b1a782SZhu Yi int ret; 371c4d2444eSSridhar Samudrala 372f545a38fSEric Dumazet ret = sk_add_backlog(sk, skb, sk->sk_rcvbuf); 37350b1a782SZhu Yi if (!ret) { 37461c9fed4SVladislav Yasevich /* Hold the assoc/ep while hanging on the backlog queue. 37550b1a782SZhu Yi * This way, we know structures we need will not disappear 37650b1a782SZhu Yi * from us 37761c9fed4SVladislav Yasevich */ 37861c9fed4SVladislav Yasevich if (SCTP_EP_TYPE_ASSOCIATION == rcvr->type) 379dae399d7SXin Long sctp_transport_hold(t); 38061c9fed4SVladislav Yasevich else if (SCTP_EP_TYPE_SOCKET == rcvr->type) 38161c9fed4SVladislav Yasevich sctp_endpoint_hold(sctp_ep(rcvr)); 382c4d2444eSSridhar Samudrala else 38361c9fed4SVladislav Yasevich BUG(); 38450b1a782SZhu Yi } 38550b1a782SZhu Yi return ret; 38661c9fed4SVladislav Yasevich 387c4d2444eSSridhar Samudrala } 388c4d2444eSSridhar Samudrala 3891da177e4SLinus Torvalds /* Handle icmp frag needed error. */ 3901da177e4SLinus Torvalds void sctp_icmp_frag_needed(struct sock *sk, struct sctp_association *asoc, 3911da177e4SLinus Torvalds struct sctp_transport *t, __u32 pmtu) 3921da177e4SLinus Torvalds { 39391bd6b1eSWei Yongjun if (!t || (t->pathmtu <= pmtu)) 39452ccb8e9SFrank Filz return; 39552ccb8e9SFrank Filz 3968a479491SVlad Yasevich if (sock_owned_by_user(sk)) { 3978a479491SVlad Yasevich asoc->pmtu_pending = 1; 3988a479491SVlad Yasevich t->pmtu_pending = 1; 3998a479491SVlad Yasevich return; 4008a479491SVlad Yasevich } 4018a479491SVlad Yasevich 40252ccb8e9SFrank Filz if (t->param_flags & SPP_PMTUD_ENABLE) { 403c910b47eSVlad Yasevich /* Update transports view of the MTU */ 4043ebfdf08SXin Long sctp_transport_update_pmtu(t, pmtu); 4051da177e4SLinus Torvalds 40652ccb8e9SFrank Filz /* Update association pmtu. */ 4073ebfdf08SXin Long sctp_assoc_sync_pmtu(asoc); 4081da177e4SLinus Torvalds } 40952ccb8e9SFrank Filz 41052ccb8e9SFrank Filz /* Retransmit with the new pmtu setting. 41152ccb8e9SFrank Filz * Normally, if PMTU discovery is disabled, an ICMP Fragmentation 41252ccb8e9SFrank Filz * Needed will never be sent, but if a message was sent before 41352ccb8e9SFrank Filz * PMTU discovery was disabled that was larger than the PMTU, it 41452ccb8e9SFrank Filz * would not be fragmented, so it must be re-transmitted fragmented. 41552ccb8e9SFrank Filz */ 41652ccb8e9SFrank Filz sctp_retransmit(&asoc->outqueue, t, SCTP_RTXR_PMTUD); 4171da177e4SLinus Torvalds } 4181da177e4SLinus Torvalds 419ec18d9a2SDavid S. Miller void sctp_icmp_redirect(struct sock *sk, struct sctp_transport *t, 42055be7a9cSDavid S. Miller struct sk_buff *skb) 42155be7a9cSDavid S. Miller { 42255be7a9cSDavid S. Miller struct dst_entry *dst; 42355be7a9cSDavid S. Miller 4241cc276ceSXin Long if (sock_owned_by_user(sk) || !t) 42555be7a9cSDavid S. Miller return; 42655be7a9cSDavid S. Miller dst = sctp_transport_dst_check(t); 4271ed5c48fSDavid S. Miller if (dst) 4286700c270SDavid S. Miller dst->ops->redirect(dst, sk, skb); 42955be7a9cSDavid S. Miller } 43055be7a9cSDavid S. Miller 4311da177e4SLinus Torvalds /* 4321da177e4SLinus Torvalds * SCTP Implementer's Guide, 2.37 ICMP handling procedures 4331da177e4SLinus Torvalds * 4341da177e4SLinus Torvalds * ICMP8) If the ICMP code is a "Unrecognized next header type encountered" 4351da177e4SLinus Torvalds * or a "Protocol Unreachable" treat this message as an abort 4361da177e4SLinus Torvalds * with the T bit set. 4371da177e4SLinus Torvalds * 4381da177e4SLinus Torvalds * This function sends an event to the state machine, which will abort the 4391da177e4SLinus Torvalds * association. 4401da177e4SLinus Torvalds * 4411da177e4SLinus Torvalds */ 4421da177e4SLinus Torvalds void sctp_icmp_proto_unreachable(struct sock *sk, 4431da177e4SLinus Torvalds struct sctp_association *asoc, 4441da177e4SLinus Torvalds struct sctp_transport *t) 4451da177e4SLinus Torvalds { 44650b5d6adSVlad Yasevich if (sock_owned_by_user(sk)) { 44750b5d6adSVlad Yasevich if (timer_pending(&t->proto_unreach_timer)) 44850b5d6adSVlad Yasevich return; 44950b5d6adSVlad Yasevich else { 45050b5d6adSVlad Yasevich if (!mod_timer(&t->proto_unreach_timer, 45150b5d6adSVlad Yasevich jiffies + (HZ/20))) 45250b5d6adSVlad Yasevich sctp_association_hold(asoc); 45350b5d6adSVlad Yasevich } 45450b5d6adSVlad Yasevich } else { 45555e26eb9SEric W. Biederman struct net *net = sock_net(sk); 45655e26eb9SEric W. Biederman 457bb33381dSDaniel Borkmann pr_debug("%s: unrecognized next header type " 458bb33381dSDaniel Borkmann "encountered!\n", __func__); 459bb33381dSDaniel Borkmann 46025cc4ae9SYing Xue if (del_timer(&t->proto_unreach_timer)) 46150b5d6adSVlad Yasevich sctp_association_put(asoc); 46250b5d6adSVlad Yasevich 46355e26eb9SEric W. Biederman sctp_do_sm(net, SCTP_EVENT_T_OTHER, 4641da177e4SLinus Torvalds SCTP_ST_OTHER(SCTP_EVENT_ICMP_PROTO_UNREACH), 4653f7a87d2SFrank Filz asoc->state, asoc->ep, asoc, t, 4661da177e4SLinus Torvalds GFP_ATOMIC); 46750b5d6adSVlad Yasevich } 4681da177e4SLinus Torvalds } 4691da177e4SLinus Torvalds 4701da177e4SLinus Torvalds /* Common lookup code for icmp/icmpv6 error handler. */ 4714110cc25SEric W. Biederman struct sock *sctp_err_lookup(struct net *net, int family, struct sk_buff *skb, 4721da177e4SLinus Torvalds struct sctphdr *sctphdr, 4731da177e4SLinus Torvalds struct sctp_association **app, 4741da177e4SLinus Torvalds struct sctp_transport **tpp) 4751da177e4SLinus Torvalds { 476804ec7ebSDavide Caratti struct sctp_init_chunk *chunkhdr, _chunkhdr; 4771da177e4SLinus Torvalds union sctp_addr saddr; 4781da177e4SLinus Torvalds union sctp_addr daddr; 4791da177e4SLinus Torvalds struct sctp_af *af; 4801da177e4SLinus Torvalds struct sock *sk = NULL; 4818de8c873SSridhar Samudrala struct sctp_association *asoc; 4821da177e4SLinus Torvalds struct sctp_transport *transport = NULL; 4837115e632SWei Yongjun __u32 vtag = ntohl(sctphdr->vtag); 4841da177e4SLinus Torvalds 485d1ad1ff2SSridhar Samudrala *app = NULL; *tpp = NULL; 4861da177e4SLinus Torvalds 4871da177e4SLinus Torvalds af = sctp_get_af_specific(family); 4881da177e4SLinus Torvalds if (unlikely(!af)) { 4891da177e4SLinus Torvalds return NULL; 4901da177e4SLinus Torvalds } 4911da177e4SLinus Torvalds 4921da177e4SLinus Torvalds /* Initialize local addresses for lookups. */ 4931da177e4SLinus Torvalds af->from_skb(&saddr, skb, 1); 4941da177e4SLinus Torvalds af->from_skb(&daddr, skb, 0); 4951da177e4SLinus Torvalds 4961da177e4SLinus Torvalds /* Look for an association that matches the incoming ICMP error 4971da177e4SLinus Torvalds * packet. 4981da177e4SLinus Torvalds */ 4994110cc25SEric W. Biederman asoc = __sctp_lookup_association(net, &saddr, &daddr, &transport); 500d1ad1ff2SSridhar Samudrala if (!asoc) 5011da177e4SLinus Torvalds return NULL; 5021da177e4SLinus Torvalds 5031da177e4SLinus Torvalds sk = asoc->base.sk; 5041da177e4SLinus Torvalds 5057115e632SWei Yongjun /* RFC 4960, Appendix C. ICMP Handling 5067115e632SWei Yongjun * 5077115e632SWei Yongjun * ICMP6) An implementation MUST validate that the Verification Tag 5087115e632SWei Yongjun * contained in the ICMP message matches the Verification Tag of 5097115e632SWei Yongjun * the peer. If the Verification Tag is not 0 and does NOT 5107115e632SWei Yongjun * match, discard the ICMP message. If it is 0 and the ICMP 5117115e632SWei Yongjun * message contains enough bytes to verify that the chunk type is 5127115e632SWei Yongjun * an INIT chunk and that the Initiate Tag matches the tag of the 5137115e632SWei Yongjun * peer, continue with ICMP7. If the ICMP message is too short 5147115e632SWei Yongjun * or the chunk type or the Initiate Tag does not match, silently 5157115e632SWei Yongjun * discard the packet. 5167115e632SWei Yongjun */ 5177115e632SWei Yongjun if (vtag == 0) { 518804ec7ebSDavide Caratti /* chunk header + first 4 octects of init header */ 519804ec7ebSDavide Caratti chunkhdr = skb_header_pointer(skb, skb_transport_offset(skb) + 520804ec7ebSDavide Caratti sizeof(struct sctphdr), 521804ec7ebSDavide Caratti sizeof(struct sctp_chunkhdr) + 522804ec7ebSDavide Caratti sizeof(__be32), &_chunkhdr); 523804ec7ebSDavide Caratti if (!chunkhdr || 5247115e632SWei Yongjun chunkhdr->chunk_hdr.type != SCTP_CID_INIT || 525804ec7ebSDavide Caratti ntohl(chunkhdr->init_hdr.init_tag) != asoc->c.my_vtag) 5267115e632SWei Yongjun goto out; 527804ec7ebSDavide Caratti 5287115e632SWei Yongjun } else if (vtag != asoc->c.peer_vtag) { 5291da177e4SLinus Torvalds goto out; 5301da177e4SLinus Torvalds } 5311da177e4SLinus Torvalds 5325bc1d1b4Swangweidong bh_lock_sock(sk); 5331da177e4SLinus Torvalds 5341da177e4SLinus Torvalds /* If too many ICMPs get dropped on busy 5351da177e4SLinus Torvalds * servers this needs to be solved differently. 5361da177e4SLinus Torvalds */ 5371da177e4SLinus Torvalds if (sock_owned_by_user(sk)) 53802a1d6e7SEric Dumazet __NET_INC_STATS(net, LINUX_MIB_LOCKDROPPEDICMPS); 5391da177e4SLinus Torvalds 5401da177e4SLinus Torvalds *app = asoc; 5411da177e4SLinus Torvalds *tpp = transport; 5421da177e4SLinus Torvalds return sk; 5431da177e4SLinus Torvalds 5441da177e4SLinus Torvalds out: 545dae399d7SXin Long sctp_transport_put(transport); 5461da177e4SLinus Torvalds return NULL; 5471da177e4SLinus Torvalds } 5481da177e4SLinus Torvalds 5491da177e4SLinus Torvalds /* Common cleanup code for icmp/icmpv6 error handler. */ 550dae399d7SXin Long void sctp_err_finish(struct sock *sk, struct sctp_transport *t) 5511da177e4SLinus Torvalds { 5525bc1d1b4Swangweidong bh_unlock_sock(sk); 553dae399d7SXin Long sctp_transport_put(t); 5541da177e4SLinus Torvalds } 5551da177e4SLinus Torvalds 5561da177e4SLinus Torvalds /* 5571da177e4SLinus Torvalds * This routine is called by the ICMP module when it gets some 5581da177e4SLinus Torvalds * sort of error condition. If err < 0 then the socket should 5591da177e4SLinus Torvalds * be closed and the error returned to the user. If err > 0 5601da177e4SLinus Torvalds * it's just the icmp type << 8 | icmp code. After adjustment 5611da177e4SLinus Torvalds * header points to the first 8 bytes of the sctp header. We need 5621da177e4SLinus Torvalds * to find the appropriate port. 5631da177e4SLinus Torvalds * 5641da177e4SLinus Torvalds * The locking strategy used here is very "optimistic". When 5651da177e4SLinus Torvalds * someone else accesses the socket the ICMP is just dropped 5661da177e4SLinus Torvalds * and for some paths there is no check at all. 5671da177e4SLinus Torvalds * A more general error queue to queue errors for later handling 5681da177e4SLinus Torvalds * is probably better. 5691da177e4SLinus Torvalds * 5701da177e4SLinus Torvalds */ 5711da177e4SLinus Torvalds void sctp_v4_err(struct sk_buff *skb, __u32 info) 5721da177e4SLinus Torvalds { 573b71d1d42SEric Dumazet const struct iphdr *iph = (const struct iphdr *)skb->data; 574a27ef749SArnaldo Carvalho de Melo const int ihlen = iph->ihl * 4; 57588c7664fSArnaldo Carvalho de Melo const int type = icmp_hdr(skb)->type; 57688c7664fSArnaldo Carvalho de Melo const int code = icmp_hdr(skb)->code; 5771da177e4SLinus Torvalds struct sock *sk; 5788de8c873SSridhar Samudrala struct sctp_association *asoc = NULL; 5791da177e4SLinus Torvalds struct sctp_transport *transport; 5801da177e4SLinus Torvalds struct inet_sock *inet; 581aef6de51SSimon Horman __u16 saveip, savesctp; 5821da177e4SLinus Torvalds int err; 5834110cc25SEric W. Biederman struct net *net = dev_net(skb->dev); 5841da177e4SLinus Torvalds 5851da177e4SLinus Torvalds /* Fix up skb to look at the embedded net header. */ 586b0e380b1SArnaldo Carvalho de Melo saveip = skb->network_header; 587b0e380b1SArnaldo Carvalho de Melo savesctp = skb->transport_header; 58831c7711bSArnaldo Carvalho de Melo skb_reset_network_header(skb); 589a27ef749SArnaldo Carvalho de Melo skb_set_transport_header(skb, ihlen); 5904110cc25SEric W. Biederman sk = sctp_err_lookup(net, AF_INET, skb, sctp_hdr(skb), &asoc, &transport); 5912e07fa9cSArnaldo Carvalho de Melo /* Put back, the original values. */ 592b0e380b1SArnaldo Carvalho de Melo skb->network_header = saveip; 593b0e380b1SArnaldo Carvalho de Melo skb->transport_header = savesctp; 5941da177e4SLinus Torvalds if (!sk) { 5955d3848bcSEric Dumazet __ICMP_INC_STATS(net, ICMP_MIB_INERRORS); 5961da177e4SLinus Torvalds return; 5971da177e4SLinus Torvalds } 5981da177e4SLinus Torvalds /* Warning: The sock lock is held. Remember to call 5991da177e4SLinus Torvalds * sctp_err_finish! 6001da177e4SLinus Torvalds */ 6011da177e4SLinus Torvalds 6021da177e4SLinus Torvalds switch (type) { 6031da177e4SLinus Torvalds case ICMP_PARAMETERPROB: 6041da177e4SLinus Torvalds err = EPROTO; 6051da177e4SLinus Torvalds break; 6061da177e4SLinus Torvalds case ICMP_DEST_UNREACH: 6071da177e4SLinus Torvalds if (code > NR_ICMP_UNREACH) 6081da177e4SLinus Torvalds goto out_unlock; 6091da177e4SLinus Torvalds 6101da177e4SLinus Torvalds /* PMTU discovery (RFC1191) */ 6111da177e4SLinus Torvalds if (ICMP_FRAG_NEEDED == code) { 6123822a5ffSMarcelo Ricardo Leitner sctp_icmp_frag_needed(sk, asoc, transport, 613e2f036a9SMarcelo Ricardo Leitner SCTP_TRUNC4(info)); 6141da177e4SLinus Torvalds goto out_unlock; 6158d72651dSwangweidong } else { 6161da177e4SLinus Torvalds if (ICMP_PROT_UNREACH == code) { 617d1ad1ff2SSridhar Samudrala sctp_icmp_proto_unreachable(sk, asoc, 6181da177e4SLinus Torvalds transport); 6191da177e4SLinus Torvalds goto out_unlock; 6201da177e4SLinus Torvalds } 6211da177e4SLinus Torvalds } 6221da177e4SLinus Torvalds err = icmp_err_convert[code].errno; 6231da177e4SLinus Torvalds break; 6241da177e4SLinus Torvalds case ICMP_TIME_EXCEEDED: 6251da177e4SLinus Torvalds /* Ignore any time exceeded errors due to fragment reassembly 6261da177e4SLinus Torvalds * timeouts. 6271da177e4SLinus Torvalds */ 6281da177e4SLinus Torvalds if (ICMP_EXC_FRAGTIME == code) 6291da177e4SLinus Torvalds goto out_unlock; 6301da177e4SLinus Torvalds 6311da177e4SLinus Torvalds err = EHOSTUNREACH; 6321da177e4SLinus Torvalds break; 63355be7a9cSDavid S. Miller case ICMP_REDIRECT: 63455be7a9cSDavid S. Miller sctp_icmp_redirect(sk, transport, skb); 6353f96a532SDaniel Borkmann /* Fall through to out_unlock. */ 6361da177e4SLinus Torvalds default: 6371da177e4SLinus Torvalds goto out_unlock; 6381da177e4SLinus Torvalds } 6391da177e4SLinus Torvalds 6401da177e4SLinus Torvalds inet = inet_sk(sk); 6411da177e4SLinus Torvalds if (!sock_owned_by_user(sk) && inet->recverr) { 6421da177e4SLinus Torvalds sk->sk_err = err; 6431da177e4SLinus Torvalds sk->sk_error_report(sk); 6441da177e4SLinus Torvalds } else { /* Only an error on timeout */ 6451da177e4SLinus Torvalds sk->sk_err_soft = err; 6461da177e4SLinus Torvalds } 6471da177e4SLinus Torvalds 6481da177e4SLinus Torvalds out_unlock: 649dae399d7SXin Long sctp_err_finish(sk, transport); 6501da177e4SLinus Torvalds } 6511da177e4SLinus Torvalds 6521da177e4SLinus Torvalds /* 6531da177e4SLinus Torvalds * RFC 2960, 8.4 - Handle "Out of the blue" Packets. 6541da177e4SLinus Torvalds * 6551da177e4SLinus Torvalds * This function scans all the chunks in the OOTB packet to determine if 6561da177e4SLinus Torvalds * the packet should be discarded right away. If a response might be needed 6571da177e4SLinus Torvalds * for this packet, or, if further processing is possible, the packet will 6581da177e4SLinus Torvalds * be queued to a proper inqueue for the next phase of handling. 6591da177e4SLinus Torvalds * 6601da177e4SLinus Torvalds * Output: 6611da177e4SLinus Torvalds * Return 0 - If further processing is needed. 6621da177e4SLinus Torvalds * Return 1 - If the packet can be discarded right away. 6631da177e4SLinus Torvalds */ 66404675210Ssebastian@breakpoint.cc static int sctp_rcv_ootb(struct sk_buff *skb) 6651da177e4SLinus Torvalds { 666922dbc5bSXin Long struct sctp_chunkhdr *ch, _ch; 6673acb50c1SMarcelo Ricardo Leitner int ch_end, offset = 0; 6681da177e4SLinus Torvalds 6691da177e4SLinus Torvalds /* Scan through all the chunks in the packet. */ 670a7d1f1b6STsutomu Fujii do { 6713acb50c1SMarcelo Ricardo Leitner /* Make sure we have at least the header there */ 672922dbc5bSXin Long if (offset + sizeof(_ch) > skb->len) 6733acb50c1SMarcelo Ricardo Leitner break; 6743acb50c1SMarcelo Ricardo Leitner 6753acb50c1SMarcelo Ricardo Leitner ch = skb_header_pointer(skb, offset, sizeof(*ch), &_ch); 6763acb50c1SMarcelo Ricardo Leitner 677a7d1f1b6STsutomu Fujii /* Break out if chunk length is less then minimal. */ 678922dbc5bSXin Long if (ntohs(ch->length) < sizeof(_ch)) 679a7d1f1b6STsutomu Fujii break; 680a7d1f1b6STsutomu Fujii 681e2f036a9SMarcelo Ricardo Leitner ch_end = offset + SCTP_PAD4(ntohs(ch->length)); 6823acb50c1SMarcelo Ricardo Leitner if (ch_end > skb->len) 683a7d1f1b6STsutomu Fujii break; 6841da177e4SLinus Torvalds 6851da177e4SLinus Torvalds /* RFC 8.4, 2) If the OOTB packet contains an ABORT chunk, the 6861da177e4SLinus Torvalds * receiver MUST silently discard the OOTB packet and take no 6871da177e4SLinus Torvalds * further action. 6881da177e4SLinus Torvalds */ 6891da177e4SLinus Torvalds if (SCTP_CID_ABORT == ch->type) 6901da177e4SLinus Torvalds goto discard; 6911da177e4SLinus Torvalds 6921da177e4SLinus Torvalds /* RFC 8.4, 6) If the packet contains a SHUTDOWN COMPLETE 6931da177e4SLinus Torvalds * chunk, the receiver should silently discard the packet 6941da177e4SLinus Torvalds * and take no further action. 6951da177e4SLinus Torvalds */ 6961da177e4SLinus Torvalds if (SCTP_CID_SHUTDOWN_COMPLETE == ch->type) 6971da177e4SLinus Torvalds goto discard; 6981da177e4SLinus Torvalds 6993c77f961SVlad Yasevich /* RFC 4460, 2.11.2 7003c77f961SVlad Yasevich * This will discard packets with INIT chunk bundled as 7013c77f961SVlad Yasevich * subsequent chunks in the packet. When INIT is first, 7023c77f961SVlad Yasevich * the normal INIT processing will discard the chunk. 7033c77f961SVlad Yasevich */ 7043c77f961SVlad Yasevich if (SCTP_CID_INIT == ch->type && (void *)ch != skb->data) 7053c77f961SVlad Yasevich goto discard; 7063c77f961SVlad Yasevich 7073acb50c1SMarcelo Ricardo Leitner offset = ch_end; 7083acb50c1SMarcelo Ricardo Leitner } while (ch_end < skb->len); 7091da177e4SLinus Torvalds 7101da177e4SLinus Torvalds return 0; 7111da177e4SLinus Torvalds 7121da177e4SLinus Torvalds discard: 7131da177e4SLinus Torvalds return 1; 7141da177e4SLinus Torvalds } 7151da177e4SLinus Torvalds 7161da177e4SLinus Torvalds /* Insert endpoint into the hash table. */ 7171da177e4SLinus Torvalds static void __sctp_hash_endpoint(struct sctp_endpoint *ep) 7181da177e4SLinus Torvalds { 7194cdadcbcSEric W. Biederman struct net *net = sock_net(ep->base.sk); 7201da177e4SLinus Torvalds struct sctp_ep_common *epb; 7211da177e4SLinus Torvalds struct sctp_hashbucket *head; 7221da177e4SLinus Torvalds 7231da177e4SLinus Torvalds epb = &ep->base; 7241da177e4SLinus Torvalds 7254cdadcbcSEric W. Biederman epb->hashent = sctp_ep_hashfn(net, epb->bind_addr.port); 7261da177e4SLinus Torvalds head = &sctp_ep_hashtable[epb->hashent]; 7271da177e4SLinus Torvalds 728387602dfSwangweidong write_lock(&head->lock); 729d970dbf8SVlad Yasevich hlist_add_head(&epb->node, &head->chain); 730387602dfSwangweidong write_unlock(&head->lock); 7311da177e4SLinus Torvalds } 7321da177e4SLinus Torvalds 7331da177e4SLinus Torvalds /* Add an endpoint to the hash. Local BH-safe. */ 7341da177e4SLinus Torvalds void sctp_hash_endpoint(struct sctp_endpoint *ep) 7351da177e4SLinus Torvalds { 73679b91130Swangweidong local_bh_disable(); 7371da177e4SLinus Torvalds __sctp_hash_endpoint(ep); 73879b91130Swangweidong local_bh_enable(); 7391da177e4SLinus Torvalds } 7401da177e4SLinus Torvalds 7411da177e4SLinus Torvalds /* Remove endpoint from the hash table. */ 7421da177e4SLinus Torvalds static void __sctp_unhash_endpoint(struct sctp_endpoint *ep) 7431da177e4SLinus Torvalds { 7444cdadcbcSEric W. Biederman struct net *net = sock_net(ep->base.sk); 7451da177e4SLinus Torvalds struct sctp_hashbucket *head; 7461da177e4SLinus Torvalds struct sctp_ep_common *epb; 7471da177e4SLinus Torvalds 7481da177e4SLinus Torvalds epb = &ep->base; 7491da177e4SLinus Torvalds 7504cdadcbcSEric W. Biederman epb->hashent = sctp_ep_hashfn(net, epb->bind_addr.port); 7511da177e4SLinus Torvalds 7521da177e4SLinus Torvalds head = &sctp_ep_hashtable[epb->hashent]; 7531da177e4SLinus Torvalds 754387602dfSwangweidong write_lock(&head->lock); 7552eebc1e1SNeil Horman hlist_del_init(&epb->node); 756387602dfSwangweidong write_unlock(&head->lock); 7571da177e4SLinus Torvalds } 7581da177e4SLinus Torvalds 7591da177e4SLinus Torvalds /* Remove endpoint from the hash. Local BH-safe. */ 7601da177e4SLinus Torvalds void sctp_unhash_endpoint(struct sctp_endpoint *ep) 7611da177e4SLinus Torvalds { 76279b91130Swangweidong local_bh_disable(); 7631da177e4SLinus Torvalds __sctp_unhash_endpoint(ep); 76479b91130Swangweidong local_bh_enable(); 7651da177e4SLinus Torvalds } 7661da177e4SLinus Torvalds 7671da177e4SLinus Torvalds /* Look up an endpoint. */ 7684cdadcbcSEric W. Biederman static struct sctp_endpoint *__sctp_rcv_lookup_endpoint(struct net *net, 7694cdadcbcSEric W. Biederman const union sctp_addr *laddr) 7701da177e4SLinus Torvalds { 7711da177e4SLinus Torvalds struct sctp_hashbucket *head; 7721da177e4SLinus Torvalds struct sctp_ep_common *epb; 7731da177e4SLinus Torvalds struct sctp_endpoint *ep; 7741da177e4SLinus Torvalds int hash; 7751da177e4SLinus Torvalds 7764cdadcbcSEric W. Biederman hash = sctp_ep_hashfn(net, ntohs(laddr->v4.sin_port)); 7771da177e4SLinus Torvalds head = &sctp_ep_hashtable[hash]; 7781da177e4SLinus Torvalds read_lock(&head->lock); 779b67bfe0dSSasha Levin sctp_for_each_hentry(epb, &head->chain) { 7801da177e4SLinus Torvalds ep = sctp_ep(epb); 7814cdadcbcSEric W. Biederman if (sctp_endpoint_is_match(ep, net, laddr)) 7821da177e4SLinus Torvalds goto hit; 7831da177e4SLinus Torvalds } 7841da177e4SLinus Torvalds 7852ce95503SEric W. Biederman ep = sctp_sk(net->sctp.ctl_sock)->ep; 7861da177e4SLinus Torvalds 7871da177e4SLinus Torvalds hit: 7881da177e4SLinus Torvalds sctp_endpoint_hold(ep); 7891da177e4SLinus Torvalds read_unlock(&head->lock); 7901da177e4SLinus Torvalds return ep; 7911da177e4SLinus Torvalds } 7921da177e4SLinus Torvalds 793d6c0256aSXin Long /* rhashtable for transport */ 794d6c0256aSXin Long struct sctp_hash_cmp_arg { 795d6c0256aSXin Long const union sctp_addr *paddr; 796d6c0256aSXin Long const struct net *net; 797*8d32503eSXin Long __be16 lport; 798d6c0256aSXin Long }; 799d6c0256aSXin Long 800d6c0256aSXin Long static inline int sctp_hash_cmp(struct rhashtable_compare_arg *arg, 801d6c0256aSXin Long const void *ptr) 802d6c0256aSXin Long { 803715f5552SXin Long struct sctp_transport *t = (struct sctp_transport *)ptr; 804d6c0256aSXin Long const struct sctp_hash_cmp_arg *x = arg->key; 805715f5552SXin Long int err = 1; 806d6c0256aSXin Long 807d6c0256aSXin Long if (!sctp_cmp_addr_exact(&t->ipaddr, x->paddr)) 808715f5552SXin Long return err; 809715f5552SXin Long if (!sctp_transport_hold(t)) 810715f5552SXin Long return err; 811715f5552SXin Long 8127fda702fSXin Long if (!net_eq(sock_net(t->asoc->base.sk), x->net)) 813715f5552SXin Long goto out; 8147fda702fSXin Long if (x->lport != htons(t->asoc->base.bind_addr.port)) 815715f5552SXin Long goto out; 816d6c0256aSXin Long 817715f5552SXin Long err = 0; 818715f5552SXin Long out: 819715f5552SXin Long sctp_transport_put(t); 820715f5552SXin Long return err; 821d6c0256aSXin Long } 822d6c0256aSXin Long 823*8d32503eSXin Long static inline __u32 sctp_hash_obj(const void *data, u32 len, u32 seed) 824d6c0256aSXin Long { 825d6c0256aSXin Long const struct sctp_transport *t = data; 826d6c0256aSXin Long const union sctp_addr *paddr = &t->ipaddr; 827d6c0256aSXin Long const struct net *net = sock_net(t->asoc->base.sk); 828*8d32503eSXin Long __be16 lport = htons(t->asoc->base.bind_addr.port); 829*8d32503eSXin Long __u32 addr; 830d6c0256aSXin Long 831d6c0256aSXin Long if (paddr->sa.sa_family == AF_INET6) 832d6c0256aSXin Long addr = jhash(&paddr->v6.sin6_addr, 16, seed); 833d6c0256aSXin Long else 834*8d32503eSXin Long addr = (__force __u32)paddr->v4.sin_addr.s_addr; 835d6c0256aSXin Long 836*8d32503eSXin Long return jhash_3words(addr, ((__force __u32)paddr->v4.sin_port) << 16 | 837d6c0256aSXin Long (__force __u32)lport, net_hash_mix(net), seed); 838d6c0256aSXin Long } 839d6c0256aSXin Long 840*8d32503eSXin Long static inline __u32 sctp_hash_key(const void *data, u32 len, u32 seed) 841d6c0256aSXin Long { 842d6c0256aSXin Long const struct sctp_hash_cmp_arg *x = data; 843d6c0256aSXin Long const union sctp_addr *paddr = x->paddr; 844d6c0256aSXin Long const struct net *net = x->net; 845*8d32503eSXin Long __be16 lport = x->lport; 846*8d32503eSXin Long __u32 addr; 847d6c0256aSXin Long 848d6c0256aSXin Long if (paddr->sa.sa_family == AF_INET6) 849d6c0256aSXin Long addr = jhash(&paddr->v6.sin6_addr, 16, seed); 850d6c0256aSXin Long else 851*8d32503eSXin Long addr = (__force __u32)paddr->v4.sin_addr.s_addr; 852d6c0256aSXin Long 853*8d32503eSXin Long return jhash_3words(addr, ((__force __u32)paddr->v4.sin_port) << 16 | 854d6c0256aSXin Long (__force __u32)lport, net_hash_mix(net), seed); 855d6c0256aSXin Long } 856d6c0256aSXin Long 857d6c0256aSXin Long static const struct rhashtable_params sctp_hash_params = { 858d6c0256aSXin Long .head_offset = offsetof(struct sctp_transport, node), 859d6c0256aSXin Long .hashfn = sctp_hash_key, 860d6c0256aSXin Long .obj_hashfn = sctp_hash_obj, 861d6c0256aSXin Long .obj_cmpfn = sctp_hash_cmp, 862d6c0256aSXin Long .automatic_shrinking = true, 863d6c0256aSXin Long }; 864d6c0256aSXin Long 865d6c0256aSXin Long int sctp_transport_hashtable_init(void) 866d6c0256aSXin Long { 8677fda702fSXin Long return rhltable_init(&sctp_transport_hashtable, &sctp_hash_params); 868d6c0256aSXin Long } 869d6c0256aSXin Long 870d6c0256aSXin Long void sctp_transport_hashtable_destroy(void) 871d6c0256aSXin Long { 8727fda702fSXin Long rhltable_destroy(&sctp_transport_hashtable); 873d6c0256aSXin Long } 874d6c0256aSXin Long 8757fda702fSXin Long int sctp_hash_transport(struct sctp_transport *t) 876d6c0256aSXin Long { 877cd2b7087SXin Long struct sctp_transport *transport; 878cd2b7087SXin Long struct rhlist_head *tmp, *list; 879d6c0256aSXin Long struct sctp_hash_cmp_arg arg; 8807fda702fSXin Long int err; 881d6c0256aSXin Long 882dd7445adSXin Long if (t->asoc->temp) 8837fda702fSXin Long return 0; 884dd7445adSXin Long 885d6c0256aSXin Long arg.net = sock_net(t->asoc->base.sk); 8867fda702fSXin Long arg.paddr = &t->ipaddr; 8877fda702fSXin Long arg.lport = htons(t->asoc->base.bind_addr.port); 888d6c0256aSXin Long 8895179b266SXin Long rcu_read_lock(); 890cd2b7087SXin Long list = rhltable_lookup(&sctp_transport_hashtable, &arg, 891cd2b7087SXin Long sctp_hash_params); 892cd2b7087SXin Long 893cd2b7087SXin Long rhl_for_each_entry_rcu(transport, tmp, list, node) 894cd2b7087SXin Long if (transport->asoc->ep == t->asoc->ep) { 8955179b266SXin Long rcu_read_unlock(); 896cd2b7087SXin Long err = -EEXIST; 897cd2b7087SXin Long goto out; 898cd2b7087SXin Long } 8995179b266SXin Long rcu_read_unlock(); 900cd2b7087SXin Long 9017fda702fSXin Long err = rhltable_insert_key(&sctp_transport_hashtable, &arg, 9027fda702fSXin Long &t->node, sctp_hash_params); 903cd2b7087SXin Long 904cd2b7087SXin Long out: 9057fda702fSXin Long if (err) 9067fda702fSXin Long pr_err_once("insert transport fail, errno %d\n", err); 9077fda702fSXin Long 9087fda702fSXin Long return err; 909d6c0256aSXin Long } 910d6c0256aSXin Long 911d6c0256aSXin Long void sctp_unhash_transport(struct sctp_transport *t) 912d6c0256aSXin Long { 913dd7445adSXin Long if (t->asoc->temp) 914dd7445adSXin Long return; 915dd7445adSXin Long 9167fda702fSXin Long rhltable_remove(&sctp_transport_hashtable, &t->node, 917d6c0256aSXin Long sctp_hash_params); 918d6c0256aSXin Long } 919d6c0256aSXin Long 9207fda702fSXin Long /* return a transport with holding it */ 921d6c0256aSXin Long struct sctp_transport *sctp_addrs_lookup_transport( 922d6c0256aSXin Long struct net *net, 923d6c0256aSXin Long const union sctp_addr *laddr, 924d6c0256aSXin Long const union sctp_addr *paddr) 925d6c0256aSXin Long { 9267fda702fSXin Long struct rhlist_head *tmp, *list; 9277fda702fSXin Long struct sctp_transport *t; 928d6c0256aSXin Long struct sctp_hash_cmp_arg arg = { 929d6c0256aSXin Long .paddr = paddr, 930d6c0256aSXin Long .net = net, 9317fda702fSXin Long .lport = laddr->v4.sin_port, 932d6c0256aSXin Long }; 933d6c0256aSXin Long 9347fda702fSXin Long list = rhltable_lookup(&sctp_transport_hashtable, &arg, 935d6c0256aSXin Long sctp_hash_params); 9367fda702fSXin Long 9377fda702fSXin Long rhl_for_each_entry_rcu(t, tmp, list, node) { 9387fda702fSXin Long if (!sctp_transport_hold(t)) 9397fda702fSXin Long continue; 9407fda702fSXin Long 9417fda702fSXin Long if (sctp_bind_addr_match(&t->asoc->base.bind_addr, 9427fda702fSXin Long laddr, sctp_sk(t->asoc->base.sk))) 9437fda702fSXin Long return t; 9447fda702fSXin Long sctp_transport_put(t); 945d6c0256aSXin Long } 946d6c0256aSXin Long 9477fda702fSXin Long return NULL; 9487fda702fSXin Long } 9497fda702fSXin Long 9507fda702fSXin Long /* return a transport without holding it, as it's only used under sock lock */ 951d6c0256aSXin Long struct sctp_transport *sctp_epaddr_lookup_transport( 952d6c0256aSXin Long const struct sctp_endpoint *ep, 953d6c0256aSXin Long const union sctp_addr *paddr) 954d6c0256aSXin Long { 955d6c0256aSXin Long struct net *net = sock_net(ep->base.sk); 9567fda702fSXin Long struct rhlist_head *tmp, *list; 9577fda702fSXin Long struct sctp_transport *t; 95865a5124aSXin Long struct sctp_hash_cmp_arg arg = { 95965a5124aSXin Long .paddr = paddr, 96065a5124aSXin Long .net = net, 9617fda702fSXin Long .lport = htons(ep->base.bind_addr.port), 96265a5124aSXin Long }; 963d6c0256aSXin Long 9647fda702fSXin Long list = rhltable_lookup(&sctp_transport_hashtable, &arg, 96565a5124aSXin Long sctp_hash_params); 9667fda702fSXin Long 9677fda702fSXin Long rhl_for_each_entry_rcu(t, tmp, list, node) 9687fda702fSXin Long if (ep == t->asoc->ep) 9697fda702fSXin Long return t; 9707fda702fSXin Long 9717fda702fSXin Long return NULL; 972d6c0256aSXin Long } 973d6c0256aSXin Long 9741da177e4SLinus Torvalds /* Look up an association. */ 9751da177e4SLinus Torvalds static struct sctp_association *__sctp_lookup_association( 9764110cc25SEric W. Biederman struct net *net, 9771da177e4SLinus Torvalds const union sctp_addr *local, 9781da177e4SLinus Torvalds const union sctp_addr *peer, 9791da177e4SLinus Torvalds struct sctp_transport **pt) 9801da177e4SLinus Torvalds { 9814f008781SXin Long struct sctp_transport *t; 9821eed6779SXin Long struct sctp_association *asoc = NULL; 9831da177e4SLinus Torvalds 9844f008781SXin Long t = sctp_addrs_lookup_transport(net, local, peer); 9857fda702fSXin Long if (!t) 9861eed6779SXin Long goto out; 9871da177e4SLinus Torvalds 9881eed6779SXin Long asoc = t->asoc; 9894f008781SXin Long *pt = t; 9904f008781SXin Long 9911eed6779SXin Long out: 9921eed6779SXin Long return asoc; 9931da177e4SLinus Torvalds } 9941da177e4SLinus Torvalds 9954f008781SXin Long /* Look up an association. protected by RCU read lock */ 996dda91928SDaniel Borkmann static 9974110cc25SEric W. Biederman struct sctp_association *sctp_lookup_association(struct net *net, 9984110cc25SEric W. Biederman const union sctp_addr *laddr, 9991da177e4SLinus Torvalds const union sctp_addr *paddr, 10001da177e4SLinus Torvalds struct sctp_transport **transportp) 10011da177e4SLinus Torvalds { 10021da177e4SLinus Torvalds struct sctp_association *asoc; 10031da177e4SLinus Torvalds 1004f46c7011SXin Long rcu_read_lock(); 10054110cc25SEric W. Biederman asoc = __sctp_lookup_association(net, laddr, paddr, transportp); 1006f46c7011SXin Long rcu_read_unlock(); 10071da177e4SLinus Torvalds 10081da177e4SLinus Torvalds return asoc; 10091da177e4SLinus Torvalds } 10101da177e4SLinus Torvalds 10111da177e4SLinus Torvalds /* Is there an association matching the given local and peer addresses? */ 10124110cc25SEric W. Biederman int sctp_has_association(struct net *net, 10134110cc25SEric W. Biederman const union sctp_addr *laddr, 10141da177e4SLinus Torvalds const union sctp_addr *paddr) 10151da177e4SLinus Torvalds { 10161da177e4SLinus Torvalds struct sctp_association *asoc; 10171da177e4SLinus Torvalds struct sctp_transport *transport; 10181da177e4SLinus Torvalds 10194110cc25SEric W. Biederman if ((asoc = sctp_lookup_association(net, laddr, paddr, &transport))) { 1020dae399d7SXin Long sctp_transport_put(transport); 10211da177e4SLinus Torvalds return 1; 10221da177e4SLinus Torvalds } 10231da177e4SLinus Torvalds 10241da177e4SLinus Torvalds return 0; 10251da177e4SLinus Torvalds } 10261da177e4SLinus Torvalds 10271da177e4SLinus Torvalds /* 10281da177e4SLinus Torvalds * SCTP Implementors Guide, 2.18 Handling of address 10291da177e4SLinus Torvalds * parameters within the INIT or INIT-ACK. 10301da177e4SLinus Torvalds * 10311da177e4SLinus Torvalds * D) When searching for a matching TCB upon reception of an INIT 10321da177e4SLinus Torvalds * or INIT-ACK chunk the receiver SHOULD use not only the 10331da177e4SLinus Torvalds * source address of the packet (containing the INIT or 10341da177e4SLinus Torvalds * INIT-ACK) but the receiver SHOULD also use all valid 10351da177e4SLinus Torvalds * address parameters contained within the chunk. 10361da177e4SLinus Torvalds * 10371da177e4SLinus Torvalds * 2.18.3 Solution description 10381da177e4SLinus Torvalds * 10391da177e4SLinus Torvalds * This new text clearly specifies to an implementor the need 10401da177e4SLinus Torvalds * to look within the INIT or INIT-ACK. Any implementation that 10411da177e4SLinus Torvalds * does not do this, may not be able to establish associations 10421da177e4SLinus Torvalds * in certain circumstances. 10431da177e4SLinus Torvalds * 10441da177e4SLinus Torvalds */ 10454110cc25SEric W. Biederman static struct sctp_association *__sctp_rcv_init_lookup(struct net *net, 10464110cc25SEric W. Biederman struct sk_buff *skb, 10471da177e4SLinus Torvalds const union sctp_addr *laddr, struct sctp_transport **transportp) 10481da177e4SLinus Torvalds { 10491da177e4SLinus Torvalds struct sctp_association *asoc; 10501da177e4SLinus Torvalds union sctp_addr addr; 10511da177e4SLinus Torvalds union sctp_addr *paddr = &addr; 10522c0fd387SArnaldo Carvalho de Melo struct sctphdr *sh = sctp_hdr(skb); 10531da177e4SLinus Torvalds union sctp_params params; 105401a992beSXin Long struct sctp_init_chunk *init; 10551da177e4SLinus Torvalds struct sctp_af *af; 10561da177e4SLinus Torvalds 10571da177e4SLinus Torvalds /* 10581da177e4SLinus Torvalds * This code will NOT touch anything inside the chunk--it is 10591da177e4SLinus Torvalds * strictly READ-ONLY. 10601da177e4SLinus Torvalds * 10611da177e4SLinus Torvalds * RFC 2960 3 SCTP packet Format 10621da177e4SLinus Torvalds * 10631da177e4SLinus Torvalds * Multiple chunks can be bundled into one SCTP packet up to 10641da177e4SLinus Torvalds * the MTU size, except for the INIT, INIT ACK, and SHUTDOWN 10651da177e4SLinus Torvalds * COMPLETE chunks. These chunks MUST NOT be bundled with any 10661da177e4SLinus Torvalds * other chunk in a packet. See Section 6.10 for more details 10671da177e4SLinus Torvalds * on chunk bundling. 10681da177e4SLinus Torvalds */ 10691da177e4SLinus Torvalds 10701da177e4SLinus Torvalds /* Find the start of the TLVs and the end of the chunk. This is 10711da177e4SLinus Torvalds * the region we search for address parameters. 10721da177e4SLinus Torvalds */ 107301a992beSXin Long init = (struct sctp_init_chunk *)skb->data; 10741da177e4SLinus Torvalds 10751da177e4SLinus Torvalds /* Walk the parameters looking for embedded addresses. */ 10761da177e4SLinus Torvalds sctp_walk_params(params, init, init_hdr.params) { 10771da177e4SLinus Torvalds 10781da177e4SLinus Torvalds /* Note: Ignoring hostname addresses. */ 10791da177e4SLinus Torvalds af = sctp_get_af_specific(param_type2af(params.p->type)); 10801da177e4SLinus Torvalds if (!af) 10811da177e4SLinus Torvalds continue; 10821da177e4SLinus Torvalds 1083dd86d136SAl Viro af->from_addr_param(paddr, params.addr, sh->source, 0); 10841da177e4SLinus Torvalds 10857c17fcc7SXin Long asoc = __sctp_lookup_association(net, laddr, paddr, transportp); 10861da177e4SLinus Torvalds if (asoc) 10871da177e4SLinus Torvalds return asoc; 10881da177e4SLinus Torvalds } 10891da177e4SLinus Torvalds 10901da177e4SLinus Torvalds return NULL; 10911da177e4SLinus Torvalds } 10921da177e4SLinus Torvalds 1093df218577SVlad Yasevich /* ADD-IP, Section 5.2 1094df218577SVlad Yasevich * When an endpoint receives an ASCONF Chunk from the remote peer 1095df218577SVlad Yasevich * special procedures may be needed to identify the association the 1096df218577SVlad Yasevich * ASCONF Chunk is associated with. To properly find the association 1097df218577SVlad Yasevich * the following procedures SHOULD be followed: 1098df218577SVlad Yasevich * 1099df218577SVlad Yasevich * D2) If the association is not found, use the address found in the 1100df218577SVlad Yasevich * Address Parameter TLV combined with the port number found in the 1101df218577SVlad Yasevich * SCTP common header. If found proceed to rule D4. 1102df218577SVlad Yasevich * 1103df218577SVlad Yasevich * D2-ext) If more than one ASCONF Chunks are packed together, use the 1104df218577SVlad Yasevich * address found in the ASCONF Address Parameter TLV of each of the 1105df218577SVlad Yasevich * subsequent ASCONF Chunks. If found, proceed to rule D4. 1106df218577SVlad Yasevich */ 1107df218577SVlad Yasevich static struct sctp_association *__sctp_rcv_asconf_lookup( 11084110cc25SEric W. Biederman struct net *net, 1109922dbc5bSXin Long struct sctp_chunkhdr *ch, 1110df218577SVlad Yasevich const union sctp_addr *laddr, 1111bc92dd19SAl Viro __be16 peer_port, 1112df218577SVlad Yasevich struct sctp_transport **transportp) 1113df218577SVlad Yasevich { 111468d75469SXin Long struct sctp_addip_chunk *asconf = (struct sctp_addip_chunk *)ch; 1115df218577SVlad Yasevich struct sctp_af *af; 1116df218577SVlad Yasevich union sctp_addr_param *param; 1117df218577SVlad Yasevich union sctp_addr paddr; 1118df218577SVlad Yasevich 1119df218577SVlad Yasevich /* Skip over the ADDIP header and find the Address parameter */ 1120df218577SVlad Yasevich param = (union sctp_addr_param *)(asconf + 1); 1121df218577SVlad Yasevich 11226a435732SShan Wei af = sctp_get_af_specific(param_type2af(param->p.type)); 1123df218577SVlad Yasevich if (unlikely(!af)) 1124df218577SVlad Yasevich return NULL; 1125df218577SVlad Yasevich 1126df218577SVlad Yasevich af->from_addr_param(&paddr, param, peer_port, 0); 1127df218577SVlad Yasevich 11284110cc25SEric W. Biederman return __sctp_lookup_association(net, laddr, &paddr, transportp); 1129df218577SVlad Yasevich } 1130df218577SVlad Yasevich 1131df218577SVlad Yasevich 1132bbd0d598SVlad Yasevich /* SCTP-AUTH, Section 6.3: 1133bbd0d598SVlad Yasevich * If the receiver does not find a STCB for a packet containing an AUTH 1134bbd0d598SVlad Yasevich * chunk as the first chunk and not a COOKIE-ECHO chunk as the second 1135bbd0d598SVlad Yasevich * chunk, it MUST use the chunks after the AUTH chunk to look up an existing 1136bbd0d598SVlad Yasevich * association. 1137bbd0d598SVlad Yasevich * 1138bbd0d598SVlad Yasevich * This means that any chunks that can help us identify the association need 113925985edcSLucas De Marchi * to be looked at to find this association. 1140bbd0d598SVlad Yasevich */ 11414110cc25SEric W. Biederman static struct sctp_association *__sctp_rcv_walk_lookup(struct net *net, 11424110cc25SEric W. Biederman struct sk_buff *skb, 1143bbd0d598SVlad Yasevich const union sctp_addr *laddr, 1144bbd0d598SVlad Yasevich struct sctp_transport **transportp) 1145bbd0d598SVlad Yasevich { 1146df218577SVlad Yasevich struct sctp_association *asoc = NULL; 1147922dbc5bSXin Long struct sctp_chunkhdr *ch; 1148df218577SVlad Yasevich int have_auth = 0; 1149df218577SVlad Yasevich unsigned int chunk_num = 1; 1150df218577SVlad Yasevich __u8 *ch_end; 1151df218577SVlad Yasevich 1152df218577SVlad Yasevich /* Walk through the chunks looking for AUTH or ASCONF chunks 1153df218577SVlad Yasevich * to help us find the association. 1154bbd0d598SVlad Yasevich */ 1155922dbc5bSXin Long ch = (struct sctp_chunkhdr *)skb->data; 1156df218577SVlad Yasevich do { 1157df218577SVlad Yasevich /* Break out if chunk length is less then minimal. */ 1158922dbc5bSXin Long if (ntohs(ch->length) < sizeof(*ch)) 1159df218577SVlad Yasevich break; 1160df218577SVlad Yasevich 1161e2f036a9SMarcelo Ricardo Leitner ch_end = ((__u8 *)ch) + SCTP_PAD4(ntohs(ch->length)); 1162df218577SVlad Yasevich if (ch_end > skb_tail_pointer(skb)) 1163df218577SVlad Yasevich break; 1164df218577SVlad Yasevich 1165df218577SVlad Yasevich switch (ch->type) { 1166df218577SVlad Yasevich case SCTP_CID_AUTH: 1167df218577SVlad Yasevich have_auth = chunk_num; 1168df218577SVlad Yasevich break; 1169df218577SVlad Yasevich 1170df218577SVlad Yasevich case SCTP_CID_COOKIE_ECHO: 1171df218577SVlad Yasevich /* If a packet arrives containing an AUTH chunk as 1172df218577SVlad Yasevich * a first chunk, a COOKIE-ECHO chunk as the second 1173df218577SVlad Yasevich * chunk, and possibly more chunks after them, and 1174df218577SVlad Yasevich * the receiver does not have an STCB for that 1175df218577SVlad Yasevich * packet, then authentication is based on 1176df218577SVlad Yasevich * the contents of the COOKIE- ECHO chunk. 1177df218577SVlad Yasevich */ 1178df218577SVlad Yasevich if (have_auth == 1 && chunk_num == 2) 1179bbd0d598SVlad Yasevich return NULL; 1180df218577SVlad Yasevich break; 1181df218577SVlad Yasevich 1182df218577SVlad Yasevich case SCTP_CID_ASCONF: 1183e1fc3b14SEric W. Biederman if (have_auth || net->sctp.addip_noauth) 11844110cc25SEric W. Biederman asoc = __sctp_rcv_asconf_lookup( 11854110cc25SEric W. Biederman net, ch, laddr, 1186df218577SVlad Yasevich sctp_hdr(skb)->source, 1187df218577SVlad Yasevich transportp); 1188df218577SVlad Yasevich default: 1189df218577SVlad Yasevich break; 1190df218577SVlad Yasevich } 1191df218577SVlad Yasevich 1192df218577SVlad Yasevich if (asoc) 1193df218577SVlad Yasevich break; 1194df218577SVlad Yasevich 1195922dbc5bSXin Long ch = (struct sctp_chunkhdr *)ch_end; 1196df218577SVlad Yasevich chunk_num++; 1197df218577SVlad Yasevich } while (ch_end < skb_tail_pointer(skb)); 1198df218577SVlad Yasevich 1199df218577SVlad Yasevich return asoc; 1200bbd0d598SVlad Yasevich } 1201bbd0d598SVlad Yasevich 1202bbd0d598SVlad Yasevich /* 1203bbd0d598SVlad Yasevich * There are circumstances when we need to look inside the SCTP packet 1204bbd0d598SVlad Yasevich * for information to help us find the association. Examples 1205bbd0d598SVlad Yasevich * include looking inside of INIT/INIT-ACK chunks or after the AUTH 1206bbd0d598SVlad Yasevich * chunks. 1207bbd0d598SVlad Yasevich */ 12084110cc25SEric W. Biederman static struct sctp_association *__sctp_rcv_lookup_harder(struct net *net, 12094110cc25SEric W. Biederman struct sk_buff *skb, 1210bbd0d598SVlad Yasevich const union sctp_addr *laddr, 1211bbd0d598SVlad Yasevich struct sctp_transport **transportp) 1212bbd0d598SVlad Yasevich { 1213922dbc5bSXin Long struct sctp_chunkhdr *ch; 1214bbd0d598SVlad Yasevich 121590017accSMarcelo Ricardo Leitner /* We do not allow GSO frames here as we need to linearize and 121690017accSMarcelo Ricardo Leitner * then cannot guarantee frame boundaries. This shouldn't be an 121790017accSMarcelo Ricardo Leitner * issue as packets hitting this are mostly INIT or INIT-ACK and 121890017accSMarcelo Ricardo Leitner * those cannot be on GSO-style anyway. 121990017accSMarcelo Ricardo Leitner */ 122090017accSMarcelo Ricardo Leitner if ((skb_shinfo(skb)->gso_type & SKB_GSO_SCTP) == SKB_GSO_SCTP) 122190017accSMarcelo Ricardo Leitner return NULL; 122290017accSMarcelo Ricardo Leitner 1223922dbc5bSXin Long ch = (struct sctp_chunkhdr *)skb->data; 1224bbd0d598SVlad Yasevich 1225df218577SVlad Yasevich /* The code below will attempt to walk the chunk and extract 1226df218577SVlad Yasevich * parameter information. Before we do that, we need to verify 1227df218577SVlad Yasevich * that the chunk length doesn't cause overflow. Otherwise, we'll 1228df218577SVlad Yasevich * walk off the end. 1229df218577SVlad Yasevich */ 1230e2f036a9SMarcelo Ricardo Leitner if (SCTP_PAD4(ntohs(ch->length)) > skb->len) 1231df218577SVlad Yasevich return NULL; 1232df218577SVlad Yasevich 1233bbd0d598SVlad Yasevich /* If this is INIT/INIT-ACK look inside the chunk too. */ 1234f482f2fcSwangweidong if (ch->type == SCTP_CID_INIT || ch->type == SCTP_CID_INIT_ACK) 12354110cc25SEric W. Biederman return __sctp_rcv_init_lookup(net, skb, laddr, transportp); 1236bbd0d598SVlad Yasevich 12374110cc25SEric W. Biederman return __sctp_rcv_walk_lookup(net, skb, laddr, transportp); 1238bbd0d598SVlad Yasevich } 1239bbd0d598SVlad Yasevich 12401da177e4SLinus Torvalds /* Lookup an association for an inbound skb. */ 12414110cc25SEric W. Biederman static struct sctp_association *__sctp_rcv_lookup(struct net *net, 12424110cc25SEric W. Biederman struct sk_buff *skb, 12431da177e4SLinus Torvalds const union sctp_addr *paddr, 12441da177e4SLinus Torvalds const union sctp_addr *laddr, 12451da177e4SLinus Torvalds struct sctp_transport **transportp) 12461da177e4SLinus Torvalds { 12471da177e4SLinus Torvalds struct sctp_association *asoc; 12481da177e4SLinus Torvalds 12494110cc25SEric W. Biederman asoc = __sctp_lookup_association(net, laddr, paddr, transportp); 1250b77b7565SMarcelo Ricardo Leitner if (asoc) 1251b77b7565SMarcelo Ricardo Leitner goto out; 12521da177e4SLinus Torvalds 12531da177e4SLinus Torvalds /* Further lookup for INIT/INIT-ACK packets. 12541da177e4SLinus Torvalds * SCTP Implementors Guide, 2.18 Handling of address 12551da177e4SLinus Torvalds * parameters within the INIT or INIT-ACK. 12561da177e4SLinus Torvalds */ 12574110cc25SEric W. Biederman asoc = __sctp_rcv_lookup_harder(net, skb, laddr, transportp); 1258b77b7565SMarcelo Ricardo Leitner if (asoc) 1259b77b7565SMarcelo Ricardo Leitner goto out; 12601da177e4SLinus Torvalds 1261b77b7565SMarcelo Ricardo Leitner if (paddr->sa.sa_family == AF_INET) 1262b77b7565SMarcelo Ricardo Leitner pr_debug("sctp: asoc not found for src:%pI4:%d dst:%pI4:%d\n", 1263b77b7565SMarcelo Ricardo Leitner &laddr->v4.sin_addr, ntohs(laddr->v4.sin_port), 1264b77b7565SMarcelo Ricardo Leitner &paddr->v4.sin_addr, ntohs(paddr->v4.sin_port)); 1265b77b7565SMarcelo Ricardo Leitner else 1266b77b7565SMarcelo Ricardo Leitner pr_debug("sctp: asoc not found for src:%pI6:%d dst:%pI6:%d\n", 1267b77b7565SMarcelo Ricardo Leitner &laddr->v6.sin6_addr, ntohs(laddr->v6.sin6_port), 1268b77b7565SMarcelo Ricardo Leitner &paddr->v6.sin6_addr, ntohs(paddr->v6.sin6_port)); 1269b77b7565SMarcelo Ricardo Leitner 1270b77b7565SMarcelo Ricardo Leitner out: 12711da177e4SLinus Torvalds return asoc; 12721da177e4SLinus Torvalds } 1273