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);
   }
