From patchwork Fri Jun 14 13:38:16 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tobias Waldekranz X-Patchwork-Id: 13698719 X-Patchwork-Delegate: dsahern@gmail.com Received: from mail-lj1-f172.google.com (mail-lj1-f172.google.com [209.85.208.172]) (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 CB2DB184E for ; Fri, 14 Jun 2024 13:38:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718372338; cv=none; b=Ux277Dt71N4KTtDj1Me+0qynoAhEEdkCxfmo9KzUBlSlfNQIacrkpS29nfnZwXw9qwl8SRseZs9PDcYspBLi6AAj9vA6BgqyewdUAtLZF5vFFbN53Kt8eR9/B97tvTdGS1RpoLVxXxg8LnDFwm/opdT39dFV3+PFlVoyKMtJE3Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718372338; c=relaxed/simple; bh=ZVLaGLZG/PqORfy+FQw8Lf37kV4aEYO/FMejChT+k6U=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=B0zWKyxc7Tj4nuBtg9UZNku7OeS3SeTnB1ivtl185w6E6CsSOIC/w16uS2q8zjSvKhqARPZYxbaiHwWuHkqvixxQZ85DzGnuqzb02JwCxn76254jeVwClp9jEFnrc01j4QT7CHeHwhZLi8eNDZgTBPJhiEl0fBTh8JOSRCCbClg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=waldekranz.com; spf=pass smtp.mailfrom=waldekranz.com; dkim=pass (2048-bit key) header.d=waldekranz-com.20230601.gappssmtp.com header.i=@waldekranz-com.20230601.gappssmtp.com header.b=c7XxNVeT; arc=none smtp.client-ip=209.85.208.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=waldekranz.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=waldekranz.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=waldekranz-com.20230601.gappssmtp.com header.i=@waldekranz-com.20230601.gappssmtp.com header.b="c7XxNVeT" Received: by mail-lj1-f172.google.com with SMTP id 38308e7fff4ca-2ebed33cb65so23530751fa.2 for ; Fri, 14 Jun 2024 06:38:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=waldekranz-com.20230601.gappssmtp.com; s=20230601; t=1718372335; x=1718977135; darn=vger.kernel.org; h=content-transfer-encoding:organization:mime-version:references :in-reply-to:message-id:date:subject:cc:to:from:from:to:cc:subject :date:message-id:reply-to; bh=QPtIu2Oh1GAneYAcqWUOWEePzATLj5rj0bM+l+vj59A=; b=c7XxNVeT3bRbQymj4PBExG+mVrTLMRHAAgPw6mqVNIH84wuGE9v4B1s7SZY8kSKxTX WT1ObmsKmvD8VJTF1iju03efOxjaOvzLtEVMMkCAOayz3QhWuh/H+meEqGm8tlGrSMve g/U4rz0ct1G2Dx0txgKXu807YSNZrCWaA4BdAtUd8duW2v6tMXaXG5D5U8jrDUt+uU2r ZSZrvX1dU9pXwtk6JfEKDH1Z3qCtaTL8qV754XYLF9xcsSElZW54cfJ8JXVat4CD19TN O+uxFiORGvbZoVvzyJSJrLClyqDvi2WwLaSIVfR+plXg4JeRqXDH3fGwciJ7SxpgkF/L 3UQw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1718372335; x=1718977135; h=content-transfer-encoding:organization:mime-version:references :in-reply-to:message-id:date:subject:cc:to:from:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=QPtIu2Oh1GAneYAcqWUOWEePzATLj5rj0bM+l+vj59A=; b=fN8GPNmeWt8lOoTT12MSsfC5ojgYCkzFR+x6aHQsiT6JMXM0+W+Z1dhSsTwGSXjypN 1UxTHJHccyCF/v0mM1CKH/3Uy5CC8PwiCEThXiJ2vTtoXFQZQN1PYfRht9X03/Bhk2Lv kNxGQdLR0N5nyB0C0/J/3fD9yOohcRhVZDWcTTL0tHZ0818ZsTOiWGcObes2bCEN3wqW chIkWpHHfa0Khn35WoAzWY7g1ux5RKzIfAex2JRYr4V2Gw5a1A8rAA0ZUIVzrtZ/Ud9C NzPZ3qQHMUJzYmb4bzekafvuByM8JUFSDMVOmQSF5SBCQiB5GP2+jqVoC1qxV4wr3bSj se/Q== X-Forwarded-Encrypted: i=1; AJvYcCXW09dfff6ZJBzc6HJThWb/bPQh9pIgpMYa5j4KdtyJN0a9EpFTouTQdYfNJV2XHxz9QZmqjnfhUWy3L/Y3mgfwCgQ0U1ly X-Gm-Message-State: AOJu0YwOrsCFeCAjqVN/2NLFXP32GpPLiYsJBjV/1IWGNPWJiTQr79K8 w9thSiVrohZXQHIkRRfkFwvla6By+K0Jjep+nIvmPZuVeE4Kd6PKaOMOHURfiZc= X-Google-Smtp-Source: AGHT+IFQkG3EBTfxtsw5JaE8O+dTTeYyOa5fVY1r3lJWtSCEeY4VA8eNDpIa3p7MyHD1WyWp6UMSeQ== X-Received: by 2002:a2e:9244:0:b0:2eb:e405:dc with SMTP id 38308e7fff4ca-2ec0e46db18mr19619891fa.14.1718372334868; Fri, 14 Jun 2024 06:38:54 -0700 (PDT) Received: from wkz-x13.addiva.ad (h-79-136-22-50.NA.cust.bahnhof.se. [79.136.22.50]) by smtp.gmail.com with ESMTPSA id 38308e7fff4ca-2ec05c179c5sm5327621fa.67.2024.06.14.06.38.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 14 Jun 2024 06:38:54 -0700 (PDT) From: Tobias Waldekranz To: stephen@networkplumber.org, dsahern@kernel.org Cc: liuhangbin@gmail.com, netdev@vger.kernel.org Subject: [PATCH iproute2 1/3] ip: bridge: add support for mst_enabled Date: Fri, 14 Jun 2024 15:38:16 +0200 Message-Id: <20240614133818.14876-2-tobias@waldekranz.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240614133818.14876-1-tobias@waldekranz.com> References: <20240614133818.14876-1-tobias@waldekranz.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Organization: Addiva Elektronik X-Patchwork-Delegate: dsahern@gmail.com When enabled, the bridge's legacy per-VLAN STP facility is replaced with the Multiple Spanning Tree Protocol (MSTP) compatible version. Signed-off-by: Tobias Waldekranz --- ip/iplink_bridge.c | 19 +++++++++++++++++++ man/man8/ip-link.8.in | 14 ++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/ip/iplink_bridge.c b/ip/iplink_bridge.c index 6b70ffbb..8c4428a0 100644 --- a/ip/iplink_bridge.c +++ b/ip/iplink_bridge.c @@ -30,6 +30,7 @@ static void print_explain(FILE *f) " [ max_age MAX_AGE ]\n" " [ ageing_time AGEING_TIME ]\n" " [ stp_state STP_STATE ]\n" + " [ mst_enabled MST_ENABLED ]\n" " [ priority PRIORITY ]\n" " [ group_fwd_mask MASK ]\n" " [ group_address ADDRESS ]\n" @@ -169,6 +170,18 @@ static int bridge_parse_opt(struct link_util *lu, int argc, char **argv, bm.optval |= no_ll_learn_bit; else bm.optval &= ~no_ll_learn_bit; + } else if (matches(*argv, "mst_enabled") == 0) { + __u32 mst_bit = 1 << BR_BOOLOPT_MST_ENABLE; + __u8 mst_enabled; + + NEXT_ARG(); + if (get_u8(&mst_enabled, *argv, 0)) + invarg("invalid mst_enabled", *argv); + bm.optmask |= mst_bit; + if (mst_enabled) + bm.optval |= mst_bit; + else + bm.optval &= ~mst_bit; } else if (strcmp(*argv, "fdb_max_learned") == 0) { __u32 fdb_max_learned; @@ -609,6 +622,7 @@ static void bridge_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[]) if (tb[IFLA_BR_MULTI_BOOLOPT]) { __u32 mcvl_bit = 1 << BR_BOOLOPT_MCAST_VLAN_SNOOPING; __u32 no_ll_learn_bit = 1 << BR_BOOLOPT_NO_LL_LEARN; + __u32 mst_bit = 1 << BR_BOOLOPT_MST_ENABLE; struct br_boolopt_multi *bm; bm = RTA_DATA(tb[IFLA_BR_MULTI_BOOLOPT]); @@ -622,6 +636,11 @@ static void bridge_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[]) "mcast_vlan_snooping", "mcast_vlan_snooping %u ", !!(bm->optval & mcvl_bit)); + if (bm->optmask & mst_bit) + print_uint(PRINT_ANY, + "mst_enabled", + "mst_enabled %u ", + !!(bm->optval & mst_bit)); } if (tb[IFLA_BR_MCAST_ROUTER]) diff --git a/man/man8/ip-link.8.in b/man/man8/ip-link.8.in index c1984158..eabca490 100644 --- a/man/man8/ip-link.8.in +++ b/man/man8/ip-link.8.in @@ -1685,6 +1685,8 @@ the following additional arguments are supported: ] [ .BI stp_state " STP_STATE " ] [ +.BI mst_enabled " MST_ENABLED " +] [ .BI priority " PRIORITY " ] [ .BI no_linklocal_learn " NO_LINKLOCAL_LEARN " @@ -1788,6 +1790,18 @@ or off .RI ( STP_STATE " == 0). " for this bridge. +.BI mst_enabled " MST_ENABLED " +- turn multiple spanning tree (MST) support on +.RI ( MST_ENABLED " > 0) " +or off +.RI ( MST_ENABLED " == 0). " +When enabled, sets of VLANs can be associated with multiple spanning +tree instances (MSTIs), and STP states for each port can be controlled +on a per-MSTI basis. Note: no implementation of the MSTP protocol is +provided, only the primitives needed to implement it. To avoid +interfering with the legacy per-VLAN STP states, this setting can only +be changed when no bridge VLANs are configured. + .BI priority " PRIORITY " - set this bridge's spanning tree priority, used during STP root bridge election. From patchwork Fri Jun 14 13:38:17 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tobias Waldekranz X-Patchwork-Id: 13698720 X-Patchwork-Delegate: dsahern@gmail.com Received: from mail-lj1-f178.google.com (mail-lj1-f178.google.com [209.85.208.178]) (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 B8B141C27 for ; Fri, 14 Jun 2024 13:38:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.178 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718372339; cv=none; b=jwFQI+iftKiSRlPNSqsxOZ5QCZPKJtmZemySk/PT/4W4r4kYNlIu86RUzmZv+P9pxUiGRWqGF+vvggFF8XibWgRZvF32M01hWztEnxChaAQSeeOZi44bvvht44HuJgozes4KMgsW7MQ5V1F/t23jdSdFU+MyPgPiY71ktOVV7AQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718372339; c=relaxed/simple; bh=xnE3v2fU7NxIpzyZJ2ceEC+dccvprNag/D4piqTJLCQ=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=YgESUqdKg1jT8SN6AG9wrsc76p/NZ82Xqd41ssGm5rg2JHF632zQXuBwSSQe0KX/7k64v5gwvWWtocUHZWbhJGWp5AzawJf9pFfjpQXao+8kCwpMOHyNfIaOAnCFnROHAgjm/50d5kFK3Pbgg7WQ2prgQvkf26LvVYYcu12ytK8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=waldekranz.com; spf=pass smtp.mailfrom=waldekranz.com; dkim=pass (2048-bit key) header.d=waldekranz-com.20230601.gappssmtp.com header.i=@waldekranz-com.20230601.gappssmtp.com header.b=CLVVA4AN; arc=none smtp.client-ip=209.85.208.178 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=waldekranz.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=waldekranz.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=waldekranz-com.20230601.gappssmtp.com header.i=@waldekranz-com.20230601.gappssmtp.com header.b="CLVVA4AN" Received: by mail-lj1-f178.google.com with SMTP id 38308e7fff4ca-2ebd421a931so21485371fa.1 for ; Fri, 14 Jun 2024 06:38:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=waldekranz-com.20230601.gappssmtp.com; s=20230601; t=1718372336; x=1718977136; darn=vger.kernel.org; h=content-transfer-encoding:organization:mime-version:references :in-reply-to:message-id:date:subject:cc:to:from:from:to:cc:subject :date:message-id:reply-to; bh=u0S+LRarOvOVQhRVeLVj58mXdHnF8qmLz8b6eobZUBs=; b=CLVVA4ANXzUMP8KWaqiKIlj11a3Tb7xwsd0oLp41mRIVcxgypsmE2Fe3ZYrWyhdVlq LI6fxu9H2yXS5TmhLnvg8AFVI6pqIZteP3mx8WiWpCCK4AKlxzWZXdmbbD1ZOmsva/fs +rInHU6t4AyDghUTbqgvdAp2kRX96JDpvnlDLnAkBZ+wdD/0Qt/MK2Igwp9WtOivH1V+ lnsncJxCBsFeGoK1MtEaqGZ7CbakTRy6ECuqrZuCVR2PCU8I4Dy6bLQKMwWp+RCUUkeG rd/loLFqFSEAr6jLvnr0p2EUAUsYeoVYWpEtA6ZnZBOpkToEmf2OfHcw2vNi/mQyOxou UmBg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1718372336; x=1718977136; h=content-transfer-encoding:organization:mime-version:references :in-reply-to:message-id:date:subject:cc:to:from:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=u0S+LRarOvOVQhRVeLVj58mXdHnF8qmLz8b6eobZUBs=; b=MYRqbkJS7QSr99vTUwRhThXro3/bjYdH04wfQXOnDV1ky3gH5PigxdTY7NU246xJDb IoJbFBbdRxIqhysjvrMqwaWnjUG5AJmc4KqMjlztHjfV+K7Rsh6GAYaFJrXq5RUQc2bd Aat4bFGrfGXyfWMAmAhyjGheCcvwyF5gGQ7LCzIc2MOHBTocUyruSUclVcDmnV+KDlKV oMbx2LNgBGLXkGtwQK4BxDkw4j3ggMAi/BhlJSSV1WKeLvuopM8FyVTuI2sXZ9mr+7uG z8zlCdwkN0WbxZWJ+aLZQZm+Jir8c/J1kLO8hqBTqr8sY6bmwsg0amFoRCII3jP9xmV7 IK2w== X-Forwarded-Encrypted: i=1; AJvYcCWmmLtnlg+EcFRn/EUXcVgYOz5ddczyq8/ndWekMDgI54QZXEHPgCtIZKLDFCcMPM1qg00GKDKIOEjYc5rxBg4/9t942Mpr X-Gm-Message-State: AOJu0YyhNTzpnDINtSFHhJQzZjk/arjFkq6IcUAQVTDzLAQi2DtS5VQR c2xIi98uL2Ua+BueuTbDkisUoSBBbvH/CLxVTenOKeBrH4oynqMcz7Whpsw/YGc= X-Google-Smtp-Source: AGHT+IHKZDtHfMwsnJm+qDyAeGSnQhp6dFxmtliJyzHeZS27UXqCWt+2+mX/w6z9ZKpcvsj67mvD9g== X-Received: by 2002:a2e:9f44:0:b0:2ea:e98e:4399 with SMTP id 38308e7fff4ca-2ec0e5ffc00mr19536901fa.36.1718372336046; Fri, 14 Jun 2024 06:38:56 -0700 (PDT) Received: from wkz-x13.addiva.ad (h-79-136-22-50.NA.cust.bahnhof.se. [79.136.22.50]) by smtp.gmail.com with ESMTPSA id 38308e7fff4ca-2ec05c179c5sm5327621fa.67.2024.06.14.06.38.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 14 Jun 2024 06:38:55 -0700 (PDT) From: Tobias Waldekranz To: stephen@networkplumber.org, dsahern@kernel.org Cc: liuhangbin@gmail.com, netdev@vger.kernel.org Subject: [PATCH iproute2 2/3] bridge: vlan: Add support for setting a VLANs MSTI Date: Fri, 14 Jun 2024 15:38:17 +0200 Message-Id: <20240614133818.14876-3-tobias@waldekranz.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240614133818.14876-1-tobias@waldekranz.com> References: <20240614133818.14876-1-tobias@waldekranz.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Organization: Addiva Elektronik X-Patchwork-Delegate: dsahern@gmail.com Allow the user to associate one or more VLANs with a multiple spanning tree instance (MSTI), when MST is enabled on the bridge. Signed-off-by: Tobias Waldekranz --- bridge/vlan.c | 13 +++++++++++++ man/man8/bridge.8 | 9 ++++++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/bridge/vlan.c b/bridge/vlan.c index 0a7e6c45..34d7f767 100644 --- a/bridge/vlan.c +++ b/bridge/vlan.c @@ -56,6 +56,7 @@ static void usage(void) " [ mcast_querier_interval QUERIER_INTERVAL ]\n" " [ mcast_query_interval QUERY_INTERVAL ]\n" " [ mcast_query_response_interval QUERY_RESPONSE_INTERVAL ]\n" + " [ msti MSTI ]\n" " bridge vlan global { show } [ dev DEV ] [ vid VLAN_ID ]\n"); exit(-1); } @@ -406,6 +407,7 @@ static int vlan_global_option_set(int argc, char **argv) short vid = -1; __u64 val64; __u32 val32; + __u16 val16; __u8 val8; afspec = addattr_nest(&req.n, sizeof(req), @@ -536,6 +538,12 @@ static int vlan_global_option_set(int argc, char **argv) addattr64(&req.n, 1024, BRIDGE_VLANDB_GOPTS_MCAST_STARTUP_QUERY_INTVL, val64); + } else if (strcmp(*argv, "msti") == 0) { + NEXT_ARG(); + if (get_u16(&val16, *argv, 0)) + invarg("invalid msti", *argv); + addattr16(&req.n, 1024, + BRIDGE_VLANDB_GOPTS_MSTI, val16); } else { if (strcmp(*argv, "help") == 0) NEXT_ARG(); @@ -945,6 +953,11 @@ static void print_vlan_global_opts(struct rtattr *a, int ifindex) "mcast_query_response_interval %llu ", rta_getattr_u64(vattr)); } + if (vtb[BRIDGE_VLANDB_GOPTS_MSTI]) { + vattr = vtb[BRIDGE_VLANDB_GOPTS_MSTI]; + print_uint(PRINT_ANY, "msti", "msti %u ", + rta_getattr_u16(vattr)); + } print_nl(); if (vtb[BRIDGE_VLANDB_GOPTS_MCAST_ROUTER_PORTS]) { vattr = RTA_DATA(vtb[BRIDGE_VLANDB_GOPTS_MCAST_ROUTER_PORTS]); diff --git a/man/man8/bridge.8 b/man/man8/bridge.8 index bb02bd27..b4699801 100644 --- a/man/man8/bridge.8 +++ b/man/man8/bridge.8 @@ -266,7 +266,9 @@ bridge \- show / manipulate bridge addresses and devices .B mcast_query_interval .IR QUERY_INTERVAL " ] [ " .B mcast_query_response_interval -.IR QUERY_RESPONSE_INTERVAL " ]" +.IR QUERY_RESPONSE_INTERVAL " ] [ " +.B msti +.IR MSTI " ]" .ti -8 .BR "bridge vlan global" " [ " show " ] [ " @@ -1493,6 +1495,11 @@ startup phase. set the Max Response Time/Maximum Response Delay for IGMP/MLD queries sent by the bridge. +.TP +.BI msti " MSTI " +associate the VLAN with the specified multiple spanning tree instance +(MSTI). + .SS bridge vlan global show - list global vlan options. This command displays the global VLAN options for each VLAN entry. From patchwork Fri Jun 14 13:38:18 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tobias Waldekranz X-Patchwork-Id: 13698721 X-Patchwork-Delegate: dsahern@gmail.com Received: from mail-lj1-f175.google.com (mail-lj1-f175.google.com [209.85.208.175]) (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 DADE519D8B2 for ; Fri, 14 Jun 2024 13:38:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.175 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718372341; cv=none; b=V7ZFqp6kBmSA8nAssAkVD3gxSCQBpuGccVRsMEfAwlTe9IKiQRDDIUYlNIV9Wv5aii1qReoBisD0vCjSIka/5G8rG5f/lC3EI3lsg+u4qKV8ksWqRw7Ups4XXNCbESEQhxE7eTzszSR9Cfntx0RZYPrQVYXc3VGB2dQKa29QR34= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718372341; c=relaxed/simple; bh=NfOvLuh5WOf8Hdo6LN2wpjDQm8QakCsGfnpHQRRdAt8=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=BO2Qdc2ai8cvDP8NvkRNdtkJTgHNkpUEW2Reqc62tX7inkkfXBxEuuVbYcKAClXNYrgS3Pi1YFvbGCQ9L413SK7Ss/d02S/0rUpv57P6Xx4Zw8pH6TN/ZbkuNiFmbJ9/iLx/BVaTNBiLfGkP+dVrYwjUIzBPiHr7Tn7UWaX0rlk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=waldekranz.com; spf=pass smtp.mailfrom=waldekranz.com; dkim=pass (2048-bit key) header.d=waldekranz-com.20230601.gappssmtp.com header.i=@waldekranz-com.20230601.gappssmtp.com header.b=e9JA1miF; arc=none smtp.client-ip=209.85.208.175 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=waldekranz.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=waldekranz.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=waldekranz-com.20230601.gappssmtp.com header.i=@waldekranz-com.20230601.gappssmtp.com header.b="e9JA1miF" Received: by mail-lj1-f175.google.com with SMTP id 38308e7fff4ca-2e724bc466fso25094321fa.3 for ; Fri, 14 Jun 2024 06:38:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=waldekranz-com.20230601.gappssmtp.com; s=20230601; t=1718372337; x=1718977137; darn=vger.kernel.org; h=content-transfer-encoding:organization:mime-version:references :in-reply-to:message-id:date:subject:cc:to:from:from:to:cc:subject :date:message-id:reply-to; bh=oMzaptHEUYgcsJloL3vT7lSkVXfNwAQtqAjb6Kh7Tk4=; b=e9JA1miFLAHBnTdLraHj4m7DlAY8Kk+amC/jBVt5g6NBGfIh1lSPoqnsEMJZa3ZnYu /JBOo4Cewx4ecswywSYD5VZIY0tRQRFVcWhxPAQGCX6PGW3+cdUbB+tOIhyfD+6uW/9o MQbQ4f3B2ba4j9ZT/xZw2sFYknvw7lleBX4c3ZJT1b8fciDvTJRPDLM3XiDnAZc46vVD vLE4ROvCNumKrauqbyv428d5d1E7AX7WQWFFb3CcI2AN3BwS2ld9AaUxgWvVKd4GaMhZ 3vB+JqsfpJtNtMBbRFMYAf0NVNiySwt+dtI3Agn6cAFI3y0rA8M0RsmbxZpz4bwq8WRM Hijg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1718372337; x=1718977137; h=content-transfer-encoding:organization:mime-version:references :in-reply-to:message-id:date:subject:cc:to:from:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=oMzaptHEUYgcsJloL3vT7lSkVXfNwAQtqAjb6Kh7Tk4=; b=ZDF1vwH+DgW2YyAaqLx+21TThuMUVFy6W7V4+r9HRfUAx/aJk8Zqlf5fHxt8936FTl HSEUCaxuR8ezLQrLw7CtM+JcsTr35oCAg61RC+TkdmtMQy1nII7r2vLgyxXJbCFzY83d /pMr/nUVb8gwoljUoeDm92a9NJAd8XaF01ryK4oaLb9RKMVYfyIQuB2vjDD/Xy6l8LVe si0tXLSUWzUOFwBq6OhafC2InAM1R5+ygKxahPmyljuSfFsiSdJdXm5csdyM9Z73C4Kx +ePOBR1PAre/khamtNu8kQdXnzMwx0zz3a6C0Ra8/Dckgm45eg8Q2TCs6IFqRR2yhP/n GyRQ== X-Forwarded-Encrypted: i=1; AJvYcCWJngMtZwiijnDgoM9Pm2Zsyr0CsCpmDyKGl53X/oQ88illgsAXeLixLTMuvGlZdXSkV273+4EiKnEAVnNwtuhaJLPcL5+3 X-Gm-Message-State: AOJu0Yy+nD3MkRT6mdEsN2K5LJ5F9MIzwsWLZZahwk1CMtoCtvchStkC T+NyKLQi/4O7IwnDnWOzk7c5XFJe64RryrO3EW8RDQGqwyJm2ECW98fJyPq+qlc= X-Google-Smtp-Source: AGHT+IFx+H03lVy1v16GYaHazcy1AGMYm6RRJF0N6mSGjtrDZfudh3idOZS5RFkYhWpLqDwUgoBfzA== X-Received: by 2002:a2e:b055:0:b0:2ec:1ca4:3952 with SMTP id 38308e7fff4ca-2ec1ca4397fmr3955291fa.44.1718372337086; Fri, 14 Jun 2024 06:38:57 -0700 (PDT) Received: from wkz-x13.addiva.ad (h-79-136-22-50.NA.cust.bahnhof.se. [79.136.22.50]) by smtp.gmail.com with ESMTPSA id 38308e7fff4ca-2ec05c179c5sm5327621fa.67.2024.06.14.06.38.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 14 Jun 2024 06:38:56 -0700 (PDT) From: Tobias Waldekranz To: stephen@networkplumber.org, dsahern@kernel.org Cc: liuhangbin@gmail.com, netdev@vger.kernel.org Subject: [PATCH iproute2 3/3] bridge: mst: Add get/set support for MST states Date: Fri, 14 Jun 2024 15:38:18 +0200 Message-Id: <20240614133818.14876-4-tobias@waldekranz.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240614133818.14876-1-tobias@waldekranz.com> References: <20240614133818.14876-1-tobias@waldekranz.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Organization: Addiva Elektronik X-Patchwork-Delegate: dsahern@gmail.com Allow a port's spanning tree state to be modified on a per-MSTI basis, and support dumping the current MST states for every port and MSTI. Signed-off-by: Tobias Waldekranz --- bridge/Makefile | 2 +- bridge/br_common.h | 1 + bridge/bridge.c | 3 +- bridge/mst.c | 262 +++++++++++++++++++++++++++++++++++++++++++++ man/man8/bridge.8 | 57 ++++++++++ 5 files changed, 323 insertions(+), 2 deletions(-) create mode 100644 bridge/mst.c diff --git a/bridge/Makefile b/bridge/Makefile index 01f8a455..4c57df43 100644 --- a/bridge/Makefile +++ b/bridge/Makefile @@ -1,5 +1,5 @@ # SPDX-License-Identifier: GPL-2.0 -BROBJ = bridge.o fdb.o monitor.o link.o mdb.o vlan.o vni.o +BROBJ = bridge.o fdb.o monitor.o link.o mdb.o mst.o vlan.o vni.o include ../config.mk diff --git a/bridge/br_common.h b/bridge/br_common.h index 704e76b0..3a0cf882 100644 --- a/bridge/br_common.h +++ b/bridge/br_common.h @@ -20,6 +20,7 @@ void print_headers(FILE *fp, const char *label); int do_fdb(int argc, char **argv); int do_mdb(int argc, char **argv); int do_monitor(int argc, char **argv); +int do_mst(int argc, char **argv); int do_vlan(int argc, char **argv); int do_link(int argc, char **argv); int do_vni(int argc, char **argv); diff --git a/bridge/bridge.c b/bridge/bridge.c index ef592815..f8b5646a 100644 --- a/bridge/bridge.c +++ b/bridge/bridge.c @@ -36,7 +36,7 @@ static void usage(void) fprintf(stderr, "Usage: bridge [ OPTIONS ] OBJECT { COMMAND | help }\n" " bridge [ -force ] -batch filename\n" -"where OBJECT := { link | fdb | mdb | vlan | vni | monitor }\n" +"where OBJECT := { link | fdb | mdb | mst | vlan | vni | monitor }\n" " OPTIONS := { -V[ersion] | -s[tatistics] | -d[etails] |\n" " -o[neline] | -t[imestamp] | -n[etns] name |\n" " -com[pressvlans] -c[olor] -p[retty] -j[son] }\n"); @@ -56,6 +56,7 @@ static const struct cmd { { "link", do_link }, { "fdb", do_fdb }, { "mdb", do_mdb }, + { "mst", do_mst }, { "vlan", do_vlan }, { "vni", do_vni }, { "monitor", do_monitor }, diff --git a/bridge/mst.c b/bridge/mst.c new file mode 100644 index 00000000..873ca536 --- /dev/null +++ b/bridge/mst.c @@ -0,0 +1,262 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Get/set Multiple Spanning Tree (MST) states + */ + +#include +#include +#include + +#include "libnetlink.h" +#include "json_print.h" +#include "utils.h" + +#include "br_common.h" + +#define MST_ID_LEN 9 + +#define __stringify_1(x...) #x +#define __stringify(x...) __stringify_1(x) + +static unsigned int filter_index; + +static void usage(void) +{ + fprintf(stderr, + "Usage: bridge mst set dev DEV msti MSTI state STATE\n" + " bridge mst {show} [ dev DEV ]\n"); + exit(-1); +} + +static void print_mst_entry(struct rtattr *a, FILE *fp) +{ + struct rtattr *tb[IFLA_BRIDGE_MST_ENTRY_MAX + 1]; + __u16 msti = 0; + __u8 state = 0; + + parse_rtattr_flags(tb, IFLA_BRIDGE_MST_ENTRY_MAX, RTA_DATA(a), + RTA_PAYLOAD(a), NLA_F_NESTED); + + + if (!(tb[IFLA_BRIDGE_MST_ENTRY_MSTI] && + tb[IFLA_BRIDGE_MST_ENTRY_STATE])) { + fprintf(stderr, "BUG: broken MST entry"); + return; + } + + msti = rta_getattr_u16(tb[IFLA_BRIDGE_MST_ENTRY_MSTI]); + state = rta_getattr_u8(tb[IFLA_BRIDGE_MST_ENTRY_STATE]); + + open_json_object(NULL); + print_uint(PRINT_ANY, "msti", "%u", msti); + print_nl(); + print_string(PRINT_FP, NULL, "%-" __stringify(IFNAMSIZ) "s ", ""); + print_stp_state(state); + print_nl(); + close_json_object(); +} + +static int print_msts(struct nlmsghdr *n, void *arg) +{ + struct ifinfomsg *ifi = NLMSG_DATA(n); + struct rtattr *af_spec, *mst, *a; + int rem = n->nlmsg_len; + bool opened = false; + + rem -= NLMSG_LENGTH(sizeof(*ifi)); + if (rem < 0) { + fprintf(stderr, "BUG: wrong nlmsg len %d\n", rem); + return -1; + } + + af_spec = parse_rtattr_one(IFLA_AF_SPEC, IFLA_RTA(ifi), rem); + if (!af_spec) + return -1; + + if (filter_index && filter_index != ifi->ifi_index) + return 0; + + mst = parse_rtattr_one_nested(NLA_F_NESTED | IFLA_BRIDGE_MST, af_spec); + if (!mst) + return 0; + + rem = RTA_PAYLOAD(mst); + for (a = RTA_DATA(mst); RTA_OK(a, rem); a = RTA_NEXT(a, rem)) { + unsigned short rta_type = a->rta_type & NLA_TYPE_MASK; + + if (rta_type > IFLA_BRIDGE_MST_MAX) + continue; + + switch (rta_type) { + case IFLA_BRIDGE_MST_ENTRY: + if (!opened) { + open_json_object(NULL); + print_color_string(PRINT_ANY, COLOR_IFNAME, + "ifname", + "%-" __stringify(IFNAMSIZ) "s ", + ll_index_to_name(ifi->ifi_index)); + open_json_array(PRINT_JSON, "mst"); + opened = true; + } else { + print_string(PRINT_FP, NULL, "%-" + __stringify(IFNAMSIZ) "s ", ""); + } + + print_mst_entry(a, arg); + break; + } + } + + if (opened) { + close_json_array(PRINT_JSON, NULL); + close_json_object(); + } + + return 0; +} + +static int mst_show(int argc, char **argv) +{ + char *filter_dev = NULL; + + while (argc > 0) { + if (strcmp(*argv, "dev") == 0) { + NEXT_ARG(); + if (filter_dev) + duparg("dev", *argv); + filter_dev = *argv; + } + argc--; argv++; + } + + if (filter_dev) { + filter_index = ll_name_to_index(filter_dev); + if (!filter_index) + return nodev(filter_dev); + } + + if (rtnl_linkdump_req_filter(&rth, PF_BRIDGE, RTEXT_FILTER_MST) < 0) { + perror("Cannon send dump request"); + exit(1); + } + + new_json_obj(json); + + if (!is_json_context()) { + printf("%-" __stringify(IFNAMSIZ) "s " + "%-" __stringify(MST_ID_LEN) "s", + "port", "msti"); + printf("\n"); + } + + if (rtnl_dump_filter(&rth, print_msts, stdout) < 0) { + fprintf(stderr, "Dump terminated\n"); + return -1; + } + + delete_json_obj(); + fflush(stdout); + return 0; +} + +static int mst_set(int argc, char **argv) +{ + struct { + struct nlmsghdr n; + struct ifinfomsg ifi; + char buf[512]; + } req = { + .n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)), + .n.nlmsg_flags = NLM_F_REQUEST, + .n.nlmsg_type = RTM_SETLINK, + .ifi.ifi_family = PF_BRIDGE, + }; + char *d = NULL, *m = NULL, *s = NULL, *endptr; + struct rtattr *af_spec, *mst, *entry; + __u16 msti; + __u8 state; + + while (argc > 0) { + if (strcmp(*argv, "dev") == 0) { + NEXT_ARG(); + d = *argv; + } else if (strcmp(*argv, "msti") == 0) { + NEXT_ARG(); + m = *argv; + } else if (strcmp(*argv, "state") == 0) { + NEXT_ARG(); + s = *argv; + } else { + if (matches(*argv, "help") == 0) + usage(); + } + argc--; argv++; + } + + if (d == NULL || m == NULL || s == NULL) { + fprintf(stderr, "Device, MSTI and state are required arguments.\n"); + return -1; + } + + req.ifi.ifi_index = ll_name_to_index(d); + if (!req.ifi.ifi_index) + return nodev(d); + + msti = strtol(m, &endptr, 10); + if (!(*s != '\0' && *endptr == '\0')) { + fprintf(stderr, + "Error: invalid MSTI\n"); + return -1; + } + + state = strtol(s, &endptr, 10); + if (!(*s != '\0' && *endptr == '\0')) { + state = parse_stp_state(s); + if (state == -1) { + fprintf(stderr, + "Error: invalid STP port state\n"); + return -1; + } + } + + af_spec = addattr_nest(&req.n, sizeof(req), IFLA_AF_SPEC); + mst = addattr_nest(&req.n, sizeof(req), IFLA_BRIDGE_MST); + + entry = addattr_nest(&req.n, sizeof(req), IFLA_BRIDGE_MST_ENTRY); + entry->rta_type |= NLA_F_NESTED; + + addattr16(&req.n, sizeof(req), IFLA_BRIDGE_MST_ENTRY_MSTI, msti); + addattr8(&req.n, sizeof(req), IFLA_BRIDGE_MST_ENTRY_STATE, state); + + addattr_nest_end(&req.n, entry); + + addattr_nest_end(&req.n, mst); + addattr_nest_end(&req.n, af_spec); + + + if (rtnl_talk(&rth, &req.n, NULL) < 0) + return -1; + + return 0; +} + +int do_mst(int argc, char **argv) +{ + ll_init_map(&rth); + + if (argc > 0) { + if (matches(*argv, "set") == 0) + return mst_set(argc-1, argv+1); + + if (matches(*argv, "show") == 0 || + matches(*argv, "lst") == 0 || + matches(*argv, "list") == 0) + return mst_show(argc-1, argv+1); + if (matches(*argv, "help") == 0) + usage(); + } else + return mst_show(0, NULL); + + fprintf(stderr, "Command \"%s\" is unknown, try \"bridge mst help\".\n", *argv); + exit(-1); +} diff --git a/man/man8/bridge.8 b/man/man8/bridge.8 index b4699801..08f329c6 100644 --- a/man/man8/bridge.8 +++ b/man/man8/bridge.8 @@ -207,6 +207,15 @@ bridge \- show / manipulate bridge addresses and devices .RB "[ " vni .IR VNI " ]" +.ti -8 +.B "bridge mst set" +.IR dev " DEV " msti " MSTI " state " STP_STATE " + +.ti -8 +.BR "bridge mst" " [ [ " show " ] [ " +.B dev +.IR DEV " ] ]" + .ti -8 .BR "bridge vlan" " { " add " | " del " } " .B dev @@ -1247,6 +1256,54 @@ endpoint. Match entries only with the specified destination port number. the VXLAN VNI Network Identifier to use to connect to the remote VXLAN tunnel endpoint. Match entries only with the specified destination VNI. +.SH bridge mst - multiple spanning tree port states + +In the multiple spanning tree (MST) model, the active paths through a +network can be different for different VLANs. In other words, a +bridge port can simultaneously forward one subset of VLANs, while +blocking another. + +Provided that the +.B mst_enable +bridge option is enabled, a group of VLANs can be forwarded along the +same spanning tree by associating them with the same instance (MSTI) +using +.BR "bridge vlan global set" . + +.SS bridge mst set - set multiple spanning tree state + +Set the spanning tree state for +.IR DEV , +in the multiple spanning tree instance +.IR MSTI , +to +.IR STP_STATE . + +.TP +.BI dev " DEV" +Interface name of the bridge port. + +.TP +.BI msti " MSTI" +The multiple spanning tree instance. + +.TP +.BI state " STP_STATE" +The spanning tree state, see the +.B state +option of +.B "bridge link set" +for supported states. + +.SS bridge mst show - list MST states + +List current MST port states in every MSTI. + +.TP +.BI dev " DEV" +If specified, only display states of the bridge port with this +interface name. + .SH bridge vlan - VLAN filter list .B vlan