aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJo-Philipp Wich <jow@openwrt.org>2011-06-19 22:48:53 +0000
committerJo-Philipp Wich <jow@openwrt.org>2011-06-19 22:48:53 +0000
commit6f3abd061e00473f72b75d3056a63c3da0a4dffa (patch)
tree4081746685a3de2540a4f6dd3a529be156f1432a
parentd2e81efd809f4ce4976171edafb04db095787f56 (diff)
downloadupstream-6f3abd061e00473f72b75d3056a63c3da0a4dffa.tar.gz
upstream-6f3abd061e00473f72b75d3056a63c3da0a4dffa.tar.bz2
upstream-6f3abd061e00473f72b75d3056a63c3da0a4dffa.zip
[PATCH] generic: Remove IPv6 depependency of bridge in 2.6.38+
Since 2.6.38 the bridge module has a dependency to IPv6 if IPv6 is enabled. Since the IPv6 module isn't exactly lightweight and bridge also only needs a single function from IPv6, it's rather easy to create a common "lib" module with a RCU pointer to the actual implementation, if the IPv6 module is loaded (although slightly hackish). The codepath seems to be only taken when using IPv6, so there should be no negative side effects when IPv6 isn't loaded. I did not measure how big the performance impact is. Signed-off-by: Jonas Gorski <jonas.gorski+openwrt@gmail.com> git-svn-id: svn://svn.openwrt.org/openwrt/trunk@27237 3c298f89-4303-0410-b956-a3cf2f4a3e73
-rw-r--r--target/linux/generic/patches-2.6.38/643-bridge_remove_ipv6_dependency.patch101
-rw-r--r--target/linux/generic/patches-2.6.39/643-bridge_remove_ipv6_dependency.patch101
-rw-r--r--target/linux/generic/patches-3.0/643-bridge_remove_ipv6_dependency.patch101
3 files changed, 303 insertions, 0 deletions
diff --git a/target/linux/generic/patches-2.6.38/643-bridge_remove_ipv6_dependency.patch b/target/linux/generic/patches-2.6.38/643-bridge_remove_ipv6_dependency.patch
new file mode 100644
index 0000000000..7f4f7543e0
--- /dev/null
+++ b/target/linux/generic/patches-2.6.38/643-bridge_remove_ipv6_dependency.patch
@@ -0,0 +1,101 @@
+--- a/include/net/addrconf.h
++++ b/include/net/addrconf.h
+@@ -93,6 +93,12 @@ extern void addrconf_join_solict(struc
+ extern void addrconf_leave_solict(struct inet6_dev *idev,
+ struct in6_addr *addr);
+
++extern int (*ipv6_dev_get_saddr_hook)(struct net *net,
++ struct net_device *dev,
++ const struct in6_addr *daddr,
++ unsigned int srcprefs,
++ struct in6_addr *saddr);
++
+ static inline unsigned long addrconf_timeout_fixup(u32 timeout,
+ unsigned unit)
+ {
+--- a/net/bridge/Kconfig
++++ b/net/bridge/Kconfig
+@@ -6,7 +6,6 @@ config BRIDGE
+ tristate "802.1d Ethernet Bridging"
+ select LLC
+ select STP
+- depends on IPV6 || IPV6=n
+ ---help---
+ If you say Y here, then your Linux box will be able to act as an
+ Ethernet bridge, which means that the different Ethernet segments it
+--- a/net/ipv6/Makefile
++++ b/net/ipv6/Makefile
+@@ -40,3 +40,4 @@ obj-$(CONFIG_IPV6_TUNNEL) += ip6_tunnel.
+ obj-y += addrconf_core.o exthdrs_core.o
+
+ obj-$(subst m,y,$(CONFIG_IPV6)) += inet6_hashtables.o
++obj-$(subst m,y,$(CONFIG_IPV6)) += inet6_stubs.o
+--- a/net/ipv6/addrconf.c
++++ b/net/ipv6/addrconf.c
+@@ -1119,7 +1119,7 @@ out:
+ return ret;
+ }
+
+-int ipv6_dev_get_saddr(struct net *net, struct net_device *dst_dev,
++static int __ipv6_dev_get_saddr(struct net *net, struct net_device *dst_dev,
+ const struct in6_addr *daddr, unsigned int prefs,
+ struct in6_addr *saddr)
+ {
+@@ -1244,7 +1244,6 @@ try_nextdev:
+ in6_ifa_put(hiscore->ifa);
+ return 0;
+ }
+-EXPORT_SYMBOL(ipv6_dev_get_saddr);
+
+ int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *addr,
+ unsigned char banned_flags)
+@@ -4718,6 +4717,9 @@ int __init addrconf_init(void)
+
+ ipv6_addr_label_rtnl_register();
+
++ BUG_ON(ipv6_dev_get_saddr_hook != NULL);
++ rcu_assign_pointer(ipv6_dev_get_saddr_hook, __ipv6_dev_get_saddr);
++
+ return 0;
+ errout:
+ rtnl_af_unregister(&inet6_ops);
+@@ -4736,6 +4738,9 @@ void addrconf_cleanup(void)
+ struct net_device *dev;
+ int i;
+
++ rcu_assign_pointer(ipv6_dev_get_saddr_hook, NULL);
++ synchronize_rcu();
++
+ unregister_netdevice_notifier(&ipv6_dev_notf);
+ unregister_pernet_subsys(&addrconf_ops);
+ ipv6_addr_label_cleanup();
+--- /dev/null
++++ b/net/ipv6/inet6_stubs.c
+@@ -0,0 +1,27 @@
++/*
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation; either version
++ * 2 of the License, or (at your option) any later version.
++ */
++#include <net/ipv6.h>
++
++int (*ipv6_dev_get_saddr_hook)(struct net *net, struct net_device *dev,
++ const struct in6_addr *daddr, unsigned int srcprefs,
++ struct in6_addr *saddr);
++
++EXPORT_SYMBOL(ipv6_dev_get_saddr_hook);
++
++int ipv6_dev_get_saddr(struct net *net, struct net_device *dst_dev,
++ const struct in6_addr *daddr, unsigned int prefs,
++ struct in6_addr *saddr)
++{
++ typeof(ipv6_dev_get_saddr_hook) dev_get_saddr = rcu_dereference(ipv6_dev_get_saddr_hook);
++
++ if (dev_get_saddr)
++ return dev_get_saddr(net, dst_dev, daddr, prefs, saddr);
++
++ return -EADDRNOTAVAIL;
++}
++EXPORT_SYMBOL(ipv6_dev_get_saddr);
++
diff --git a/target/linux/generic/patches-2.6.39/643-bridge_remove_ipv6_dependency.patch b/target/linux/generic/patches-2.6.39/643-bridge_remove_ipv6_dependency.patch
new file mode 100644
index 0000000000..679561eb29
--- /dev/null
+++ b/target/linux/generic/patches-2.6.39/643-bridge_remove_ipv6_dependency.patch
@@ -0,0 +1,101 @@
+--- a/include/net/addrconf.h
++++ b/include/net/addrconf.h
+@@ -93,6 +93,12 @@ extern void addrconf_join_solict(struc
+ extern void addrconf_leave_solict(struct inet6_dev *idev,
+ struct in6_addr *addr);
+
++extern int (*ipv6_dev_get_saddr_hook)(struct net *net,
++ struct net_device *dev,
++ const struct in6_addr *daddr,
++ unsigned int srcprefs,
++ struct in6_addr *saddr);
++
+ static inline unsigned long addrconf_timeout_fixup(u32 timeout,
+ unsigned unit)
+ {
+--- a/net/bridge/Kconfig
++++ b/net/bridge/Kconfig
+@@ -6,7 +6,6 @@ config BRIDGE
+ tristate "802.1d Ethernet Bridging"
+ select LLC
+ select STP
+- depends on IPV6 || IPV6=n
+ ---help---
+ If you say Y here, then your Linux box will be able to act as an
+ Ethernet bridge, which means that the different Ethernet segments it
+--- a/net/ipv6/Makefile
++++ b/net/ipv6/Makefile
+@@ -40,3 +40,4 @@ obj-$(CONFIG_IPV6_TUNNEL) += ip6_tunnel.
+ obj-y += addrconf_core.o exthdrs_core.o
+
+ obj-$(subst m,y,$(CONFIG_IPV6)) += inet6_hashtables.o
++obj-$(subst m,y,$(CONFIG_IPV6)) += inet6_stubs.o
+--- a/net/ipv6/addrconf.c
++++ b/net/ipv6/addrconf.c
+@@ -1116,7 +1116,7 @@ out:
+ return ret;
+ }
+
+-int ipv6_dev_get_saddr(struct net *net, struct net_device *dst_dev,
++static int __ipv6_dev_get_saddr(struct net *net, struct net_device *dst_dev,
+ const struct in6_addr *daddr, unsigned int prefs,
+ struct in6_addr *saddr)
+ {
+@@ -1241,7 +1241,6 @@ try_nextdev:
+ in6_ifa_put(hiscore->ifa);
+ return 0;
+ }
+-EXPORT_SYMBOL(ipv6_dev_get_saddr);
+
+ int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *addr,
+ unsigned char banned_flags)
+@@ -4715,6 +4714,9 @@ int __init addrconf_init(void)
+
+ ipv6_addr_label_rtnl_register();
+
++ BUG_ON(ipv6_dev_get_saddr_hook != NULL);
++ rcu_assign_pointer(ipv6_dev_get_saddr_hook, __ipv6_dev_get_saddr);
++
+ return 0;
+ errout:
+ rtnl_af_unregister(&inet6_ops);
+@@ -4733,6 +4735,9 @@ void addrconf_cleanup(void)
+ struct net_device *dev;
+ int i;
+
++ rcu_assign_pointer(ipv6_dev_get_saddr_hook, NULL);
++ synchronize_rcu();
++
+ unregister_netdevice_notifier(&ipv6_dev_notf);
+ unregister_pernet_subsys(&addrconf_ops);
+ ipv6_addr_label_cleanup();
+--- /dev/null
++++ b/net/ipv6/inet6_stubs.c
+@@ -0,0 +1,27 @@
++/*
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation; either version
++ * 2 of the License, or (at your option) any later version.
++ */
++#include <net/ipv6.h>
++
++int (*ipv6_dev_get_saddr_hook)(struct net *net, struct net_device *dev,
++ const struct in6_addr *daddr, unsigned int srcprefs,
++ struct in6_addr *saddr);
++
++EXPORT_SYMBOL(ipv6_dev_get_saddr_hook);
++
++int ipv6_dev_get_saddr(struct net *net, struct net_device *dst_dev,
++ const struct in6_addr *daddr, unsigned int prefs,
++ struct in6_addr *saddr)
++{
++ typeof(ipv6_dev_get_saddr_hook) dev_get_saddr = rcu_dereference(ipv6_dev_get_saddr_hook);
++
++ if (dev_get_saddr)
++ return dev_get_saddr(net, dst_dev, daddr, prefs, saddr);
++
++ return -EADDRNOTAVAIL;
++}
++EXPORT_SYMBOL(ipv6_dev_get_saddr);
++
diff --git a/target/linux/generic/patches-3.0/643-bridge_remove_ipv6_dependency.patch b/target/linux/generic/patches-3.0/643-bridge_remove_ipv6_dependency.patch
new file mode 100644
index 0000000000..5eac489515
--- /dev/null
+++ b/target/linux/generic/patches-3.0/643-bridge_remove_ipv6_dependency.patch
@@ -0,0 +1,101 @@
+--- a/include/net/addrconf.h
++++ b/include/net/addrconf.h
+@@ -91,6 +91,12 @@ extern void addrconf_join_solict(struc
+ extern void addrconf_leave_solict(struct inet6_dev *idev,
+ const struct in6_addr *addr);
+
++extern int (*ipv6_dev_get_saddr_hook)(struct net *net,
++ struct net_device *dev,
++ const struct in6_addr *daddr,
++ unsigned int srcprefs,
++ struct in6_addr *saddr);
++
+ static inline unsigned long addrconf_timeout_fixup(u32 timeout,
+ unsigned unit)
+ {
+--- a/net/bridge/Kconfig
++++ b/net/bridge/Kconfig
+@@ -6,7 +6,6 @@ config BRIDGE
+ tristate "802.1d Ethernet Bridging"
+ select LLC
+ select STP
+- depends on IPV6 || IPV6=n
+ ---help---
+ If you say Y here, then your Linux box will be able to act as an
+ Ethernet bridge, which means that the different Ethernet segments it
+--- a/net/ipv6/Makefile
++++ b/net/ipv6/Makefile
+@@ -40,3 +40,4 @@ obj-$(CONFIG_IPV6_TUNNEL) += ip6_tunnel.
+ obj-y += addrconf_core.o exthdrs_core.o
+
+ obj-$(subst m,y,$(CONFIG_IPV6)) += inet6_hashtables.o
++obj-$(subst m,y,$(CONFIG_IPV6)) += inet6_stubs.o
+--- a/net/ipv6/addrconf.c
++++ b/net/ipv6/addrconf.c
+@@ -1106,7 +1106,7 @@ out:
+ return ret;
+ }
+
+-int ipv6_dev_get_saddr(struct net *net, struct net_device *dst_dev,
++static int __ipv6_dev_get_saddr(struct net *net, struct net_device *dst_dev,
+ const struct in6_addr *daddr, unsigned int prefs,
+ struct in6_addr *saddr)
+ {
+@@ -1231,7 +1231,6 @@ try_nextdev:
+ in6_ifa_put(hiscore->ifa);
+ return 0;
+ }
+-EXPORT_SYMBOL(ipv6_dev_get_saddr);
+
+ int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *addr,
+ unsigned char banned_flags)
+@@ -4705,6 +4704,9 @@ int __init addrconf_init(void)
+
+ ipv6_addr_label_rtnl_register();
+
++ BUG_ON(ipv6_dev_get_saddr_hook != NULL);
++ rcu_assign_pointer(ipv6_dev_get_saddr_hook, __ipv6_dev_get_saddr);
++
+ return 0;
+ errout:
+ rtnl_af_unregister(&inet6_ops);
+@@ -4723,6 +4725,9 @@ void addrconf_cleanup(void)
+ struct net_device *dev;
+ int i;
+
++ rcu_assign_pointer(ipv6_dev_get_saddr_hook, NULL);
++ synchronize_rcu();
++
+ unregister_netdevice_notifier(&ipv6_dev_notf);
+ unregister_pernet_subsys(&addrconf_ops);
+ ipv6_addr_label_cleanup();
+--- /dev/null
++++ b/net/ipv6/inet6_stubs.c
+@@ -0,0 +1,27 @@
++/*
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation; either version
++ * 2 of the License, or (at your option) any later version.
++ */
++#include <net/ipv6.h>
++
++int (*ipv6_dev_get_saddr_hook)(struct net *net, struct net_device *dev,
++ const struct in6_addr *daddr, unsigned int srcprefs,
++ struct in6_addr *saddr);
++
++EXPORT_SYMBOL(ipv6_dev_get_saddr_hook);
++
++int ipv6_dev_get_saddr(struct net *net, struct net_device *dst_dev,
++ const struct in6_addr *daddr, unsigned int prefs,
++ struct in6_addr *saddr)
++{
++ typeof(ipv6_dev_get_saddr_hook) dev_get_saddr = rcu_dereference(ipv6_dev_get_saddr_hook);
++
++ if (dev_get_saddr)
++ return dev_get_saddr(net, dst_dev, daddr, prefs, saddr);
++
++ return -EADDRNOTAVAIL;
++}
++EXPORT_SYMBOL(ipv6_dev_get_saddr);
++