diff options
Diffstat (limited to 'lib/learn.c')
-rw-r--r-- | lib/learn.c | 212 |
1 files changed, 0 insertions, 212 deletions
diff --git a/lib/learn.c b/lib/learn.c index c5797ebba..e1c73cb50 100644 --- a/lib/learn.c +++ b/lib/learn.c @@ -30,145 +30,6 @@ #include "openflow/openflow.h" #include "unaligned.h" -static ovs_be16 -get_be16(const void **pp) -{ - const ovs_be16 *p = *pp; - ovs_be16 value = *p; - *pp = p + 1; - return value; -} - -static ovs_be32 -get_be32(const void **pp) -{ - const ovs_be32 *p = *pp; - ovs_be32 value = get_unaligned_be32(p); - *pp = p + 1; - return value; -} - -static void -get_subfield(int n_bits, const void **p, struct mf_subfield *sf) -{ - sf->field = mf_from_nxm_header(ntohl(get_be32(p))); - sf->ofs = ntohs(get_be16(p)); - sf->n_bits = n_bits; -} - -static unsigned int -learn_min_len(uint16_t header) -{ - int n_bits = header & NX_LEARN_N_BITS_MASK; - int src_type = header & NX_LEARN_SRC_MASK; - int dst_type = header & NX_LEARN_DST_MASK; - unsigned int min_len; - - min_len = 0; - if (src_type == NX_LEARN_SRC_FIELD) { - min_len += sizeof(ovs_be32); /* src_field */ - min_len += sizeof(ovs_be16); /* src_ofs */ - } else { - min_len += DIV_ROUND_UP(n_bits, 16); - } - if (dst_type == NX_LEARN_DST_MATCH || - dst_type == NX_LEARN_DST_LOAD) { - min_len += sizeof(ovs_be32); /* dst_field */ - min_len += sizeof(ovs_be16); /* dst_ofs */ - } - return min_len; -} - -/* Converts 'nal' into a "struct ofpact_learn" and appends that struct to - * 'ofpacts'. Returns 0 if successful, otherwise an OFPERR_*. */ -enum ofperr -learn_from_openflow(const struct nx_action_learn *nal, struct ofpbuf *ofpacts) -{ - struct ofpact_learn *learn; - const void *p, *end; - - if (nal->pad) { - return OFPERR_OFPBAC_BAD_ARGUMENT; - } - - learn = ofpact_put_LEARN(ofpacts); - - learn->idle_timeout = ntohs(nal->idle_timeout); - learn->hard_timeout = ntohs(nal->hard_timeout); - learn->priority = ntohs(nal->priority); - learn->cookie = nal->cookie; - learn->table_id = nal->table_id; - learn->fin_idle_timeout = ntohs(nal->fin_idle_timeout); - learn->fin_hard_timeout = ntohs(nal->fin_hard_timeout); - - learn->flags = ntohs(nal->flags); - if (learn->flags & ~(NX_LEARN_F_SEND_FLOW_REM | - NX_LEARN_F_DELETE_LEARNED)) { - return OFPERR_OFPBAC_BAD_ARGUMENT; - } - - if (learn->table_id == 0xff) { - return OFPERR_OFPBAC_BAD_ARGUMENT; - } - - end = (char *) nal + ntohs(nal->len); - for (p = nal + 1; p != end; ) { - struct ofpact_learn_spec *spec; - uint16_t header = ntohs(get_be16(&p)); - - if (!header) { - break; - } - - spec = ofpbuf_put_zeros(ofpacts, sizeof *spec); - learn = ofpacts->frame; - learn->n_specs++; - - spec->src_type = header & NX_LEARN_SRC_MASK; - spec->dst_type = header & NX_LEARN_DST_MASK; - spec->n_bits = header & NX_LEARN_N_BITS_MASK; - - /* Check for valid src and dst type combination. */ - if (spec->dst_type == NX_LEARN_DST_MATCH || - spec->dst_type == NX_LEARN_DST_LOAD || - (spec->dst_type == NX_LEARN_DST_OUTPUT && - spec->src_type == NX_LEARN_SRC_FIELD)) { - /* OK. */ - } else { - return OFPERR_OFPBAC_BAD_ARGUMENT; - } - - /* Check that the arguments don't overrun the end of the action. */ - if ((char *) end - (char *) p < learn_min_len(header)) { - return OFPERR_OFPBAC_BAD_LEN; - } - - /* Get the source. */ - if (spec->src_type == NX_LEARN_SRC_FIELD) { - get_subfield(spec->n_bits, &p, &spec->src); - } else { - int p_bytes = 2 * DIV_ROUND_UP(spec->n_bits, 16); - - bitwise_copy(p, p_bytes, 0, - &spec->src_imm, sizeof spec->src_imm, 0, - spec->n_bits); - p = (const uint8_t *) p + p_bytes; - } - - /* Get the destination. */ - if (spec->dst_type == NX_LEARN_DST_MATCH || - spec->dst_type == NX_LEARN_DST_LOAD) { - get_subfield(spec->n_bits, &p, &spec->dst); - } - } - ofpact_update_len(ofpacts, &learn->ofpact); - - if (!is_all_zeros(p, (char *) end - (char *) p)) { - return OFPERR_OFPBAC_BAD_ARGUMENT; - } - - return 0; -} /* Checks that 'learn' is a valid action on 'flow'. Returns 0 if it is valid, * otherwise an OFPERR_*. */ @@ -216,79 +77,6 @@ learn_check(const struct ofpact_learn *learn, const struct flow *flow) return 0; } -static void -put_be16(struct ofpbuf *b, ovs_be16 x) -{ - ofpbuf_put(b, &x, sizeof x); -} - -static void -put_be32(struct ofpbuf *b, ovs_be32 x) -{ - ofpbuf_put(b, &x, sizeof x); -} - -static void -put_u16(struct ofpbuf *b, uint16_t x) -{ - put_be16(b, htons(x)); -} - -static void -put_u32(struct ofpbuf *b, uint32_t x) -{ - put_be32(b, htonl(x)); -} - -/* Converts 'learn' into a "struct nx_action_learn" and appends that action to - * 'ofpacts'. */ -void -learn_to_nxast(const struct ofpact_learn *learn, struct ofpbuf *openflow) -{ - const struct ofpact_learn_spec *spec; - struct nx_action_learn *nal; - size_t start_ofs; - - start_ofs = ofpbuf_size(openflow); - nal = ofputil_put_NXAST_LEARN(openflow); - nal->idle_timeout = htons(learn->idle_timeout); - nal->hard_timeout = htons(learn->hard_timeout); - nal->fin_idle_timeout = htons(learn->fin_idle_timeout); - nal->fin_hard_timeout = htons(learn->fin_hard_timeout); - nal->priority = htons(learn->priority); - nal->cookie = learn->cookie; - nal->flags = htons(learn->flags); - nal->table_id = learn->table_id; - - for (spec = learn->specs; spec < &learn->specs[learn->n_specs]; spec++) { - put_u16(openflow, spec->n_bits | spec->dst_type | spec->src_type); - - if (spec->src_type == NX_LEARN_SRC_FIELD) { - put_u32(openflow, spec->src.field->nxm_header); - put_u16(openflow, spec->src.ofs); - } else { - size_t n_dst_bytes = 2 * DIV_ROUND_UP(spec->n_bits, 16); - uint8_t *bits = ofpbuf_put_zeros(openflow, n_dst_bytes); - bitwise_copy(&spec->src_imm, sizeof spec->src_imm, 0, - bits, n_dst_bytes, 0, - spec->n_bits); - } - - if (spec->dst_type == NX_LEARN_DST_MATCH || - spec->dst_type == NX_LEARN_DST_LOAD) { - put_u32(openflow, spec->dst.field->nxm_header); - put_u16(openflow, spec->dst.ofs); - } - } - - if ((ofpbuf_size(openflow) - start_ofs) % 8) { - ofpbuf_put_zeros(openflow, 8 - (ofpbuf_size(openflow) - start_ofs) % 8); - } - - nal = ofpbuf_at_assert(openflow, start_ofs, sizeof *nal); - nal->len = htons(ofpbuf_size(openflow) - start_ofs); -} - /* Composes 'fm' so that executing it will implement 'learn' given that the * packet being processed has 'flow' as its flow. * |