Linux net has removed function pointers which had used for intercepting packet from protocol handlers/pesudo devices like bridge and introduced netdev_rx_handler_register() instead. Subsequently br_handle_frame_hook is not available anymore. For patchless linux, use netdev_rx_handler_register().
Signed-off-by: Joonwoo Park <[email protected]> --- config-linuxmodule.h.in | 3 ++ configure.in | 7 +++++ elements/linuxmodule/anydevice.cc | 2 +- elements/linuxmodule/fromdevice.cc | 53 +++++++++++++++++++++++++++++++++++- elements/linuxmodule/fromdevice.hh | 5 +++ 5 files changed, 68 insertions(+), 2 deletions(-) diff --git a/config-linuxmodule.h.in b/config-linuxmodule.h.in index dbef4e2..e31ed3a 100644 --- a/config-linuxmodule.h.in +++ b/config-linuxmodule.h.in @@ -103,6 +103,9 @@ /* Define if you have the netdev_uses_trailer_tags function. */ #undef HAVE_NETDEV_USES_TRAILER_TAGS +/* Define if your Linux kernel has netdev_rx_handler_register. */ +#undef HAVE_LINUX_NETDEV_RX_HANDLER_REGISTER + /* Define if netif_receive_skb takes 3 arguments. */ #undef HAVE_NETIF_RECEIVE_SKB_EXTENDED diff --git a/configure.in b/configure.in index 04fad1f..b3b0c3b 100644 --- a/configure.in +++ b/configure.in @@ -1373,6 +1373,13 @@ void f1(int64_t) { // will fail if long long and int64_t are the same type AC_DEFINE([HAVE_NETDEV_USES_TRAILER_TAGS], [1], [Define if you have the netdev_uses_trailer_tags function.]) fi + AC_CACHE_CHECK(for netdev_rx_handler_register kernel symbol, ac_cv_linux_netdev_rx_handler_register, + [if grep "__ksymtab_netdev_rx_handler_register" $linux_system_map >/dev/null 2>&1; then + ac_cv_linux_netdev_rx_handler_register=yes + else ac_cv_linux_netdev_rx_handler_register=no; fi]) + if test $ac_cv_linux_netdev_rx_handler_register = yes; then + AC_DEFINE(HAVE_LINUX_NETDEV_RX_HANDLER_REGISTER) + fi CC="$save_cc" CXX="$save_cxx" diff --git a/elements/linuxmodule/anydevice.cc b/elements/linuxmodule/anydevice.cc index d01d842..6fd09cd 100644 --- a/elements/linuxmodule/anydevice.cc +++ b/elements/linuxmodule/anydevice.cc @@ -117,7 +117,7 @@ AnyDevice::alter_promiscuity(int delta) void AnyDevice::alter_from_device(int delta) { -#if !HAVE_CLICK_KERNEL && (defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)) && LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) +#if !HAVE_CLICK_KERNEL && !HAVE_LINUX_NETDEV_RX_HANDLER_REGISTER && (defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)) && LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) if (!_dev) return; fake_bridge *fb = reinterpret_cast<fake_bridge *>(_dev->br_port); diff --git a/elements/linuxmodule/fromdevice.cc b/elements/linuxmodule/fromdevice.cc index 9aff966..fc7ef8b 100644 --- a/elements/linuxmodule/fromdevice.cc +++ b/elements/linuxmodule/fromdevice.cc @@ -31,6 +31,14 @@ #include <click/standard/scheduleinfo.hh> #include <click/straccum.hh> +#include <click/cxxprotect.h> +CLICK_CXX_PROTECT +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) +# include <linux/rtnetlink.h> +#endif +CLICK_CXX_UNPROTECT +#include <click/cxxunprotect.h> + static AnyDeviceMap from_device_map; static int registered_readers; #if HAVE_CLICK_KERNEL @@ -39,7 +47,9 @@ static struct notifier_block packet_notifier; static struct notifier_block device_notifier_early; static struct notifier_block device_notifier_late; -#if !HAVE_CLICK_KERNEL && (defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)) +#if HAVE_LINUX_NETDEV_RX_HANDLER_REGISTER +# define CLICK_FROMDEVICE_USE_NETDEV_RX_HANDLER_REGISTER 1 +#elif !HAVE_CLICK_KERNEL && (defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)) # define CLICK_FROMDEVICE_USE_BRIDGE 1 #endif @@ -58,6 +68,8 @@ static int packet_notifier_hook(struct notifier_block *nb, unsigned long val, vo #elif CLICK_FROMDEVICE_USE_BRIDGE static struct sk_buff *click_br_handle_frame_hook(struct net_bridge_port *p, struct sk_buff *skb); static struct sk_buff *(*real_br_handle_frame_hook)(struct net_bridge_port *p, struct sk_buff *skb); +#elif CLICK_FROMDEVICE_USE_NETDEV_RX_HANDLER_REGISTER +static struct sk_buff *click_rx_handler(struct sk_buff *skb); #endif static int device_notifier_hook_early(struct notifier_block *nb, unsigned long val, void *v); static int device_notifier_hook_late(struct notifier_block *nb, unsigned long val, void *v); @@ -138,6 +150,18 @@ FromDevice::configure(Vector<String> &conf, ErrorHandler *errh) int before = errh->nerrors(); net_device *dev = lookup_device(errh); set_device(dev, &from_device_map, anydev_from_device); + +#if CLICK_FROMDEVICE_USE_NETDEV_RX_HANDLER_REGISTER + if (dev) { + rtnl_lock(); + _real_rx_handler = dev->rx_handler; + _real_rx_handler_data = dev->rx_handler_data; + netdev_rx_handler_unregister(dev); + netdev_rx_handler_register(dev, click_rx_handler, this); + rtnl_unlock(); + } +#endif + return errh->nerrors() == before ? 0 : -1; } @@ -166,6 +190,7 @@ FromDevice::initialize(ErrorHandler *errh) #elif CLICK_FROMDEVICE_USE_BRIDGE real_br_handle_frame_hook = br_handle_frame_hook; br_handle_frame_hook = click_br_handle_frame_hook; +#elif CLICK_FROMDEVICE_USE_NETDEV_RX_HANDLER_REGISTER #else errh->warning("can't get packets: not compiled for a Click kernel"); #endif @@ -198,6 +223,11 @@ FromDevice::cleanup(CleanupStage stage) #elif CLICK_FROMDEVICE_USE_BRIDGE if (registered_readers == 0) br_handle_frame_hook = real_br_handle_frame_hook; +#elif CLICK_FROMDEVICE_USE_NETDEV_RX_HANDLER_REGISTER + rtnl_lock(); + netdev_rx_handler_unregister(_dev); + netdev_rx_handler_register(_dev, _real_rx_handler, _real_rx_handler_data); + rtnl_unlock(); #endif } @@ -280,6 +310,27 @@ click_br_handle_frame_hook(struct net_bridge_port *p, struct sk_buff *skb) else return skb; } +#elif CLICK_FROMDEVICE_USE_NETDEV_RX_HANDLER_REGISTER +static struct sk_buff * +click_rx_handler(struct sk_buff *skb) +{ + int stolen; + sk_buff *ret = skb; + FromDevice *fd = rcu_dereference((*(FromDevice **)&skb->dev->rx_handler_data)); + + stolen = fd->got_skb(skb); + if (stolen) + ret = NULL; + else if (fd->_real_rx_handler) { + rcu_assign_pointer(*(unsigned long **)&skb->dev->rx_handler_data, + (unsigned long *)fd->_real_rx_handler_data); + ret = (*fd->_real_rx_handler)(skb); + rcu_assign_pointer(*(unsigned long **)&skb->dev->rx_handler_data, + (unsigned long *)fd); + } + + return ret; +} #endif static int diff --git a/elements/linuxmodule/fromdevice.hh b/elements/linuxmodule/fromdevice.hh index e31ac1f..1d2749c 100644 --- a/elements/linuxmodule/fromdevice.hh +++ b/elements/linuxmodule/fromdevice.hh @@ -159,6 +159,11 @@ class FromDevice : public AnyTaskDevice, public Storage { public: _runs = _empty_runs = _count = _drops = 0; } +#if HAVE_LINUX_NETDEV_RX_HANDLER_REGISTER + rx_handler_func_t *_real_rx_handler; + void *_real_rx_handler_data; +#endif + private: bool _active; -- 1.7.1
>From 0cb1d1c8a7b4b006b4eac5916f3a351f8ecb01cf Mon Sep 17 00:00:00 2001 From: Joonwoo Park <[email protected]> Date: Sun, 30 Jan 2011 01:07:02 -0800 Subject: [PATCH 4/5] FromDevice: use netdev_rx_handler_register Linux net has removed function pointers which had used for intercepting packet from protocol handlers/pesudo devices like bridge and introduced netdev_rx_handler_register() instead. Subsequently br_handle_frame_hook is not available anymore. For patchless linux, use netdev_rx_handler_register(). Signed-off-by: Joonwoo Park <[email protected]> --- config-linuxmodule.h.in | 3 ++ configure.in | 7 +++++ elements/linuxmodule/anydevice.cc | 2 +- elements/linuxmodule/fromdevice.cc | 53 +++++++++++++++++++++++++++++++++++- elements/linuxmodule/fromdevice.hh | 5 +++ 5 files changed, 68 insertions(+), 2 deletions(-) diff --git a/config-linuxmodule.h.in b/config-linuxmodule.h.in index dbef4e2..e31ed3a 100644 --- a/config-linuxmodule.h.in +++ b/config-linuxmodule.h.in @@ -103,6 +103,9 @@ /* Define if you have the netdev_uses_trailer_tags function. */ #undef HAVE_NETDEV_USES_TRAILER_TAGS +/* Define if your Linux kernel has netdev_rx_handler_register. */ +#undef HAVE_LINUX_NETDEV_RX_HANDLER_REGISTER + /* Define if netif_receive_skb takes 3 arguments. */ #undef HAVE_NETIF_RECEIVE_SKB_EXTENDED diff --git a/configure.in b/configure.in index 04fad1f..b3b0c3b 100644 --- a/configure.in +++ b/configure.in @@ -1373,6 +1373,13 @@ void f1(int64_t) { // will fail if long long and int64_t are the same type AC_DEFINE([HAVE_NETDEV_USES_TRAILER_TAGS], [1], [Define if you have the netdev_uses_trailer_tags function.]) fi + AC_CACHE_CHECK(for netdev_rx_handler_register kernel symbol, ac_cv_linux_netdev_rx_handler_register, + [if grep "__ksymtab_netdev_rx_handler_register" $linux_system_map >/dev/null 2>&1; then + ac_cv_linux_netdev_rx_handler_register=yes + else ac_cv_linux_netdev_rx_handler_register=no; fi]) + if test $ac_cv_linux_netdev_rx_handler_register = yes; then + AC_DEFINE(HAVE_LINUX_NETDEV_RX_HANDLER_REGISTER) + fi CC="$save_cc" CXX="$save_cxx" diff --git a/elements/linuxmodule/anydevice.cc b/elements/linuxmodule/anydevice.cc index d01d842..6fd09cd 100644 --- a/elements/linuxmodule/anydevice.cc +++ b/elements/linuxmodule/anydevice.cc @@ -117,7 +117,7 @@ AnyDevice::alter_promiscuity(int delta) void AnyDevice::alter_from_device(int delta) { -#if !HAVE_CLICK_KERNEL && (defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)) && LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) +#if !HAVE_CLICK_KERNEL && !HAVE_LINUX_NETDEV_RX_HANDLER_REGISTER && (defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)) && LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) if (!_dev) return; fake_bridge *fb = reinterpret_cast<fake_bridge *>(_dev->br_port); diff --git a/elements/linuxmodule/fromdevice.cc b/elements/linuxmodule/fromdevice.cc index 9aff966..fc7ef8b 100644 --- a/elements/linuxmodule/fromdevice.cc +++ b/elements/linuxmodule/fromdevice.cc @@ -31,6 +31,14 @@ #include <click/standard/scheduleinfo.hh> #include <click/straccum.hh> +#include <click/cxxprotect.h> +CLICK_CXX_PROTECT +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) +# include <linux/rtnetlink.h> +#endif +CLICK_CXX_UNPROTECT +#include <click/cxxunprotect.h> + static AnyDeviceMap from_device_map; static int registered_readers; #if HAVE_CLICK_KERNEL @@ -39,7 +47,9 @@ static struct notifier_block packet_notifier; static struct notifier_block device_notifier_early; static struct notifier_block device_notifier_late; -#if !HAVE_CLICK_KERNEL && (defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)) +#if HAVE_LINUX_NETDEV_RX_HANDLER_REGISTER +# define CLICK_FROMDEVICE_USE_NETDEV_RX_HANDLER_REGISTER 1 +#elif !HAVE_CLICK_KERNEL && (defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)) # define CLICK_FROMDEVICE_USE_BRIDGE 1 #endif @@ -58,6 +68,8 @@ static int packet_notifier_hook(struct notifier_block *nb, unsigned long val, vo #elif CLICK_FROMDEVICE_USE_BRIDGE static struct sk_buff *click_br_handle_frame_hook(struct net_bridge_port *p, struct sk_buff *skb); static struct sk_buff *(*real_br_handle_frame_hook)(struct net_bridge_port *p, struct sk_buff *skb); +#elif CLICK_FROMDEVICE_USE_NETDEV_RX_HANDLER_REGISTER +static struct sk_buff *click_rx_handler(struct sk_buff *skb); #endif static int device_notifier_hook_early(struct notifier_block *nb, unsigned long val, void *v); static int device_notifier_hook_late(struct notifier_block *nb, unsigned long val, void *v); @@ -138,6 +150,18 @@ FromDevice::configure(Vector<String> &conf, ErrorHandler *errh) int before = errh->nerrors(); net_device *dev = lookup_device(errh); set_device(dev, &from_device_map, anydev_from_device); + +#if CLICK_FROMDEVICE_USE_NETDEV_RX_HANDLER_REGISTER + if (dev) { + rtnl_lock(); + _real_rx_handler = dev->rx_handler; + _real_rx_handler_data = dev->rx_handler_data; + netdev_rx_handler_unregister(dev); + netdev_rx_handler_register(dev, click_rx_handler, this); + rtnl_unlock(); + } +#endif + return errh->nerrors() == before ? 0 : -1; } @@ -166,6 +190,7 @@ FromDevice::initialize(ErrorHandler *errh) #elif CLICK_FROMDEVICE_USE_BRIDGE real_br_handle_frame_hook = br_handle_frame_hook; br_handle_frame_hook = click_br_handle_frame_hook; +#elif CLICK_FROMDEVICE_USE_NETDEV_RX_HANDLER_REGISTER #else errh->warning("can't get packets: not compiled for a Click kernel"); #endif @@ -198,6 +223,11 @@ FromDevice::cleanup(CleanupStage stage) #elif CLICK_FROMDEVICE_USE_BRIDGE if (registered_readers == 0) br_handle_frame_hook = real_br_handle_frame_hook; +#elif CLICK_FROMDEVICE_USE_NETDEV_RX_HANDLER_REGISTER + rtnl_lock(); + netdev_rx_handler_unregister(_dev); + netdev_rx_handler_register(_dev, _real_rx_handler, _real_rx_handler_data); + rtnl_unlock(); #endif } @@ -280,6 +310,27 @@ click_br_handle_frame_hook(struct net_bridge_port *p, struct sk_buff *skb) else return skb; } +#elif CLICK_FROMDEVICE_USE_NETDEV_RX_HANDLER_REGISTER +static struct sk_buff * +click_rx_handler(struct sk_buff *skb) +{ + int stolen; + sk_buff *ret = skb; + FromDevice *fd = rcu_dereference((*(FromDevice **)&skb->dev->rx_handler_data)); + + stolen = fd->got_skb(skb); + if (stolen) + ret = NULL; + else if (fd->_real_rx_handler) { + rcu_assign_pointer(*(unsigned long **)&skb->dev->rx_handler_data, + (unsigned long *)fd->_real_rx_handler_data); + ret = (*fd->_real_rx_handler)(skb); + rcu_assign_pointer(*(unsigned long **)&skb->dev->rx_handler_data, + (unsigned long *)fd); + } + + return ret; +} #endif static int diff --git a/elements/linuxmodule/fromdevice.hh b/elements/linuxmodule/fromdevice.hh index e31ac1f..1d2749c 100644 --- a/elements/linuxmodule/fromdevice.hh +++ b/elements/linuxmodule/fromdevice.hh @@ -159,6 +159,11 @@ class FromDevice : public AnyTaskDevice, public Storage { public: _runs = _empty_runs = _count = _drops = 0; } +#if HAVE_LINUX_NETDEV_RX_HANDLER_REGISTER + rx_handler_func_t *_real_rx_handler; + void *_real_rx_handler_data; +#endif + private: bool _active; -- 1.7.1
_______________________________________________ click mailing list [email protected] https://amsterdam.lcs.mit.edu/mailman/listinfo/click
