aboutsummaryrefslogtreecommitdiff
path: root/libs/libpfring
diff options
context:
space:
mode:
authorRosen Penev <rosenp@gmail.com>2019-11-09 19:49:16 -0800
committerRosen Penev <rosenp@gmail.com>2019-11-09 19:51:19 -0800
commit04b5e109115ae0dad0c4a7104b1115ab8a0a7ce0 (patch)
treea84f93cf948fcc5561daee26d22bdcf02dc992b5 /libs/libpfring
parentdecf99dc64aa01802a4ca56602aec94f4df30523 (diff)
libpfring: Fix compilation with kernel >= 4.16
Backported upstream patch. Signed-off-by: Rosen Penev <rosenp@gmail.com>
Diffstat (limited to 'libs/libpfring')
-rw-r--r--libs/libpfring/Makefile2
-rw-r--r--libs/libpfring/patches/010-kernel-416.patch729
2 files changed, 730 insertions, 1 deletions
diff --git a/libs/libpfring/Makefile b/libs/libpfring/Makefile
index 996f33f2b..e82297f20 100644
--- a/libs/libpfring/Makefile
+++ b/libs/libpfring/Makefile
@@ -10,7 +10,7 @@ include $(INCLUDE_DIR)/kernel.mk
PKG_NAME:=libpfring
PKG_VERSION:=7.4.0
-PKG_RELEASE:=1
+PKG_RELEASE:=2
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/ntop/PF_RING/tar.gz/$(PKG_VERSION)?
diff --git a/libs/libpfring/patches/010-kernel-416.patch b/libs/libpfring/patches/010-kernel-416.patch
new file mode 100644
index 000000000..11bfc5207
--- /dev/null
+++ b/libs/libpfring/patches/010-kernel-416.patch
@@ -0,0 +1,729 @@
+From 2aa76765ff367e9c9c49c7373f7e2f51fb10b399 Mon Sep 17 00:00:00 2001
+From: Alfredo Cardigliano <cardigliano@ntop.org>
+Date: Wed, 27 Feb 2019 15:35:37 +0000
+Subject: [PATCH] Replaced kernel hook with exported functions
+
+---
+ .../e1000e/e1000e-3.4.0.2-zc/src/netdev.c | 30 +---
+ .../fm10k/fm10k-0.23.5-zc/src/fm10k_pci.c | 15 +-
+ .../intel/i40e/i40e-2.4.6-zc/src/i40e_main.c | 170 +++++++++---------
+ .../intel/igb/igb-5.3.5.18-zc/src/igb_main.c | 14 +-
+ .../ixgbevf-4.5.1-zc/src/ixgbevf_main.c | 16 +-
+ kernel/linux/pf_ring.h | 85 +++------
+ kernel/pf_ring.c | 115 +++---------
+ 9 files changed, 154 insertions(+), 319 deletions(-)
+
+diff --git a/drivers/intel/e1000e/e1000e-3.4.0.2-zc/src/netdev.c b/drivers/intel/e1000e/e1000e-3.4.0.2-zc/src/netdev.c
+index e0a10f04..50fdc5a5 100644
+--- a/drivers/intel/e1000e/e1000e-3.4.0.2-zc/src/netdev.c
++++ b/drivers/intel/e1000e/e1000e-3.4.0.2-zc/src/netdev.c
+@@ -610,19 +610,15 @@ e1000_receive_skb(struct e1000_adapter *adapter,
+
+ #ifdef HAVE_PF_RING
+ if (atomic_read(&adapter->pfring_zc.usage_counter) > 0) { /* act as direct driver-to-ring */
+- struct pfring_hooks *hook = (struct pfring_hooks *) netdev->pfring_ptr;
+-
+- if (hook && (hook->magic == PF_RING)) { /* PF_RING is alive */
+- int rc;
++ int rc;
+
+- //printk(KERN_INFO "[PF_RING] %s driver -> pf_ring [len=%d]\n", netdev->name, skb->len);
++ //printk(KERN_INFO "[PF_RING] %s driver -> pf_ring [len=%d]\n", netdev->name, skb->len);
+
+- rc = hook->ring_handler(skb, 1, 1, -1, 1);
++ rc = pfring_skb_ring_handler(skb, 1, 1, -1, 1);
+
+- if (rc > 0) { /* Packet handled by PF_RING */
+- kfree_skb(skb);
+- return rc; /* PF_RING has already freed the memory */
+- }
++ if (rc > 0) { /* Packet handled by PF_RING */
++ kfree_skb(skb);
++ return rc; /* PF_RING has already freed the memory */
+ }
+ }
+ #endif
+@@ -4611,9 +4607,6 @@ static void e1000_configure(struct e1000_adapter *adapter)
+
+ #ifdef HAVE_PF_RING
+ {
+- struct pfring_hooks *hook = (struct pfring_hooks*)adapter->netdev->pfring_ptr;
+-
+- if (hook != NULL) {
+ u16 cache_line_size;
+ struct e1000_ring *rx_ring = adapter->rx_ring;
+ struct e1000_ring *tx_ring = adapter->tx_ring;
+@@ -4638,7 +4631,7 @@ static void e1000_configure(struct e1000_adapter *adapter)
+ tx_info.descr_packet_memory_tot_len = tx_ring->size;
+
+ // printk("%s(%d)=%lu\n", __FUNCTION__, i, adapter->netdev->mem_start);
+- hook->zc_dev_handler(add_device_mapping,
++ pfring_zc_dev_handler(add_device_mapping,
+ #ifdef ENABLE_RX_ZC
+ &rx_info,
+ #else
+@@ -4667,8 +4660,6 @@ static void e1000_configure(struct e1000_adapter *adapter)
+
+ //printk(KERN_INFO "[PF_RING] %s(%s, rx_ring=%p, tx_ring=%p)\n", __FUNCTION__, adapter->netdev->name, rx_ring, tx_ring);
+ }
+-
+- }
+ #endif
+ }
+
+@@ -5254,10 +5245,7 @@ void e1000e_down(struct e1000_adapter *adapter, bool reset)
+
+ #ifdef HAVE_PF_RING
+ {
+- struct pfring_hooks *hook = (struct pfring_hooks*)adapter->netdev->pfring_ptr;
+-
+- if (hook != NULL) {
+- hook->zc_dev_handler(remove_device_mapping,
++ pfring_zc_dev_handler(remove_device_mapping,
+ NULL, // rx_info,
+ NULL, // tx_info,
+ NULL, /* Packet descriptors */
+@@ -5276,8 +5264,6 @@ void e1000e_down(struct e1000_adapter *adapter, bool reset)
+ NULL // notify_function_ptr
+ );
+ }
+-
+- }
+ #endif
+
+ }
+diff --git a/drivers/intel/fm10k/fm10k-0.23.5-zc/src/fm10k_pci.c b/drivers/intel/fm10k/fm10k-0.23.5-zc/src/fm10k_pci.c
+index 041779c5..04e6e673 100644
+--- a/drivers/intel/fm10k/fm10k-0.23.5-zc/src/fm10k_pci.c
++++ b/drivers/intel/fm10k/fm10k-0.23.5-zc/src/fm10k_pci.c
+@@ -2104,11 +2104,7 @@ void fm10k_up(struct fm10k_intfc *interface)
+
+ #ifdef HAVE_PF_RING
+ {
+- struct pfring_hooks *hook = (struct pfring_hooks*) interface->netdev->pfring_ptr;
+-
+- if (hook != NULL) {
+ int i;
+-
+ unsigned int buf_len = FM10K_RX_BUFSZ; /* TODO check the correct length (what about jumbo?) */
+
+ for (i = 0; i < interface->num_rx_queues; i++) {
+@@ -2129,7 +2125,7 @@ void fm10k_up(struct fm10k_intfc *interface)
+ tx_info.packet_memory_slot_len = buf_len;
+ tx_info.descr_packet_memory_tot_len = tx_ring->size;
+
+- hook->zc_dev_handler(add_device_mapping,
++ pfring_zc_dev_handler(add_device_mapping,
+ &rx_info,
+ &tx_info,
+ rx_ring->desc,
+@@ -2150,8 +2146,6 @@ void fm10k_up(struct fm10k_intfc *interface)
+ );
+ }
+ }
+-
+- }
+ #endif
+ }
+
+@@ -2245,13 +2239,10 @@ void fm10k_down(struct fm10k_intfc *interface)
+
+ #ifdef HAVE_PF_RING
+ {
+- struct pfring_hooks *hook = (struct pfring_hooks*)interface->netdev->pfring_ptr;
+-
+- if (hook != NULL) {
+ int i;
+
+ for (i = 0; i < interface->num_rx_queues; i++) {
+- hook->zc_dev_handler(remove_device_mapping,
++ pfring_zc_dev_handler(remove_device_mapping,
+ NULL, // rx_info,
+ NULL, // tx_info,
+ NULL, /* Packet descriptors */
+@@ -2271,8 +2262,6 @@ void fm10k_down(struct fm10k_intfc *interface)
+ );
+ }
+ }
+-
+- }
+ #endif
+ }
+
+diff --git a/drivers/intel/i40e/i40e-2.4.6-zc/src/i40e_main.c b/drivers/intel/i40e/i40e-2.4.6-zc/src/i40e_main.c
+index a3f2201c..466a6964 100644
+--- a/drivers/intel/i40e/i40e-2.4.6-zc/src/i40e_main.c
++++ b/drivers/intel/i40e/i40e-2.4.6-zc/src/i40e_main.c
+@@ -6063,64 +6063,60 @@ static int i40e_up_complete(struct i40e_vsi *vsi)
+
+ #ifdef HAVE_PF_RING
+ if (vsi->netdev) {
+- struct pfring_hooks *hook = (struct pfring_hooks*)vsi->netdev->pfring_ptr;
+-
+- if (hook != NULL) {
+- int i;
+- u16 cache_line_size;
+- struct i40e_pf *pf = vsi->back;
+-
+- pci_read_config_word(pf->pdev, I40E_PCI_DEVICE_CACHE_LINE_SIZE, &cache_line_size);
+- cache_line_size &= 0x00FF;
+- cache_line_size *= PCI_DEVICE_CACHE_LINE_SIZE_BYTES;
+- if (cache_line_size == 0) cache_line_size = 64;
+-
+- //if (unlikely(enable_debug))
+- printk("[PF_RING-ZC] %s: attach %s [pf start=%llu len=%llu][cache_line_size=%u][MSIX %s]\n", __FUNCTION__,
+- vsi->netdev->name, pci_resource_start(pf->pdev, 0), pci_resource_len(pf->pdev, 0),
+- cache_line_size, (vsi->back->flags & I40E_FLAG_MSIX_ENABLED) ? "enabled" : "disabled");
+-
+- for (i = 0; i < vsi->num_queue_pairs; i++) {
+- struct i40e_ring *rx_ring = vsi->rx_rings[i];
+- struct i40e_ring *tx_ring = vsi->tx_rings[i];
+- mem_ring_info rx_info = { 0 };
+- mem_ring_info tx_info = { 0 };
+-
+- init_waitqueue_head(&rx_ring->pfring_zc.rx_tx.rx.packet_waitqueue);
+-
+- rx_info.num_queues = vsi->num_queue_pairs;
+- rx_info.packet_memory_num_slots = rx_ring->count;
+- rx_info.packet_memory_slot_len = ALIGN(rx_ring->rx_buf_len, cache_line_size);
+- rx_info.descr_packet_memory_tot_len = rx_ring->size;
+- rx_info.registers_index = rx_ring->reg_idx;
+- rx_info.stats_index = vsi->info.stat_counter_idx;
+- rx_info.vector = rx_ring->q_vector->v_idx + vsi->base_vector;
++ int i;
++ u16 cache_line_size;
++ struct i40e_pf *pf = vsi->back;
++
++ pci_read_config_word(pf->pdev, I40E_PCI_DEVICE_CACHE_LINE_SIZE, &cache_line_size);
++ cache_line_size &= 0x00FF;
++ cache_line_size *= PCI_DEVICE_CACHE_LINE_SIZE_BYTES;
++ if (cache_line_size == 0) cache_line_size = 64;
++
++ //if (unlikely(enable_debug))
++ printk("[PF_RING-ZC] %s: attach %s [pf start=%llu len=%llu][cache_line_size=%u][MSIX %s]\n", __FUNCTION__,
++ vsi->netdev->name, pci_resource_start(pf->pdev, 0), pci_resource_len(pf->pdev, 0),
++ cache_line_size, (vsi->back->flags & I40E_FLAG_MSIX_ENABLED) ? "enabled" : "disabled");
++
++ for (i = 0; i < vsi->num_queue_pairs; i++) {
++ struct i40e_ring *rx_ring = vsi->rx_rings[i];
++ struct i40e_ring *tx_ring = vsi->tx_rings[i];
++ mem_ring_info rx_info = { 0 };
++ mem_ring_info tx_info = { 0 };
++
++ init_waitqueue_head(&rx_ring->pfring_zc.rx_tx.rx.packet_waitqueue);
++
++ rx_info.num_queues = vsi->num_queue_pairs;
++ rx_info.packet_memory_num_slots = rx_ring->count;
++ rx_info.packet_memory_slot_len = ALIGN(rx_ring->rx_buf_len, cache_line_size);
++ rx_info.descr_packet_memory_tot_len = rx_ring->size;
++ rx_info.registers_index = rx_ring->reg_idx;
++ rx_info.stats_index = vsi->info.stat_counter_idx;
++ rx_info.vector = rx_ring->q_vector->v_idx + vsi->base_vector;
+
+- tx_info.num_queues = vsi->num_queue_pairs;
+- tx_info.packet_memory_num_slots = tx_ring->count;
+- tx_info.packet_memory_slot_len = rx_info.packet_memory_slot_len;
+- tx_info.descr_packet_memory_tot_len = tx_ring->size;
+- tx_info.registers_index = tx_ring->reg_idx;
+-
+- hook->zc_dev_handler(add_device_mapping,
+- &rx_info,
+- &tx_info,
+- rx_ring->desc, /* rx packet descriptors */
+- tx_ring->desc, /* tx packet descriptors */
+- (void *) pci_resource_start(pf->pdev, 0),
+- pci_resource_len(pf->pdev, 0),
+- rx_ring->queue_index, /* channel id */
+- rx_ring->netdev,
+- rx_ring->dev, /* for DMA mapping */
+- intel_i40e,
+- rx_ring->netdev->dev_addr,
+- &rx_ring->pfring_zc.rx_tx.rx.packet_waitqueue,
+- &rx_ring->pfring_zc.rx_tx.rx.interrupt_received,
+- (void *) rx_ring,
+- (void *) tx_ring,
+- wait_packet_function_ptr,
+- notify_function_ptr);
+- }
++ tx_info.num_queues = vsi->num_queue_pairs;
++ tx_info.packet_memory_num_slots = tx_ring->count;
++ tx_info.packet_memory_slot_len = rx_info.packet_memory_slot_len;
++ tx_info.descr_packet_memory_tot_len = tx_ring->size;
++ tx_info.registers_index = tx_ring->reg_idx;
++
++ pfring_zc_dev_handler(add_device_mapping,
++ &rx_info,
++ &tx_info,
++ rx_ring->desc, /* rx packet descriptors */
++ tx_ring->desc, /* tx packet descriptors */
++ (void *) pci_resource_start(pf->pdev, 0),
++ pci_resource_len(pf->pdev, 0),
++ rx_ring->queue_index, /* channel id */
++ rx_ring->netdev,
++ rx_ring->dev, /* for DMA mapping */
++ intel_i40e,
++ rx_ring->netdev->dev_addr,
++ &rx_ring->pfring_zc.rx_tx.rx.packet_waitqueue,
++ &rx_ring->pfring_zc.rx_tx.rx.interrupt_received,
++ (void *) rx_ring,
++ (void *) tx_ring,
++ wait_packet_function_ptr,
++ notify_function_ptr);
+ }
+ }
+ #endif
+@@ -6273,42 +6269,38 @@ void i40e_down(struct i40e_vsi *vsi)
+
+ #ifdef HAVE_PF_RING
+ if (vsi->netdev) {
+- struct pfring_hooks *hook = (struct pfring_hooks*)vsi->netdev->pfring_ptr;
+ struct i40e_pf *pf = vsi->back;
+ struct i40e_pf *adapter = i40e_netdev_to_pf(vsi->netdev);
+ int i;
+
+- if (hook != NULL) {
+-
+- //if (unlikely(enable_debug))
+- printk("[PF_RING-ZC] %s: detach %s\n", __FUNCTION__, vsi->netdev->name);
+-
+- if (atomic_read(&adapter->pfring_zc.usage_counter) > 0)
+- printk("[PF_RING-ZC] %s: detaching %s while in use\n", __FUNCTION__, vsi->netdev->name);
+-
+- for (i = 0; i < vsi->num_queue_pairs; i++) {
+- struct i40e_ring *rx_ring = vsi->rx_rings[i];
+- struct i40e_ring *tx_ring = vsi->tx_rings[i];
+- hook->zc_dev_handler(remove_device_mapping,
+- NULL, // rx_info,
+- NULL, // tx_info,
+- NULL, /* Packet descriptors */
+- NULL, /* Packet descriptors */
+- (void*)pci_resource_start(pf->pdev, 0),
+- pci_resource_len(pf->pdev, 0),
+- rx_ring->queue_index, /* Channel Id */
+- rx_ring->netdev,
+- rx_ring->dev, /* for DMA mapping */
+- intel_i40e,
+- rx_ring->netdev->dev_addr,
+- &rx_ring->pfring_zc.rx_tx.rx.packet_waitqueue,
+- &rx_ring->pfring_zc.rx_tx.rx.interrupt_received,
+- (void*)rx_ring,
+- (void*)tx_ring,
+- NULL, // wait_packet_function_ptr
+- NULL // notify_function_ptr
+- );
+- }
++ //if (unlikely(enable_debug))
++ printk("[PF_RING-ZC] %s: detach %s\n", __FUNCTION__, vsi->netdev->name);
++
++ if (atomic_read(&adapter->pfring_zc.usage_counter) > 0)
++ printk("[PF_RING-ZC] %s: detaching %s while in use\n", __FUNCTION__, vsi->netdev->name);
++
++ for (i = 0; i < vsi->num_queue_pairs; i++) {
++ struct i40e_ring *rx_ring = vsi->rx_rings[i];
++ struct i40e_ring *tx_ring = vsi->tx_rings[i];
++ pfring_zc_dev_handler(remove_device_mapping,
++ NULL, // rx_info,
++ NULL, // tx_info,
++ NULL, /* Packet descriptors */
++ NULL, /* Packet descriptors */
++ (void*)pci_resource_start(pf->pdev, 0),
++ pci_resource_len(pf->pdev, 0),
++ rx_ring->queue_index, /* Channel Id */
++ rx_ring->netdev,
++ rx_ring->dev, /* for DMA mapping */
++ intel_i40e,
++ rx_ring->netdev->dev_addr,
++ &rx_ring->pfring_zc.rx_tx.rx.packet_waitqueue,
++ &rx_ring->pfring_zc.rx_tx.rx.interrupt_received,
++ (void*)rx_ring,
++ (void*)tx_ring,
++ NULL, // wait_packet_function_ptr
++ NULL // notify_function_ptr
++ );
+ }
+ }
+ #endif
+diff --git a/drivers/intel/igb/igb-5.3.5.18-zc/src/igb_main.c b/drivers/intel/igb/igb-5.3.5.18-zc/src/igb_main.c
+index 9965b52b..f5ea7912 100644
+--- a/drivers/intel/igb/igb-5.3.5.18-zc/src/igb_main.c
++++ b/drivers/intel/igb/igb-5.3.5.18-zc/src/igb_main.c
+@@ -1780,9 +1780,6 @@ static void igb_configure(struct igb_adapter *adapter)
+
+ #ifdef HAVE_PF_RING
+ {
+- struct pfring_hooks *hook = (struct pfring_hooks*)adapter->netdev->pfring_ptr;
+-
+- if(hook != NULL) {
+ int i;
+ u16 cache_line_size;
+
+@@ -1809,7 +1806,7 @@ static void igb_configure(struct igb_adapter *adapter)
+ tx_info.packet_memory_slot_len = rx_info.packet_memory_slot_len;
+ tx_info.descr_packet_memory_tot_len = tx_ring->size;
+
+- hook->zc_dev_handler(add_device_mapping,
++ pfring_zc_dev_handler(add_device_mapping,
+ &rx_info,
+ &tx_info,
+ rx_ring->desc, /* Packet descriptors */
+@@ -1830,8 +1827,6 @@ static void igb_configure(struct igb_adapter *adapter)
+ );
+ }
+ }
+-
+- }
+ #endif
+ }
+
+@@ -2155,13 +2150,10 @@ void igb_down(struct igb_adapter *adapter)
+
+ #ifdef HAVE_PF_RING
+ {
+- struct pfring_hooks *hook = (struct pfring_hooks*)adapter->netdev->pfring_ptr;
+-
+- if(hook != NULL) {
+ int i;
+
+ for (i = 0; i < adapter->num_rx_queues; i++) {
+- hook->zc_dev_handler(remove_device_mapping,
++ pfring_zc_dev_handler(remove_device_mapping,
+ NULL, // rx_info,
+ NULL, // tx_info,
+ NULL, /* Packet descriptors */
+@@ -2181,8 +2173,6 @@ void igb_down(struct igb_adapter *adapter)
+ );
+ }
+ }
+-
+- }
+ #endif
+ }
+
+diff --git a/kernel/linux/pf_ring.h b/kernel/linux/pf_ring.h
+index 17ea750a..1473ad84 100644
+--- a/kernel/linux/pf_ring.h
++++ b/kernel/linux/pf_ring.h
+@@ -37,9 +37,6 @@
+ #define DEFAULT_MIN_PKT_QUEUED 128
+ #define DEFAULT_POLL_WATERMARK_TIMEOUT 0
+
+-/* Dirty hack I know, but what else shall I do man? */
+-#define pfring_ptr ax25_ptr
+-
+ #define FILTERING_SAMPLING_RATIO 10
+
+ /* Versioning */
+@@ -1285,63 +1282,31 @@ typedef struct {
+
+ /* **************************************** */
+
+-typedef void (*handle_pfring_zc_dev)(zc_dev_operation operation,
+- mem_ring_info *rx_info,
+- mem_ring_info *tx_info,
+- void *rx_descr_packet_memory,
+- void *tx_descr_packet_memory,
+- void *phys_card_memory,
+- u_int phys_card_memory_len,
+- u_int channel_id,
+- struct net_device *dev,
+- struct device *hwdev,
+- zc_dev_model device_model,
+- u_char *device_address,
+- wait_queue_head_t *packet_waitqueue,
+- u_int8_t *interrupt_received,
+- void *rx_adapter_ptr, void *tx_adapter_ptr,
+- zc_dev_wait_packet wait_packet_function_ptr,
+- zc_dev_notify dev_notify_function_ptr);
+-
+-extern handle_pfring_zc_dev get_ring_zc_dev_handler(void);
+-extern void set_ring_zc_dev_handler(handle_pfring_zc_dev the_zc_device_handler);
+-extern void do_ring_zc_dev_handler(zc_dev_operation operation,
+- mem_ring_info *rx_info,
+- mem_ring_info *tx_info,
+- unsigned long *rx_packet_memory,
+- void *rx_descr_packet_memory,
+- unsigned long *tx_packet_memory,
+- void *tx_descr_packet_memory,
+- void *phys_card_memory,
+- u_int phys_card_memory_len,
+- u_int channel_id,
+- struct net_device *dev,
+- struct device *hwdev,
+- zc_dev_model device_model,
+- u_char *device_address,
+- wait_queue_head_t * packet_waitqueue,
+- u_int8_t * interrupt_received,
+- void *rx_adapter_ptr, void *tx_adapter_ptr,
+- zc_dev_wait_packet wait_packet_function_ptr,
+- zc_dev_notify dev_notify_function_ptr);
+-
+-typedef int (*handle_ring_skb)(struct sk_buff *skb, u_char recv_packet,
+- u_char real_skb,
+- int32_t channel_id,
+- u_int32_t num_rx_channels);
+-typedef int (*handle_ring_buffer)(struct net_device *dev,
+- char *data, int len);
+-
+-/* Hack to jump from a device directly to PF_RING */
+-struct pfring_hooks {
+- u_int32_t magic; /*
+- It should be set to PF_RING
+- and is MUST be the first one on this struct
+- */
+- handle_ring_skb ring_handler;
+- handle_ring_buffer buffer_ring_handler;
+- handle_pfring_zc_dev zc_dev_handler;
+-};
++/* Exported functions - used by drivers */
++
++int pfring_skb_ring_handler(struct sk_buff *skb,
++ u_int8_t recv_packet,
++ u_int8_t real_skb /* 1=real skb, 0=faked skb */,
++ int32_t channel_id,
++ u_int32_t num_rx_channels);
++
++void pfring_zc_dev_handler(zc_dev_operation operation,
++ mem_ring_info *rx_info,
++ mem_ring_info *tx_info,
++ void *rx_descr_packet_memory,
++ void *tx_descr_packet_memory,
++ void *phys_card_memory,
++ u_int phys_card_memory_len,
++ u_int channel_id,
++ struct net_device *dev,
++ struct device *hwdev,
++ zc_dev_model device_model,
++ u_char *device_address,
++ wait_queue_head_t *packet_waitqueue,
++ u_int8_t *interrupt_received,
++ void *rx_adapter_ptr, void *tx_adapter_ptr,
++ zc_dev_wait_packet wait_packet_function_ptr,
++ zc_dev_notify dev_notify_function_ptr);
+
+ /* *************************************************************** */
+
+diff --git a/kernel/pf_ring.c b/kernel/pf_ring.c
+index fb2e06e8..2fe65c36 100644
+--- a/kernel/pf_ring.c
++++ b/kernel/pf_ring.c
+@@ -381,10 +381,6 @@ static inline void ring_read_unlock_inbh(void) { read_unlock(&ring_mgmt_lock);
+ static struct proto_ops ring_ops;
+ static struct proto ring_proto;
+
+-static int skb_ring_handler(struct sk_buff *skb, u_char recv_packet,
+- u_int8_t real_skb,
+- int32_t channel_id, u_int32_t num_rx_channels);
+-static int buffer_ring_handler(struct net_device *dev, char *data, int len);
+ static int remove_from_cluster(struct sock *sock, struct pf_ring_socket *pfr);
+ static int pfring_select_zc_dev(struct pf_ring_socket *pfr, zc_dev_mapping *mapping);
+ static int pfring_get_zc_dev(struct pf_ring_socket *pfr);
+@@ -3854,7 +3850,7 @@ static struct sk_buff* defrag_skb(struct sk_buff *skb,
+ the ring due to lack of available space
+ */
+
+-static int skb_ring_handler(struct sk_buff *skb,
++int pfring_skb_ring_handler(struct sk_buff *skb,
+ u_int8_t recv_packet,
+ u_int8_t real_skb /* 1=real skb, 0=faked skb */,
+ /*
+@@ -4156,28 +4152,7 @@ static int skb_ring_handler(struct sk_buff *skb,
+ return(rc); /* 0 = packet not handled */
+ }
+
+-/* ********************************** */
+-
+-static int buffer_ring_handler(struct net_device *dev, char *data, int len)
+-{
+- struct sk_buff skb;
+-
+- skb.dev = dev;
+- skb.len = len;
+- skb.data = (u_char *) data;
+- skb.data_len = len;
+-
+- /* BD - API changed for time keeping */
+-#if(LINUX_VERSION_CODE < KERNEL_VERSION(4,10,0))
+- skb.tstamp.tv64 = 0;
+-#else
+- skb.tstamp = 0;
+-#endif
+-
+- return(skb_ring_handler(&skb, 1, 0 /* fake skb */,
+- -1 /* unknown: any channel */,
+- UNKNOWN_NUM_RX_CHANNELS));
+-}
++EXPORT_SYMBOL(pfring_skb_ring_handler);
+
+ /* ********************************** */
+
+@@ -4193,11 +4168,11 @@ static int packet_rcv(struct sk_buff *skb, struct net_device *dev,
+ if (skb->pkt_type == PACKET_OUTGOING && active_zc_socket[dev->ifindex] == 2)
+ return 0;
+
+- rc = skb_ring_handler(skb,
+- skb->pkt_type != PACKET_OUTGOING,
+- 1 /* real_skb */,
+- -1 /* unknown: any channel */,
+- UNKNOWN_NUM_RX_CHANNELS);
++ rc = pfring_skb_ring_handler(skb,
++ skb->pkt_type != PACKET_OUTGOING,
++ 1 /* real_skb */,
++ 1 /* unknown: any channel */,
++ UNKNOWN_NUM_RX_CHANNELS);
+
+ kfree_skb(skb);
+
+@@ -7609,23 +7584,23 @@ static int ring_getsockopt(struct socket *sock,
+
+ /* ************************************* */
+
+-void zc_dev_handler(zc_dev_operation operation,
+- mem_ring_info *rx_info,
+- mem_ring_info *tx_info,
+- void *rx_descr_packet_memory,
+- void *tx_descr_packet_memory,
+- void *phys_card_memory,
+- u_int phys_card_memory_len,
+- u_int channel_id,
+- struct net_device *dev,
+- struct device *hwdev,
+- zc_dev_model device_model,
+- u_char *device_address,
+- wait_queue_head_t *packet_waitqueue,
+- u_int8_t *interrupt_received,
+- void *rx_adapter_ptr, void *tx_adapter_ptr,
+- zc_dev_wait_packet wait_packet_function_ptr,
+- zc_dev_notify dev_notify_function_ptr)
++void pfring_zc_dev_handler(zc_dev_operation operation,
++ mem_ring_info *rx_info,
++ mem_ring_info *tx_info,
++ void *rx_descr_packet_memory,
++ void *tx_descr_packet_memory,
++ void *phys_card_memory,
++ u_int phys_card_memory_len,
++ u_int channel_id,
++ struct net_device *dev,
++ struct device *hwdev,
++ zc_dev_model device_model,
++ u_char *device_address,
++ wait_queue_head_t *packet_waitqueue,
++ u_int8_t *interrupt_received,
++ void *rx_adapter_ptr, void *tx_adapter_ptr,
++ zc_dev_wait_packet wait_packet_function_ptr,
++ zc_dev_notify dev_notify_function_ptr)
+ {
+ pf_ring_device *dev_ptr;
+
+@@ -7728,6 +7703,8 @@ void zc_dev_handler(zc_dev_operation operation,
+ zc_devices_list_size);
+ }
+
++EXPORT_SYMBOL(pfring_zc_dev_handler);
++
+ /* ************************************* */
+
+ static int ring_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
+@@ -7807,15 +7784,6 @@ static struct proto ring_proto = {
+
+ /* ************************************ */
+
+-static struct pfring_hooks ring_hooks = {
+- .magic = PF_RING,
+- .ring_handler = skb_ring_handler,
+- .buffer_ring_handler = buffer_ring_handler,
+- .zc_dev_handler = zc_dev_handler,
+-};
+-
+-/* ************************************ */
+-
+ void remove_device_from_proc(pf_ring_net *netns, pf_ring_device *dev_ptr) {
+ if (dev_ptr->proc_entry == NULL)
+ return;
+@@ -8078,7 +8046,6 @@ static int ring_notifier(struct notifier_block *this, unsigned long msg, void *d
+ struct net_device *dev = netdev_notifier_info_to_dev(data);
+ pf_ring_device *dev_ptr;
+ struct list_head *ptr, *tmp_ptr;
+- struct pfring_hooks *hook;
+ int if_name_clash = 0;
+
+ if(debug_on(2)) {
+@@ -8167,13 +8134,6 @@ static int ring_notifier(struct notifier_block *this, unsigned long msg, void *d
+ return NOTIFY_DONE;
+ }
+
+- hook = (struct pfring_hooks *) dev->pfring_ptr;
+- if(hook && (hook->magic != PF_RING)) {
+- printk("[PF_RING] %s %s: interface already in use by another socket not compatible with PF_RING\n",
+- __FUNCTION__, dev->name);
+- return NOTIFY_DONE;
+- }
+-
+ switch (msg) {
+ case NETDEV_POST_INIT:
+ case NETDEV_PRE_UP:
+@@ -8181,7 +8141,7 @@ static int ring_notifier(struct notifier_block *this, unsigned long msg, void *d
+ case NETDEV_DOWN:
+ break;
+ case NETDEV_REGISTER:
+- debug_printk(2, "%s: [REGISTER][ifindex: %u pfring_ptr=%p hook=%p]\n", dev->name, dev->ifindex, dev->pfring_ptr, &ring_hooks);
++ debug_printk(2, "%s: [REGISTER][ifindex: %u]\n", dev->name, dev->ifindex);
+
+ /* safety check */
+ list_for_each_safe(ptr, tmp_ptr, &ring_aware_device_list) {
+@@ -8194,7 +8154,6 @@ static int ring_notifier(struct notifier_block *this, unsigned long msg, void *d
+ }
+
+ if(!if_name_clash) {
+- dev->pfring_ptr = &ring_hooks;
+ if(add_device_to_ring_list(dev) != 0) {
+ printk("[PF_RING] Error in add_device_to_ring_list(%s)\n", dev->name);
+ }
+@@ -8202,13 +8161,9 @@ static int ring_notifier(struct notifier_block *this, unsigned long msg, void *d
+ break;
+
+ case NETDEV_UNREGISTER:
+- debug_printk(2, "%s: [UNREGISTER][ifindex: %u pfring_ptr=%p]\n", dev->name, dev->ifindex, dev->pfring_ptr);
++ debug_printk(2, "%s: [UNREGISTER][ifindex: %u]\n", dev->name, dev->ifindex);
+
+- hook = (struct pfring_hooks *) dev->pfring_ptr;
+- if(hook && (hook->magic == PF_RING)) {
+- remove_device_from_ring_list(dev);
+- dev->pfring_ptr = NULL;
+- }
++ remove_device_from_ring_list(dev);
+ /* We don't have to worry updating rules that might have used this
+ device (just removed) as reflection device. This because whenever
+ we set a rule with reflection, we do dev_put() so such device is
+@@ -8329,7 +8284,6 @@ static struct pernet_operations ring_net_ops = {
+ static void __exit ring_exit(void)
+ {
+ struct list_head *ptr, *tmp_ptr;
+- struct pfring_hooks *hook;
+ pf_ring_net *netns;
+
+ pfring_enabled = 0;
+@@ -8340,8 +8294,6 @@ static void __exit ring_exit(void)
+ list_for_each_safe(ptr, tmp_ptr, &ring_aware_device_list) {
+ pf_ring_device *dev_ptr = list_entry(ptr, pf_ring_device, device_list);
+
+- hook = (struct pfring_hooks *) dev_ptr->dev->pfring_ptr;
+-
+ write_lock(&netns_lock);
+
+ netns = netns_lookup(dev_net(dev_ptr->dev));
+@@ -8351,15 +8303,6 @@ static void __exit ring_exit(void)
+
+ write_unlock(&netns_lock);
+
+- if (hook != NULL) {
+- if(hook->magic == PF_RING) {
+- debug_printk(2, "Unregister hook for %s\n", dev_ptr->device_name);
+- dev_ptr->dev->pfring_ptr = NULL; /* Unhook PF_RING */
+- }
+- } else {
+- printk("[PF_RING] PF_RING hook was not set for %s\n", dev_ptr->device_name);
+- }
+-
+ list_del(ptr);
+ kfree(dev_ptr);
+ }