Message ID | 1355342477-4971-5-git-send-email-vyasevic@redhat.com |
---|---|
State | Deferred, archived |
Delegated to: | David Miller |
Headers | show |
On Wed, 12 Dec 2012 15:01:10 -0500 Vlad Yasevich <vyasevic@redhat.com> wrote: > On input, cache the pointer to the bridge vlan info, so that > on egress, we have can simply look at the port bitmap instead > of traversing a vlan list. > > Signed-off-by: Vlad Yasevich <vyasevic@redhat.com> This isn't going to be safe. Once packet is passed up, the cb[] can get overwritten by other things. -- 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
On 12/18/2012 12:04 PM, Stephen Hemminger wrote: > On Wed, 12 Dec 2012 15:01:10 -0500 > Vlad Yasevich <vyasevic@redhat.com> wrote: > >> On input, cache the pointer to the bridge vlan info, so that >> on egress, we have can simply look at the port bitmap instead >> of traversing a vlan list. >> >> Signed-off-by: Vlad Yasevich <vyasevic@redhat.com> > > This isn't going to be safe. Once packet is passed up, the cb[] > can get overwritten by other things. > Right, but only care about it while in bridging code. We don't look at it anywhere else... Or are you saying that cb is not guaranteed to be preserved between br_handle_frame_finish and br_forward? -vlad -- 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_device.c b/net/bridge/br_device.c index 9546742..57c5bac 100644 --- a/net/bridge/br_device.c +++ b/net/bridge/br_device.c @@ -30,6 +30,7 @@ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev) struct net_bridge_fdb_entry *dst; struct net_bridge_mdb_entry *mdst; struct br_cpu_netstats *brstats = this_cpu_ptr(br->stats); + struct net_bridge_vlan *vlan; rcu_read_lock(); #ifdef CONFIG_BRIDGE_NETFILTER @@ -47,6 +48,13 @@ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev) BR_INPUT_SKB_CB(skb)->brdev = dev; + /* Any vlan transmitted by the bridge itself is permitted. + * Try to cache the vlan in the CB to speed up forwarding. + */ + vlan = br_vlan_find(br, br_get_vlan(skb)); + if (vlan) + BR_INPUT_SKB_CB(skb)->vlan = vlan; + skb_reset_mac_header(skb); skb_pull(skb, ETH_HLEN); diff --git a/net/bridge/br_forward.c b/net/bridge/br_forward.c index 0c7ffc2..4ae5f55 100644 --- a/net/bridge/br_forward.c +++ b/net/bridge/br_forward.c @@ -30,11 +30,25 @@ static inline bool br_allowed_egress(const struct net_bridge_port *p, const struct sk_buff *skb) { struct net_port_vlan *pve; + struct net_bridge_vlan *vlan = NULL; u16 vid; if (list_empty(&p->vlan_list)) return true; + vlan = BR_INPUT_SKB_CB(skb)->vlan; + if (vlan) { + /* If we have cached VLAN information, use port_bitmap + * of the vlan to make the decision + */ + if (test_bit(p->port_no, vlan->port_bitmap)) + return true; + return false; + } + + /* We don't have cached vlan information, so we need to do + * it the hard way. + */ vid = br_get_vlan(skb); pve = nbp_vlan_find(p, vid); if (pve) diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c index 54c0894..e475f49 100644 --- a/net/bridge/br_input.c +++ b/net/bridge/br_input.c @@ -47,6 +47,8 @@ static bool br_allowed_ingress(struct net_bridge_port *p, struct sk_buff *skb) struct net_port_vlan *pve; u16 vid; + BR_INPUT_SKB_CB(skb)->vlan = NULL; + /* If there are no vlan in the permitted list, all packets are * permitted. */ @@ -55,8 +57,10 @@ static bool br_allowed_ingress(struct net_bridge_port *p, struct sk_buff *skb) vid = br_get_vlan(skb); pve = nbp_vlan_find(p, vid); - if (pve) + if (pve) { + BR_INPUT_SKB_CB(skb)->vlan = pve->vlan; return true; + } return false; } diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index a385d9a..1475fab 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h @@ -300,6 +300,7 @@ struct net_bridge struct br_input_skb_cb { struct net_device *brdev; + struct net_bridge_vlan *vlan; #ifdef CONFIG_BRIDGE_IGMP_SNOOPING int igmp; int mrouters_only;
On input, cache the pointer to the bridge vlan info, so that on egress, we have can simply look at the port bitmap instead of traversing a vlan list. Signed-off-by: Vlad Yasevich <vyasevic@redhat.com> --- net/bridge/br_device.c | 8 ++++++++ net/bridge/br_forward.c | 14 ++++++++++++++ net/bridge/br_input.c | 6 +++++- net/bridge/br_private.h | 1 + 4 files changed, 28 insertions(+), 1 deletions(-)