/** * mul_fabric_host_mod - * */ int mul_fabric_host_mod(void *service, uint64_t dpid, struct flow *fl, bool add) { struct cbuf *b; struct c_ofp_auxapp_cmd *cofp_auc; struct c_ofp_host_mod *cofp_hm; int ret = -1; b = of_prep_msg(sizeof(struct c_ofp_auxapp_cmd) + sizeof(struct c_ofp_host_mod), C_OFPT_AUX_CMD, 0); cofp_auc = (void *)(b->data); cofp_auc->cmd_code = add ? htonl(C_AUX_CMD_FAB_HOST_ADD): htonl(C_AUX_CMD_FAB_HOST_DEL); cofp_hm = (void *)(cofp_auc->data); cofp_hm->switch_id.datapath_id = htonll(dpid); memcpy(&cofp_hm->host_flow, fl, sizeof(*fl)); c_service_send(service, b); b = c_service_wait_response(service); if (b) { if (check_reply_type(b, C_AUX_CMD_SUCCESS)) { ret = 0; } free_cbuf(b); } return ret; }
/** * @name mul_conx_stale - * @brief Start user-flow staling at ConX for a particular cookie * @param [in] service Pointer to client service * @param [in] cookie Cookie-id associated with an application * * @retval int 0 for success non-0 for failure */ int mul_conx_stale(void *service, uint32_t cookie) { struct cbuf *b; struct c_ofp_auxapp_cmd *cofp_auc; struct c_conx_user_flow *conx_fl; int ret = -1; if (!service) return ret; b = of_prep_msg(sizeof(*cofp_auc) + sizeof(*conx_fl), C_OFPT_AUX_CMD, 0); if (!b) return -1; cofp_auc = CBUF_DATA(b); cofp_auc->cmd_code = htonl(C_AUX_CMD_CONX_STALE); conx_fl = ASSIGN_PTR(cofp_auc->data); conx_fl->app_cookie = htonl(cookie); c_service_send(service, b); 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; }
/** * @name mul_set_tr_loop_detect - * @brief Set mul tr loop detection status in topo module * @param [in] service Pointer to the client's service * @param [in] enable Enable or disable * * @retval int zero if no error else non-zero */ int mul_set_tr_loop_detect(void *service, bool enable) { struct cbuf *b; struct c_ofp_auxapp_cmd *cofp_auc; struct c_ofp_switch_port_query *cofp_pq; int ret = -1; if (!service) return ret; b = of_prep_msg(sizeof(*cofp_auc) + sizeof(*cofp_pq), C_OFPT_AUX_CMD, 0); cofp_auc = CBUF_DATA(b); cofp_auc->cmd_code = enable ? htonl(C_AUX_CMD_MUL_LOOP_EN): htonl(C_AUX_CMD_MUL_LOOP_DIS); c_service_send(service, b); b = c_service_wait_response(service); if (b) { cofp_auc = CBUF_DATA(b); if (check_reply_type(b, C_AUX_CMD_SUCCESS)) { ret = 0; } free_cbuf(b); } return ret; }
/** * @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; }
void c_service_send_error(void *service, struct cbuf *b, uint16_t type, uint16_t code) { struct cbuf *new_b; c_ofp_error_msg_t *cofp_em; void *data; size_t data_len; if (!service) return; data_len = b->len > C_OFP_MAX_ERR_LEN? C_OFP_MAX_ERR_LEN : b->len; new_b = of_prep_msg(sizeof(*cofp_em) + data_len, C_OFPT_ERR_MSG, 0); cofp_em = (void *)(new_b->data); cofp_em->type = htons(type); cofp_em->code = htons(code); data = (void *)(cofp_em + 1); memcpy(data, b->data, data_len); c_service_send(service, new_b); }
/** * mul_fabric_show_hosts - * */ void mul_fabric_show_hosts(void *service, bool active, bool dump_cmd, void *arg, void (*cb_fn)(void *arg, char *pbuf)) { struct cbuf *b; struct c_ofp_auxapp_cmd *cofp_auc; struct c_ofp_host_mod *cofp_hm; char *pbuf; b = of_prep_msg(sizeof(struct c_ofp_auxapp_cmd), C_OFPT_AUX_CMD, 0); cofp_auc = (void *)(b->data); cofp_auc->cmd_code = active ? htonl(C_AUX_CMD_FAB_SHOW_ACTIVE_HOSTS): htonl(C_AUX_CMD_FAB_SHOW_INACTIVE_HOSTS); 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_FAB_HOST_ADD)) { free_cbuf(b); break; } cofp_auc = (void *)(b->data); cofp_hm = (void *)(cofp_auc->data); if (ntohs(cofp_auc->header.length) < sizeof(*cofp_auc) + sizeof(*cofp_hm)) { free_cbuf(b); break; } if (!dump_cmd) { pbuf = fab_dump_single_host_from_flow( ntohll(cofp_hm->switch_id.datapath_id), &cofp_hm->host_flow); } else { pbuf = fab_dump_add_host_cmd_from_flow( ntohll(cofp_hm->switch_id.datapath_id), &cofp_hm->host_flow); } if (pbuf) { cb_fn(arg, pbuf); free(pbuf); } free_cbuf(b); } else { break; } } }
/** * mul_makdi_servicechain_mod - * * Call static int nfv_add(makdi_hdl_t *hdl, const char *name, uint64_t dpid, uint16_t iif, uint16_t oif) function */ int mul_makdi_servicechain_mod(void *service, uint64_t dpid, uint32_t port, char *service_name, uint32_t user_ip, int nfvc, char **nfv_group_list, bool add) { struct cbuf *b; struct c_ofp_auxapp_cmd *cofp_auc; struct c_ofp_s_chain_mod *cofp_scm; int ret = -1; int i = 0; if (!service) return -1; if (dpid == ULONG_MAX && errno == ERANGE) { return -1; } b = of_prep_msg( sizeof(struct c_ofp_auxapp_cmd) + sizeof(struct c_ofp_s_chain_mod), C_OFPT_AUX_CMD, 0); cofp_auc = (void *) (b->data); cofp_auc->cmd_code = add ? htonl(C_AUX_CMD_MAKDI_SERVICE_CHAIN_ADD) : htonl( C_AUX_CMD_MAKDI_SERVICE_CHAIN_DEL); cofp_scm = (void *) (cofp_auc->data); cofp_scm->user_info.switch_id.datapath_id = htonll(dpid); cofp_scm->user_info.host_flow.ip.nw_src = htonl(user_ip); cofp_scm->user_info.host_flow.in_port = htonl(port); strncpy(cofp_scm->service, service_name, MAX_NFV_NAME - 1); if (add) { cofp_scm->num_nfvs = htonll(nfvc); for (i = 0; i < nfvc; i++) { strncpy(cofp_scm->nfv_list[i], nfv_group_list[i], MAX_NFV_NAME - 1); cofp_scm->nfv_list[i][MAX_NFV_NAME - 1] = '\0'; } } c_service_send(service, b); b = c_service_wait_response(service); if (b) { if (check_reply_type(b, C_AUX_CMD_SUCCESS)) { ret = 0; } free_cbuf(b); } return ret; }
void c_service_send_success(void *service) { struct cbuf *new_b; struct c_ofp_auxapp_cmd *cofp_aac; if (!service) return; new_b = of_prep_msg(sizeof(*cofp_aac), C_OFPT_AUX_CMD, 0); cofp_aac = (void *)(new_b->data); cofp_aac->cmd_code = htonl(C_AUX_CMD_SUCCESS); c_service_send(service, new_b); }
/** * @name c_app_notify_disconnect * @brief Send a C_OFPT_NOCONN_APP event to the application */ static void c_app_notify_disconnect(c_app_hdl_t *hdl) { struct cbuf *b; if (!hdl->ev_cb) { c_controller_disconn(hdl); return; } b = of_prep_msg(sizeof(struct ofp_header), C_OFPT_NOCONN_APP, 0); hdl->ev_cb(hdl, b); free_cbuf(b); }
/** * mul_makdi_serv_mod - * * Call static int nfv_add(makdi_hdl_t *hdl, const char *name, uint64_t dpid, uint16_t iif, uint16_t oif) function */ int mul_makdi_servicechain_default_mod(void *service, char *service_name, int nfvc, char **nfv_group_list, bool add, uint16_t level) { struct cbuf *b; struct c_ofp_auxapp_cmd *cofp_auc; struct c_ofp_default_s_chain_mod *cofp_scm; int ret = -1; int i = 0; if (!service) return ret; b = of_prep_msg( sizeof(struct c_ofp_auxapp_cmd) + sizeof(struct c_ofp_s_chain_mod), C_OFPT_AUX_CMD, 0); cofp_auc = (void *) (b->data); cofp_auc->cmd_code = add ? htonl(C_AUX_CMD_MAKDI_DEFAULT_SERVICE_ADD) : htonl( C_AUX_CMD_MAKDI_DEFAULT_SERVICE_DEL); cofp_scm = (void *) (cofp_auc->data); cofp_scm->level = htons(level); strncpy(cofp_scm->service, service_name, MAX_NFV_NAME - 1); if (add) { cofp_scm->num_nfvs = htons(nfvc); for (i = 0; i < nfvc; i++) { strncpy(cofp_scm->nfv_list[i], nfv_group_list[i], MAX_NFV_NAME - 1); cofp_scm->nfv_list[i][MAX_NFV_NAME - 1] = '\0'; } } c_service_send(service, b); b = c_service_wait_response(service); if (b) { if (check_reply_type(b, C_AUX_CMD_SUCCESS)) { ret = 0; } free_cbuf(b); } return ret; }
/* * * mul_makdi_show_nfv_stats - return the nfv ingress/egress port statistics * */ void mul_makdi_show_nfv_stats(void *service, char* nfv_name, void *arg, bool nbapi UNUSED, void (*cb_fn)(void *arg, void *pbuf)) { struct cbuf *b; struct c_ofp_auxapp_cmd *cofp_auc; struct c_ofp_nfv_stats_show *cofp_nfv_stats; char *pbuf; if (!service) return; b = of_prep_msg(sizeof(struct c_ofp_auxapp_cmd) + sizeof(struct c_ofp_nfv_stats_show), C_OFPT_AUX_CMD, 0); cofp_auc = (void *) (b->data); cofp_auc->cmd_code = htonl(C_AUX_CMD_MAKDI_NFV_STATS); cofp_nfv_stats = (void *) (cofp_auc->data); strncpy(cofp_nfv_stats->name, nfv_name, MAX_NFV_NAME); 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; } pbuf = mul_dump_port_stats(b, true); if (pbuf) { cb_fn(arg, pbuf); free(pbuf); } free_cbuf(b); } else { break; } } }
/** * mul_makdi_nfvtopology_node_mod - * * */ int mul_makdi_nfv_mod(void *service, uint64_t dpid, char *group_id, uint16_t iif, uint16_t oif, char *nfv, bool add) { struct cbuf *b; struct c_ofp_auxapp_cmd *cofp_auc; struct c_ofp_s_chain_nfv_info *cofp_nfv_info; int ret = -1; if (!service) return -1; b = of_prep_msg( sizeof(struct c_ofp_auxapp_cmd) + sizeof(struct c_ofp_s_chain_nfv_info), C_OFPT_AUX_CMD, 0); cofp_auc = (void *) (b->data); if (add) cofp_auc->cmd_code = htonl(C_AUX_CMD_MAKDI_NFV_ADD); else cofp_auc->cmd_code = htonl(C_AUX_CMD_MAKDI_NFV_DEL); cofp_nfv_info = (void *) (cofp_auc->data); cofp_nfv_info->dpid = htonll(dpid); cofp_nfv_info->iif = htons(iif); cofp_nfv_info->oif = htons(oif); strncpy(cofp_nfv_info->nfv_group, group_id, MAX_NFV_NAME - 1); cofp_nfv_info->nfv_group[MAX_NFV_NAME - 1] = '\0'; strncpy(cofp_nfv_info->nfv, nfv, MAX_NFV_NAME - 1); cofp_nfv_info->nfv[MAX_NFV_NAME - 1] = '\0'; c_service_send(service, b); b = c_service_wait_response(service); if (b) { if (check_reply_type(b, C_AUX_CMD_SUCCESS)) { ret = 0; } else ret = 1; free_cbuf(b); } return ret; }
/** * mul_makdi_serv_mod - * * Call static int nfv_add(makdi_hdl_t *hdl, const char *name, uint64_t dpid, uint16_t iif, uint16_t oif) function */ int mul_makdi_service_mod(void *service, char *service_name, uint16_t vlan, bool add) { struct cbuf *b; struct c_ofp_auxapp_cmd *cofp_auc; struct c_ofp_service_info *cofp_seri; int ret = -1; if (!service) return ret; b = of_prep_msg( sizeof(struct c_ofp_auxapp_cmd) + sizeof(struct c_ofp_s_chain_mod), C_OFPT_AUX_CMD, 0); cofp_auc = (void *) (b->data); cofp_auc->cmd_code = add ? htonl(C_AUX_CMD_MAKDI_SERVICE_ADD) : htonl( C_AUX_CMD_MAKDI_SERVICE_DEL); cofp_seri = (void *) (cofp_auc->data); strncpy(cofp_seri->service, service_name, MAX_NFV_NAME); if (add) cofp_seri->vlan = htons(vlan); c_service_send(service, b); b = c_service_wait_response(service); if (b) { if (check_reply_type(b, C_AUX_CMD_SUCCESS)) { ret = 0; } free_cbuf(b); } return ret; }
/** * 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; }
/** * mul_fabric_show_routes - * */ void mul_fabric_show_routes(void *service, void *arg, void (*show_src_host)(void *arg, char *pbuf), void (*show_dst_host)(void *arg, char *pbuf), void (*show_route_links)(void *arg, char *pbuf)) { struct cbuf *b; struct c_ofp_auxapp_cmd *cofp_auc; struct c_ofp_route *cofp_r; struct c_ofp_route_link *cofp_rl; char *pbuf; size_t n_links = 0; 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_FAB_SHOW_ROUTES); 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_FAB_ROUTE)) { free_cbuf(b); break; } cofp_auc = (void *)(b->data); if (ntohs(cofp_auc->header.length) < sizeof(*cofp_auc) + sizeof(*cofp_r)) { free_cbuf(b); continue; } n_links = (ntohs(cofp_auc->header.length) - (sizeof(*cofp_auc) + sizeof(*cofp_r)))/sizeof(*cofp_rl); cofp_r = (void *)(cofp_auc->data); pbuf = fab_dump_single_host_from_flow( ntohll(cofp_r->src_host.switch_id.datapath_id), &cofp_r->src_host.host_flow); if (pbuf) { show_src_host(arg, pbuf); free(pbuf); } pbuf = fab_dump_single_host_from_flow( ntohll(cofp_r->dst_host.switch_id.datapath_id), &cofp_r->dst_host.host_flow); if (pbuf) { show_dst_host(arg, pbuf); free(pbuf); } pbuf = mul_fabric_route_link_dump( (void *)(cofp_r->route_links), n_links); if (pbuf) { show_route_links(arg, pbuf); free(pbuf); } free_cbuf(b); } else { break; } } }
/* * 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; }
/* * * 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_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; }
/** * 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; }
/** * @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; }