[shortcut-fe] support compiling with kernel 3.14.0

Change-Id: Ie1c078969e98edc32b1f1e0c106a647cae3bb180
Signed-off-by: Xiaoping Fan <xfan@codeaurora.org>
diff --git a/shortcut-fe/sfe_backport.h b/shortcut-fe/sfe_backport.h
new file mode 100644
index 0000000..72170bc
--- /dev/null
+++ b/shortcut-fe/sfe_backport.h
@@ -0,0 +1,35 @@
+#include <linux/version.h>
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,13,0)
+#define sfe_cm_ipv4_post_routing_hook(HOOKNUM, OPS, SKB, UNUSED, OUT, OKFN) \
+static unsigned int __sfe_cm_ipv4_post_routing_hook(const struct nf_hook_ops *OPS, \
+						    struct sk_buff *SKB, \
+						    const struct net_device *UNUSED, \
+						    const struct net_device *OUT, \
+						    int (*OKFN)(struct sk_buff *))
+#else
+#define sfe_cm_ipv4_post_routing_hook(HOOKNUM, OPS, SKB, UNUSED, OUT, OKFN) \
+static unsigned int __sfe_cm_ipv4_post_routing_hook(unsigned int HOOKNUM, \
+						    struct sk_buff *SKB, \
+						    const struct net_device *UNUSED, \
+						    const struct net_device *OUT, \
+						    int (*OKFN)(struct sk_buff *))
+#endif
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0)
+#define SFE_DEV_MASTER(DEV) netdev_master_upper_dev_get(DEV);
+#else
+#define SFE_DEV_MASTER(DEV) (DEV)->master;
+#endif
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,13,0)
+#define SFE_NF_CONN_ACCT(NM) struct nf_conn_acct *NM
+#else
+#define SFE_NF_CONN_ACCT(NM) struct nf_conn_counter *NM
+#endif
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,13,0)
+#define SFE_ACCT_COUNTER(NM) (NM)->counter
+#else
+#define SFE_ACCT_COUNTER(NM) (NM)
+#endif
diff --git a/shortcut-fe/sfe_cm.c b/shortcut-fe/sfe_cm.c
index c57776a..5fa23a6 100644
--- a/shortcut-fe/sfe_cm.c
+++ b/shortcut-fe/sfe_cm.c
@@ -22,6 +22,7 @@
 
 #include "sfe.h"
 #include "sfe_ipv4.h"
+#include "sfe_backport.h"
 
 /*
  * Per-module structure.
@@ -138,7 +139,7 @@
 	dst = (struct dst_entry *)rt;
 
 	rcu_read_lock();
-	neigh = dst_get_neighbour_noref(dst);
+	neigh = dst_neigh_lookup(dst, &addr);
 	if (unlikely(!neigh)) {
 		rcu_read_unlock();
 		dst_release(dst);
@@ -146,6 +147,7 @@
 	}
 
 	if (unlikely(!(neigh->nud_state & NUD_VALID))) {
+		neigh_release(neigh);
 		rcu_read_unlock();
 		dst_release(dst);
 		return false;
@@ -153,6 +155,7 @@
 
 	mac_dev = neigh->dev;
 	if (!mac_dev) {
+		neigh_release(neigh);
 		rcu_read_unlock();
 		dst_release(dst);
 		return false;
@@ -162,8 +165,8 @@
 
 	dev_hold(mac_dev);
 	*dev = mac_dev;
+	neigh_release(neigh);
 	rcu_read_unlock();
-
 	dst_release(dst);
 
 	return true;
@@ -173,11 +176,7 @@
  * sfe_cm_ipv4_post_routing_hook()
  *	Called for packets about to leave the box - either locally generated or forwarded from another interface
  */
-static unsigned int sfe_cm_ipv4_post_routing_hook(unsigned int hooknum,
-						  struct sk_buff *skb,
-						  const struct net_device *in_unused,
-						  const struct net_device *out,
-						  int (*okfn)(struct sk_buff *))
+sfe_cm_ipv4_post_routing_hook(hooknum, ops, skb, in_unused, out, okfn)
 {
 	struct sfe_ipv4_create sic;
 	struct net_device *in;
@@ -383,7 +382,7 @@
 	 * the case then find the bridge interface instead.
 	 */
 	if (src_dev->priv_flags & IFF_BRIDGE_PORT) {
-		src_br_dev = src_dev->master;
+		src_br_dev = SFE_DEV_MASTER(src_dev);
 		if (!src_br_dev) {
 			DEBUG_TRACE("no bridge found for: %s\n", src_dev->name);
 			goto done2;
@@ -394,7 +393,7 @@
 	}
 
 	if (dest_dev->priv_flags & IFF_BRIDGE_PORT) {
-		dest_br_dev = dest_dev->master;
+		dest_br_dev = SFE_DEV_MASTER(dest_dev);
 		if (!dest_br_dev) {
 			DEBUG_TRACE("no bridge found for: %s\n", dest_dev->name);
 			goto done3;
@@ -539,7 +538,7 @@
  */
 static struct nf_hook_ops sfe_cm_ipv4_ops_post_routing[] __read_mostly = {
 	{
-		.hook = sfe_cm_ipv4_post_routing_hook,
+		.hook = __sfe_cm_ipv4_post_routing_hook,
 		.owner = THIS_MODULE,
 		.pf = PF_INET,
 		.hooknum = NF_INET_POST_ROUTING,
@@ -556,7 +555,7 @@
 	struct nf_conntrack_tuple_hash *h;
 	struct nf_conntrack_tuple tuple;
 	struct nf_conn *ct;
-	struct nf_conn_counter *acct;
+	SFE_NF_CONN_ACCT(acct);
 
 	/*
 	 * Create a tuple so as to be able to look up a connection
@@ -598,10 +597,10 @@
 	acct = nf_conn_acct_find(ct);
 	if (acct) {
 		spin_lock_bh(&ct->lock);
-		atomic64_set(&acct[IP_CT_DIR_ORIGINAL].packets, sis->src_packet_count);
-		atomic64_set(&acct[IP_CT_DIR_ORIGINAL].bytes, sis->src_byte_count);
-		atomic64_set(&acct[IP_CT_DIR_REPLY].packets, sis->dest_packet_count);
-		atomic64_set(&acct[IP_CT_DIR_REPLY].bytes, sis->dest_byte_count);
+		atomic64_set(&SFE_ACCT_COUNTER(acct)[IP_CT_DIR_ORIGINAL].packets, sis->src_packet_count);
+		atomic64_set(&SFE_ACCT_COUNTER(acct)[IP_CT_DIR_ORIGINAL].bytes, sis->src_byte_count);
+		atomic64_set(&SFE_ACCT_COUNTER(acct)[IP_CT_DIR_REPLY].packets, sis->dest_packet_count);
+		atomic64_set(&SFE_ACCT_COUNTER(acct)[IP_CT_DIR_REPLY].bytes, sis->dest_byte_count);
 		spin_unlock_bh(&ct->lock);
 	}