1370 lines · 36.6 KB · C
RawDownload
// SPDX-License-Identifier: GPL-2.0-or-later/* SCTP kernel implementation * Copyright (c) 1999-2000 Cisco, Inc. * Copyright (c) 1999-2001 Motorola, Inc. * Copyright (c) 2001-2003 International Business Machines, Corp. * Copyright (c) 2001 Intel Corp. * Copyright (c) 2001 Nokia, Inc. * Copyright (c) 2001 La Monte H.P. Yarroll * * This file is part of the SCTP kernel implementation * * These functions handle all input from the IP layer into SCTP. * * Please send any bug reports or fixes you make to the * email address(es): *    lksctp developers <linux-sctp@vger.kernel.org> * * Written or modified by: *    La Monte H.P. Yarroll <piggy@acm.org> *    Karl Knutson <karl@athena.chicago.il.us> *    Xingang Guo <xingang.guo@intel.com> *    Jon Grimm <jgrimm@us.ibm.com> *    Hui Huang <hui.huang@nokia.com> *    Daisy Chang <daisyc@us.ibm.com> *    Sridhar Samudrala <sri@us.ibm.com> *    Ardelle Fan <ardelle.fan@intel.com> */ #include <linux/types.h>#include <linux/list.h> /* For struct list_head */#include <linux/socket.h>#include <linux/ip.h>#include <linux/time.h> /* For struct timeval */#include <linux/slab.h>#include <net/ip.h>#include <net/icmp.h>#include <net/snmp.h>#include <net/sock.h>#include <net/xfrm.h>#include <net/sctp/sctp.h>#include <net/sctp/sm.h>#include <net/sctp/checksum.h>#include <net/net_namespace.h>#include <linux/rhashtable.h>#include <net/sock_reuseport.h> /* Forward declarations for internal helpers. */static int sctp_rcv_ootb(struct sk_buff *);static struct sctp_association *__sctp_rcv_lookup(struct net *net,				      struct sk_buff *skb,				      const union sctp_addr *paddr,				      const union sctp_addr *laddr,				      struct sctp_transport **transportp,				      int dif, int sdif);static struct sctp_endpoint *__sctp_rcv_lookup_endpoint(					struct net *net, struct sk_buff *skb,					const union sctp_addr *laddr,					const union sctp_addr *daddr,					int dif, int sdif);static struct sctp_association *__sctp_lookup_association(					struct net *net,					const union sctp_addr *local,					const union sctp_addr *peer,					struct sctp_transport **pt,					int dif, int sdif); static int sctp_add_backlog(struct sock *sk, struct sk_buff *skb);  /* Calculate the SCTP checksum of an SCTP packet.  */static inline int sctp_rcv_checksum(struct net *net, struct sk_buff *skb){	struct sctphdr *sh = sctp_hdr(skb);	__le32 cmp = sh->checksum;	__le32 val = sctp_compute_cksum(skb, 0); 	if (val != cmp) {		/* CRC failure, dump it. */		__SCTP_INC_STATS(net, SCTP_MIB_CHECKSUMERRORS);		return -1;	}	return 0;} /* * This is the routine which IP calls when receiving an SCTP packet. */int sctp_rcv(struct sk_buff *skb){	struct sock *sk;	struct sctp_association *asoc;	struct sctp_endpoint *ep = NULL;	struct sctp_ep_common *rcvr;	struct sctp_transport *transport = NULL;	struct sctp_chunk *chunk;	union sctp_addr src;	union sctp_addr dest;	int family;	struct sctp_af *af;	struct net *net = dev_net(skb->dev);	bool is_gso = skb_is_gso(skb) && skb_is_gso_sctp(skb);	int dif, sdif; 	if (skb->pkt_type != PACKET_HOST)		goto discard_it; 	__SCTP_INC_STATS(net, SCTP_MIB_INSCTPPACKS); 	/* If packet is too small to contain a single chunk, let's not	 * waste time on it anymore.	 */	if (skb->len < sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr) +		       skb_transport_offset(skb))		goto discard_it; 	/* If the packet is fragmented and we need to do crc checking,	 * it's better to just linearize it otherwise crc computing	 * takes longer.	 */	if (((!is_gso || skb_cloned(skb)) && skb_linearize(skb)) ||	    !pskb_may_pull(skb, sizeof(struct sctphdr)))		goto discard_it; 	/* Pull up the IP header. */	__skb_pull(skb, skb_transport_offset(skb)); 	skb->csum_valid = 0; /* Previous value not applicable */	if (skb_csum_unnecessary(skb))		__skb_decr_checksum_unnecessary(skb);	else if (!sctp_checksum_disable &&		 !is_gso &&		 sctp_rcv_checksum(net, skb) < 0)		goto discard_it;	skb->csum_valid = 1; 	__skb_pull(skb, sizeof(struct sctphdr)); 	family = ipver2af(ip_hdr(skb)->version);	af = sctp_get_af_specific(family);	if (unlikely(!af))		goto discard_it;	SCTP_INPUT_CB(skb)->af = af; 	/* Initialize local addresses for lookups. */	af->from_skb(&src, skb, 1);	af->from_skb(&dest, skb, 0);	dif = af->skb_iif(skb);	sdif = af->skb_sdif(skb); 	/* If the packet is to or from a non-unicast address,	 * silently discard the packet.	 *	 * This is not clearly defined in the RFC except in section	 * 8.4 - OOTB handling.  However, based on the book "Stream Control	 * Transmission Protocol" 2.1, "It is important to note that the	 * IP address of an SCTP transport address must be a routable	 * unicast address.  In other words, IP multicast addresses and	 * IP broadcast addresses cannot be used in an SCTP transport	 * address."	 */	if (!af->addr_valid(&src, NULL, skb) ||	    !af->addr_valid(&dest, NULL, skb))		goto discard_it; 	asoc = __sctp_rcv_lookup(net, skb, &src, &dest, &transport, dif, sdif); 	if (!asoc)		ep = __sctp_rcv_lookup_endpoint(net, skb, &dest, &src, dif, sdif); 	/* Retrieve the common input handling substructure. */	rcvr = asoc ? &asoc->base : &ep->base;	sk = rcvr->sk; 	/*	 * RFC 2960, 8.4 - Handle "Out of the blue" Packets.	 * An SCTP packet is called an "out of the blue" (OOTB)	 * packet if it is correctly formed, i.e., passed the	 * receiver's checksum check, but the receiver is not	 * able to identify the association to which this	 * packet belongs.	 */	if (!asoc) {		if (sctp_rcv_ootb(skb)) {			__SCTP_INC_STATS(net, SCTP_MIB_OUTOFBLUES);			goto discard_release;		}	} 	if (!xfrm_policy_check(sk, XFRM_POLICY_IN, skb, family))		goto discard_release;	nf_reset_ct(skb); 	if (sk_filter(sk, skb) || skb->len < sizeof(struct sctp_chunkhdr))		goto discard_release; 	/* Create an SCTP packet structure. */	chunk = sctp_chunkify(skb, asoc, sk, GFP_ATOMIC);	if (!chunk)		goto discard_release;	SCTP_INPUT_CB(skb)->chunk = chunk; 	/* Remember what endpoint is to handle this packet. */	chunk->rcvr = rcvr; 	/* Remember the SCTP header. */	chunk->sctp_hdr = sctp_hdr(skb); 	/* Set the source and destination addresses of the incoming chunk.  */	sctp_init_addrs(chunk, &src, &dest); 	/* Remember where we came from.  */	chunk->transport = transport; 	/* Acquire access to the sock lock. Note: We are safe from other	 * bottom halves on this lock, but a user may be in the lock too,	 * so check if it is busy.	 */	bh_lock_sock(sk); 	if (sk != rcvr->sk) {		/* Our cached sk is different from the rcvr->sk.  This is		 * because migrate()/accept() may have moved the association		 * to a new socket and released all the sockets.  So now we		 * are holding a lock on the old socket while the user may		 * be doing something with the new socket.  Switch our veiw		 * of the current sk.		 */		bh_unlock_sock(sk);		sk = rcvr->sk;		bh_lock_sock(sk);	} 	if (sock_owned_by_user(sk) || !sctp_newsk_ready(sk)) {		if (sctp_add_backlog(sk, skb)) {			bh_unlock_sock(sk);			sctp_chunk_free(chunk);			skb = NULL; /* sctp_chunk_free already freed the skb */			goto discard_release;		}		__SCTP_INC_STATS(net, SCTP_MIB_IN_PKT_BACKLOG);	} else {		__SCTP_INC_STATS(net, SCTP_MIB_IN_PKT_SOFTIRQ);		sctp_inq_push(&chunk->rcvr->inqueue, chunk);	} 	bh_unlock_sock(sk); 	/* Release the asoc/ep ref we took in the lookup calls. */	if (transport)		sctp_transport_put(transport);	else		sctp_endpoint_put(ep); 	return 0; discard_it:	__SCTP_INC_STATS(net, SCTP_MIB_IN_PKT_DISCARDS);	kfree_skb(skb);	return 0; discard_release:	/* Release the asoc/ep ref we took in the lookup calls. */	if (transport)		sctp_transport_put(transport);	else		sctp_endpoint_put(ep); 	goto discard_it;} /* Process the backlog queue of the socket.  Every skb on * the backlog holds a ref on an association or endpoint. * We hold this ref throughout the state machine to make * sure that the structure we need is still around. */int sctp_backlog_rcv(struct sock *sk, struct sk_buff *skb){	struct sctp_chunk *chunk = SCTP_INPUT_CB(skb)->chunk;	struct sctp_inq *inqueue = &chunk->rcvr->inqueue;	struct sctp_transport *t = chunk->transport;	struct sctp_ep_common *rcvr = NULL;	int backloged = 0; 	rcvr = chunk->rcvr; 	/* If the rcvr is dead then the association or endpoint	 * has been deleted and we can safely drop the chunk	 * and refs that we are holding.	 */	if (rcvr->dead) {		sctp_chunk_free(chunk);		goto done;	} 	if (unlikely(rcvr->sk != sk)) {		/* In this case, the association moved from one socket to		 * another.  We are currently sitting on the backlog of the		 * old socket, so we need to move.		 * However, since we are here in the process context we		 * need to take make sure that the user doesn't own		 * the new socket when we process the packet.		 * If the new socket is user-owned, queue the chunk to the		 * backlog of the new socket without dropping any refs.		 * Otherwise, we can safely push the chunk on the inqueue.		 */ 		sk = rcvr->sk;		local_bh_disable();		bh_lock_sock(sk); 		if (sock_owned_by_user(sk) || !sctp_newsk_ready(sk)) {			if (sk_add_backlog(sk, skb, READ_ONCE(sk->sk_rcvbuf)))				sctp_chunk_free(chunk);			else				backloged = 1;		} else			sctp_inq_push(inqueue, chunk); 		bh_unlock_sock(sk);		local_bh_enable(); 		/* If the chunk was backloged again, don't drop refs */		if (backloged)			return 0;	} else {		if (!sctp_newsk_ready(sk)) {			if (!sk_add_backlog(sk, skb, READ_ONCE(sk->sk_rcvbuf)))				return 0;			sctp_chunk_free(chunk);		} else {			sctp_inq_push(inqueue, chunk);		}	} done:	/* Release the refs we took in sctp_add_backlog */	if (SCTP_EP_TYPE_ASSOCIATION == rcvr->type)		sctp_transport_put(t);	else if (SCTP_EP_TYPE_SOCKET == rcvr->type)		sctp_endpoint_put(sctp_ep(rcvr));	else		BUG(); 	return 0;} static int sctp_add_backlog(struct sock *sk, struct sk_buff *skb){	struct sctp_chunk *chunk = SCTP_INPUT_CB(skb)->chunk;	struct sctp_transport *t = chunk->transport;	struct sctp_ep_common *rcvr = chunk->rcvr;	int ret; 	ret = sk_add_backlog(sk, skb, READ_ONCE(sk->sk_rcvbuf));	if (!ret) {		/* Hold the assoc/ep while hanging on the backlog queue.		 * This way, we know structures we need will not disappear		 * from us		 */		if (SCTP_EP_TYPE_ASSOCIATION == rcvr->type)			sctp_transport_hold(t);		else if (SCTP_EP_TYPE_SOCKET == rcvr->type)			sctp_endpoint_hold(sctp_ep(rcvr));		else			BUG();	}	return ret; } /* Handle icmp frag needed error. */void sctp_icmp_frag_needed(struct sock *sk, struct sctp_association *asoc,			   struct sctp_transport *t, __u32 pmtu){	if (!t ||	    (t->pathmtu <= pmtu &&	     t->pl.probe_size + sctp_transport_pl_hlen(t) <= pmtu))		return; 	if (sock_owned_by_user(sk)) {		atomic_set(&t->mtu_info, pmtu);		asoc->pmtu_pending = 1;		t->pmtu_pending = 1;		return;	} 	if (!(t->param_flags & SPP_PMTUD_ENABLE))		/* We can't allow retransmitting in such case, as the		 * retransmission would be sized just as before, and thus we		 * would get another icmp, and retransmit again.		 */		return; 	/* Update transports view of the MTU. Return if no update was needed.	 * If an update wasn't needed/possible, it also doesn't make sense to	 * try to retransmit now.	 */	if (!sctp_transport_update_pmtu(t, pmtu))		return; 	/* Update association pmtu. */	sctp_assoc_sync_pmtu(asoc); 	/* Retransmit with the new pmtu setting. */	sctp_retransmit(&asoc->outqueue, t, SCTP_RTXR_PMTUD);} void sctp_icmp_redirect(struct sock *sk, struct sctp_transport *t,			struct sk_buff *skb){	struct dst_entry *dst; 	if (sock_owned_by_user(sk) || !t)		return;	dst = sctp_transport_dst_check(t);	if (dst)		dst->ops->redirect(dst, sk, skb);} /* * SCTP Implementer's Guide, 2.37 ICMP handling procedures * * ICMP8) If the ICMP code is a "Unrecognized next header type encountered" *        or a "Protocol Unreachable" treat this message as an abort *        with the T bit set. * * This function sends an event to the state machine, which will abort the * association. * */void sctp_icmp_proto_unreachable(struct sock *sk,			   struct sctp_association *asoc,			   struct sctp_transport *t){	if (sock_owned_by_user(sk)) {		if (timer_pending(&t->proto_unreach_timer))			return;		else {			if (!mod_timer(&t->proto_unreach_timer,						jiffies + (HZ/20)))				sctp_transport_hold(t);		}	} else {		struct net *net = sock_net(sk); 		pr_debug("%s: unrecognized next header type "			 "encountered!\n", __func__); 		if (timer_delete(&t->proto_unreach_timer))			sctp_transport_put(t); 		sctp_do_sm(net, SCTP_EVENT_T_OTHER,			   SCTP_ST_OTHER(SCTP_EVENT_ICMP_PROTO_UNREACH),			   asoc->state, asoc->ep, asoc, t,			   GFP_ATOMIC);	}} /* Common lookup code for icmp/icmpv6 error handler. */struct sock *sctp_err_lookup(struct net *net, int family, struct sk_buff *skb,			     struct sctphdr *sctphdr,			     struct sctp_association **app,			     struct sctp_transport **tpp){	struct sctp_init_chunk *chunkhdr, _chunkhdr;	union sctp_addr saddr;	union sctp_addr daddr;	struct sctp_af *af;	struct sock *sk = NULL;	struct sctp_association *asoc;	struct sctp_transport *transport = NULL;	__u32 vtag = ntohl(sctphdr->vtag);	int sdif = inet_sdif(skb);	int dif = inet_iif(skb); 	*app = NULL; *tpp = NULL; 	af = sctp_get_af_specific(family);	if (unlikely(!af)) {		return NULL;	} 	/* Initialize local addresses for lookups. */	af->from_skb(&saddr, skb, 1);	af->from_skb(&daddr, skb, 0); 	/* Look for an association that matches the incoming ICMP error	 * packet.	 */	asoc = __sctp_lookup_association(net, &saddr, &daddr, &transport, dif, sdif);	if (!asoc)		return NULL; 	sk = asoc->base.sk; 	/* RFC 4960, Appendix C. ICMP Handling	 *	 * ICMP6) An implementation MUST validate that the Verification Tag	 * contained in the ICMP message matches the Verification Tag of	 * the peer.  If the Verification Tag is not 0 and does NOT

Lines 1–500 of 1370.