From patchwork Fri Sep 8 07:00:14 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Axtens X-Patchwork-Id: 811336 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) by ozlabs.org (Postfix) with ESMTP id 3xpSrm6Zb8z9t2M; Fri, 8 Sep 2017 17:00:40 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1dqDHK-0000nc-1V; Fri, 08 Sep 2017 07:00:38 +0000 Received: from youngberry.canonical.com ([91.189.89.112]) by huckleberry.canonical.com with esmtps (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:128) (Exim 4.86_2) (envelope-from ) id 1dqDHI-0000mA-A2 for kernel-team@lists.canonical.com; Fri, 08 Sep 2017 07:00:36 +0000 Received: from mail-pg0-f70.google.com ([74.125.83.70]) by youngberry.canonical.com with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.76) (envelope-from ) id 1dqDHH-00039Z-UB for kernel-team@lists.canonical.com; Fri, 08 Sep 2017 07:00:36 +0000 Received: by mail-pg0-f70.google.com with SMTP id 188so3653804pgb.3 for ; Fri, 08 Sep 2017 00:00:35 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=2VLXzo8ZwYtDHgvTOcwrdW4K32TsYVZVOSSCDSTFO1o=; b=nGpHu+GkFTJKSyA1b4jEEqYfDz8GegPFxEIkF1FQ7r9a1o5pn8Esg43SQqrgqtvgsc OLJciCZLtableY9aWn7wWhqmS17CrTUnn+EyfIFu3FOBzudR6w+bWGFl8VAWcj1gkxC0 LvlKqdkweVUowjsRveVd4dBjVJIXk5kzHK3HhLE5tym3wpMuClWG7Ii2WYykbkXpRSYG MQ5j0u2i7cfqE3b3nEUrEJHonQR65yKVhtGrikaPR8lhfLlXi042VKHbmRvKxiMSRU51 7zYNZ7jqiUX0+Xc2Vt7cUiQSsyoyIaKtkUDDA+Y/BmT7FnsK0KWNf2YG3OuFuGOj7cIN 0C5Q== X-Gm-Message-State: AHPjjUinVfj7cztDIy65uRCvkebtpESK9h159U8CCW0dqKsbO65jDj3P X59UyNgPVSfwLmQ//KKG1cFNGEECVfvsY5mhJuE1B9iqRWlzHeGHTMc+H9HSaCwHR6OY403CS1J SCXtjSAR73YA04lybtDXB5eFxXoS9Ba95m1H6Kc4= X-Received: by 10.84.141.168 with SMTP id 37mr2383301plv.140.1504854034445; Fri, 08 Sep 2017 00:00:34 -0700 (PDT) X-Google-Smtp-Source: ADKCNb4dNtCSVzIaR7MSQd4uJ374xlj/K3KnBYbYq66AUZzYvpzjB2Dq0QlEpoDlmEAnp8ap+bUlJQ== X-Received: by 10.84.141.168 with SMTP id 37mr2383288plv.140.1504854034177; Fri, 08 Sep 2017 00:00:34 -0700 (PDT) Received: from localhost.localdomain (124-171-202-56.dyn.iinet.net.au. [124.171.202.56]) by smtp.gmail.com with ESMTPSA id 125sm2138129pff.5.2017.09.08.00.00.32 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 08 Sep 2017 00:00:33 -0700 (PDT) From: Daniel Axtens To: kernel-team@lists.canonical.com Subject: [SRU][Zesty][PATCH 3/7] sctp: add dst_pending_confirm flag Date: Fri, 8 Sep 2017 17:00:14 +1000 Message-Id: <20170908070018.4141-4-daniel.axtens@canonical.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170908070018.4141-1-daniel.axtens@canonical.com> References: <20170908070018.4141-1-daniel.axtens@canonical.com> X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Julian Anastasov BugLink: https://bugs.launchpad.net/bugs/1715812 Add new transport flag to allow sockets to confirm neighbour. When same struct dst_entry can be used for many different neighbours we can not use it for pending confirmations. The flag is propagated from transport to every packet. It is reset when cached dst is reset. Reported-by: YueHaibing Fixes: 5110effee8fd ("net: Do delayed neigh confirmation.") Fixes: f2bb4bedf35d ("ipv4: Cache output routes in fib_info nexthops.") Signed-off-by: Julian Anastasov Acked-by: Eric Dumazet Acked-by: Neil Horman Signed-off-by: David S. Miller (cherry picked from commit c86a773c78025f5b825bacd7b846f4fa60dc0317) Signed-off-by: Daniel Axtens --- include/net/sctp/sctp.h | 6 ++---- include/net/sctp/structs.h | 4 ++++ net/sctp/associola.c | 3 +-- net/sctp/output.c | 10 +++++++++- net/sctp/outqueue.c | 2 +- net/sctp/sm_make_chunk.c | 6 ++---- net/sctp/sm_sideeffect.c | 2 +- net/sctp/socket.c | 4 ++-- net/sctp/transport.c | 16 +++++++++++++++- 9 files changed, 37 insertions(+), 16 deletions(-) diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h index d8833a86cd7e..897f6365d98d 100644 --- a/include/net/sctp/sctp.h +++ b/include/net/sctp/sctp.h @@ -586,10 +586,8 @@ static inline void sctp_v4_map_v6(union sctp_addr *addr) */ static inline struct dst_entry *sctp_transport_dst_check(struct sctp_transport *t) { - if (t->dst && !dst_check(t->dst, t->dst_cookie)) { - dst_release(t->dst); - t->dst = NULL; - } + if (t->dst && !dst_check(t->dst, t->dst_cookie)) + sctp_transport_dst_release(t); return t->dst; } diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index 92daabdc007d..e842e84816f7 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h @@ -838,6 +838,8 @@ struct sctp_transport { __u32 burst_limited; /* Holds old cwnd when max.burst is applied */ + __u32 dst_pending_confirm; /* need to confirm neighbour */ + /* Destination */ struct dst_entry *dst; /* Source address. */ @@ -980,6 +982,8 @@ unsigned long sctp_transport_timeout(struct sctp_transport *); void sctp_transport_reset(struct sctp_transport *); void sctp_transport_update_pmtu(struct sock *, struct sctp_transport *, u32); void sctp_transport_immediate_rtx(struct sctp_transport *); +void sctp_transport_dst_release(struct sctp_transport *t); +void sctp_transport_dst_confirm(struct sctp_transport *t); /* This is the structure we use to queue packets as they come into diff --git a/net/sctp/associola.c b/net/sctp/associola.c index d3cc30c25c41..56a8c7df0f95 100644 --- a/net/sctp/associola.c +++ b/net/sctp/associola.c @@ -820,8 +820,7 @@ void sctp_assoc_control_transport(struct sctp_association *asoc, if (transport->state != SCTP_UNCONFIRMED) transport->state = SCTP_INACTIVE; else { - dst_release(transport->dst); - transport->dst = NULL; + sctp_transport_dst_release(transport); ulp_notify = false; } diff --git a/net/sctp/output.c b/net/sctp/output.c index f5320a87341e..116488a2b574 100644 --- a/net/sctp/output.c +++ b/net/sctp/output.c @@ -550,6 +550,7 @@ int sctp_packet_transmit(struct sctp_packet *packet, gfp_t gfp) struct sctp_association *asoc = tp->asoc; struct sctp_chunk *chunk, *tmp; int pkt_count, gso = 0; + int confirm; struct dst_entry *dst; struct sk_buff *head; struct sctphdr *sh; @@ -628,7 +629,14 @@ int sctp_packet_transmit(struct sctp_packet *packet, gfp_t gfp) asoc->peer.last_sent_to = tp; } head->ignore_df = packet->ipfragok; - tp->af_specific->sctp_xmit(head, tp); + confirm = tp->dst_pending_confirm; + if (confirm) + skb_set_dst_pending_confirm(head, 1); + /* neighbour should be confirmed on successful transmission or + * positive error + */ + if (tp->af_specific->sctp_xmit(head, tp) >= 0 && confirm) + tp->dst_pending_confirm = 0; out: list_for_each_entry_safe(chunk, tmp, &packet->chunk_list, list) { diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c index 34efaa4ef2f6..e4a940efc4a5 100644 --- a/net/sctp/outqueue.c +++ b/net/sctp/outqueue.c @@ -1641,7 +1641,7 @@ static void sctp_check_transmitted(struct sctp_outq *q, if (forward_progress) { if (transport->dst) - dst_confirm(transport->dst); + sctp_transport_dst_confirm(transport); } } diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c index 9e9690b7afe1..6fb15bf5387d 100644 --- a/net/sctp/sm_make_chunk.c +++ b/net/sctp/sm_make_chunk.c @@ -3317,8 +3317,7 @@ static void sctp_asconf_param_success(struct sctp_association *asoc, local_bh_enable(); list_for_each_entry(transport, &asoc->peer.transport_addr_list, transports) { - dst_release(transport->dst); - transport->dst = NULL; + sctp_transport_dst_release(transport); } break; case SCTP_PARAM_DEL_IP: @@ -3332,8 +3331,7 @@ static void sctp_asconf_param_success(struct sctp_association *asoc, local_bh_enable(); list_for_each_entry(transport, &asoc->peer.transport_addr_list, transports) { - dst_release(transport->dst); - transport->dst = NULL; + sctp_transport_dst_release(transport); } break; default: diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c index c345bf153bed..9255b291ebfd 100644 --- a/net/sctp/sm_sideeffect.c +++ b/net/sctp/sm_sideeffect.c @@ -723,7 +723,7 @@ static void sctp_cmd_transport_on(sctp_cmd_seq_t *cmds, * forward progress. */ if (t->dst) - dst_confirm(t->dst); + sctp_transport_dst_confirm(t); /* The receiver of the HEARTBEAT ACK should also perform an * RTT measurement for that destination transport address diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 6932cf34fea8..02de002ed7c5 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -592,7 +592,7 @@ static int sctp_send_asconf_add_ip(struct sock *sk, list_for_each_entry(trans, &asoc->peer.transport_addr_list, transports) { /* Clear the source and route cache */ - dst_release(trans->dst); + sctp_transport_dst_release(trans); trans->cwnd = min(4*asoc->pathmtu, max_t(__u32, 2*asoc->pathmtu, 4380)); trans->ssthresh = asoc->peer.i.a_rwnd; @@ -843,7 +843,7 @@ static int sctp_send_asconf_del_ip(struct sock *sk, */ list_for_each_entry(transport, &asoc->peer.transport_addr_list, transports) { - dst_release(transport->dst); + sctp_transport_dst_release(transport); sctp_transport_route(transport, NULL, sctp_sk(asoc->base.sk)); } diff --git a/net/sctp/transport.c b/net/sctp/transport.c index a1652ab63918..cd52f161ebd1 100644 --- a/net/sctp/transport.c +++ b/net/sctp/transport.c @@ -227,7 +227,7 @@ void sctp_transport_pmtu(struct sctp_transport *transport, struct sock *sk) { /* If we don't have a fresh route, look one up */ if (!transport->dst || transport->dst->obsolete) { - dst_release(transport->dst); + sctp_transport_dst_release(transport); transport->af_specific->get_dst(transport, &transport->saddr, &transport->fl, sk); } @@ -659,3 +659,17 @@ void sctp_transport_immediate_rtx(struct sctp_transport *t) sctp_transport_hold(t); } } + +/* Drop dst */ +void sctp_transport_dst_release(struct sctp_transport *t) +{ + dst_release(t->dst); + t->dst = NULL; + t->dst_pending_confirm = 0; +} + +/* Schedule neighbour confirm */ +void sctp_transport_dst_confirm(struct sctp_transport *t) +{ + t->dst_pending_confirm = 1; +}