ofpacts_check() now stores the nw_proto field from flow to port number set actions, so that we later remember which protocol they relate to. This is needed for an accurate tranlation to OF 1.2+ set field action.
Simplify some of the ofp-actions interface. Signed-off-by: Jarno Rajahalme <jrajaha...@nicira.com> --- lib/ofp-actions.c | 235 +++++++++++++++++++++++++++++++++++++++---------- lib/ofp-actions.h | 18 ++-- lib/ofp-util.c | 49 ++++++----- lib/ofp-util.h | 3 +- ofproto/ofproto.c | 5 +- tests/ovs-ofctl.at | 12 ++- utilities/ovs-ofctl.c | 10 ++- 7 files changed, 248 insertions(+), 84 deletions(-) diff --git a/lib/ofp-actions.c b/lib/ofp-actions.c index 8c9dd8c..0963874 100644 --- a/lib/ofp-actions.c +++ b/lib/ofp-actions.c @@ -1524,7 +1524,7 @@ exit: /* May modify flow->dl_type, caller must restore it. */ static enum ofperr -ofpact_check__(const struct ofpact *a, struct flow *flow, ofp_port_t max_ports, +ofpact_check__(struct ofpact *a, struct flow *flow, ofp_port_t max_ports, uint8_t table_id) { const struct ofpact_enqueue *enqueue; @@ -1562,12 +1562,28 @@ ofpact_check__(const struct ofpact *a, struct flow *flow, ofp_port_t max_ports, case OFPACT_SET_IPV4_SRC: case OFPACT_SET_IPV4_DST: case OFPACT_SET_IPV4_DSCP: - case OFPACT_SET_L4_SRC_PORT: - case OFPACT_SET_L4_DST_PORT: case OFPACT_SET_IP_ECN: case OFPACT_SET_IP_TTL: return 0; + case OFPACT_SET_L4_SRC_PORT: + /* Note on which transport protocol the port numbers are set. + * This allows this set action to be converted to an OF1.2 set field + * action. */ + if (is_ip_any(flow)) { + ofpact_get_SET_L4_SRC_PORT(a)->ip_proto = flow->nw_proto; + } + return 0; + + case OFPACT_SET_L4_DST_PORT: + /* Note on which transport protocol the port numbers are set. + * This allows this set action to be converted to an OF1.2 set field + * action. */ + if (is_ip_any(flow)) { + ofpact_get_SET_L4_DST_PORT(a)->ip_proto = flow->nw_proto; + } + return 0; + case OFPACT_REG_MOVE: return nxm_reg_move_check(ofpact_get_REG_MOVE(a), flow); @@ -1658,12 +1674,14 @@ ofpact_check__(const struct ofpact *a, struct flow *flow, ofp_port_t max_ports, * appropriate for a packet with the prerequisites satisfied by 'flow' in a * switch with no more than 'max_ports' ports. * + * May annotate ofpacts with information gathered from the 'flow'. + * * May temporarily modify 'flow', but restores the changes before returning. */ enum ofperr -ofpacts_check(const struct ofpact ofpacts[], size_t ofpacts_len, +ofpacts_check(struct ofpact ofpacts[], size_t ofpacts_len, struct flow *flow, ofp_port_t max_ports, uint8_t table_id) { - const struct ofpact *a; + struct ofpact *a; ovs_be16 dl_type = flow->dl_type; enum ofperr error = 0; @@ -1871,10 +1889,6 @@ ofpact_to_nxast(const struct ofpact *a, struct ofpbuf *out) nxm_reg_load_to_nxast(ofpact_get_REG_LOAD(a), out); break; - case OFPACT_SET_FIELD: - ofputil_set_field_to_openflow(ofpact_get_SET_FIELD(a), out); - break; - case OFPACT_STACK_PUSH: nxm_stack_push_to_nxast(ofpact_get_STACK_PUSH(a), out); break; @@ -1971,6 +1985,7 @@ ofpact_to_nxast(const struct ofpact *a, struct ofpbuf *out) case OFPACT_CLEAR_ACTIONS: case OFPACT_GOTO_TABLE: case OFPACT_METER: + case OFPACT_SET_FIELD: NOT_REACHED(); } } @@ -2071,12 +2086,15 @@ ofpact_to_openflow10(const struct ofpact *a, struct ofpbuf *out) case OFPACT_GROUP: break; + case OFPACT_SET_FIELD: + ofputil_set_field_to_openflow(ofpact_get_SET_FIELD(a), out); + break; + case OFPACT_CONTROLLER: case OFPACT_OUTPUT_REG: case OFPACT_BUNDLE: case OFPACT_REG_MOVE: case OFPACT_REG_LOAD: - case OFPACT_SET_FIELD: case OFPACT_STACK_PUSH: case OFPACT_STACK_POP: case OFPACT_DEC_TTL: @@ -2101,20 +2119,6 @@ ofpact_to_openflow10(const struct ofpact *a, struct ofpbuf *out) break; } } - -/* Converts the 'ofpacts_len' bytes of ofpacts in 'ofpacts' into OpenFlow 1.0 - * actions in 'openflow', appending the actions to any existing data in - * 'openflow'. */ -void -ofpacts_put_openflow10(const struct ofpact ofpacts[], size_t ofpacts_len, - struct ofpbuf *openflow) -{ - const struct ofpact *a; - - OFPACT_FOR_EACH (a, ofpacts, ofpacts_len) { - ofpact_to_openflow10(a, openflow); - } -} /* Converting ofpacts to OpenFlow 1.1. */ @@ -2262,12 +2266,15 @@ ofpact_to_openflow11(const struct ofpact *a, struct ofpbuf *out) htonl(ofpact_get_GROUP(a)->group_id); break; + case OFPACT_SET_FIELD: + ofputil_set_field_to_openflow(ofpact_get_SET_FIELD(a), out); + break; + case OFPACT_CONTROLLER: case OFPACT_OUTPUT_REG: case OFPACT_BUNDLE: case OFPACT_REG_MOVE: case OFPACT_REG_LOAD: - case OFPACT_SET_FIELD: case OFPACT_STACK_PUSH: case OFPACT_STACK_POP: case OFPACT_SET_TUNNEL: @@ -2284,20 +2291,149 @@ ofpact_to_openflow11(const struct ofpact *a, struct ofpbuf *out) } } -/* Converts the ofpacts in 'ofpacts' (terminated by OFPACT_END) into OpenFlow - * 1.1 actions in 'openflow', appending the actions to any existing data in +/* Output deprecated set actions as set_field actions. */ +static void +ofpact_to_openflow12(const struct ofpact *a, struct ofpbuf *out) +{ + uint64_t ofpacts_stub[128 / 8]; + struct ofpbuf sf_act; + enum mf_field_id field; + union mf_value mf_value; + void *value = &mf_value; + struct ofpact_set_field *sf; + struct ofpact_l4_port *l4port; + uint8_t proto; + + switch ((int)a->type) { + case OFPACT_SET_VLAN_VID: + case OFPACT_SET_VLAN_PCP: + case OFPACT_SET_ETH_SRC: + case OFPACT_SET_ETH_DST: + case OFPACT_SET_IPV4_SRC: + case OFPACT_SET_IPV4_DST: + case OFPACT_SET_IPV4_DSCP: + case OFPACT_SET_IP_ECN: + case OFPACT_SET_IP_TTL: + case OFPACT_SET_L4_SRC_PORT: + case OFPACT_SET_L4_DST_PORT: + /* case OFPACT_SET_MPLS_LABEL: */ + /* case OFPACT_SET_MPLS_TC: */ + case OFPACT_SET_TUNNEL: /* Convert to a set_field, too. */ + + switch ((int)a->type) { + + case OFPACT_SET_VLAN_VID: + field = MFF_VLAN_VID; + mf_value.be16 = htons(ofpact_get_SET_VLAN_VID(a)->vlan_vid); + break; + + case OFPACT_SET_VLAN_PCP: + field = MFF_VLAN_PCP; + value = &ofpact_get_SET_VLAN_PCP(a)->vlan_pcp; + break; + + case OFPACT_SET_ETH_SRC: + field = MFF_ETH_SRC; + value = &ofpact_get_SET_ETH_SRC(a)->mac; + break; + + case OFPACT_SET_ETH_DST: + field = MFF_ETH_DST; + value = &ofpact_get_SET_ETH_DST(a)->mac; + break; + + case OFPACT_SET_IPV4_SRC: + field = MFF_IPV4_SRC; + value = &ofpact_get_SET_IPV4_SRC(a)->ipv4; + break; + + case OFPACT_SET_IPV4_DST: + field = MFF_IPV4_DST; + value = &ofpact_get_SET_IPV4_DST(a)->ipv4; + break; + + case OFPACT_SET_IPV4_DSCP: + field = MFF_IP_DSCP; + value = &ofpact_get_SET_IPV4_DSCP(a)->dscp; + break; + + case OFPACT_SET_IP_ECN: + field = MFF_IP_ECN; + value = &ofpact_get_SET_IP_ECN(a)->ecn; + break; + + case OFPACT_SET_IP_TTL: + field = MFF_IP_TTL; + value = &ofpact_get_SET_IP_TTL(a)->ttl; + break; + + case OFPACT_SET_L4_SRC_PORT: + l4port = ofpact_get_SET_L4_SRC_PORT(a); + proto = l4port->ip_proto; + field = proto == IPPROTO_SCTP ? MFF_SCTP_SRC + : proto == IPPROTO_UDP ? MFF_UDP_SRC : MFF_TCP_SRC; /* XXX */ + mf_value.be16 = htons(l4port->port); + break; + + case OFPACT_SET_L4_DST_PORT: + l4port = ofpact_get_SET_L4_DST_PORT(a); + proto = l4port->ip_proto; + field = proto == IPPROTO_SCTP ? MFF_SCTP_DST + : proto == IPPROTO_UDP ? MFF_UDP_DST : MFF_TCP_DST; /* XXX */ + mf_value.be16 = htons(l4port->port); + break; +#if 0 + case OFPACT_SET_MPLS_LABEL: + field = MFF_MPLS_LABEL; + mf_value.be32 = htonl(ofpact_get_SET_MPLS_LABEL(a)->label); + break; + + case OFPACT_SET_MPLS_TC: + field = MFF_MPLS_TC; + value = &ofpact_get_SET_MPLS_LABEL(a)->tc; + break; +#endif + case OFPACT_SET_TUNNEL: + field = MFF_TUN_ID; + mf_value.be64 = htonll(ofpact_get_SET_TUNNEL(a)->tun_id); + break; + + default: + field = MFF_N_IDS; + } + + /* Out the action out as a set field action. */ + if (field < MFF_N_IDS) { + ofpbuf_use_stub(&sf_act, ofpacts_stub, sizeof ofpacts_stub); + sf = ofpact_set_field_from_be_value(mf_from_id(field), value, + &sf_act); + ofputil_set_field_to_openflow(sf, out); + return; + } + } + + ofpact_to_openflow11(a, out); +} + +/* Converts the 'ofpacts_len' bytes of ofpacts in 'ofpacts' into OpenFlow + * actions in 'openflow', appending the actions to any existing data in * 'openflow'. */ size_t -ofpacts_put_openflow11_actions(const struct ofpact ofpacts[], - size_t ofpacts_len, struct ofpbuf *openflow) +ofpacts_put_openflow_actions(const struct ofpact ofpacts[], size_t ofpacts_len, + struct ofpbuf *openflow, + enum ofp_version ofp_version) { const struct ofpact *a; size_t start_size = openflow->size; + void (*translate)(const struct ofpact *a, struct ofpbuf *out) = + (ofp_version == OFP10_VERSION) ? ofpact_to_openflow10 : + (ofp_version == OFP11_VERSION) ? ofpact_to_openflow11 : + ofpact_to_openflow12; + OFPACT_FOR_EACH (a, ofpacts, ofpacts_len) { - ofpact_to_openflow11(a, openflow); + translate(a, openflow); } - return openflow->size - start_size; } @@ -2316,12 +2452,15 @@ ofpacts_update_instruction_actions(struct ofpbuf *openflow, size_t ofs) } void -ofpacts_put_openflow11_instructions(const struct ofpact ofpacts[], - size_t ofpacts_len, - struct ofpbuf *openflow) +ofpacts_put_openflow_instructions(const struct ofpact ofpacts[], + size_t ofpacts_len, + struct ofpbuf *openflow, + enum ofp_version ofp_version) { const struct ofpact *a; + ovs_assert(ofp_version >= OFP11_VERSION); + OFPACT_FOR_EACH (a, ofpacts, ofpacts_len) { switch (ovs_instruction_type_from_ofpact_type(a->type)) { case OVSINST_OFPIT11_CLEAR_ACTIONS: @@ -2347,15 +2486,16 @@ ofpacts_put_openflow11_instructions(const struct ofpact ofpacts[], break; } - case OVSINST_OFPIT13_METER: { - const struct ofpact_meter *om; - struct ofp13_instruction_meter *oim; + case OVSINST_OFPIT13_METER: + if (ofp_version >= OFP13_VERSION) { + const struct ofpact_meter *om; + struct ofp13_instruction_meter *oim; - om = ofpact_get_METER(a); - oim = instruction_put_OFPIT13_METER(openflow); - oim->meter_id = htonl(om->meter_id); + om = ofpact_get_METER(a); + oim = instruction_put_OFPIT13_METER(openflow); + oim->meter_id = htonl(om->meter_id); + } break; - } case OVSINST_OFPIT11_APPLY_ACTIONS: { const size_t ofs = openflow->size; @@ -2370,7 +2510,11 @@ ofpacts_put_openflow11_instructions(const struct ofpact ofpacts[], != OVSINST_OFPIT11_APPLY_ACTIONS) { break; } - ofpact_to_openflow11(action, openflow); + if (ofp_version == OFP11_VERSION) { + ofpact_to_openflow11(action, openflow); + } else { + ofpact_to_openflow12(action, openflow); + } processed = action; } ofpacts_update_instruction_actions(openflow, ofs); @@ -2384,9 +2528,9 @@ ofpacts_put_openflow11_instructions(const struct ofpact ofpacts[], on = ofpact_get_WRITE_ACTIONS(a); instruction_put_OFPIT11_WRITE_ACTIONS(openflow); - ofpacts_put_openflow11_actions(on->actions, - ofpact_nest_get_action_len(on), - openflow); + ofpacts_put_openflow_actions(on->actions, + ofpact_nest_get_action_len(on), + openflow, ofp_version); ofpacts_update_instruction_actions(openflow, ofs); break; @@ -2394,6 +2538,7 @@ ofpacts_put_openflow11_instructions(const struct ofpact ofpacts[], } } } + /* Returns true if 'action' outputs to 'port', false otherwise. */ static bool diff --git a/lib/ofp-actions.h b/lib/ofp-actions.h index b97d14b..4e13472 100644 --- a/lib/ofp-actions.h +++ b/lib/ofp-actions.h @@ -320,7 +320,8 @@ struct ofpact_ip_ttl { * Used for OFPAT10_SET_TP_SRC, OFPAT10_SET_TP_DST. */ struct ofpact_l4_port { struct ofpact ofpact; - uint16_t port; /* TCP or UDP port number. */ + uint16_t port; /* TCP, UDP or SCTP port number. */ + uint8_t ip_proto; /* IP proto from corresponding match, or 0 */ }; /* OFPACT_REG_MOVE. @@ -601,19 +602,18 @@ enum ofperr ofpacts_pull_openflow11_actions(struct ofpbuf *openflow, enum ofperr ofpacts_pull_openflow11_instructions(struct ofpbuf *openflow, unsigned int instructions_len, struct ofpbuf *ofpacts); -enum ofperr ofpacts_check(const struct ofpact[], size_t ofpacts_len, +enum ofperr ofpacts_check(struct ofpact[], size_t ofpacts_len, struct flow *, ofp_port_t max_ports, uint8_t table_id); enum ofperr ofpacts_verify(const struct ofpact ofpacts[], size_t ofpacts_len); /* Converting ofpacts to OpenFlow. */ -void ofpacts_put_openflow10(const struct ofpact[], size_t ofpacts_len, - struct ofpbuf *openflow); -size_t ofpacts_put_openflow11_actions(const struct ofpact[], size_t ofpacts_len, - struct ofpbuf *openflow); -void ofpacts_put_openflow11_instructions(const struct ofpact[], - size_t ofpacts_len, - struct ofpbuf *openflow); +size_t ofpacts_put_openflow_actions(const struct ofpact[], size_t ofpacts_len, + struct ofpbuf *openflow, enum ofp_version); +void ofpacts_put_openflow_instructions(const struct ofpact[], + size_t ofpacts_len, + struct ofpbuf *openflow, + enum ofp_version ofp_version); /* Working with ofpacts. */ bool ofpacts_output_to_port(const struct ofpact[], size_t ofpacts_len, diff --git a/lib/ofp-util.c b/lib/ofp-util.c index 17642d2..ee701e9 100644 --- a/lib/ofp-util.c +++ b/lib/ofp-util.c @@ -2065,7 +2065,8 @@ ofputil_encode_flow_mod(const struct ofputil_flow_mod *fm, ofm->out_group = htonl(fm->out_group); ofm->flags = raw_flags; ofputil_put_ofp11_match(msg, &fm->match, protocol); - ofpacts_put_openflow11_instructions(fm->ofpacts, fm->ofpacts_len, msg); + ofpacts_put_openflow_instructions(fm->ofpacts, fm->ofpacts_len, msg, + version); break; } @@ -2085,7 +2086,8 @@ ofputil_encode_flow_mod(const struct ofputil_flow_mod *fm, ofm->buffer_id = htonl(fm->buffer_id); ofm->out_port = htons(ofp_to_u16(fm->out_port)); ofm->flags = raw_flags; - ofpacts_put_openflow10(fm->ofpacts, fm->ofpacts_len, msg); + ofpacts_put_openflow_actions(fm->ofpacts, fm->ofpacts_len, msg, + version); break; } @@ -2108,7 +2110,8 @@ ofputil_encode_flow_mod(const struct ofputil_flow_mod *fm, nfm->out_port = htons(ofp_to_u16(fm->out_port)); nfm->flags = raw_flags; nfm->match_len = htons(match_len); - ofpacts_put_openflow10(fm->ofpacts, fm->ofpacts_len, msg); + ofpacts_put_openflow_actions(fm->ofpacts, fm->ofpacts_len, msg, + version); break; } @@ -2498,16 +2501,16 @@ ofputil_append_flow_stats_reply(const struct ofputil_flow_stats *fs, struct ofpbuf *reply = ofpbuf_from_list(list_back(replies)); size_t start_ofs = reply->size; enum ofpraw raw; + const struct ofp_header *oh = reply->data; ofpraw_decode_partial(&raw, reply->data, reply->size); if (raw == OFPRAW_OFPST11_FLOW_REPLY || raw == OFPRAW_OFPST13_FLOW_REPLY) { - const struct ofp_header *oh = reply->data; struct ofp11_flow_stats *ofs; ofpbuf_put_uninit(reply, sizeof *ofs); oxm_put_match(reply, &fs->match); - ofpacts_put_openflow11_instructions(fs->ofpacts, fs->ofpacts_len, - reply); + ofpacts_put_openflow_instructions(fs->ofpacts, fs->ofpacts_len, reply, + oh->version); ofs = ofpbuf_at_assert(reply, start_ofs, sizeof *ofs); ofs->length = htons(reply->size - start_ofs); @@ -2531,8 +2534,8 @@ ofputil_append_flow_stats_reply(const struct ofputil_flow_stats *fs, struct ofp10_flow_stats *ofs; ofpbuf_put_uninit(reply, sizeof *ofs); - ofpacts_put_openflow10(fs->ofpacts, fs->ofpacts_len, reply); - + ofpacts_put_openflow_actions(fs->ofpacts, fs->ofpacts_len, reply, + oh->version); ofs = ofpbuf_at_assert(reply, start_ofs, sizeof *ofs); ofs->length = htons(reply->size - start_ofs); ofs->table_id = fs->table_id; @@ -2555,8 +2558,8 @@ ofputil_append_flow_stats_reply(const struct ofputil_flow_stats *fs, ofpbuf_put_uninit(reply, sizeof *nfs); match_len = nx_put_match(reply, &fs->match, 0, 0); - ofpacts_put_openflow10(fs->ofpacts, fs->ofpacts_len, reply); - + ofpacts_put_openflow_actions(fs->ofpacts, fs->ofpacts_len, reply, + oh->version); nfs = ofpbuf_at_assert(reply, start_ofs, sizeof *nfs); nfs->length = htons(reply->size - start_ofs); nfs->table_id = fs->table_id; @@ -4298,9 +4301,11 @@ ofputil_append_flow_update(const struct ofputil_flow_update *update, struct nx_flow_update_header *nfuh; struct ofpbuf *msg; size_t start_ofs; + struct ofp_header *oh; msg = ofpbuf_from_list(list_back(replies)); start_ofs = msg->size; + oh = msg->l2; if (update->event == NXFME_ABBREV) { struct nx_flow_update_abbrev *nfua; @@ -4313,8 +4318,8 @@ ofputil_append_flow_update(const struct ofputil_flow_update *update, ofpbuf_put_zeros(msg, sizeof *nfuf); match_len = nx_put_match(msg, update->match, htonll(0), htonll(0)); - ofpacts_put_openflow10(update->ofpacts, update->ofpacts_len, msg); - + ofpacts_put_openflow_actions(update->ofpacts, update->ofpacts_len, msg, + oh->version); nfuf = ofpbuf_at_assert(msg, start_ofs, sizeof *nfuf); nfuf->reason = htons(update->reason); nfuf->priority = htons(update->priority); @@ -4353,7 +4358,8 @@ ofputil_encode_packet_out(const struct ofputil_packet_out *po, msg = ofpraw_alloc(OFPRAW_OFPT10_PACKET_OUT, OFP10_VERSION, size); ofpbuf_put_zeros(msg, sizeof *opo); actions_ofs = msg->size; - ofpacts_put_openflow10(po->ofpacts, po->ofpacts_len, msg); + ofpacts_put_openflow_actions(po->ofpacts, po->ofpacts_len, msg, + ofp_version); opo = msg->l3; opo->buffer_id = htonl(po->buffer_id); @@ -4370,8 +4376,8 @@ ofputil_encode_packet_out(const struct ofputil_packet_out *po, msg = ofpraw_alloc(OFPRAW_OFPT11_PACKET_OUT, ofp_version, size); ofpbuf_put_zeros(msg, sizeof *opo); - len = ofpacts_put_openflow11_actions(po->ofpacts, po->ofpacts_len, msg); - + len = ofpacts_put_openflow_actions(po->ofpacts, po->ofpacts_len, msg, + ofp_version); opo = msg->l3; opo->buffer_id = htonl(po->buffer_id); opo->in_port = ofputil_port_to_ofp11(po->in_port); @@ -5641,7 +5647,8 @@ ofputil_decode_group_stats_reply(struct ofpbuf *msg, void ofputil_append_group_desc_reply(const struct ofputil_group_desc *gds, struct list *buckets, - struct list *replies) + struct list *replies, + enum ofp_version ofp_version) { struct ofpbuf *reply = ofpbuf_from_list(list_back(replies)); struct ofp11_group_desc_stats *ogds; @@ -5656,9 +5663,8 @@ ofputil_append_group_desc_reply(const struct ofputil_group_desc *gds, start_ob = reply->size; ofpbuf_put_zeros(reply, sizeof *ob); - ofpacts_put_openflow11_actions(bucket->ofpacts, - bucket->ofpacts_len, reply); - + ofpacts_put_openflow_actions(bucket->ofpacts, bucket->ofpacts_len, + reply, ofp_version); ob = ofpbuf_at_assert(reply, start_ob, sizeof *ob); ob->len = htons(reply->size - start_ob); ob->weight = htons(bucket->weight); @@ -5815,8 +5821,9 @@ ofputil_encode_group_mod(enum ofp_version ofp_version, start_bucket = b->size; ofpbuf_put_uninit(b, sizeof *ob); if (bucket->ofpacts && bucket->ofpacts_len) { - ofpacts_put_openflow11_actions(bucket->ofpacts, - bucket->ofpacts_len, b); + ofpacts_put_openflow_actions(bucket->ofpacts, + bucket->ofpacts_len, b, + ofp_version); } ob = ofpbuf_at_assert(b, start_bucket, sizeof *ob); ob->len = htons(b->size - start_bucket);; diff --git a/lib/ofp-util.h b/lib/ofp-util.h index f998e09..17d14c0 100644 --- a/lib/ofp-util.h +++ b/lib/ofp-util.h @@ -979,7 +979,8 @@ int ofputil_decode_group_desc_reply(struct ofputil_group_desc *, void ofputil_append_group_desc_reply(const struct ofputil_group_desc *, struct list *buckets, - struct list *replies); + struct list *replies, + enum ofp_version); struct ofpbuf *ofputil_encode_group_desc_request(enum ofp_version); void diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c index fe004b5..ef81889 100644 --- a/ofproto/ofproto.c +++ b/ofproto/ofproto.c @@ -2799,7 +2799,7 @@ reject_slave_controller(struct ofconn *ofconn) */ static enum ofperr ofproto_check_ofpacts(struct ofproto *ofproto, - const struct ofpact ofpacts[], size_t ofpacts_len, + struct ofpact ofpacts[], size_t ofpacts_len, struct flow *flow, uint8_t table_id) { enum ofperr error; @@ -5359,7 +5359,8 @@ handle_group_desc_stats_request(struct ofconn *ofconn, HMAP_FOR_EACH (group, hmap_node, &ofproto->groups) { gds.group_id = group->group_id; gds.type = group->type; - ofputil_append_group_desc_reply(&gds, &group->buckets, &replies); + ofputil_append_group_desc_reply(&gds, &group->buckets, &replies, + request->version); } ovs_rwlock_unlock(&ofproto->groups_rwlock); diff --git a/tests/ovs-ofctl.at b/tests/ovs-ofctl.at index 9ceb4a9..a196647 100644 --- a/tests/ovs-ofctl.at +++ b/tests/ovs-ofctl.at @@ -180,7 +180,7 @@ AT_SETUP([ovs-ofctl parse-flows (OpenFlow 1.2)]) AT_DATA([flows.txt], [[ # comment tcp,tp_src=123,actions=flood -in_port=LOCAL dl_vlan=9 dl_src=00:0A:E4:25:6B:B0 actions=drop +in_port=LOCAL dl_vlan=9 dl_src=00:0A:E4:25:6B:B0 actions=mod_vlan_vid:7,mod_vlan_pcp:2 udp dl_vlan_pcp=7 idle_timeout=5 actions=strip_vlan output:0 tcp,nw_src=192.168.0.3,tp_dst=80 actions=set_queue:37,output:1 udp,nw_src=192.168.0.3,tp_dst=53 actions=pop_queue,output:1 @@ -189,6 +189,10 @@ actions=note:41.42.43,note:00.01.02.03.04.05.06.07,note ipv6,actions=set_field:fe80:0123:4567:890a:a6ba:dbff:fefe:59fa->ipv6_src sctp actions=set_field:3334->sctp_src sctp actions=set_field:4445->sctp_dst +tcp actions=mod_tp_dst:1234 +udp actions=mod_tp_src:1111 +ip actions=mod_nw_src:10.1.1.2,mod_nw_dst:192.168.10.1,mod_nw_ttl:1,mod_nw_tos:16,mod_nw_ecn:2 +in_port=0 actions=mod_dl_src:11:22:33:44:55:66,mod_dl_dst:10:20:30:40:50:60 in_port=0 actions=resubmit:0 actions=sample(probability=12345,collector_set_id=23456,obs_domain_id=34567,obs_point_id=45678) ]]) @@ -199,7 +203,7 @@ AT_CHECK([[sed 's/ (xid=0x[0-9a-fA-F]*)//' stdout]], [0], [[usable protocols: NXM,OXM chosen protocol: OXM-OpenFlow12 OFPT_FLOW_MOD (OF1.2): ADD table:255 tcp,tp_src=123 actions=FLOOD -OFPT_FLOW_MOD (OF1.2): ADD table:255 in_port=LOCAL,dl_vlan=9,dl_src=00:0a:e4:25:6b:b0 actions=drop +OFPT_FLOW_MOD (OF1.2): ADD table:255 in_port=LOCAL,dl_vlan=9,dl_src=00:0a:e4:25:6b:b0 actions=set_field:7->vlan_vid,set_field:2->vlan_pcp OFPT_FLOW_MOD (OF1.2): ADD table:255 udp,dl_vlan_pcp=7 idle:5 actions=strip_vlan,output:0 OFPT_FLOW_MOD (OF1.2): ADD table:255 tcp,nw_src=192.168.0.3,tp_dst=80 actions=set_queue:37,output:1 OFPT_FLOW_MOD (OF1.2): ADD table:255 udp,nw_src=192.168.0.3,tp_dst=53 actions=pop_queue,output:1 @@ -208,6 +212,10 @@ OFPT_FLOW_MOD (OF1.2): ADD table:255 actions=note:41.42.43.00.00.00,note:00.01.0 OFPT_FLOW_MOD (OF1.2): ADD table:255 ipv6 actions=set_field:fe80:123:4567:890a:a6ba:dbff:fefe:59fa->ipv6_src OFPT_FLOW_MOD (OF1.2): ADD table:255 sctp actions=set_field:3334->sctp_src OFPT_FLOW_MOD (OF1.2): ADD table:255 sctp actions=set_field:4445->sctp_dst +OFPT_FLOW_MOD (OF1.2): ADD table:255 tcp actions=set_field:1234->tcp_dst +OFPT_FLOW_MOD (OF1.2): ADD table:255 udp actions=set_field:1111->udp_src +OFPT_FLOW_MOD (OF1.2): ADD table:255 ip actions=set_field:10.1.1.2->ip_src,set_field:192.168.10.1->ip_dst,set_field:1->nw_ttl,set_field:16->nw_tos,set_field:2->nw_ecn +OFPT_FLOW_MOD (OF1.2): ADD table:255 in_port=0 actions=set_field:11:22:33:44:55:66->eth_src,set_field:10:20:30:40:50:60->eth_dst OFPT_FLOW_MOD (OF1.2): ADD table:255 in_port=0 actions=resubmit:0 OFPT_FLOW_MOD (OF1.2): ADD table:255 actions=sample(probability=12345,collector_set_id=23456,obs_domain_id=34567,obs_point_id=45678) ]]) diff --git a/utilities/ovs-ofctl.c b/utilities/ovs-ofctl.c index 2b89755..5ec8f11 100644 --- a/utilities/ovs-ofctl.c +++ b/utilities/ovs-ofctl.c @@ -2802,7 +2802,8 @@ ofctl_parse_ofp10_actions(int argc OVS_UNUSED, char *argv[] OVS_UNUSED) /* Convert back to ofp10 actions and print differences from input. */ ofpbuf_init(&of10_out, 0); - ofpacts_put_openflow10(ofpacts.data, ofpacts.size, &of10_out); + ofpacts_put_openflow_actions(ofpacts.data, ofpacts.size, &of10_out, + OFP10_VERSION); print_differences("", of10_in.data, of10_in.size, of10_out.data, of10_out.size); @@ -2989,7 +2990,8 @@ ofctl_parse_ofp11_actions(int argc OVS_UNUSED, char *argv[] OVS_UNUSED) /* Convert back to ofp11 actions and print differences from input. */ ofpbuf_init(&of11_out, 0); - ofpacts_put_openflow11_actions(ofpacts.data, ofpacts.size, &of11_out); + ofpacts_put_openflow_actions(ofpacts.data, ofpacts.size, &of11_out, + OFP11_VERSION); print_differences("", of11_in.data, of11_in.size, of11_out.data, of11_out.size); @@ -3066,8 +3068,8 @@ ofctl_parse_ofp11_instructions(int argc OVS_UNUSED, char *argv[] OVS_UNUSED) /* Convert back to ofp11 instructions and print differences from * input. */ ofpbuf_init(&of11_out, 0); - ofpacts_put_openflow11_instructions(ofpacts.data, ofpacts.size, - &of11_out); + ofpacts_put_openflow_instructions(ofpacts.data, ofpacts.size, + &of11_out, OFP13_VERSION); print_differences("", of11_in.data, of11_in.size, of11_out.data, of11_out.size); -- 1.7.10.4 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev