// 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; }
/** * 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; }
/* * * 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; }
/** * 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; }