From patchwork Fri Jan 5 00:06:31 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aahil Awatramani X-Patchwork-Id: 185172 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7301:6f82:b0:100:9c79:88ff with SMTP id tb2csp5939221dyb; Thu, 4 Jan 2024 16:07:28 -0800 (PST) X-Google-Smtp-Source: AGHT+IFIvxRugIA0imJoZxM/L2A1MiJKOPnQIjKMRk5APoRGs6sAvkUgYSi4QG0dCLrVvO+2mCcV X-Received: by 2002:ad4:5aad:0:b0:67f:dc29:f9d0 with SMTP id u13-20020ad45aad000000b0067fdc29f9d0mr1583948qvg.114.1704413248089; Thu, 04 Jan 2024 16:07:28 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1704413248; cv=none; d=google.com; s=arc-20160816; b=mQrqbvyPKo2ar8LeKAf3L25YuG0L4Yulpp6pveCtGcZli+I3QEORQkksMT/MzWOWrH q/KrXu8qLWooVHwOPKIUsqmy0Zg1gytVefEGhfgGXb65U/e/MOTJsgj1i0W06FzFfJui gkbVM0iMq27oouYoNzoDy5P0/J+jUyOCrXLzCn7C2dZObXgjAAmm7ubWupBuHOZimImZ tYzWjRX1jm2aMhddWUX4OuxjloTn27oKiY2HoyEixn9/x3uneTiaecjUPupEIOstJHAP hy6yFloo+zvJqLlF/f8v+a+6INeWYBueTm5kXMEhMrVirjho+cPXXNBB6KiuNOgfuDJN hUzQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=to:from:subject:message-id:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:date:dkim-signature; bh=ZCm4qbqYLKL0X2tawwVQnjcJ74n/29xH0+vMdcngW8c=; fh=GyVGW8U1MvtbEyh/ldAgs7Rk0zl8uwbRC+ltCCnLM7k=; b=Rf6QnxCgdZNOwBMSmPP2ZEDOxwkcfmtbt9YIqSzLI60HqXn+vMaq+yYj72VPiPNeYP jVoNnMKaWbpqfInJBsUsPxNhnjfLDPNMl3qkfOAHpguk2T0B9cOSdUxAGjWHB75x483q KU/Glk3lHHzwWdLR7wguXGCKktHn28RcrnVxgp32Pmhz742Dz+8KZbvTF+wHZN4EYhEU /gWlHcNECbM924NQGg4atmUSGpqC/qwX1i036v+0jhUPYXkUsHAk8zqEltuGKD7nrhow OnpHxjjZm7d5d5W5/hUeIF4fVIfoU95diRgZiwe+3kXJIK1Q+gYSAG7THJ0VHtodQdqi XDKA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=mNUcjAqj; spf=pass (google.com: domain of linux-kernel+bounces-17347-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) smtp.mailfrom="linux-kernel+bounces-17347-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [147.75.199.223]) by mx.google.com with ESMTPS id bi29-20020a05620a319d00b0078308612decsi365649qkb.127.2024.01.04.16.07.27 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 04 Jan 2024 16:07:28 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-17347-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) client-ip=147.75.199.223; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=mNUcjAqj; spf=pass (google.com: domain of linux-kernel+bounces-17347-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) smtp.mailfrom="linux-kernel+bounces-17347-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ny.mirrors.kernel.org (Postfix) with ESMTPS id DC7361C22017 for ; Fri, 5 Jan 2024 00:07:27 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 1263C28F2; Fri, 5 Jan 2024 00:07:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="mNUcjAqj" X-Original-To: linux-kernel@vger.kernel.org Received: from mail-pg1-f201.google.com (mail-pg1-f201.google.com [209.85.215.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 376891FCA for ; Fri, 5 Jan 2024 00:07:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--aahila.bounces.google.com Received: by mail-pg1-f201.google.com with SMTP id 41be03b00d2f7-5c65e666609so952533a12.1 for ; Thu, 04 Jan 2024 16:07:03 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1704413222; x=1705018022; darn=vger.kernel.org; h=to:from:subject:message-id:mime-version:date:from:to:cc:subject :date:message-id:reply-to; bh=ZCm4qbqYLKL0X2tawwVQnjcJ74n/29xH0+vMdcngW8c=; b=mNUcjAqjjvGF5xpDOMseDVfN7pidAvcDn8p7kxy/x5Bdu8hGrAxDFUyALF3G9VVPt9 7A9UOgTMNICN4XfcSibsZJFqevzeUebtcwSQ54z76f8/QKtXF2mOdUx63kXLWtH5jzMj G9jnxMyzXf5LzCBZJqoSpSqXjboQAZS8JqOq1E8dShtX2JiCwUhEK83omsumSpSquATp oTWHipD7KjgO1ox5zJ7Nu1SY0K4iQ37eQjuXVjutPMc4WpsAHED/BNMkfb+OvfIr9vxN t5picz7zohze/dJNHm+bs3Q0ebLtvvc0On42MA5jbOQEEzHtug7dYGni8aclLLSaZLl0 mpbg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1704413222; x=1705018022; h=to:from:subject:message-id:mime-version:date:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=ZCm4qbqYLKL0X2tawwVQnjcJ74n/29xH0+vMdcngW8c=; b=jsaOutFVka3yQnJDNMYSN9Rmqsg4CwZb2IZLijhD495BZuFZ86Tl7O110vACBT82IN jzycmyTX2l/dwB5AzOzX3/h2pCaejbNddUf5jN0Yy2AvhQR+Ry/xxZ5T0CDY7UY33p8U WrUATot48LD/7T3L0VKKF8vNiC6TVC3uGLjDXarUbC6/CYYQ2xFiw5DbecNlc3l4MKcx BfMZixKcqkUTjFIkAUYoERVndYtmu2Fgi2Pj1gnPdWTYfiqWoDzzTm++S/uc+aHdoUau lG5Wj2TkDkhUROz0enVe9fYzub8TG0iYuelhjFMI8nzupS4VXspznobtHeZbCx/M9KdL FhYg== X-Gm-Message-State: AOJu0YxryDxTXEfsAgbi8TCV6ZUzo3C43rceqf0C/QiBNXiIbnstrT6F 9dgdE8UW1wuips/rWpr7wAddnDbtJrO9v7KQUQ== X-Received: from aahila.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:2f3]) (user=aahila job=sendgmr) by 2002:a05:6a02:491:b0:5ce:474:352b with SMTP id bw17-20020a056a02049100b005ce0474352bmr7789pgb.5.1704413222131; Thu, 04 Jan 2024 16:07:02 -0800 (PST) Date: Fri, 5 Jan 2024 00:06:31 +0000 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 X-Mailer: git-send-email 2.43.0.472.g3155946c3a-goog Message-ID: <20240105000632.2484182-1-aahila@google.com> Subject: [PATCH 1/2 net-next v2] bonding: Extending LACP MUX State Machine to include a Collecting State. From: Aahil Awatramani To: Aahil Awatramani , David Dillow , Mahesh Bandewar , Jay Vosburgh , Andy Gospodarek , "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Martin KaFai Lau , Herbert Xu , Daniel Borkmann , netdev@vger.kernel.org, linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1785857305613733901 X-GMAIL-MSGID: 1787206826171305096 Introduces two new states, AD_MUX_COLLECTING and AD_MUX_DISTRIBUTING in the LACP MUX state machine for separated handling of an initial Collecting state before the Collecting and Distributing state. This enables a port to be in a state where it can receive incoming packets while not still distributing. This is useful for reducing packet loss when a port begins distributing before its partner is able to collect. Additionally this also brings the 802.3ad bonding driver's implementation closer to the LACP specification which already predefined this behaviour, that is currently the implementation only supports coupled control. Added new functions such as bond_set_slave_tx_disabled_flags and bond_set_slave_rx_enabled_flags to precisely manage the port's collecting and distributing states. Previously, there was no dedicated method to disable TX while keeping RX enabled, which this patch addresses. Note that the regular flow process in the kernel's bonding driver remains unaffected by this patch. The extension requires explicit opt-in by the user (in order to ensure no disruptions for existing setups) via netlink support using the new bonding parameter coupled_control. The default value for coupled_control is set to 1 so as to preserve existing behaviour. Signed-off-by: Aahil Awatramani --- Documentation/networking/bonding.rst | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Documentation/networking/bonding.rst b/Documentation/networking/bonding.rst index f7a73421eb76..cb3e6013605d 100644 --- a/Documentation/networking/bonding.rst +++ b/Documentation/networking/bonding.rst @@ -444,6 +444,14 @@ arp_missed_max The default value is 2, and the allowable range is 1 - 255. +coupled_control + + Specifies whether the LACP state machine's MUX in the 802.3ad mode + should have separate Collecting and Distributing states. + + The default value is 1. This setting does not separate the Collecting + and Distributing states, maintaining the bond in coupled control. + downdelay Specifies the time, in milliseconds, to wait before disabling From patchwork Fri Jan 5 00:06:32 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aahil Awatramani X-Patchwork-Id: 185173 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7301:6f82:b0:100:9c79:88ff with SMTP id tb2csp5939368dyb; Thu, 4 Jan 2024 16:07:47 -0800 (PST) X-Google-Smtp-Source: AGHT+IFyN+TO2EdF3swSN+32xnzsSu6U9zou1qWAf83AuxpMgEv51luuaNuoHQRFci0gCuugfXS1 X-Received: by 2002:a05:6214:301a:b0:67f:da1f:8cec with SMTP id ke26-20020a056214301a00b0067fda1f8cecmr1359686qvb.131.1704413267131; Thu, 04 Jan 2024 16:07:47 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1704413267; cv=none; d=google.com; s=arc-20160816; b=zOJtEHDCWG6K1tmEXtombH7buNWsNteLQ4Kuz/jK7yzVrcSz2iHHFzFiDyFg5KzTy4 cyBLsJqSqs6YepRAcAR3aOr4tDXHIQ7bxCSQRDR3Co3GJCSUPfLYbkuy5Zg5pmMdtZTu 60rk3r8vm1q28HXO9EmZA2rFj7mtWDsUcsrV1r0kdWXY2AJ6SGw+XIYRZiD0sx+CZaqL oDx88n3kf5ji21TIFXkvJx2OBne76v3PIpSp2bPJ1tE4UoSPHtvUqKP7SDqjW4Z6fOzd Svtkr1EUzGofYlxTTigPrmJySqt24AFC+VMPfmg3C1R4P2hTZ/1QQ4vx01KL3Fn3U10C IiqA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=to:from:subject:message-id:references:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:in-reply-to:date:dkim-signature; bh=c/PZhfRDJE4f2N26DQZJBtaJ77B1vFZQghFrW+dCwes=; fh=GyVGW8U1MvtbEyh/ldAgs7Rk0zl8uwbRC+ltCCnLM7k=; b=RZvjEpt/Sq8Ea1fI3T1NpooxTP9kxy4yWZyK5u8mEvhMbltcdajNrJHdAOcIXN73yy 70zzKQ3SQneQqGDDaw5BI5ixOGtv2Zm2DpU3gaPzx+OKPnGIEPcBOT+eY4HoprpXgrt5 q7KHRuzfJ342gTfLbXC5JmBfBUPsvVYcTVmxL8Sgt+iLSSme+75XCXitpJheLdyxQUMK ZsAZgExL9H6aqFXB+1y/cY3VJ6Di1mN+rIMCGHyNuD1eG2qiPuLVXHLOnJmSoF0ZWdm2 eFTO3w6miWDGsU28M8mAEayzM99Wsuu/wVA0s8h7PnEdKhAbZQN3yJucUxm4btgO56LD BBWQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=d4ui8gZb; spf=pass (google.com: domain of linux-kernel+bounces-17348-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) smtp.mailfrom="linux-kernel+bounces-17348-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [147.75.199.223]) by mx.google.com with ESMTPS id q3-20020a05620a024300b00781ed0152a2si534779qkn.666.2024.01.04.16.07.47 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 04 Jan 2024 16:07:47 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-17348-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) client-ip=147.75.199.223; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=d4ui8gZb; spf=pass (google.com: domain of linux-kernel+bounces-17348-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) smtp.mailfrom="linux-kernel+bounces-17348-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ny.mirrors.kernel.org (Postfix) with ESMTPS id D85141C221B7 for ; Fri, 5 Jan 2024 00:07:46 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 8BA67290A; Fri, 5 Jan 2024 00:07:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="d4ui8gZb" X-Original-To: linux-kernel@vger.kernel.org Received: from mail-yb1-f201.google.com (mail-yb1-f201.google.com [209.85.219.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AEDE9290D for ; Fri, 5 Jan 2024 00:07:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--aahila.bounces.google.com Received: by mail-yb1-f201.google.com with SMTP id 3f1490d57ef6-dbea2ea8363so1192073276.2 for ; Thu, 04 Jan 2024 16:07:09 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1704413228; x=1705018028; darn=vger.kernel.org; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=c/PZhfRDJE4f2N26DQZJBtaJ77B1vFZQghFrW+dCwes=; b=d4ui8gZbiCrjzjhIT5BfEYaEBIawv4rceaA1phX03JByoV6rDe8E6Ri8AE19BfA0MW 8yh7P6vKW3VsZG4QHDyiB2S0EeF9VYpKQf3mJEBdwYJjHBAaPn9VMxKjDCJm+uayTzo1 pKtN2wHCN3NLKHmmBvRK2/GoE/nIqyEUB2YhuhpdtaauN4YvXHviI2lbXlW3bQsrbq0X nupunR0EheKaGgQhpnBvP6Jxa+SJfd6WoxYDJO1jsj86zy1v4YUR+oN6IArVmrSJFLVQ lTRenEZZfTXMEfuCO8CAEH64a0P+rMB5/mz54P8J5YS3T3gwOel6bYkbQ6m3L/YxNtzf usNg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1704413228; x=1705018028; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=c/PZhfRDJE4f2N26DQZJBtaJ77B1vFZQghFrW+dCwes=; b=GRm5Brqo1DGz40oz6zo/EPatht/W41WzdeWtQXoAA4mnBr/AmQAJ7lcyvo5qzk+vt1 ufGB5jCCit42304Bh0HdSBqhUCKkGt5ffQA+v5OL3xvTWqzWD9bzGCm+vuVT1paTN5tH MsNGYc5c8rCgsMdRL4x9Ngu2w7bOQZDtr4EzhH11rvFMnX/wFYagJu6HFe5IFQPL7FtI PJa0veLR6XqJ6EB/wkpNcwlJ1+zXvR15WQR3L5dAT3qdtcIegEbU+/OZQ9oEQJCrOuMV tOjNwB7czMWKZzZQZHs3fQB/hjn9bol/xM65F883NJQeuGxHK1j/vNKP0YDL6d4YSVqp nrtw== X-Gm-Message-State: AOJu0YwDULXoOtnfQO96skJ1rQi/KBnNxBTQt6f4iyosyJXeybsyg/z8 5ro3ODr0jJipjybSpjH49Zm5kplIoqyJkaFeig== X-Received: from aahila.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:2f3]) (user=aahila job=sendgmr) by 2002:a25:8241:0:b0:dbe:30cd:8fcb with SMTP id d1-20020a258241000000b00dbe30cd8fcbmr36564ybn.0.1704413228688; Thu, 04 Jan 2024 16:07:08 -0800 (PST) Date: Fri, 5 Jan 2024 00:06:32 +0000 In-Reply-To: <20240105000632.2484182-1-aahila@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240105000632.2484182-1-aahila@google.com> X-Mailer: git-send-email 2.43.0.472.g3155946c3a-goog Message-ID: <20240105000632.2484182-2-aahila@google.com> Subject: [PATCH 2/2 net-next v2] bonding: Extending LACP MUX State Machine to include a Collecting State. From: Aahil Awatramani To: Aahil Awatramani , David Dillow , Mahesh Bandewar , Jay Vosburgh , Andy Gospodarek , "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Martin KaFai Lau , Herbert Xu , Daniel Borkmann , netdev@vger.kernel.org, linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1785857305613733901 X-GMAIL-MSGID: 1787206846146672812 Introduces two new states, AD_MUX_COLLECTING and AD_MUX_DISTRIBUTING in the LACP MUX state machine for separated handling of an initial Collecting state before the Collecting and Distributing state. This enables a port to be in a state where it can receive incoming packets while not still distributing. This is useful for reducing packet loss when a port begins distributing before its partner is able to collect. Additionally this also brings the 802.3ad bonding driver's implementation closer to the LACP specification which already predefined this behaviour, that is currently the implementation only supports coupled control. Added new functions such as bond_set_slave_tx_disabled_flags and bond_set_slave_rx_enabled_flags to precisely manage the port's collecting and distributing states. Previously, there was no dedicated method to disable TX while keeping RX enabled, which this patch addresses. Note that the regular flow process in the kernel's bonding driver remains unaffected by this patch. The extension requires explicit opt-in by the user (in order to ensure no disruptions for existing setups) via netlink support using the new bonding parameter coupled_control. The default value for coupled_control is set to 1 so as to preserve existing behaviour. Signed-off-by: Aahil Awatramani --- drivers/net/bonding/bond_3ad.c | 159 +++++++++++++++++++++++++++-- drivers/net/bonding/bond_main.c | 1 + drivers/net/bonding/bond_netlink.c | 16 +++ drivers/net/bonding/bond_options.c | 26 ++++- include/net/bond_3ad.h | 2 + include/net/bond_options.h | 1 + include/net/bonding.h | 23 +++++ include/uapi/linux/if_link.h | 1 + tools/include/uapi/linux/if_link.h | 1 + 9 files changed, 222 insertions(+), 8 deletions(-) diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c index c99ffe6c683a..c2a658f2aaa3 100644 --- a/drivers/net/bonding/bond_3ad.c +++ b/drivers/net/bonding/bond_3ad.c @@ -106,6 +106,9 @@ static void ad_agg_selection_logic(struct aggregator *aggregator, static void ad_clear_agg(struct aggregator *aggregator); static void ad_initialize_agg(struct aggregator *aggregator); static void ad_initialize_port(struct port *port, int lacp_fast); +static void ad_enable_collecting(struct port *port); +static void ad_disable_distributing(struct port *port, + bool *update_slave_arr); static void ad_enable_collecting_distributing(struct port *port, bool *update_slave_arr); static void ad_disable_collecting_distributing(struct port *port, @@ -171,9 +174,38 @@ static inline int __agg_has_partner(struct aggregator *agg) return !is_zero_ether_addr(agg->partner_system.mac_addr_value); } +/** + * __disable_distributing_port - disable the port's slave for distributing. + * Port will still be able to collect. + * @port: the port we're looking at + * + * This will disable only distributing on the port's slave. + */ +static inline void __disable_distributing_port(struct port *port) +{ + bond_set_slave_tx_disabled_flags(port->slave, BOND_SLAVE_NOTIFY_LATER); +} + +/** + * __enable_collecting_port - enable the port's slave for collecting, + * if it's up + * @port: the port we're looking at + * + * This will enable only collecting on the port's slave. + */ +static inline void __enable_collecting_port(struct port *port) +{ + struct slave *slave = port->slave; + + if (slave->link == BOND_LINK_UP && bond_slave_is_up(slave)) + bond_set_slave_rx_enabled_flags(slave, BOND_SLAVE_NOTIFY_LATER); +} + /** * __disable_port - disable the port's slave * @port: the port we're looking at + * + * This will disable both collecting and distributing on the port's slave. */ static inline void __disable_port(struct port *port) { @@ -183,6 +215,8 @@ static inline void __disable_port(struct port *port) /** * __enable_port - enable the port's slave, if it's up * @port: the port we're looking at + * + * This will enable both collecting and distributing on the port's slave. */ static inline void __enable_port(struct port *port) { @@ -193,10 +227,24 @@ static inline void __enable_port(struct port *port) } /** - * __port_is_enabled - check if the port's slave is in active state + * __port_should_mux_attached - check if port should transition back to attached + * state. * @port: the port we're looking at */ -static inline int __port_is_enabled(struct port *port) +static inline int __port_should_mux_attached(struct port *port) +{ + return !(port->sm_vars & AD_PORT_SELECTED) || + (port->sm_vars & AD_PORT_STANDBY) || + !(port->partner_oper.port_state & LACP_STATE_SYNCHRONIZATION) || + !(port->actor_oper_port_state & LACP_STATE_SYNCHRONIZATION); +} + +/** + * __port_is_collecting_distributing - check if the port's slave is in the + * combined collecting/distributing state + * @port: the port we're looking at + */ +static inline int __port_is_collecting_distributing(struct port *port) { return bond_is_active_slave(port->slave); } @@ -942,6 +990,7 @@ static int ad_marker_send(struct port *port, struct bond_marker *marker) */ static void ad_mux_machine(struct port *port, bool *update_slave_arr) { + struct bonding *bond = __get_bond_by_port(port); mux_states_t last_state; /* keep current State Machine state to compare later if it was @@ -999,9 +1048,13 @@ static void ad_mux_machine(struct port *port, bool *update_slave_arr) if ((port->sm_vars & AD_PORT_SELECTED) && (port->partner_oper.port_state & LACP_STATE_SYNCHRONIZATION) && !__check_agg_selection_timer(port)) { - if (port->aggregator->is_active) - port->sm_mux_state = - AD_MUX_COLLECTING_DISTRIBUTING; + if (port->aggregator->is_active) { + int state = AD_MUX_COLLECTING_DISTRIBUTING; + + if (!bond->params.coupled_control) + state = AD_MUX_COLLECTING; + port->sm_mux_state = state; + } } else if (!(port->sm_vars & AD_PORT_SELECTED) || (port->sm_vars & AD_PORT_STANDBY)) { /* if UNSELECTED or STANDBY */ @@ -1019,11 +1072,50 @@ static void ad_mux_machine(struct port *port, bool *update_slave_arr) } break; case AD_MUX_COLLECTING_DISTRIBUTING: + if (__port_should_mux_attached(port)) { + port->sm_mux_state = AD_MUX_ATTACHED; + } else { + /* if port state hasn't changed make + * sure that a collecting distributing + * port in an active aggregator is enabled + */ + if (port->aggregator && + port->aggregator->is_active && + !__port_is_collecting_distributing(port)) { + __enable_port(port); + *update_slave_arr = true; + } + } + break; + case AD_MUX_COLLECTING: + if (__port_should_mux_attached(port)) { + port->sm_mux_state = AD_MUX_ATTACHED; + } else if ((port->sm_vars & AD_PORT_SELECTED) && + (port->partner_oper.port_state & LACP_STATE_SYNCHRONIZATION) && + (port->partner_oper.port_state & LACP_STATE_COLLECTING)) { + port->sm_mux_state = AD_MUX_DISTRIBUTING; + } else { + /* If port state hasn't changed, make sure that a collecting + * port is enabled for an active aggregator. + */ + if (port->aggregator && + port->aggregator->is_active) { + struct slave *slave = port->slave; + + if (bond_is_slave_rx_disabled(slave) != 0) { + ad_enable_collecting(port); + *update_slave_arr = true; + } + } + } + break; + case AD_MUX_DISTRIBUTING: if (!(port->sm_vars & AD_PORT_SELECTED) || (port->sm_vars & AD_PORT_STANDBY) || + !(port->partner_oper.port_state & LACP_STATE_COLLECTING) || !(port->partner_oper.port_state & LACP_STATE_SYNCHRONIZATION) || !(port->actor_oper_port_state & LACP_STATE_SYNCHRONIZATION)) { - port->sm_mux_state = AD_MUX_ATTACHED; + port->sm_mux_state = AD_MUX_COLLECTING; } else { /* if port state hasn't changed make * sure that a collecting distributing @@ -1031,7 +1123,7 @@ static void ad_mux_machine(struct port *port, bool *update_slave_arr) */ if (port->aggregator && port->aggregator->is_active && - !__port_is_enabled(port)) { + !__port_is_collecting_distributing(port)) { __enable_port(port); *update_slave_arr = true; } @@ -1082,6 +1174,20 @@ static void ad_mux_machine(struct port *port, bool *update_slave_arr) update_slave_arr); port->ntt = true; break; + case AD_MUX_COLLECTING: + port->actor_oper_port_state |= LACP_STATE_COLLECTING; + port->actor_oper_port_state &= ~LACP_STATE_DISTRIBUTING; + port->actor_oper_port_state |= LACP_STATE_SYNCHRONIZATION; + ad_enable_collecting(port); + ad_disable_distributing(port, update_slave_arr); + port->ntt = true; + break; + case AD_MUX_DISTRIBUTING: + port->actor_oper_port_state |= LACP_STATE_DISTRIBUTING; + port->actor_oper_port_state |= LACP_STATE_SYNCHRONIZATION; + ad_enable_collecting_distributing(port, + update_slave_arr); + break; default: break; } @@ -1906,6 +2012,45 @@ static void ad_initialize_port(struct port *port, int lacp_fast) } } +/** + * ad_enable_collecting - enable a port's receive + * @port: the port we're looking at + * + * Enable @port if it's in an active aggregator + */ +static void ad_enable_collecting(struct port *port) +{ + if (port->aggregator->is_active) { + struct slave *slave = port->slave; + + slave_dbg(slave->bond->dev, slave->dev, + "Enabling collecting on port %d (LAG %d)\n", + port->actor_port_number, + port->aggregator->aggregator_identifier); + __enable_collecting_port(port); + } +} + +/** + * ad_disable_distributing - disable a port's transmit + * @port: the port we're looking at + * @update_slave_arr: Does slave array need update? + */ +static void ad_disable_distributing(struct port *port, bool *update_slave_arr) +{ + if (port->aggregator && + !MAC_ADDRESS_EQUAL(&port->aggregator->partner_system, + &(null_mac_addr))) { + slave_dbg(port->slave->bond->dev, port->slave->dev, + "Disabling distributing on port %d (LAG %d)\n", + port->actor_port_number, + port->aggregator->aggregator_identifier); + __disable_distributing_port(port); + /* Slave array needs an update */ + *update_slave_arr = true; + } +} + /** * ad_enable_collecting_distributing - enable a port's transmit/receive * @port: the port we're looking at diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 8e6cc0e133b7..30f4b0ff01c0 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -6331,6 +6331,7 @@ static int __init bond_check_params(struct bond_params *params) params->ad_actor_sys_prio = ad_actor_sys_prio; eth_zero_addr(params->ad_actor_system); params->ad_user_port_key = ad_user_port_key; + params->coupled_control = 1; if (packets_per_slave > 0) { params->reciprocal_packets_per_slave = reciprocal_value(packets_per_slave); diff --git a/drivers/net/bonding/bond_netlink.c b/drivers/net/bonding/bond_netlink.c index cfa74cf8bb1a..29b4c3d1b9b6 100644 --- a/drivers/net/bonding/bond_netlink.c +++ b/drivers/net/bonding/bond_netlink.c @@ -122,6 +122,7 @@ static const struct nla_policy bond_policy[IFLA_BOND_MAX + 1] = { [IFLA_BOND_PEER_NOTIF_DELAY] = NLA_POLICY_FULL_RANGE(NLA_U32, &delay_range), [IFLA_BOND_MISSED_MAX] = { .type = NLA_U8 }, [IFLA_BOND_NS_IP6_TARGET] = { .type = NLA_NESTED }, + [IFLA_BOND_COUPLED_CONTROL] = { .type = NLA_U8 }, }; static const struct nla_policy bond_slave_policy[IFLA_BOND_SLAVE_MAX + 1] = { @@ -549,6 +550,16 @@ static int bond_changelink(struct net_device *bond_dev, struct nlattr *tb[], return err; } + if (data[IFLA_BOND_COUPLED_CONTROL]) { + int coupled_control = nla_get_u8(data[IFLA_BOND_COUPLED_CONTROL]); + + bond_opt_initval(&newval, coupled_control); + err = __bond_opt_set(bond, BOND_OPT_COUPLED_CONTROL, &newval, + data[IFLA_BOND_COUPLED_CONTROL], extack); + if (err) + return err; + } + return 0; } @@ -615,6 +626,7 @@ static size_t bond_get_size(const struct net_device *bond_dev) /* IFLA_BOND_NS_IP6_TARGET */ nla_total_size(sizeof(struct nlattr)) + nla_total_size(sizeof(struct in6_addr)) * BOND_MAX_NS_TARGETS + + nla_total_size(sizeof(u8)) + /* IFLA_BOND_COUPLED_CONTROL */ 0; } @@ -774,6 +786,10 @@ static int bond_fill_info(struct sk_buff *skb, bond->params.missed_max)) goto nla_put_failure; + if (nla_put_u8(skb, IFLA_BOND_COUPLED_CONTROL, + bond->params.coupled_control)) + goto nla_put_failure; + if (BOND_MODE(bond) == BOND_MODE_8023AD) { struct ad_info info; diff --git a/drivers/net/bonding/bond_options.c b/drivers/net/bonding/bond_options.c index f3f27f0bd2a6..af5d3c57700b 100644 --- a/drivers/net/bonding/bond_options.c +++ b/drivers/net/bonding/bond_options.c @@ -84,7 +84,8 @@ static int bond_option_ad_user_port_key_set(struct bonding *bond, const struct bond_opt_value *newval); static int bond_option_missed_max_set(struct bonding *bond, const struct bond_opt_value *newval); - +static int bond_option_coupled_control_set(struct bonding *bond, + const struct bond_opt_value *newval); static const struct bond_opt_value bond_mode_tbl[] = { { "balance-rr", BOND_MODE_ROUNDROBIN, BOND_VALFLAG_DEFAULT}, @@ -232,6 +233,12 @@ static const struct bond_opt_value bond_missed_max_tbl[] = { { NULL, -1, 0}, }; +static const struct bond_opt_value bond_coupled_control_tbl[] = { + { "on", 1, BOND_VALFLAG_DEFAULT}, + { "off", 0, 0}, + { NULL, -1, 0}, +}; + static const struct bond_option bond_opts[BOND_OPT_LAST] = { [BOND_OPT_MODE] = { .id = BOND_OPT_MODE, @@ -496,6 +503,14 @@ static const struct bond_option bond_opts[BOND_OPT_LAST] = { .desc = "Delay between each peer notification on failover event, in milliseconds", .values = bond_peer_notif_delay_tbl, .set = bond_option_peer_notif_delay_set + }, + [BOND_OPT_COUPLED_CONTROL] = { + .id = BOND_OPT_COUPLED_CONTROL, + .name = "coupled_control", + .desc = "Opt into using coupled control MUX for LACP states", + .unsuppmodes = BOND_MODE_ALL_EX(BIT(BOND_MODE_8023AD)), + .values = bond_coupled_control_tbl, + .set = bond_option_coupled_control_set, } }; @@ -1692,3 +1707,12 @@ static int bond_option_ad_user_port_key_set(struct bonding *bond, bond->params.ad_user_port_key = newval->value; return 0; } + +static int bond_option_coupled_control_set(struct bonding *bond, + const struct bond_opt_value *newval) +{ + netdev_info(bond->dev, "Setting coupled_control to %s (%llu)\n", + newval->string, newval->value); + bond->params.coupled_control = newval->value; + return 0; +} diff --git a/include/net/bond_3ad.h b/include/net/bond_3ad.h index c5e57c6bd873..9ce5ac2bfbad 100644 --- a/include/net/bond_3ad.h +++ b/include/net/bond_3ad.h @@ -54,6 +54,8 @@ typedef enum { AD_MUX_DETACHED, /* mux machine */ AD_MUX_WAITING, /* mux machine */ AD_MUX_ATTACHED, /* mux machine */ + AD_MUX_COLLECTING, /* mux machine */ + AD_MUX_DISTRIBUTING, /* mux machine */ AD_MUX_COLLECTING_DISTRIBUTING /* mux machine */ } mux_states_t; diff --git a/include/net/bond_options.h b/include/net/bond_options.h index 69292ecc0325..473a0147769e 100644 --- a/include/net/bond_options.h +++ b/include/net/bond_options.h @@ -76,6 +76,7 @@ enum { BOND_OPT_MISSED_MAX, BOND_OPT_NS_TARGETS, BOND_OPT_PRIO, + BOND_OPT_COUPLED_CONTROL, BOND_OPT_LAST }; diff --git a/include/net/bonding.h b/include/net/bonding.h index 5b8b1b644a2d..b61fb1aa3a56 100644 --- a/include/net/bonding.h +++ b/include/net/bonding.h @@ -148,6 +148,7 @@ struct bond_params { #if IS_ENABLED(CONFIG_IPV6) struct in6_addr ns_targets[BOND_MAX_NS_TARGETS]; #endif + int coupled_control; /* 2 bytes of padding : see ether_addr_equal_64bits() */ u8 ad_actor_system[ETH_ALEN + 2]; @@ -167,6 +168,7 @@ struct slave { u8 backup:1, /* indicates backup slave. Value corresponds with BOND_STATE_ACTIVE and BOND_STATE_BACKUP */ inactive:1, /* indicates inactive slave */ + rx_disabled:1, /* indicates whether slave's Rx is disabled */ should_notify:1, /* indicates whether the state changed */ should_notify_link:1; /* indicates whether the link changed */ u8 duplex; @@ -568,6 +570,14 @@ static inline void bond_set_slave_inactive_flags(struct slave *slave, bond_set_slave_state(slave, BOND_STATE_BACKUP, notify); if (!slave->bond->params.all_slaves_active) slave->inactive = 1; + if (BOND_MODE(slave->bond) == BOND_MODE_8023AD) + slave->rx_disabled = 1; +} + +static inline void bond_set_slave_tx_disabled_flags(struct slave *slave, + bool notify) +{ + bond_set_slave_state(slave, BOND_STATE_BACKUP, notify); } static inline void bond_set_slave_active_flags(struct slave *slave, @@ -575,6 +585,14 @@ static inline void bond_set_slave_active_flags(struct slave *slave, { bond_set_slave_state(slave, BOND_STATE_ACTIVE, notify); slave->inactive = 0; + if (BOND_MODE(slave->bond) == BOND_MODE_8023AD) + slave->rx_disabled = 0; +} + +static inline void bond_set_slave_rx_enabled_flags(struct slave *slave, + bool notify) +{ + slave->rx_disabled = 0; } static inline bool bond_is_slave_inactive(struct slave *slave) @@ -582,6 +600,11 @@ static inline bool bond_is_slave_inactive(struct slave *slave) return slave->inactive; } +static inline bool bond_is_slave_rx_disabled(struct slave *slave) +{ + return slave->rx_disabled; +} + static inline void bond_propose_link_state(struct slave *slave, int state) { slave->link_new_state = state; diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h index 29ff80da2775..7a54fcff2eec 100644 --- a/include/uapi/linux/if_link.h +++ b/include/uapi/linux/if_link.h @@ -976,6 +976,7 @@ enum { IFLA_BOND_AD_LACP_ACTIVE, IFLA_BOND_MISSED_MAX, IFLA_BOND_NS_IP6_TARGET, + IFLA_BOND_COUPLED_CONTROL, __IFLA_BOND_MAX, }; diff --git a/tools/include/uapi/linux/if_link.h b/tools/include/uapi/linux/if_link.h index a0aa05a28cf2..f0d71b2a3f1e 100644 --- a/tools/include/uapi/linux/if_link.h +++ b/tools/include/uapi/linux/if_link.h @@ -974,6 +974,7 @@ enum { IFLA_BOND_AD_LACP_ACTIVE, IFLA_BOND_MISSED_MAX, IFLA_BOND_NS_IP6_TARGET, + IFLA_BOND_COUPLED_CONTROL, __IFLA_BOND_MAX, };