X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=lib%2Fofp-util.c;h=3487cbac14528c3a8aa24a9786803508209c28e9;hb=007948177581f3b3dad188221593d0e4bdca6ba0;hp=ddac77270e1b60c80ef7123d767f26121914cc02;hpb=2db65bf72c008cf7ee658d0b44744b39495ead14;p=sliver-openvswitch.git diff --git a/lib/ofp-util.c b/lib/ofp-util.c index ddac77270..3487cbac1 100644 --- a/lib/ofp-util.c +++ b/lib/ofp-util.c @@ -138,8 +138,7 @@ ofputil_cls_rule_from_match(const struct ofp_match *match, /* Initialize most of rule->flow. */ rule->flow.nw_src = match->nw_src; rule->flow.nw_dst = match->nw_dst; - rule->flow.in_port = (match->in_port == htons(OFPP_LOCAL) ? ODPP_LOCAL - : ntohs(match->in_port)); + rule->flow.in_port = ntohs(match->in_port); rule->flow.dl_type = ofputil_dl_type_from_openflow(match->dl_type); rule->flow.tp_src = match->tp_src; rule->flow.tp_dst = match->tp_dst; @@ -234,8 +233,7 @@ ofputil_cls_rule_to_match(const struct cls_rule *rule, struct ofp_match *match) /* Compose most of the match structure. */ match->wildcards = htonl(ofpfw); - match->in_port = htons(rule->flow.in_port == ODPP_LOCAL ? OFPP_LOCAL - : rule->flow.in_port); + match->in_port = htons(rule->flow.in_port); memcpy(match->dl_src, rule->flow.dl_src, ETH_ADDR_LEN); memcpy(match->dl_dst, rule->flow.dl_dst, ETH_ADDR_LEN); match->dl_type = ofputil_dl_type_to_openflow(rule->flow.dl_type); @@ -341,16 +339,27 @@ ofputil_lookup_openflow_message(const struct ofputil_msg_category *cat, const struct ofputil_msg_type **typep) { const struct ofputil_msg_type *type; + bool found; + found = false; for (type = cat->types; type < &cat->types[cat->n_types]; type++) { if (type->value == value) { - if (!ofputil_length_ok(cat, type, size)) { - return ofp_mkerr(OFPET_BAD_REQUEST, OFPBRC_BAD_LEN); + if (ofputil_length_ok(cat, type, size)) { + *typep = type; + return 0; } - *typep = type; - return 0; + + /* We found a matching command type but it had the wrong length. + * Probably this is just an error. However, a screwup means that + * NXT_SET_FLOW_FORMAT and NXT_FLOW_MOD_TABLE_ID have the same + * value. They do have different lengths, so we can distinguish + * them that way. */ + found = true; } } + if (found) { + return ofp_mkerr(OFPET_BAD_REQUEST, OFPBRC_BAD_LEN); + } VLOG_WARN_RL(&bad_ofmsg_rl, "received %s of unknown type %"PRIu32, cat->name, value); @@ -361,6 +370,9 @@ static int ofputil_decode_vendor(const struct ofp_header *oh, const struct ofputil_msg_type **typep) { + BUILD_ASSERT_DECL(sizeof(struct nxt_set_flow_format) + != sizeof(struct nxt_flow_mod_table_id)); + static const struct ofputil_msg_type nxt_messages[] = { { OFPUTIL_NXT_ROLE_REQUEST, NXT_ROLE_REQUEST, "NXT_ROLE_REQUEST", @@ -374,6 +386,10 @@ ofputil_decode_vendor(const struct ofp_header *oh, NXT_SET_FLOW_FORMAT, "NXT_SET_FLOW_FORMAT", sizeof(struct nxt_set_flow_format), 0 }, + { OFPUTIL_NXT_FLOW_MOD_TABLE_ID, + NXT_FLOW_MOD_TABLE_ID, "NXT_FLOW_MOD_TABLE_ID", + sizeof(struct nxt_flow_mod_table_id), 0 }, + { OFPUTIL_NXT_FLOW_MOD, NXT_FLOW_MOD, "NXT_FLOW_MOD", sizeof(struct nx_flow_mod), 8 }, @@ -852,15 +868,33 @@ ofputil_make_set_flow_format(enum nx_flow_format flow_format) return msg; } +/* Returns an OpenFlow message that can be used to turn the flow_mod_table_id + * extension on or off (according to 'flow_mod_table_id'). */ +struct ofpbuf * +ofputil_make_flow_mod_table_id(bool flow_mod_table_id) +{ + struct nxt_flow_mod_table_id *nfmti; + struct ofpbuf *msg; + + nfmti = make_nxmsg(sizeof *nfmti, NXT_FLOW_MOD_TABLE_ID, &msg); + nfmti->set = flow_mod_table_id; + return msg; +} + /* Converts an OFPT_FLOW_MOD or NXT_FLOW_MOD message 'oh' into an abstract * flow_mod in 'fm'. Returns 0 if successful, otherwise an OpenFlow error * code. * + * 'flow_mod_table_id' should be true if the NXT_FLOW_MOD_TABLE_ID extension is + * enabled, false otherwise. + * * Does not validate the flow_mod actions. */ int -ofputil_decode_flow_mod(struct flow_mod *fm, const struct ofp_header *oh) +ofputil_decode_flow_mod(struct flow_mod *fm, const struct ofp_header *oh, + bool flow_mod_table_id) { const struct ofputil_msg_type *type; + uint16_t command; struct ofpbuf b; ofpbuf_use_const(&b, oh, ntohs(oh->length)); @@ -900,7 +934,7 @@ ofputil_decode_flow_mod(struct flow_mod *fm, const struct ofp_header *oh) /* Translate the message. */ ofputil_cls_rule_from_match(&match, ntohs(ofm->priority), &fm->cr); fm->cookie = ofm->cookie; - fm->command = ntohs(ofm->command); + command = ntohs(ofm->command); fm->idle_timeout = ntohs(ofm->idle_timeout); fm->hard_timeout = ntohs(ofm->hard_timeout); fm->buffer_id = ntohl(ofm->buffer_id); @@ -925,7 +959,7 @@ ofputil_decode_flow_mod(struct flow_mod *fm, const struct ofp_header *oh) /* Translate the message. */ fm->cookie = nfm->cookie; - fm->command = ntohs(nfm->command); + command = ntohs(nfm->command); fm->idle_timeout = ntohs(nfm->idle_timeout); fm->hard_timeout = ntohs(nfm->hard_timeout); fm->buffer_id = ntohl(nfm->buffer_id); @@ -935,17 +969,34 @@ ofputil_decode_flow_mod(struct flow_mod *fm, const struct ofp_header *oh) NOT_REACHED(); } + if (flow_mod_table_id) { + fm->command = command & 0xff; + fm->table_id = command >> 8; + } else { + fm->command = command; + fm->table_id = 0xff; + } + return 0; } /* Converts 'fm' into an OFPT_FLOW_MOD or NXT_FLOW_MOD message according to - * 'flow_format' and returns the message. */ + * 'flow_format' and returns the message. + * + * 'flow_mod_table_id' should be true if the NXT_FLOW_MOD_TABLE_ID extension is + * enabled, false otherwise. */ struct ofpbuf * ofputil_encode_flow_mod(const struct flow_mod *fm, - enum nx_flow_format flow_format) + enum nx_flow_format flow_format, + bool flow_mod_table_id) { size_t actions_len = fm->n_actions * sizeof *fm->actions; struct ofpbuf *msg; + uint16_t command; + + command = (flow_mod_table_id + ? (fm->command & 0xff) | (fm->table_id << 8) + : fm->command); if (flow_format == NXFF_OPENFLOW10) { struct ofp_flow_mod *ofm; @@ -953,7 +1004,6 @@ ofputil_encode_flow_mod(const struct flow_mod *fm, msg = ofpbuf_new(sizeof *ofm + actions_len); ofm = put_openflow(sizeof *ofm, OFPT_FLOW_MOD, msg); ofputil_cls_rule_to_match(&fm->cr, &ofm->match); - ofm->cookie = fm->cookie; ofm->command = htons(fm->command); ofm->idle_timeout = htons(fm->idle_timeout); ofm->hard_timeout = htons(fm->hard_timeout); @@ -971,7 +1021,7 @@ ofputil_encode_flow_mod(const struct flow_mod *fm, nfm = msg->data; nfm->cookie = fm->cookie; - nfm->command = htons(fm->command); + nfm->command = htons(command); nfm->idle_timeout = htons(fm->idle_timeout); nfm->hard_timeout = htons(fm->hard_timeout); nfm->priority = htons(fm->cr.priority); @@ -1725,19 +1775,6 @@ make_echo_reply(const struct ofp_header *rq) return out; } -/* Converts the members of 'opp' from host to network byte order. */ -void -hton_ofp_phy_port(struct ofp_phy_port *opp) -{ - opp->port_no = htons(opp->port_no); - opp->config = htonl(opp->config); - opp->state = htonl(opp->state); - opp->curr = htonl(opp->curr); - opp->advertised = htonl(opp->advertised); - opp->supported = htonl(opp->supported); - opp->peer = htonl(opp->peer); -} - static int check_action_exact_len(const union ofp_action *a, unsigned int len, unsigned int required_len) @@ -1989,10 +2026,9 @@ validate_actions(const union ofp_action *actions, size_t n_actions, return 0; } -/* Returns true if 'action' outputs to 'port' (which must be in network byte - * order), false otherwise. */ +/* Returns true if 'action' outputs to 'port', false otherwise. */ bool -action_outputs_to_port(const union ofp_action *action, uint16_t port) +action_outputs_to_port(const union ofp_action *action, ovs_be16 port) { switch (ntohs(action->type)) { case OFPAT_OUTPUT: