From: Vlad Yasevich <vyasevic@redhat.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] bridge: Prevent insertion of FDB entry with disallowed vlan
Date: Wed, 28 May 2014 10:02:05 -0400 [thread overview]
Message-ID: <5385EC5D.40106@redhat.com> (raw)
In-Reply-To: <1401084953-10135-1-git-send-email-makita.toshiaki@lab.ntt.co.jp>
On 05/26/2014 02:15 AM, Toshiaki Makita wrote:
> br_handle_local_finish() is allowing us to insert an FDB entry with
> disallowed vlan. For example, when port 1 and 2 are communicating in
> vlan 10, and even if vlan 10 is disallowed on port 3, port 3 can
> interfere with their communication by spoofed src mac address with
> vlan id 10.
>
> Note: Even if it is judged that a frame should not be learned, it should
> not be dropped because it is destined for not forwarding layer but higher
> layer. See IEEE 802.1Q-2011 8.13.10.
>
> Signed-off-by: Toshiaki Makita <makita.toshiaki@lab.ntt.co.jp>
> ---
> net/bridge/br_input.c | 4 ++--
> net/bridge/br_private.h | 7 +++++++
> net/bridge/br_vlan.c | 28 ++++++++++++++++++++++++++++
> 3 files changed, 37 insertions(+), 2 deletions(-)
>
> diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c
> index 7985dea..04d6348 100644
> --- a/net/bridge/br_input.c
> +++ b/net/bridge/br_input.c
> @@ -147,8 +147,8 @@ static int br_handle_local_finish(struct sk_buff *skb)
> struct net_bridge_port *p = br_port_get_rcu(skb->dev);
> u16 vid = 0;
>
> - br_vlan_get_tag(skb, &vid);
> - if (p->flags & BR_LEARNING)
> + /* check if vlan is allowed, to avoid spoofing */
> + if (p->flags & BR_LEARNING && br_should_learn(p, skb, &vid))
> br_fdb_update(p->br, p, eth_hdr(skb)->h_source, vid, false);
> return 0; /* process further */
> }
> diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
> index 06811d7..59d3a85 100644
> --- a/net/bridge/br_private.h
> +++ b/net/bridge/br_private.h
> @@ -581,6 +581,7 @@ bool br_allowed_ingress(struct net_bridge *br, struct net_port_vlans *v,
> struct sk_buff *skb, u16 *vid);
> bool br_allowed_egress(struct net_bridge *br, const struct net_port_vlans *v,
> const struct sk_buff *skb);
> +bool br_should_learn(struct net_bridge_port *p, struct sk_buff *skb, u16 *vid);
> struct sk_buff *br_handle_vlan(struct net_bridge *br,
> const struct net_port_vlans *v,
> struct sk_buff *skb);
> @@ -648,6 +649,12 @@ static inline bool br_allowed_egress(struct net_bridge *br,
> return true;
> }
>
> +static inline bool br_should_learn(struct net_bridge_port *p,
> + struct sk_buff *skb, u16 *vid)
> +{
> + return true;
> +}
> +
> static inline struct sk_buff *br_handle_vlan(struct net_bridge *br,
> const struct net_port_vlans *v,
> struct sk_buff *skb)
> diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c
> index 4a37161..5fee2fe 100644
> --- a/net/bridge/br_vlan.c
> +++ b/net/bridge/br_vlan.c
> @@ -241,6 +241,34 @@ bool br_allowed_egress(struct net_bridge *br,
> return false;
> }
>
> +/* Called under RCU */
> +bool br_should_learn(struct net_bridge_port *p, struct sk_buff *skb, u16 *vid)
> +{
> + struct net_bridge *br = p->br;
> + struct net_port_vlans *v;
> +
> + if (!br->vlan_enabled)
> + return true;
> +
> + v = rcu_dereference(p->vlan_info);
> + if (!v)
> + return false;
> +
> + br_vlan_get_tag(skb, vid);
> + if (!*vid) {
> + *vid = br_get_pvid(v);
> + if (*vid == VLAN_N_VID)
> + return false;
> +
> + return true;
> + }
> +
> + if (test_bit(*vid, v->vlan_bitmap))
> + return true;
> +
> + return false;
> +}
> +
> /* Must be protected by RTNL.
> * Must be called with vid in range from 1 to 4094 inclusive.
> */
>
This is very similar to br_allow_ingress(), so may be you can
re-factor so that we only have 1 such function...
-vlad
WARNING: multiple messages have this Message-ID (diff)
From: Vlad Yasevich <vyasevic@redhat.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] bridge: Prevent insertion of FDB entry with disallowed vlan
Date: Wed, 28 May 2014 10:02:05 -0400 [thread overview]
Message-ID: <5385EC5D.40106@redhat.com> (raw)
In-Reply-To: <1401084953-10135-1-git-send-email-makita.toshiaki@lab.ntt.co.jp>
On 05/26/2014 02:15 AM, Toshiaki Makita wrote:
> br_handle_local_finish() is allowing us to insert an FDB entry with
> disallowed vlan. For example, when port 1 and 2 are communicating in
> vlan 10, and even if vlan 10 is disallowed on port 3, port 3 can
> interfere with their communication by spoofed src mac address with
> vlan id 10.
>
> Note: Even if it is judged that a frame should not be learned, it should
> not be dropped because it is destined for not forwarding layer but higher
> layer. See IEEE 802.1Q-2011 8.13.10.
>
> Signed-off-by: Toshiaki Makita <makita.toshiaki@lab.ntt.co.jp>
> ---
> net/bridge/br_input.c | 4 ++--
> net/bridge/br_private.h | 7 +++++++
> net/bridge/br_vlan.c | 28 ++++++++++++++++++++++++++++
> 3 files changed, 37 insertions(+), 2 deletions(-)
>
> diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c
> index 7985dea..04d6348 100644
> --- a/net/bridge/br_input.c
> +++ b/net/bridge/br_input.c
> @@ -147,8 +147,8 @@ static int br_handle_local_finish(struct sk_buff *skb)
> struct net_bridge_port *p = br_port_get_rcu(skb->dev);
> u16 vid = 0;
>
> - br_vlan_get_tag(skb, &vid);
> - if (p->flags & BR_LEARNING)
> + /* check if vlan is allowed, to avoid spoofing */
> + if (p->flags & BR_LEARNING && br_should_learn(p, skb, &vid))
> br_fdb_update(p->br, p, eth_hdr(skb)->h_source, vid, false);
> return 0; /* process further */
> }
> diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
> index 06811d7..59d3a85 100644
> --- a/net/bridge/br_private.h
> +++ b/net/bridge/br_private.h
> @@ -581,6 +581,7 @@ bool br_allowed_ingress(struct net_bridge *br, struct net_port_vlans *v,
> struct sk_buff *skb, u16 *vid);
> bool br_allowed_egress(struct net_bridge *br, const struct net_port_vlans *v,
> const struct sk_buff *skb);
> +bool br_should_learn(struct net_bridge_port *p, struct sk_buff *skb, u16 *vid);
> struct sk_buff *br_handle_vlan(struct net_bridge *br,
> const struct net_port_vlans *v,
> struct sk_buff *skb);
> @@ -648,6 +649,12 @@ static inline bool br_allowed_egress(struct net_bridge *br,
> return true;
> }
>
> +static inline bool br_should_learn(struct net_bridge_port *p,
> + struct sk_buff *skb, u16 *vid)
> +{
> + return true;
> +}
> +
> static inline struct sk_buff *br_handle_vlan(struct net_bridge *br,
> const struct net_port_vlans *v,
> struct sk_buff *skb)
> diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c
> index 4a37161..5fee2fe 100644
> --- a/net/bridge/br_vlan.c
> +++ b/net/bridge/br_vlan.c
> @@ -241,6 +241,34 @@ bool br_allowed_egress(struct net_bridge *br,
> return false;
> }
>
> +/* Called under RCU */
> +bool br_should_learn(struct net_bridge_port *p, struct sk_buff *skb, u16 *vid)
> +{
> + struct net_bridge *br = p->br;
> + struct net_port_vlans *v;
> +
> + if (!br->vlan_enabled)
> + return true;
> +
> + v = rcu_dereference(p->vlan_info);
> + if (!v)
> + return false;
> +
> + br_vlan_get_tag(skb, vid);
> + if (!*vid) {
> + *vid = br_get_pvid(v);
> + if (*vid == VLAN_N_VID)
> + return false;
> +
> + return true;
> + }
> +
> + if (test_bit(*vid, v->vlan_bitmap))
> + return true;
> +
> + return false;
> +}
> +
> /* Must be protected by RTNL.
> * Must be called with vid in range from 1 to 4094 inclusive.
> */
>
This is very similar to br_allow_ingress(), so may be you can
re-factor so that we only have 1 such function...
-vlad
next prev parent reply other threads:[~2014-05-28 14:02 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-05-26 6:15 [Bridge] [PATCH net] bridge: Prevent insertion of FDB entry with disallowed vlan Toshiaki Makita
2014-05-26 6:15 ` Toshiaki Makita
2014-05-28 14:02 ` Vlad Yasevich [this message]
2014-05-28 14:02 ` Vlad Yasevich
2014-05-28 14:32 ` [Bridge] " Toshiaki Makita
2014-05-28 14:32 ` Toshiaki Makita
2014-05-30 22:48 ` David Miller
2014-05-30 22:48 ` David Miller
2014-06-02 14:22 ` [Bridge] " Vlad Yasevich
2014-06-02 14:22 ` Vlad Yasevich
2014-06-02 20:38 ` [Bridge] " David Miller
2014-06-02 20:38 ` David Miller
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=5385EC5D.40106@redhat.com \
--to=vyasevic@redhat.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.