160c778b2SVlad Yasevich /* SCTP kernel implementation 21da177e4SLinus Torvalds * (C) Copyright IBM Corp. 2001, 2004 31da177e4SLinus Torvalds * Copyright (c) 1999-2000 Cisco, Inc. 41da177e4SLinus Torvalds * Copyright (c) 1999-2001 Motorola, Inc. 51da177e4SLinus Torvalds * 660c778b2SVlad Yasevich * This file is part of the SCTP kernel implementation 71da177e4SLinus Torvalds * 81da177e4SLinus Torvalds * These functions handle output processing. 91da177e4SLinus Torvalds * 1060c778b2SVlad Yasevich * This SCTP implementation is free software; 111da177e4SLinus Torvalds * you can redistribute it and/or modify it under the terms of 121da177e4SLinus Torvalds * the GNU General Public License as published by 131da177e4SLinus Torvalds * the Free Software Foundation; either version 2, or (at your option) 141da177e4SLinus Torvalds * any later version. 151da177e4SLinus Torvalds * 1660c778b2SVlad Yasevich * This SCTP implementation is distributed in the hope that it 171da177e4SLinus Torvalds * will be useful, but WITHOUT ANY WARRANTY; without even the implied 181da177e4SLinus Torvalds * ************************ 191da177e4SLinus Torvalds * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 201da177e4SLinus Torvalds * See the GNU General Public License for more details. 211da177e4SLinus Torvalds * 221da177e4SLinus Torvalds * You should have received a copy of the GNU General Public License 234b2f13a2SJeff Kirsher * along with GNU CC; see the file COPYING. If not, see 244b2f13a2SJeff Kirsher * <http://www.gnu.org/licenses/>. 251da177e4SLinus Torvalds * 261da177e4SLinus Torvalds * Please send any bug reports or fixes you make to the 271da177e4SLinus Torvalds * email address(es): 2891705c61SDaniel Borkmann * lksctp developers <linux-sctp@vger.kernel.org> 291da177e4SLinus Torvalds * 301da177e4SLinus Torvalds * Written or modified by: 311da177e4SLinus Torvalds * La Monte H.P. Yarroll <piggy@acm.org> 321da177e4SLinus Torvalds * Karl Knutson <karl@athena.chicago.il.us> 331da177e4SLinus Torvalds * Jon Grimm <jgrimm@austin.ibm.com> 341da177e4SLinus Torvalds * Sridhar Samudrala <sri@us.ibm.com> 351da177e4SLinus Torvalds */ 361da177e4SLinus Torvalds 37145ce502SJoe Perches #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 38145ce502SJoe Perches 391da177e4SLinus Torvalds #include <linux/types.h> 401da177e4SLinus Torvalds #include <linux/kernel.h> 411da177e4SLinus Torvalds #include <linux/wait.h> 421da177e4SLinus Torvalds #include <linux/time.h> 431da177e4SLinus Torvalds #include <linux/ip.h> 441da177e4SLinus Torvalds #include <linux/ipv6.h> 451da177e4SLinus Torvalds #include <linux/init.h> 465a0e3ad6STejun Heo #include <linux/slab.h> 471da177e4SLinus Torvalds #include <net/inet_ecn.h> 488d2f9e81SVlad Yasevich #include <net/ip.h> 491da177e4SLinus Torvalds #include <net/icmp.h> 507c73a6faSPavel Emelyanov #include <net/net_namespace.h> 511da177e4SLinus Torvalds 521da177e4SLinus Torvalds #include <linux/socket.h> /* for sa_family_t */ 531da177e4SLinus Torvalds #include <net/sock.h> 541da177e4SLinus Torvalds 551da177e4SLinus Torvalds #include <net/sctp/sctp.h> 561da177e4SLinus Torvalds #include <net/sctp/sm.h> 579ad0977fSVlad Yasevich #include <net/sctp/checksum.h> 581da177e4SLinus Torvalds 591da177e4SLinus Torvalds /* Forward declarations for private helpers. */ 60ed106277SNeil Horman static sctp_xmit_t __sctp_packet_append_chunk(struct sctp_packet *packet, 61ed106277SNeil Horman struct sctp_chunk *chunk); 62e83963b7SVlad Yasevich static sctp_xmit_t sctp_packet_can_append_data(struct sctp_packet *packet, 631da177e4SLinus Torvalds struct sctp_chunk *chunk); 64e83963b7SVlad Yasevich static void sctp_packet_append_data(struct sctp_packet *packet, 65e83963b7SVlad Yasevich struct sctp_chunk *chunk); 66e83963b7SVlad Yasevich static sctp_xmit_t sctp_packet_will_fit(struct sctp_packet *packet, 67e83963b7SVlad Yasevich struct sctp_chunk *chunk, 68e83963b7SVlad Yasevich u16 chunk_len); 691da177e4SLinus Torvalds 70be297143SWei Yongjun static void sctp_packet_reset(struct sctp_packet *packet) 71be297143SWei Yongjun { 72be297143SWei Yongjun packet->size = packet->overhead; 73be297143SWei Yongjun packet->has_cookie_echo = 0; 74be297143SWei Yongjun packet->has_sack = 0; 75be297143SWei Yongjun packet->has_data = 0; 76be297143SWei Yongjun packet->has_auth = 0; 77be297143SWei Yongjun packet->ipfragok = 0; 78be297143SWei Yongjun packet->auth = NULL; 79be297143SWei Yongjun } 80be297143SWei Yongjun 811da177e4SLinus Torvalds /* Config a packet. 821da177e4SLinus Torvalds * This appears to be a followup set of initializations. 831da177e4SLinus Torvalds */ 841da177e4SLinus Torvalds struct sctp_packet *sctp_packet_config(struct sctp_packet *packet, 851da177e4SLinus Torvalds __u32 vtag, int ecn_capable) 861da177e4SLinus Torvalds { 8790017accSMarcelo Ricardo Leitner struct sctp_transport *tp = packet->transport; 8890017accSMarcelo Ricardo Leitner struct sctp_association *asoc = tp->asoc; 891da177e4SLinus Torvalds 90bb33381dSDaniel Borkmann pr_debug("%s: packet:%p vtag:0x%x\n", __func__, packet, vtag); 911da177e4SLinus Torvalds 921da177e4SLinus Torvalds packet->vtag = vtag; 931da177e4SLinus Torvalds 9490017accSMarcelo Ricardo Leitner if (asoc && tp->dst) { 9590017accSMarcelo Ricardo Leitner struct sock *sk = asoc->base.sk; 9690017accSMarcelo Ricardo Leitner 9790017accSMarcelo Ricardo Leitner rcu_read_lock(); 9890017accSMarcelo Ricardo Leitner if (__sk_dst_get(sk) != tp->dst) { 9990017accSMarcelo Ricardo Leitner dst_hold(tp->dst); 10090017accSMarcelo Ricardo Leitner sk_setup_caps(sk, tp->dst); 10190017accSMarcelo Ricardo Leitner } 10290017accSMarcelo Ricardo Leitner 10390017accSMarcelo Ricardo Leitner if (sk_can_gso(sk)) { 10490017accSMarcelo Ricardo Leitner struct net_device *dev = tp->dst->dev; 10590017accSMarcelo Ricardo Leitner 10690017accSMarcelo Ricardo Leitner packet->max_size = dev->gso_max_size; 10790017accSMarcelo Ricardo Leitner } else { 10890017accSMarcelo Ricardo Leitner packet->max_size = asoc->pathmtu; 10990017accSMarcelo Ricardo Leitner } 11090017accSMarcelo Ricardo Leitner rcu_read_unlock(); 11190017accSMarcelo Ricardo Leitner 11290017accSMarcelo Ricardo Leitner } else { 11390017accSMarcelo Ricardo Leitner packet->max_size = tp->pathmtu; 11490017accSMarcelo Ricardo Leitner } 11590017accSMarcelo Ricardo Leitner 1161da177e4SLinus Torvalds if (ecn_capable && sctp_packet_empty(packet)) { 11790017accSMarcelo Ricardo Leitner struct sctp_chunk *chunk; 1181da177e4SLinus Torvalds 1191da177e4SLinus Torvalds /* If there a is a prepend chunk stick it on the list before 1201da177e4SLinus Torvalds * any other chunks get appended. 1211da177e4SLinus Torvalds */ 12290017accSMarcelo Ricardo Leitner chunk = sctp_get_ecne_prepend(asoc); 1231da177e4SLinus Torvalds if (chunk) 1241da177e4SLinus Torvalds sctp_packet_append_chunk(packet, chunk); 1251da177e4SLinus Torvalds } 1261da177e4SLinus Torvalds 1271da177e4SLinus Torvalds return packet; 1281da177e4SLinus Torvalds } 1291da177e4SLinus Torvalds 1301da177e4SLinus Torvalds /* Initialize the packet structure. */ 1311da177e4SLinus Torvalds struct sctp_packet *sctp_packet_init(struct sctp_packet *packet, 1321da177e4SLinus Torvalds struct sctp_transport *transport, 1331da177e4SLinus Torvalds __u16 sport, __u16 dport) 1341da177e4SLinus Torvalds { 1351da177e4SLinus Torvalds struct sctp_association *asoc = transport->asoc; 1361da177e4SLinus Torvalds size_t overhead; 1371da177e4SLinus Torvalds 138bb33381dSDaniel Borkmann pr_debug("%s: packet:%p transport:%p\n", __func__, packet, transport); 1391da177e4SLinus Torvalds 1401da177e4SLinus Torvalds packet->transport = transport; 1411da177e4SLinus Torvalds packet->source_port = sport; 1421da177e4SLinus Torvalds packet->destination_port = dport; 14379af02c2SDavid S. Miller INIT_LIST_HEAD(&packet->chunk_list); 1441da177e4SLinus Torvalds if (asoc) { 1451da177e4SLinus Torvalds struct sctp_sock *sp = sctp_sk(asoc->base.sk); 1461da177e4SLinus Torvalds overhead = sp->pf->af->net_header_len; 1471da177e4SLinus Torvalds } else { 1481da177e4SLinus Torvalds overhead = sizeof(struct ipv6hdr); 1491da177e4SLinus Torvalds } 1501da177e4SLinus Torvalds overhead += sizeof(struct sctphdr); 1511da177e4SLinus Torvalds packet->overhead = overhead; 152be297143SWei Yongjun sctp_packet_reset(packet); 1531da177e4SLinus Torvalds packet->vtag = 0; 1543e3251b3SDaniel Borkmann 1551da177e4SLinus Torvalds return packet; 1561da177e4SLinus Torvalds } 1571da177e4SLinus Torvalds 1581da177e4SLinus Torvalds /* Free a packet. */ 1591da177e4SLinus Torvalds void sctp_packet_free(struct sctp_packet *packet) 1601da177e4SLinus Torvalds { 16179af02c2SDavid S. Miller struct sctp_chunk *chunk, *tmp; 1621da177e4SLinus Torvalds 163bb33381dSDaniel Borkmann pr_debug("%s: packet:%p\n", __func__, packet); 1641da177e4SLinus Torvalds 16579af02c2SDavid S. Miller list_for_each_entry_safe(chunk, tmp, &packet->chunk_list, list) { 16679af02c2SDavid S. Miller list_del_init(&chunk->list); 1671da177e4SLinus Torvalds sctp_chunk_free(chunk); 16879af02c2SDavid S. Miller } 1691da177e4SLinus Torvalds } 1701da177e4SLinus Torvalds 1711da177e4SLinus Torvalds /* This routine tries to append the chunk to the offered packet. If adding 1721da177e4SLinus Torvalds * the chunk causes the packet to exceed the path MTU and COOKIE_ECHO chunk 1731da177e4SLinus Torvalds * is not present in the packet, it transmits the input packet. 1741da177e4SLinus Torvalds * Data can be bundled with a packet containing a COOKIE_ECHO chunk as long 1751da177e4SLinus Torvalds * as it can fit in the packet, but any more data that does not fit in this 1761da177e4SLinus Torvalds * packet can be sent only after receiving the COOKIE_ACK. 1771da177e4SLinus Torvalds */ 1781da177e4SLinus Torvalds sctp_xmit_t sctp_packet_transmit_chunk(struct sctp_packet *packet, 1792e3216cdSVlad Yasevich struct sctp_chunk *chunk, 180cea8768fSMarcelo Ricardo Leitner int one_packet, gfp_t gfp) 1811da177e4SLinus Torvalds { 1821da177e4SLinus Torvalds sctp_xmit_t retval; 1831da177e4SLinus Torvalds int error = 0; 1841da177e4SLinus Torvalds 185*3b55a537SDavid S. Miller pr_debug("%s: packet:%p size:%Zu chunk:%p size:%d\n", __func__, 186942b3235SMarcelo Ricardo Leitner packet, packet->size, chunk, chunk->skb ? chunk->skb->len : -1); 1871da177e4SLinus Torvalds 1881da177e4SLinus Torvalds switch ((retval = (sctp_packet_append_chunk(packet, chunk)))) { 1891da177e4SLinus Torvalds case SCTP_XMIT_PMTU_FULL: 1901da177e4SLinus Torvalds if (!packet->has_cookie_echo) { 191cea8768fSMarcelo Ricardo Leitner error = sctp_packet_transmit(packet, gfp); 1921da177e4SLinus Torvalds if (error < 0) 1931da177e4SLinus Torvalds chunk->skb->sk->sk_err = -error; 1941da177e4SLinus Torvalds 1951da177e4SLinus Torvalds /* If we have an empty packet, then we can NOT ever 1961da177e4SLinus Torvalds * return PMTU_FULL. 1971da177e4SLinus Torvalds */ 1982e3216cdSVlad Yasevich if (!one_packet) 1992e3216cdSVlad Yasevich retval = sctp_packet_append_chunk(packet, 2002e3216cdSVlad Yasevich chunk); 2011da177e4SLinus Torvalds } 2021da177e4SLinus Torvalds break; 2031da177e4SLinus Torvalds 2041da177e4SLinus Torvalds case SCTP_XMIT_RWND_FULL: 2051da177e4SLinus Torvalds case SCTP_XMIT_OK: 206526cbef7SDavid Laight case SCTP_XMIT_DELAY: 2071da177e4SLinus Torvalds break; 2083ff50b79SStephen Hemminger } 2091da177e4SLinus Torvalds 2101da177e4SLinus Torvalds return retval; 2111da177e4SLinus Torvalds } 2121da177e4SLinus Torvalds 2134cd57c80SVlad Yasevich /* Try to bundle an auth chunk into the packet. */ 2144cd57c80SVlad Yasevich static sctp_xmit_t sctp_packet_bundle_auth(struct sctp_packet *pkt, 2154cd57c80SVlad Yasevich struct sctp_chunk *chunk) 2164cd57c80SVlad Yasevich { 2174cd57c80SVlad Yasevich struct sctp_association *asoc = pkt->transport->asoc; 2184cd57c80SVlad Yasevich struct sctp_chunk *auth; 2194cd57c80SVlad Yasevich sctp_xmit_t retval = SCTP_XMIT_OK; 2204cd57c80SVlad Yasevich 2214cd57c80SVlad Yasevich /* if we don't have an association, we can't do authentication */ 2224cd57c80SVlad Yasevich if (!asoc) 2234cd57c80SVlad Yasevich return retval; 2244cd57c80SVlad Yasevich 2254cd57c80SVlad Yasevich /* See if this is an auth chunk we are bundling or if 2264cd57c80SVlad Yasevich * auth is already bundled. 2274cd57c80SVlad Yasevich */ 2284007cc88SVlad Yasevich if (chunk->chunk_hdr->type == SCTP_CID_AUTH || pkt->has_auth) 2294cd57c80SVlad Yasevich return retval; 2304cd57c80SVlad Yasevich 2314cd57c80SVlad Yasevich /* if the peer did not request this chunk to be authenticated, 2324cd57c80SVlad Yasevich * don't do it 2334cd57c80SVlad Yasevich */ 2344cd57c80SVlad Yasevich if (!chunk->auth) 2354cd57c80SVlad Yasevich return retval; 2364cd57c80SVlad Yasevich 2374cd57c80SVlad Yasevich auth = sctp_make_auth(asoc); 2384cd57c80SVlad Yasevich if (!auth) 2394cd57c80SVlad Yasevich return retval; 2404cd57c80SVlad Yasevich 241ed106277SNeil Horman retval = __sctp_packet_append_chunk(pkt, auth); 242ed106277SNeil Horman 243ed106277SNeil Horman if (retval != SCTP_XMIT_OK) 244ed106277SNeil Horman sctp_chunk_free(auth); 2454cd57c80SVlad Yasevich 2464cd57c80SVlad Yasevich return retval; 2474cd57c80SVlad Yasevich } 2484cd57c80SVlad Yasevich 2491da177e4SLinus Torvalds /* Try to bundle a SACK with the packet. */ 2501da177e4SLinus Torvalds static sctp_xmit_t sctp_packet_bundle_sack(struct sctp_packet *pkt, 2511da177e4SLinus Torvalds struct sctp_chunk *chunk) 2521da177e4SLinus Torvalds { 2531da177e4SLinus Torvalds sctp_xmit_t retval = SCTP_XMIT_OK; 2541da177e4SLinus Torvalds 2551da177e4SLinus Torvalds /* If sending DATA and haven't aleady bundled a SACK, try to 2561da177e4SLinus Torvalds * bundle one in to the packet. 2571da177e4SLinus Torvalds */ 2581da177e4SLinus Torvalds if (sctp_chunk_is_data(chunk) && !pkt->has_sack && 2591da177e4SLinus Torvalds !pkt->has_cookie_echo) { 2601da177e4SLinus Torvalds struct sctp_association *asoc; 261af87b823SDoug Graham struct timer_list *timer; 2621da177e4SLinus Torvalds asoc = pkt->transport->asoc; 263af87b823SDoug Graham timer = &asoc->timers[SCTP_EVENT_TIMEOUT_SACK]; 2641da177e4SLinus Torvalds 265af87b823SDoug Graham /* If the SACK timer is running, we have a pending SACK */ 266af87b823SDoug Graham if (timer_pending(timer)) { 2671da177e4SLinus Torvalds struct sctp_chunk *sack; 2684244854dSNeil Horman 2694244854dSNeil Horman if (pkt->transport->sack_generation != 2704244854dSNeil Horman pkt->transport->asoc->peer.sack_generation) 2714244854dSNeil Horman return retval; 2724244854dSNeil Horman 2731da177e4SLinus Torvalds asoc->a_rwnd = asoc->rwnd; 2741da177e4SLinus Torvalds sack = sctp_make_sack(asoc); 2751da177e4SLinus Torvalds if (sack) { 276ed106277SNeil Horman retval = __sctp_packet_append_chunk(pkt, sack); 277ed106277SNeil Horman if (retval != SCTP_XMIT_OK) { 278ed106277SNeil Horman sctp_chunk_free(sack); 279ed106277SNeil Horman goto out; 280ed106277SNeil Horman } 2811da177e4SLinus Torvalds asoc->peer.sack_needed = 0; 282af87b823SDoug Graham if (del_timer(timer)) 2831da177e4SLinus Torvalds sctp_association_put(asoc); 2841da177e4SLinus Torvalds } 2851da177e4SLinus Torvalds } 2861da177e4SLinus Torvalds } 287ed106277SNeil Horman out: 2881da177e4SLinus Torvalds return retval; 2891da177e4SLinus Torvalds } 2901da177e4SLinus Torvalds 291ed106277SNeil Horman 2921da177e4SLinus Torvalds /* Append a chunk to the offered packet reporting back any inability to do 2931da177e4SLinus Torvalds * so. 2941da177e4SLinus Torvalds */ 295ed106277SNeil Horman static sctp_xmit_t __sctp_packet_append_chunk(struct sctp_packet *packet, 2961da177e4SLinus Torvalds struct sctp_chunk *chunk) 2971da177e4SLinus Torvalds { 2981da177e4SLinus Torvalds sctp_xmit_t retval = SCTP_XMIT_OK; 2991da177e4SLinus Torvalds __u16 chunk_len = WORD_ROUND(ntohs(chunk->chunk_hdr->length)); 3001da177e4SLinus Torvalds 301e83963b7SVlad Yasevich /* Check to see if this chunk will fit into the packet */ 302e83963b7SVlad Yasevich retval = sctp_packet_will_fit(packet, chunk, chunk_len); 303e83963b7SVlad Yasevich if (retval != SCTP_XMIT_OK) 3041da177e4SLinus Torvalds goto finish; 3051da177e4SLinus Torvalds 306e83963b7SVlad Yasevich /* We believe that this chunk is OK to add to the packet */ 3074cd57c80SVlad Yasevich switch (chunk->chunk_hdr->type) { 3084cd57c80SVlad Yasevich case SCTP_CID_DATA: 309e83963b7SVlad Yasevich /* Account for the data being in the packet */ 310e83963b7SVlad Yasevich sctp_packet_append_data(packet, chunk); 3111da177e4SLinus Torvalds /* Disallow SACK bundling after DATA. */ 3121da177e4SLinus Torvalds packet->has_sack = 1; 3134cd57c80SVlad Yasevich /* Disallow AUTH bundling after DATA */ 3144cd57c80SVlad Yasevich packet->has_auth = 1; 3154cd57c80SVlad Yasevich /* Let it be knows that packet has DATA in it */ 3164cd57c80SVlad Yasevich packet->has_data = 1; 317759af00eSVlad Yasevich /* timestamp the chunk for rtx purposes */ 318759af00eSVlad Yasevich chunk->sent_at = jiffies; 3194cd57c80SVlad Yasevich break; 3204cd57c80SVlad Yasevich case SCTP_CID_COOKIE_ECHO: 3211da177e4SLinus Torvalds packet->has_cookie_echo = 1; 3224cd57c80SVlad Yasevich break; 3234cd57c80SVlad Yasevich 3244cd57c80SVlad Yasevich case SCTP_CID_SACK: 3251da177e4SLinus Torvalds packet->has_sack = 1; 326196d6759SMichele Baldessari if (chunk->asoc) 327196d6759SMichele Baldessari chunk->asoc->stats.osacks++; 3284cd57c80SVlad Yasevich break; 3294cd57c80SVlad Yasevich 3304cd57c80SVlad Yasevich case SCTP_CID_AUTH: 3314cd57c80SVlad Yasevich packet->has_auth = 1; 3324cd57c80SVlad Yasevich packet->auth = chunk; 3334cd57c80SVlad Yasevich break; 3344cd57c80SVlad Yasevich } 3351da177e4SLinus Torvalds 3361da177e4SLinus Torvalds /* It is OK to send this chunk. */ 33779af02c2SDavid S. Miller list_add_tail(&chunk->list, &packet->chunk_list); 3381da177e4SLinus Torvalds packet->size += chunk_len; 3391da177e4SLinus Torvalds chunk->transport = packet->transport; 3401da177e4SLinus Torvalds finish: 3411da177e4SLinus Torvalds return retval; 3421da177e4SLinus Torvalds } 3431da177e4SLinus Torvalds 344ed106277SNeil Horman /* Append a chunk to the offered packet reporting back any inability to do 345ed106277SNeil Horman * so. 346ed106277SNeil Horman */ 347ed106277SNeil Horman sctp_xmit_t sctp_packet_append_chunk(struct sctp_packet *packet, 348ed106277SNeil Horman struct sctp_chunk *chunk) 349ed106277SNeil Horman { 350ed106277SNeil Horman sctp_xmit_t retval = SCTP_XMIT_OK; 351ed106277SNeil Horman 352bb33381dSDaniel Borkmann pr_debug("%s: packet:%p chunk:%p\n", __func__, packet, chunk); 353ed106277SNeil Horman 354ed106277SNeil Horman /* Data chunks are special. Before seeing what else we can 355ed106277SNeil Horman * bundle into this packet, check to see if we are allowed to 356ed106277SNeil Horman * send this DATA. 357ed106277SNeil Horman */ 358ed106277SNeil Horman if (sctp_chunk_is_data(chunk)) { 359ed106277SNeil Horman retval = sctp_packet_can_append_data(packet, chunk); 360ed106277SNeil Horman if (retval != SCTP_XMIT_OK) 361ed106277SNeil Horman goto finish; 362ed106277SNeil Horman } 363ed106277SNeil Horman 364ed106277SNeil Horman /* Try to bundle AUTH chunk */ 365ed106277SNeil Horman retval = sctp_packet_bundle_auth(packet, chunk); 366ed106277SNeil Horman if (retval != SCTP_XMIT_OK) 367ed106277SNeil Horman goto finish; 368ed106277SNeil Horman 369ed106277SNeil Horman /* Try to bundle SACK chunk */ 370ed106277SNeil Horman retval = sctp_packet_bundle_sack(packet, chunk); 371ed106277SNeil Horman if (retval != SCTP_XMIT_OK) 372ed106277SNeil Horman goto finish; 373ed106277SNeil Horman 374ed106277SNeil Horman retval = __sctp_packet_append_chunk(packet, chunk); 375ed106277SNeil Horman 376ed106277SNeil Horman finish: 377ed106277SNeil Horman return retval; 378ed106277SNeil Horman } 379ed106277SNeil Horman 3804c3a5bdaSThomas Graf static void sctp_packet_release_owner(struct sk_buff *skb) 3814c3a5bdaSThomas Graf { 3824c3a5bdaSThomas Graf sk_free(skb->sk); 3834c3a5bdaSThomas Graf } 3844c3a5bdaSThomas Graf 3854c3a5bdaSThomas Graf static void sctp_packet_set_owner_w(struct sk_buff *skb, struct sock *sk) 3864c3a5bdaSThomas Graf { 3874c3a5bdaSThomas Graf skb_orphan(skb); 3884c3a5bdaSThomas Graf skb->sk = sk; 3894c3a5bdaSThomas Graf skb->destructor = sctp_packet_release_owner; 3904c3a5bdaSThomas Graf 3914c3a5bdaSThomas Graf /* 3924c3a5bdaSThomas Graf * The data chunks have already been accounted for in sctp_sendmsg(), 3934c3a5bdaSThomas Graf * therefore only reserve a single byte to keep socket around until 3944c3a5bdaSThomas Graf * the packet has been transmitted. 3954c3a5bdaSThomas Graf */ 3964c3a5bdaSThomas Graf atomic_inc(&sk->sk_wmem_alloc); 3974c3a5bdaSThomas Graf } 3984c3a5bdaSThomas Graf 3991da177e4SLinus Torvalds /* All packets are sent to the network through this function from 4001da177e4SLinus Torvalds * sctp_outq_tail(). 4011da177e4SLinus Torvalds * 4021da177e4SLinus Torvalds * The return value is a normal kernel error return value. 4031da177e4SLinus Torvalds */ 404cea8768fSMarcelo Ricardo Leitner int sctp_packet_transmit(struct sctp_packet *packet, gfp_t gfp) 4051da177e4SLinus Torvalds { 4061da177e4SLinus Torvalds struct sctp_transport *tp = packet->transport; 4071da177e4SLinus Torvalds struct sctp_association *asoc = tp->asoc; 4081da177e4SLinus Torvalds struct sctphdr *sh; 40990017accSMarcelo Ricardo Leitner struct sk_buff *nskb = NULL, *head = NULL; 41079af02c2SDavid S. Miller struct sctp_chunk *chunk, *tmp; 4111da177e4SLinus Torvalds struct sock *sk; 4121da177e4SLinus Torvalds int err = 0; 4131da177e4SLinus Torvalds int padding; /* How much padding do we need? */ 41490017accSMarcelo Ricardo Leitner int pkt_size; 4151da177e4SLinus Torvalds __u8 has_data = 0; 41690017accSMarcelo Ricardo Leitner int gso = 0; 41790017accSMarcelo Ricardo Leitner int pktcount = 0; 4180438816eSwangweidong struct dst_entry *dst; 4194cd57c80SVlad Yasevich unsigned char *auth = NULL; /* pointer to auth in skb data */ 4201da177e4SLinus Torvalds 421bb33381dSDaniel Borkmann pr_debug("%s: packet:%p\n", __func__, packet); 4221da177e4SLinus Torvalds 4231da177e4SLinus Torvalds /* Do NOT generate a chunkless packet. */ 42479af02c2SDavid S. Miller if (list_empty(&packet->chunk_list)) 4251da177e4SLinus Torvalds return err; 4261da177e4SLinus Torvalds 4271da177e4SLinus Torvalds /* Set up convenience variables... */ 42879af02c2SDavid S. Miller chunk = list_entry(packet->chunk_list.next, struct sctp_chunk, list); 4291da177e4SLinus Torvalds sk = chunk->skb->sk; 4301da177e4SLinus Torvalds 43190017accSMarcelo Ricardo Leitner /* Allocate the head skb, or main one if not in GSO */ 43290017accSMarcelo Ricardo Leitner if (packet->size > tp->pathmtu && !packet->ipfragok) { 43390017accSMarcelo Ricardo Leitner if (sk_can_gso(sk)) { 43490017accSMarcelo Ricardo Leitner gso = 1; 43590017accSMarcelo Ricardo Leitner pkt_size = packet->overhead; 43690017accSMarcelo Ricardo Leitner } else { 43790017accSMarcelo Ricardo Leitner /* If this happens, we trash this packet and try 43890017accSMarcelo Ricardo Leitner * to build a new one, hopefully correct this 43990017accSMarcelo Ricardo Leitner * time. Application may notice this error. 44090017accSMarcelo Ricardo Leitner */ 44190017accSMarcelo Ricardo Leitner pr_err_once("Trying to GSO but underlying device doesn't support it."); 4421da177e4SLinus Torvalds goto nomem; 44390017accSMarcelo Ricardo Leitner } 44490017accSMarcelo Ricardo Leitner } else { 44590017accSMarcelo Ricardo Leitner pkt_size = packet->size; 44690017accSMarcelo Ricardo Leitner } 44790017accSMarcelo Ricardo Leitner head = alloc_skb(pkt_size + MAX_HEADER, gfp); 44890017accSMarcelo Ricardo Leitner if (!head) 44990017accSMarcelo Ricardo Leitner goto nomem; 45090017accSMarcelo Ricardo Leitner if (gso) { 45190017accSMarcelo Ricardo Leitner NAPI_GRO_CB(head)->last = head; 45290017accSMarcelo Ricardo Leitner skb_shinfo(head)->gso_type = sk->sk_gso_type; 45390017accSMarcelo Ricardo Leitner } 4541da177e4SLinus Torvalds 4551da177e4SLinus Torvalds /* Make sure the outbound skb has enough header room reserved. */ 45690017accSMarcelo Ricardo Leitner skb_reserve(head, packet->overhead + MAX_HEADER); 4571da177e4SLinus Torvalds 4581da177e4SLinus Torvalds /* Set the owning socket so that we know where to get the 4591da177e4SLinus Torvalds * destination IP address. 4601da177e4SLinus Torvalds */ 46190017accSMarcelo Ricardo Leitner sctp_packet_set_owner_w(head, sk); 4621da177e4SLinus Torvalds 463e0268868SNicolas Dichtel if (!sctp_transport_dst_check(tp)) { 464503b55fdSSridhar Samudrala sctp_transport_route(tp, NULL, sctp_sk(sk)); 465503b55fdSSridhar Samudrala if (asoc && (asoc->param_flags & SPP_PMTUD_ENABLE)) { 46602f3d4ceSDavid S. Miller sctp_assoc_sync_pmtu(sk, asoc); 467503b55fdSSridhar Samudrala } 468503b55fdSSridhar Samudrala } 469adf30907SEric Dumazet dst = dst_clone(tp->dst); 470ff0ac74aSWei Yongjun if (!dst) 471503b55fdSSridhar Samudrala goto no_route; 47290017accSMarcelo Ricardo Leitner skb_dst_set(head, dst); 473503b55fdSSridhar Samudrala 4741da177e4SLinus Torvalds /* Build the SCTP header. */ 47590017accSMarcelo Ricardo Leitner sh = (struct sctphdr *)skb_push(head, sizeof(struct sctphdr)); 47690017accSMarcelo Ricardo Leitner skb_reset_transport_header(head); 4771da177e4SLinus Torvalds sh->source = htons(packet->source_port); 4781da177e4SLinus Torvalds sh->dest = htons(packet->destination_port); 4791da177e4SLinus Torvalds 4801da177e4SLinus Torvalds /* From 6.8 Adler-32 Checksum Calculation: 4811da177e4SLinus Torvalds * After the packet is constructed (containing the SCTP common 4821da177e4SLinus Torvalds * header and one or more control or DATA chunks), the 4831da177e4SLinus Torvalds * transmitter shall: 4841da177e4SLinus Torvalds * 4851da177e4SLinus Torvalds * 1) Fill in the proper Verification Tag in the SCTP common 4861da177e4SLinus Torvalds * header and initialize the checksum field to 0's. 4871da177e4SLinus Torvalds */ 4881da177e4SLinus Torvalds sh->vtag = htonl(packet->vtag); 4891da177e4SLinus Torvalds sh->checksum = 0; 4901da177e4SLinus Torvalds 49190017accSMarcelo Ricardo Leitner pr_debug("***sctp_transmit_packet***\n"); 49290017accSMarcelo Ricardo Leitner 49390017accSMarcelo Ricardo Leitner do { 49490017accSMarcelo Ricardo Leitner /* Set up convenience variables... */ 49590017accSMarcelo Ricardo Leitner chunk = list_entry(packet->chunk_list.next, struct sctp_chunk, list); 49690017accSMarcelo Ricardo Leitner pktcount++; 49790017accSMarcelo Ricardo Leitner 49890017accSMarcelo Ricardo Leitner /* Calculate packet size, so it fits in PMTU. Leave 49990017accSMarcelo Ricardo Leitner * other chunks for the next packets. 5001da177e4SLinus Torvalds */ 50190017accSMarcelo Ricardo Leitner if (gso) { 50290017accSMarcelo Ricardo Leitner pkt_size = packet->overhead; 50390017accSMarcelo Ricardo Leitner list_for_each_entry(chunk, &packet->chunk_list, list) { 50490017accSMarcelo Ricardo Leitner int padded = WORD_ROUND(chunk->skb->len); 50590017accSMarcelo Ricardo Leitner 50690017accSMarcelo Ricardo Leitner if (pkt_size + padded > tp->pathmtu) 50790017accSMarcelo Ricardo Leitner break; 50890017accSMarcelo Ricardo Leitner pkt_size += padded; 50990017accSMarcelo Ricardo Leitner } 51090017accSMarcelo Ricardo Leitner 51190017accSMarcelo Ricardo Leitner /* Allocate a new skb. */ 51290017accSMarcelo Ricardo Leitner nskb = alloc_skb(pkt_size + MAX_HEADER, gfp); 51390017accSMarcelo Ricardo Leitner if (!nskb) 51490017accSMarcelo Ricardo Leitner goto nomem; 51590017accSMarcelo Ricardo Leitner 51690017accSMarcelo Ricardo Leitner /* Make sure the outbound skb has enough header 51790017accSMarcelo Ricardo Leitner * room reserved. 51890017accSMarcelo Ricardo Leitner */ 51990017accSMarcelo Ricardo Leitner skb_reserve(nskb, packet->overhead + MAX_HEADER); 52090017accSMarcelo Ricardo Leitner } else { 52190017accSMarcelo Ricardo Leitner nskb = head; 52290017accSMarcelo Ricardo Leitner } 5231da177e4SLinus Torvalds 5241da177e4SLinus Torvalds /** 5251da177e4SLinus Torvalds * 3.2 Chunk Field Descriptions 5261da177e4SLinus Torvalds * 5271da177e4SLinus Torvalds * The total length of a chunk (including Type, Length and 5281da177e4SLinus Torvalds * Value fields) MUST be a multiple of 4 bytes. If the length 5291da177e4SLinus Torvalds * of the chunk is not a multiple of 4 bytes, the sender MUST 5301da177e4SLinus Torvalds * pad the chunk with all zero bytes and this padding is not 5311da177e4SLinus Torvalds * included in the chunk length field. The sender should 5321da177e4SLinus Torvalds * never pad with more than 3 bytes. 5331da177e4SLinus Torvalds * 5341da177e4SLinus Torvalds * [This whole comment explains WORD_ROUND() below.] 5351da177e4SLinus Torvalds */ 536bb33381dSDaniel Borkmann 53790017accSMarcelo Ricardo Leitner pkt_size -= packet->overhead; 53879af02c2SDavid S. Miller list_for_each_entry_safe(chunk, tmp, &packet->chunk_list, list) { 53979af02c2SDavid S. Miller list_del_init(&chunk->list); 5401da177e4SLinus Torvalds if (sctp_chunk_is_data(chunk)) { 5411da177e4SLinus Torvalds /* 6.3.1 C4) When data is in flight and when allowed 5421da177e4SLinus Torvalds * by rule C5, a new RTT measurement MUST be made each 5431da177e4SLinus Torvalds * round trip. Furthermore, new RTT measurements 5441da177e4SLinus Torvalds * SHOULD be made no more than once per round-trip 5451da177e4SLinus Torvalds * for a given destination transport address. 5461da177e4SLinus Torvalds */ 5471da177e4SLinus Torvalds 5486eabca54SXufeng Zhang if (!chunk->resent && !tp->rto_pending) { 5491da177e4SLinus Torvalds chunk->rtt_in_progress = 1; 5501da177e4SLinus Torvalds tp->rto_pending = 1; 5511da177e4SLinus Torvalds } 5526eabca54SXufeng Zhang 5531da177e4SLinus Torvalds has_data = 1; 5541da177e4SLinus Torvalds } 5551da177e4SLinus Torvalds 5561da177e4SLinus Torvalds padding = WORD_ROUND(chunk->skb->len) - chunk->skb->len; 5571da177e4SLinus Torvalds if (padding) 5581da177e4SLinus Torvalds memset(skb_put(chunk->skb, padding), 0, padding); 5591da177e4SLinus Torvalds 5604cd57c80SVlad Yasevich /* if this is the auth chunk that we are adding, 5614cd57c80SVlad Yasevich * store pointer where it will be added and put 5624cd57c80SVlad Yasevich * the auth into the packet. 5634cd57c80SVlad Yasevich */ 5644cd57c80SVlad Yasevich if (chunk == packet->auth) 5654cd57c80SVlad Yasevich auth = skb_tail_pointer(nskb); 5664cd57c80SVlad Yasevich 567503b55fdSSridhar Samudrala memcpy(skb_put(nskb, chunk->skb->len), 568503b55fdSSridhar Samudrala chunk->skb->data, chunk->skb->len); 5691da177e4SLinus Torvalds 57090017accSMarcelo Ricardo Leitner pr_debug("*** Chunk:%p[%s] %s 0x%x, length:%d, chunk->skb->len:%d, rtt_in_progress:%d\n", 57190017accSMarcelo Ricardo Leitner chunk, 572bb33381dSDaniel Borkmann sctp_cname(SCTP_ST_CHUNK(chunk->chunk_hdr->type)), 5731da177e4SLinus Torvalds chunk->has_tsn ? "TSN" : "No TSN", 574bb33381dSDaniel Borkmann chunk->has_tsn ? ntohl(chunk->subh.data_hdr->tsn) : 0, 575bb33381dSDaniel Borkmann ntohs(chunk->chunk_hdr->length), chunk->skb->len, 576bb33381dSDaniel Borkmann chunk->rtt_in_progress); 5771da177e4SLinus Torvalds 57890017accSMarcelo Ricardo Leitner /* If this is a control chunk, this is our last 5791da177e4SLinus Torvalds * reference. Free data chunks after they've been 5801da177e4SLinus Torvalds * acknowledged or have failed. 58190017accSMarcelo Ricardo Leitner * Re-queue auth chunks if needed. 5821da177e4SLinus Torvalds */ 58390017accSMarcelo Ricardo Leitner pkt_size -= WORD_ROUND(chunk->skb->len); 58490017accSMarcelo Ricardo Leitner 58590017accSMarcelo Ricardo Leitner if (chunk == packet->auth && !list_empty(&packet->chunk_list)) 58690017accSMarcelo Ricardo Leitner list_add(&chunk->list, &packet->chunk_list); 58790017accSMarcelo Ricardo Leitner else if (!sctp_chunk_is_data(chunk)) 5881da177e4SLinus Torvalds sctp_chunk_free(chunk); 58990017accSMarcelo Ricardo Leitner 59090017accSMarcelo Ricardo Leitner if (!pkt_size) 59190017accSMarcelo Ricardo Leitner break; 5921da177e4SLinus Torvalds } 5931da177e4SLinus Torvalds 5944cd57c80SVlad Yasevich /* SCTP-AUTH, Section 6.2 5954cd57c80SVlad Yasevich * The sender MUST calculate the MAC as described in RFC2104 [2] 5964cd57c80SVlad Yasevich * using the hash function H as described by the MAC Identifier and 5974cd57c80SVlad Yasevich * the shared association key K based on the endpoint pair shared key 5984cd57c80SVlad Yasevich * described by the shared key identifier. The 'data' used for the 5994cd57c80SVlad Yasevich * computation of the AUTH-chunk is given by the AUTH chunk with its 6004cd57c80SVlad Yasevich * HMAC field set to zero (as shown in Figure 6) followed by all 6014cd57c80SVlad Yasevich * chunks that are placed after the AUTH chunk in the SCTP packet. 6024cd57c80SVlad Yasevich */ 6034cd57c80SVlad Yasevich if (auth) 6044cd57c80SVlad Yasevich sctp_auth_calculate_hmac(asoc, nskb, 6054cd57c80SVlad Yasevich (struct sctp_auth_chunk *)auth, 60628fd3498SMarcelo Ricardo Leitner gfp); 6074cd57c80SVlad Yasevich 60890017accSMarcelo Ricardo Leitner if (!gso) 60990017accSMarcelo Ricardo Leitner break; 61090017accSMarcelo Ricardo Leitner 61190017accSMarcelo Ricardo Leitner if (skb_gro_receive(&head, nskb)) 61290017accSMarcelo Ricardo Leitner goto nomem; 61390017accSMarcelo Ricardo Leitner nskb = NULL; 61490017accSMarcelo Ricardo Leitner if (WARN_ON_ONCE(skb_shinfo(head)->gso_segs >= 61590017accSMarcelo Ricardo Leitner sk->sk_gso_max_segs)) 61690017accSMarcelo Ricardo Leitner goto nomem; 61790017accSMarcelo Ricardo Leitner } while (!list_empty(&packet->chunk_list)); 61890017accSMarcelo Ricardo Leitner 6194cd57c80SVlad Yasevich /* 2) Calculate the Adler-32 checksum of the whole packet, 6204cd57c80SVlad Yasevich * including the SCTP common header and all the 6214cd57c80SVlad Yasevich * chunks. 6224cd57c80SVlad Yasevich * 6234cd57c80SVlad Yasevich * Note: Adler-32 is no longer applicable, as has been replaced 6244cd57c80SVlad Yasevich * by CRC32-C as described in <draft-ietf-tsvwg-sctpcsum-02.txt>. 62590017accSMarcelo Ricardo Leitner * 62690017accSMarcelo Ricardo Leitner * If it's a GSO packet, it's postponed to sctp_skb_segment. 6274cd57c80SVlad Yasevich */ 62890017accSMarcelo Ricardo Leitner if (!sctp_checksum_disable || gso) { 62990017accSMarcelo Ricardo Leitner if (!gso && (!(dst->dev->features & NETIF_F_SCTP_CRC) || 63090017accSMarcelo Ricardo Leitner dst_xfrm(dst) || packet->ipfragok)) { 63190017accSMarcelo Ricardo Leitner sh->checksum = sctp_compute_cksum(head, 0); 6328dc92f7eSJesse Brandeburg } else { 63325985edcSLucas De Marchi /* no need to seed pseudo checksum for SCTP */ 63490017accSMarcelo Ricardo Leitner head->ip_summed = CHECKSUM_PARTIAL; 63590017accSMarcelo Ricardo Leitner head->csum_start = skb_transport_header(head) - head->head; 63690017accSMarcelo Ricardo Leitner head->csum_offset = offsetof(struct sctphdr, checksum); 6378dc92f7eSJesse Brandeburg } 6388dc92f7eSJesse Brandeburg } 6391da177e4SLinus Torvalds 6401da177e4SLinus Torvalds /* IP layer ECN support 6411da177e4SLinus Torvalds * From RFC 2481 6421da177e4SLinus Torvalds * "The ECN-Capable Transport (ECT) bit would be set by the 6431da177e4SLinus Torvalds * data sender to indicate that the end-points of the 6441da177e4SLinus Torvalds * transport protocol are ECN-capable." 6451da177e4SLinus Torvalds * 6461da177e4SLinus Torvalds * Now setting the ECT bit all the time, as it should not cause 6471da177e4SLinus Torvalds * any problems protocol-wise even if our peer ignores it. 6481da177e4SLinus Torvalds * 6491da177e4SLinus Torvalds * Note: The works for IPv6 layer checks this bit too later 6501da177e4SLinus Torvalds * in transmission. See IP6_ECN_flow_xmit(). 6511da177e4SLinus Torvalds */ 65290017accSMarcelo Ricardo Leitner tp->af_specific->ecn_capable(sk); 6531da177e4SLinus Torvalds 6541da177e4SLinus Torvalds /* Set up the IP options. */ 6551da177e4SLinus Torvalds /* BUG: not implemented 6561da177e4SLinus Torvalds * For v4 this all lives somewhere in sk->sk_opt... 6571da177e4SLinus Torvalds */ 6581da177e4SLinus Torvalds 6591da177e4SLinus Torvalds /* Dump that on IP! */ 660196d6759SMichele Baldessari if (asoc) { 66190017accSMarcelo Ricardo Leitner asoc->stats.opackets += pktcount; 662196d6759SMichele Baldessari if (asoc->peer.last_sent_to != tp) 6631da177e4SLinus Torvalds /* Considering the multiple CPU scenario, this is a 6641da177e4SLinus Torvalds * "correcter" place for last_sent_to. --xguo 6651da177e4SLinus Torvalds */ 6661da177e4SLinus Torvalds asoc->peer.last_sent_to = tp; 6671da177e4SLinus Torvalds } 6681da177e4SLinus Torvalds 6691da177e4SLinus Torvalds if (has_data) { 6701da177e4SLinus Torvalds struct timer_list *timer; 6711da177e4SLinus Torvalds unsigned long timeout; 6721da177e4SLinus Torvalds 6731da177e4SLinus Torvalds /* Restart the AUTOCLOSE timer when sending data. */ 6749f70f46bSNeil Horman if (sctp_state(asoc, ESTABLISHED) && 6759f70f46bSNeil Horman asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE]) { 6761da177e4SLinus Torvalds timer = &asoc->timers[SCTP_EVENT_TIMEOUT_AUTOCLOSE]; 6771da177e4SLinus Torvalds timeout = asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE]; 6781da177e4SLinus Torvalds 6791da177e4SLinus Torvalds if (!mod_timer(timer, jiffies + timeout)) 6801da177e4SLinus Torvalds sctp_association_hold(asoc); 6811da177e4SLinus Torvalds } 6821da177e4SLinus Torvalds } 6831da177e4SLinus Torvalds 68490017accSMarcelo Ricardo Leitner pr_debug("***sctp_transmit_packet*** skb->len:%d\n", head->len); 6851da177e4SLinus Torvalds 68690017accSMarcelo Ricardo Leitner if (gso) { 68790017accSMarcelo Ricardo Leitner /* Cleanup our debris for IP stacks */ 68890017accSMarcelo Ricardo Leitner memset(head->cb, 0, max(sizeof(struct inet_skb_parm), 68990017accSMarcelo Ricardo Leitner sizeof(struct inet6_skb_parm))); 69090017accSMarcelo Ricardo Leitner 69190017accSMarcelo Ricardo Leitner skb_shinfo(head)->gso_segs = pktcount; 69290017accSMarcelo Ricardo Leitner skb_shinfo(head)->gso_size = GSO_BY_FRAGS; 69390017accSMarcelo Ricardo Leitner 69490017accSMarcelo Ricardo Leitner /* We have to refresh this in case we are xmiting to 69590017accSMarcelo Ricardo Leitner * more than one transport at a time 69690017accSMarcelo Ricardo Leitner */ 69790017accSMarcelo Ricardo Leitner rcu_read_lock(); 69890017accSMarcelo Ricardo Leitner if (__sk_dst_get(sk) != tp->dst) { 69990017accSMarcelo Ricardo Leitner dst_hold(tp->dst); 70090017accSMarcelo Ricardo Leitner sk_setup_caps(sk, tp->dst); 70190017accSMarcelo Ricardo Leitner } 70290017accSMarcelo Ricardo Leitner rcu_read_unlock(); 70390017accSMarcelo Ricardo Leitner } 70490017accSMarcelo Ricardo Leitner head->ignore_df = packet->ipfragok; 70590017accSMarcelo Ricardo Leitner tp->af_specific->sctp_xmit(head, tp); 7061da177e4SLinus Torvalds 7071da177e4SLinus Torvalds out: 708d521c08fSWei Yongjun sctp_packet_reset(packet); 7091da177e4SLinus Torvalds return err; 7101da177e4SLinus Torvalds no_route: 71190017accSMarcelo Ricardo Leitner kfree_skb(head); 71290017accSMarcelo Ricardo Leitner if (nskb != head) 7131da177e4SLinus Torvalds kfree_skb(nskb); 71429c4afc4SAlexander Sverdlin 71529c4afc4SAlexander Sverdlin if (asoc) 716757efd32SEric Dumazet IP_INC_STATS(sock_net(asoc->base.sk), IPSTATS_MIB_OUTNOROUTES); 7171da177e4SLinus Torvalds 7181da177e4SLinus Torvalds /* FIXME: Returning the 'err' will effect all the associations 7191da177e4SLinus Torvalds * associated with a socket, although only one of the paths of the 7201da177e4SLinus Torvalds * association is unreachable. 7211da177e4SLinus Torvalds * The real failure of a transport or association can be passed on 7221da177e4SLinus Torvalds * to the user via notifications. So setting this error may not be 7231da177e4SLinus Torvalds * required. 7241da177e4SLinus Torvalds */ 7251da177e4SLinus Torvalds /* err = -EHOSTUNREACH; */ 7261da177e4SLinus Torvalds err: 7271da177e4SLinus Torvalds /* Control chunks are unreliable so just drop them. DATA chunks 7281da177e4SLinus Torvalds * will get resent or dropped later. 7291da177e4SLinus Torvalds */ 7301da177e4SLinus Torvalds 73179af02c2SDavid S. Miller list_for_each_entry_safe(chunk, tmp, &packet->chunk_list, list) { 73279af02c2SDavid S. Miller list_del_init(&chunk->list); 7331da177e4SLinus Torvalds if (!sctp_chunk_is_data(chunk)) 7341da177e4SLinus Torvalds sctp_chunk_free(chunk); 7351da177e4SLinus Torvalds } 7361da177e4SLinus Torvalds goto out; 7371da177e4SLinus Torvalds nomem: 7381da177e4SLinus Torvalds err = -ENOMEM; 7391da177e4SLinus Torvalds goto err; 7401da177e4SLinus Torvalds } 7411da177e4SLinus Torvalds 7421da177e4SLinus Torvalds /******************************************************************** 7431da177e4SLinus Torvalds * 2nd Level Abstractions 7441da177e4SLinus Torvalds ********************************************************************/ 7451da177e4SLinus Torvalds 746e83963b7SVlad Yasevich /* This private function check to see if a chunk can be added */ 747e83963b7SVlad Yasevich static sctp_xmit_t sctp_packet_can_append_data(struct sctp_packet *packet, 7481da177e4SLinus Torvalds struct sctp_chunk *chunk) 7491da177e4SLinus Torvalds { 750e83963b7SVlad Yasevich size_t datasize, rwnd, inflight, flight_size; 7511da177e4SLinus Torvalds struct sctp_transport *transport = packet->transport; 7521da177e4SLinus Torvalds struct sctp_association *asoc = transport->asoc; 7531da177e4SLinus Torvalds struct sctp_outq *q = &asoc->outqueue; 7541da177e4SLinus Torvalds 7551da177e4SLinus Torvalds /* RFC 2960 6.1 Transmission of DATA Chunks 7561da177e4SLinus Torvalds * 7571da177e4SLinus Torvalds * A) At any given time, the data sender MUST NOT transmit new data to 7581da177e4SLinus Torvalds * any destination transport address if its peer's rwnd indicates 7591da177e4SLinus Torvalds * that the peer has no buffer space (i.e. rwnd is 0, see Section 7601da177e4SLinus Torvalds * 6.2.1). However, regardless of the value of rwnd (including if it 7611da177e4SLinus Torvalds * is 0), the data sender can always have one DATA chunk in flight to 7621da177e4SLinus Torvalds * the receiver if allowed by cwnd (see rule B below). This rule 7631da177e4SLinus Torvalds * allows the sender to probe for a change in rwnd that the sender 7641da177e4SLinus Torvalds * missed due to the SACK having been lost in transit from the data 7651da177e4SLinus Torvalds * receiver to the data sender. 7661da177e4SLinus Torvalds */ 7671da177e4SLinus Torvalds 7681da177e4SLinus Torvalds rwnd = asoc->peer.rwnd; 769e83963b7SVlad Yasevich inflight = q->outstanding_bytes; 770e83963b7SVlad Yasevich flight_size = transport->flight_size; 7711da177e4SLinus Torvalds 7721da177e4SLinus Torvalds datasize = sctp_data_size(chunk); 7731da177e4SLinus Torvalds 774723189faSDavid Laight if (datasize > rwnd && inflight > 0) 7751da177e4SLinus Torvalds /* We have (at least) one data chunk in flight, 7761da177e4SLinus Torvalds * so we can't fall back to rule 6.1 B). 7771da177e4SLinus Torvalds */ 778723189faSDavid Laight return SCTP_XMIT_RWND_FULL; 7791da177e4SLinus Torvalds 7801da177e4SLinus Torvalds /* RFC 2960 6.1 Transmission of DATA Chunks 7811da177e4SLinus Torvalds * 7821da177e4SLinus Torvalds * B) At any given time, the sender MUST NOT transmit new data 7831da177e4SLinus Torvalds * to a given transport address if it has cwnd or more bytes 7841da177e4SLinus Torvalds * of data outstanding to that transport address. 7851da177e4SLinus Torvalds */ 7861da177e4SLinus Torvalds /* RFC 7.2.4 & the Implementers Guide 2.8. 7871da177e4SLinus Torvalds * 7881da177e4SLinus Torvalds * 3) ... 7891da177e4SLinus Torvalds * When a Fast Retransmit is being performed the sender SHOULD 7901da177e4SLinus Torvalds * ignore the value of cwnd and SHOULD NOT delay retransmission. 7911da177e4SLinus Torvalds */ 792723189faSDavid Laight if (chunk->fast_retransmit != SCTP_NEED_FRTX && 793723189faSDavid Laight flight_size >= transport->cwnd) 794723189faSDavid Laight return SCTP_XMIT_RWND_FULL; 7951da177e4SLinus Torvalds 7961da177e4SLinus Torvalds /* Nagle's algorithm to solve small-packet problem: 7971da177e4SLinus Torvalds * Inhibit the sending of new chunks when new outgoing data arrives 7981da177e4SLinus Torvalds * if any previously transmitted data on the connection remains 7991da177e4SLinus Torvalds * unacknowledged. 8001da177e4SLinus Torvalds */ 8011da177e4SLinus Torvalds 802723189faSDavid Laight if (sctp_sk(asoc->base.sk)->nodelay) 803723189faSDavid Laight /* Nagle disabled */ 804723189faSDavid Laight return SCTP_XMIT_OK; 805723189faSDavid Laight 806723189faSDavid Laight if (!sctp_packet_empty(packet)) 807723189faSDavid Laight /* Append to packet */ 808723189faSDavid Laight return SCTP_XMIT_OK; 809723189faSDavid Laight 810723189faSDavid Laight if (inflight == 0) 811723189faSDavid Laight /* Nothing unacked */ 812723189faSDavid Laight return SCTP_XMIT_OK; 813723189faSDavid Laight 814723189faSDavid Laight if (!sctp_state(asoc, ESTABLISHED)) 815723189faSDavid Laight return SCTP_XMIT_OK; 816723189faSDavid Laight 817723189faSDavid Laight /* Check whether this chunk and all the rest of pending data will fit 818723189faSDavid Laight * or delay in hopes of bundling a full sized packet. 8191da177e4SLinus Torvalds */ 820e43569e6SMarcelo Ricardo Leitner if (chunk->skb->len + q->out_qlen > 821e43569e6SMarcelo Ricardo Leitner transport->pathmtu - packet->overhead - sizeof(sctp_data_chunk_t) - 4) 822723189faSDavid Laight /* Enough data queued to fill a packet */ 823723189faSDavid Laight return SCTP_XMIT_OK; 8241da177e4SLinus Torvalds 825723189faSDavid Laight /* Don't delay large message writes that may have been fragmented */ 826723189faSDavid Laight if (!chunk->msg->can_delay) 827723189faSDavid Laight return SCTP_XMIT_OK; 828723189faSDavid Laight 829723189faSDavid Laight /* Defer until all data acked or packet full */ 830526cbef7SDavid Laight return SCTP_XMIT_DELAY; 831e83963b7SVlad Yasevich } 832e83963b7SVlad Yasevich 833e83963b7SVlad Yasevich /* This private function does management things when adding DATA chunk */ 834e83963b7SVlad Yasevich static void sctp_packet_append_data(struct sctp_packet *packet, 835e83963b7SVlad Yasevich struct sctp_chunk *chunk) 836e83963b7SVlad Yasevich { 837e83963b7SVlad Yasevich struct sctp_transport *transport = packet->transport; 838e83963b7SVlad Yasevich size_t datasize = sctp_data_size(chunk); 839e83963b7SVlad Yasevich struct sctp_association *asoc = transport->asoc; 840e83963b7SVlad Yasevich u32 rwnd = asoc->peer.rwnd; 841e83963b7SVlad Yasevich 8421da177e4SLinus Torvalds /* Keep track of how many bytes are in flight over this transport. */ 8431da177e4SLinus Torvalds transport->flight_size += datasize; 8441da177e4SLinus Torvalds 8451da177e4SLinus Torvalds /* Keep track of how many bytes are in flight to the receiver. */ 8461da177e4SLinus Torvalds asoc->outqueue.outstanding_bytes += datasize; 8471da177e4SLinus Torvalds 848a76c0adfSThomas Graf /* Update our view of the receiver's rwnd. */ 8491da177e4SLinus Torvalds if (datasize < rwnd) 8501da177e4SLinus Torvalds rwnd -= datasize; 8511da177e4SLinus Torvalds else 8521da177e4SLinus Torvalds rwnd = 0; 8531da177e4SLinus Torvalds 8541da177e4SLinus Torvalds asoc->peer.rwnd = rwnd; 8551da177e4SLinus Torvalds /* Has been accepted for transmission. */ 8561da177e4SLinus Torvalds if (!asoc->peer.prsctp_capable) 8571da177e4SLinus Torvalds chunk->msg->can_abandon = 0; 858d8dd1578SNeil Horman sctp_chunk_assign_tsn(chunk); 859d8dd1578SNeil Horman sctp_chunk_assign_ssn(chunk); 860e83963b7SVlad Yasevich } 8611da177e4SLinus Torvalds 862e83963b7SVlad Yasevich static sctp_xmit_t sctp_packet_will_fit(struct sctp_packet *packet, 863e83963b7SVlad Yasevich struct sctp_chunk *chunk, 864e83963b7SVlad Yasevich u16 chunk_len) 865e83963b7SVlad Yasevich { 86690017accSMarcelo Ricardo Leitner size_t psize, pmtu; 867e83963b7SVlad Yasevich sctp_xmit_t retval = SCTP_XMIT_OK; 868e83963b7SVlad Yasevich 869e83963b7SVlad Yasevich psize = packet->size; 87090017accSMarcelo Ricardo Leitner if (packet->transport->asoc) 87190017accSMarcelo Ricardo Leitner pmtu = packet->transport->asoc->pathmtu; 87290017accSMarcelo Ricardo Leitner else 87390017accSMarcelo Ricardo Leitner pmtu = packet->transport->pathmtu; 874e83963b7SVlad Yasevich 875e83963b7SVlad Yasevich /* Decide if we need to fragment or resubmit later. */ 87690017accSMarcelo Ricardo Leitner if (psize + chunk_len > pmtu) { 87790017accSMarcelo Ricardo Leitner /* It's OK to fragment at IP level if any one of the following 878e83963b7SVlad Yasevich * is true: 879e83963b7SVlad Yasevich * 1. The packet is empty (meaning this chunk is greater 880e83963b7SVlad Yasevich * the MTU) 88190017accSMarcelo Ricardo Leitner * 2. The packet doesn't have any data in it yet and data 882e83963b7SVlad Yasevich * requires authentication. 883e83963b7SVlad Yasevich */ 88490017accSMarcelo Ricardo Leitner if (sctp_packet_empty(packet) || 885e83963b7SVlad Yasevich (!packet->has_data && chunk->auth)) { 886e83963b7SVlad Yasevich /* We no longer do re-fragmentation. 887e83963b7SVlad Yasevich * Just fragment at the IP layer, if we 888e83963b7SVlad Yasevich * actually hit this condition 889e83963b7SVlad Yasevich */ 890e83963b7SVlad Yasevich packet->ipfragok = 1; 89190017accSMarcelo Ricardo Leitner goto out; 892e83963b7SVlad Yasevich } 893e83963b7SVlad Yasevich 89490017accSMarcelo Ricardo Leitner /* It is also okay to fragment if the chunk we are 89590017accSMarcelo Ricardo Leitner * adding is a control chunk, but only if current packet 89690017accSMarcelo Ricardo Leitner * is not a GSO one otherwise it causes fragmentation of 89790017accSMarcelo Ricardo Leitner * a large frame. So in this case we allow the 89890017accSMarcelo Ricardo Leitner * fragmentation by forcing it to be in a new packet. 89990017accSMarcelo Ricardo Leitner */ 90090017accSMarcelo Ricardo Leitner if (!sctp_chunk_is_data(chunk) && packet->has_data) 90190017accSMarcelo Ricardo Leitner retval = SCTP_XMIT_PMTU_FULL; 90290017accSMarcelo Ricardo Leitner 90390017accSMarcelo Ricardo Leitner if (psize + chunk_len > packet->max_size) 90490017accSMarcelo Ricardo Leitner /* Hit GSO/PMTU limit, gotta flush */ 90590017accSMarcelo Ricardo Leitner retval = SCTP_XMIT_PMTU_FULL; 90690017accSMarcelo Ricardo Leitner 90790017accSMarcelo Ricardo Leitner if (!packet->transport->burst_limited && 90890017accSMarcelo Ricardo Leitner psize + chunk_len > (packet->transport->cwnd >> 1)) 90990017accSMarcelo Ricardo Leitner /* Do not allow a single GSO packet to use more 91090017accSMarcelo Ricardo Leitner * than half of cwnd. 91190017accSMarcelo Ricardo Leitner */ 91290017accSMarcelo Ricardo Leitner retval = SCTP_XMIT_PMTU_FULL; 91390017accSMarcelo Ricardo Leitner 91490017accSMarcelo Ricardo Leitner if (packet->transport->burst_limited && 91590017accSMarcelo Ricardo Leitner psize + chunk_len > (packet->transport->burst_limited >> 1)) 91690017accSMarcelo Ricardo Leitner /* Do not allow a single GSO packet to use more 91790017accSMarcelo Ricardo Leitner * than half of original cwnd. 91890017accSMarcelo Ricardo Leitner */ 91990017accSMarcelo Ricardo Leitner retval = SCTP_XMIT_PMTU_FULL; 92090017accSMarcelo Ricardo Leitner /* Otherwise it will fit in the GSO packet */ 92190017accSMarcelo Ricardo Leitner } 92290017accSMarcelo Ricardo Leitner 92390017accSMarcelo Ricardo Leitner out: 9241da177e4SLinus Torvalds return retval; 9251da177e4SLinus Torvalds } 926