From: Vlad Yasevich <vyasevic@redhat.com>
To: netdev@vger.kernel.org
Cc: bridge@lists.linux-foundation.org, davem@davemloft.net,
shemminger@vyatta.com, mst@redhat.com, shmulik.ladkani@gmail.com
Subject: [PATCH net-next V6 11/14] bridge: Add vlan id to multicast groups
Date: Wed, 16 Jan 2013 13:18:06 -0500 [thread overview]
Message-ID: <1358360289-23249-12-git-send-email-vyasevic@redhat.com> (raw)
In-Reply-To: <1358360289-23249-1-git-send-email-vyasevic@redhat.com>
Add vlan_id to multicasts groups so that we know which vlan
each group belongs to and can correctly forward to appropriate vlan.
Signed-off-by: Vlad Yasevich <vyasevic@redhat.com>
---
net/bridge/br_multicast.c | 69 ++++++++++++++++++++++++++++++++-------------
net/bridge/br_private.h | 1 +
2 files changed, 50 insertions(+), 20 deletions(-)
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c
index 5391ca4..b3e3289 100644
--- a/net/bridge/br_multicast.c
+++ b/net/bridge/br_multicast.c
@@ -39,6 +39,8 @@ static inline int br_ip_equal(const struct br_ip *a, const struct br_ip *b)
{
if (a->proto != b->proto)
return 0;
+ if (a->vid != b->vid)
+ return 0;
switch (a->proto) {
case htons(ETH_P_IP):
return a->u.ip4 == b->u.ip4;
@@ -50,16 +52,19 @@ static inline int br_ip_equal(const struct br_ip *a, const struct br_ip *b)
return 0;
}
-static inline int __br_ip4_hash(struct net_bridge_mdb_htable *mdb, __be32 ip)
+static inline int __br_ip4_hash(struct net_bridge_mdb_htable *mdb, __be32 ip,
+ __u16 vid)
{
- return jhash_1word(mdb->secret, (__force u32)ip) & (mdb->max - 1);
+ return jhash_2words((__force u32)ip, vid, mdb->secret) & (mdb->max - 1);
}
#if IS_ENABLED(CONFIG_IPV6)
static inline int __br_ip6_hash(struct net_bridge_mdb_htable *mdb,
- const struct in6_addr *ip)
+ const struct in6_addr *ip,
+ __u16 vid)
{
- return jhash2((__force u32 *)ip->s6_addr32, 4, mdb->secret) & (mdb->max - 1);
+ return jhash_2words(ipv6_addr_hash(ip), vid,
+ mdb->secret) & (mdb->max - 1);
}
#endif
@@ -68,10 +73,10 @@ static inline int br_ip_hash(struct net_bridge_mdb_htable *mdb,
{
switch (ip->proto) {
case htons(ETH_P_IP):
- return __br_ip4_hash(mdb, ip->u.ip4);
+ return __br_ip4_hash(mdb, ip->u.ip4, ip->vid);
#if IS_ENABLED(CONFIG_IPV6)
case htons(ETH_P_IPV6):
- return __br_ip6_hash(mdb, &ip->u.ip6);
+ return __br_ip6_hash(mdb, &ip->u.ip6, ip->vid);
#endif
}
return 0;
@@ -101,24 +106,27 @@ struct net_bridge_mdb_entry *br_mdb_ip_get(struct net_bridge_mdb_htable *mdb,
}
static struct net_bridge_mdb_entry *br_mdb_ip4_get(
- struct net_bridge_mdb_htable *mdb, __be32 dst)
+ struct net_bridge_mdb_htable *mdb, __be32 dst, __u16 vid)
{
struct br_ip br_dst;
br_dst.u.ip4 = dst;
br_dst.proto = htons(ETH_P_IP);
+ br_dst.vid = vid;
return br_mdb_ip_get(mdb, &br_dst);
}
#if IS_ENABLED(CONFIG_IPV6)
static struct net_bridge_mdb_entry *br_mdb_ip6_get(
- struct net_bridge_mdb_htable *mdb, const struct in6_addr *dst)
+ struct net_bridge_mdb_htable *mdb, const struct in6_addr *dst,
+ __u16 vid)
{
struct br_ip br_dst;
br_dst.u.ip6 = *dst;
br_dst.proto = htons(ETH_P_IPV6);
+ br_dst.vid = vid;
return br_mdb_ip_get(mdb, &br_dst);
}
@@ -694,7 +702,8 @@ err:
static int br_ip4_multicast_add_group(struct net_bridge *br,
struct net_bridge_port *port,
- __be32 group)
+ __be32 group,
+ __u16 vid)
{
struct br_ip br_group;
@@ -703,6 +712,7 @@ static int br_ip4_multicast_add_group(struct net_bridge *br,
br_group.u.ip4 = group;
br_group.proto = htons(ETH_P_IP);
+ br_group.vid = vid;
return br_multicast_add_group(br, port, &br_group);
}
@@ -710,7 +720,8 @@ static int br_ip4_multicast_add_group(struct net_bridge *br,
#if IS_ENABLED(CONFIG_IPV6)
static int br_ip6_multicast_add_group(struct net_bridge *br,
struct net_bridge_port *port,
- const struct in6_addr *group)
+ const struct in6_addr *group,
+ __u16 vid)
{
struct br_ip br_group;
@@ -719,6 +730,7 @@ static int br_ip6_multicast_add_group(struct net_bridge *br,
br_group.u.ip6 = *group;
br_group.proto = htons(ETH_P_IPV6);
+ br_group.vid = vid;
return br_multicast_add_group(br, port, &br_group);
}
@@ -895,10 +907,12 @@ static int br_ip4_multicast_igmp3_report(struct net_bridge *br,
int type;
int err = 0;
__be32 group;
+ u16 vid = 0;
if (!pskb_may_pull(skb, sizeof(*ih)))
return -EINVAL;
+ br_get_vlan(skb, &vid);
ih = igmpv3_report_hdr(skb);
num = ntohs(ih->ngrec);
len = sizeof(*ih);
@@ -930,7 +944,7 @@ static int br_ip4_multicast_igmp3_report(struct net_bridge *br,
continue;
}
- err = br_ip4_multicast_add_group(br, port, group);
+ err = br_ip4_multicast_add_group(br, port, group, vid);
if (err)
break;
}
@@ -949,10 +963,12 @@ static int br_ip6_multicast_mld2_report(struct net_bridge *br,
int len;
int num;
int err = 0;
+ u16 vid = 0;
if (!pskb_may_pull(skb, sizeof(*icmp6h)))
return -EINVAL;
+ br_get_vlan(skb, &vid);
icmp6h = icmp6_hdr(skb);
num = ntohs(icmp6h->icmp6_dataun.un_data16[1]);
len = sizeof(*icmp6h);
@@ -990,7 +1006,8 @@ static int br_ip6_multicast_mld2_report(struct net_bridge *br,
continue;
}
- err = br_ip6_multicast_add_group(br, port, &grec->grec_mca);
+ err = br_ip6_multicast_add_group(br, port, &grec->grec_mca,
+ vid);
if (!err)
break;
}
@@ -1074,6 +1091,7 @@ static int br_ip4_multicast_query(struct net_bridge *br,
unsigned long now = jiffies;
__be32 group;
int err = 0;
+ u16 vid = 0;
spin_lock(&br->multicast_lock);
if (!netif_running(br->dev) ||
@@ -1108,7 +1126,8 @@ static int br_ip4_multicast_query(struct net_bridge *br,
if (!group)
goto out;
- mp = br_mdb_ip4_get(mlock_dereference(br->mdb, br), group);
+ br_get_vlan(skb, &vid);
+ mp = br_mdb_ip4_get(mlock_dereference(br->mdb, br), group, vid);
if (!mp)
goto out;
@@ -1149,6 +1168,7 @@ static int br_ip6_multicast_query(struct net_bridge *br,
unsigned long now = jiffies;
const struct in6_addr *group = NULL;
int err = 0;
+ u16 vid = 0;
spin_lock(&br->multicast_lock);
if (!netif_running(br->dev) ||
@@ -1180,7 +1200,8 @@ static int br_ip6_multicast_query(struct net_bridge *br,
if (!group)
goto out;
- mp = br_mdb_ip6_get(mlock_dereference(br->mdb, br), group);
+ br_get_vlan(skb, &vid);
+ mp = br_mdb_ip6_get(mlock_dereference(br->mdb, br), group, vid);
if (!mp)
goto out;
@@ -1286,7 +1307,8 @@ out:
static void br_ip4_multicast_leave_group(struct net_bridge *br,
struct net_bridge_port *port,
- __be32 group)
+ __be32 group,
+ __u16 vid)
{
struct br_ip br_group;
@@ -1295,6 +1317,7 @@ static void br_ip4_multicast_leave_group(struct net_bridge *br,
br_group.u.ip4 = group;
br_group.proto = htons(ETH_P_IP);
+ br_group.vid = vid;
br_multicast_leave_group(br, port, &br_group);
}
@@ -1302,7 +1325,8 @@ static void br_ip4_multicast_leave_group(struct net_bridge *br,
#if IS_ENABLED(CONFIG_IPV6)
static void br_ip6_multicast_leave_group(struct net_bridge *br,
struct net_bridge_port *port,
- const struct in6_addr *group)
+ const struct in6_addr *group,
+ __u16 vid)
{
struct br_ip br_group;
@@ -1311,6 +1335,7 @@ static void br_ip6_multicast_leave_group(struct net_bridge *br,
br_group.u.ip6 = *group;
br_group.proto = htons(ETH_P_IPV6);
+ br_group.vid = vid;
br_multicast_leave_group(br, port, &br_group);
}
@@ -1326,6 +1351,7 @@ static int br_multicast_ipv4_rcv(struct net_bridge *br,
unsigned int len;
unsigned int offset;
int err;
+ u16 vid = 0;
/* We treat OOM as packet loss for now. */
if (!pskb_may_pull(skb, sizeof(*iph)))
@@ -1386,6 +1412,7 @@ static int br_multicast_ipv4_rcv(struct net_bridge *br,
err = 0;
+ br_get_vlan(skb2, &vid);
BR_INPUT_SKB_CB(skb)->igmp = 1;
ih = igmp_hdr(skb2);
@@ -1393,7 +1420,7 @@ static int br_multicast_ipv4_rcv(struct net_bridge *br,
case IGMP_HOST_MEMBERSHIP_REPORT:
case IGMPV2_HOST_MEMBERSHIP_REPORT:
BR_INPUT_SKB_CB(skb)->mrouters_only = 1;
- err = br_ip4_multicast_add_group(br, port, ih->group);
+ err = br_ip4_multicast_add_group(br, port, ih->group, vid);
break;
case IGMPV3_HOST_MEMBERSHIP_REPORT:
err = br_ip4_multicast_igmp3_report(br, port, skb2);
@@ -1402,7 +1429,7 @@ static int br_multicast_ipv4_rcv(struct net_bridge *br,
err = br_ip4_multicast_query(br, port, skb2);
break;
case IGMP_HOST_LEAVE_MESSAGE:
- br_ip4_multicast_leave_group(br, port, ih->group);
+ br_ip4_multicast_leave_group(br, port, ih->group, vid);
break;
}
@@ -1427,6 +1454,7 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br,
unsigned int len;
int offset;
int err;
+ u16 vid = 0;
if (!pskb_may_pull(skb, sizeof(*ip6h)))
return -EINVAL;
@@ -1510,6 +1538,7 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br,
err = 0;
+ br_get_vlan(skb, &vid);
BR_INPUT_SKB_CB(skb)->igmp = 1;
switch (icmp6_type) {
@@ -1522,7 +1551,7 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br,
}
mld = (struct mld_msg *)skb_transport_header(skb2);
BR_INPUT_SKB_CB(skb)->mrouters_only = 1;
- err = br_ip6_multicast_add_group(br, port, &mld->mld_mca);
+ err = br_ip6_multicast_add_group(br, port, &mld->mld_mca, vid);
break;
}
case ICMPV6_MLD2_REPORT:
@@ -1539,7 +1568,7 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br,
goto out;
}
mld = (struct mld_msg *)skb_transport_header(skb2);
- br_ip6_multicast_leave_group(br, port, &mld->mld_mca);
+ br_ip6_multicast_leave_group(br, port, &mld->mld_mca, vid);
}
}
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index 8a30c03..908a72a 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -63,6 +63,7 @@ struct br_ip
#endif
} u;
__be16 proto;
+ __u16 vid;
};
#define BR_INVALID_VID (1<<15)
--
1.7.7.6
next prev parent reply other threads:[~2013-01-16 18:18 UTC|newest]
Thread overview: 34+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-01-16 18:17 [PATCH net-next V6 00/14] Add basic VLAN support to bridges Vlad Yasevich
2013-01-16 18:17 ` [PATCH net-next V6 01/14] vlan: wrap hw-acceleration calls in separate functions Vlad Yasevich
2013-01-16 22:00 ` Michał Mirosław
2013-01-16 22:03 ` Michał Mirosław
2013-01-16 18:17 ` [PATCH net-next V6 02/14] bridge: Add vlan filtering infrastructure Vlad Yasevich
2013-01-17 4:47 ` Cong Wang
2013-01-18 1:57 ` Michał Mirosław
2013-01-20 17:59 ` Vlad Yasevich
2013-01-20 19:38 ` Stephen Hemminger
2013-01-21 1:50 ` Vlad Yasevich
2013-01-21 11:45 ` Shmulik Ladkani
2013-01-22 14:31 ` Vlad Yasevich
2013-01-22 15:55 ` Shmulik Ladkani
2013-01-22 16:27 ` Vlad Yasevich
[not found] ` <CB4696DA7737D0409230B481D0363B1414F0E6029D@HQ1-EXCH03.corp.brocade.com>
[not found] ` <20130122091746.7a3820e9@nehalam.linuxnetplumber.net>
2013-01-22 17:32 ` Vlad Yasevich
2013-01-20 21:38 ` Shmulik Ladkani
2013-01-21 1:56 ` Vlad Yasevich
2013-01-16 18:17 ` [PATCH net-next V6 03/14] bridge: Validate that vlan is permitted on ingress Vlad Yasevich
2013-01-20 22:27 ` Shmulik Ladkani
2013-01-21 1:58 ` Vlad Yasevich
2013-01-16 18:17 ` [PATCH net-next V6 04/14] bridge: Verify that a vlan is allowed to egress on give port Vlad Yasevich
2013-01-16 18:18 ` [PATCH net-next V6 05/14] bridge: Cache vlan in the cb for faster egress lookup Vlad Yasevich
2013-01-16 18:18 ` [PATCH net-next V6 06/14] bridge: Add netlink interface to configure vlans on bridge ports Vlad Yasevich
2013-01-17 4:54 ` Cong Wang
2013-01-17 5:52 ` David Miller
2013-01-16 18:18 ` [PATCH net-next V6 07/14] bridge: Add the ability to configure pvid Vlad Yasevich
2013-01-16 18:18 ` [PATCH net-next V6 08/14] bridge: Implement vlan ingress/egress policy Vlad Yasevich
2013-01-16 18:18 ` [PATCH net-next V6 09/14] bridge: API to configure egress policy Vlad Yasevich
2013-01-16 18:18 ` [PATCH net-next V6 10/14] bridge: Add vlan to unicast fdb entries Vlad Yasevich
2013-01-16 18:18 ` Vlad Yasevich [this message]
2013-01-16 18:18 ` [PATCH net-next V6 12/14] bridge: Add vlan support to static neighbors Vlad Yasevich
2013-01-17 5:16 ` Cong Wang
2013-01-16 18:18 ` [PATCH net-next V6 13/14] bridge: Add vlan support for local fdb entries Vlad Yasevich
2013-01-16 18:18 ` [PATCH net-next V6 14/14] bridge: Dump vlan information from a bridge port 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=1358360289-23249-12-git-send-email-vyasevic@redhat.com \
--to=vyasevic@redhat.com \
--cc=bridge@lists.linux-foundation.org \
--cc=davem@davemloft.net \
--cc=mst@redhat.com \
--cc=netdev@vger.kernel.org \
--cc=shemminger@vyatta.com \
--cc=shmulik.ladkani@gmail.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).