From: Toshiaki Makita <makita.toshiaki@lab.ntt.co.jp> To: "David S . Miller" <davem@davemloft.net>, Stephen Hemminger <stephen@networkplumber.org> Cc: Vlad Yasevich <vyasevic@redhat.com>, netdev@vger.kernel.org, bridge@lists.linux-foundation.org Subject: [PATCH net-next 2/4] bridge: Prepare for 802.1ad vlan filtering support Date: Mon, 9 Jun 2014 20:34:45 +0900 [thread overview] Message-ID: <1402313687-28067-3-git-send-email-makita.toshiaki@lab.ntt.co.jp> (raw) In-Reply-To: <1402313687-28067-1-git-send-email-makita.toshiaki@lab.ntt.co.jp> This enables a bridge to have vlan protocol informantion and allows vlan tag manipulation (retrieve, insert and remove tags) according to vlan protocols. Signed-off-by: Toshiaki Makita <makita.toshiaki@lab.ntt.co.jp> --- net/bridge/br_device.c | 1 + net/bridge/br_private.h | 6 ++++++ net/bridge/br_vlan.c | 56 ++++++++++++++++++++++++++++++++++++++----------- 3 files changed, 51 insertions(+), 12 deletions(-) diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c index 82a410a..1b797c4 100644 --- a/net/bridge/br_device.c +++ b/net/bridge/br_device.c @@ -388,4 +388,5 @@ void br_dev_setup(struct net_device *dev) br_netfilter_rtable_init(br); br_stp_timer_init(br); br_multicast_init(br); + br_vlan_init(br); } diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index bc17210..b65fee9 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h @@ -298,6 +298,7 @@ struct net_bridge u32 auto_cnt; #ifdef CONFIG_BRIDGE_VLAN_FILTERING u8 vlan_enabled; + __be16 vlan_proto; struct net_port_vlans __rcu *vlan_info; #endif }; @@ -598,6 +599,7 @@ int br_vlan_delete(struct net_bridge *br, u16 vid); void br_vlan_flush(struct net_bridge *br); bool br_vlan_find(struct net_bridge *br, u16 vid); int br_vlan_filter_toggle(struct net_bridge *br, unsigned long val); +void br_vlan_init(struct net_bridge *br); int nbp_vlan_add(struct net_bridge_port *port, u16 vid, u16 flags); int nbp_vlan_delete(struct net_bridge_port *port, u16 vid); void nbp_vlan_flush(struct net_bridge_port *port); @@ -693,6 +695,10 @@ static inline bool br_vlan_find(struct net_bridge *br, u16 vid) return false; } +static inline void br_vlan_init(struct net_bridge *br) +{ +} + static inline int nbp_vlan_add(struct net_bridge_port *port, u16 vid, u16 flags) { return -EOPNOTSUPP; diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c index fcc9539..63bd981 100644 --- a/net/bridge/br_vlan.c +++ b/net/bridge/br_vlan.c @@ -60,7 +60,7 @@ static int __vlan_add(struct net_port_vlans *v, u16 vid, u16 flags) * that ever changes this code will allow tagged * traffic to enter the bridge. */ - err = vlan_vid_add(dev, htons(ETH_P_8021Q), vid); + err = vlan_vid_add(dev, br->vlan_proto, vid); if (err) return err; } @@ -80,7 +80,7 @@ static int __vlan_add(struct net_port_vlans *v, u16 vid, u16 flags) out_filt: if (p) - vlan_vid_del(dev, htons(ETH_P_8021Q), vid); + vlan_vid_del(dev, br->vlan_proto, vid); return err; } @@ -92,8 +92,10 @@ static int __vlan_del(struct net_port_vlans *v, u16 vid) __vlan_delete_pvid(v, vid); clear_bit(vid, v->untagged_bitmap); - if (v->port_idx) - vlan_vid_del(v->parent.port->dev, htons(ETH_P_8021Q), vid); + if (v->port_idx) { + struct net_bridge_port *p = v->parent.port; + vlan_vid_del(p->dev, p->br->vlan_proto, vid); + } clear_bit(vid, v->vlan_bitmap); v->num_vlans--; @@ -158,7 +160,8 @@ out: bool br_allowed_ingress(struct net_bridge *br, struct net_port_vlans *v, struct sk_buff *skb, u16 *vid) { - int err; + bool tagged; + __be16 proto; /* If VLAN filtering is disabled on the bridge, all packets are * permitted. @@ -172,19 +175,41 @@ bool br_allowed_ingress(struct net_bridge *br, struct net_port_vlans *v, if (!v) goto drop; + proto = br->vlan_proto; + /* If vlan tx offload is disabled on bridge device and frame was * sent from vlan device on the bridge device, it does not have * HW accelerated vlan tag. */ if (unlikely(!vlan_tx_tag_present(skb) && - (skb->protocol == htons(ETH_P_8021Q) || - skb->protocol == htons(ETH_P_8021AD)))) { + skb->protocol == proto)) { skb = vlan_untag(skb); if (unlikely(!skb)) return false; } - err = br_vlan_get_tag(skb, vid); + if (!br_vlan_get_tag(skb, vid)) { + /* Tagged frame */ + if (skb->vlan_proto != proto) { + /* Protocol-mismatch, empty out vlan_tci for new tag */ + skb_push(skb, ETH_HLEN); + skb = __vlan_put_tag(skb, skb->vlan_proto, + vlan_tx_tag_get(skb)); + if (unlikely(!skb)) + return false; + + skb_pull(skb, ETH_HLEN); + skb_reset_mac_len(skb); + *vid = 0; + tagged = false; + } else { + tagged = true; + } + } else { + /* Untagged frame */ + tagged = false; + } + if (!*vid) { u16 pvid = br_get_pvid(v); @@ -199,9 +224,9 @@ bool br_allowed_ingress(struct net_bridge *br, struct net_port_vlans *v, * ingress frame is considered to belong to this vlan. */ *vid = pvid; - if (likely(err)) + if (likely(!tagged)) /* Untagged Frame. */ - __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), pvid); + __vlan_hwaccel_put_tag(skb, proto, pvid); else /* Priority-tagged Frame. * At this point, We know that skb->vlan_tci had @@ -254,7 +279,9 @@ bool br_should_learn(struct net_bridge_port *p, struct sk_buff *skb, u16 *vid) if (!v) return false; - br_vlan_get_tag(skb, vid); + if (!br_vlan_get_tag(skb, vid) && skb->vlan_proto != br->vlan_proto) + *vid = 0; + if (!*vid) { *vid = br_get_pvid(v); if (*vid == VLAN_N_VID) @@ -367,6 +394,11 @@ unlock: return 0; } +void br_vlan_init(struct net_bridge *br) +{ + br->vlan_proto = htons(ETH_P_8021Q); +} + /* Must be protected by RTNL. * Must be called with vid in range from 1 to 4094 inclusive. */ @@ -433,7 +465,7 @@ void nbp_vlan_flush(struct net_bridge_port *port) return; for_each_set_bit(vid, pv->vlan_bitmap, VLAN_N_VID) - vlan_vid_del(port->dev, htons(ETH_P_8021Q), vid); + vlan_vid_del(port->dev, port->br->vlan_proto, vid); __vlan_flush(pv); } -- 1.8.1.2
WARNING: multiple messages have this Message-ID (diff)
From: Toshiaki Makita <makita.toshiaki@lab.ntt.co.jp> To: "David S . Miller" <davem@davemloft.net>, Stephen Hemminger <stephen@networkplumber.org> Cc: Vlad Yasevich <vyasevic@redhat.com>, netdev@vger.kernel.org, bridge@lists.linux-foundation.org Subject: [Bridge] [PATCH net-next 2/4] bridge: Prepare for 802.1ad vlan filtering support Date: Mon, 9 Jun 2014 20:34:45 +0900 [thread overview] Message-ID: <1402313687-28067-3-git-send-email-makita.toshiaki@lab.ntt.co.jp> (raw) In-Reply-To: <1402313687-28067-1-git-send-email-makita.toshiaki@lab.ntt.co.jp> This enables a bridge to have vlan protocol informantion and allows vlan tag manipulation (retrieve, insert and remove tags) according to vlan protocols. Signed-off-by: Toshiaki Makita <makita.toshiaki@lab.ntt.co.jp> --- net/bridge/br_device.c | 1 + net/bridge/br_private.h | 6 ++++++ net/bridge/br_vlan.c | 56 ++++++++++++++++++++++++++++++++++++++----------- 3 files changed, 51 insertions(+), 12 deletions(-) diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c index 82a410a..1b797c4 100644 --- a/net/bridge/br_device.c +++ b/net/bridge/br_device.c @@ -388,4 +388,5 @@ void br_dev_setup(struct net_device *dev) br_netfilter_rtable_init(br); br_stp_timer_init(br); br_multicast_init(br); + br_vlan_init(br); } diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index bc17210..b65fee9 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h @@ -298,6 +298,7 @@ struct net_bridge u32 auto_cnt; #ifdef CONFIG_BRIDGE_VLAN_FILTERING u8 vlan_enabled; + __be16 vlan_proto; struct net_port_vlans __rcu *vlan_info; #endif }; @@ -598,6 +599,7 @@ int br_vlan_delete(struct net_bridge *br, u16 vid); void br_vlan_flush(struct net_bridge *br); bool br_vlan_find(struct net_bridge *br, u16 vid); int br_vlan_filter_toggle(struct net_bridge *br, unsigned long val); +void br_vlan_init(struct net_bridge *br); int nbp_vlan_add(struct net_bridge_port *port, u16 vid, u16 flags); int nbp_vlan_delete(struct net_bridge_port *port, u16 vid); void nbp_vlan_flush(struct net_bridge_port *port); @@ -693,6 +695,10 @@ static inline bool br_vlan_find(struct net_bridge *br, u16 vid) return false; } +static inline void br_vlan_init(struct net_bridge *br) +{ +} + static inline int nbp_vlan_add(struct net_bridge_port *port, u16 vid, u16 flags) { return -EOPNOTSUPP; diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c index fcc9539..63bd981 100644 --- a/net/bridge/br_vlan.c +++ b/net/bridge/br_vlan.c @@ -60,7 +60,7 @@ static int __vlan_add(struct net_port_vlans *v, u16 vid, u16 flags) * that ever changes this code will allow tagged * traffic to enter the bridge. */ - err = vlan_vid_add(dev, htons(ETH_P_8021Q), vid); + err = vlan_vid_add(dev, br->vlan_proto, vid); if (err) return err; } @@ -80,7 +80,7 @@ static int __vlan_add(struct net_port_vlans *v, u16 vid, u16 flags) out_filt: if (p) - vlan_vid_del(dev, htons(ETH_P_8021Q), vid); + vlan_vid_del(dev, br->vlan_proto, vid); return err; } @@ -92,8 +92,10 @@ static int __vlan_del(struct net_port_vlans *v, u16 vid) __vlan_delete_pvid(v, vid); clear_bit(vid, v->untagged_bitmap); - if (v->port_idx) - vlan_vid_del(v->parent.port->dev, htons(ETH_P_8021Q), vid); + if (v->port_idx) { + struct net_bridge_port *p = v->parent.port; + vlan_vid_del(p->dev, p->br->vlan_proto, vid); + } clear_bit(vid, v->vlan_bitmap); v->num_vlans--; @@ -158,7 +160,8 @@ out: bool br_allowed_ingress(struct net_bridge *br, struct net_port_vlans *v, struct sk_buff *skb, u16 *vid) { - int err; + bool tagged; + __be16 proto; /* If VLAN filtering is disabled on the bridge, all packets are * permitted. @@ -172,19 +175,41 @@ bool br_allowed_ingress(struct net_bridge *br, struct net_port_vlans *v, if (!v) goto drop; + proto = br->vlan_proto; + /* If vlan tx offload is disabled on bridge device and frame was * sent from vlan device on the bridge device, it does not have * HW accelerated vlan tag. */ if (unlikely(!vlan_tx_tag_present(skb) && - (skb->protocol == htons(ETH_P_8021Q) || - skb->protocol == htons(ETH_P_8021AD)))) { + skb->protocol == proto)) { skb = vlan_untag(skb); if (unlikely(!skb)) return false; } - err = br_vlan_get_tag(skb, vid); + if (!br_vlan_get_tag(skb, vid)) { + /* Tagged frame */ + if (skb->vlan_proto != proto) { + /* Protocol-mismatch, empty out vlan_tci for new tag */ + skb_push(skb, ETH_HLEN); + skb = __vlan_put_tag(skb, skb->vlan_proto, + vlan_tx_tag_get(skb)); + if (unlikely(!skb)) + return false; + + skb_pull(skb, ETH_HLEN); + skb_reset_mac_len(skb); + *vid = 0; + tagged = false; + } else { + tagged = true; + } + } else { + /* Untagged frame */ + tagged = false; + } + if (!*vid) { u16 pvid = br_get_pvid(v); @@ -199,9 +224,9 @@ bool br_allowed_ingress(struct net_bridge *br, struct net_port_vlans *v, * ingress frame is considered to belong to this vlan. */ *vid = pvid; - if (likely(err)) + if (likely(!tagged)) /* Untagged Frame. */ - __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), pvid); + __vlan_hwaccel_put_tag(skb, proto, pvid); else /* Priority-tagged Frame. * At this point, We know that skb->vlan_tci had @@ -254,7 +279,9 @@ bool br_should_learn(struct net_bridge_port *p, struct sk_buff *skb, u16 *vid) if (!v) return false; - br_vlan_get_tag(skb, vid); + if (!br_vlan_get_tag(skb, vid) && skb->vlan_proto != br->vlan_proto) + *vid = 0; + if (!*vid) { *vid = br_get_pvid(v); if (*vid == VLAN_N_VID) @@ -367,6 +394,11 @@ unlock: return 0; } +void br_vlan_init(struct net_bridge *br) +{ + br->vlan_proto = htons(ETH_P_8021Q); +} + /* Must be protected by RTNL. * Must be called with vid in range from 1 to 4094 inclusive. */ @@ -433,7 +465,7 @@ void nbp_vlan_flush(struct net_bridge_port *port) return; for_each_set_bit(vid, pv->vlan_bitmap, VLAN_N_VID) - vlan_vid_del(port->dev, htons(ETH_P_8021Q), vid); + vlan_vid_del(port->dev, port->br->vlan_proto, vid); __vlan_flush(pv); } -- 1.8.1.2
next prev parent reply other threads:[~2014-06-09 11:34 UTC|newest] Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top 2014-06-09 11:34 [PATCH net-next 0/4] bridge: 802.1ad vlan protocol support Toshiaki Makita 2014-06-09 11:34 ` [Bridge] " Toshiaki Makita 2014-06-09 11:34 ` [PATCH net-next 1/4] bridge: Add 802.1ad tx vlan acceleration Toshiaki Makita 2014-06-09 11:34 ` [Bridge] " Toshiaki Makita 2014-06-09 11:34 ` Toshiaki Makita [this message] 2014-06-09 11:34 ` [Bridge] [PATCH net-next 2/4] bridge: Prepare for 802.1ad vlan filtering support Toshiaki Makita 2014-06-09 11:34 ` [PATCH net-next 3/4] bridge: Consider the Nearest Customer Bridge group addresses Toshiaki Makita 2014-06-09 11:34 ` [Bridge] " Toshiaki Makita 2014-06-09 15:52 ` Stephen Hemminger 2014-06-09 15:52 ` [Bridge] " Stephen Hemminger 2014-06-09 16:45 ` Toshiaki Makita 2014-06-09 16:45 ` [Bridge] " Toshiaki Makita 2014-06-09 22:33 ` Vlad Yasevich 2014-06-09 22:33 ` [Bridge] " Vlad Yasevich 2014-06-10 7:05 ` Toshiaki Makita 2014-06-10 7:05 ` [Bridge] " Toshiaki Makita 2014-06-10 16:21 ` Stephen Hemminger 2014-06-10 16:21 ` [Bridge] " Stephen Hemminger 2014-06-11 6:12 ` Toshiaki Makita 2014-06-11 6:12 ` [Bridge] " Toshiaki Makita 2014-06-09 11:34 ` [PATCH net-next 4/4] bridge: Support 802.1ad vlan filtering Toshiaki Makita 2014-06-09 11:34 ` [Bridge] " Toshiaki Makita 2014-06-10 0:50 ` Vlad Yasevich 2014-06-10 0:50 ` [Bridge] " Vlad Yasevich 2014-06-10 7:15 ` Toshiaki Makita 2014-06-10 7:15 ` [Bridge] " Toshiaki Makita
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=1402313687-28067-3-git-send-email-makita.toshiaki@lab.ntt.co.jp \ --to=makita.toshiaki@lab.ntt.co.jp \ --cc=bridge@lists.linux-foundation.org \ --cc=davem@davemloft.net \ --cc=netdev@vger.kernel.org \ --cc=stephen@networkplumber.org \ --cc=vyasevic@redhat.com \ /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: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.