X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=lib%2Fnx-match.c;h=bdb3a2ba7a02ba04f1c22ff518a8db551d8f5607;hb=74cc3969aff34f24c093905c427471ebfb219f0c;hp=e111000fc7be580682b4380402577aba186cf942;hpb=ec9f40dce11c7e81bc41d42e3bbfaaf8287165ce;p=sliver-openvswitch.git diff --git a/lib/nx-match.c b/lib/nx-match.c index e111000fc..bdb3a2ba7 100644 --- a/lib/nx-match.c +++ b/lib/nx-match.c @@ -568,12 +568,12 @@ nx_put_raw(struct ofpbuf *b, bool oxm, const struct match *match, BUILD_ASSERT_DECL(FLOW_WC_SEQ == 20); /* Metadata. */ - if (match->wc.masks.in_port) { - uint16_t in_port = flow->in_port; + if (match->wc.masks.in_port.ofp_port) { + ofp_port_t in_port = flow->in_port.ofp_port; if (oxm) { nxm_put_32(b, OXM_OF_IN_PORT, ofputil_port_to_ofp11(in_port)); } else { - nxm_put_16(b, NXM_OF_IN_PORT, htons(in_port)); + nxm_put_16(b, NXM_OF_IN_PORT, htons(ofp_to_u16(in_port))); } } @@ -744,7 +744,7 @@ oxm_put_match(struct ofpbuf *b, const struct match *match) match_len = nx_put_raw(b, true, match, cookie, cookie_mask) + sizeof *omh; ofpbuf_put_zeros(b, ROUND_UP(match_len, 8) - match_len); - omh = (struct ofp11_match_header *)((char *)b->data + start_len); + omh = ofpbuf_at(b, start_len, sizeof *omh); omh->type = htons(OFPMT_OXM); omh->length = htons(match_len); @@ -807,9 +807,9 @@ nx_match_to_string(const uint8_t *p, unsigned int match_len) } char * -oxm_match_to_string(const uint8_t *p, unsigned int match_len) +oxm_match_to_string(const struct ofpbuf *p, unsigned int match_len) { - const struct ofp11_match_header *omh = (struct ofp11_match_header *)p; + const struct ofp11_match_header *omh = p->data; uint16_t match_len_; struct ds s; @@ -837,7 +837,8 @@ oxm_match_to_string(const uint8_t *p, unsigned int match_len) goto err; } - return nx_match_to_string(p + sizeof *omh, match_len - sizeof *omh); + return nx_match_to_string(ofpbuf_at(p, sizeof *omh, 0), + match_len - sizeof *omh); err: return ds_steal_cstr(&s); @@ -997,57 +998,74 @@ oxm_match_from_string(const char *s, struct ofpbuf *b) match_len = nx_match_from_string_raw(s, b) + sizeof *omh; ofpbuf_put_zeros(b, ROUND_UP(match_len, 8) - match_len); - omh = (struct ofp11_match_header *)((char *)b->data + start_len); + omh = ofpbuf_at(b, start_len, sizeof *omh); omh->type = htons(OFPMT_OXM); omh->length = htons(match_len); return match_len; } -void +/* Parses 's' as a "move" action, in the form described in ovs-ofctl(8), into + * '*move'. + * + * Returns NULL if successful, otherwise a malloc()'d string describing the + * error. The caller is responsible for freeing the returned string. */ +char * WARN_UNUSED_RESULT nxm_parse_reg_move(struct ofpact_reg_move *move, const char *s) { const char *full_s = s; + char *error; - s = mf_parse_subfield(&move->src, s); + error = mf_parse_subfield__(&move->src, &s); + if (error) { + return error; + } if (strncmp(s, "->", 2)) { - ovs_fatal(0, "%s: missing `->' following source", full_s); + return xasprintf("%s: missing `->' following source", full_s); } s += 2; - s = mf_parse_subfield(&move->dst, s); - if (*s != '\0') { - ovs_fatal(0, "%s: trailing garbage following destination", full_s); + error = mf_parse_subfield(&move->dst, s); + if (error) { + return error; } if (move->src.n_bits != move->dst.n_bits) { - ovs_fatal(0, "%s: source field is %d bits wide but destination is " - "%d bits wide", full_s, - move->src.n_bits, move->dst.n_bits); + return xasprintf("%s: source field is %d bits wide but destination is " + "%d bits wide", full_s, + move->src.n_bits, move->dst.n_bits); } + return NULL; } -void +/* Parses 's' as a "load" action, in the form described in ovs-ofctl(8), into + * '*load'. + * + * Returns NULL if successful, otherwise a malloc()'d string describing the + * error. The caller is responsible for freeing the returned string. */ +char * WARN_UNUSED_RESULT nxm_parse_reg_load(struct ofpact_reg_load *load, const char *s) { const char *full_s = s; uint64_t value = strtoull(s, (char **) &s, 0); + char *error; if (strncmp(s, "->", 2)) { - ovs_fatal(0, "%s: missing `->' following value", full_s); + return xasprintf("%s: missing `->' following value", full_s); } s += 2; - s = mf_parse_subfield(&load->dst, s); - if (*s != '\0') { - ovs_fatal(0, "%s: trailing garbage following destination", full_s); + error = mf_parse_subfield(&load->dst, s); + if (error) { + return error; } if (load->dst.n_bits < 64 && (value >> load->dst.n_bits) != 0) { - ovs_fatal(0, "%s: value %"PRIu64" does not fit into %d bits", - full_s, value, load->dst.n_bits); + return xasprintf("%s: value %"PRIu64" does not fit into %d bits", + full_s, value, load->dst.n_bits); } load->subvalue.be64[0] = htonll(0); load->subvalue.be64[1] = htonll(value); + return NULL; } /* nxm_format_reg_move(), nxm_format_reg_load(). */ @@ -1279,11 +1297,15 @@ nxm_reg_load_to_nxast(const struct ofpact_reg_load *load, void nxm_execute_reg_move(const struct ofpact_reg_move *move, - struct flow *flow) + struct flow *flow, struct flow_wildcards *wc) { + union mf_subvalue mask_value; union mf_value src_value; union mf_value dst_value; + memset(&mask_value, 0xff, sizeof mask_value); + mf_write_subfield_flow(&move->src, &mask_value, &wc->masks); + mf_get_value(move->dst.field, flow, &dst_value); mf_get_value(move->src.field, flow, &src_value); bitwise_copy(&src_value, move->src.field->n_bytes, move->src.ofs, @@ -1312,13 +1334,27 @@ nxm_reg_load(const struct mf_subfield *dst, uint64_t src_data, } /* nxm_parse_stack_action, works for both push() and pop(). */ -void + +/* Parses 's' as a "push" or "pop" action, in the form described in + * ovs-ofctl(8), into '*stack_action'. + * + * Returns NULL if successful, otherwise a malloc()'d string describing the + * error. The caller is responsible for freeing the returned string. */ +char * WARN_UNUSED_RESULT nxm_parse_stack_action(struct ofpact_stack *stack_action, const char *s) { - s = mf_parse_subfield(&stack_action->subfield, s); + char *error; + + error = mf_parse_subfield__(&stack_action->subfield, &s); + if (error) { + return error; + } + if (*s != '\0') { - ovs_fatal(0, "%s: trailing garbage following push or pop", s); + return xasprintf("%s: trailing garbage following push or pop", s); } + + return NULL; } void @@ -1428,10 +1464,15 @@ nx_stack_pop(struct ofpbuf *stack) void nxm_execute_stack_push(const struct ofpact_stack *push, - const struct flow *flow, struct ofpbuf *stack) + const struct flow *flow, struct flow_wildcards *wc, + struct ofpbuf *stack) { + union mf_subvalue mask_value; union mf_subvalue dst_value; + memset(&mask_value, 0xff, sizeof mask_value); + mf_write_subfield_flow(&push->subfield, &mask_value, &wc->masks); + mf_read_subfield(&push->subfield, flow, &dst_value); nx_stack_push(stack, &dst_value); }