+void
+lnet_ni_free(struct lnet_ni *ni)
+{
+ int i;
+
+ lnet_net_remove_cpts(ni->ni_cpts, ni->ni_ncpts, ni->ni_net);
+
+ if (ni->ni_refs != NULL)
+ cfs_percpt_free(ni->ni_refs);
+
+ if (ni->ni_tx_queues != NULL)
+ cfs_percpt_free(ni->ni_tx_queues);
+
+ if (ni->ni_cpts != NULL)
+ cfs_expr_list_values_free(ni->ni_cpts, ni->ni_ncpts);
+
+ for (i = 0; i < LNET_INTERFACES_NUM &&
+ ni->ni_interfaces[i] != NULL; i++) {
+ LIBCFS_FREE(ni->ni_interfaces[i],
+ strlen(ni->ni_interfaces[i]) + 1);
+ }
+
+ /* release reference to net namespace */
+ if (ni->ni_net_ns != NULL)
+ put_net(ni->ni_net_ns);
+
+ LIBCFS_FREE(ni, sizeof(*ni));
+}
+
+void
+lnet_net_free(struct lnet_net *net)
+{
+ struct list_head *tmp, *tmp2;
+ struct lnet_ni *ni;
+
+ LASSERT(list_empty(&net->net_ni_zombie));
+
+ /*
+ * delete any nis that haven't been added yet. This could happen
+ * if there is a failure on net startup
+ */
+ list_for_each_safe(tmp, tmp2, &net->net_ni_added) {
+ ni = list_entry(tmp, struct lnet_ni, ni_netlist);
+ list_del_init(&ni->ni_netlist);
+ lnet_ni_free(ni);
+ }
+
+ /* delete any nis which have been started. */
+ list_for_each_safe(tmp, tmp2, &net->net_ni_list) {
+ ni = list_entry(tmp, struct lnet_ni, ni_netlist);
+ list_del_init(&ni->ni_netlist);
+ lnet_ni_free(ni);
+ }
+
+ if (net->net_cpts != NULL)
+ LIBCFS_FREE(net->net_cpts,
+ sizeof(*net->net_cpts) * net->net_ncpts);
+
+ LIBCFS_FREE(net, sizeof(*net));
+}
+
+struct lnet_net *
+lnet_net_alloc(__u32 net_id, struct list_head *net_list)
+{
+ struct lnet_net *net;
+
+ if (!lnet_net_unique(net_id, net_list, NULL)) {
+ CERROR("Duplicate net %s. Ignore\n",
+ libcfs_net2str(net_id));
+ return NULL;
+ }
+
+ LIBCFS_ALLOC(net, sizeof(*net));
+ if (net == NULL) {
+ CERROR("Out of memory creating network %s\n",
+ libcfs_net2str(net_id));
+ return NULL;
+ }
+
+ INIT_LIST_HEAD(&net->net_list);
+ INIT_LIST_HEAD(&net->net_ni_list);
+ INIT_LIST_HEAD(&net->net_ni_added);
+ INIT_LIST_HEAD(&net->net_ni_zombie);
+
+ net->net_id = net_id;
+ net->net_state = LNET_NET_STATE_INIT;
+
+ /* initialize global paramters to undefiend */
+ net->net_tunables.lct_peer_timeout = -1;
+ net->net_tunables.lct_max_tx_credits = -1;
+ net->net_tunables.lct_peer_tx_credits = -1;
+ net->net_tunables.lct_peer_rtr_credits = -1;
+
+ if (net_list)
+ list_add_tail(&net->net_list, net_list);
+
+ return net;
+}
+
+static int
+lnet_ni_add_interface(struct lnet_ni *ni, char *iface)