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. */ 6086b36f2aSXin Long static enum sctp_xmit __sctp_packet_append_chunk(struct sctp_packet *packet, 61ed106277SNeil Horman struct sctp_chunk *chunk); 6286b36f2aSXin Long static enum sctp_xmit 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); 6686b36f2aSXin Long static enum sctp_xmit 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 */ 8466b91d2cSMarcelo Ricardo Leitner void sctp_packet_config(struct sctp_packet *packet, __u32 vtag, 8566b91d2cSMarcelo Ricardo Leitner int ecn_capable) 861da177e4SLinus Torvalds { 8790017accSMarcelo Ricardo Leitner struct sctp_transport *tp = packet->transport; 8890017accSMarcelo Ricardo Leitner struct sctp_association *asoc = tp->asoc; 89df2729c3SXin Long struct sock *sk; 901da177e4SLinus Torvalds 91bb33381dSDaniel Borkmann pr_debug("%s: packet:%p vtag:0x%x\n", __func__, packet, vtag); 921da177e4SLinus Torvalds packet->vtag = vtag; 931da177e4SLinus Torvalds 94df2729c3SXin Long /* do the following jobs only once for a flush schedule */ 95df2729c3SXin Long if (!sctp_packet_empty(packet)) 96df2729c3SXin Long return; 9790017accSMarcelo Ricardo Leitner 98df2729c3SXin Long /* set packet max_size with pathmtu */ 99df2729c3SXin Long packet->max_size = tp->pathmtu; 100df2729c3SXin Long if (!asoc) 101df2729c3SXin Long return; 102df2729c3SXin Long 103df2729c3SXin Long /* update dst or transport pathmtu if in need */ 104df2729c3SXin Long sk = asoc->base.sk; 105df2729c3SXin Long if (!sctp_transport_dst_check(tp)) { 106df2729c3SXin Long sctp_transport_route(tp, NULL, sctp_sk(sk)); 107df2729c3SXin Long if (asoc->param_flags & SPP_PMTUD_ENABLE) 1083ebfdf08SXin Long sctp_assoc_sync_pmtu(asoc); 109df2729c3SXin Long } else if (!sctp_transport_pmtu_check(tp)) { 110df2729c3SXin Long if (asoc->param_flags & SPP_PMTUD_ENABLE) 1113ebfdf08SXin Long sctp_assoc_sync_pmtu(asoc); 112df2729c3SXin Long } 113df2729c3SXin Long 114df2729c3SXin Long /* If there a is a prepend chunk stick it on the list before 115df2729c3SXin Long * any other chunks get appended. 116df2729c3SXin Long */ 117df2729c3SXin Long if (ecn_capable) { 118df2729c3SXin Long struct sctp_chunk *chunk = sctp_get_ecne_prepend(asoc); 119df2729c3SXin Long 120df2729c3SXin Long if (chunk) 121df2729c3SXin Long sctp_packet_append_chunk(packet, chunk); 122df2729c3SXin Long } 123df2729c3SXin Long 124df2729c3SXin Long if (!tp->dst) 125df2729c3SXin Long return; 126df2729c3SXin Long 127df2729c3SXin Long /* set packet max_size with gso_max_size if gso is enabled*/ 12890017accSMarcelo Ricardo Leitner rcu_read_lock(); 12990017accSMarcelo Ricardo Leitner if (__sk_dst_get(sk) != tp->dst) { 13090017accSMarcelo Ricardo Leitner dst_hold(tp->dst); 13190017accSMarcelo Ricardo Leitner sk_setup_caps(sk, tp->dst); 13290017accSMarcelo Ricardo Leitner } 133df2729c3SXin Long packet->max_size = sk_can_gso(sk) ? tp->dst->dev->gso_max_size 134df2729c3SXin Long : asoc->pathmtu; 13590017accSMarcelo Ricardo Leitner rcu_read_unlock(); 1361da177e4SLinus Torvalds } 1371da177e4SLinus Torvalds 1381da177e4SLinus Torvalds /* Initialize the packet structure. */ 13966b91d2cSMarcelo Ricardo Leitner void sctp_packet_init(struct sctp_packet *packet, 1401da177e4SLinus Torvalds struct sctp_transport *transport, 1411da177e4SLinus Torvalds __u16 sport, __u16 dport) 1421da177e4SLinus Torvalds { 1431da177e4SLinus Torvalds struct sctp_association *asoc = transport->asoc; 1441da177e4SLinus Torvalds size_t overhead; 1451da177e4SLinus Torvalds 146bb33381dSDaniel Borkmann pr_debug("%s: packet:%p transport:%p\n", __func__, packet, transport); 1471da177e4SLinus Torvalds 1481da177e4SLinus Torvalds packet->transport = transport; 1491da177e4SLinus Torvalds packet->source_port = sport; 1501da177e4SLinus Torvalds packet->destination_port = dport; 15179af02c2SDavid S. Miller INIT_LIST_HEAD(&packet->chunk_list); 1521da177e4SLinus Torvalds if (asoc) { 1531da177e4SLinus Torvalds struct sctp_sock *sp = sctp_sk(asoc->base.sk); 1541da177e4SLinus Torvalds overhead = sp->pf->af->net_header_len; 1551da177e4SLinus Torvalds } else { 1561da177e4SLinus Torvalds overhead = sizeof(struct ipv6hdr); 1571da177e4SLinus Torvalds } 1581da177e4SLinus Torvalds overhead += sizeof(struct sctphdr); 1591da177e4SLinus Torvalds packet->overhead = overhead; 160be297143SWei Yongjun sctp_packet_reset(packet); 1611da177e4SLinus Torvalds packet->vtag = 0; 1621da177e4SLinus Torvalds } 1631da177e4SLinus Torvalds 1641da177e4SLinus Torvalds /* Free a packet. */ 1651da177e4SLinus Torvalds void sctp_packet_free(struct sctp_packet *packet) 1661da177e4SLinus Torvalds { 16779af02c2SDavid S. Miller struct sctp_chunk *chunk, *tmp; 1681da177e4SLinus Torvalds 169bb33381dSDaniel Borkmann pr_debug("%s: packet:%p\n", __func__, packet); 1701da177e4SLinus Torvalds 17179af02c2SDavid S. Miller list_for_each_entry_safe(chunk, tmp, &packet->chunk_list, list) { 17279af02c2SDavid S. Miller list_del_init(&chunk->list); 1731da177e4SLinus Torvalds sctp_chunk_free(chunk); 17479af02c2SDavid S. Miller } 1751da177e4SLinus Torvalds } 1761da177e4SLinus Torvalds 1771da177e4SLinus Torvalds /* This routine tries to append the chunk to the offered packet. If adding 1781da177e4SLinus Torvalds * the chunk causes the packet to exceed the path MTU and COOKIE_ECHO chunk 1791da177e4SLinus Torvalds * is not present in the packet, it transmits the input packet. 1801da177e4SLinus Torvalds * Data can be bundled with a packet containing a COOKIE_ECHO chunk as long 1811da177e4SLinus Torvalds * as it can fit in the packet, but any more data that does not fit in this 1821da177e4SLinus Torvalds * packet can be sent only after receiving the COOKIE_ACK. 1831da177e4SLinus Torvalds */ 18486b36f2aSXin Long enum sctp_xmit sctp_packet_transmit_chunk(struct sctp_packet *packet, 1852e3216cdSVlad Yasevich struct sctp_chunk *chunk, 186cea8768fSMarcelo Ricardo Leitner int one_packet, gfp_t gfp) 1871da177e4SLinus Torvalds { 18886b36f2aSXin Long enum sctp_xmit retval; 1891da177e4SLinus Torvalds 1905b5e0928SAlexey Dobriyan pr_debug("%s: packet:%p size:%zu chunk:%p size:%d\n", __func__, 191942b3235SMarcelo Ricardo Leitner packet, packet->size, chunk, chunk->skb ? chunk->skb->len : -1); 1921da177e4SLinus Torvalds 1931da177e4SLinus Torvalds switch ((retval = (sctp_packet_append_chunk(packet, chunk)))) { 1941da177e4SLinus Torvalds case SCTP_XMIT_PMTU_FULL: 1951da177e4SLinus Torvalds if (!packet->has_cookie_echo) { 19664519440SXin Long int error = 0; 19764519440SXin Long 198cea8768fSMarcelo Ricardo Leitner error = sctp_packet_transmit(packet, gfp); 1991da177e4SLinus Torvalds if (error < 0) 2001da177e4SLinus Torvalds chunk->skb->sk->sk_err = -error; 2011da177e4SLinus Torvalds 2021da177e4SLinus Torvalds /* If we have an empty packet, then we can NOT ever 2031da177e4SLinus Torvalds * return PMTU_FULL. 2041da177e4SLinus Torvalds */ 2052e3216cdSVlad Yasevich if (!one_packet) 2062e3216cdSVlad Yasevich retval = sctp_packet_append_chunk(packet, 2072e3216cdSVlad Yasevich chunk); 2081da177e4SLinus Torvalds } 2091da177e4SLinus Torvalds break; 2101da177e4SLinus Torvalds 2111da177e4SLinus Torvalds case SCTP_XMIT_RWND_FULL: 2121da177e4SLinus Torvalds case SCTP_XMIT_OK: 213526cbef7SDavid Laight case SCTP_XMIT_DELAY: 2141da177e4SLinus Torvalds break; 2153ff50b79SStephen Hemminger } 2161da177e4SLinus Torvalds 2171da177e4SLinus Torvalds return retval; 2181da177e4SLinus Torvalds } 2191da177e4SLinus Torvalds 2204cd57c80SVlad Yasevich /* Try to bundle an auth chunk into the packet. */ 22186b36f2aSXin Long static enum sctp_xmit sctp_packet_bundle_auth(struct sctp_packet *pkt, 2224cd57c80SVlad Yasevich struct sctp_chunk *chunk) 2234cd57c80SVlad Yasevich { 2244cd57c80SVlad Yasevich struct sctp_association *asoc = pkt->transport->asoc; 22586b36f2aSXin Long enum sctp_xmit retval = SCTP_XMIT_OK; 2264cd57c80SVlad Yasevich struct sctp_chunk *auth; 2274cd57c80SVlad Yasevich 2284cd57c80SVlad Yasevich /* if we don't have an association, we can't do authentication */ 2294cd57c80SVlad Yasevich if (!asoc) 2304cd57c80SVlad Yasevich return retval; 2314cd57c80SVlad Yasevich 2324cd57c80SVlad Yasevich /* See if this is an auth chunk we are bundling or if 2334cd57c80SVlad Yasevich * auth is already bundled. 2344cd57c80SVlad Yasevich */ 2354007cc88SVlad Yasevich if (chunk->chunk_hdr->type == SCTP_CID_AUTH || pkt->has_auth) 2364cd57c80SVlad Yasevich return retval; 2374cd57c80SVlad Yasevich 2384cd57c80SVlad Yasevich /* if the peer did not request this chunk to be authenticated, 2394cd57c80SVlad Yasevich * don't do it 2404cd57c80SVlad Yasevich */ 2414cd57c80SVlad Yasevich if (!chunk->auth) 2424cd57c80SVlad Yasevich return retval; 2434cd57c80SVlad Yasevich 2444cd57c80SVlad Yasevich auth = sctp_make_auth(asoc); 2454cd57c80SVlad Yasevich if (!auth) 2464cd57c80SVlad Yasevich return retval; 2474cd57c80SVlad Yasevich 248ed106277SNeil Horman retval = __sctp_packet_append_chunk(pkt, auth); 249ed106277SNeil Horman 250ed106277SNeil Horman if (retval != SCTP_XMIT_OK) 251ed106277SNeil Horman sctp_chunk_free(auth); 2524cd57c80SVlad Yasevich 2534cd57c80SVlad Yasevich return retval; 2544cd57c80SVlad Yasevich } 2554cd57c80SVlad Yasevich 2561da177e4SLinus Torvalds /* Try to bundle a SACK with the packet. */ 25786b36f2aSXin Long static enum sctp_xmit sctp_packet_bundle_sack(struct sctp_packet *pkt, 2581da177e4SLinus Torvalds struct sctp_chunk *chunk) 2591da177e4SLinus Torvalds { 26086b36f2aSXin Long enum sctp_xmit retval = SCTP_XMIT_OK; 2611da177e4SLinus Torvalds 2621da177e4SLinus Torvalds /* If sending DATA and haven't aleady bundled a SACK, try to 2631da177e4SLinus Torvalds * bundle one in to the packet. 2641da177e4SLinus Torvalds */ 2651da177e4SLinus Torvalds if (sctp_chunk_is_data(chunk) && !pkt->has_sack && 2661da177e4SLinus Torvalds !pkt->has_cookie_echo) { 2671da177e4SLinus Torvalds struct sctp_association *asoc; 268af87b823SDoug Graham struct timer_list *timer; 2691da177e4SLinus Torvalds asoc = pkt->transport->asoc; 270af87b823SDoug Graham timer = &asoc->timers[SCTP_EVENT_TIMEOUT_SACK]; 2711da177e4SLinus Torvalds 272af87b823SDoug Graham /* If the SACK timer is running, we have a pending SACK */ 273af87b823SDoug Graham if (timer_pending(timer)) { 2741da177e4SLinus Torvalds struct sctp_chunk *sack; 2754244854dSNeil Horman 2764244854dSNeil Horman if (pkt->transport->sack_generation != 2774244854dSNeil Horman pkt->transport->asoc->peer.sack_generation) 2784244854dSNeil Horman return retval; 2794244854dSNeil Horman 2801da177e4SLinus Torvalds asoc->a_rwnd = asoc->rwnd; 2811da177e4SLinus Torvalds sack = sctp_make_sack(asoc); 2821da177e4SLinus Torvalds if (sack) { 283ed106277SNeil Horman retval = __sctp_packet_append_chunk(pkt, sack); 284ed106277SNeil Horman if (retval != SCTP_XMIT_OK) { 285ed106277SNeil Horman sctp_chunk_free(sack); 286ed106277SNeil Horman goto out; 287ed106277SNeil Horman } 2881da177e4SLinus Torvalds asoc->peer.sack_needed = 0; 289af87b823SDoug Graham if (del_timer(timer)) 2901da177e4SLinus Torvalds sctp_association_put(asoc); 2911da177e4SLinus Torvalds } 2921da177e4SLinus Torvalds } 2931da177e4SLinus Torvalds } 294ed106277SNeil Horman out: 2951da177e4SLinus Torvalds return retval; 2961da177e4SLinus Torvalds } 2971da177e4SLinus Torvalds 298ed106277SNeil Horman 2991da177e4SLinus Torvalds /* Append a chunk to the offered packet reporting back any inability to do 3001da177e4SLinus Torvalds * so. 3011da177e4SLinus Torvalds */ 30286b36f2aSXin Long static enum sctp_xmit __sctp_packet_append_chunk(struct sctp_packet *packet, 3031da177e4SLinus Torvalds struct sctp_chunk *chunk) 3041da177e4SLinus Torvalds { 305e2f036a9SMarcelo Ricardo Leitner __u16 chunk_len = SCTP_PAD4(ntohs(chunk->chunk_hdr->length)); 30686b36f2aSXin Long enum sctp_xmit retval = SCTP_XMIT_OK; 3071da177e4SLinus Torvalds 308e83963b7SVlad Yasevich /* Check to see if this chunk will fit into the packet */ 309e83963b7SVlad Yasevich retval = sctp_packet_will_fit(packet, chunk, chunk_len); 310e83963b7SVlad Yasevich if (retval != SCTP_XMIT_OK) 3111da177e4SLinus Torvalds goto finish; 3121da177e4SLinus Torvalds 313e83963b7SVlad Yasevich /* We believe that this chunk is OK to add to the packet */ 3144cd57c80SVlad Yasevich switch (chunk->chunk_hdr->type) { 3154cd57c80SVlad Yasevich case SCTP_CID_DATA: 316*668c9bebSXin Long case SCTP_CID_I_DATA: 317e83963b7SVlad Yasevich /* Account for the data being in the packet */ 318e83963b7SVlad Yasevich sctp_packet_append_data(packet, chunk); 3191da177e4SLinus Torvalds /* Disallow SACK bundling after DATA. */ 3201da177e4SLinus Torvalds packet->has_sack = 1; 3214cd57c80SVlad Yasevich /* Disallow AUTH bundling after DATA */ 3224cd57c80SVlad Yasevich packet->has_auth = 1; 3234cd57c80SVlad Yasevich /* Let it be knows that packet has DATA in it */ 3244cd57c80SVlad Yasevich packet->has_data = 1; 325759af00eSVlad Yasevich /* timestamp the chunk for rtx purposes */ 326759af00eSVlad Yasevich chunk->sent_at = jiffies; 327a6c2f792SXin Long /* Mainly used for prsctp RTX policy */ 328a6c2f792SXin Long chunk->sent_count++; 3294cd57c80SVlad Yasevich break; 3304cd57c80SVlad Yasevich case SCTP_CID_COOKIE_ECHO: 3311da177e4SLinus Torvalds packet->has_cookie_echo = 1; 3324cd57c80SVlad Yasevich break; 3334cd57c80SVlad Yasevich 3344cd57c80SVlad Yasevich case SCTP_CID_SACK: 3351da177e4SLinus Torvalds packet->has_sack = 1; 336196d6759SMichele Baldessari if (chunk->asoc) 337196d6759SMichele Baldessari chunk->asoc->stats.osacks++; 3384cd57c80SVlad Yasevich break; 3394cd57c80SVlad Yasevich 3404cd57c80SVlad Yasevich case SCTP_CID_AUTH: 3414cd57c80SVlad Yasevich packet->has_auth = 1; 3424cd57c80SVlad Yasevich packet->auth = chunk; 3434cd57c80SVlad Yasevich break; 3444cd57c80SVlad Yasevich } 3451da177e4SLinus Torvalds 3461da177e4SLinus Torvalds /* It is OK to send this chunk. */ 34779af02c2SDavid S. Miller list_add_tail(&chunk->list, &packet->chunk_list); 3481da177e4SLinus Torvalds packet->size += chunk_len; 3491da177e4SLinus Torvalds chunk->transport = packet->transport; 3501da177e4SLinus Torvalds finish: 3511da177e4SLinus Torvalds return retval; 3521da177e4SLinus Torvalds } 3531da177e4SLinus Torvalds 354ed106277SNeil Horman /* Append a chunk to the offered packet reporting back any inability to do 355ed106277SNeil Horman * so. 356ed106277SNeil Horman */ 35786b36f2aSXin Long enum sctp_xmit sctp_packet_append_chunk(struct sctp_packet *packet, 358ed106277SNeil Horman struct sctp_chunk *chunk) 359ed106277SNeil Horman { 36086b36f2aSXin Long enum sctp_xmit retval = SCTP_XMIT_OK; 361ed106277SNeil Horman 362bb33381dSDaniel Borkmann pr_debug("%s: packet:%p chunk:%p\n", __func__, packet, chunk); 363ed106277SNeil Horman 364ed106277SNeil Horman /* Data chunks are special. Before seeing what else we can 365ed106277SNeil Horman * bundle into this packet, check to see if we are allowed to 366ed106277SNeil Horman * send this DATA. 367ed106277SNeil Horman */ 368ed106277SNeil Horman if (sctp_chunk_is_data(chunk)) { 369ed106277SNeil Horman retval = sctp_packet_can_append_data(packet, chunk); 370ed106277SNeil Horman if (retval != SCTP_XMIT_OK) 371ed106277SNeil Horman goto finish; 372ed106277SNeil Horman } 373ed106277SNeil Horman 374ed106277SNeil Horman /* Try to bundle AUTH chunk */ 375ed106277SNeil Horman retval = sctp_packet_bundle_auth(packet, chunk); 376ed106277SNeil Horman if (retval != SCTP_XMIT_OK) 377ed106277SNeil Horman goto finish; 378ed106277SNeil Horman 379ed106277SNeil Horman /* Try to bundle SACK chunk */ 380ed106277SNeil Horman retval = sctp_packet_bundle_sack(packet, chunk); 381ed106277SNeil Horman if (retval != SCTP_XMIT_OK) 382ed106277SNeil Horman goto finish; 383ed106277SNeil Horman 384ed106277SNeil Horman retval = __sctp_packet_append_chunk(packet, chunk); 385ed106277SNeil Horman 386ed106277SNeil Horman finish: 387ed106277SNeil Horman return retval; 388ed106277SNeil Horman } 389ed106277SNeil Horman 3904c3a5bdaSThomas Graf static void sctp_packet_release_owner(struct sk_buff *skb) 3914c3a5bdaSThomas Graf { 3924c3a5bdaSThomas Graf sk_free(skb->sk); 3934c3a5bdaSThomas Graf } 3944c3a5bdaSThomas Graf 3954c3a5bdaSThomas Graf static void sctp_packet_set_owner_w(struct sk_buff *skb, struct sock *sk) 3964c3a5bdaSThomas Graf { 3974c3a5bdaSThomas Graf skb_orphan(skb); 3984c3a5bdaSThomas Graf skb->sk = sk; 3994c3a5bdaSThomas Graf skb->destructor = sctp_packet_release_owner; 4004c3a5bdaSThomas Graf 4014c3a5bdaSThomas Graf /* 4024c3a5bdaSThomas Graf * The data chunks have already been accounted for in sctp_sendmsg(), 4034c3a5bdaSThomas Graf * therefore only reserve a single byte to keep socket around until 4044c3a5bdaSThomas Graf * the packet has been transmitted. 4054c3a5bdaSThomas Graf */ 40614afee4bSReshetova, Elena refcount_inc(&sk->sk_wmem_alloc); 4074c3a5bdaSThomas Graf } 4084c3a5bdaSThomas Graf 409e4ff952aSXin Long static int sctp_packet_pack(struct sctp_packet *packet, 410e4ff952aSXin Long struct sk_buff *head, int gso, gfp_t gfp) 4111da177e4SLinus Torvalds { 4121da177e4SLinus Torvalds struct sctp_transport *tp = packet->transport; 413e4ff952aSXin Long struct sctp_auth_chunk *auth = NULL; 41479af02c2SDavid S. Miller struct sctp_chunk *chunk, *tmp; 415e4ff952aSXin Long int pkt_count = 0, pkt_size; 416e4ff952aSXin Long struct sock *sk = head->sk; 417e4ff952aSXin Long struct sk_buff *nskb; 418ecc515d7SXin Long int auth_len = 0; 4191da177e4SLinus Torvalds 42090017accSMarcelo Ricardo Leitner if (gso) { 42190017accSMarcelo Ricardo Leitner skb_shinfo(head)->gso_type = sk->sk_gso_type; 422e4ff952aSXin Long NAPI_GRO_CB(head)->last = head; 423e4ff952aSXin Long } else { 424e4ff952aSXin Long nskb = head; 425e4ff952aSXin Long pkt_size = packet->size; 426e4ff952aSXin Long goto merge; 42790017accSMarcelo Ricardo Leitner } 4281da177e4SLinus Torvalds 42990017accSMarcelo Ricardo Leitner do { 430e4ff952aSXin Long /* calculate the pkt_size and alloc nskb */ 43190017accSMarcelo Ricardo Leitner pkt_size = packet->overhead; 432e4ff952aSXin Long list_for_each_entry_safe(chunk, tmp, &packet->chunk_list, 433e4ff952aSXin Long list) { 434e2f036a9SMarcelo Ricardo Leitner int padded = SCTP_PAD4(chunk->skb->len); 43590017accSMarcelo Ricardo Leitner 436ecc515d7SXin Long if (chunk == packet->auth) 437ecc515d7SXin Long auth_len = padded; 438ecc515d7SXin Long else if (auth_len + padded + packet->overhead > 439ecc515d7SXin Long tp->pathmtu) 440e4ff952aSXin Long return 0; 441ecc515d7SXin Long else if (pkt_size + padded > tp->pathmtu) 44290017accSMarcelo Ricardo Leitner break; 44390017accSMarcelo Ricardo Leitner pkt_size += padded; 44490017accSMarcelo Ricardo Leitner } 44590017accSMarcelo Ricardo Leitner nskb = alloc_skb(pkt_size + MAX_HEADER, gfp); 44690017accSMarcelo Ricardo Leitner if (!nskb) 447e4ff952aSXin Long return 0; 44890017accSMarcelo Ricardo Leitner skb_reserve(nskb, packet->overhead + MAX_HEADER); 4491da177e4SLinus Torvalds 450e4ff952aSXin Long merge: 451e4ff952aSXin Long /* merge chunks into nskb and append nskb into head list */ 45290017accSMarcelo Ricardo Leitner pkt_size -= packet->overhead; 45379af02c2SDavid S. Miller list_for_each_entry_safe(chunk, tmp, &packet->chunk_list, list) { 454e4ff952aSXin Long int padding; 455e4ff952aSXin Long 45679af02c2SDavid S. Miller list_del_init(&chunk->list); 4571da177e4SLinus Torvalds if (sctp_chunk_is_data(chunk)) { 458cc6ac9bcSXin Long if (!sctp_chunk_retransmitted(chunk) && 459cc6ac9bcSXin Long !tp->rto_pending) { 4601da177e4SLinus Torvalds chunk->rtt_in_progress = 1; 4611da177e4SLinus Torvalds tp->rto_pending = 1; 4621da177e4SLinus Torvalds } 4631da177e4SLinus Torvalds } 4641da177e4SLinus Torvalds 465e2f036a9SMarcelo Ricardo Leitner padding = SCTP_PAD4(chunk->skb->len) - chunk->skb->len; 4661da177e4SLinus Torvalds if (padding) 467b080db58SJohannes Berg skb_put_zero(chunk->skb, padding); 4681da177e4SLinus Torvalds 4694cd57c80SVlad Yasevich if (chunk == packet->auth) 470e4ff952aSXin Long auth = (struct sctp_auth_chunk *) 471e4ff952aSXin Long skb_tail_pointer(nskb); 4724cd57c80SVlad Yasevich 47359ae1d12SJohannes Berg skb_put_data(nskb, chunk->skb->data, chunk->skb->len); 4741da177e4SLinus Torvalds 47590017accSMarcelo Ricardo Leitner pr_debug("*** Chunk:%p[%s] %s 0x%x, length:%d, chunk->skb->len:%d, rtt_in_progress:%d\n", 47690017accSMarcelo Ricardo Leitner chunk, 477bb33381dSDaniel Borkmann sctp_cname(SCTP_ST_CHUNK(chunk->chunk_hdr->type)), 4781da177e4SLinus Torvalds chunk->has_tsn ? "TSN" : "No TSN", 479bb33381dSDaniel Borkmann chunk->has_tsn ? ntohl(chunk->subh.data_hdr->tsn) : 0, 480bb33381dSDaniel Borkmann ntohs(chunk->chunk_hdr->length), chunk->skb->len, 481bb33381dSDaniel Borkmann chunk->rtt_in_progress); 4821da177e4SLinus Torvalds 483e2f036a9SMarcelo Ricardo Leitner pkt_size -= SCTP_PAD4(chunk->skb->len); 48490017accSMarcelo Ricardo Leitner 485f1533cceSMarcelo Ricardo Leitner if (!sctp_chunk_is_data(chunk) && chunk != packet->auth) 4861da177e4SLinus Torvalds sctp_chunk_free(chunk); 48790017accSMarcelo Ricardo Leitner 48890017accSMarcelo Ricardo Leitner if (!pkt_size) 48990017accSMarcelo Ricardo Leitner break; 4901da177e4SLinus Torvalds } 4911da177e4SLinus Torvalds 492e4ff952aSXin Long if (auth) { 493e4ff952aSXin Long sctp_auth_calculate_hmac(tp->asoc, nskb, auth, gfp); 494e4ff952aSXin Long /* free auth if no more chunks, or add it back */ 495e4ff952aSXin Long if (list_empty(&packet->chunk_list)) 496e4ff952aSXin Long sctp_chunk_free(packet->auth); 497e4ff952aSXin Long else 4981aa25ec2SXin Long list_add(&packet->auth->list, 4991aa25ec2SXin Long &packet->chunk_list); 500f1533cceSMarcelo Ricardo Leitner } 5011da177e4SLinus Torvalds 50290017accSMarcelo Ricardo Leitner if (gso) { 503e4ff952aSXin Long if (skb_gro_receive(&head, nskb)) { 504e4ff952aSXin Long kfree_skb(nskb); 505e4ff952aSXin Long return 0; 506e4ff952aSXin Long } 507e4ff952aSXin Long if (WARN_ON_ONCE(skb_shinfo(head)->gso_segs >= 508e4ff952aSXin Long sk->sk_gso_max_segs)) 509e4ff952aSXin Long return 0; 510e4ff952aSXin Long } 511e4ff952aSXin Long 512e4ff952aSXin Long pkt_count++; 513e4ff952aSXin Long } while (!list_empty(&packet->chunk_list)); 514e4ff952aSXin Long 515e4ff952aSXin Long if (gso) { 51690017accSMarcelo Ricardo Leitner memset(head->cb, 0, max(sizeof(struct inet_skb_parm), 51790017accSMarcelo Ricardo Leitner sizeof(struct inet6_skb_parm))); 518e4ff952aSXin Long skb_shinfo(head)->gso_segs = pkt_count; 51990017accSMarcelo Ricardo Leitner skb_shinfo(head)->gso_size = GSO_BY_FRAGS; 52090017accSMarcelo Ricardo Leitner rcu_read_lock(); 521e4ff952aSXin Long if (skb_dst(head) != tp->dst) { 52290017accSMarcelo Ricardo Leitner dst_hold(tp->dst); 52390017accSMarcelo Ricardo Leitner sk_setup_caps(sk, tp->dst); 52490017accSMarcelo Ricardo Leitner } 52590017accSMarcelo Ricardo Leitner rcu_read_unlock(); 526e4ff952aSXin Long goto chksum; 527e4ff952aSXin Long } 528e4ff952aSXin Long 529e4ff952aSXin Long if (sctp_checksum_disable) 530e4ff952aSXin Long return 1; 531e4ff952aSXin Long 532e4ff952aSXin Long if (!(skb_dst(head)->dev->features & NETIF_F_SCTP_CRC) || 533e4ff952aSXin Long dst_xfrm(skb_dst(head)) || packet->ipfragok) { 534e4ff952aSXin Long struct sctphdr *sh = 535e4ff952aSXin Long (struct sctphdr *)skb_transport_header(head); 536e4ff952aSXin Long 537e4ff952aSXin Long sh->checksum = sctp_compute_cksum(head, 0); 538e4ff952aSXin Long } else { 539e4ff952aSXin Long chksum: 540e4ff952aSXin Long head->ip_summed = CHECKSUM_PARTIAL; 541dba00306SDavide Caratti head->csum_not_inet = 1; 542e4ff952aSXin Long head->csum_start = skb_transport_header(head) - head->head; 543e4ff952aSXin Long head->csum_offset = offsetof(struct sctphdr, checksum); 544e4ff952aSXin Long } 545e4ff952aSXin Long 546e4ff952aSXin Long return pkt_count; 547e4ff952aSXin Long } 548e4ff952aSXin Long 549e4ff952aSXin Long /* All packets are sent to the network through this function from 550e4ff952aSXin Long * sctp_outq_tail(). 551e4ff952aSXin Long * 552e4ff952aSXin Long * The return value is always 0 for now. 553e4ff952aSXin Long */ 554e4ff952aSXin Long int sctp_packet_transmit(struct sctp_packet *packet, gfp_t gfp) 555e4ff952aSXin Long { 556e4ff952aSXin Long struct sctp_transport *tp = packet->transport; 557e4ff952aSXin Long struct sctp_association *asoc = tp->asoc; 558e4ff952aSXin Long struct sctp_chunk *chunk, *tmp; 559e4ff952aSXin Long int pkt_count, gso = 0; 560e4ff952aSXin Long struct dst_entry *dst; 561e4ff952aSXin Long struct sk_buff *head; 562e4ff952aSXin Long struct sctphdr *sh; 563e4ff952aSXin Long struct sock *sk; 564e4ff952aSXin Long 565e4ff952aSXin Long pr_debug("%s: packet:%p\n", __func__, packet); 566e4ff952aSXin Long if (list_empty(&packet->chunk_list)) 567e4ff952aSXin Long return 0; 568e4ff952aSXin Long chunk = list_entry(packet->chunk_list.next, struct sctp_chunk, list); 569e4ff952aSXin Long sk = chunk->skb->sk; 570e4ff952aSXin Long 571e4ff952aSXin Long /* check gso */ 572e4ff952aSXin Long if (packet->size > tp->pathmtu && !packet->ipfragok) { 573e4ff952aSXin Long if (!sk_can_gso(sk)) { 574e4ff952aSXin Long pr_err_once("Trying to GSO but underlying device doesn't support it."); 575e4ff952aSXin Long goto out; 576e4ff952aSXin Long } 577e4ff952aSXin Long gso = 1; 578e4ff952aSXin Long } 579e4ff952aSXin Long 580e4ff952aSXin Long /* alloc head skb */ 581e4ff952aSXin Long head = alloc_skb((gso ? packet->overhead : packet->size) + 582e4ff952aSXin Long MAX_HEADER, gfp); 583e4ff952aSXin Long if (!head) 584e4ff952aSXin Long goto out; 585e4ff952aSXin Long skb_reserve(head, packet->overhead + MAX_HEADER); 586e4ff952aSXin Long sctp_packet_set_owner_w(head, sk); 587e4ff952aSXin Long 588e4ff952aSXin Long /* set sctp header */ 589d58ff351SJohannes Berg sh = skb_push(head, sizeof(struct sctphdr)); 590e4ff952aSXin Long skb_reset_transport_header(head); 591e4ff952aSXin Long sh->source = htons(packet->source_port); 592e4ff952aSXin Long sh->dest = htons(packet->destination_port); 593e4ff952aSXin Long sh->vtag = htonl(packet->vtag); 594e4ff952aSXin Long sh->checksum = 0; 595e4ff952aSXin Long 596df2729c3SXin Long /* drop packet if no dst */ 597e4ff952aSXin Long dst = dst_clone(tp->dst); 598e4ff952aSXin Long if (!dst) { 599e4ff952aSXin Long IP_INC_STATS(sock_net(sk), IPSTATS_MIB_OUTNOROUTES); 600e4ff952aSXin Long kfree_skb(head); 601e4ff952aSXin Long goto out; 602e4ff952aSXin Long } 603e4ff952aSXin Long skb_dst_set(head, dst); 604e4ff952aSXin Long 605e4ff952aSXin Long /* pack up chunks */ 606e4ff952aSXin Long pkt_count = sctp_packet_pack(packet, head, gso, gfp); 607e4ff952aSXin Long if (!pkt_count) { 608e4ff952aSXin Long kfree_skb(head); 609e4ff952aSXin Long goto out; 610e4ff952aSXin Long } 611e4ff952aSXin Long pr_debug("***sctp_transmit_packet*** skb->len:%d\n", head->len); 612e4ff952aSXin Long 613e4ff952aSXin Long /* start autoclose timer */ 614e4ff952aSXin Long if (packet->has_data && sctp_state(asoc, ESTABLISHED) && 615e4ff952aSXin Long asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE]) { 616e4ff952aSXin Long struct timer_list *timer = 617e4ff952aSXin Long &asoc->timers[SCTP_EVENT_TIMEOUT_AUTOCLOSE]; 618e4ff952aSXin Long unsigned long timeout = 619e4ff952aSXin Long asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE]; 620e4ff952aSXin Long 621e4ff952aSXin Long if (!mod_timer(timer, jiffies + timeout)) 622e4ff952aSXin Long sctp_association_hold(asoc); 623e4ff952aSXin Long } 624e4ff952aSXin Long 625e4ff952aSXin Long /* sctp xmit */ 626e4ff952aSXin Long tp->af_specific->ecn_capable(sk); 627e4ff952aSXin Long if (asoc) { 628e4ff952aSXin Long asoc->stats.opackets += pkt_count; 629e4ff952aSXin Long if (asoc->peer.last_sent_to != tp) 630e4ff952aSXin Long asoc->peer.last_sent_to = tp; 63190017accSMarcelo Ricardo Leitner } 63290017accSMarcelo Ricardo Leitner head->ignore_df = packet->ipfragok; 633486a43dbSXin Long if (tp->dst_pending_confirm) 634c86a773cSJulian Anastasov skb_set_dst_pending_confirm(head, 1); 635c86a773cSJulian Anastasov /* neighbour should be confirmed on successful transmission or 636c86a773cSJulian Anastasov * positive error 637c86a773cSJulian Anastasov */ 638486a43dbSXin Long if (tp->af_specific->sctp_xmit(head, tp) >= 0 && 639486a43dbSXin Long tp->dst_pending_confirm) 640c86a773cSJulian Anastasov tp->dst_pending_confirm = 0; 6411da177e4SLinus Torvalds 642e4ff952aSXin Long out: 64379af02c2SDavid S. Miller list_for_each_entry_safe(chunk, tmp, &packet->chunk_list, list) { 64479af02c2SDavid S. Miller list_del_init(&chunk->list); 6451da177e4SLinus Torvalds if (!sctp_chunk_is_data(chunk)) 6461da177e4SLinus Torvalds sctp_chunk_free(chunk); 6471da177e4SLinus Torvalds } 64841001fafSXin Long sctp_packet_reset(packet); 649e4ff952aSXin Long return 0; 6501da177e4SLinus Torvalds } 6511da177e4SLinus Torvalds 6521da177e4SLinus Torvalds /******************************************************************** 6531da177e4SLinus Torvalds * 2nd Level Abstractions 6541da177e4SLinus Torvalds ********************************************************************/ 6551da177e4SLinus Torvalds 656e83963b7SVlad Yasevich /* This private function check to see if a chunk can be added */ 65786b36f2aSXin Long static enum sctp_xmit sctp_packet_can_append_data(struct sctp_packet *packet, 6581da177e4SLinus Torvalds struct sctp_chunk *chunk) 6591da177e4SLinus Torvalds { 660e83963b7SVlad Yasevich size_t datasize, rwnd, inflight, flight_size; 6611da177e4SLinus Torvalds struct sctp_transport *transport = packet->transport; 6621da177e4SLinus Torvalds struct sctp_association *asoc = transport->asoc; 6631da177e4SLinus Torvalds struct sctp_outq *q = &asoc->outqueue; 6641da177e4SLinus Torvalds 6651da177e4SLinus Torvalds /* RFC 2960 6.1 Transmission of DATA Chunks 6661da177e4SLinus Torvalds * 6671da177e4SLinus Torvalds * A) At any given time, the data sender MUST NOT transmit new data to 6681da177e4SLinus Torvalds * any destination transport address if its peer's rwnd indicates 6691da177e4SLinus Torvalds * that the peer has no buffer space (i.e. rwnd is 0, see Section 6701da177e4SLinus Torvalds * 6.2.1). However, regardless of the value of rwnd (including if it 6711da177e4SLinus Torvalds * is 0), the data sender can always have one DATA chunk in flight to 6721da177e4SLinus Torvalds * the receiver if allowed by cwnd (see rule B below). This rule 6731da177e4SLinus Torvalds * allows the sender to probe for a change in rwnd that the sender 6741da177e4SLinus Torvalds * missed due to the SACK having been lost in transit from the data 6751da177e4SLinus Torvalds * receiver to the data sender. 6761da177e4SLinus Torvalds */ 6771da177e4SLinus Torvalds 6781da177e4SLinus Torvalds rwnd = asoc->peer.rwnd; 679e83963b7SVlad Yasevich inflight = q->outstanding_bytes; 680e83963b7SVlad Yasevich flight_size = transport->flight_size; 6811da177e4SLinus Torvalds 6821da177e4SLinus Torvalds datasize = sctp_data_size(chunk); 6831da177e4SLinus Torvalds 684723189faSDavid Laight if (datasize > rwnd && inflight > 0) 6851da177e4SLinus Torvalds /* We have (at least) one data chunk in flight, 6861da177e4SLinus Torvalds * so we can't fall back to rule 6.1 B). 6871da177e4SLinus Torvalds */ 688723189faSDavid Laight return SCTP_XMIT_RWND_FULL; 6891da177e4SLinus Torvalds 6901da177e4SLinus Torvalds /* RFC 2960 6.1 Transmission of DATA Chunks 6911da177e4SLinus Torvalds * 6921da177e4SLinus Torvalds * B) At any given time, the sender MUST NOT transmit new data 6931da177e4SLinus Torvalds * to a given transport address if it has cwnd or more bytes 6941da177e4SLinus Torvalds * of data outstanding to that transport address. 6951da177e4SLinus Torvalds */ 6961da177e4SLinus Torvalds /* RFC 7.2.4 & the Implementers Guide 2.8. 6971da177e4SLinus Torvalds * 6981da177e4SLinus Torvalds * 3) ... 6991da177e4SLinus Torvalds * When a Fast Retransmit is being performed the sender SHOULD 7001da177e4SLinus Torvalds * ignore the value of cwnd and SHOULD NOT delay retransmission. 7011da177e4SLinus Torvalds */ 702723189faSDavid Laight if (chunk->fast_retransmit != SCTP_NEED_FRTX && 703723189faSDavid Laight flight_size >= transport->cwnd) 704723189faSDavid Laight return SCTP_XMIT_RWND_FULL; 7051da177e4SLinus Torvalds 7061da177e4SLinus Torvalds /* Nagle's algorithm to solve small-packet problem: 7071da177e4SLinus Torvalds * Inhibit the sending of new chunks when new outgoing data arrives 7081da177e4SLinus Torvalds * if any previously transmitted data on the connection remains 7091da177e4SLinus Torvalds * unacknowledged. 7101da177e4SLinus Torvalds */ 7111da177e4SLinus Torvalds 7124ea0c32fSXin Long if ((sctp_sk(asoc->base.sk)->nodelay || inflight == 0) && 713f9ba3501SXin Long !asoc->force_delay) 7144ea0c32fSXin Long /* Nothing unacked */ 715723189faSDavid Laight return SCTP_XMIT_OK; 716723189faSDavid Laight 717723189faSDavid Laight if (!sctp_packet_empty(packet)) 718723189faSDavid Laight /* Append to packet */ 719723189faSDavid Laight return SCTP_XMIT_OK; 720723189faSDavid Laight 721723189faSDavid Laight if (!sctp_state(asoc, ESTABLISHED)) 722723189faSDavid Laight return SCTP_XMIT_OK; 723723189faSDavid Laight 724723189faSDavid Laight /* Check whether this chunk and all the rest of pending data will fit 725723189faSDavid Laight * or delay in hopes of bundling a full sized packet. 7261da177e4SLinus Torvalds */ 7279f8d3147SXin Long if (chunk->skb->len + q->out_qlen > transport->pathmtu - 728*668c9bebSXin Long packet->overhead - sctp_datachk_len(&chunk->asoc->stream) - 4) 729723189faSDavid Laight /* Enough data queued to fill a packet */ 730723189faSDavid Laight return SCTP_XMIT_OK; 7311da177e4SLinus Torvalds 732723189faSDavid Laight /* Don't delay large message writes that may have been fragmented */ 733723189faSDavid Laight if (!chunk->msg->can_delay) 734723189faSDavid Laight return SCTP_XMIT_OK; 735723189faSDavid Laight 736723189faSDavid Laight /* Defer until all data acked or packet full */ 737526cbef7SDavid Laight return SCTP_XMIT_DELAY; 738e83963b7SVlad Yasevich } 739e83963b7SVlad Yasevich 740e83963b7SVlad Yasevich /* This private function does management things when adding DATA chunk */ 741e83963b7SVlad Yasevich static void sctp_packet_append_data(struct sctp_packet *packet, 742e83963b7SVlad Yasevich struct sctp_chunk *chunk) 743e83963b7SVlad Yasevich { 744e83963b7SVlad Yasevich struct sctp_transport *transport = packet->transport; 745e83963b7SVlad Yasevich size_t datasize = sctp_data_size(chunk); 746e83963b7SVlad Yasevich struct sctp_association *asoc = transport->asoc; 747e83963b7SVlad Yasevich u32 rwnd = asoc->peer.rwnd; 748e83963b7SVlad Yasevich 7491da177e4SLinus Torvalds /* Keep track of how many bytes are in flight over this transport. */ 7501da177e4SLinus Torvalds transport->flight_size += datasize; 7511da177e4SLinus Torvalds 7521da177e4SLinus Torvalds /* Keep track of how many bytes are in flight to the receiver. */ 7531da177e4SLinus Torvalds asoc->outqueue.outstanding_bytes += datasize; 7541da177e4SLinus Torvalds 755a76c0adfSThomas Graf /* Update our view of the receiver's rwnd. */ 7561da177e4SLinus Torvalds if (datasize < rwnd) 7571da177e4SLinus Torvalds rwnd -= datasize; 7581da177e4SLinus Torvalds else 7591da177e4SLinus Torvalds rwnd = 0; 7601da177e4SLinus Torvalds 7611da177e4SLinus Torvalds asoc->peer.rwnd = rwnd; 762d8dd1578SNeil Horman sctp_chunk_assign_tsn(chunk); 763*668c9bebSXin Long asoc->stream.si->assign_number(chunk); 764e83963b7SVlad Yasevich } 7651da177e4SLinus Torvalds 76686b36f2aSXin Long static enum sctp_xmit sctp_packet_will_fit(struct sctp_packet *packet, 767e83963b7SVlad Yasevich struct sctp_chunk *chunk, 768e83963b7SVlad Yasevich u16 chunk_len) 769e83963b7SVlad Yasevich { 77086b36f2aSXin Long enum sctp_xmit retval = SCTP_XMIT_OK; 7717303a147SMarcelo Ricardo Leitner size_t psize, pmtu, maxsize; 772e83963b7SVlad Yasevich 773e83963b7SVlad Yasevich psize = packet->size; 77490017accSMarcelo Ricardo Leitner if (packet->transport->asoc) 77590017accSMarcelo Ricardo Leitner pmtu = packet->transport->asoc->pathmtu; 77690017accSMarcelo Ricardo Leitner else 77790017accSMarcelo Ricardo Leitner pmtu = packet->transport->pathmtu; 778e83963b7SVlad Yasevich 779e83963b7SVlad Yasevich /* Decide if we need to fragment or resubmit later. */ 78090017accSMarcelo Ricardo Leitner if (psize + chunk_len > pmtu) { 78190017accSMarcelo Ricardo Leitner /* It's OK to fragment at IP level if any one of the following 782e83963b7SVlad Yasevich * is true: 783e83963b7SVlad Yasevich * 1. The packet is empty (meaning this chunk is greater 784e83963b7SVlad Yasevich * the MTU) 78590017accSMarcelo Ricardo Leitner * 2. The packet doesn't have any data in it yet and data 786e83963b7SVlad Yasevich * requires authentication. 787e83963b7SVlad Yasevich */ 78890017accSMarcelo Ricardo Leitner if (sctp_packet_empty(packet) || 789e83963b7SVlad Yasevich (!packet->has_data && chunk->auth)) { 790e83963b7SVlad Yasevich /* We no longer do re-fragmentation. 791e83963b7SVlad Yasevich * Just fragment at the IP layer, if we 792e83963b7SVlad Yasevich * actually hit this condition 793e83963b7SVlad Yasevich */ 794e83963b7SVlad Yasevich packet->ipfragok = 1; 79590017accSMarcelo Ricardo Leitner goto out; 796e83963b7SVlad Yasevich } 797e83963b7SVlad Yasevich 7987303a147SMarcelo Ricardo Leitner /* Similarly, if this chunk was built before a PMTU 7997303a147SMarcelo Ricardo Leitner * reduction, we have to fragment it at IP level now. So 8007303a147SMarcelo Ricardo Leitner * if the packet already contains something, we need to 8017303a147SMarcelo Ricardo Leitner * flush. 8027303a147SMarcelo Ricardo Leitner */ 8037303a147SMarcelo Ricardo Leitner maxsize = pmtu - packet->overhead; 8047303a147SMarcelo Ricardo Leitner if (packet->auth) 805e2f036a9SMarcelo Ricardo Leitner maxsize -= SCTP_PAD4(packet->auth->skb->len); 8067303a147SMarcelo Ricardo Leitner if (chunk_len > maxsize) 8077303a147SMarcelo Ricardo Leitner retval = SCTP_XMIT_PMTU_FULL; 8087303a147SMarcelo Ricardo Leitner 80990017accSMarcelo Ricardo Leitner /* It is also okay to fragment if the chunk we are 81090017accSMarcelo Ricardo Leitner * adding is a control chunk, but only if current packet 81190017accSMarcelo Ricardo Leitner * is not a GSO one otherwise it causes fragmentation of 81290017accSMarcelo Ricardo Leitner * a large frame. So in this case we allow the 81390017accSMarcelo Ricardo Leitner * fragmentation by forcing it to be in a new packet. 81490017accSMarcelo Ricardo Leitner */ 81590017accSMarcelo Ricardo Leitner if (!sctp_chunk_is_data(chunk) && packet->has_data) 81690017accSMarcelo Ricardo Leitner retval = SCTP_XMIT_PMTU_FULL; 81790017accSMarcelo Ricardo Leitner 81890017accSMarcelo Ricardo Leitner if (psize + chunk_len > packet->max_size) 81990017accSMarcelo Ricardo Leitner /* Hit GSO/PMTU limit, gotta flush */ 82090017accSMarcelo Ricardo Leitner retval = SCTP_XMIT_PMTU_FULL; 82190017accSMarcelo Ricardo Leitner 82290017accSMarcelo Ricardo Leitner if (!packet->transport->burst_limited && 82390017accSMarcelo Ricardo Leitner psize + chunk_len > (packet->transport->cwnd >> 1)) 82490017accSMarcelo Ricardo Leitner /* Do not allow a single GSO packet to use more 82590017accSMarcelo Ricardo Leitner * than half of cwnd. 82690017accSMarcelo Ricardo Leitner */ 82790017accSMarcelo Ricardo Leitner retval = SCTP_XMIT_PMTU_FULL; 82890017accSMarcelo Ricardo Leitner 82990017accSMarcelo Ricardo Leitner if (packet->transport->burst_limited && 83090017accSMarcelo Ricardo Leitner psize + chunk_len > (packet->transport->burst_limited >> 1)) 83190017accSMarcelo Ricardo Leitner /* Do not allow a single GSO packet to use more 83290017accSMarcelo Ricardo Leitner * than half of original cwnd. 83390017accSMarcelo Ricardo Leitner */ 83490017accSMarcelo Ricardo Leitner retval = SCTP_XMIT_PMTU_FULL; 83590017accSMarcelo Ricardo Leitner /* Otherwise it will fit in the GSO packet */ 83690017accSMarcelo Ricardo Leitner } 83790017accSMarcelo Ricardo Leitner 83890017accSMarcelo Ricardo Leitner out: 8391da177e4SLinus Torvalds return retval; 8401da177e4SLinus Torvalds } 841