From patchwork Thu Aug 13 16:55:16 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Fischer, Anna" X-Patchwork-Id: 31341 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@bilbo.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from ozlabs.org (ozlabs.org [203.10.76.45]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "mx.ozlabs.org", Issuer "CA Cert Signing Authority" (verified OK)) by bilbo.ozlabs.org (Postfix) with ESMTPS id 5856EB6F1E for ; Fri, 14 Aug 2009 02:56:23 +1000 (EST) Received: by ozlabs.org (Postfix) id 45C1CDDD0C; Fri, 14 Aug 2009 02:56:23 +1000 (EST) Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by ozlabs.org (Postfix) with ESMTP id C1354DDD04 for ; Fri, 14 Aug 2009 02:56:22 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754953AbZHMQza (ORCPT ); Thu, 13 Aug 2009 12:55:30 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1753819AbZHMQza (ORCPT ); Thu, 13 Aug 2009 12:55:30 -0400 Received: from g5t0009.atlanta.hp.com ([15.192.0.46]:30669 "EHLO g5t0009.atlanta.hp.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752153AbZHMQz3 convert rfc822-to-8bit (ORCPT ); Thu, 13 Aug 2009 12:55:29 -0400 Received: from G6W0640.americas.hpqcorp.net (g6w0640.atlanta.hp.com [16.230.34.76]) (using TLSv1 with cipher RC4-MD5 (128/128 bits)) (No client certificate requested) by g5t0009.atlanta.hp.com (Postfix) with ESMTPS id D2A8530876; Thu, 13 Aug 2009 16:55:29 +0000 (UTC) Received: from G5W0325.americas.hpqcorp.net (16.228.8.67) by G6W0640.americas.hpqcorp.net (16.230.34.76) with Microsoft SMTP Server (TLS) id 8.1.375.2; Thu, 13 Aug 2009 16:55:22 +0000 Received: from GVW1118EXC.americas.hpqcorp.net ([16.228.24.174]) by G5W0325.americas.hpqcorp.net ([16.228.8.67]) with mapi; Thu, 13 Aug 2009 16:55:21 +0000 From: "Fischer, Anna" To: "linux-kernel@vger.kernel.org" , "netdev@vger.kernel.org" CC: Stephen Hemminger , "Paul Congdon (UC Davis)" , "evb@yahoogroups.com" , "bridge@lists.linux-foundation.org" , "davem@davemloft.net" , "virtualization@lists.linux-foundation.org" , "kaber@trash.net" , Arnd Bergmann , "Dickson, Mike (ISS Software)" , "adobriyan@gmail.com" , "bridge@osdl.org" Date: Thu, 13 Aug 2009 16:55:16 +0000 Subject: [PATCH] net/bridge: Add 'hairpin' port forwarding mode Thread-Topic: [PATCH] net/bridge: Add 'hairpin' port forwarding mode Thread-Index: AcocNtV+HJLiuqM3QOCpEB5SIWIPdw== Message-ID: <0199E0D51A61344794750DC57738F58E6D6B0C70D9@GVW1118EXC.americas.hpqcorp.net> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: acceptlanguage: en-US MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org This patch adds a 'hairpin' (also called 'reflective relay') mode port configuration to the Linux Ethernet bridge kernel module. A bridge supporting hairpin forwarding mode can send frames back out through the port the frame was received on. Hairpin mode is required to support basic VEPA (Virtual Ethernet Port Aggregator) capabilities. You can find additional information on VEPA here: http://tech.groups.yahoo.com/group/evb/ http://www.ieee802.org/1/files/public/docs2009/new-hudson-vepa_seminar-20090514d.pdf http://www.internet2.edu/presentations/jt2009jul/20090719-congdon.pdf An additional patch 'bridge-utils: Add 'hairpin' port forwarding mode' is provided to allow configuring hairpin mode from userspace tools. Signed-off-by: Paul Congdon Signed-off-by: Anna Fischer Acked-by: Arnd Bergmann --- net/bridge/br_forward.c | 3 ++- net/bridge/br_if.c | 1 + net/bridge/br_private.h | 3 +++ net/bridge/br_sysfs_if.c | 17 +++++++++++++++++ 4 files changed, 23 insertions(+), 1 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/net/bridge/br_forward.c b/net/bridge/br_forward.c index d2c27c8..bc1704a 100644 --- a/net/bridge/br_forward.c +++ b/net/bridge/br_forward.c @@ -22,7 +22,8 @@ static inline int should_deliver(const struct net_bridge_port *p, const struct sk_buff *skb) { - return (skb->dev != p->dev && p->state == BR_STATE_FORWARDING); + return (((p->flags & BR_HAIRPIN_MODE) || skb->dev != p->dev) && + p->state == BR_STATE_FORWARDING); } static inline unsigned packet_length(const struct sk_buff *skb) diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index eb404dc..e486f1f 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c @@ -256,6 +256,7 @@ static struct net_bridge_port *new_nbp(struct net_bridge *br, p->path_cost = port_cost(dev); p->priority = 0x8000 >> BR_PORT_BITS; p->port_no = index; + p->flags = 0; br_init_port(p); p->state = BR_STATE_DISABLED; br_stp_port_timer_init(p); diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index d5b5537..8319247 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h @@ -81,6 +81,9 @@ struct net_bridge_port struct timer_list message_age_timer; struct kobject kobj; struct rcu_head rcu; + + unsigned long flags; +#define BR_HAIRPIN_MODE 0x00000001 }; struct net_bridge diff --git a/net/bridge/br_sysfs_if.c b/net/bridge/br_sysfs_if.c index 4a3cdf8..820643a 100644 --- a/net/bridge/br_sysfs_if.c +++ b/net/bridge/br_sysfs_if.c @@ -143,6 +143,22 @@ static ssize_t store_flush(struct net_bridge_port *p, unsigned long v) } static BRPORT_ATTR(flush, S_IWUSR, NULL, store_flush); +static ssize_t show_hairpin_mode(struct net_bridge_port *p, char *buf) +{ + int hairpin_mode = (p->flags & BR_HAIRPIN_MODE) ? 1 : 0; + return sprintf(buf, "%d\n", hairpin_mode); +} +static ssize_t store_hairpin_mode(struct net_bridge_port *p, unsigned long v) +{ + if (v) + p->flags |= BR_HAIRPIN_MODE; + else + p->flags &= ~BR_HAIRPIN_MODE; + return 0; +} +static BRPORT_ATTR(hairpin_mode, S_IRUGO | S_IWUSR, + show_hairpin_mode, store_hairpin_mode); + static struct brport_attribute *brport_attrs[] = { &brport_attr_path_cost, &brport_attr_priority, @@ -159,6 +175,7 @@ static struct brport_attribute *brport_attrs[] = { &brport_attr_forward_delay_timer, &brport_attr_hold_timer, &brport_attr_flush, + &brport_attr_hairpin_mode, NULL };