+EXPORT_SYMBOL(LNetNIFini);
+
+/**
+ * Grabs the ni data from the ni structure and fills the out
+ * parameters
+ *
+ * \param[in] ni network interface structure
+ * \param[out] cpt_count the number of cpts the ni is on
+ * \param[out] nid Network Interface ID
+ * \param[out] peer_timeout NI peer timeout
+ * \param[out] peer_tx_crdits NI peer transmit credits
+ * \param[out] peer_rtr_credits NI peer router credits
+ * \param[out] max_tx_credits NI max transmit credit
+ * \param[out] net_config Network configuration
+ */
+static void
+lnet_fill_ni_info(struct lnet_ni *ni, __u32 *cpt_count, __u64 *nid,
+ int *peer_timeout, int *peer_tx_credits,
+ int *peer_rtr_credits, int *max_tx_credits,
+ struct lnet_ioctl_net_config *net_config)
+{
+ int i;
+
+ if (ni == NULL)
+ return;
+
+ if (net_config == NULL)
+ return;
+
+ CLASSERT(ARRAY_SIZE(ni->ni_interfaces) ==
+ ARRAY_SIZE(net_config->ni_interfaces));
+
+ if (ni->ni_interfaces[0] != NULL) {
+ for (i = 0; i < ARRAY_SIZE(ni->ni_interfaces); i++) {
+ if (ni->ni_interfaces[i] != NULL) {
+ strncpy(net_config->ni_interfaces[i],
+ ni->ni_interfaces[i],
+ sizeof(net_config->ni_interfaces[i]));
+ }
+ }
+ }
+
+ *nid = ni->ni_nid;
+ *peer_timeout = ni->ni_peertimeout;
+ *peer_tx_credits = ni->ni_peertxcredits;
+ *peer_rtr_credits = ni->ni_peerrtrcredits;
+ *max_tx_credits = ni->ni_maxtxcredits;
+
+ net_config->ni_status = ni->ni_status->ns_status;
+
+ for (i = 0;
+ ni->ni_cpts != NULL && i < ni->ni_ncpts &&
+ i < LNET_MAX_SHOW_NUM_CPT;
+ i++)
+ net_config->ni_cpts[i] = ni->ni_cpts[i];
+
+ *cpt_count = ni->ni_ncpts;
+}
+
+int
+lnet_get_net_config(int idx, __u32 *cpt_count, __u64 *nid, int *peer_timeout,
+ int *peer_tx_credits, int *peer_rtr_credits,
+ int *max_tx_credits,
+ struct lnet_ioctl_net_config *net_config)
+{
+ struct lnet_ni *ni;
+ struct list_head *tmp;
+ int cpt;
+ int rc = -ENOENT;
+
+ cpt = lnet_net_lock_current();
+
+ list_for_each(tmp, &the_lnet.ln_nis) {
+ ni = list_entry(tmp, lnet_ni_t, ni_list);
+ if (idx-- == 0) {
+ rc = 0;
+ lnet_ni_lock(ni);
+ lnet_fill_ni_info(ni, cpt_count, nid, peer_timeout,
+ peer_tx_credits, peer_rtr_credits,
+ max_tx_credits, net_config);
+ lnet_ni_unlock(ni);
+ break;
+ }
+ }
+
+ lnet_net_unlock(cpt);
+ return rc;
+}
+
+int
+lnet_dyn_add_ni(lnet_pid_t requested_pid, char *nets,
+ __s32 peer_timeout, __s32 peer_cr, __s32 peer_buf_cr,
+ __s32 credits)
+{
+ lnet_ping_info_t *pinfo;
+ lnet_handle_md_t md_handle;
+ struct lnet_ni *ni;
+ struct list_head net_head;
+ int rc;
+
+ INIT_LIST_HEAD(&net_head);
+
+ /* Create a ni structure for the network string */
+ rc = lnet_parse_networks(&net_head, nets);
+ if (rc < 0)
+ return rc;
+
+ LNET_MUTEX_LOCK(&the_lnet.ln_api_mutex);
+
+ if (rc > 1) {
+ rc = -EINVAL; /* only add one interface per call */
+ goto failed0;
+ }
+
+ rc = lnet_ping_info_setup(&pinfo, &md_handle, 1 + lnet_get_ni_count(),
+ false);
+ if (rc != 0)
+ goto failed0;
+
+ rc = lnet_startup_lndnis(&net_head, peer_timeout, peer_cr,
+ peer_buf_cr, credits, NULL);
+ if (rc != 0)
+ goto failed1;
+
+ lnet_ping_target_update(pinfo, md_handle);
+ LNET_MUTEX_UNLOCK(&the_lnet.ln_api_mutex);
+
+ return 0;
+
+failed1:
+ lnet_ping_md_unlink(pinfo, &md_handle);
+ lnet_ping_info_free(pinfo);
+failed0:
+ LNET_MUTEX_UNLOCK(&the_lnet.ln_api_mutex);
+ while (!list_empty(&net_head)) {
+ ni = list_entry(net_head.next, struct lnet_ni, ni_list);
+ list_del_init(&ni->ni_list);
+ lnet_ni_free(ni);
+ }
+ return rc;
+}
+
+int
+lnet_dyn_del_ni(__u32 net)
+{
+ int rc;
+
+ LNET_MUTEX_LOCK(&the_lnet.ln_api_mutex);
+ rc = lnet_shutdown_lndni(net);
+ LNET_MUTEX_UNLOCK(&the_lnet.ln_api_mutex);
+
+ return rc;
+}