示例#1
0
/**
 * fab_host_delete_inactive - 
 * @fab_ctx : fab context pointer 
 * @lkup_host : host instance
 * @locked : flag to specify whether fab_ctx is already held or not
 *
 * Delete an inactive fabric host 
 */
int
fab_host_delete_inactive(fab_struct_t *fab_ctx, fab_host_t *lkup_host, 
                         bool locked) 
{
    fab_host_t *host;
    int err = 0;
    char *host_pstr;

    if (!locked) c_wr_lock(&fab_ctx->lock);

    if (!(host = g_hash_table_lookup(fab_ctx->inact_host_htbl, lkup_host))) {
        c_log_err("%s: No such inactive host", FN);
        err = -1;
        goto done;
    } 

    host_pstr = fab_dump_single_host(host);
    c_log_err("%s: Inactive Host deleted %s", FN, host_pstr);
    free(host_pstr);

    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;
    }
    g_hash_table_remove(fab_ctx->inact_host_htbl, host);

done:
    if (!locked) c_wr_unlock(&fab_ctx->lock);

    return err;

}
示例#2
0
/**
 * mul_route_service_get -
 *
 * Get a handle to the routing service 
 */
void *
mul_route_service_get(void)
{
    void *ptr = NULL;
    rt_apsp_t *rt_apsp_info;
    int serv_fd;

    c_log_debug("%s: ", FN);

    if ((serv_fd = shm_open(MUL_TR_SERVICE_NAME, O_RDONLY, 0)) < 0) {
        c_log_err("%s: Cant get service (unavailable)", FN);
        return NULL;
    }

    perror("shm_open");

    ptr = mmap(0, RT_APSP_BLOCK_SIZE, PROT_READ, MAP_SHARED, serv_fd, 0);
    if (ptr == MAP_FAILED) {
        c_log_err("%s: Cant get service (failed to map)", FN);
        return NULL;
    }

    rt_apsp_info = calloc(1, sizeof(*rt_apsp_info));
    if (!rt_apsp_info) {
        c_log_err("%s: RT apsp info allocation fail", FN);
        return NULL;
    }

    mul_route_init_block_meta(rt_apsp_info, ptr);

    close(serv_fd);

    return (void *)rt_apsp_info;
}
示例#3
0
static int 
c_service_clr_rcv_buf(mul_service_t *service)
{
    char buf[1024];
    int ret = 0;
    int retries = 0;

    if (service->conn.dead) {
        return -1;
    }

    if (c_make_socket_nonblocking(service->conn.fd))
        c_log_err("%s: Failed to set non-blocking", FN);
    while(1) {
        ret = recv(service->conn.fd, buf, 1024, MSG_DONTWAIT);
        if (ret < 0) {
            break;
        }

        if (retries++ >= 100) {
            c_log_err("%s: noise on service(%s) conn",
                      FN, service->service_name);
            ret = -1;
            break;
        }
    }

    if (c_make_socket_blocking(service->conn.fd)) 
        c_log_err("%s: Failed to set blocking", FN);

    return ret;
}
示例#4
0
// Note:
// As main thread will be responsible for the handling
// Tying up the main thread to the worker context in the main thread
// is the key. The logic for the controller operates on ?
// So, once the information has been put into the ?? , then the logic
// can get the information from the c_switch_t->cmn_ctx where the 
// hashtable stores the DPID and switch information 
static int
c_thread_event_loop_lib_support(struct c_main_ctx *main_ctx)
{
    c_switch_t *sw = NULL;
    struct cbuf *b = NULL;
    
    c_log_debug("%s: tid(%u)", __FUNCTION__, (unsigned int)pthread_self());
    // instead of looping on the socket fd, the main thread
    // will be looping on the cbuf.
    
    // Not considering the application threads for now
    //return event_base_dispatch(cmn_ctx->base);

    // check cbuf
    // get first message from buffer and begin the processing.
    if(cbuf_list_queue_len(&ctrl_hdl.c_main_buf_head))
    {
	// Get the first message
	b = cbuf_list_dequeue(&ctrl_hdl.c_main_buf_head);
    }

    if (!of_hdr_valid(b->data)) 
    {
	c_log_err("%s: Corrupted header", FN);
	return 0; /* Close the socket */
    }

    // No need to allocate the worker thread
    // Pass the main_ctx now. Previously, this was:
    // sw = of_switch_alloc(c_wrk_ctx);
    sw = of_switch_alloc(main_ctx);
    of_switch_recv_msg(sw, b);

    return 0;
}
示例#5
0
/**
 * @name fab_route_elem_valid
 * @brief Check if a fabric route elem is valid
 */
static int 
fab_route_elem_valid(void *rt_path_arg, void *route_arg)
{
    rt_path_elem_t *rt_elem = rt_path_arg;
    fab_switch_t *sw;
    fab_route_t *froute = route_arg;

    sw = __fab_switch_get_with_alias(fab_ctx, rt_elem->sw_alias);
    if (!sw) {
        goto route_inv_switch;
    }

    if ((rt_elem->flags & RT_PELEM_LAST_HOP)) {
        if (!fab_port_valid(fab_ctx, sw, froute->dst->sw.port)) {
            goto route_inv_port;
        }
    } else {
        if (!fab_port_up(fab_ctx, sw, rt_elem->link.la)) {
            goto route_inv_port;
        }
    }

    fab_switch_put_locked(sw);

    return 0;

route_inv_port:
    fab_switch_put_locked(sw);
route_inv_switch:
    c_log_err("%s: Route elem err", FN);
    return -1;
}
示例#6
0
/**
 * @name mul_neigh_get -
 * @brief Get a switch's neighbour info using TR service
 * @param [in] service Pointer to the client's service
 * @param [in] dpid datapath-id of the switch whose neighborhood 
 *                  info us required 
 * @retval struct cbuf * Pointer to the buffer response from the server
 *
 * This function uses auxillary mlapi type C_AUX_CMD_TR_GET_NEIGH
 * Caller needs to free returned cbuf (if not NULL)
 */
struct cbuf *
mul_neigh_get(void *service, uint64_t dpid)
{
    struct cbuf *b;
    struct c_ofp_auxapp_cmd *cofp_auc;
    struct c_ofp_req_dpid_attr *cofp_rda;
    struct ofp_header *h;

    b = of_prep_msg(sizeof(struct c_ofp_auxapp_cmd) +
                    sizeof(struct c_ofp_req_dpid_attr),
                    C_OFPT_AUX_CMD, 0);

    cofp_auc = (void *)(b->data);
    cofp_auc->cmd_code = htonl(C_AUX_CMD_TR_GET_NEIGH);
    cofp_rda = (void *)(cofp_auc->data);
    cofp_rda->datapath_id = htonll(dpid);
    
    c_service_send(service, b);
    b = c_service_wait_response(service);
    if (b) {
        h = (void *)(b->data);
        if (h->type == C_OFPT_ERR_MSG) {
            c_log_err("%s: Failed", FN);
            free_cbuf(b);
            return NULL;
        }
    }

    return b;
}
示例#7
0
int
mul_cc_recv_pkt(uint64_t dp_id, uint8_t aux_id, void *of_msg, uint32_t msg_len)
{
    
    struct cbuf *b = NULL;
    
    if(cbuf_list_queue_len(&ctrl_hdl.c_main_buf_head) > 1024) 
    {
	// Throw an error
	c_log_err("Main thread buffer queue is full\n");
    }
    else
    {
	// Allocate
	b = alloc_cbuf(msg_len);
	if(b == NULL)
	{
	    // Kajal: What else to log for a new connection
	    // chann_id.aux_id -- is of type uint64_t 
	    // c_log_err("Buffer node could not be allocated dp-id:0x%x aux-id:0x%x\n",
	    //          chann_id.dp_id, chann_id.aux_id);
	    //return 0;
	}

	// if_msg should be freed by library assuming that 
	// buffer should copy it.
	memcpy(b->data, of_msg, msg_len);
	// Insert buffer in queue	
	cbuf_list_queue_tail(&ctrl_hdl.c_main_buf_head, b);
    }

    return 0;
}
示例#8
0
文件: mul_lldp.c 项目: ashang/openmul
static void
__lldp_set_next_tr_timeo(time_t timeo)
{
    time_t ctime = time(NULL);
    if (!topo_hdl->tr->rt_timeo_set) {
        topo_hdl->tr->rt.rt_next_trigger_ts = ctime + timeo;
        topo_hdl->tr->rt_timeo_set = true;
        c_log_err("%s: Topo routing set to expire at %lu",
                   FN, topo_hdl->tr->rt.rt_next_trigger_ts);
    }
}
示例#9
0
文件: mul_lldp.c 项目: ashang/openmul
/**
 * __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);
}
示例#10
0
/**
 * mul_route_service_alive -
 * @service : Handle to the route service 
 *
 * Checks status of routing service 
 */
static bool
mul_route_service_alive(void *service)
{
    rt_apsp_t *rt_apsp_info = service;
    time_t curr_ts = time(NULL);

    if (curr_ts >
        (rt_apsp_info->state_info->serv_ts + (2*RT_HB_INTVL_SEC))) {
        c_log_err("%s: %s not available", FN, MUL_TR_SERVICE_NAME);
        return false;
    }

    return true;
}
示例#11
0
/**
 * @name    fab_port_add_cb
 * @brief   switch port add notifier handler 
 * @ingroup Fabric Application 
 *
 * @param [in] sw Pointer to infra switch pointer
 * @param [in] port Pointer to infra port pointer
 *
 * @retval void Nothing
 *
 */
static void
fab_port_add_cb(mul_switch_t *sw,  mul_port_t *port)
{
    fab_switch_t *fab_sw;

    fab_sw = fab_switch_get(fab_ctx, sw->dpid);
    if (!fab_sw) {
        c_log_err("%s: Unknown switch (0x%llx)", FN, U642ULL(sw->dpid));
        return;
    }

    fab_port_add(fab_ctx, fab_sw, port->port_no, port->config, port->state); 
    fab_activate_all_hosts_on_switch_port(fab_ctx, sw->dpid, port->port_no);
    fab_switch_put(fab_sw);
}
示例#12
0
c_app_info_t *
c_app_alloc(void *ctx)
{
    c_app_info_t *app = NULL;
    
    app = calloc(1, sizeof(c_app_info_t));
    if (!app) {
        c_log_err("%s: App alloc failed", FN);
        return NULL;
    }

    app->ctx = ctx;

    return app;
}
示例#13
0
/**
 * mul_route_list_dump -
 *
 */
static void
mul_route_list_dump(rt_list_t *path_head)
{
    rt_list_t *cur_path = path_head;
    int i = 0;
    char *dump_route;

    while (cur_path) {
        c_log_debug("List # %d", i++);
        dump_route = mul_dump_route(cur_path->route);
        c_log_err(" %s", dump_route);
        if (dump_route) free(dump_route);
        cur_path = cur_path->next;
    }
}
示例#14
0
/**
 * @name    fab_port_del_cb
 * @brief   switch port del notifier handler 
 * @ingroup Fabric Application 
 *
 * @param [in] sw Pointer to infra switch pointer
 * @param [in] port Pointer to infra port pointer
 *
 * @retval void Nothing
 *
 */
static void
fab_port_del_cb(mul_switch_t *sw,  mul_port_t *port)
{
    fab_switch_t *fab_sw;

    fab_sw = fab_switch_get(fab_ctx, sw->dpid);
    if (!fab_sw) {
        c_log_err("%s: Unknown switch (0x%llx)", FN, U642ULL(sw->dpid));
        return;
    }

    fab_port_delete(fab_ctx, fab_sw, port->port_no);
    fab_delete_routes_with_port(fab_ctx, sw->alias_id, port->port_no);
    fab_switch_put(fab_sw);
}
示例#15
0
/**
 * @name    fab_switch_add_notifier 
 * @brief   switch add notifier handler 
 * @ingroup Fabric Application 
 *
 * @param [in] sw Pointer to infra switch pointer
 *
 * @retval void Nothing
 *
 */
static void
fab_switch_add_notifier(mul_switch_t *sw)
{
    if (fab_switch_add(fab_ctx, sw->dpid, sw->alias_id)) {
        c_log_err("%s: Failed", FN);
        return;
    }

    fab_add_dhcp_tap_per_switch(NULL, sw->dpid);

    if(fab_ctx->fab_learning == FAB_PROXY_ARP_ENABLED) {
        fab_add_arp_tap_per_switch(NULL, sw->dpid);
    }
    else {
        fab_add_all_flows_per_switch(sw->dpid);
    }
}
示例#16
0
static void
c_service_validity_timer(evutil_socket_t fd UNUSED, short event UNUSED,
                         void *arg)
{ 
    mul_service_t *service = arg;
    struct timeval tv = { 5, 0 };

    if (service->conn.dead) return;

    if (!mul_service_alive(service)) {
        c_log_err("%s: service died", service->service_name);
        return c_service_reconnect(service);
    }

    if (service->valid_timer_event)
        evtimer_add(service->valid_timer_event, &tv);
}
示例#17
0
/**
 * tr_service_handler -
 *
 * Handler service requests 
 */
static void
tr_service_handler(void *tr_service, struct cbuf *b)
{
    struct c_ofp_auxapp_cmd *cofp_aac = (void *)(b->data);

    if (ntohs(cofp_aac->header.length) < sizeof(struct c_ofp_auxapp_cmd)) {
        c_log_err("%s: Size err (%u) of (%u)", FN,
                  ntohs(cofp_aac->header.length),
                  sizeof(struct c_ofp_auxapp_cmd));
        return tr_service_error(tr_service, b, OFPET_BAD_REQUEST, OFPBRC_BAD_LEN);
    }

    switch(ntohl(cofp_aac->cmd_code)) {
    case C_AUX_CMD_TR_GET_NEIGH:
        return tr_service_request_neigh(tr_service, b, cofp_aac);
    default:
        tr_service_error(tr_service, b, OFPET_BAD_REQUEST, OFPBRC_BAD_GENERIC);
    }
}
示例#18
0
/**
 * @name fab_port_chg
 * @brief Application port change callback 
 */
static void
fab_port_chg(mul_switch_t *sw,  mul_port_t *port, bool adm, bool link)
{
    fab_switch_t *fab_sw;

    fab_sw = fab_switch_get(fab_ctx, sw->dpid);
    if (!fab_sw) {
        c_log_err("%s: Unknown switch (0x%llx)", FN, U642ULL(sw->dpid));
        return;
    }

    fab_port_update(fab_ctx, fab_sw, port->port_no, port->config, port->state);
    if (adm && link) {
        fab_ctx->rt_scan_all_pending = true;
    } else if (!adm || !link) {
        fab_delete_routes_with_port(fab_ctx, sw->alias_id, port->port_no);
    }
    fab_switch_put(fab_sw);
}
示例#19
0
/**
 * mul_route_get -
 * @rt_service : Handle to the route service 
 * @src_sw : Source node  
 * @dest_sw : Destination node 
 *
 * Front-end api of routing service to get route from source to dest 
 * Applicable when users dont want multi-pathing support
 */
GSList *
mul_route_get(void *rt_service, int src_sw, int dest_sw)
{
    rt_apsp_t *rt_apsp_info = rt_service;

    if (!mul_route_service_alive(rt_service)) {
        return 0;
    }

    if (src_sw < 0 || dest_sw < 0 ||
        ((src_sw != dest_sw) && (src_sw >= rt_apsp_info->state_info->nodes ||
        dest_sw >= rt_apsp_info->state_info->nodes))) {
        c_log_err("%s: src(%d) or dst(%d) out of range(%d)",
                  FN, src_sw, dest_sw, rt_apsp_info->state_info->nodes);
        return NULL;
    }

    return mul_route_apsp_get_sp(rt_service, src_sw, dest_sw);
}
示例#20
0
static int
c_worker_thread_run(struct c_worker_ctx *w_ctx)
{
    switch(w_ctx->cmn_ctx.run_state) {
    case THREAD_STATE_PRE_INIT:
        signal(SIGPIPE, SIG_IGN);
        w_ctx->cmn_ctx.run_state = THREAD_STATE_FINAL_INIT;
        break;
    case THREAD_STATE_FINAL_INIT:
        return c_worker_thread_final_init(w_ctx);
    case THREAD_STATE_RUNNING:
        return c_thread_event_loop((void *)w_ctx);
    default:
        c_log_err("Unknown run state");
        break;
    }

    return 0;
}
示例#21
0
/**
 * tr_service_request_neigh -
 *
 * Handle neigh request 
 */
static void
tr_service_request_neigh(void *tr_service,
                         struct cbuf *req_b,
                         struct c_ofp_auxapp_cmd *cofp_aac)
{
    struct cbuf *b;
    c_ofp_req_dpid_attr_t *req_dpid = (void *)(cofp_aac->data);

    if (ntohs(cofp_aac->header.length) < sizeof(*req_dpid)) {
        c_log_err("%s: Size err (%u) of (%u)", FN,
                  ntohs(cofp_aac->header.length),
                  sizeof(*req_dpid));
        return;
    }

    b = lldp_service_neigh_request(ntohll(req_dpid->datapath_id),
                                   cofp_aac->header.xid); 
    if (b) {
        c_service_send(tr_service, b);
    } else {
        tr_service_error(tr_service, req_b, OFPET_BAD_REQUEST, OFPBRC_BAD_DPID);
    }
}
示例#22
0
/**
 * @name mul_dump_neigh -
 * @brief Dump a switch's neighbour to a printable buffer
 * @param [in] b struct cbuf buffer containing response from the server
 * @param [in] free_bug flag to specify if buffer needs to be freed
 * 
 * @retval char * Print buffer
 */
char *
mul_dump_neigh(struct cbuf *b, bool free_buf)
{
    char *pbuf = calloc(1, TR_DFL_PBUF_SZ);
    c_ofp_auxapp_cmd_t *cofp_auc  = (void *)(b->data);    
    int num_ports, i = 0, len = 0;
    struct c_ofp_port_neigh *port;
    c_ofp_switch_neigh_t *neigh = (void *)(cofp_auc->data);
    bool neigh_switch = false;

    num_ports = (ntohs(cofp_auc->header.length) - (sizeof(c_ofp_switch_neigh_t) 
                + sizeof(c_ofp_auxapp_cmd_t)))/ sizeof(struct c_ofp_port_neigh);

    port = (void *)(neigh->data);
    for (; i < num_ports; i++) {
        neigh_switch = ntohs(port->neigh_present) & COFP_NEIGH_SWITCH ? 
                          true: false;
        len += snprintf(pbuf + len, TR_DFL_PBUF_SZ-len-1,
                    "%12u | %10s | 0x%10llx | %u\r\n",
                     ntohs(port->port_no), neigh_switch ? "SWITCH" : "EXT",
                     U642ULL(ntohll(port->neigh_dpid)),
                     ntohs(port->neigh_port));
        if (len >= TR_DFL_PBUF_SZ-1) {
            goto out_buf_err;
        }
        port++;
    }
out:
    if (free_buf) {
        free_cbuf(b);
    }
    return pbuf;
out_buf_err:
    c_log_err("%s: pbuf alloc failed", FN);
    goto out;
}
示例#23
0
static char *
mul_fabric_route_link_dump(struct c_ofp_route_link *rl, size_t n_links)
{
    int i = 0 , len = 0;
    char *pbuf = calloc(1, FAB_DFL_PBUF_SZ);

    if (!pbuf) {
        return NULL;
    }

    for (; i < n_links; i++) {
        len += snprintf(pbuf+len, FAB_DFL_PBUF_SZ-len-1,
                        "Node(0x%llx):Link(%hu)",
                        ntohll(rl->datapath_id), ntohs(rl->src_link));
        if (len >= FAB_DFL_PBUF_SZ-1) {
            c_log_err("%s: print buf overrun", FN);
            free(pbuf);
            return NULL;
        }
        rl++;
    }

    return pbuf;
}
示例#24
0
/**
 * @name mul_conx_mod_uflow -
 * @brief Add/Del a conx association for a user-supplied flow flow  
 * @param [in] add flag to specify add or del operation
 * @param [in] n_dpid number of source dpids requested 
 * @param [in] src_dps list of source dpids
 * @param [in] dst_dp Destination dpid 
 * @param [in] in_fl User-flow to match in incoming (source) switches
 * @param [in] tunnel_key Tunnel-id if connection between src and dest is overlay
 * @param [in] tunnel_type Tunnel-type (undefined for now)
 * @param [in] actions Actions to be applied at the egress node
 * @param [in] action_len Length of the actions 
 * @param [in] fl_flags Flow flags using which flow is to be installed in the core
 * @param [in] conx_flags Mask of following flags - 
 *                        CONX_UFLOW_FORCE: Force to add all path-flows irrespective of 
 *                                          failure in any path
 *                        CONX_UFLOW_DFL: Install the user flow with default low priority * 
 * @retval int 0 for success or non-0 for failure
 */
int
mul_conx_mod_uflow(void *service,
                   bool add,
                   size_t n_dpid,
                   uint64_t *src_dps,
                   uint64_t dst_dp,
                   struct flow *in_fl,
                   struct flow *in_mask,
                   uint32_t tunnel_key,
                   uint32_t tunnel_type,
                   void *actions,
                   size_t action_len,
                   uint64_t fl_flags,
                   uint32_t conx_flags)
{
    struct cbuf *b;
    struct c_ofp_auxapp_cmd *cofp_auc;
    struct c_conx_user_flow *conx_fl;
    int ret = 0;
    int i = 0;
    uint8_t zero_mac[6] = { 0, 0, 0, 0, 0, 0};
    size_t ext_len = 0;
    uint8_t *act_ptr = NULL;
    uint64_t *src_dpid;

    if (!service || n_dpid < 1 || n_dpid > 1024) return -1;

    if (tunnel_type == CONX_TUNNEL_OF &&
        (memcmp(in_mask->dl_dst, zero_mac, 6) ||
        memcmp(in_mask->dl_src, zero_mac, 6))) {
        c_log_err("uFlow can't use src-dst Mac match");
        return -1;
    }

    if (of_check_flow_wildcard_generic(in_fl, in_mask)) {
        c_log_debug("Conx add-uflow all-wc not allowed");
        return -1;
    }

    ext_len = action_len + (sizeof(uint64_t)*n_dpid);

    b = of_prep_msg(sizeof(*cofp_auc) + sizeof(*conx_fl) + ext_len,
                    C_OFPT_AUX_CMD, 0);
    if (!b) return -1;
    cofp_auc = CBUF_DATA(b);
    cofp_auc->cmd_code = add ? htonl(C_AUX_CMD_CONX_ADD_UFLOW):
                               htonl(C_AUX_CMD_CONX_DEL_UFLOW);

    conx_fl = ASSIGN_PTR(cofp_auc->data);   
    conx_fl->dst_dpid = htonll(dst_dp);
    conx_fl->tunnel_key = htonl(tunnel_key); /* Overridden as tenant-id */
    conx_fl->tunnel_type = htonl(tunnel_type);
    conx_fl->app_cookie = htonl(c_app_main_hdl.app_cookie);
    conx_fl->fl_flags = htonll(fl_flags);
    conx_fl->conx_flags = htonl(conx_flags);
    conx_fl->n_src = htonll(n_dpid);

    memcpy(&conx_fl->flow, in_fl, sizeof(struct flow));
    memcpy(&conx_fl->mask, in_mask, sizeof(struct flow));

    src_dpid = ASSIGN_PTR(conx_fl->src_dpid_list);
    for (i = 0; i < n_dpid; i++) {
        src_dpid[i] = htonll(src_dps[i]);
    }

    if (add && action_len) {
        act_ptr = INC_PTR8(conx_fl->src_dpid_list, sizeof(uint64_t)*n_dpid);
        memcpy(act_ptr, actions, action_len); 
    }

    c_service_send(service, b);
    if (!(fl_flags & C_FL_NO_ACK))  {
        b = c_service_wait_response(service);
        if (b) {
            cofp_auc = CBUF_DATA(b);
            if (!c_check_reply_type(b, C_AUX_CMD_SUCCESS)) {
                ret = 0;
            }
            free_cbuf(b);
        }
    }
    return ret;
}
示例#25
0
/**
 * fab_host_delete - 
 * @fab_ctx: fab context pointer 
 * @dpid : switch dpid to the connected host
 * @sw_alias : switch alias id to the connected host
 * @fl : flow defining a host 
 * @locked : flag to specify whether fab_ctx is already held or not
 * @deactivate : flag to specify whether to only deactivate not delete 
 *
 * Delete a fabric host 
 */
int
fab_host_delete(fab_struct_t *fab_ctx, struct flow *fl, 
                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;
    
    lkup_host = fab_host_create(0, 0, fl);

    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 {
            c_log_err("%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);
        c_log_err("%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);
        c_log_err("%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;
} 
示例#26
0
/*
 *
 * mul_makdi_show_nfv_stats_all - return the every nfv ingress/egress port statistics
 *
 */
void
mul_makdi_show_nfv_stats_all(void *service,  void *arg, bool nbapi, 
                             void (*cb_fn)(void *arg, void *pbuf))
{
    struct cbuf *b;
    struct c_ofp_auxapp_cmd *cofp_auc;
    struct c_ofp_switch_port_query *cofp_pq;
    int n_nfvs = 0;
    struct cbuf_head bufs;
    int retries = 0;
    char *pbuf;

    if (!service)
        return;
    
    cbuf_list_head_init(&bufs);


try_again:
    b = of_prep_msg(sizeof(struct c_ofp_auxapp_cmd), C_OFPT_AUX_CMD, 0);

    cofp_auc = (void *) (b->data);
    cofp_auc->cmd_code = htonl(C_AUX_CMD_MAKDI_NFV_STATS_ALL);

    c_service_send(service, b);
    while (1) {
        b = c_service_wait_response(service);
        if (b) {
            if (check_reply_type(b, C_AUX_CMD_SUCCESS) ||
                !check_reply_type(b, C_AUX_CMD_MUL_SWITCH_PORT_QUERY)) {
                free_cbuf(b);
                break;
            }
            cofp_auc = (void *) (b->data);
            cofp_pq = (void *) (cofp_auc->data);
            if (ntohs(cofp_auc->header.length) <
                    sizeof(*cofp_pq) + sizeof(*cofp_auc)) {
                free_cbuf(b);
                goto try_restart;
            }
            b = cbuf_realloc_headroom(b, 0, true);
            cbuf_list_queue_tail(&bufs, b);
            n_nfvs++;
        } else {
            goto try_restart;
        }
    }
    
    while ((b = cbuf_list_dequeue(&bufs))) {
        cofp_auc = (void *) (b->data);
        cofp_pq = (void *) (cofp_auc->data);
        if (nbapi) {
            cb_fn(arg, cofp_pq);
        } else {
            pbuf = makdi_dump_port_stats(cofp_auc, cofp_pq);
            if (pbuf) {
                cb_fn(arg, pbuf);
                free(pbuf);
            }
            free_cbuf(b);
        }
    }
    return;

try_restart:
    cbuf_list_purge(&bufs);
    if (retries++ >= C_SERV_RETRY_CNT) {
        cbuf_list_purge(&bufs);
        c_log_err("%s: Restarting serv msg", FN);
        goto try_again;
    }
    c_log_err("%s: Can't restart serv msg", FN);
    return;
}
示例#27
0
/**
 * mul_makdi_show_nfv -
 */
int mul_makdi_show_servicechain_default(void *service, void *arg, bool nbapi,
        void (*cb_fn)(void *arg, void *pbuf)) {
    struct cbuf *b;
    struct c_ofp_auxapp_cmd *cofp_auc;
    struct c_ofp_default_rule_info *cofp_servicechain_default;
    char *pbuf;
    int n_services = 0;
    struct cbuf_head bufs;
    int retries = 0;

    if (!service)
        return -1;
    
    cbuf_list_head_init(&bufs);

try_again:
    b = of_prep_msg(sizeof(struct c_ofp_auxapp_cmd), C_OFPT_AUX_CMD, 0);

    cofp_auc = (void *) (b->data);
    cofp_auc->cmd_code = htonl(C_AUX_CMD_MAKDI_SHOW_DEFAULT_SERVICE);

    c_service_send(service, b);
    while (1) {
        b = c_service_wait_response(service);
        if (b) {
            if (check_reply_type(b, C_AUX_CMD_SUCCESS)
                    || !check_reply_type(b, C_AUX_CMD_MAKDI_SHOW_DEFAULT_SERVICE)) {
                free_cbuf(b);
                break;
            }
            cofp_auc = (void *) (b->data);
            cofp_servicechain_default = (void *) (cofp_auc->data);
            /*  FIXME : Length missmtach, header.length == 2050
                
            if (ntohs(cofp_nfv_group->header.length) < sizeof(*cofp_nfv_group))
            {   
                free_cbuf(b);
                goto try_restart;
            }
            */
            b = cbuf_realloc_headroom(b, 0, true);
            cbuf_list_queue_tail(&bufs, b);
            n_services++;
        } else {
            goto try_restart;
        }
    }

    while ((b = cbuf_list_dequeue(&bufs))) {
        cofp_auc = (void *) (b->data);
        cofp_servicechain_default = (void *)(cofp_auc->data);
        if (nbapi) {
            cb_fn(arg, cofp_servicechain_default);
        } else {
            pbuf = makdi_dump_servicechain_default(
                        cofp_servicechain_default);
            if (pbuf) {
                cb_fn(arg, pbuf);
                free(pbuf);
            }
            free_cbuf(b);
        }
    }
    return n_services;

try_restart:
    cbuf_list_purge(&bufs);
    if (retries++ >= C_SERV_RETRY_CNT) {
        cbuf_list_purge(&bufs);
        c_log_err("%s: Restarting serv msg", FN);
        goto try_again;
    }
    c_log_err("%s: Can't restart serv msg", FN);
    return 0;
}
示例#28
0
/**
 * mul_makdi_show_nfv -
 */
int mul_makdi_show_nfv(void *service, void *arg, bool dump_cmd,
                       void (*cb_fn)(void *arg, void *pbuf))
{
    struct cbuf *b;
    struct c_ofp_auxapp_cmd *cofp_auc;
    struct c_ofp_s_chain_nfv_group_info *cofp_nfv_group;
    char *pbuf;
    int n_groups = 0;
    struct cbuf_head bufs;
    int retries = 0;

    if (!service)
        return -1;

    cbuf_list_head_init(&bufs);

try_again:
    b = of_prep_msg(sizeof(struct c_ofp_auxapp_cmd), C_OFPT_AUX_CMD, 0);

    cofp_auc = (void *) (b->data);
    cofp_auc->cmd_code = htonl(C_AUX_CMD_MAKDI_SHOW_NFV);

    c_service_send(service, b);
    while (1) {
        b = c_service_wait_response(service);
        if (b) {
            if (check_reply_type(b, C_AUX_CMD_SUCCESS) ||
                !check_reply_type(b, C_AUX_CMD_MAKDI_SHOW_NFV_GROUP)) {
                free_cbuf(b);
                break;
            }
            cofp_auc = (void *) (b->data);
            cofp_nfv_group = (void *) (cofp_auc->data);
            if (ntohs(cofp_auc->header.length)
                   < sizeof(*cofp_nfv_group) + sizeof(*cofp_auc)) {
                free_cbuf(b);
                goto try_restart;
            }
            b = cbuf_realloc_headroom(b, 0, true);
            cbuf_list_queue_tail(&bufs, b);
            n_groups++;
        } else {
            goto try_restart;
            break;
        }
    }
    
    while ((b = cbuf_list_dequeue(&bufs))) {
        cofp_auc = (void *) (b->data);
        cofp_nfv_group = (void *)(cofp_auc->data);
        if (dump_cmd) {
            makdi_dump_nfv_groups_cmd(cofp_nfv_group, arg, cb_fn);
        } else {
            pbuf = makdi_dump_nfv_groups(cofp_nfv_group);
            if (pbuf) {
                cb_fn(arg, pbuf);
                free(pbuf);
            }
        }
        free_cbuf(b);
    }
    return n_groups;

try_restart:
    cbuf_list_purge(&bufs);
    if (retries++ < C_SERV_RETRY_CNT) {
        cbuf_list_purge(&bufs);
        c_log_err("%s: Restarting serv msg", FN);
        goto try_again;
    }
    c_log_err("%s: Can't restart serv msg", FN);
    return 0;
}
示例#29
0
/*
 * mul_makdi_show_user_stats_all - 
 * 
 * Return the every user statistics on service chain domain
 *
 */
int mul_makdi_show_user_stats_all(void *service,
        void *arg, bool nbapi, void (*cb_fn)(void *arg, void *pbuf))
{
    struct cbuf *b;
    struct c_ofp_auxapp_cmd *cofp_auc;
    struct c_ofp_user_stats_show *cofp_user_stats;  
    struct cbuf_head bufs;
    int retries = 0;
    int n_chains = 0;

    if (!service)
        return n_chains;
    
    cbuf_list_head_init(&bufs);

try_again:
    b = of_prep_msg(sizeof(struct c_ofp_auxapp_cmd), C_OFPT_AUX_CMD, 0);

    cofp_auc = (void *) (b->data);
    cofp_auc->cmd_code = htonl(C_AUX_CMD_MAKDI_USER_STATS_ALL);

    c_service_send(service, b);
    while (1) {
    b = c_service_wait_response(service);
    if (b) {
        if (check_reply_type(b, C_AUX_CMD_SUCCESS)
                    || !check_reply_type(b, C_AUX_CMD_MAKDI_USER_STATS_ALL)) {
            free_cbuf(b);
            break;
        }
        cofp_auc = (void *) (b->data);
        cofp_user_stats  = (void *) (cofp_auc->data);
        
        n_chains++;   
   
        if (nbapi) {
            cb_fn(arg, &cofp_user_stats->stats);
        } else {
            char *pbuf = calloc(1, SERV_CHAIN_PBUF_SZ);
            uint8_t len = 0;
            len += snprintf(pbuf + len, SERV_CHAIN_PBUF_SZ - len - 1, "User Flow : %sPacket_Count(%llu) : Byte_Count(%llu) : Bps(%s) : PPS(%s) \r\n", 
                    of_dump_flow(&cofp_user_stats->stats.flow, 0),
                    U642ULL(ntohll(cofp_user_stats->stats.packet_count)), 
                    U642ULL(ntohll(cofp_user_stats->stats.byte_count)), 
                    cofp_user_stats->stats.bps, cofp_user_stats->stats.pps);
            cb_fn(arg, pbuf);
            free_cbuf(b);
            free(pbuf);
        }
    } else {
        goto try_restart;
    }
    }
    return n_chains;

try_restart:
    cbuf_list_purge(&bufs);
    if (retries++ >= C_SERV_RETRY_CNT) {
        cbuf_list_purge(&bufs);
        c_log_err("%s: Restarting serv msg", FN);
        goto try_again;
    }
    c_log_err("%s: Can't restart serv msg", FN);
    return -1;
}
示例#30
0
/*
 * mul_makdi_show_service_stats_all -
 *
 * Return every service ingress/egress port statistics
 *
 */
int mul_makdi_show_service_stats_all(void *service,
                                      void *arg, bool nbapi,
                                      void (*cb_fn)(void *arg, void *pbuf))
{
    struct cbuf *b;
    struct c_ofp_auxapp_cmd *cofp_auc;
    struct c_ofp_service_stats_show *cofp_services;
    struct cbuf_head bufs;
    int retries = 0;
    int n_chains = 0;

    if (!service)
        return n_chains;
    
    cbuf_list_head_init(&bufs);

try_again:
    b = of_prep_msg(sizeof(struct c_ofp_auxapp_cmd), C_OFPT_AUX_CMD, 0);

    cofp_auc = (void *) (b->data);
    cofp_auc->cmd_code = htonl(C_AUX_CMD_MAKDI_SERVICE_STATS_ALL);

    c_service_send(service, b);
    
    while (1) {
        b = c_service_wait_response(service);
        if (b) {
            if (check_reply_type(b, C_AUX_CMD_SUCCESS) ||
                !check_reply_type(b, C_AUX_CMD_MAKDI_SERVICE_STATS_ALL)) {
                free_cbuf(b);
                break;
            }
            cofp_auc = (void *) (b->data);
            cofp_services = (void *) (cofp_auc->data);

            if (ntohs(cofp_auc->header.length) <
                    sizeof(*cofp_services) + sizeof(*cofp_auc)) {
                free_cbuf(b);
                goto try_restart;
            }
            n_chains++;
 
            if (nbapi) {
                cb_fn(arg, &cofp_services->stats);
            } else {
                char *pbuf = calloc(1, SERV_CHAIN_PBUF_SZ);
                uint8_t len = 0;
                len += snprintf(pbuf + len, SERV_CHAIN_PBUF_SZ - len - 1, 
                            "Service(%s) : User IP(0x%04x) : dpid(0x%016llx) :"
                            " vlan(%hu) : Packet_Count(%llu) : Byte_Count(%llu)"
                            " : Bps(%s) : PPS(%s) : Inport(%hu) \r\n", 
                    cofp_services->service_name,
                    ntohl(cofp_services->stats.flow.ip.nw_src & 0xffffffff), 
                    U642ULL(ntohll(cofp_services->stats.datapath_id)), 
                    ntohs(cofp_services->stats.flow.dl_vlan), 
                    U642ULL(ntohll(cofp_services->stats.packet_count)), 
                    U642ULL(ntohll(cofp_services->stats.byte_count)), 
                    cofp_services->stats.bps,
                    cofp_services->stats.pps,
                    ntohl(cofp_services->stats.flow.in_port));
                cb_fn(arg, pbuf);
                free_cbuf(b);
                free(pbuf);
            }
        } else {
            goto try_restart;
        }
    }
        
    return n_chains;

try_restart:
    cbuf_list_purge(&bufs);
    if (retries++ >= C_SERV_RETRY_CNT) {
        cbuf_list_purge(&bufs);
        c_log_err("%s: Restarting serv msg", FN);
        goto try_again;
    }
    c_log_err("%s: Can't restart serv msg", FN);
    return 0;
}