From patchwork Sat Nov 25 13:18:35 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xin Long X-Patchwork-Id: 841243 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="IMbRtLUv"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3ykYYT0VMBz9s7F for ; Sun, 26 Nov 2017 00:19:09 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751684AbdKYNTD (ORCPT ); Sat, 25 Nov 2017 08:19:03 -0500 Received: from mail-pl0-f65.google.com ([209.85.160.65]:43688 "EHLO mail-pl0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751666AbdKYNTB (ORCPT ); Sat, 25 Nov 2017 08:19:01 -0500 Received: by mail-pl0-f65.google.com with SMTP id s23so581006plk.10; Sat, 25 Nov 2017 05:19:01 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :in-reply-to:references; bh=lfxH6L3EtECU+I5hXM1IFIlWZiSKzu3I3iO2djBJsdA=; b=IMbRtLUvLq9ekE6QEicFJ3jcfWlOnw1py0Sb0cIguWiapAXBXVm3VEOC9r8IUNOBtZ 2f8+SZdpSHPpMhJ92TqEcEbGitNcIWlp4rGwgPL62OF0iuNtUZzYU5Yk7cKA2XPKZjd0 NbnIT+LqpV1Slytt1bJp+gBrPod5HmWlK8sl0K1aoM7EIOo4M3EAUKX1Fwho/EWYvYw1 RoBmO/1lLQqj1p32VZJO/1OId51z69y76y5rJpjfEomQqQ7aJ7Nu/8PmcX2kxHKeCSw/ kbuBVwGIjiI/kS6GuVozo/oqXdFtInO8SABBncLw5skF+HXpV+w9url+nqFtW+t5JMN2 l8vg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:in-reply-to:references; bh=lfxH6L3EtECU+I5hXM1IFIlWZiSKzu3I3iO2djBJsdA=; b=XlTzYEdmRQIedFrCbUTEyNQ8FLFL5bM9h+9SPsJeu4yHmVBJlStgJamHF+7v6+eYxl bP3oxKqKdSACV8t4/PHALg4PseiDWcVGHs25ipKdmlZuUenV0sMz2IDnVK7N59YnnYQh D8jiUJh5gPhWBLDav4hRqhuCQSp4CVgBHrI5YYcA+vms4gnlo3UscFiTOs9aqMgvXjuU X+gXEmomyqM4+PEYqDFVmXnbmbdokLTOEQMNkA1mhKqusYmXDTvMnGoRXQMf8ptNfscW 84WjZ1rQ9SMSEDM84xEGOpMwR7BCM4MDilb+iU9FVqcW/XBrj2m6ba3fMhOcPU0tnzI2 h2lQ== X-Gm-Message-State: AJaThX7NZDR9UTJ0NZi4x+X9xjRRBJ/WVL6kQdw5Zod1sRN7ACQDpTRd 4FgBp5oZYXmyuyIjnOVaGya0l6mj X-Google-Smtp-Source: AGs4zMaTdg3FPEgFuPPbz8POjk/TLBupMev6cAiEs/mHf/00XQRjXxAZhWQfVVh0ZZ+vnPcbIqojtQ== X-Received: by 10.84.229.5 with SMTP id b5mr32966475plk.405.1511615940827; Sat, 25 Nov 2017 05:19:00 -0800 (PST) Received: from localhost ([209.132.188.80]) by smtp.gmail.com with ESMTPSA id y131sm26913635pfg.125.2017.11.25.05.18.59 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 25 Nov 2017 05:19:00 -0800 (PST) From: Xin Long To: network dev , linux-sctp@vger.kernel.org Cc: davem@davemloft.net, Marcelo Ricardo Leitner , Neil Horman Subject: [PATCH net 2/3] sctp: abandon the whole msg if one part of a fragmented message is abandoned Date: Sat, 25 Nov 2017 21:18:35 +0800 Message-Id: <527417b933f70998528cbbfcdf4f6a8405fb0292.1511615658.git.lucien.xin@gmail.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <9c96424d052af79cfcefeec8bc53b6b541c1900f.1511615658.git.lucien.xin@gmail.com> References: <9c96424d052af79cfcefeec8bc53b6b541c1900f.1511615658.git.lucien.xin@gmail.com> In-Reply-To: References: Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org As rfc3758#section-3.1 demands: A3) When a TSN is "abandoned", if it is part of a fragmented message, all other TSN's within that fragmented message MUST be abandoned at the same time. Besides, if it couldn't handle this, the rest frags would never get assembled in peer side. This patch supports it by adding abandoned flag in sctp_datamsg, when one chunk is being abandoned, set chunk->msg->abandoned as well. Next time when checking for abandoned, go checking chunk->msg->abandoned first. Signed-off-by: Xin Long Acked-by: Marcelo Ricardo Leitner --- include/net/sctp/structs.h | 3 ++- net/sctp/chunk.c | 7 +++++++ net/sctp/outqueue.c | 12 ++++++++---- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index 16f949e..2f8f93d 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h @@ -503,7 +503,8 @@ struct sctp_datamsg { /* Did the messenge fail to send? */ int send_error; u8 send_failed:1, - can_delay; /* should this message be Nagle delayed */ + can_delay:1, /* should this message be Nagle delayed */ + abandoned:1; /* should this message be abandoned */ }; struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *, diff --git a/net/sctp/chunk.c b/net/sctp/chunk.c index 7b261af..9213805 100644 --- a/net/sctp/chunk.c +++ b/net/sctp/chunk.c @@ -53,6 +53,7 @@ static void sctp_datamsg_init(struct sctp_datamsg *msg) msg->send_failed = 0; msg->send_error = 0; msg->can_delay = 1; + msg->abandoned = 0; msg->expires_at = 0; INIT_LIST_HEAD(&msg->chunks); } @@ -304,6 +305,9 @@ int sctp_chunk_abandoned(struct sctp_chunk *chunk) if (!chunk->asoc->peer.prsctp_capable) return 0; + if (chunk->msg->abandoned) + return 1; + if (SCTP_PR_TTL_ENABLED(chunk->sinfo.sinfo_flags) && time_after(jiffies, chunk->msg->expires_at)) { struct sctp_stream_out *streamout = @@ -316,6 +320,7 @@ int sctp_chunk_abandoned(struct sctp_chunk *chunk) chunk->asoc->abandoned_unsent[SCTP_PR_INDEX(TTL)]++; streamout->ext->abandoned_unsent[SCTP_PR_INDEX(TTL)]++; } + chunk->msg->abandoned = 1; return 1; } else if (SCTP_PR_RTX_ENABLED(chunk->sinfo.sinfo_flags) && chunk->sent_count > chunk->sinfo.sinfo_timetolive) { @@ -324,10 +329,12 @@ int sctp_chunk_abandoned(struct sctp_chunk *chunk) chunk->asoc->abandoned_sent[SCTP_PR_INDEX(RTX)]++; streamout->ext->abandoned_sent[SCTP_PR_INDEX(RTX)]++; + chunk->msg->abandoned = 1; return 1; } else if (!SCTP_PR_POLICY(chunk->sinfo.sinfo_flags) && chunk->msg->expires_at && time_after(jiffies, chunk->msg->expires_at)) { + chunk->msg->abandoned = 1; return 1; } /* PRIO policy is processed by sendmsg, not here */ diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c index 7029f8b..4ab164b 100644 --- a/net/sctp/outqueue.c +++ b/net/sctp/outqueue.c @@ -364,10 +364,12 @@ static int sctp_prsctp_prune_sent(struct sctp_association *asoc, list_for_each_entry_safe(chk, temp, queue, transmitted_list) { struct sctp_stream_out *streamout; - if (!SCTP_PR_PRIO_ENABLED(chk->sinfo.sinfo_flags) || - chk->sinfo.sinfo_timetolive <= sinfo->sinfo_timetolive) + if (!chk->msg->abandoned && + (!SCTP_PR_PRIO_ENABLED(chk->sinfo.sinfo_flags) || + chk->sinfo.sinfo_timetolive <= sinfo->sinfo_timetolive)) continue; + chk->msg->abandoned = 1; list_del_init(&chk->transmitted_list); sctp_insert_list(&asoc->outqueue.abandoned, &chk->transmitted_list); @@ -404,10 +406,12 @@ static int sctp_prsctp_prune_unsent(struct sctp_association *asoc, q->sched->unsched_all(&asoc->stream); list_for_each_entry_safe(chk, temp, &q->out_chunk_list, list) { - if (!SCTP_PR_PRIO_ENABLED(chk->sinfo.sinfo_flags) || - chk->sinfo.sinfo_timetolive <= sinfo->sinfo_timetolive) + if (!chk->msg->abandoned && + (!SCTP_PR_PRIO_ENABLED(chk->sinfo.sinfo_flags) || + chk->sinfo.sinfo_timetolive <= sinfo->sinfo_timetolive)) continue; + chk->msg->abandoned = 1; sctp_sched_dequeue_common(q, chk); asoc->sent_cnt_removable--; asoc->abandoned_unsent[SCTP_PR_INDEX(PRIO)]++;