void ind_cxn_bundle_cleanup(connection_t *cxn) { int i; for (i = 0; i < MAX_BUNDLES; i++) { if (cxn->bundles[i].id != BUNDLE_ID_INVALID) { free_bundle(&cxn->bundles[i]); } } }
/* When loading all tracked bundles into memory, they happen * to be hold in subs global var, for some reasons it is * needed to just pop out one or more of this loaded tracked * bundles, this function search for bundle_name into subs * struct and if it found then free it from the list. */ static int unload_tracked_bundle(const char *bundle_name) { struct list *bundles; struct list *cur_item; struct sub *bundle; bundles = list_head(subs); while (bundles) { bundle = bundles->data; cur_item = bundles; bundles = bundles->next; if (strcmp(bundle->component, bundle_name) == 0) { /* unlink (aka untrack) matching bundle name from tracked ones */ subs = free_bundle(cur_item); return EXIT_SUCCESS; } } return EBUNDLE_NOT_TRACKED; }
void ind_cxn_bundle_ctrl_handle(connection_t *cxn, of_object_t *obj) { uint32_t bundle_id; uint16_t ctrl_type; uint16_t flags; uint16_t err_code = OFPBFC_UNKNOWN; of_bundle_ctrl_msg_bundle_id_get(obj, &bundle_id); of_bundle_ctrl_msg_bundle_ctrl_type_get(obj, &ctrl_type); of_bundle_ctrl_msg_flags_get(obj, &flags); bundle_t *bundle = find_bundle(cxn, bundle_id); if (ctrl_type == OFPBCT_OPEN_REQUEST) { if (bundle != NULL) { err_code = OFPBFC_BUNDLE_EXIST; goto error; } bundle = find_bundle(cxn, BUNDLE_ID_INVALID); if (bundle == NULL) { err_code = OFPBFC_OUT_OF_BUNDLES; goto error; } bundle->id = bundle_id; bundle->flags = flags; AIM_ASSERT(bundle->count == 0); AIM_ASSERT(bundle->allocated == 0); AIM_ASSERT(bundle->bytes == 0); AIM_ASSERT(bundle->msgs == NULL); } else if (ctrl_type == OFPBCT_CLOSE_REQUEST) { /* Ignored */ } else if (ctrl_type == OFPBCT_COMMIT_REQUEST) { if (bundle == NULL) { err_code = OFPBFC_BAD_ID; goto error; } if (comparator && !(bundle->flags & OFPBF_ORDERED)) { qsort(bundle->msgs, bundle->count, sizeof(bundle->msgs[0]), compare_message); } struct bundle_task_state *state = aim_zmalloc(sizeof(*state)); state->cxn_id = cxn->cxn_id; state->reply = of_object_dup(obj); of_bundle_ctrl_msg_bundle_ctrl_type_set(state->reply, OFPBCT_COMMIT_REPLY); state->id = bundle->id; state->count = bundle->count; state->offset = 0; state->msgs = bundle->msgs; if (ind_soc_task_register(bundle_task, state, IND_SOC_NORMAL_PRIORITY) < 0) { AIM_DIE("Failed to create long running task for bundle"); } ind_cxn_pause(cxn); /* Transfer ownership of msgs to task */ bundle->msgs = NULL; bundle->count = 0; free_bundle(bundle); /* Do not send reply yet */ return; } else if (ctrl_type == OFPBCT_DISCARD_REQUEST) { if (bundle == NULL) { err_code = OFPBFC_BAD_ID; goto error; } free_bundle(bundle); } else { err_code = OFPBFC_BAD_TYPE; goto error; } /* Send reply */ of_object_t *reply = of_object_dup(obj); /* Derive the reply subtype from the request */ of_bundle_ctrl_msg_bundle_ctrl_type_set(reply, ctrl_type+1); indigo_cxn_send_controller_message(cxn->cxn_id, reply); return; error: indigo_cxn_send_error_reply( cxn->cxn_id, obj, OF_ERROR_TYPE_BUNDLE_FAILED, err_code); }