Received: by 2002:a05:6a10:22f:0:0:0:0 with SMTP id 15csp1166187pxk; Fri, 4 Sep 2020 02:20:34 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyvTxtGf5XWW/DCyfhNuvT1K1OgDdH/0kUIHz4bbZhvgsIRPQMhDzr9m2M+gO3Zxd2k6hpu X-Received: by 2002:a17:906:faec:: with SMTP id lu44mr6238816ejb.527.1599211234371; Fri, 04 Sep 2020 02:20:34 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1599211234; cv=none; d=google.com; s=arc-20160816; b=JpDr5UKw6VyonHQ/jzt7VSnRddz59V8uJY++KDSZpPMjgSrxOJcCTXfC7yfL56LHhY AgIiZcHND9v6miUAMXJpzJzjGX1rPbaASWS07FzCYK7EMEeqdS/70MUVYo0TPz336s+C vxgATrJutVWduZXwlPmDm8QN3L+d7R//VmlTliG7P17EOoo8roncUknYnwdZ8ZHgpqI4 dpQ/E4INraccXGJ018kYbKG3yUpFuRWrXaGVn512ktMvUOM3QuiAE419knC4XaoOt7e3 9/7rtunFc36FYGUx0wqg3Z+eLt4NSXI7VNOggZLDK5TlEO9FuZplTMckKy0iuz05PJcU imNQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :ironport-sdr:dkim-signature; bh=anH1Q2GgidKvpzgeUl6RghNgDqSlMkdQtkFzQCv06XQ=; b=pnTUE9mDWxCXABbbD36w5uAUVLPQ3sP1bjO7vJ2kQzG4bBQPN1GZ6DOTXQYpZeuxgc 9L300esFjiLCrVYlbA8FIejeMMMD0cioLiZmT8jEyq6HAYlrEv50flYR1jMbn7diVEgg cYaI2IzJ1Bu3FSboOQDtdkgKE9k5aaIAT/tle+T/q03htX1ILSBYUevNXWVqymIr4MXP bQ/nbg24etjeXB6KbIdlO4HQaZOtpKSB12vrsBiX+OFpuIfHK++rY6dsQRDPi22VhNHU NFuQJayKSrIBJyMKJ/f9pZsIUs8Z90flhDq8+WftTJSAbYbnc1pbyKj/LTgf9vbGzDqZ RMUg== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@microchip.com header.s=mchp header.b=FnZL4yvb; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=microchip.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id y25si587550ejb.231.2020.09.04.02.20.11; Fri, 04 Sep 2020 02:20:34 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=fail header.i=@microchip.com header.s=mchp header.b=FnZL4yvb; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=microchip.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730018AbgIDJTE (ORCPT + 99 others); Fri, 4 Sep 2020 05:19:04 -0400 Received: from esa5.microchip.iphmx.com ([216.71.150.166]:43022 "EHLO esa5.microchip.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729993AbgIDJTC (ORCPT ); Fri, 4 Sep 2020 05:19:02 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1599211143; x=1630747143; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=SGwHJADcKZzhFgoYDj7ACD9S4HVVPmXGdfyKY5/RzEk=; b=FnZL4yvbsKmC22JHKc2n9XQfGWoVj5Z49Zm7SAnr5afZn9rTr9gUIc9v z592VjCN5QXPCKzdZ1IQ4jtsc7JDzOIS6lDYqcXQmRip3dhR2CiDeXktd sxBQ23C7S2UxAXL9++ieEs7Zn8fb6bCM2/rg61wa2EBBkPiYfwSNQZZHH 9VnUZjhUzuWbpHUNuqVA4aYClEFiPcSYiO6qlhJHMnJAoSZtRDmpGeKSm BDj3ccsDmMSKsI9bLs2DtOmZeLj32N/ucxNwbGZZp+SVFclwOJGnHnmVq VEjIwlqtg3xQxgWlJYKK7HHpaof3YTg3gYCOJgVIS5XefgetVyx+vIjew g==; IronPort-SDR: ivyu7l+otKR8HtfFGH8z1HVhOKLGFIyMqgI8vbsB0mh96d4Ymr/KZKOKwjB9SE+g5qNS4aH0DN FD8Z0r5KaiTdkm1tOh/ozpUDNl6jzURxB5RmWX2xHFXwAicZ87QLnSjuj7OJSsBdzhp45j6xrp UKN9gyFZ2B/euiffBZonfcXzu8P73dB7OtfOKDNOZMM4AQ4rMYG1VfZGSQJ8cKiDhRw7QEjEox W0INSXN2fd92c06CB5DxNL+hG2RcZ6/zjWpxoBgqHnTnXw1LYGLdouJX6vNpuV2egkr+cyz5Vc O3o= X-IronPort-AV: E=Sophos;i="5.76,389,1592895600"; d="scan'208";a="89828995" Received: from smtpout.microchip.com (HELO email.microchip.com) ([198.175.253.82]) by esa5.microchip.iphmx.com with ESMTP/TLS/AES256-SHA256; 04 Sep 2020 02:19:02 -0700 Received: from chn-vm-ex03.mchp-main.com (10.10.85.151) by chn-vm-ex03.mchp-main.com (10.10.85.151) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1979.3; Fri, 4 Sep 2020 02:18:53 -0700 Received: from soft-test08.microsemi.net (10.10.115.15) by chn-vm-ex03.mchp-main.com (10.10.85.151) with Microsoft SMTP Server id 15.1.1979.3 via Frontend Transport; Fri, 4 Sep 2020 02:18:50 -0700 From: Henrik Bjoernlund To: , , , , , , , , , CC: Henrik Bjoernlund , Horatiu Vultur Subject: [PATCH RFC 1/7] net: bridge: extend the process of special frames Date: Fri, 4 Sep 2020 09:15:21 +0000 Message-ID: <20200904091527.669109-2-henrik.bjoernlund@microchip.com> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200904091527.669109-1-henrik.bjoernlund@microchip.com> References: <20200904091527.669109-1-henrik.bjoernlund@microchip.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org This patch extends the processing of frames in the bridge. Currently MRP frames needs special processing and the current implementation doesn't allow a nice way to process different frame types. Therefore try to improve this by adding a list that contains frame types that need special processing. This list is iterated for each input frame and if there is a match based on frame type then these functions will be called and decide what to do with the frame. It can process the frame then the bridge doesn't need to do anything or don't process so then the bridge will do normal forwarding. Signed-off-by: Henrik Bjoernlund --- net/bridge/br_device.c | 1 + net/bridge/br_input.c | 31 ++++++++++++++++++++++++++++++- net/bridge/br_mrp.c | 19 +++++++++++++++---- net/bridge/br_private.h | 18 ++++++++++++------ 4 files changed, 58 insertions(+), 11 deletions(-) diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c index 9a2fb4aa1a10..a9232db03108 100644 --- a/net/bridge/br_device.c +++ b/net/bridge/br_device.c @@ -473,6 +473,7 @@ void br_dev_setup(struct net_device *dev) spin_lock_init(&br->lock); INIT_LIST_HEAD(&br->port_list); INIT_HLIST_HEAD(&br->fdb_list); + INIT_LIST_HEAD(&br->ftype_list); #if IS_ENABLED(CONFIG_BRIDGE_MRP) INIT_LIST_HEAD(&br->mrp_list); #endif diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c index 59a318b9f646..0f475b21094c 100644 --- a/net/bridge/br_input.c +++ b/net/bridge/br_input.c @@ -254,6 +254,21 @@ static int nf_hook_bridge_pre(struct sk_buff *skb, struct sk_buff **pskb) return RX_HANDLER_CONSUMED; } +/* Return 0 if the frame was not processed otherwise 1 + * note: already called with rcu_read_lock + */ +static int br_process_frame_type(struct net_bridge_port *p, + struct sk_buff *skb) +{ + struct br_frame_type *tmp; + + list_for_each_entry_rcu(tmp, &p->br->ftype_list, list) { + if (unlikely(tmp->type == skb->protocol)) + return tmp->func(p, skb); + } + return 0; +} + /* * Return NULL if skb is handled * note: already called with rcu_read_lock @@ -343,7 +358,7 @@ static rx_handler_result_t br_handle_frame(struct sk_buff **pskb) } } - if (unlikely(br_mrp_process(p, skb))) + if (unlikely(br_process_frame_type(p, skb))) return RX_HANDLER_PASS; forward: @@ -380,3 +395,17 @@ rx_handler_func_t *br_get_rx_handler(const struct net_device *dev) return br_handle_frame; } + +void br_add_frame(struct net_bridge *br, struct br_frame_type *ft) +{ + list_add_rcu(&ft->list, &br->ftype_list); +} + +void br_del_frame(struct net_bridge *br, struct br_frame_type *ft) +{ + struct br_frame_type *tmp; + + list_for_each_entry(tmp, &br->ftype_list, list) + if (ft == tmp) + list_del_rcu(&ft->list); +} diff --git a/net/bridge/br_mrp.c b/net/bridge/br_mrp.c index b36689e6e7cb..0428e1785041 100644 --- a/net/bridge/br_mrp.c +++ b/net/bridge/br_mrp.c @@ -6,6 +6,13 @@ static const u8 mrp_test_dmac[ETH_ALEN] = { 0x1, 0x15, 0x4e, 0x0, 0x0, 0x1 }; static const u8 mrp_in_test_dmac[ETH_ALEN] = { 0x1, 0x15, 0x4e, 0x0, 0x0, 0x3 }; +static int br_mrp_process(struct net_bridge_port *p, struct sk_buff *skb); + +static struct br_frame_type mrp_frame_type __read_mostly = { + .type = cpu_to_be16(ETH_P_MRP), + .func = br_mrp_process, +}; + static bool br_mrp_is_ring_port(struct net_bridge_port *p_port, struct net_bridge_port *s_port, struct net_bridge_port *port) @@ -445,6 +452,9 @@ static void br_mrp_del_impl(struct net_bridge *br, struct br_mrp *mrp) list_del_rcu(&mrp->list); kfree_rcu(mrp, rcu); + + if (list_empty(&br->mrp_list)) + br_del_frame(br, &mrp_frame_type); } /* Adds a new MRP instance. @@ -493,6 +503,9 @@ int br_mrp_add(struct net_bridge *br, struct br_mrp_instance *instance) spin_unlock_bh(&br->lock); rcu_assign_pointer(mrp->s_port, p); + if (list_empty(&br->mrp_list)) + br_add_frame(br, &mrp_frame_type); + INIT_DELAYED_WORK(&mrp->test_work, br_mrp_test_work_expired); INIT_DELAYED_WORK(&mrp->in_test_work, br_mrp_in_test_work_expired); list_add_tail_rcu(&mrp->list, &br->mrp_list); @@ -1172,15 +1185,13 @@ static int br_mrp_rcv(struct net_bridge_port *p, * normal forwarding. * note: already called with rcu_read_lock */ -int br_mrp_process(struct net_bridge_port *p, struct sk_buff *skb) +static int br_mrp_process(struct net_bridge_port *p, struct sk_buff *skb) { /* If there is no MRP instance do normal forwarding */ if (likely(!(p->flags & BR_MRP_AWARE))) goto out; - if (unlikely(skb->protocol == htons(ETH_P_MRP))) - return br_mrp_rcv(p, skb, p->dev); - + return br_mrp_rcv(p, skb, p->dev); out: return 0; } diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index baa1500f384f..e67c6d9e8bea 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h @@ -89,6 +89,13 @@ struct bridge_mcast_stats { }; #endif +struct br_frame_type { + __be16 type; + int (*func)(struct net_bridge_port *port, + struct sk_buff *skb); + struct list_head list; +}; + struct br_vlan_stats { u64 rx_bytes; u64 rx_packets; @@ -433,6 +440,8 @@ struct net_bridge { #endif struct hlist_head fdb_list; + struct list_head ftype_list; + #if IS_ENABLED(CONFIG_BRIDGE_MRP) struct list_head mrp_list; #endif @@ -708,6 +717,9 @@ int nbp_backup_change(struct net_bridge_port *p, struct net_device *backup_dev); int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb); rx_handler_func_t *br_get_rx_handler(const struct net_device *dev); +void br_add_frame(struct net_bridge *br, struct br_frame_type *ft); +void br_del_frame(struct net_bridge *br, struct br_frame_type *ft); + static inline bool br_rx_handler_check_rcu(const struct net_device *dev) { return rcu_dereference(dev->rx_handler) == br_get_rx_handler(dev); @@ -1320,7 +1332,6 @@ extern int (*br_fdb_test_addr_hook)(struct net_device *dev, unsigned char *addr) #if IS_ENABLED(CONFIG_BRIDGE_MRP) int br_mrp_parse(struct net_bridge *br, struct net_bridge_port *p, struct nlattr *attr, int cmd, struct netlink_ext_ack *extack); -int br_mrp_process(struct net_bridge_port *p, struct sk_buff *skb); bool br_mrp_enabled(struct net_bridge *br); void br_mrp_port_del(struct net_bridge *br, struct net_bridge_port *p); int br_mrp_fill_info(struct sk_buff *skb, struct net_bridge *br); @@ -1332,11 +1343,6 @@ static inline int br_mrp_parse(struct net_bridge *br, struct net_bridge_port *p, return -EOPNOTSUPP; } -static inline int br_mrp_process(struct net_bridge_port *p, struct sk_buff *skb) -{ - return 0; -} - static inline bool br_mrp_enabled(struct net_bridge *br) { return false; -- 2.28.0