All of lore.kernel.org
 help / color / mirror / Atom feed
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
>

  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.