lagopus_result_t ofp_role_channel_update(struct channel *channel, struct ofp_role_request *role_request, uint64_t dpid) { lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES; uint32_t current_role; if (channel != NULL && role_request != NULL) { current_role = channel_role_get(channel); /* Not change. */ if (role_request->role == current_role || role_request->role == OFPCR_ROLE_NOCHANGE) { lagopus_msg_debug(1, "Role not change (%u).\n", role_request->role); role_request->role = current_role; ret = LAGOPUS_RESULT_OK; } else { if (current_role == OFPCR_ROLE_MASTER) { /* every other master controller to slave. */ channel_mgr_dpid_iterate(dpid, change_master2slave, NULL); } channel_role_set(channel, role_request->role); ret = LAGOPUS_RESULT_OK; } } else { ret = LAGOPUS_RESULT_INVALID_ARGS; } return ret; }
bool ofp_role_mp_check(struct channel *channel, struct pbuf *pbuf, struct ofp_multipart_request *multipart) { bool ret = false; if (channel != NULL && multipart != NULL && pbuf != NULL) { if (channel_role_get(channel) == OFPCR_ROLE_SLAVE) { switch (multipart->type) { case OFPMP_TABLE_FEATURES: /* Check length */ if (pbuf_plen_equal_check(pbuf, 0) == LAGOPUS_RESULT_OK) { /* Body is empty. */ ret = true; } else { ret = false; } break; default: ret = true; break; } } else { ret = true; } } else { ret = false; } return ret; }
bool ofp_role_check(struct channel *channel, struct ofp_header *header) { bool ret = false; if (channel != NULL && header != NULL) { if (channel_role_get(channel) == OFPCR_ROLE_SLAVE) { switch (header->type) { case OFPT_SET_CONFIG: case OFPT_TABLE_MOD: case OFPT_FLOW_MOD: case OFPT_GROUP_MOD: case OFPT_PORT_MOD: case OFPT_METER_MOD: case OFPT_PACKET_OUT: case OFPT_PACKET_IN: case OFPT_FLOW_REMOVED: ret = false; break; default: ret = true; break; } } else { ret = true; } } else { ret = false; } return ret; }
lagopus_result_t channel_mgr_channel_role_get(const char *channel_name, datastore_controller_role_t *role) { uint32_t ofp_role; lagopus_result_t ret; struct channel *chan; ret = channel_mgr_channel_lookup_by_name(channel_name, &chan); if (ret != LAGOPUS_RESULT_OK) { return ret; } ofp_role = channel_role_get(chan); switch (ofp_role) { case OFPCR_ROLE_EQUAL: *role = DATASTORE_CONTROLLER_ROLE_EQUAL; break; case OFPCR_ROLE_MASTER: *role = DATASTORE_CONTROLLER_ROLE_MASTER; break; case OFPCR_ROLE_SLAVE: *role = DATASTORE_CONTROLLER_ROLE_SLAVE; break; default: *role = DATASTORE_CONTROLLER_ROLE_UNKNOWN; break; } return LAGOPUS_RESULT_OK; }
static lagopus_result_t change_master2slave(struct channel *channel, void *val) { (void) val; if (channel_role_get(channel) == OFPCR_ROLE_MASTER) { channel_role_set(channel, OFPCR_ROLE_SLAVE); } return LAGOPUS_RESULT_OK; }
lagopus_result_t channel_mgr_controller_set(const char *channel_name, datastore_controller_role_t role, datastore_controller_connection_type_t type) { uint32_t ofp_role, prev_role; lagopus_result_t ret; struct channel *chan; ret = channel_mgr_channel_lookup_by_name(channel_name, &chan); if (ret != LAGOPUS_RESULT_OK) { return ret; } prev_role = channel_role_get(chan); switch (role) { case DATASTORE_CONTROLLER_ROLE_EQUAL: ofp_role = OFPCR_ROLE_EQUAL; break; case DATASTORE_CONTROLLER_ROLE_MASTER: ofp_role = OFPCR_ROLE_MASTER; break; case DATASTORE_CONTROLLER_ROLE_SLAVE: ofp_role = OFPCR_ROLE_SLAVE; break; default: return LAGOPUS_RESULT_INVALID_ARGS; } channel_role_set(chan, ofp_role); if (type == DATASTORE_CONTROLLER_CONNECTION_TYPE_MAIN) { ret = channel_auxiliary_set(chan, false); } else if (type == DATASTORE_CONTROLLER_CONNECTION_TYPE_AUXILIARY) { ret = channel_auxiliary_set(chan, true); } else { channel_role_set(chan, prev_role); return LAGOPUS_RESULT_INVALID_ARGS; } if (ret != LAGOPUS_RESULT_OK) { channel_role_set(chan, prev_role); return ret; } return LAGOPUS_RESULT_OK; }