From: Vlad Yasevich <vyasevic@redhat.com>
To: "Michał Mirosław" <mirqus@gmail.com>
Cc: netdev@vger.kernel.org, shemminger@vyatta.com,
bridge@lists.linux-foundation.org, davem@davemloft.net
Subject: Re: [Bridge] [PATCH v9 net-next 01/12] bridge: Add vlan filtering infrastructure
Date: Fri, 01 Feb 2013 21:11:39 -0500 [thread overview]
Message-ID: <510C75DB.5010801@redhat.com> (raw)
In-Reply-To: <CAHXqBFJfPYwnxbeDR6AfG0-PQJ__=rKMxQWRcFJGseGiXyuYGg@mail.gmail.com>
On 02/01/2013 08:04 PM, Michał Mirosław wrote:
> 2013/2/1 Vlad Yasevich <vyasevic@redhat.com>:
>> Adds an optional infrustructure component to bridge that would allow
>> native vlan filtering in the bridge. Each bridge port (as well
>> as the bridge device) now get a VLAN bitmap. Each bit in the bitmap
>> is associated with a vlan id. This way if the bit corresponding to
>> the vid is set in the bitmap that the packet with vid is allowed to
>> enter and exit the port.
> [...]
> +struct net_port_vlans {
> + u16 port_idx;
> + void *parent;
> + struct rcu_head rcu;
> + unsigned long vlan_bitmap[BR_VLAN_BITMAP_LEN];
> +};
> [later, in br_vlan.c]
> +#define vlans_to_parent(type, pv) ((type *)(pv)->parent)
>
> A really don't like this pointer casting. It's easy to get it wrong
> (and you did in __vlan_del).
>
> 1. union { struct net_bridge *br; struct net_bridge_port *port; } parent;
>
> 2. inline net_port_vlans __rcu **br_vlan_info_parent_ptr(struct
> net_port_vlans *v)
> {
> return v->port_idx ? &v->parent.port->vlan_info : &v->parent.br->vlan_info;
> }
>
> (I'm not insisting on #2. Just think about it. ;)
I need the parent, not the vlan_info. Sometimes I need to get to the
device and I really don't want to then use container_of().
I suppose I could do the union, but that's really not much different
then the type casts. Just as easy to goof.
>
>> @@ -156,6 +166,7 @@ struct net_bridge_port
>> #ifdef CONFIG_NET_POLL_CONTROLLER
>> struct netpoll *np;
>> #endif
>> + struct net_port_vlans __rcu *vlan_info;
>> };
>
> Missing #ifdef CONFIG_BRIDGE_VLAN_FILTERING?
Yep. Its in net_bridge, but not here. Will fix.
>
>> +static int __vlan_del(struct net_port_vlans *v, u16 vid)
>> +{
>> + unsigned long first_bit;
>> + unsigned long last_bit;
>> +
>> + if (!test_bit(vid, v->vlan_bitmap))
>> + return -EINVAL;
>> +
>> + /* Check to see if any other vlans are in this table. If this
>> + * is the last vlan, delete the whole structure. If this is not the
>> + * last vlan, just clear the bit.
>> + */
>> + first_bit = find_first_bit(v->vlan_bitmap, BR_VLAN_BITMAP_LEN);
>> + last_bit = find_last_bit(v->vlan_bitmap, BR_VLAN_BITMAP_LEN);
>> +
>> + if (v->port_idx && vid) {
>> + struct net_device *dev =
>> + vlans_to_parent(struct net_bridge, v)->dev;
>
> struct net_bridge_port (or union and v->parent.port)
Yep. Typo when doing conversions.
>
>> +
>> + if (dev->features & NETIF_F_HW_VLAN_FILTER)
>> + dev->netdev_ops->ndo_vlan_rx_kill_vid(dev, vid);
>> + }
>> +
>> + clear_bit(vid, v->vlan_bitmap);
>> + if (first_bit == last_bit) {
>
> bitmap_empty() is faster than two times find_xxx_bit().
>
WTH? I did this change and now its gone... Time to see what else I
somehow lost...
>> + if (v->port_idx) {
>> + struct net_bridge_port *p =
>> + vlans_to_parent(struct net_bridge_port, v);
>> + rcu_assign_pointer(p->vlan_info, NULL);
>> + } else {
>> + struct net_bridge *br =
>> + vlans_to_parent(struct net_bridge, v);
>> + rcu_assign_pointer(br->vlan_info, NULL);
>> + }
>
> With inline function above:
>
> rcu_assign_pointer(*br_vlan_info_parent_ptr(v), NULL);
>
>> + kfree_rcu(v, rcu);
>> + }
>> + return 0;
>> +}
>> +
>> +static void __vlan_flush(struct net_port_vlans *v)
>> +{
>> + bitmap_zero(v->vlan_bitmap, BR_VLAN_BITMAP_LEN);
>> + if (v->port_idx) {
>> + struct net_bridge_port *p =
>> + vlans_to_parent(struct net_bridge_port, v);
>> + rcu_assign_pointer(p->vlan_info, NULL);
>> + } else {
>> + struct net_bridge *br =
>> + vlans_to_parent(struct net_bridge, v);
>> + rcu_assign_pointer(br->vlan_info, NULL);
>> + }
>
> Same here.
Thanks. I'll probably go with the union for direct reference.
-vlad
>
>> + kfree_rcu(v, rcu);
>> +}
>
> Best Regards,
> Michał Mirosław
>
WARNING: multiple messages have this Message-ID (diff)
From: Vlad Yasevich <vyasevic@redhat.com>
To: "Michał Mirosław" <mirqus@gmail.com>
Cc: shemminger@vyatta.com, bridge@lists.linux-foundation.org,
davem@davemloft.net, netdev@vger.kernel.org
Subject: Re: [PATCH v9 net-next 01/12] bridge: Add vlan filtering infrastructure
Date: Fri, 01 Feb 2013 21:11:39 -0500 [thread overview]
Message-ID: <510C75DB.5010801@redhat.com> (raw)
In-Reply-To: <CAHXqBFJfPYwnxbeDR6AfG0-PQJ__=rKMxQWRcFJGseGiXyuYGg@mail.gmail.com>
On 02/01/2013 08:04 PM, Michał Mirosław wrote:
> 2013/2/1 Vlad Yasevich <vyasevic@redhat.com>:
>> Adds an optional infrustructure component to bridge that would allow
>> native vlan filtering in the bridge. Each bridge port (as well
>> as the bridge device) now get a VLAN bitmap. Each bit in the bitmap
>> is associated with a vlan id. This way if the bit corresponding to
>> the vid is set in the bitmap that the packet with vid is allowed to
>> enter and exit the port.
> [...]
> +struct net_port_vlans {
> + u16 port_idx;
> + void *parent;
> + struct rcu_head rcu;
> + unsigned long vlan_bitmap[BR_VLAN_BITMAP_LEN];
> +};
> [later, in br_vlan.c]
> +#define vlans_to_parent(type, pv) ((type *)(pv)->parent)
>
> A really don't like this pointer casting. It's easy to get it wrong
> (and you did in __vlan_del).
>
> 1. union { struct net_bridge *br; struct net_bridge_port *port; } parent;
>
> 2. inline net_port_vlans __rcu **br_vlan_info_parent_ptr(struct
> net_port_vlans *v)
> {
> return v->port_idx ? &v->parent.port->vlan_info : &v->parent.br->vlan_info;
> }
>
> (I'm not insisting on #2. Just think about it. ;)
I need the parent, not the vlan_info. Sometimes I need to get to the
device and I really don't want to then use container_of().
I suppose I could do the union, but that's really not much different
then the type casts. Just as easy to goof.
>
>> @@ -156,6 +166,7 @@ struct net_bridge_port
>> #ifdef CONFIG_NET_POLL_CONTROLLER
>> struct netpoll *np;
>> #endif
>> + struct net_port_vlans __rcu *vlan_info;
>> };
>
> Missing #ifdef CONFIG_BRIDGE_VLAN_FILTERING?
Yep. Its in net_bridge, but not here. Will fix.
>
>> +static int __vlan_del(struct net_port_vlans *v, u16 vid)
>> +{
>> + unsigned long first_bit;
>> + unsigned long last_bit;
>> +
>> + if (!test_bit(vid, v->vlan_bitmap))
>> + return -EINVAL;
>> +
>> + /* Check to see if any other vlans are in this table. If this
>> + * is the last vlan, delete the whole structure. If this is not the
>> + * last vlan, just clear the bit.
>> + */
>> + first_bit = find_first_bit(v->vlan_bitmap, BR_VLAN_BITMAP_LEN);
>> + last_bit = find_last_bit(v->vlan_bitmap, BR_VLAN_BITMAP_LEN);
>> +
>> + if (v->port_idx && vid) {
>> + struct net_device *dev =
>> + vlans_to_parent(struct net_bridge, v)->dev;
>
> struct net_bridge_port (or union and v->parent.port)
Yep. Typo when doing conversions.
>
>> +
>> + if (dev->features & NETIF_F_HW_VLAN_FILTER)
>> + dev->netdev_ops->ndo_vlan_rx_kill_vid(dev, vid);
>> + }
>> +
>> + clear_bit(vid, v->vlan_bitmap);
>> + if (first_bit == last_bit) {
>
> bitmap_empty() is faster than two times find_xxx_bit().
>
WTH? I did this change and now its gone... Time to see what else I
somehow lost...
>> + if (v->port_idx) {
>> + struct net_bridge_port *p =
>> + vlans_to_parent(struct net_bridge_port, v);
>> + rcu_assign_pointer(p->vlan_info, NULL);
>> + } else {
>> + struct net_bridge *br =
>> + vlans_to_parent(struct net_bridge, v);
>> + rcu_assign_pointer(br->vlan_info, NULL);
>> + }
>
> With inline function above:
>
> rcu_assign_pointer(*br_vlan_info_parent_ptr(v), NULL);
>
>> + kfree_rcu(v, rcu);
>> + }
>> + return 0;
>> +}
>> +
>> +static void __vlan_flush(struct net_port_vlans *v)
>> +{
>> + bitmap_zero(v->vlan_bitmap, BR_VLAN_BITMAP_LEN);
>> + if (v->port_idx) {
>> + struct net_bridge_port *p =
>> + vlans_to_parent(struct net_bridge_port, v);
>> + rcu_assign_pointer(p->vlan_info, NULL);
>> + } else {
>> + struct net_bridge *br =
>> + vlans_to_parent(struct net_bridge, v);
>> + rcu_assign_pointer(br->vlan_info, NULL);
>> + }
>
> Same here.
Thanks. I'll probably go with the union for direct reference.
-vlad
>
>> + kfree_rcu(v, rcu);
>> +}
>
> Best Regards,
> Michał Mirosław
>
next prev parent reply other threads:[~2013-02-02 2:11 UTC|newest]
Thread overview: 56+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-02-01 20:01 [Bridge] [PATCH v9 net-next 00/12] Add basic VLAN support to bridges Vlad Yasevich
2013-02-01 20:01 ` Vlad Yasevich
2013-02-01 20:01 ` [Bridge] [PATCH v9 net-next 01/12] bridge: Add vlan filtering infrastructure Vlad Yasevich
2013-02-01 20:01 ` Vlad Yasevich
2013-02-02 1:04 ` [Bridge] " Michał Mirosław
2013-02-02 1:04 ` Michał Mirosław
2013-02-02 2:11 ` Vlad Yasevich [this message]
2013-02-02 2:11 ` Vlad Yasevich
2013-02-01 20:02 ` [Bridge] [PATCH v9 net-next 02/12] bridge: Validate that vlan is permitted on ingress Vlad Yasevich
2013-02-01 20:02 ` Vlad Yasevich
2013-02-02 1:04 ` [Bridge] " Michał Mirosław
2013-02-02 1:04 ` Michał Mirosław
2013-02-02 2:13 ` [Bridge] " Vlad Yasevich
2013-02-02 2:13 ` Vlad Yasevich
2013-02-01 20:02 ` [Bridge] [PATCH v9 net-next 03/12] bridge: Verify that a vlan is allowed to egress on give port Vlad Yasevich
2013-02-01 20:02 ` Vlad Yasevich
2013-02-01 20:02 ` [Bridge] [PATCH v9 net-next 04/12] bridge: Add netlink interface to configure vlans on bridge ports Vlad Yasevich
2013-02-01 20:02 ` Vlad Yasevich
2013-02-01 20:02 ` [Bridge] [PATCH v9 net-next 05/12] bridge: Add the ability to configure pvid Vlad Yasevich
2013-02-01 20:02 ` Vlad Yasevich
2013-02-02 1:04 ` [Bridge] " Michał Mirosław
2013-02-02 1:04 ` Michał Mirosław
2013-02-02 1:15 ` [Bridge] " Michał Mirosław
2013-02-02 1:15 ` Michał Mirosław
2013-02-02 2:22 ` [Bridge] " Vlad Yasevich
2013-02-02 2:22 ` Vlad Yasevich
2013-02-03 14:49 ` [Bridge] " Michał Mirosław
2013-02-03 14:49 ` Michał Mirosław
2013-02-03 15:20 ` [Bridge] " Michał Mirosław
2013-02-03 15:20 ` Michał Mirosław
2013-02-04 16:59 ` [Bridge] " Vlad Yasevich
2013-02-04 16:59 ` Vlad Yasevich
2013-02-01 20:02 ` [Bridge] [PATCH v9 net-next 06/12] bridge: Implement vlan ingress/egress policy Vlad Yasevich
2013-02-01 20:02 ` Vlad Yasevich
2013-02-01 20:02 ` [Bridge] [PATCH v9 net-next 07/12] bridge: Add vlan to unicast fdb entries Vlad Yasevich
2013-02-01 20:02 ` Vlad Yasevich
2013-02-01 20:02 ` [Bridge] [PATCH v9 net-next 08/12] bridge: Add vlan id to multicast groups Vlad Yasevich
2013-02-01 20:02 ` Vlad Yasevich
2013-02-01 20:02 ` [Bridge] [PATCH v9 net-next 09/12] bridge: Add vlan support to static neighbors Vlad Yasevich
2013-02-01 20:02 ` Vlad Yasevich
2013-02-01 20:02 ` [Bridge] [PATCH v9 net-next 10/12] bridge: Add vlan support for local fdb entries Vlad Yasevich
2013-02-01 20:02 ` Vlad Yasevich
2013-02-01 20:02 ` [Bridge] [PATCH v9 net-next 11/12] bridge: Dump vlan information from a bridge port Vlad Yasevich
2013-02-01 20:02 ` Vlad Yasevich
2013-02-01 20:02 ` [Bridge] [PATCH v9 net-next 12/12] bridge: Separate egress policy bitmap Vlad Yasevich
2013-02-01 20:02 ` Vlad Yasevich
2013-02-04 16:24 ` [Bridge] [PATCH v9 net-next 00/12] Add basic VLAN support to bridges Stephen Hemminger
2013-02-04 16:24 ` Stephen Hemminger
2013-02-04 16:58 ` [Bridge] " Vlad Yasevich
2013-02-04 16:58 ` Vlad Yasevich
2013-02-07 22:48 ` [Bridge] " Vlad Yasevich
2013-02-07 22:48 ` Vlad Yasevich
2013-02-07 22:57 ` [Bridge] " Stephen Hemminger
2013-02-07 22:57 ` Stephen Hemminger
2013-02-07 23:00 ` [Bridge] " Vlad Yasevich
2013-02-07 23:00 ` Vlad Yasevich
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=510C75DB.5010801@redhat.com \
--to=vyasevic@redhat.com \
--cc=bridge@lists.linux-foundation.org \
--cc=davem@davemloft.net \
--cc=mirqus@gmail.com \
--cc=netdev@vger.kernel.org \
--cc=shemminger@vyatta.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: 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.