struct in_addr          ms_addr_ip4;
        struct in_addr          sgsn_addr_ip4;
 
+       struct net_device       *dev;
+
        atomic_t                tx_seq;
        struct rcu_head         rcu_head;
 };
        return false;
 }
 
+static int gtp_rx(struct pdp_ctx *pctx, struct sk_buff *skb, unsigned int hdrlen,
+                 bool xnet)
+{
+       struct pcpu_sw_netstats *stats;
+
+       if (!gtp_check_src_ms(skb, pctx, hdrlen)) {
+               netdev_dbg(pctx->dev, "No PDP ctx for this MS\n");
+               return 1;
+       }
+
+       /* Get rid of the GTP + UDP headers. */
+       if (iptunnel_pull_header(skb, hdrlen, skb->protocol, xnet))
+               return -1;
+
+       netdev_dbg(pctx->dev, "forwarding packet from GGSN to uplink\n");
+
+       /* Now that the UDP and the GTP header have been removed, set up the
+        * new network header. This is required by the upper layer to
+        * calculate the transport header.
+        */
+       skb_reset_network_header(skb);
+
+       skb->dev = pctx->dev;
+
+       stats = this_cpu_ptr(pctx->dev->tstats);
+       u64_stats_update_begin(&stats->syncp);
+       stats->rx_packets++;
+       stats->rx_bytes += skb->len;
+       u64_stats_update_end(&stats->syncp);
+
+       netif_rx(skb);
+       return 0;
+}
+
 /* 1 means pass up to the stack, -1 means drop and 0 means decapsulated. */
 static int gtp0_udp_encap_recv(struct gtp_dev *gtp, struct sk_buff *skb,
                               bool xnet)
                return 1;
        }
 
-       if (!gtp_check_src_ms(skb, pctx, hdrlen)) {
-               netdev_dbg(gtp->dev, "No PDP ctx for this MS\n");
-               return 1;
-       }
-
-       /* Get rid of the GTP + UDP headers. */
-       return iptunnel_pull_header(skb, hdrlen, skb->protocol, xnet);
+       return gtp_rx(pctx, skb, hdrlen, xnet);
 }
 
 static int gtp1u_udp_encap_recv(struct gtp_dev *gtp, struct sk_buff *skb,
                return 1;
        }
 
-       if (!gtp_check_src_ms(skb, pctx, hdrlen)) {
-               netdev_dbg(gtp->dev, "No PDP ctx for this MS\n");
-               return 1;
-       }
-
-       /* Get rid of the GTP + UDP headers. */
-       return iptunnel_pull_header(skb, hdrlen, skb->protocol, xnet);
+       return gtp_rx(pctx, skb, hdrlen, xnet);
 }
 
 static void gtp_encap_destroy(struct sock *sk)
  */
 static int gtp_encap_recv(struct sock *sk, struct sk_buff *skb)
 {
-       struct pcpu_sw_netstats *stats;
        struct gtp_dev *gtp;
+       int ret = 0;
        bool xnet;
-       int ret;
 
        gtp = rcu_dereference_sk_user_data(sk);
        if (!gtp)
        switch (ret) {
        case 1:
                netdev_dbg(gtp->dev, "pass up to the process\n");
-               return 1;
+               break;
        case 0:
-               netdev_dbg(gtp->dev, "forwarding packet from GGSN to uplink\n");
                break;
        case -1:
                netdev_dbg(gtp->dev, "GTP packet has been dropped\n");
                kfree_skb(skb);
-               return 0;
+               ret = 0;
+               break;
        }
 
-       /* Now that the UDP and the GTP header have been removed, set up the
-        * new network header. This is required by the upper layer to
-        * calculate the transport header.
-        */
-       skb_reset_network_header(skb);
-
-       skb->dev = gtp->dev;
-
-       stats = this_cpu_ptr(gtp->dev->tstats);
-       u64_stats_update_begin(&stats->syncp);
-       stats->rx_packets++;
-       stats->rx_bytes += skb->len;
-       u64_stats_update_end(&stats->syncp);
-
-       netif_rx(skb);
-
-       return 0;
+       return ret;
 }
 
 static int gtp_dev_init(struct net_device *dev)
        if (pctx == NULL)
                return -ENOMEM;
 
+       pctx->dev = gtp->dev;
        ipv4_pdp_fill(pctx, info);
        atomic_set(&pctx->tx_seq, 0);