/** * @name fab_loop_inactive_all_hosts * @brief Loop through all known hosts and call iter_fn for each * @param [in] fab_ctx fabric context pointer * @param [in] iter_fn iteration function for each host * @param [in] arg argument to be passed to iter_fn * * @retval void Nothing * NOTE - This function can only be used as long as iter_fn * does not require any global list manipulations eg host add/del etc. */ void fab_loop_all_inactive_hosts(fab_struct_t *fab_ctx, GHFunc iter_fn, void *arg) { c_rd_lock(&fab_ctx->lock); __fab_loop_all_inactive_hosts(fab_ctx, iter_fn, arg); c_rd_unlock(&fab_ctx->lock); }
/** * __lldp_init_neigh_pair_adjacencies - * * Send neigh connections betwenn two switches to routing module * NOTE - lockless version expects locking by the caller */ void __lldp_init_neigh_pair_adjacencies(tr_neigh_query_arg_t *arg) { topo_hdl_t *topo; lldp_switch_t *from_sw, *to_sw; lldp_neigh_t *neighbour; int locked = 0; if (!arg) { c_log_err("%s: Invalid arg", FN); return; } topo = arg->tr->topo_hdl; from_sw = lldp_get_switch_from_imap(topo, arg->src_sw); to_sw = lldp_get_switch_from_imap(topo, arg->dst_sw); if (!from_sw || !to_sw) { c_log_err("%s: NULL switch args", FN); return; } locked = !c_rd_trylock(&from_sw->lock); neighbour = g_hash_table_lookup(from_sw->neighbors, &to_sw->dpid); if (!neighbour) { if (locked) c_rd_unlock(&from_sw->lock); //c_log_err("%s: lldp neigh %llx of %llx not found", // FN, to_sw->dpid, from_sw->dpid); return; } arg->src_dpid = from_sw->dpid; arg->dst_dpid = to_sw->dpid; lldp_traverse_all_neigh_ports(neighbour, lldp_send_rt_neigh_conn, (void *)arg); if (locked) c_rd_unlock(&from_sw->lock); }
/** * lldp_port_traverse_all - * * Traverse through all the ports of a switch calling iter_fn for each port */ void lldp_port_traverse_all(lldp_switch_t *lldpsw, GHFunc iter_fn, void *arg) { c_rd_lock(&lldpsw->lock); if (lldpsw->ports) { g_hash_table_foreach(lldpsw->ports, (GHFunc)iter_fn, arg); } c_rd_unlock(&lldpsw->lock); return; }
/** * lldp_switch_traverse_all - * * Traverse through all the switch list calling iter_fn for each switch found */ void lldp_switch_traverse_all(topo_hdl_t *topo_hdl, GHFunc iter_fn, void *arg) { c_rd_lock(&topo_hdl->switch_lock); if (topo_hdl->switches) { g_hash_table_foreach(topo_hdl->switches, (GHFunc)iter_fn, arg); } c_rd_unlock(&topo_hdl->switch_lock); }
c_app_info_t * c_app_get(ctrl_hdl_t *c_hdl, char *app_name) { c_app_info_t *app = NULL; c_rd_lock(&c_hdl->lock); if ((app = __c_app_lookup(c_hdl, app_name))) { atomic_inc(&app->ref, 1); } c_rd_unlock(&c_hdl->lock); return app; }
/** * @name fab_host_delete - * @brief Delete a fabric host * @parama [in] fab_ctx: fab context pointer * @param [in] dpid: switch dpid to the connected host * @param [in] sw_alias: switch alias id to the connected host * @param [un] fl: struct flow defining a host * @param [in] locked: flag to specify whether fab_ctx is already held or not * @param [in] deactivate: flag to specify whether to only deactivate not delete * * @retval int zero if no error else non-zero */ int fab_host_delete(fab_struct_t *fab_ctx, struct flow *fl, uint8_t *tenant_id, uint8_t *network_id, bool locked, bool deactivate, bool sync_ha) { fab_host_t *lkup_host, *host; char *host_pstr; int err = 0; bool dont_free = false; fab_port_t *port; fab_switch_t *sw; struct fab_host_service_arg iter_arg = { false, NULL, (send_cb_t)mul_app_ha_proc }; lkup_host = fab_host_create(0, 0, fl, tenant_id, network_id); if (sync_ha && mul_app_is_master()) { fabric_service_send_host_info(lkup_host, NULL, &iter_arg); } if (!locked) c_wr_lock(&fab_ctx->lock); if (!(host = g_hash_table_lookup(fab_ctx->host_htbl, lkup_host))) { if (!deactivate) { err = fab_host_delete_inactive(fab_ctx, lkup_host, true); } else { app_log_debug("%s: No active host", FN); err = -1; } goto done; } host->dead = true; __fab_host_route_delete(host, NULL, fab_ctx); __fab_del_pending_routes_tofro_host(fab_ctx, host); if (host->tenant_nw) { host->tenant_nw->host_list = g_slist_remove(host->tenant_nw->host_list, host); fab_tenant_nw_put(host->tenant_nw); host->tenant_nw = NULL; } if (deactivate) { fab_host_clone_prop(lkup_host, host); host_pstr = fab_dump_single_host(lkup_host); app_log_debug("%s: Host Active->Inactive %s", FN, host_pstr); free(host_pstr); fab_host_add_inactive(fab_ctx, lkup_host, true); dont_free = true; } else { /* Force port off the host and hence its host ref */ if ((sw = __fab_switch_get(fab_ctx, host->sw.swid))) { c_rd_lock(&sw->lock); if ((port = __fab_port_find(fab_ctx, sw, host->sw.port)) && port->host == host) { fab_host_put(port->host); port->host = NULL; } fab_switch_put_locked(sw); c_rd_unlock(&sw->lock); } host_pstr = fab_dump_single_host(lkup_host); app_log_debug("%s: Host Deleted %s", FN, host_pstr); free(host_pstr); } g_hash_table_remove(fab_ctx->host_htbl, host); done: if (!locked) c_wr_unlock(&fab_ctx->lock); if (!dont_free) fab_free(lkup_host); return err; }