/* Parses 'string' as an OFPT_FLOW_MOD or NXT_FLOW_MOD with command 'command' * (one of OFPFC_*) and appends the parsed OpenFlow message to 'packets'. * '*cur_format' should initially contain the flow format currently configured * on the connection; this function will add a message to change the flow * format and update '*cur_format', if this is necessary to add the parsed * flow. */ void parse_ofp_flow_mod_str(struct list *packets, enum nx_flow_format *cur_format, char *string, uint16_t command) { bool is_del = command == OFPFC_DELETE || command == OFPFC_DELETE_STRICT; enum nx_flow_format min_format, next_format; struct ofpbuf actions; struct ofpbuf *ofm; struct flow_mod fm; ofpbuf_init(&actions, 64); parse_ofp_str(&fm, NULL, is_del ? NULL : &actions, string); fm.command = command; min_format = ofputil_min_flow_format(&fm.cr, true, fm.cookie); next_format = MAX(*cur_format, min_format); if (next_format != *cur_format) { struct ofpbuf *sff = ofputil_make_set_flow_format(next_format); list_push_back(packets, &sff->list_node); *cur_format = next_format; } ofm = ofputil_encode_flow_mod(&fm, *cur_format); list_push_back(packets, &ofm->list_node); ofpbuf_uninit(&actions); }
void parse_ofp_flow_stats_request_str(struct ofputil_flow_stats_request *fsr, bool aggregate, const char *string) { struct ofputil_flow_mod fm; parse_ofp_str(&fm, -1, string, false); fsr->aggregate = aggregate; fsr->cookie = fm.cookie; fsr->cookie_mask = fm.cookie_mask; fsr->match = fm.match; fsr->out_port = fm.out_port; fsr->table_id = fm.table_id; }
/* Parses 'string' as an OFPT_FLOW_MOD or NXT_FLOW_MOD with command 'command' * (one of OFPFC_*) into 'fm'. */ void parse_ofp_flow_mod_str(struct ofputil_flow_mod *fm, const char *string, uint16_t command, bool verbose) { struct match match_copy; parse_ofp_str(fm, command, string, verbose); /* Normalize a copy of the match. This ensures that non-normalized flows * get logged but doesn't affect what gets sent to the switch, so that the * switch can do whatever it likes with the flow. */ match_copy = fm->match; ofputil_normalize_match(&match_copy); }
/* Parses 'string' as an OFPT_FLOW_MOD or NXT_FLOW_MOD with command 'command' * (one of OFPFC_*) into 'fm'. * * If 'command' is given as -2, 'string' may begin with a command name ("add", * "modify", "delete", "modify_strict", or "delete_strict"). A missing command * name is treated as "add". * * Returns NULL if successful, otherwise a malloc()'d string describing the * error. The caller is responsible for freeing the returned string. */ char * OVS_WARN_UNUSED_RESULT parse_ofp_flow_mod_str(struct ofputil_flow_mod *fm, const char *string, const struct ofputil_port_map *port_map, const struct ofputil_table_map *table_map, int command, enum ofputil_protocol *usable_protocols) { char *error = parse_ofp_str(fm, command, string, port_map, table_map, usable_protocols); if (!error) { /* Normalize a copy of the match. This ensures that non-normalized * flows get logged but doesn't affect what gets sent to the switch, so * that the switch can do whatever it likes with the flow. */ struct match match_copy = fm->match; ofputil_normalize_match(&match_copy); } return error; }
/* Parses 'string' as an OFPT_FLOW_MOD or NXT_FLOW_MOD with command 'command' * (one of OFPFC_*) and appends the parsed OpenFlow message to 'packets'. * '*cur_format' should initially contain the flow format currently configured * on the connection; this function will add a message to change the flow * format and update '*cur_format', if this is necessary to add the parsed * flow. */ void parse_ofp_flow_mod_str(struct list *packets, enum nx_flow_format *cur_format, bool *flow_mod_table_id, char *string, uint16_t command, bool verbose) { enum nx_flow_format min_format, next_format; struct cls_rule rule_copy; struct ofpbuf *ofm; struct ofputil_flow_mod fm; parse_ofp_str(&fm, command, string, verbose); min_format = ofputil_min_flow_format(&fm.cr); if (command != OFPFC_ADD && fm.cookie_mask != htonll(0)) { min_format = NXFF_NXM; } next_format = MAX(*cur_format, min_format); if (next_format != *cur_format) { struct ofpbuf *sff = ofputil_make_set_flow_format(next_format); list_push_back(packets, &sff->list_node); *cur_format = next_format; } /* Normalize a copy of the rule. This ensures that non-normalized flows * get logged but doesn't affect what gets sent to the switch, so that the * switch can do whatever it likes with the flow. */ rule_copy = fm.cr; ofputil_normalize_rule(&rule_copy, next_format); if (fm.table_id != 0xff && !*flow_mod_table_id) { struct ofpbuf *sff = ofputil_make_flow_mod_table_id(true); list_push_back(packets, &sff->list_node); *flow_mod_table_id = true; } ofm = ofputil_encode_flow_mod(&fm, *cur_format, *flow_mod_table_id); list_push_back(packets, &ofm->list_node); }