diff options
author | Luka Perkov <luka@openwrt.org> | 2015-04-11 10:28:14 +0000 |
---|---|---|
committer | Luka Perkov <luka@openwrt.org> | 2015-04-11 10:28:14 +0000 |
commit | 88655056656fdbd9d021d8de11a6077fb49428da (patch) | |
tree | d3b641c3c5876ee5e79c67034a95a8fd532a4077 /target/linux/generic/patches-3.14/645-bridge_multicast_to_unicast.patch | |
parent | b66b0ae6323fea7dedd400785c556a39a30cdf4f (diff) | |
download | upstream-88655056656fdbd9d021d8de11a6077fb49428da.tar.gz upstream-88655056656fdbd9d021d8de11a6077fb49428da.tar.bz2 upstream-88655056656fdbd9d021d8de11a6077fb49428da.zip |
generic: drop 3.14
Signed-off-by: Luka Perkov <luka@openwrt.org>
SVN-Revision: 45375
Diffstat (limited to 'target/linux/generic/patches-3.14/645-bridge_multicast_to_unicast.patch')
-rw-r--r-- | target/linux/generic/patches-3.14/645-bridge_multicast_to_unicast.patch | 378 |
1 files changed, 0 insertions, 378 deletions
diff --git a/target/linux/generic/patches-3.14/645-bridge_multicast_to_unicast.patch b/target/linux/generic/patches-3.14/645-bridge_multicast_to_unicast.patch deleted file mode 100644 index 0f59ab5c70..0000000000 --- a/target/linux/generic/patches-3.14/645-bridge_multicast_to_unicast.patch +++ /dev/null @@ -1,378 +0,0 @@ ---- a/net/bridge/br_multicast.c -+++ b/net/bridge/br_multicast.c -@@ -634,7 +634,8 @@ struct net_bridge_port_group *br_multica - struct net_bridge_port *port, - struct br_ip *group, - struct net_bridge_port_group __rcu *next, -- unsigned char state) -+ unsigned char state, -+ const unsigned char *src) - { - struct net_bridge_port_group *p; - -@@ -649,12 +650,33 @@ struct net_bridge_port_group *br_multica - hlist_add_head(&p->mglist, &port->mglist); - setup_timer(&p->timer, br_multicast_port_group_expired, - (unsigned long)p); -+ if ((port->flags & BR_MULTICAST_TO_UCAST) && src) { -+ memcpy(p->eth_addr, src, ETH_ALEN); -+ p->unicast = true; -+ } - return p; - } - -+static bool br_port_group_equal(struct net_bridge_port_group *p, -+ struct net_bridge_port *port, -+ const unsigned char *src) -+{ -+ if (p->port != port) -+ return false; -+ -+ if (!p->unicast) -+ return true; -+ -+ if (!src) -+ return false; -+ -+ return ether_addr_equal(src, p->eth_addr); -+} -+ - static int br_multicast_add_group(struct net_bridge *br, - struct net_bridge_port *port, -- struct br_ip *group) -+ struct br_ip *group, -+ const unsigned char *src) - { - struct net_bridge_mdb_entry *mp; - struct net_bridge_port_group *p; -@@ -681,13 +703,13 @@ static int br_multicast_add_group(struct - for (pp = &mp->ports; - (p = mlock_dereference(*pp, br)) != NULL; - pp = &p->next) { -- if (p->port == port) -+ if (br_port_group_equal(p, port, src)) - goto found; - if ((unsigned long)p->port < (unsigned long)port) - break; - } - -- p = br_multicast_new_port_group(port, group, *pp, MDB_TEMPORARY); -+ p = br_multicast_new_port_group(port, group, *pp, MDB_TEMPORARY, src); - if (unlikely(!p)) - goto err; - rcu_assign_pointer(*pp, p); -@@ -706,7 +728,7 @@ err: - static int br_ip4_multicast_add_group(struct net_bridge *br, - struct net_bridge_port *port, - __be32 group, -- __u16 vid) -+ __u16 vid, const unsigned char *src) - { - struct br_ip br_group; - -@@ -717,14 +739,14 @@ static int br_ip4_multicast_add_group(st - br_group.proto = htons(ETH_P_IP); - br_group.vid = vid; - -- return br_multicast_add_group(br, port, &br_group); -+ return br_multicast_add_group(br, port, &br_group, src); - } - - #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, -- __u16 vid) -+ __u16 vid, const unsigned char *src) - { - struct br_ip br_group; - -@@ -735,7 +757,10 @@ static int br_ip6_multicast_add_group(st - br_group.proto = htons(ETH_P_IPV6); - br_group.vid = vid; - -- return br_multicast_add_group(br, port, &br_group); -+ if (ipv6_addr_is_solict_mult(group)) -+ src = NULL; -+ -+ return br_multicast_add_group(br, port, &br_group, src); - } - #endif - -@@ -950,6 +975,7 @@ static int br_ip4_multicast_igmp3_report - struct sk_buff *skb, - u16 vid) - { -+ const unsigned char *src = eth_hdr(skb)->h_source; - struct igmpv3_report *ih; - struct igmpv3_grec *grec; - int i; -@@ -993,7 +1019,7 @@ static int br_ip4_multicast_igmp3_report - continue; - } - -- err = br_ip4_multicast_add_group(br, port, group, vid); -+ err = br_ip4_multicast_add_group(br, port, group, vid, src); - if (err) - break; - } -@@ -1007,6 +1033,7 @@ static int br_ip6_multicast_mld2_report( - struct sk_buff *skb, - u16 vid) - { -+ const unsigned char *src = eth_hdr(skb)->h_source; - struct icmp6hdr *icmp6h; - struct mld2_grec *grec; - int i; -@@ -1055,7 +1082,7 @@ static int br_ip6_multicast_mld2_report( - } - - err = br_ip6_multicast_add_group(br, port, &grec->grec_mca, -- vid); -+ vid, src); - if (!err) - break; - } -@@ -1319,7 +1346,8 @@ static void br_multicast_leave_group(str - struct net_bridge_port *port, - struct br_ip *group, - struct bridge_mcast_querier *querier, -- struct bridge_mcast_query *query) -+ struct bridge_mcast_query *query, -+ const unsigned char *src) - { - struct net_bridge_mdb_htable *mdb; - struct net_bridge_mdb_entry *mp; -@@ -1369,7 +1397,7 @@ static void br_multicast_leave_group(str - for (pp = &mp->ports; - (p = mlock_dereference(*pp, br)) != NULL; - pp = &p->next) { -- if (p->port != port) -+ if (!br_port_group_equal(p, port, src)) - continue; - - rcu_assign_pointer(*pp, p->next); -@@ -1403,7 +1431,7 @@ static void br_multicast_leave_group(str - for (p = mlock_dereference(mp->ports, br); - p != NULL; - p = mlock_dereference(p->next, br)) { -- if (p->port != port) -+ if (!br_port_group_equal(p, port, src)) - continue; - - if (!hlist_unhashed(&p->mglist) && -@@ -1421,8 +1449,8 @@ out: - - static void br_ip4_multicast_leave_group(struct net_bridge *br, - struct net_bridge_port *port, -- __be32 group, -- __u16 vid) -+ __be32 group, __u16 vid, -+ const unsigned char *src) - { - struct br_ip br_group; - struct bridge_mcast_query *query = port ? &port->ip4_query : -@@ -1435,14 +1463,15 @@ static void br_ip4_multicast_leave_group - br_group.proto = htons(ETH_P_IP); - br_group.vid = vid; - -- br_multicast_leave_group(br, port, &br_group, &br->ip4_querier, query); -+ br_multicast_leave_group(br, port, &br_group, &br->ip4_querier, query, -+ src); - } - - #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, -- __u16 vid) -+ __u16 vid, const unsigned char *src) - { - struct br_ip br_group; - struct bridge_mcast_query *query = port ? &port->ip6_query : -@@ -1456,7 +1485,8 @@ static void br_ip6_multicast_leave_group - br_group.proto = htons(ETH_P_IPV6); - br_group.vid = vid; - -- br_multicast_leave_group(br, port, &br_group, &br->ip6_querier, query); -+ br_multicast_leave_group(br, port, &br_group, &br->ip6_querier, query, -+ src); - } - #endif - -@@ -1465,6 +1495,7 @@ static int br_multicast_ipv4_rcv(struct - struct sk_buff *skb, - u16 vid) - { -+ const unsigned char *src = eth_hdr(skb)->h_source; - struct sk_buff *skb2 = skb; - const struct iphdr *iph; - struct igmphdr *ih; -@@ -1538,7 +1569,7 @@ static int br_multicast_ipv4_rcv(struct - 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, vid); -+ err = br_ip4_multicast_add_group(br, port, ih->group, vid, src); - break; - case IGMPV3_HOST_MEMBERSHIP_REPORT: - err = br_ip4_multicast_igmp3_report(br, port, skb2, vid); -@@ -1547,7 +1578,7 @@ static int br_multicast_ipv4_rcv(struct - err = br_ip4_multicast_query(br, port, skb2, vid); - break; - case IGMP_HOST_LEAVE_MESSAGE: -- br_ip4_multicast_leave_group(br, port, ih->group, vid); -+ br_ip4_multicast_leave_group(br, port, ih->group, vid, src); - break; - } - -@@ -1565,6 +1596,7 @@ static int br_multicast_ipv6_rcv(struct - struct sk_buff *skb, - u16 vid) - { -+ const unsigned char *src = eth_hdr(skb)->h_source; - struct sk_buff *skb2; - const struct ipv6hdr *ip6h; - u8 icmp6_type; -@@ -1674,7 +1706,8 @@ static int br_multicast_ipv6_rcv(struct - } - 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, vid); -+ err = br_ip6_multicast_add_group(br, port, &mld->mld_mca, vid, -+ src); - break; - } - case ICMPV6_MLD2_REPORT: -@@ -1691,7 +1724,7 @@ static int br_multicast_ipv6_rcv(struct - goto out; - } - mld = (struct mld_msg *)skb_transport_header(skb2); -- br_ip6_multicast_leave_group(br, port, &mld->mld_mca, vid); -+ br_ip6_multicast_leave_group(br, port, &mld->mld_mca, vid, src); - } - } - ---- a/net/bridge/br_private.h -+++ b/net/bridge/br_private.h -@@ -116,6 +116,9 @@ struct net_bridge_port_group { - struct timer_list timer; - struct br_ip addr; - unsigned char state; -+ -+ unsigned char eth_addr[ETH_ALEN]; -+ bool unicast; - }; - - struct net_bridge_mdb_entry -@@ -175,6 +178,7 @@ struct net_bridge_port - #define BR_LEARNING 0x00000020 - #define BR_FLOOD 0x00000040 - #define BR_ISOLATE_MODE 0x00000080 -+#define BR_MULTICAST_TO_UCAST 0x00000100 - - #ifdef CONFIG_BRIDGE_IGMP_SNOOPING - struct bridge_mcast_query ip4_query; -@@ -471,7 +475,8 @@ void br_multicast_free_pg(struct rcu_hea - struct net_bridge_port_group * - br_multicast_new_port_group(struct net_bridge_port *port, struct br_ip *group, - struct net_bridge_port_group __rcu *next, -- unsigned char state); -+ unsigned char state, -+ const unsigned char *src); - void br_mdb_init(void); - void br_mdb_uninit(void); - void br_mdb_notify(struct net_device *dev, struct net_bridge_port *port, ---- a/net/bridge/br_mdb.c -+++ b/net/bridge/br_mdb.c -@@ -342,7 +342,7 @@ static int br_mdb_add_group(struct net_b - break; - } - -- p = br_multicast_new_port_group(port, group, *pp, state); -+ p = br_multicast_new_port_group(port, group, *pp, state, NULL); - if (unlikely(!p)) - return -ENOMEM; - rcu_assign_pointer(*pp, p); ---- a/net/bridge/br_forward.c -+++ b/net/bridge/br_forward.c -@@ -170,6 +170,29 @@ out: - return p; - } - -+static struct net_bridge_port *maybe_deliver_addr( -+ struct net_bridge_port *prev, struct net_bridge_port *p, -+ struct sk_buff *skb, const unsigned char *addr, -+ void (*__packet_hook)(const struct net_bridge_port *p, -+ struct sk_buff *skb)) -+{ -+ struct net_device *dev = BR_INPUT_SKB_CB(skb)->brdev; -+ -+ if (!should_deliver(p, skb)) -+ return prev; -+ -+ skb = skb_copy(skb, GFP_ATOMIC); -+ if (!skb) { -+ dev->stats.tx_dropped++; -+ return prev; -+ } -+ -+ memcpy(eth_hdr(skb)->h_dest, addr, ETH_ALEN); -+ __packet_hook(p, skb); -+ -+ return prev; -+} -+ - /* called under bridge lock */ - static void br_flood(struct net_bridge *br, struct sk_buff *skb, - struct sk_buff *skb0, -@@ -234,6 +257,7 @@ static void br_multicast_flood(struct ne - struct net_bridge_port *prev = NULL; - struct net_bridge_port_group *p; - struct hlist_node *rp; -+ const unsigned char *addr; - - rp = rcu_dereference(hlist_first_rcu(&br->router_list)); - p = mdst ? rcu_dereference(mdst->ports) : NULL; -@@ -244,10 +268,19 @@ static void br_multicast_flood(struct ne - rport = rp ? hlist_entry(rp, struct net_bridge_port, rlist) : - NULL; - -- port = (unsigned long)lport > (unsigned long)rport ? -- lport : rport; -- -- prev = maybe_deliver(prev, port, skb, __packet_hook); -+ if ((unsigned long)lport > (unsigned long)rport) { -+ port = lport; -+ addr = p->unicast ? p->eth_addr : NULL; -+ } else { -+ port = rport; -+ addr = NULL; -+ } -+ -+ if (addr) -+ prev = maybe_deliver_addr(prev, port, skb, addr, -+ __packet_hook); -+ else -+ prev = maybe_deliver(prev, port, skb, __packet_hook); - if (IS_ERR(prev)) - goto out; - ---- a/net/bridge/br_sysfs_if.c -+++ b/net/bridge/br_sysfs_if.c -@@ -192,6 +192,7 @@ static BRPORT_ATTR(multicast_router, S_I - store_multicast_router); - - BRPORT_ATTR_FLAG(multicast_fast_leave, BR_MULTICAST_FAST_LEAVE); -+BRPORT_ATTR_FLAG(multicast_to_unicast, BR_MULTICAST_TO_UCAST); - #endif - - static const struct brport_attribute *brport_attrs[] = { -@@ -218,6 +219,7 @@ static const struct brport_attribute *br - #ifdef CONFIG_BRIDGE_IGMP_SNOOPING - &brport_attr_multicast_router, - &brport_attr_multicast_fast_leave, -+ &brport_attr_multicast_to_unicast, - #endif - &brport_attr_isolate_mode, - NULL |