netpoll: Move all receive processing under CONFIG_NETPOLL_TRAP

Make rx_skb_hook, and rx in struct netpoll depend on
CONFIG_NETPOLL_TRAP Make rx_lock, rx_np, and neigh_tx in struct
netpoll_info depend on CONFIG_NETPOLL_TRAP

Make the functions netpoll_rx_on, netpoll_rx, and netpoll_receive_skb
no-ops when CONFIG_NETPOLL_TRAP is not set.

Only build netpoll_neigh_reply, checksum_udp service_neigh_queue,
pkt_is_ns, and __netpoll_rx when CONFIG_NETPOLL_TRAP is defined.

Add helper functions netpoll_trap_setup, netpoll_trap_setup_info,
netpoll_trap_cleanup, and netpoll_trap_cleanup_info that initialize
and cleanup the struct netpoll and struct netpoll_info receive
specific fields when CONFIG_NETPOLL_TRAP is enabled and do nothing
otherwise.

Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
diff --git a/net/core/netpoll.c b/net/core/netpoll.c
index b69bb3f..eed8b1d 100644
--- a/net/core/netpoll.c
+++ b/net/core/netpoll.c
@@ -48,6 +48,7 @@
 
 #ifdef CONFIG_NETPOLL_TRAP
 static atomic_t trapped;
+static void netpoll_neigh_reply(struct sk_buff *skb, struct netpoll_info *npinfo);
 #endif
 
 DEFINE_STATIC_SRCU(netpoll_srcu);
@@ -61,7 +62,6 @@
 	 MAX_UDP_CHUNK)
 
 static void zap_completion_queue(void);
-static void netpoll_neigh_reply(struct sk_buff *skb, struct netpoll_info *npinfo);
 static void netpoll_async_cleanup(struct work_struct *work);
 
 static unsigned int carrier_timeout = 4;
@@ -109,6 +109,7 @@
 	}
 }
 
+#ifdef CONFIG_NETPOLL_TRAP
 static __sum16 checksum_udp(struct sk_buff *skb, struct udphdr *uh,
 			    unsigned short ulen, __be32 saddr, __be32 daddr)
 {
@@ -127,6 +128,7 @@
 
 	return __skb_checksum_complete(skb);
 }
+#endif /* CONFIG_NETPOLL_TRAP */
 
 /*
  * Check whether delayed processing was scheduled for our NIC. If so,
@@ -179,6 +181,7 @@
 	}
 }
 
+#ifdef CONFIG_NETPOLL_TRAP
 static void service_neigh_queue(struct net_device *dev,
 				struct netpoll_info *npi)
 {
@@ -197,6 +200,12 @@
 	while ((skb = skb_dequeue(&npi->neigh_tx)))
 		netpoll_neigh_reply(skb, npi);
 }
+#else /* !CONFIG_NETPOLL_TRAP */
+static inline void service_neigh_queue(struct net_device *dev,
+				struct netpoll_info *npi)
+{
+}
+#endif /* CONFIG_NETPOLL_TRAP */
 
 static void netpoll_poll_dev(struct net_device *dev)
 {
@@ -522,6 +531,7 @@
 }
 EXPORT_SYMBOL(netpoll_send_udp);
 
+#ifdef CONFIG_NETPOLL_TRAP
 static void netpoll_neigh_reply(struct sk_buff *skb, struct netpoll_info *npinfo)
 {
 	int size, type = ARPOP_REPLY;
@@ -900,6 +910,55 @@
 	return 0;
 }
 
+static void netpoll_trap_setup_info(struct netpoll_info *npinfo)
+{
+	INIT_LIST_HEAD(&npinfo->rx_np);
+	spin_lock_init(&npinfo->rx_lock);
+	skb_queue_head_init(&npinfo->neigh_tx);
+}
+
+static void netpoll_trap_cleanup_info(struct netpoll_info *npinfo)
+{
+	skb_queue_purge(&npinfo->neigh_tx);
+}
+
+static void netpoll_trap_setup(struct netpoll *np, struct netpoll_info *npinfo)
+{
+	unsigned long flags;
+	if (np->rx_skb_hook) {
+		spin_lock_irqsave(&npinfo->rx_lock, flags);
+		list_add_tail(&np->rx, &npinfo->rx_np);
+		spin_unlock_irqrestore(&npinfo->rx_lock, flags);
+	}
+}
+
+static void netpoll_trap_cleanup(struct netpoll *np, struct netpoll_info *npinfo)
+{
+	unsigned long flags;
+	if (!list_empty(&npinfo->rx_np)) {
+		spin_lock_irqsave(&npinfo->rx_lock, flags);
+		list_del(&np->rx);
+		spin_unlock_irqrestore(&npinfo->rx_lock, flags);
+	}
+}
+
+#else /* !CONFIG_NETPOLL_TRAP */
+static inline void netpoll_trap_setup_info(struct netpoll_info *npinfo)
+{
+}
+static inline void netpoll_trap_cleanup_info(struct netpoll_info *npinfo)
+{
+}
+static inline
+void netpoll_trap_setup(struct netpoll *np, struct netpoll_info *npinfo)
+{
+}
+static inline
+void netpoll_trap_cleanup(struct netpoll *np, struct netpoll_info *npinfo)
+{
+}
+#endif /* CONFIG_NETPOLL_TRAP */
+
 void netpoll_print_options(struct netpoll *np)
 {
 	np_info(np, "local port %d\n", np->local_port);
@@ -1023,7 +1082,6 @@
 {
 	struct netpoll_info *npinfo;
 	const struct net_device_ops *ops;
-	unsigned long flags;
 	int err;
 
 	np->dev = ndev;
@@ -1045,11 +1103,9 @@
 			goto out;
 		}
 
-		INIT_LIST_HEAD(&npinfo->rx_np);
+		netpoll_trap_setup_info(npinfo);
 
-		spin_lock_init(&npinfo->rx_lock);
 		sema_init(&npinfo->dev_lock, 1);
-		skb_queue_head_init(&npinfo->neigh_tx);
 		skb_queue_head_init(&npinfo->txq);
 		INIT_DELAYED_WORK(&npinfo->tx_work, queue_process);
 
@@ -1068,11 +1124,7 @@
 
 	npinfo->netpoll = np;
 
-	if (np->rx_skb_hook) {
-		spin_lock_irqsave(&npinfo->rx_lock, flags);
-		list_add_tail(&np->rx, &npinfo->rx_np);
-		spin_unlock_irqrestore(&npinfo->rx_lock, flags);
-	}
+	netpoll_trap_setup(np, npinfo);
 
 	/* last thing to do is link it to the net device structure */
 	rcu_assign_pointer(ndev->npinfo, npinfo);
@@ -1222,7 +1274,7 @@
 	struct netpoll_info *npinfo =
 			container_of(rcu_head, struct netpoll_info, rcu);
 
-	skb_queue_purge(&npinfo->neigh_tx);
+	netpoll_trap_cleanup_info(npinfo);
 	skb_queue_purge(&npinfo->txq);
 
 	/* we can't call cancel_delayed_work_sync here, as we are in softirq */
@@ -1238,7 +1290,6 @@
 void __netpoll_cleanup(struct netpoll *np)
 {
 	struct netpoll_info *npinfo;
-	unsigned long flags;
 
 	/* rtnl_dereference would be preferable here but
 	 * rcu_cleanup_netpoll path can put us in here safely without
@@ -1248,11 +1299,7 @@
 	if (!npinfo)
 		return;
 
-	if (!list_empty(&npinfo->rx_np)) {
-		spin_lock_irqsave(&npinfo->rx_lock, flags);
-		list_del(&np->rx);
-		spin_unlock_irqrestore(&npinfo->rx_lock, flags);
-	}
+	netpoll_trap_cleanup(np, npinfo);
 
 	synchronize_srcu(&netpoll_srcu);