/* Handles flow mod messages with MODIFY command. */
static ofl_err
flow_table_modify(struct flow_table *table, struct ofl_msg_flow_mod *mod, bool strict, bool *match_kept, bool *insts_kept) {
    struct flow_entry *entry;
    bool match_found;

    match_found = false;

    LIST_FOR_EACH (entry, struct flow_entry, match_node, &table->match_entries) {
        if (flow_entry_matches(entry, mod, strict, true/*check_cookie*/)) {
            flow_entry_replace_instructions(entry, mod->instructions_num, mod->instructions);
            *insts_kept = true;
            match_found = true;
        }
    }

    /* NOTE: if modify does not modify any entries, it acts like an add according to spec. */
    if (!match_found) {
        return flow_table_add(table, mod, false, match_kept, insts_kept);
    }

    return 0;
}
示例#2
0
ofl_err
flow_table_flow_mod(struct flow_table *table, struct ofl_msg_flow_mod *mod, bool *match_kept, bool *insts_kept) {
    switch (mod->command) {
        case (OFPFC_ADD): {
            bool overlap = ((mod->flags & OFPFF_CHECK_OVERLAP) != 0);
            return flow_table_add(table, mod, overlap, match_kept, insts_kept);
        }
        case (OFPFC_MODIFY): {
            return flow_table_modify(table, mod, false, insts_kept);
        }
        case (OFPFC_MODIFY_STRICT): {
            return flow_table_modify(table, mod, true, insts_kept);
        }
        case (OFPFC_DELETE): {
            return flow_table_delete(table, mod, false);
        }
        case (OFPFC_DELETE_STRICT): {
            return flow_table_delete(table, mod, true);
        }
        default: {
            return ofl_error(OFPET_FLOW_MOD_FAILED, OFPFMFC_BAD_COMMAND);
        }
    }
}