lagopus_result_t bridge_ofp_version_bitmap_set(struct bridge *bridge, uint8_t version) { if (version != OPENFLOW_VERSION_1_3 && version != OPENFLOW_VERSION_1_4) { return LAGOPUS_RESULT_INVALID_ARGS; } SET32_FLAG(bridge->version_bitmap, (1 << version)); return LAGOPUS_RESULT_OK; }
/* Parse the line. */ enum cparse_result cparse(char *line, struct cnode *top, struct cparam *param, int exec) { uint32_t i; uint32_t j; char *arg; struct cnode *cnode; enum match_type current; struct vector *args; struct vector *matched; struct vector *candidate; struct vector *argv; /* Arguments, matched and candidate. */ args = param->args; matched = param->matched; candidate = param->candidate; argv = param->argv; /* Lexical analysis. */ clex(line, args); /* Set top candidate. */ vector_reset(candidate); vector_append(candidate, top->v); /* Empty line. */ if (vector_max(args) == 0) { return CPARSE_EMPTY_LINE; } /* Parse user input arguments. */ for (i = 0; i < vector_max(args); i++) { /* Set current word to arg. */ arg = vector_slot(args, i); /* Empty tail space. */ if (strcmp(arg, "") == 0) { if (param->index > 0) { param->index--; } if (args->max > 0) { args->max--; } param->tail = 1; break; } /* Remember index. */ param->index = i; /* Starting from no match. */ current = NONE_MATCH; /* Rest matched vector. */ vector_reset(matched); /* Match with schema. */ for (j = 0; j < vector_max(candidate); j++) { enum match_type match = NONE_MATCH; cnode = vector_slot(candidate, j); if (exec == CPARSE_EXEC_MODE || exec == CPARSE_CONFIG_EXEC_MODE) { cnode_schema_match(cnode, arg, &match); } if (exec == CPARSE_CONFIG_MODE || (exec == CPARSE_CONFIG_EXEC_MODE && match == NONE_MATCH)) { if (strcmp(arg, cnode->name) == 0) { match = KEYWORD_MATCH; } } if (match == NONE_MATCH) { continue; } if (match > current) { vector_reset(matched); current = match; vector_set(matched, cnode); } else if (match == current) { vector_set(matched, cnode); } if (CHECK_FLAG(cnode->flags, CNODE_FLAG_SET_NODE)) { SET32_FLAG(param->flags, CNODE_FLAG_SET_NODE); } if (CHECK_FLAG(cnode->flags, CNODE_FLAG_DELETE_NODE)) { SET32_FLAG(param->flags, CNODE_FLAG_DELETE_NODE); } } /* There is no match. */ if (vector_max(matched) == 0) { break; } /* Update next level schema. */ vector_reset(candidate); for (j = 0; j < vector_max(matched); j++) { cnode = vector_slot(matched, j); vector_append(candidate, cnode->v); } } /* Match result check. */ if (vector_max(matched) == 0) { return CPARSE_NO_MATCH; } else if (vector_max(matched) > 1) { return CPARSE_AMBIGUOUS; } /* Parse success, set matched node. */ param->exec = vector_first(matched); /* Return incomplete if the node is not leaf. */ if (!cnode_is_leaf(param->exec)) { return CPARSE_INCOMPLETE; } /* Here we can build argc/argv. This is only possible at this stage * since during parsing, we can't determine which node is actually * matched. We allow user to abbreviate input so there could be * multiple candidate node during parsing. */ if (exec) { build_argv(param->exec, args, vector_max(args) - 1, argv); } /* Success. */ return CPARSE_SUCCESS; }
/* Allocate a new bridge. */ static struct bridge * bridge_alloc(const char *name) { struct bridge *bridge; /* Allocate memory. */ bridge = (struct bridge *)calloc(1, sizeof(struct bridge)); if (bridge == NULL) { return NULL; } /* Set bridge name. */ strncpy(bridge->name, name, BRIDGE_MAX_NAME_LEN); /* Set default wire protocol version to OpenFlow 1.3. */ bridge_ofp_version_set(bridge, OPENFLOW_VERSION_1_3); bridge_ofp_version_bitmap_set(bridge, OPENFLOW_VERSION_1_3); /* Set default fail mode. */ bridge_fail_mode_set(bridge, FAIL_STANDALONE_MODE); /* Set default features. */ bridge->features.n_buffers = BRIDGE_N_BUFFERS_DEFAULT; bridge->features.n_tables = BRIDGE_N_TABLES_DEFAULT; /* Auxiliary connection id. This value is not used. For * auxiliary_id, please use channel_auxiliary_id_get(). */ bridge->features.auxiliary_id = 0; /* Capabilities. */ SET32_FLAG(bridge->features.capabilities, OFPC_FLOW_STATS); SET32_FLAG(bridge->features.capabilities, OFPC_TABLE_STATS); SET32_FLAG(bridge->features.capabilities, OFPC_PORT_STATS); SET32_FLAG(bridge->features.capabilities, OFPC_GROUP_STATS); UNSET32_FLAG(bridge->features.capabilities, OFPC_IP_REASM); SET32_FLAG(bridge->features.capabilities, OFPC_QUEUE_STATS); UNSET32_FLAG(bridge->features.capabilities, OFPC_PORT_BLOCKED); bridge->switch_config.flags = OFPC_FRAG_NORMAL; bridge->switch_config.miss_send_len = 128; /* Prepare bridge's port vector. */ bridge->ports = vector_alloc(); if (bridge->ports == NULL) { goto out; } /* Allocate flowdb with table 0. */ bridge->flowdb = flowdb_alloc(1); if (bridge->flowdb == NULL) { goto out; } /* Allocate group table. */ bridge->group_table = group_table_alloc(bridge); if (bridge->group_table == NULL) { goto out; } /* Allocate meter table. */ bridge->meter_table = meter_table_alloc(); if (bridge->meter_table == NULL) { goto out; } /* Return bridge. */ return bridge; out: bridge_free(bridge); return NULL; }
void cnode_set_flag(struct cnode *cnode, int flag) { SET32_FLAG(cnode->flags, flag); }