.fill_info      = gtp_fill_info,
 };
 
-static struct net *gtp_genl_get_net(struct net *src_net, struct nlattr *tb[])
-{
-       struct net *net;
-
-       /* Examine the link attributes and figure out which network namespace
-        * we are talking about.
-        */
-       if (tb[GTPA_NET_NS_FD])
-               net = get_net_ns_by_fd(nla_get_u32(tb[GTPA_NET_NS_FD]));
-       else
-               net = get_net(src_net);
-
-       return net;
-}
-
 static int gtp_hashtable_new(struct gtp_dev *gtp, int hsize)
 {
        int i;
        return 0;
 }
 
-static struct net_device *gtp_find_dev(struct net *net, int ifindex)
+static struct gtp_dev *gtp_find_dev(struct net *src_net, struct nlattr *nla[])
 {
-       struct gtp_net *gn = net_generic(net, gtp_net_id);
-       struct gtp_dev *gtp;
+       struct gtp_dev *gtp = NULL;
+       struct net_device *dev;
+       struct net *net;
 
-       list_for_each_entry_rcu(gtp, &gn->gtp_dev_list, list) {
-               if (ifindex == gtp->dev->ifindex)
-                       return gtp->dev;
-       }
-       return NULL;
+       /* Examine the link attributes and figure out which network namespace
+        * we are talking about.
+        */
+       if (nla[GTPA_NET_NS_FD])
+               net = get_net_ns_by_fd(nla_get_u32(nla[GTPA_NET_NS_FD]));
+       else
+               net = get_net(src_net);
+
+       if (IS_ERR(net))
+               return NULL;
+
+       /* Check if there's an existing gtpX device to configure */
+       dev = dev_get_by_index_rcu(net, nla_get_u32(nla[GTPA_LINK]));
+       if (dev->netdev_ops == >p_netdev_ops)
+               gtp = netdev_priv(dev);
+
+       put_net(net);
+       return gtp;
 }
 
 static void ipv4_pdp_fill(struct pdp_ctx *pctx, struct genl_info *info)
        }
 }
 
-static int ipv4_pdp_add(struct net_device *dev, struct genl_info *info)
+static int ipv4_pdp_add(struct gtp_dev *gtp, struct genl_info *info)
 {
-       struct gtp_dev *gtp = netdev_priv(dev);
+       struct net_device *dev = gtp->dev;
        u32 hash_ms, hash_tid = 0;
        struct pdp_ctx *pctx;
        bool found = false;
 
 static int gtp_genl_new_pdp(struct sk_buff *skb, struct genl_info *info)
 {
-       struct net_device *dev;
-       struct net *net;
+       struct gtp_dev *gtp;
+       int err;
 
        if (!info->attrs[GTPA_VERSION] ||
            !info->attrs[GTPA_LINK] ||
                return -EINVAL;
        }
 
-       net = gtp_genl_get_net(sock_net(skb->sk), info->attrs);
-       if (IS_ERR(net))
-               return PTR_ERR(net);
+       rcu_read_lock();
 
-       /* Check if there's an existing gtpX device to configure */
-       dev = gtp_find_dev(net, nla_get_u32(info->attrs[GTPA_LINK]));
-       if (dev == NULL) {
-               put_net(net);
-               return -ENODEV;
+       gtp = gtp_find_dev(sock_net(skb->sk), info->attrs);
+       if (!gtp) {
+               err = -ENODEV;
+               goto out_unlock;
        }
-       put_net(net);
 
-       return ipv4_pdp_add(dev, info);
+       err = ipv4_pdp_add(gtp, info);
+
+out_unlock:
+       rcu_read_unlock();
+       return err;
 }
 
 static int gtp_genl_del_pdp(struct sk_buff *skb, struct genl_info *info)
 {
-       struct net_device *dev;
        struct pdp_ctx *pctx;
        struct gtp_dev *gtp;
-       struct net *net;
+       int err = 0;
 
        if (!info->attrs[GTPA_VERSION] ||
            !info->attrs[GTPA_LINK])
                return -EINVAL;
 
-       net = gtp_genl_get_net(sock_net(skb->sk), info->attrs);
-       if (IS_ERR(net))
-               return PTR_ERR(net);
+       rcu_read_lock();
 
-       /* Check if there's an existing gtpX device to configure */
-       dev = gtp_find_dev(net, nla_get_u32(info->attrs[GTPA_LINK]));
-       if (dev == NULL) {
-               put_net(net);
-               return -ENODEV;
+       gtp = gtp_find_dev(sock_net(skb->sk), info->attrs);
+       if (!gtp) {
+               err = -ENODEV;
+               goto out_unlock;
        }
-       put_net(net);
-
-       gtp = netdev_priv(dev);
 
        switch (nla_get_u32(info->attrs[GTPA_VERSION])) {
        case GTP_V0:
-               if (!info->attrs[GTPA_TID])
-                       return -EINVAL;
+               if (!info->attrs[GTPA_TID]) {
+                       err = -EINVAL;
+                       goto out_unlock;
+               }
                pctx = gtp0_pdp_find(gtp, nla_get_u64(info->attrs[GTPA_TID]));
                break;
        case GTP_V1:
-               if (!info->attrs[GTPA_I_TEI])
-                       return -EINVAL;
+               if (!info->attrs[GTPA_I_TEI]) {
+                       err = -EINVAL;
+                       goto out_unlock;
+               }
                pctx = gtp1_pdp_find(gtp, nla_get_u64(info->attrs[GTPA_I_TEI]));
                break;
 
        default:
-               return -EINVAL;
+               err = -EINVAL;
+               goto out_unlock;
        }
 
-       if (pctx == NULL)
-               return -ENOENT;
+       if (!pctx) {
+               err = -ENOENT;
+               goto out_unlock;
+       }
 
        if (pctx->gtp_version == GTP_V0)
-               netdev_dbg(dev, "GTPv0-U: deleting tunnel id = %llx (pdp %p)\n",
+               netdev_dbg(gtp->dev, "GTPv0-U: deleting tunnel id = %llx (pdp %p)\n",
                           pctx->u.v0.tid, pctx);
        else if (pctx->gtp_version == GTP_V1)
-               netdev_dbg(dev, "GTPv1-U: deleting tunnel id = %x/%x (pdp %p)\n",
+               netdev_dbg(gtp->dev, "GTPv1-U: deleting tunnel id = %x/%x (pdp %p)\n",
                           pctx->u.v1.i_tei, pctx->u.v1.o_tei, pctx);
 
        hlist_del_rcu(&pctx->hlist_tid);
        hlist_del_rcu(&pctx->hlist_addr);
        kfree_rcu(pctx, rcu_head);
 
-       return 0;
+out_unlock:
+       rcu_read_unlock();
+       return err;
 }
 
 static struct genl_family gtp_genl_family;
 static int gtp_genl_get_pdp(struct sk_buff *skb, struct genl_info *info)
 {
        struct pdp_ctx *pctx = NULL;
-       struct net_device *dev;
        struct sk_buff *skb2;
        struct gtp_dev *gtp;
        u32 gtp_version;
-       struct net *net;
        int err;
 
        if (!info->attrs[GTPA_VERSION] ||
                return -EINVAL;
        }
 
-       net = gtp_genl_get_net(sock_net(skb->sk), info->attrs);
-       if (IS_ERR(net))
-               return PTR_ERR(net);
+       rcu_read_lock();
 
-       /* Check if there's an existing gtpX device to configure */
-       dev = gtp_find_dev(net, nla_get_u32(info->attrs[GTPA_LINK]));
-       if (dev == NULL) {
-               put_net(net);
-               return -ENODEV;
+       gtp = gtp_find_dev(sock_net(skb->sk), info->attrs);
+       if (!gtp) {
+               err = -ENODEV;
+               goto err_unlock;
        }
-       put_net(net);
-
-       gtp = netdev_priv(dev);
 
-       rcu_read_lock();
        if (gtp_version == GTP_V0 &&
            info->attrs[GTPA_TID]) {
                u64 tid = nla_get_u64(info->attrs[GTPA_TID]);