From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6162BC433EF for ; Wed, 9 Feb 2022 13:06:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233875AbiBINGP (ORCPT ); Wed, 9 Feb 2022 08:06:15 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43464 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233833AbiBINGE (ORCPT ); Wed, 9 Feb 2022 08:06:04 -0500 Received: from mail-lf1-x12f.google.com (mail-lf1-x12f.google.com [IPv6:2a00:1450:4864:20::12f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8C46AC0613CA; Wed, 9 Feb 2022 05:06:07 -0800 (PST) Received: by mail-lf1-x12f.google.com with SMTP id x23so4159655lfc.0; Wed, 09 Feb 2022 05:06:07 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:organization:content-transfer-encoding; bh=bYcBMD0263VidrD3hBmBNToThm3cO5xgVyUXSYwtNSk=; b=T4omMjjTBYUygDUJqs2qeyJWoxrIZ8VgP6zJChmrH8GlXMT7A7uHI8RCaZb48a1vc8 CriPE3c4iztC8LQlxpnwcAb1X8bRgeleRuZoFZ8V8FAWWbdsuSQPpwHBsflM0clmk1Va 1dLozc8Up7stMYssey58mBkRz12AKi6XUxAObqucuoU3iBZeWk3qaTN1qZ9eKcQJMLwc 687APJkB7FQg50eB+8SgHsH2RPEp4eOVo2Oa6y84pmpcwLTpNWgpS20BoMdFuUVMs7X6 sGrTeCqobAjv5zjZeyPdCfpB7piQUWo7IdLuGLCN5/7W/Yd23WRp6n/YESNFpYEqeOgQ t7sQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:organization:content-transfer-encoding; bh=bYcBMD0263VidrD3hBmBNToThm3cO5xgVyUXSYwtNSk=; b=KdfjSk3ASyoBks8FyGbKmzbLNFnxzYfkSAc9AD3gZrgYrVliNKibwlWq/U2YCKtAWy 7PVY85SNZWZBa8ZN+lewyOZPug0RgW4fEXqhKQcVodN2BUw1c+jAsXC5Cqvn6RTLuwVD 0L8JYkyyo6cSzXmSlVicxzX1fj16l389UXGfSo6dVBcpN8IxW3dTWC1uFBMw0i5O/Rmx Qm729tZzq3cqTjAKVhmbc37SKK+UM79FN9FRQ7f4/8q9SPP8b/waUo4psYDoS6JFpOO6 HsviGf81nz8xxXv+suFigJ/6hq49mo2HW+tPMzZK0yit6YiMC/0StGYGsGE90DMLkcrI mFCA== X-Gm-Message-State: AOAM533bp1GoQNAsmwRDpbPJnEo/l1856foS+D3aQQs4V9B43ATVqKTi QVqFfw1gUu4Q5Uk4nvq9Hhc= X-Google-Smtp-Source: ABdhPJyCll4ka0Jps7Twlmmr0XKRGoCjIkwwxOKu0pLjUtPupIPa00vNd0wEmuK/o27xnNhSTaZaHg== X-Received: by 2002:a05:6512:3b93:: with SMTP id g19mr1564844lfv.316.1644411965835; Wed, 09 Feb 2022 05:06:05 -0800 (PST) Received: from wse-c0127.beijerelectronics.com ([208.127.141.29]) by smtp.gmail.com with ESMTPSA id k3sm2352608lfo.127.2022.02.09.05.06.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 09 Feb 2022 05:06:05 -0800 (PST) From: Hans Schultz X-Google-Original-From: Hans Schultz To: davem@davemloft.net, kuba@kernel.org Cc: netdev@vger.kernel.org, Hans Schultz , Roopa Prabhu , Nikolay Aleksandrov , linux-kernel@vger.kernel.org, bridge@lists.linux-foundation.org Subject: [PATCH net-next v2 1/5] net: bridge: Add support for bridge port in locked mode Date: Wed, 9 Feb 2022 14:05:33 +0100 Message-Id: <20220209130538.533699-2-schultz.hans+netdev@gmail.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220209130538.533699-1-schultz.hans+netdev@gmail.com> References: <20220209130538.533699-1-schultz.hans+netdev@gmail.com> MIME-Version: 1.0 Organization: Westermo Network Technologies AB Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org In a 802.1X scenario, clients connected to a bridge port shall not be allowed to have traffic forwarded until fully authenticated. A static fdb entry of the clients MAC address for the bridge port unlocks the client and allows bidirectional communication. This scenario is facilitated with setting the bridge port in locked mode, which is also supported by various switchcore chipsets. Signed-off-by: Hans Schultz --- include/linux/if_bridge.h | 1 + include/uapi/linux/if_link.h | 1 + net/bridge/br_input.c | 10 +++++++++- net/bridge/br_netlink.c | 6 +++++- 4 files changed, 16 insertions(+), 2 deletions(-) diff --git a/include/linux/if_bridge.h b/include/linux/if_bridge.h index 509e18c7e740..3aae023a9353 100644 --- a/include/linux/if_bridge.h +++ b/include/linux/if_bridge.h @@ -58,6 +58,7 @@ struct br_ip_list { #define BR_MRP_LOST_CONT BIT(18) #define BR_MRP_LOST_IN_CONT BIT(19) #define BR_TX_FWD_OFFLOAD BIT(20) +#define BR_PORT_LOCKED BIT(21) #define BR_DEFAULT_AGEING_TIME (300 * HZ) diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h index 6218f93f5c1a..a45cc0a1f415 100644 --- a/include/uapi/linux/if_link.h +++ b/include/uapi/linux/if_link.h @@ -537,6 +537,7 @@ enum { IFLA_BRPORT_MRP_IN_OPEN, IFLA_BRPORT_MCAST_EHT_HOSTS_LIMIT, IFLA_BRPORT_MCAST_EHT_HOSTS_CNT, + IFLA_BRPORT_LOCKED, __IFLA_BRPORT_MAX }; #define IFLA_BRPORT_MAX (__IFLA_BRPORT_MAX - 1) diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c index b50382f957c1..469e3adbce07 100644 --- a/net/bridge/br_input.c +++ b/net/bridge/br_input.c @@ -69,6 +69,7 @@ int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb struct net_bridge_port *p = br_port_get_rcu(skb->dev); enum br_pkt_type pkt_type = BR_PKT_UNICAST; struct net_bridge_fdb_entry *dst = NULL; + struct net_bridge_fdb_entry *fdb_entry; struct net_bridge_mcast_port *pmctx; struct net_bridge_mdb_entry *mdst; bool local_rcv, mcast_hit = false; @@ -81,6 +82,8 @@ int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb if (!p || p->state == BR_STATE_DISABLED) goto drop; + br = p->br; + brmctx = &p->br->multicast_ctx; pmctx = &p->multicast_ctx; state = p->state; @@ -88,10 +91,15 @@ int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb &state, &vlan)) goto out; + if (p->flags & BR_PORT_LOCKED) { + fdb_entry = br_fdb_find_rcu(br, eth_hdr(skb)->h_source, vid); + if (!(fdb_entry && fdb_entry->dst == p)) + goto drop; + } + nbp_switchdev_frame_mark(p, skb); /* insert into forwarding database after filtering to avoid spoofing */ - br = p->br; if (p->flags & BR_LEARNING) br_fdb_update(br, p, eth_hdr(skb)->h_source, vid, 0); diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c index 2ff83d84230d..7d4432ca9a20 100644 --- a/net/bridge/br_netlink.c +++ b/net/bridge/br_netlink.c @@ -184,6 +184,7 @@ static inline size_t br_port_info_size(void) + nla_total_size(1) /* IFLA_BRPORT_VLAN_TUNNEL */ + nla_total_size(1) /* IFLA_BRPORT_NEIGH_SUPPRESS */ + nla_total_size(1) /* IFLA_BRPORT_ISOLATED */ + + nla_total_size(1) /* IFLA_BRPORT_LOCKED */ + nla_total_size(sizeof(struct ifla_bridge_id)) /* IFLA_BRPORT_ROOT_ID */ + nla_total_size(sizeof(struct ifla_bridge_id)) /* IFLA_BRPORT_BRIDGE_ID */ + nla_total_size(sizeof(u16)) /* IFLA_BRPORT_DESIGNATED_PORT */ @@ -269,7 +270,8 @@ static int br_port_fill_attrs(struct sk_buff *skb, BR_MRP_LOST_CONT)) || nla_put_u8(skb, IFLA_BRPORT_MRP_IN_OPEN, !!(p->flags & BR_MRP_LOST_IN_CONT)) || - nla_put_u8(skb, IFLA_BRPORT_ISOLATED, !!(p->flags & BR_ISOLATED))) + nla_put_u8(skb, IFLA_BRPORT_ISOLATED, !!(p->flags & BR_ISOLATED)) || + nla_put_u8(skb, IFLA_BRPORT_LOCKED, !!(p->flags & BR_PORT_LOCKED))) return -EMSGSIZE; timerval = br_timer_value(&p->message_age_timer); @@ -827,6 +829,7 @@ static const struct nla_policy br_port_policy[IFLA_BRPORT_MAX + 1] = { [IFLA_BRPORT_GROUP_FWD_MASK] = { .type = NLA_U16 }, [IFLA_BRPORT_NEIGH_SUPPRESS] = { .type = NLA_U8 }, [IFLA_BRPORT_ISOLATED] = { .type = NLA_U8 }, + [IFLA_BRPORT_LOCKED] = { .type = NLA_U8 }, [IFLA_BRPORT_BACKUP_PORT] = { .type = NLA_U32 }, [IFLA_BRPORT_MCAST_EHT_HOSTS_LIMIT] = { .type = NLA_U32 }, }; @@ -893,6 +896,7 @@ static int br_setport(struct net_bridge_port *p, struct nlattr *tb[], br_set_port_flag(p, tb, IFLA_BRPORT_VLAN_TUNNEL, BR_VLAN_TUNNEL); br_set_port_flag(p, tb, IFLA_BRPORT_NEIGH_SUPPRESS, BR_NEIGH_SUPPRESS); br_set_port_flag(p, tb, IFLA_BRPORT_ISOLATED, BR_ISOLATED); + br_set_port_flag(p, tb, IFLA_BRPORT_LOCKED, BR_PORT_LOCKED); changed_mask = old_flags ^ p->flags; -- 2.30.2 From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:organization:content-transfer-encoding; bh=bYcBMD0263VidrD3hBmBNToThm3cO5xgVyUXSYwtNSk=; b=T4omMjjTBYUygDUJqs2qeyJWoxrIZ8VgP6zJChmrH8GlXMT7A7uHI8RCaZb48a1vc8 CriPE3c4iztC8LQlxpnwcAb1X8bRgeleRuZoFZ8V8FAWWbdsuSQPpwHBsflM0clmk1Va 1dLozc8Up7stMYssey58mBkRz12AKi6XUxAObqucuoU3iBZeWk3qaTN1qZ9eKcQJMLwc 687APJkB7FQg50eB+8SgHsH2RPEp4eOVo2Oa6y84pmpcwLTpNWgpS20BoMdFuUVMs7X6 sGrTeCqobAjv5zjZeyPdCfpB7piQUWo7IdLuGLCN5/7W/Yd23WRp6n/YESNFpYEqeOgQ t7sQ== From: Hans Schultz Date: Wed, 9 Feb 2022 14:05:33 +0100 Message-Id: <20220209130538.533699-2-schultz.hans+netdev@gmail.com> In-Reply-To: <20220209130538.533699-1-schultz.hans+netdev@gmail.com> References: <20220209130538.533699-1-schultz.hans+netdev@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Subject: [Bridge] [PATCH net-next v2 1/5] net: bridge: Add support for bridge port in locked mode List-Id: Linux Ethernet Bridging List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: davem@davemloft.net, kuba@kernel.org Cc: netdev@vger.kernel.org, bridge@lists.linux-foundation.org, linux-kernel@vger.kernel.org, Hans Schultz , Nikolay Aleksandrov , Roopa Prabhu In a 802.1X scenario, clients connected to a bridge port shall not be allowed to have traffic forwarded until fully authenticated. A static fdb entry of the clients MAC address for the bridge port unlocks the client and allows bidirectional communication. This scenario is facilitated with setting the bridge port in locked mode, which is also supported by various switchcore chipsets. Signed-off-by: Hans Schultz --- include/linux/if_bridge.h | 1 + include/uapi/linux/if_link.h | 1 + net/bridge/br_input.c | 10 +++++++++- net/bridge/br_netlink.c | 6 +++++- 4 files changed, 16 insertions(+), 2 deletions(-) diff --git a/include/linux/if_bridge.h b/include/linux/if_bridge.h index 509e18c7e740..3aae023a9353 100644 --- a/include/linux/if_bridge.h +++ b/include/linux/if_bridge.h @@ -58,6 +58,7 @@ struct br_ip_list { #define BR_MRP_LOST_CONT BIT(18) #define BR_MRP_LOST_IN_CONT BIT(19) #define BR_TX_FWD_OFFLOAD BIT(20) +#define BR_PORT_LOCKED BIT(21) #define BR_DEFAULT_AGEING_TIME (300 * HZ) diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h index 6218f93f5c1a..a45cc0a1f415 100644 --- a/include/uapi/linux/if_link.h +++ b/include/uapi/linux/if_link.h @@ -537,6 +537,7 @@ enum { IFLA_BRPORT_MRP_IN_OPEN, IFLA_BRPORT_MCAST_EHT_HOSTS_LIMIT, IFLA_BRPORT_MCAST_EHT_HOSTS_CNT, + IFLA_BRPORT_LOCKED, __IFLA_BRPORT_MAX }; #define IFLA_BRPORT_MAX (__IFLA_BRPORT_MAX - 1) diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c index b50382f957c1..469e3adbce07 100644 --- a/net/bridge/br_input.c +++ b/net/bridge/br_input.c @@ -69,6 +69,7 @@ int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb struct net_bridge_port *p = br_port_get_rcu(skb->dev); enum br_pkt_type pkt_type = BR_PKT_UNICAST; struct net_bridge_fdb_entry *dst = NULL; + struct net_bridge_fdb_entry *fdb_entry; struct net_bridge_mcast_port *pmctx; struct net_bridge_mdb_entry *mdst; bool local_rcv, mcast_hit = false; @@ -81,6 +82,8 @@ int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb if (!p || p->state == BR_STATE_DISABLED) goto drop; + br = p->br; + brmctx = &p->br->multicast_ctx; pmctx = &p->multicast_ctx; state = p->state; @@ -88,10 +91,15 @@ int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb &state, &vlan)) goto out; + if (p->flags & BR_PORT_LOCKED) { + fdb_entry = br_fdb_find_rcu(br, eth_hdr(skb)->h_source, vid); + if (!(fdb_entry && fdb_entry->dst == p)) + goto drop; + } + nbp_switchdev_frame_mark(p, skb); /* insert into forwarding database after filtering to avoid spoofing */ - br = p->br; if (p->flags & BR_LEARNING) br_fdb_update(br, p, eth_hdr(skb)->h_source, vid, 0); diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c index 2ff83d84230d..7d4432ca9a20 100644 --- a/net/bridge/br_netlink.c +++ b/net/bridge/br_netlink.c @@ -184,6 +184,7 @@ static inline size_t br_port_info_size(void) + nla_total_size(1) /* IFLA_BRPORT_VLAN_TUNNEL */ + nla_total_size(1) /* IFLA_BRPORT_NEIGH_SUPPRESS */ + nla_total_size(1) /* IFLA_BRPORT_ISOLATED */ + + nla_total_size(1) /* IFLA_BRPORT_LOCKED */ + nla_total_size(sizeof(struct ifla_bridge_id)) /* IFLA_BRPORT_ROOT_ID */ + nla_total_size(sizeof(struct ifla_bridge_id)) /* IFLA_BRPORT_BRIDGE_ID */ + nla_total_size(sizeof(u16)) /* IFLA_BRPORT_DESIGNATED_PORT */ @@ -269,7 +270,8 @@ static int br_port_fill_attrs(struct sk_buff *skb, BR_MRP_LOST_CONT)) || nla_put_u8(skb, IFLA_BRPORT_MRP_IN_OPEN, !!(p->flags & BR_MRP_LOST_IN_CONT)) || - nla_put_u8(skb, IFLA_BRPORT_ISOLATED, !!(p->flags & BR_ISOLATED))) + nla_put_u8(skb, IFLA_BRPORT_ISOLATED, !!(p->flags & BR_ISOLATED)) || + nla_put_u8(skb, IFLA_BRPORT_LOCKED, !!(p->flags & BR_PORT_LOCKED))) return -EMSGSIZE; timerval = br_timer_value(&p->message_age_timer); @@ -827,6 +829,7 @@ static const struct nla_policy br_port_policy[IFLA_BRPORT_MAX + 1] = { [IFLA_BRPORT_GROUP_FWD_MASK] = { .type = NLA_U16 }, [IFLA_BRPORT_NEIGH_SUPPRESS] = { .type = NLA_U8 }, [IFLA_BRPORT_ISOLATED] = { .type = NLA_U8 }, + [IFLA_BRPORT_LOCKED] = { .type = NLA_U8 }, [IFLA_BRPORT_BACKUP_PORT] = { .type = NLA_U32 }, [IFLA_BRPORT_MCAST_EHT_HOSTS_LIMIT] = { .type = NLA_U32 }, }; @@ -893,6 +896,7 @@ static int br_setport(struct net_bridge_port *p, struct nlattr *tb[], br_set_port_flag(p, tb, IFLA_BRPORT_VLAN_TUNNEL, BR_VLAN_TUNNEL); br_set_port_flag(p, tb, IFLA_BRPORT_NEIGH_SUPPRESS, BR_NEIGH_SUPPRESS); br_set_port_flag(p, tb, IFLA_BRPORT_ISOLATED, BR_ISOLATED); + br_set_port_flag(p, tb, IFLA_BRPORT_LOCKED, BR_PORT_LOCKED); changed_mask = old_flags ^ p->flags; -- 2.30.2