X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=lib%2Flearn.c;h=9d97cb35cdfd28747ec066f5600d7f8de6df9ab3;hb=acd051f1761569205827dc9b037e15568a8d59f8;hp=9f95a13126f89878921846698fd930e3289c5c7a;hpb=4cb3fde7c9224ca4f939852c5e7987fc5112d680;p=openvswitch diff --git a/lib/learn.c b/lib/learn.c index 9f95a131..9d97cb35 100644 --- a/lib/learn.c +++ b/lib/learn.c @@ -169,7 +169,7 @@ learn_check(const struct nx_action_learn *learn, const struct flow *flow) if (dst_type == NX_LEARN_DST_MATCH && src_type == NX_LEARN_SRC_IMMEDIATE) { - mf_set_subfield(nxm_field_to_mf_field(ntohl(dst_field)), value, + mf_set_subfield(mf_from_nxm_header(ntohl(dst_field)), value, dst_ofs, n_bits, &rule); } } @@ -232,7 +232,7 @@ learn_execute(const struct nx_action_learn *learn, const struct flow *flow, case NX_LEARN_DST_MATCH: dst_field = get_be32(&p); dst_ofs = ntohs(get_be16(&p)); - mf_set_subfield(nxm_field_to_mf_field(ntohl(dst_field)), value, + mf_set_subfield(mf_from_nxm_header(ntohl(dst_field)), value, dst_ofs, n_bits, &fm->cr); break; @@ -346,10 +346,10 @@ learn_parse_spec(const char *orig, char *name, char *value, spec->n_bits = n_bits; spec->src_type = NX_LEARN_SRC_FIELD; - spec->src = nxm_field_to_mf_field(src_header); + spec->src = mf_from_nxm_header(src_header); spec->src_ofs = src_ofs; spec->dst_type = NX_LEARN_DST_MATCH; - spec->dst = nxm_field_to_mf_field(dst_header); + spec->dst = mf_from_nxm_header(dst_header); spec->dst_ofs = 0; } else if (!strcmp(name, "load")) { if (value[strcspn(value, "[-")] == '-') { @@ -371,7 +371,7 @@ learn_parse_spec(const char *orig, char *name, char *value, spec->src_imm[i] = imm >> ((imm_bytes - i - 1) * 8); } spec->dst_type = NX_LEARN_DST_LOAD; - spec->dst = nxm_field_to_mf_field(ntohl(load.dst)); + spec->dst = mf_from_nxm_header(ntohl(load.dst)); spec->dst_ofs = nxm_decode_ofs(load.ofs_nbits); } else { struct nx_action_reg_move move; @@ -380,10 +380,10 @@ learn_parse_spec(const char *orig, char *name, char *value, spec->n_bits = ntohs(move.n_bits); spec->src_type = NX_LEARN_SRC_FIELD; - spec->src = nxm_field_to_mf_field(ntohl(move.src)); + spec->src = mf_from_nxm_header(ntohl(move.src)); spec->src_ofs = ntohs(move.src_ofs); spec->dst_type = NX_LEARN_DST_LOAD; - spec->dst = nxm_field_to_mf_field(ntohl(move.dst)); + spec->dst = mf_from_nxm_header(ntohl(move.dst)); spec->dst_ofs = ntohs(move.dst_ofs); } } else if (!strcmp(name, "output")) { @@ -397,7 +397,7 @@ learn_parse_spec(const char *orig, char *name, char *value, spec->n_bits = n_bits; spec->src_type = NX_LEARN_SRC_FIELD; - spec->src = nxm_field_to_mf_field(header); + spec->src = mf_from_nxm_header(header); spec->src_ofs = ofs; spec->dst_type = NX_LEARN_DST_OUTPUT; spec->dst = NULL; @@ -605,7 +605,7 @@ learn_format(const struct nx_action_learn *learn, struct ds *s) /* Get the destination. */ if (dst_type == NX_LEARN_DST_MATCH || dst_type == NX_LEARN_DST_LOAD) { dst_header = ntohl(get_be32(&p)); - dst_field = nxm_field_to_mf_field(dst_header); + dst_field = mf_from_nxm_header(dst_header); dst_ofs = ntohs(get_be16(&p)); } else { dst_header = 0; @@ -621,6 +621,17 @@ learn_format(const struct nx_action_learn *learn, struct ds *s) union mf_value value; uint8_t *bytes = (uint8_t *) &value; + if (src_value_bytes > dst_field->n_bytes) { + /* The destination field is an odd number of bytes, which + * got rounded up to a multiple of 2 to be put into the + * learning action. Skip over the leading byte, which + * should be zero anyway. Otherwise the memcpy() below + * will overrun the start of 'value'. */ + int diff = src_value_bytes - dst_field->n_bytes; + src_value += diff; + src_value_bytes -= diff; + } + memset(&value, 0, sizeof value); memcpy(&bytes[dst_field->n_bytes - src_value_bytes], src_value, src_value_bytes);