X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=lib%2Fofp-parse.c;h=e3b7dc12269326bdfaa070e0c479fa57756d3cf3;hb=c6100d92142bc3dd325180cb4e10553eb4341731;hp=73a70c60c053ff13885f53ce54f5e9c8258345fd;hpb=623e1caf2f493bfcd96e3f9381d4e89257c92798;p=sliver-openvswitch.git diff --git a/lib/ofp-parse.c b/lib/ofp-parse.c index 73a70c60c..e3b7dc122 100644 --- a/lib/ofp-parse.c +++ b/lib/ofp-parse.c @@ -28,9 +28,10 @@ #include "dynamic-string.h" #include "learn.h" #include "meta-flow.h" -#include "netdev.h" #include "multipath.h" +#include "netdev.h" #include "nx-match.h" +#include "ofp-actions.h" #include "ofp-util.h" #include "ofpbuf.h" #include "openflow/openflow.h" @@ -122,107 +123,74 @@ str_to_ip(const char *str, ovs_be32 *ip) *ip = in_addr.s_addr; } -static struct ofp_action_output * -put_output_action(struct ofpbuf *b, uint16_t port) -{ - struct ofp_action_output *oao; - - oao = ofputil_put_OFPAT10_OUTPUT(b); - oao->port = htons(port); - return oao; -} - static void -parse_enqueue(struct ofpbuf *b, char *arg) +parse_enqueue(char *arg, struct ofpbuf *ofpacts) { char *sp = NULL; char *port = strtok_r(arg, ":q", &sp); char *queue = strtok_r(NULL, "", &sp); - struct ofp_action_enqueue *oae; + struct ofpact_enqueue *enqueue; if (port == NULL || queue == NULL) { ovs_fatal(0, "\"enqueue\" syntax is \"enqueue:PORT:QUEUE\""); } - oae = ofputil_put_OFPAT10_ENQUEUE(b); - oae->port = htons(str_to_u32(port)); - oae->queue_id = htonl(str_to_u32(queue)); + enqueue = ofpact_put_ENQUEUE(ofpacts); + enqueue->port = str_to_u32(port); + enqueue->queue = str_to_u32(queue); } static void -parse_output(struct ofpbuf *b, char *arg) +parse_output(char *arg, struct ofpbuf *ofpacts) { if (strchr(arg, '[')) { - struct nx_action_output_reg *naor; - struct mf_subfield src; + struct ofpact_output_reg *output_reg; - mf_parse_subfield(&src, arg); - - naor = ofputil_put_NXAST_OUTPUT_REG(b); - naor->ofs_nbits = nxm_encode_ofs_nbits(src.ofs, src.n_bits); - naor->src = htonl(src.field->nxm_header); - naor->max_len = htons(UINT16_MAX); + output_reg = ofpact_put_OUTPUT_REG(ofpacts); + mf_parse_subfield(&output_reg->src, arg); + output_reg->max_len = UINT16_MAX; } else { - put_output_action(b, str_to_u32(arg)); + struct ofpact_output *output; + + output = ofpact_put_OUTPUT(ofpacts); + output->port = str_to_u32(arg); + output->max_len = output->port == OFPP_CONTROLLER ? UINT16_MAX : 0; } } static void -parse_resubmit(struct ofpbuf *b, char *arg) +parse_resubmit(char *arg, struct ofpbuf *ofpacts) { - struct nx_action_resubmit *nar; + struct ofpact_resubmit *resubmit; char *in_port_s, *table_s; - uint16_t in_port; - uint8_t table; + + resubmit = ofpact_put_RESUBMIT(ofpacts); in_port_s = strsep(&arg, ","); if (in_port_s && in_port_s[0]) { - if (!ofputil_port_from_string(in_port_s, &in_port)) { - in_port = str_to_u32(in_port_s); + resubmit->in_port = ofputil_port_from_string(in_port_s); + if (!resubmit->in_port) { + ovs_fatal(0, "%s: resubmit to unknown port", in_port_s); } } else { - in_port = OFPP_IN_PORT; + resubmit->in_port = OFPP_IN_PORT; } table_s = strsep(&arg, ","); - table = table_s && table_s[0] ? str_to_u32(table_s) : 255; + resubmit->table_id = table_s && table_s[0] ? str_to_u32(table_s) : 255; - if (in_port == OFPP_IN_PORT && table == 255) { + if (resubmit->in_port == OFPP_IN_PORT && resubmit->table_id == 255) { ovs_fatal(0, "at least one \"in_port\" or \"table\" must be specified " " on resubmit"); } - - if (in_port != OFPP_IN_PORT && table == 255) { - nar = ofputil_put_NXAST_RESUBMIT(b); - } else { - nar = ofputil_put_NXAST_RESUBMIT_TABLE(b); - nar->table = table; - } - nar->in_port = htons(in_port); } static void -parse_set_tunnel(struct ofpbuf *b, const char *arg) +parse_note(const char *arg, struct ofpbuf *ofpacts) { - uint64_t tun_id = str_to_u64(arg); - if (tun_id > UINT32_MAX) { - ofputil_put_NXAST_SET_TUNNEL64(b)->tun_id = htonll(tun_id); - } else { - ofputil_put_NXAST_SET_TUNNEL(b)->tun_id = htonl(tun_id); - } -} - -static void -parse_note(struct ofpbuf *b, const char *arg) -{ - size_t start_ofs = b->size; - struct nx_action_note *nan; - int remainder; - size_t len; + struct ofpact_note *note; - nan = ofputil_put_NXAST_NOTE(b); - - b->size -= sizeof nan->note; + note = ofpact_put_NOTE(ofpacts); while (*arg != '\0') { uint8_t byte; bool ok; @@ -238,32 +206,27 @@ parse_note(struct ofpbuf *b, const char *arg) if (!ok) { ovs_fatal(0, "bad hex digit in `note' argument"); } - ofpbuf_put(b, &byte, 1); + ofpbuf_put(ofpacts, &byte, 1); - arg += 2; - } + note = ofpacts->l2; + note->length++; - len = b->size - start_ofs; - remainder = len % OFP_ACTION_ALIGN; - if (remainder) { - ofpbuf_put_zeros(b, OFP_ACTION_ALIGN - remainder); + arg += 2; } - nan = (struct nx_action_note *)((char *)b->data + start_ofs); - nan->len = htons(b->size - start_ofs); + ofpact_update_len(ofpacts, ¬e->ofpact); } static void parse_fin_timeout(struct ofpbuf *b, char *arg) { - struct nx_action_fin_timeout *naft; + struct ofpact_fin_timeout *oft = ofpact_put_FIN_TIMEOUT(b); char *key, *value; - naft = ofputil_put_NXAST_FIN_TIMEOUT(b); while (ofputil_parse_key_value(&arg, &key, &value)) { if (!strcmp(key, "idle_timeout")) { - naft->fin_idle_timeout = htons(str_to_u16(value, key)); + oft->fin_idle_timeout = str_to_u16(value, key); } else if (!strcmp(key, "hard_timeout")) { - naft->fin_hard_timeout = htons(str_to_u16(value, key)); + oft->fin_hard_timeout = str_to_u16(value, key); } else { ovs_fatal(0, "invalid key '%s' in 'fin_timeout' argument", key); } @@ -301,148 +264,224 @@ parse_controller(struct ofpbuf *b, char *arg) } if (reason == OFPR_ACTION && controller_id == 0) { - put_output_action(b, OFPP_CONTROLLER)->max_len = htons(max_len); + struct ofpact_output *output; + + output = ofpact_put_OUTPUT(b); + output->port = OFPP_CONTROLLER; + output->max_len = max_len; } else { - struct nx_action_controller *nac; + struct ofpact_controller *controller; - nac = ofputil_put_NXAST_CONTROLLER(b); - nac->max_len = htons(max_len); - nac->reason = reason; - nac->controller_id = htons(controller_id); + controller = ofpact_put_CONTROLLER(b); + controller->max_len = max_len; + controller->reason = reason; + controller->controller_id = controller_id; } } +static void +parse_dec_ttl(struct ofpbuf *b, char *arg) +{ + struct ofpact_cnt_ids *ids; + + ids = ofpact_put_DEC_TTL(b); + + if (*arg == '\0') { + uint16_t id = 0; + + ids->ofpact.compat = OFPUTIL_NXAST_DEC_TTL; + ofpbuf_put(b, &id, sizeof id); + ids = b->l2; + ids->n_controllers++; + } else { + char *cntr; + + ids->ofpact.compat = OFPUTIL_NXAST_DEC_TTL_CNT_IDS; + for (cntr = strtok_r(arg, ", ", &arg); cntr != NULL; + cntr = strtok_r(NULL, ", ", &arg)) { + uint16_t id = atoi(cntr); + + ofpbuf_put(b, &id, sizeof id); + ids = b->l2; + ids->n_controllers++; + } + if (!ids->n_controllers) { + ovs_fatal(0, "dec_ttl_cnt_ids: expected at least one controller " + "id."); + } + + } + ofpact_update_len(b, &ids->ofpact); +} + static void parse_named_action(enum ofputil_action_code code, const struct flow *flow, - struct ofpbuf *b, char *arg) + char *arg, struct ofpbuf *ofpacts) { - struct ofp_action_dl_addr *oada; - struct ofp_action_vlan_pcp *oavp; - struct ofp_action_vlan_vid *oavv; - struct ofp_action_nw_addr *oana; - struct ofp_action_tp_port *oata; + struct ofpact_tunnel *tunnel; + uint16_t vid; + ovs_be32 ip; + uint8_t pcp; + uint8_t tos; switch (code) { + case OFPUTIL_ACTION_INVALID: + NOT_REACHED(); + case OFPUTIL_OFPAT10_OUTPUT: - parse_output(b, arg); + case OFPUTIL_OFPAT11_OUTPUT: + parse_output(arg, ofpacts); break; case OFPUTIL_OFPAT10_SET_VLAN_VID: - oavv = ofputil_put_OFPAT10_SET_VLAN_VID(b); - oavv->vlan_vid = htons(str_to_u32(arg)); + case OFPUTIL_OFPAT11_SET_VLAN_VID: + vid = str_to_u32(arg); + if (vid & ~VLAN_VID_MASK) { + ovs_fatal(0, "%s: not a valid VLAN VID", arg); + } + ofpact_put_SET_VLAN_VID(ofpacts)->vlan_vid = vid; break; case OFPUTIL_OFPAT10_SET_VLAN_PCP: - oavp = ofputil_put_OFPAT10_SET_VLAN_PCP(b); - oavp->vlan_pcp = str_to_u32(arg); + case OFPUTIL_OFPAT11_SET_VLAN_PCP: + pcp = str_to_u32(arg); + if (pcp & ~7) { + ovs_fatal(0, "%s: not a valid VLAN PCP", arg); + } + ofpact_put_SET_VLAN_PCP(ofpacts)->vlan_pcp = pcp; + break; + + case OFPUTIL_OFPAT12_SET_FIELD: + NOT_REACHED(); /* This will be implemented by later patch and + * enabled using a non-NULL name in + * OFPAT12_ACTION(OFPAT12_SET_FIELD, ...) */ break; case OFPUTIL_OFPAT10_STRIP_VLAN: - ofputil_put_OFPAT10_STRIP_VLAN(b); + ofpact_put_STRIP_VLAN(ofpacts); break; case OFPUTIL_OFPAT10_SET_DL_SRC: + case OFPUTIL_OFPAT11_SET_DL_SRC: + str_to_mac(arg, ofpact_put_SET_ETH_SRC(ofpacts)->mac); + break; + case OFPUTIL_OFPAT10_SET_DL_DST: - oada = ofputil_put_action(code, b); - str_to_mac(arg, oada->dl_addr); + case OFPUTIL_OFPAT11_SET_DL_DST: + str_to_mac(arg, ofpact_put_SET_ETH_DST(ofpacts)->mac); break; case OFPUTIL_OFPAT10_SET_NW_SRC: + case OFPUTIL_OFPAT11_SET_NW_SRC: + str_to_ip(arg, &ip); + ofpact_put_SET_IPV4_SRC(ofpacts)->ipv4 = ip; + break; + case OFPUTIL_OFPAT10_SET_NW_DST: - oana = ofputil_put_action(code, b); - str_to_ip(arg, &oana->nw_addr); + case OFPUTIL_OFPAT11_SET_NW_DST: + str_to_ip(arg, &ip); + ofpact_put_SET_IPV4_DST(ofpacts)->ipv4 = ip; break; case OFPUTIL_OFPAT10_SET_NW_TOS: - ofputil_put_OFPAT10_SET_NW_TOS(b)->nw_tos = str_to_u32(arg); + case OFPUTIL_OFPAT11_SET_NW_TOS: + tos = str_to_u32(arg); + if (tos & ~IP_DSCP_MASK) { + ovs_fatal(0, "%s: not a valid TOS", arg); + } + ofpact_put_SET_IPV4_DSCP(ofpacts)->dscp = tos; break; case OFPUTIL_OFPAT10_SET_TP_SRC: + case OFPUTIL_OFPAT11_SET_TP_SRC: + ofpact_put_SET_L4_SRC_PORT(ofpacts)->port = str_to_u32(arg); + break; + case OFPUTIL_OFPAT10_SET_TP_DST: - oata = ofputil_put_action(code, b); - oata->tp_port = htons(str_to_u32(arg)); + case OFPUTIL_OFPAT11_SET_TP_DST: + ofpact_put_SET_L4_DST_PORT(ofpacts)->port = str_to_u32(arg); break; case OFPUTIL_OFPAT10_ENQUEUE: - parse_enqueue(b, arg); + parse_enqueue(arg, ofpacts); break; case OFPUTIL_NXAST_RESUBMIT: - parse_resubmit(b, arg); + parse_resubmit(arg, ofpacts); break; case OFPUTIL_NXAST_SET_TUNNEL: - parse_set_tunnel(b, arg); + case OFPUTIL_NXAST_SET_TUNNEL64: + tunnel = ofpact_put_SET_TUNNEL(ofpacts); + tunnel->ofpact.compat = code; + tunnel->tun_id = str_to_u64(arg); break; case OFPUTIL_NXAST_SET_QUEUE: - ofputil_put_NXAST_SET_QUEUE(b)->queue_id = htonl(str_to_u32(arg)); + ofpact_put_SET_QUEUE(ofpacts)->queue_id = str_to_u32(arg); break; case OFPUTIL_NXAST_POP_QUEUE: - ofputil_put_NXAST_POP_QUEUE(b); + ofpact_put_POP_QUEUE(ofpacts); break; case OFPUTIL_NXAST_REG_MOVE: - nxm_parse_reg_move(ofputil_put_NXAST_REG_MOVE(b), arg); + nxm_parse_reg_move(ofpact_put_REG_MOVE(ofpacts), arg); break; case OFPUTIL_NXAST_REG_LOAD: - nxm_parse_reg_load(ofputil_put_NXAST_REG_LOAD(b), arg); + nxm_parse_reg_load(ofpact_put_REG_LOAD(ofpacts), arg); break; case OFPUTIL_NXAST_NOTE: - parse_note(b, arg); - break; - - case OFPUTIL_NXAST_SET_TUNNEL64: - ofputil_put_NXAST_SET_TUNNEL64(b)->tun_id = htonll(str_to_u64(arg)); + parse_note(arg, ofpacts); break; case OFPUTIL_NXAST_MULTIPATH: - multipath_parse(ofputil_put_NXAST_MULTIPATH(b), arg); + multipath_parse(ofpact_put_MULTIPATH(ofpacts), arg); break; - case OFPUTIL_NXAST_AUTOPATH: - autopath_parse(ofputil_put_NXAST_AUTOPATH(b), arg); + case OFPUTIL_NXAST_AUTOPATH__DEPRECATED: + autopath_parse(ofpact_put_AUTOPATH(ofpacts), arg); break; case OFPUTIL_NXAST_BUNDLE: - bundle_parse(b, arg); + bundle_parse(arg, ofpacts); break; case OFPUTIL_NXAST_BUNDLE_LOAD: - bundle_parse_load(b, arg); + bundle_parse_load(arg, ofpacts); break; case OFPUTIL_NXAST_RESUBMIT_TABLE: case OFPUTIL_NXAST_OUTPUT_REG: + case OFPUTIL_NXAST_DEC_TTL_CNT_IDS: NOT_REACHED(); case OFPUTIL_NXAST_LEARN: - learn_parse(b, arg, flow); + learn_parse(arg, flow, ofpacts); break; case OFPUTIL_NXAST_EXIT: - ofputil_put_NXAST_EXIT(b); + ofpact_put_EXIT(ofpacts); break; case OFPUTIL_NXAST_DEC_TTL: - ofputil_put_NXAST_DEC_TTL(b); + parse_dec_ttl(ofpacts, arg); break; case OFPUTIL_NXAST_FIN_TIMEOUT: - parse_fin_timeout(b, arg); + parse_fin_timeout(ofpacts, arg); break; case OFPUTIL_NXAST_CONTROLLER: - parse_controller(b, arg); + parse_controller(ofpacts, arg); break; } } static void -str_to_action(const struct flow *flow, char *str, struct ofpbuf *b) +str_to_ofpacts(const struct flow *flow, char *str, struct ofpbuf *ofpacts) { char *pos, *act, *arg; int n_actions; @@ -450,15 +489,10 @@ str_to_action(const struct flow *flow, char *str, struct ofpbuf *b) pos = str; n_actions = 0; while (ofputil_parse_key_value(&pos, &act, &arg)) { - uint16_t port; - int code; - - code = ofputil_action_code_from_name(act); + int code = ofputil_action_code_from_name(act); if (code >= 0) { - parse_named_action(code, flow, b, arg); + parse_named_action(code, flow, arg, ofpacts); } else if (!strcasecmp(act, "drop")) { - /* A drop action in OpenFlow occurs by just not setting - * an action. */ if (n_actions) { ovs_fatal(0, "Drop actions must not be preceded by other " "actions"); @@ -467,13 +501,17 @@ str_to_action(const struct flow *flow, char *str, struct ofpbuf *b) "actions"); } break; - } else if (ofputil_port_from_string(act, &port)) { - put_output_action(b, port); } else { - ovs_fatal(0, "Unknown action: %s", act); + uint16_t port = ofputil_port_from_string(act); + if (port) { + ofpact_put_OUTPUT(ofpacts)->port = port; + } else { + ovs_fatal(0, "Unknown action: %s", act); + } } n_actions++; } + ofpact_pad(ofpacts); } struct protocol { @@ -523,7 +561,7 @@ ofp_fatal(const char *flow, bool verbose, const char *format, ...) } static void -parse_field(const struct mf_field *mf, const char *s, struct cls_rule *rule) +parse_field(const struct mf_field *mf, const char *s, struct match *match) { union mf_value value, mask; char *error; @@ -533,7 +571,7 @@ parse_field(const struct mf_field *mf, const char *s, struct cls_rule *rule) ovs_fatal(0, "%s", error); } - mf_set(mf, &value, &mask, rule); + mf_set(mf, &value, &mask, match); } /* Convert 'str_' (as described in the Flow Syntax section of the ovs-ofctl man @@ -589,7 +627,8 @@ parse_ofp_str(struct ofputil_flow_mod *fm, int command, const char *str_, NOT_REACHED(); } - cls_rule_init_catchall(&fm->cr, OFP_DEFAULT_PRIORITY); + match_init_catchall(&fm->match); + fm->priority = OFP_DEFAULT_PRIORITY; fm->cookie = htonll(0); fm->cookie_mask = htonll(0); if (command == OFPFC_MODIFY || command == OFPFC_MODIFY_STRICT) { @@ -624,9 +663,9 @@ parse_ofp_str(struct ofputil_flow_mod *fm, int command, const char *str_, const struct protocol *p; if (parse_protocol(name, &p)) { - cls_rule_set_dl_type(&fm->cr, htons(p->dl_type)); + match_set_dl_type(&fm->match, htons(p->dl_type)); if (p->nw_proto) { - cls_rule_set_nw_proto(&fm->cr, p->nw_proto); + match_set_nw_proto(&fm->match, p->nw_proto); } } else if (fields & F_FLAGS && !strcmp(name, "send_flow_rem")) { fm->flags |= OFPFF_SEND_FLOW_REM; @@ -643,9 +682,13 @@ parse_ofp_str(struct ofputil_flow_mod *fm, int command, const char *str_, if (!strcmp(name, "table")) { fm->table_id = str_to_table_id(value); } else if (!strcmp(name, "out_port")) { - fm->out_port = atoi(value); + fm->out_port = ofputil_port_from_string(name); + if (!fm->out_port) { + ofp_fatal(str_, verbose, "%s is not a valid OpenFlow port", + name); + } } else if (fields & F_PRIORITY && !strcmp(name, "priority")) { - fm->cr.priority = str_to_u16(value, name); + fm->priority = str_to_u16(value, name); } else if (fields & F_TIMEOUT && !strcmp(name, "idle_timeout")) { fm->idle_timeout = str_to_u16(value, name); } else if (fields & F_TIMEOUT && !strcmp(name, "hard_timeout")) { @@ -671,7 +714,7 @@ parse_ofp_str(struct ofputil_flow_mod *fm, int command, const char *str_, fm->new_cookie = htonll(str_to_u64(value)); } } else if (mf_from_name(name)) { - parse_field(mf_from_name(name), value, &fm->cr); + parse_field(mf_from_name(name), value, &fm->match); } else if (!strcmp(name, "duration") || !strcmp(name, "n_packets") || !strcmp(name, "n_bytes")) { @@ -691,30 +734,92 @@ parse_ofp_str(struct ofputil_flow_mod *fm, int command, const char *str_, fm->new_cookie = htonll(0); } if (fields & F_ACTIONS) { - struct ofpbuf actions; + struct ofpbuf ofpacts; - ofpbuf_init(&actions, sizeof(union ofp_action)); - str_to_action(&fm->cr.flow, act_str, &actions); - fm->actions = ofpbuf_steal_data(&actions); - fm->n_actions = actions.size / sizeof(union ofp_action); + ofpbuf_init(&ofpacts, 32); + str_to_ofpacts(&fm->match.flow, act_str, &ofpacts); + fm->ofpacts_len = ofpacts.size; + fm->ofpacts = ofpbuf_steal_data(&ofpacts); } else { - fm->actions = NULL; - fm->n_actions = 0; + fm->ofpacts_len = 0; + fm->ofpacts = NULL; } free(string); } +/* Convert 'str_' (as described in the documentation for the "monitor" command + * in the ovs-ofctl man page) into 'fmr'. */ +void +parse_flow_monitor_request(struct ofputil_flow_monitor_request *fmr, + const char *str_) +{ + static uint32_t id; + + char *string = xstrdup(str_); + char *save_ptr = NULL; + char *name; + + fmr->id = id++; + fmr->flags = (NXFMF_INITIAL | NXFMF_ADD | NXFMF_DELETE | NXFMF_MODIFY + | NXFMF_OWN | NXFMF_ACTIONS); + fmr->out_port = OFPP_NONE; + fmr->table_id = 0xff; + match_init_catchall(&fmr->match); + + for (name = strtok_r(string, "=, \t\r\n", &save_ptr); name; + name = strtok_r(NULL, "=, \t\r\n", &save_ptr)) { + const struct protocol *p; + + if (!strcmp(name, "!initial")) { + fmr->flags &= ~NXFMF_INITIAL; + } else if (!strcmp(name, "!add")) { + fmr->flags &= ~NXFMF_ADD; + } else if (!strcmp(name, "!delete")) { + fmr->flags &= ~NXFMF_DELETE; + } else if (!strcmp(name, "!modify")) { + fmr->flags &= ~NXFMF_MODIFY; + } else if (!strcmp(name, "!actions")) { + fmr->flags &= ~NXFMF_ACTIONS; + } else if (!strcmp(name, "!own")) { + fmr->flags &= ~NXFMF_OWN; + } else if (parse_protocol(name, &p)) { + match_set_dl_type(&fmr->match, htons(p->dl_type)); + if (p->nw_proto) { + match_set_nw_proto(&fmr->match, p->nw_proto); + } + } else { + char *value; + + value = strtok_r(NULL, ", \t\r\n", &save_ptr); + if (!value) { + ovs_fatal(0, "%s: field %s missing value", str_, name); + } + + if (!strcmp(name, "table")) { + fmr->table_id = str_to_table_id(value); + } else if (!strcmp(name, "out_port")) { + fmr->out_port = atoi(value); + } else if (mf_from_name(name)) { + parse_field(mf_from_name(name), value, &fmr->match); + } else { + ovs_fatal(0, "%s: unknown keyword %s", str_, name); + } + } + } + free(string); +} + /* Parses 's' as a set of OpenFlow actions and appends the actions to * 'actions'. * * Prints an error on stderr and aborts the program if 's' syntax is * invalid. */ void -parse_ofp_actions(const char *s_, struct ofpbuf *actions) +parse_ofpacts(const char *s_, struct ofpbuf *ofpacts) { char *s = xstrdup(s_); - str_to_action(NULL, s, actions); + str_to_ofpacts(NULL, s, ofpacts); free(s); } @@ -724,15 +829,15 @@ void parse_ofp_flow_mod_str(struct ofputil_flow_mod *fm, const char *string, uint16_t command, bool verbose) { - struct cls_rule rule_copy; + struct match match_copy; parse_ofp_str(fm, command, string, verbose); - /* Normalize a copy of the rule. This ensures that non-normalized flows + /* 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. */ - rule_copy = fm->cr; - ofputil_normalize_rule(&rule_copy); + match_copy = fm->match; + ofputil_normalize_match(&match_copy); } void @@ -774,7 +879,7 @@ parse_ofp_flow_stats_request_str(struct ofputil_flow_stats_request *fsr, fsr->aggregate = aggregate; fsr->cookie = fm.cookie; fsr->cookie_mask = fm.cookie_mask; - fsr->match = fm.cr; + fsr->match = fm.match; fsr->out_port = fm.out_port; fsr->table_id = fm.table_id; }