Skip to content

Commit

Permalink
net/bridge: Add 'hairpin' port forwarding mode
Browse files Browse the repository at this point in the history
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 <[email protected]>
Signed-off-by: Anna Fischer <[email protected]>
Acked-by: Arnd Bergmann <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
Fischer, Anna authored and davem330 committed Aug 13, 2009
1 parent 8dd0708 commit 3982d3d
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 1 deletion.
3 changes: 2 additions & 1 deletion net/bridge/br_forward.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
1 change: 1 addition & 0 deletions net/bridge/br_if.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
3 changes: 3 additions & 0 deletions net/bridge/br_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
17 changes: 17 additions & 0 deletions net/bridge/br_sysfs_if.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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
};

Expand Down

0 comments on commit 3982d3d

Please sign in to comment.