From: Vlad Yasevich <vyasevich@gmail.com>
To: Toshiaki Makita <makita.toshiaki@lab.ntt.co.jp>,
"David S . Miller" <davem@davemloft.net>,
Stephen Hemminger <stephen@networkplumber.org>
Cc: netdev@vger.kernel.org, bridge@lists.linux-foundation.org
Subject: Re: [Bridge] [PATCH net-next 4/4] bridge: Support 802.1ad vlan filtering
Date: Mon, 09 Jun 2014 20:50:18 -0400 [thread overview]
Message-ID: <5396564A.5040108@gmail.com> (raw)
In-Reply-To: <1402313687-28067-5-git-send-email-makita.toshiaki@lab.ntt.co.jp>
On 06/09/2014 07:34 AM, Toshiaki Makita wrote:
> This enables us to change the vlan protocol for vlan filtering.
> We come to be able to filter frames on the basis of 802.1ad vlan tags
> through a bridge.
>
> This also changes br->group_addr if it has not been set by user.
> This is needed for an 802.1ad bridge.
> (See IEEE 802.1Q-2011 8.13.5.)
>
> To change the vlan protocol, write a protocol in sysfs:
> # echo 0x88a8 > /sys/class/net/br0/bridge/vlan_protocol
>
> Signed-off-by: Toshiaki Makita <makita.toshiaki@lab.ntt.co.jp>
> ---
> net/bridge/br_private.h | 2 ++
> net/bridge/br_sysfs_br.c | 18 +++++++++++
> net/bridge/br_vlan.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 101 insertions(+)
>
> diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
> index 65204c2..3c5b23b 100644
> --- a/net/bridge/br_private.h
> +++ b/net/bridge/br_private.h
> @@ -246,6 +246,7 @@ struct net_bridge
> unsigned long bridge_forward_delay;
>
> u8 group_addr[ETH_ALEN];
> + unsigned char group_addr_set;
nit: can be bool since you just use true/false.
-vlad
> u16 root_port;
>
> enum {
> @@ -599,6 +600,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);
> +int br_vlan_set_proto(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);
> diff --git a/net/bridge/br_sysfs_br.c b/net/bridge/br_sysfs_br.c
> index 8dac6555..1831018 100644
> --- a/net/bridge/br_sysfs_br.c
> +++ b/net/bridge/br_sysfs_br.c
> @@ -315,6 +315,7 @@ static ssize_t group_addr_store(struct device *d,
> spin_lock_bh(&br->lock);
> for (i = 0; i < 6; i++)
> br->group_addr[i] = new_addr[i];
> + br->group_addr_set = 1;
> spin_unlock_bh(&br->lock);
> return len;
> }
> @@ -700,6 +701,22 @@ static ssize_t vlan_filtering_store(struct device *d,
> return store_bridge_parm(d, buf, len, br_vlan_filter_toggle);
> }
> static DEVICE_ATTR_RW(vlan_filtering);
> +
> +static ssize_t vlan_protocol_show(struct device *d,
> + struct device_attribute *attr,
> + char *buf)
> +{
> + struct net_bridge *br = to_bridge(d);
> + return sprintf(buf, "%#06x\n", ntohs(br->vlan_proto));
> +}
> +
> +static ssize_t vlan_protocol_store(struct device *d,
> + struct device_attribute *attr,
> + const char *buf, size_t len)
> +{
> + return store_bridge_parm(d, buf, len, br_vlan_set_proto);
> +}
> +static DEVICE_ATTR_RW(vlan_protocol);
> #endif
>
> static struct attribute *bridge_attrs[] = {
> @@ -745,6 +762,7 @@ static struct attribute *bridge_attrs[] = {
> #endif
> #ifdef CONFIG_BRIDGE_VLAN_FILTERING
> &dev_attr_vlan_filtering.attr,
> + &dev_attr_vlan_protocol.attr,
> #endif
> NULL
> };
> diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c
> index 63bd981..c86a7a6 100644
> --- a/net/bridge/br_vlan.c
> +++ b/net/bridge/br_vlan.c
> @@ -394,6 +394,87 @@ unlock:
> return 0;
> }
>
> +int br_vlan_set_proto(struct net_bridge *br, unsigned long val)
> +{
> + int err = 0;
> + struct net_bridge_port *p;
> + struct net_port_vlans *pv;
> + __be16 proto, oldproto;
> + u16 vid, errvid;
> +
> + if (val != ETH_P_8021Q && val != ETH_P_8021AD)
> + return -EPROTONOSUPPORT;
> +
> + if (!rtnl_trylock())
> + return restart_syscall();
> +
> + proto = htons(val);
> + if (br->vlan_proto == proto)
> + goto unlock;
> +
> + /* Add VLANs for the new proto to the device filter. */
> + list_for_each_entry(p, &br->port_list, list) {
> + pv = rtnl_dereference(p->vlan_info);
> + if (!pv)
> + continue;
> +
> + for_each_set_bit(vid, pv->vlan_bitmap, VLAN_N_VID) {
> + err = vlan_vid_add(p->dev, proto, vid);
> + if (err)
> + goto err_filt;
> + }
> + }
> +
> + spin_lock_bh(&br->lock);
> + if (!br->group_addr_set) {
> + switch (val) {
> + case ETH_P_8021Q:
> + /* Bridge Group Address */
> + br->group_addr[5] = 0x00;
> + break;
> +
> + case ETH_P_8021AD:
> + /* Provider Bridge Group Address */
> + br->group_addr[5] = 0x08;
> + break;
> + }
> + }
> + spin_unlock_bh(&br->lock);
> +
> + oldproto = br->vlan_proto;
> + br->vlan_proto = proto;
> +
> + /* Delete VLANs for the old proto from the device filter. */
> + list_for_each_entry(p, &br->port_list, list) {
> + pv = rtnl_dereference(p->vlan_info);
> + if (!pv)
> + continue;
> +
> + for_each_set_bit(vid, pv->vlan_bitmap, VLAN_N_VID)
> + vlan_vid_del(p->dev, oldproto, vid);
> + }
> +
> +unlock:
> + rtnl_unlock();
> + return err;
> +
> +err_filt:
> + errvid = vid;
> + for_each_set_bit(vid, pv->vlan_bitmap, errvid)
> + vlan_vid_del(p->dev, proto, vid);
> +
> + list_for_each_entry_continue_reverse(p, &br->port_list, list) {
> + pv = rtnl_dereference(p->vlan_info);
> + if (!pv)
> + continue;
> +
> + for_each_set_bit(vid, pv->vlan_bitmap, VLAN_N_VID)
> + vlan_vid_del(p->dev, proto, vid);
> + }
> +
> + goto unlock;
> +}
> +
> void br_vlan_init(struct net_bridge *br)
> {
> br->vlan_proto = htons(ETH_P_8021Q);
>
WARNING: multiple messages have this Message-ID (diff)
From: Vlad Yasevich <vyasevich@gmail.com>
To: Toshiaki Makita <makita.toshiaki@lab.ntt.co.jp>,
"David S . Miller" <davem@davemloft.net>,
Stephen Hemminger <stephen@networkplumber.org>
Cc: netdev@vger.kernel.org, bridge@lists.linux-foundation.org
Subject: Re: [PATCH net-next 4/4] bridge: Support 802.1ad vlan filtering
Date: Mon, 09 Jun 2014 20:50:18 -0400 [thread overview]
Message-ID: <5396564A.5040108@gmail.com> (raw)
In-Reply-To: <1402313687-28067-5-git-send-email-makita.toshiaki@lab.ntt.co.jp>
On 06/09/2014 07:34 AM, Toshiaki Makita wrote:
> This enables us to change the vlan protocol for vlan filtering.
> We come to be able to filter frames on the basis of 802.1ad vlan tags
> through a bridge.
>
> This also changes br->group_addr if it has not been set by user.
> This is needed for an 802.1ad bridge.
> (See IEEE 802.1Q-2011 8.13.5.)
>
> To change the vlan protocol, write a protocol in sysfs:
> # echo 0x88a8 > /sys/class/net/br0/bridge/vlan_protocol
>
> Signed-off-by: Toshiaki Makita <makita.toshiaki@lab.ntt.co.jp>
> ---
> net/bridge/br_private.h | 2 ++
> net/bridge/br_sysfs_br.c | 18 +++++++++++
> net/bridge/br_vlan.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 101 insertions(+)
>
> diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
> index 65204c2..3c5b23b 100644
> --- a/net/bridge/br_private.h
> +++ b/net/bridge/br_private.h
> @@ -246,6 +246,7 @@ struct net_bridge
> unsigned long bridge_forward_delay;
>
> u8 group_addr[ETH_ALEN];
> + unsigned char group_addr_set;
nit: can be bool since you just use true/false.
-vlad
> u16 root_port;
>
> enum {
> @@ -599,6 +600,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);
> +int br_vlan_set_proto(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);
> diff --git a/net/bridge/br_sysfs_br.c b/net/bridge/br_sysfs_br.c
> index 8dac6555..1831018 100644
> --- a/net/bridge/br_sysfs_br.c
> +++ b/net/bridge/br_sysfs_br.c
> @@ -315,6 +315,7 @@ static ssize_t group_addr_store(struct device *d,
> spin_lock_bh(&br->lock);
> for (i = 0; i < 6; i++)
> br->group_addr[i] = new_addr[i];
> + br->group_addr_set = 1;
> spin_unlock_bh(&br->lock);
> return len;
> }
> @@ -700,6 +701,22 @@ static ssize_t vlan_filtering_store(struct device *d,
> return store_bridge_parm(d, buf, len, br_vlan_filter_toggle);
> }
> static DEVICE_ATTR_RW(vlan_filtering);
> +
> +static ssize_t vlan_protocol_show(struct device *d,
> + struct device_attribute *attr,
> + char *buf)
> +{
> + struct net_bridge *br = to_bridge(d);
> + return sprintf(buf, "%#06x\n", ntohs(br->vlan_proto));
> +}
> +
> +static ssize_t vlan_protocol_store(struct device *d,
> + struct device_attribute *attr,
> + const char *buf, size_t len)
> +{
> + return store_bridge_parm(d, buf, len, br_vlan_set_proto);
> +}
> +static DEVICE_ATTR_RW(vlan_protocol);
> #endif
>
> static struct attribute *bridge_attrs[] = {
> @@ -745,6 +762,7 @@ static struct attribute *bridge_attrs[] = {
> #endif
> #ifdef CONFIG_BRIDGE_VLAN_FILTERING
> &dev_attr_vlan_filtering.attr,
> + &dev_attr_vlan_protocol.attr,
> #endif
> NULL
> };
> diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c
> index 63bd981..c86a7a6 100644
> --- a/net/bridge/br_vlan.c
> +++ b/net/bridge/br_vlan.c
> @@ -394,6 +394,87 @@ unlock:
> return 0;
> }
>
> +int br_vlan_set_proto(struct net_bridge *br, unsigned long val)
> +{
> + int err = 0;
> + struct net_bridge_port *p;
> + struct net_port_vlans *pv;
> + __be16 proto, oldproto;
> + u16 vid, errvid;
> +
> + if (val != ETH_P_8021Q && val != ETH_P_8021AD)
> + return -EPROTONOSUPPORT;
> +
> + if (!rtnl_trylock())
> + return restart_syscall();
> +
> + proto = htons(val);
> + if (br->vlan_proto == proto)
> + goto unlock;
> +
> + /* Add VLANs for the new proto to the device filter. */
> + list_for_each_entry(p, &br->port_list, list) {
> + pv = rtnl_dereference(p->vlan_info);
> + if (!pv)
> + continue;
> +
> + for_each_set_bit(vid, pv->vlan_bitmap, VLAN_N_VID) {
> + err = vlan_vid_add(p->dev, proto, vid);
> + if (err)
> + goto err_filt;
> + }
> + }
> +
> + spin_lock_bh(&br->lock);
> + if (!br->group_addr_set) {
> + switch (val) {
> + case ETH_P_8021Q:
> + /* Bridge Group Address */
> + br->group_addr[5] = 0x00;
> + break;
> +
> + case ETH_P_8021AD:
> + /* Provider Bridge Group Address */
> + br->group_addr[5] = 0x08;
> + break;
> + }
> + }
> + spin_unlock_bh(&br->lock);
> +
> + oldproto = br->vlan_proto;
> + br->vlan_proto = proto;
> +
> + /* Delete VLANs for the old proto from the device filter. */
> + list_for_each_entry(p, &br->port_list, list) {
> + pv = rtnl_dereference(p->vlan_info);
> + if (!pv)
> + continue;
> +
> + for_each_set_bit(vid, pv->vlan_bitmap, VLAN_N_VID)
> + vlan_vid_del(p->dev, oldproto, vid);
> + }
> +
> +unlock:
> + rtnl_unlock();
> + return err;
> +
> +err_filt:
> + errvid = vid;
> + for_each_set_bit(vid, pv->vlan_bitmap, errvid)
> + vlan_vid_del(p->dev, proto, vid);
> +
> + list_for_each_entry_continue_reverse(p, &br->port_list, list) {
> + pv = rtnl_dereference(p->vlan_info);
> + if (!pv)
> + continue;
> +
> + for_each_set_bit(vid, pv->vlan_bitmap, VLAN_N_VID)
> + vlan_vid_del(p->dev, proto, vid);
> + }
> +
> + goto unlock;
> +}
> +
> void br_vlan_init(struct net_bridge *br)
> {
> br->vlan_proto = htons(ETH_P_8021Q);
>
next prev parent reply other threads:[~2014-06-10 0:50 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-06-09 11:34 [Bridge] [PATCH net-next 0/4] bridge: 802.1ad vlan protocol support Toshiaki Makita
2014-06-09 11:34 ` Toshiaki Makita
2014-06-09 11:34 ` [Bridge] [PATCH net-next 1/4] bridge: Add 802.1ad tx vlan acceleration Toshiaki Makita
2014-06-09 11:34 ` Toshiaki Makita
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 ` Toshiaki Makita
2014-06-09 11:34 ` [Bridge] [PATCH net-next 3/4] bridge: Consider the Nearest Customer Bridge group addresses Toshiaki Makita
2014-06-09 11:34 ` Toshiaki Makita
2014-06-09 15:52 ` [Bridge] " Stephen Hemminger
2014-06-09 15:52 ` Stephen Hemminger
2014-06-09 16:45 ` [Bridge] " Toshiaki Makita
2014-06-09 16:45 ` Toshiaki Makita
2014-06-09 22:33 ` [Bridge] " Vlad Yasevich
2014-06-09 22:33 ` Vlad Yasevich
2014-06-10 7:05 ` [Bridge] " Toshiaki Makita
2014-06-10 7:05 ` Toshiaki Makita
2014-06-10 16:21 ` [Bridge] " Stephen Hemminger
2014-06-10 16:21 ` Stephen Hemminger
2014-06-11 6:12 ` [Bridge] " Toshiaki Makita
2014-06-11 6:12 ` Toshiaki Makita
2014-06-09 11:34 ` [Bridge] [PATCH net-next 4/4] bridge: Support 802.1ad vlan filtering Toshiaki Makita
2014-06-09 11:34 ` Toshiaki Makita
2014-06-10 0:50 ` Vlad Yasevich [this message]
2014-06-10 0:50 ` Vlad Yasevich
2014-06-10 7:15 ` [Bridge] " Toshiaki Makita
2014-06-10 7:15 ` 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=5396564A.5040108@gmail.com \
--to=vyasevich@gmail.com \
--cc=bridge@lists.linux-foundation.org \
--cc=davem@davemloft.net \
--cc=makita.toshiaki@lab.ntt.co.jp \
--cc=netdev@vger.kernel.org \
--cc=stephen@networkplumber.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 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.