From patchwork Sun Apr 29 15:56:32 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marcelo Ricardo Leitner X-Patchwork-Id: 906381 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@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; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="KTTfMUsf"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40YtXF72dvz9ryr for ; Mon, 30 Apr 2018 02:33:33 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753958AbeD2Qdc (ORCPT ); Sun, 29 Apr 2018 12:33:32 -0400 Received: from mail-qt0-f196.google.com ([209.85.216.196]:38341 "EHLO mail-qt0-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753904AbeD2QdS (ORCPT ); Sun, 29 Apr 2018 12:33:18 -0400 Received: by mail-qt0-f196.google.com with SMTP id z23-v6so8368815qti.5; Sun, 29 Apr 2018 09:33:18 -0700 (PDT) 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; bh=tzde+dU+y1XNCc+MFguafEdLWxSaq8FG4UBwzEJK2eY=; b=KTTfMUsfEcobpG3fbkt99OzBJYcrRfZqIKGFZyzWiUxUZADu+e1laKByEky993oZ63 gLCOkMu5PTbtrNJ8QWFedL5ayhll4annD555Bx1qWSJGw20FO7XRMwk4c8M1dqX/v+rc zCwfL2VpXKYhhfjY7gXwybujXoVeq1+wI5SPqLhjj5Mktvh8tGpL0YuyQ5xI0eEQuptI Iv17MLrHgqgoCI3pR3jwFVzUxcRtND/mGcxkybl4bbe0x8PrWSYk2HQz1O+b/1Vyob5A 269CHfaKgVUCd3KjwbV2IK7r7NZDeDWMl0tPTM652fuZACWpJi0YXb0mxedh2Ol6TG36 ohFQ== 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; bh=tzde+dU+y1XNCc+MFguafEdLWxSaq8FG4UBwzEJK2eY=; b=om6ZYnaMlrS9py2GuEikKXMFBeCwlZi3thBqtSYCVOe7MjB0ShRDNXWu/b8Cth/zVf o8LTeLVY/x15jgsbMQvKgftSwan3794GjWlCtgAfXtACX28NKnHlvOVmDfPoIURmbhop w+dqRpR0fOdwloaa9cxnXIkT05qGavvX/HWKznob8guY9Or/T6txeEC/xtKMUp6zOCC3 ij45Zd1BocH+qr57scHKA/yr67AW8lKdgn85JdCapI/3zwo5Ds4X8dRD/YsPyoVa5Ykl yxBHfG7OPq7wgp/LqpINCaa06pP/s5mOGasTYCDSL37w3u06zp3iNsI2O4SlN7VcxDdO +yvg== X-Gm-Message-State: ALQs6tDceRfNneAC5DPvhgsFjObxph78S6AWOJWEQOY96aJNgJL2ZbFb LwTf4qcRkFxNqy8pmElpdDY8dQ== X-Google-Smtp-Source: AB8JxZodzopavLArduiTqFZOkk9U2KVpmHk96ZS24++19NSxKCouFStk0GPAoe8OPG/Le01JsxPl6g== X-Received: by 2002:ac8:44cd:: with SMTP id b13-v6mr8560216qto.394.1525019597632; Sun, 29 Apr 2018 09:33:17 -0700 (PDT) Received: from localhost.localdomain ([177.10.56.95]) by smtp.gmail.com with ESMTPSA id f82sm4961927qkh.73.2018.04.29.09.33.15 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sun, 29 Apr 2018 09:33:16 -0700 (PDT) Received: by localhost.localdomain (Postfix, from userid 89) id 9E701181009; Sun, 29 Apr 2018 13:35:35 -0300 (-03) Received: by localhost.localdomain (Postfix, from userid 89) id A7FBD180916; Sun, 29 Apr 2018 13:25:30 -0300 (-03) Received: by localhost.localdomain (Postfix, from userid 89) id AEF511808BB; Sun, 29 Apr 2018 13:01:57 -0300 (-03) Received: by localhost.localdomain (Postfix, from userid 1000) id C520B180E66; Sun, 29 Apr 2018 12:56:37 -0300 (-03) From: Marcelo Ricardo Leitner To: netdev@vger.kernel.org Cc: linux-sctp@vger.kernel.org, Vlad Yasevich , Neil Horman , Xin Long Subject: [PATCH net-next 2/2] sctp: add sctp_make_op_error_limited and reuse inner functions Date: Sun, 29 Apr 2018 12:56:32 -0300 Message-Id: <53909b1bd523d45a453431968fd1e03fd4be6196.1525017179.git.marcelo.leitner@gmail.com> X-Mailer: git-send-email 2.14.3 In-Reply-To: References: Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org The idea is quite similar to the old functions, but note that the _fixed function wasn't "fixed" as in that it would generate a packet with a fixed size, but rather limited/bounded to PMTU. Also, now with sctp_mtu_payload(), we have a more accurate limit. Signed-off-by: Marcelo Ricardo Leitner --- net/sctp/sm_make_chunk.c | 130 +++++++++++++++++------------------------------ 1 file changed, 46 insertions(+), 84 deletions(-) diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c index e518eb64ccf3578f7892da050c160a56cf3cc833..4d7b3ccea0789f3a695f710046b50855e4cc41fc 100644 --- a/net/sctp/sm_make_chunk.c +++ b/net/sctp/sm_make_chunk.c @@ -81,8 +81,6 @@ static int sctp_process_param(struct sctp_association *asoc, gfp_t gfp); static void *sctp_addto_param(struct sctp_chunk *chunk, int len, const void *data); -static void *sctp_addto_chunk_fixed(struct sctp_chunk *, int len, - const void *data); /* Control chunk destructor */ static void sctp_control_release_owner(struct sk_buff *skb) @@ -154,9 +152,8 @@ static const struct sctp_paramhdr prsctp_param = { cpu_to_be16(sizeof(struct sctp_paramhdr)), }; -/* A helper to initialize an op error inside a - * provided chunk, as most cause codes will be embedded inside an - * abort chunk. +/* A helper to initialize an op error inside a provided chunk, as most + * cause codes will be embedded inside an abort chunk. */ int sctp_init_cause(struct sctp_chunk *chunk, __be16 cause_code, size_t paylen) @@ -177,29 +174,6 @@ int sctp_init_cause(struct sctp_chunk *chunk, __be16 cause_code, return 0; } -/* A helper to initialize an op error inside a - * provided chunk, as most cause codes will be embedded inside an - * abort chunk. Differs from sctp_init_cause in that it won't oops - * if there isn't enough space in the op error chunk - */ -static int sctp_init_cause_fixed(struct sctp_chunk *chunk, __be16 cause_code, - size_t paylen) -{ - struct sctp_errhdr err; - __u16 len; - - /* Cause code constants are now defined in network order. */ - err.cause = cause_code; - len = sizeof(err) + paylen; - err.length = htons(len); - - if (skb_tailroom(chunk->skb) < len) - return -ENOSPC; - - chunk->subh.err_hdr = sctp_addto_chunk_fixed(chunk, sizeof(err), &err); - - return 0; -} /* 3.3.2 Initiation (INIT) (1) * * This chunk is used to initiate a SCTP association between two @@ -1263,20 +1237,26 @@ static struct sctp_chunk *sctp_make_op_error_space( return retval; } -/* Create an Operation Error chunk of a fixed size, - * specifically, max(asoc->pathmtu, SCTP_DEFAULT_MAXSEGMENT) - * This is a helper function to allocate an error chunk for - * for those invalid parameter codes in which we may not want - * to report all the errors, if the incoming chunk is large +/* Create an Operation Error chunk of a fixed size, specifically, + * min(asoc->pathmtu, SCTP_DEFAULT_MAXSEGMENT) - overheads. + * This is a helper function to allocate an error chunk for for those + * invalid parameter codes in which we may not want to report all the + * errors, if the incoming chunk is large. If it can't fit in a single + * packet, we ignore it. */ -static inline struct sctp_chunk *sctp_make_op_error_fixed( +static inline struct sctp_chunk *sctp_make_op_error_limited( const struct sctp_association *asoc, const struct sctp_chunk *chunk) { - size_t size = asoc ? asoc->pathmtu : 0; + size_t size = SCTP_DEFAULT_MAXSEGMENT; + struct sctp_sock *sp = NULL; + + if (asoc) { + size = min_t(size_t, size, asoc->pathmtu); + sp = sctp_sk(asoc->base.sk); + } - if (!size) - size = SCTP_DEFAULT_MAXSEGMENT; + size = sctp_mtu_payload(sp, size, sizeof(struct sctp_errhdr)); return sctp_make_op_error_space(asoc, chunk, size); } @@ -1528,18 +1508,6 @@ void *sctp_addto_chunk(struct sctp_chunk *chunk, int len, const void *data) return target; } -/* Append bytes to the end of a chunk. Returns NULL if there isn't sufficient - * space in the chunk - */ -static void *sctp_addto_chunk_fixed(struct sctp_chunk *chunk, - int len, const void *data) -{ - if (skb_tailroom(chunk->skb) >= len) - return sctp_addto_chunk(chunk, len, data); - else - return NULL; -} - /* Append bytes from user space to the end of a chunk. Will panic if * chunk is not big enough. * Returns a kernel err value. @@ -1834,6 +1802,9 @@ struct sctp_association *sctp_unpack_cookie( kt = ktime_get_real(); if (!asoc && ktime_before(bear_cookie->expiration, kt)) { + suseconds_t usecs = ktime_to_us(ktime_sub(kt, bear_cookie->expiration)); + __be32 n = htonl(usecs); + /* * Section 3.3.10.3 Stale Cookie Error (3) * @@ -1842,17 +1813,12 @@ struct sctp_association *sctp_unpack_cookie( * Stale Cookie Error: Indicates the receipt of a valid State * Cookie that has expired. */ - len = ntohs(chunk->chunk_hdr->length); - *errp = sctp_make_op_error_space(asoc, chunk, len); - if (*errp) { - suseconds_t usecs = ktime_to_us(ktime_sub(kt, bear_cookie->expiration)); - __be32 n = htonl(usecs); - - sctp_init_cause(*errp, SCTP_ERROR_STALE_COOKIE, - sizeof(n)); - sctp_addto_chunk(*errp, sizeof(n), &n); + *errp = sctp_make_op_error(asoc, chunk, + SCTP_ERROR_STALE_COOKIE, &n, + sizeof(n), 0); + if (*errp) *error = -SCTP_IERROR_STALE_COOKIE; - } else + else *error = -SCTP_IERROR_NOMEM; goto fail; @@ -2003,12 +1969,8 @@ static int sctp_process_hn_param(const struct sctp_association *asoc, if (*errp) sctp_chunk_free(*errp); - *errp = sctp_make_op_error_space(asoc, chunk, len); - - if (*errp) { - sctp_init_cause(*errp, SCTP_ERROR_DNS_FAILED, len); - sctp_addto_chunk(*errp, len, param.v); - } + *errp = sctp_make_op_error(asoc, chunk, SCTP_ERROR_DNS_FAILED, + param.v, len, 0); /* Stop processing this chunk. */ return 0; @@ -2133,23 +2095,23 @@ static enum sctp_ierror sctp_process_unk_param( /* Make an ERROR chunk, preparing enough room for * returning multiple unknown parameters. */ - if (NULL == *errp) - *errp = sctp_make_op_error_fixed(asoc, chunk); - - if (*errp) { - if (!sctp_init_cause_fixed(*errp, SCTP_ERROR_UNKNOWN_PARAM, - SCTP_PAD4(ntohs(param.p->length)))) - sctp_addto_chunk_fixed(*errp, - SCTP_PAD4(ntohs(param.p->length)), - param.v); - } else { - /* If there is no memory for generating the ERROR - * report as specified, an ABORT will be triggered - * to the peer and the association won't be - * established. - */ - retval = SCTP_IERROR_NOMEM; + if (!*errp) { + *errp = sctp_make_op_error_limited(asoc, chunk); + if (!*errp) { + /* If there is no memory for generating the + * ERROR report as specified, an ABORT will be + * triggered to the peer and the association + * won't be established. + */ + retval = SCTP_IERROR_NOMEM; + break; + } } + + if (!sctp_init_cause(*errp, SCTP_ERROR_UNKNOWN_PARAM, + ntohs(param.p->length))) + sctp_addto_chunk(*errp, ntohs(param.p->length), + param.v); break; default: break; @@ -2225,10 +2187,10 @@ static enum sctp_ierror sctp_verify_param(struct net *net, * MUST be aborted. The ABORT chunk SHOULD contain the error * cause 'Protocol Violation'. */ - if (SCTP_AUTH_RANDOM_LENGTH != - ntohs(param.p->length) - sizeof(struct sctp_paramhdr)) { + if (SCTP_AUTH_RANDOM_LENGTH != ntohs(param.p->length) - + sizeof(struct sctp_paramhdr)) { sctp_process_inv_paramlength(asoc, param.p, - chunk, err_chunk); + chunk, err_chunk); retval = SCTP_IERROR_ABORT; } break;