Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3982d3d2 authored by Fischer, Anna's avatar Fischer, Anna Committed by David S. Miller
Browse files

net/bridge: Add 'hairpin' port forwarding mode

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: default avatarPaul Congdon <paul.congdon@hp.com>
Signed-off-by: default avatarAnna Fischer <anna.fischer@hp.com>
Acked-by: default avatarArnd Bergmann <arnd@arndb.de>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 8dd07086
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -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)
+1 −0
Original line number Diff line number Diff line
@@ -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);
+3 −0
Original line number Diff line number Diff line
@@ -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
+17 −0
Original line number Diff line number Diff line
@@ -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
};