From: Cyrill Gorcunov <gorcunov@gmail.com>
To: Stephen Hemminger <shemminger@linux-foundation.org>,
davem@davemloft.net, netdev@vger.kernel.org,
bridge@lists.linux-foundation.org, xemul@openvz.org
Subject: Re: [RFC 5/5] net: bridge - handle via_phys_dev feature on a bridge level
Date: Mon, 11 May 2009 17:01:15 +0400 [thread overview]
Message-ID: <20090511130115.GG4624@lenovo> (raw)
In-Reply-To: <20090511125351.432336750@openvz.org>
quilt didn't get refreshed copy. here is an updated
one. sorry for inconvenience.
-- Cyrill
---
From: Cyrill Gorcunov <gorcunov@gmail.com>
Subject: [RFC 5/5] net: bridge - handle via_phys_dev feature on a bridge level
The idea is to use existing routing table instead of
generating new one if the bridge is to be created.
This allow to login on remote machine then create bridge
there and continue working on this machine without
session interrupted (though delay while bridge is learning
still present).
To achive this we introduce via_phys_dev feature which
force to work some real NIC as bridge.
How to use it:
- Create a new bridge set via_phys_dev in sysfs entry for the bridge
- Add a bridge port. This port will behave like it's a bridge
itself, i.e. a packet recieved from network will be handled the same
way if it was received by bridge device. Any write on this
device from OS behaves like it is being written to bridge device
itself too.
Typical session looks like
| ssh@10.10.0.160$ brctl addbr br0
| ssh@10.10.0.160$ ifconfig br0 up
| ssh@10.10.0.160$ echo 1 > /sys/class/net/bridge/br0/via_phys_dev
| ssh@10.10.0.160$ brctl addif br0 eth0
| (...waiting a bit...)
| ssh@10.10.0.160$
Which implies that eth0 is already up and running.
Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
---
net/bridge/br.c | 2 ++
net/bridge/br_device.c | 37 +++++++++++++++++++++++++++++++++++++
net/bridge/br_forward.c | 1 +
net/bridge/br_input.c | 14 +++++++++++++-
net/bridge/br_private.h | 1 +
5 files changed, 54 insertions(+), 1 deletion(-)
Index: linux-2.6.git/net/bridge/br.c
=====================================================================
--- linux-2.6.git.orig/net/bridge/br.c
+++ linux-2.6.git/net/bridge/br.c
@@ -64,6 +64,7 @@ static int __init br_init(void)
brioctl_set(br_ioctl_deviceless_stub);
br_handle_frame_hook = br_handle_frame;
+ br_hard_xmit_hook = br_hard_xmit;
br_fdb_get_hook = br_fdb_get;
br_fdb_put_hook = br_fdb_put;
@@ -99,6 +100,7 @@ static void __exit br_deinit(void)
br_fdb_put_hook = NULL;
br_handle_frame_hook = NULL;
+ br_hard_xmit_hook = NULL;
br_fdb_fini();
}
Index: linux-2.6.git/net/bridge/br_device.c
=====================================================================
--- linux-2.6.git.orig/net/bridge/br_device.c
+++ linux-2.6.git/net/bridge/br_device.c
@@ -32,6 +32,8 @@ int br_dev_xmit(struct sk_buff *skb, str
skb_reset_mac_header(skb);
skb_pull(skb, ETH_HLEN);
+ skb->br_seen = 1;
+
if (is_multicast_ether_addr(dest))
br_flood_deliver(br, skb);
else if ((dst = __br_fdb_get(br, dest)) != NULL)
@@ -42,6 +44,41 @@ int br_dev_xmit(struct sk_buff *skb, str
return 0;
}
+int br_hard_xmit(struct sk_buff *skb, struct net_bridge_port *port)
+{
+ struct net_bridge *br = port->br;
+ const unsigned char *dest = skb->data;
+ struct net_bridge_fdb_entry *dst;
+ struct sk_buff *skb2;
+
+ /* forward via master device only */
+ if (!br->via_phys_dev || br->master_dev != port->dev)
+ return 0;
+
+ skb2 = skb_clone(skb, GFP_ATOMIC);
+ if (!skb2) {
+ br->dev->stats.tx_dropped++;
+ return 0;
+ }
+
+ br->dev->stats.tx_packets++;
+ br->dev->stats.tx_bytes += skb2->len;
+
+ skb_reset_mac_header(skb2);
+ skb_pull(skb2, ETH_HLEN);
+
+ skb2->br_seen = 1;
+
+ if (is_multicast_ether_addr(dest))
+ br_flood_deliver(br, skb2);
+ else if ((dst = __br_fdb_get(br, dest)) != NULL)
+ br_deliver(dst->dst, skb2);
+ else
+ br_flood_deliver(br, skb2);
+
+ return 0;
+}
+
static int br_dev_open(struct net_device *dev)
{
struct net_bridge *br = netdev_priv(dev);
Index: linux-2.6.git/net/bridge/br_forward.c
=====================================================================
--- linux-2.6.git.orig/net/bridge/br_forward.c
+++ linux-2.6.git/net/bridge/br_forward.c
@@ -148,5 +148,6 @@ void br_flood_deliver(struct net_bridge
/* called under bridge lock */
void br_flood_forward(struct net_bridge *br, struct sk_buff *skb)
{
+ skb->br_seen = 1;
br_flood(br, skb, __br_forward);
}
Index: linux-2.6.git/net/bridge/br_input.c
=====================================================================
--- linux-2.6.git.orig/net/bridge/br_input.c
+++ linux-2.6.git/net/bridge/br_input.c
@@ -28,7 +28,15 @@ static void br_pass_frame_up(struct net_
brdev->stats.rx_bytes += skb->len;
indev = skb->dev;
- skb->dev = brdev;
+
+ if (br->via_phys_dev) {
+ skb->br_seen = 1;
+ if (likely(br->master_dev))
+ skb->dev = br->master_dev;
+ else
+ skb->dev = brdev;
+ } else
+ skb->dev = brdev;
NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_IN, skb, indev, NULL,
netif_receive_skb);
@@ -151,6 +159,10 @@ struct sk_buff *br_handle_frame(struct n
}
/* fall through */
case BR_STATE_LEARNING:
+ /* if we saw this skb earlier just pass it up */
+ if (skb->br_seen)
+ return skb;
+
if (!compare_ether_addr(p->br->dev->dev_addr, dest))
skb->pkt_type = PACKET_HOST;
Index: linux-2.6.git/net/bridge/br_private.h
=====================================================================
--- linux-2.6.git.orig/net/bridge/br_private.h
+++ linux-2.6.git/net/bridge/br_private.h
@@ -144,6 +144,7 @@ static inline int br_is_root_bridge(cons
/* br_device.c */
extern void br_dev_setup(struct net_device *dev);
extern int br_dev_xmit(struct sk_buff *skb, struct net_device *dev);
+extern int br_hard_xmit(struct sk_buff *skb, struct net_bridge_port *port);
/* br_fdb.c */
extern int br_fdb_init(void);
next prev parent reply other threads:[~2009-05-11 13:07 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-05-11 11:46 [RFC 0/5] bridge - introduce via_phys_dev feature Cyrill Gorcunov
2009-05-11 11:46 ` [RFC 1/5] net: bridge - use is_multicast_ether_addr helper Cyrill Gorcunov
2009-05-19 22:18 ` Stephen Hemminger
2009-05-11 11:46 ` [RFC 2/5] net: bridge - add managing of BRCTL_SET_VIA_PHYS_DEV and BRCTL_SET_MASTER_DEV Cyrill Gorcunov
2009-05-11 11:46 ` [RFC 3/5] net: sk_buff - introduce br_seen field to mark skb issued by a bridge Cyrill Gorcunov
2009-05-11 11:46 ` [RFC 4/5] net: dev.c - introduce br_hard_xmit_hook Cyrill Gorcunov
2009-05-11 11:46 ` [RFC 5/5] net: bridge - handle via_phys_dev feature on a bridge level Cyrill Gorcunov
2009-05-11 13:01 ` Cyrill Gorcunov [this message]
2009-05-12 5:30 ` [Bridge] [RFC 0/5] bridge - introduce via_phys_dev feature Daniel Robbins
2009-05-12 6:19 ` Cyrill Gorcunov
2009-05-12 7:02 ` Daniel Robbins
2009-05-12 16:24 ` Cyrill Gorcunov
2009-05-12 17:07 ` Daniel Robbins
2009-05-12 17:21 ` Cyrill Gorcunov
2009-05-19 22:21 ` Stephen Hemminger
[not found] ` <20090520192726.GF4968@lenovo>
[not found] ` <20090520131225.03b7715a@nehalam>
[not found] ` <20090521180805.GC4932@lenovo>
[not found] ` <20090521140504.1865883b@nehalam>
[not found] ` <20090522201850.GF5354@lenovo>
2010-02-26 16:18 ` Stephen Hemminger
2010-02-26 16:51 ` Cyrill Gorcunov
2010-02-26 17:39 ` Pavel Emelyanov
2010-02-26 18:01 ` Stephen Hemminger
2010-02-26 18:08 ` David Miller
2010-02-26 18:30 ` Stephen Hemminger
2010-02-26 18:40 ` Ben Greear
2010-02-26 18:49 ` Stephen Hemminger
2010-02-26 21:16 ` Pavel Emelyanov
2010-02-26 18:55 ` Cyrill Gorcunov
2010-02-26 19:01 ` David Miller
2010-02-26 16:52 ` [Bridge] " richardvoigt
2010-02-26 17:25 ` Stephen Hemminger
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20090511130115.GG4624@lenovo \
--to=gorcunov@gmail.com \
--cc=bridge@lists.linux-foundation.org \
--cc=davem@davemloft.net \
--cc=netdev@vger.kernel.org \
--cc=shemminger@linux-foundation.org \
--cc=xemul@openvz.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox