#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/mutex.h>
+#include <linux/netdevice.h>
 #include <rdma/rdma_netlink.h>
 
 #include "core_priv.h"
 }
 EXPORT_SYMBOL(ib_find_pkey);
 
+/**
+ * ib_get_net_dev_by_params() - Return the appropriate net_dev
+ * for a received CM request
+ * @dev:       An RDMA device on which the request has been received.
+ * @port:      Port number on the RDMA device.
+ * @pkey:      The Pkey the request came on.
+ * @gid:       A GID that the net_dev uses to communicate.
+ * @addr:      Contains the IP address that the request specified as its
+ *             destination.
+ */
+struct net_device *ib_get_net_dev_by_params(struct ib_device *dev,
+                                           u8 port,
+                                           u16 pkey,
+                                           const union ib_gid *gid,
+                                           const struct sockaddr *addr)
+{
+       struct net_device *net_dev = NULL;
+       struct ib_client_data *context;
+
+       if (!rdma_protocol_ib(dev, port))
+               return NULL;
+
+       down_read(&lists_rwsem);
+
+       list_for_each_entry(context, &dev->client_data_list, list) {
+               struct ib_client *client = context->client;
+
+               if (context->going_down)
+                       continue;
+
+               if (client->get_net_dev_by_params) {
+                       net_dev = client->get_net_dev_by_params(dev, port, pkey,
+                                                               gid, addr,
+                                                               context->data);
+                       if (net_dev)
+                               break;
+               }
+       }
+
+       up_read(&lists_rwsem);
+
+       return net_dev;
+}
+EXPORT_SYMBOL(ib_get_net_dev_by_params);
+
 static int __init ib_core_init(void)
 {
        int ret;
 
 #include <linux/rwsem.h>
 #include <linux/scatterlist.h>
 #include <linux/workqueue.h>
+#include <linux/socket.h>
 #include <uapi/linux/if_ether.h>
 
 #include <linux/atomic.h>
        void (*add)   (struct ib_device *);
        void (*remove)(struct ib_device *, void *client_data);
 
+       /* Returns the net_dev belonging to this ib_client and matching the
+        * given parameters.
+        * @dev:         An RDMA device that the net_dev use for communication.
+        * @port:        A physical port number on the RDMA device.
+        * @pkey:        P_Key that the net_dev uses if applicable.
+        * @gid:         A GID that the net_dev uses to communicate.
+        * @addr:        An IP address the net_dev is configured with.
+        * @client_data: The device's client data set by ib_set_client_data().
+        *
+        * An ib_client that implements a net_dev on top of RDMA devices
+        * (such as IP over IB) should implement this callback, allowing the
+        * rdma_cm module to find the right net_dev for a given request.
+        *
+        * The caller is responsible for calling dev_put on the returned
+        * netdev. */
+       struct net_device *(*get_net_dev_by_params)(
+                       struct ib_device *dev,
+                       u8 port,
+                       u16 pkey,
+                       const union ib_gid *gid,
+                       const struct sockaddr *addr,
+                       void *client_data);
        struct list_head list;
 };
 
 int ib_check_mr_status(struct ib_mr *mr, u32 check_mask,
                       struct ib_mr_status *mr_status);
 
+struct net_device *ib_get_net_dev_by_params(struct ib_device *dev, u8 port,
+                                           u16 pkey, const union ib_gid *gid,
+                                           const struct sockaddr *addr);
+
 #endif /* IB_VERBS_H */