case NX_LEARN_DST_OUTPUT:
if (spec->n_bits <= 16
|| is_all_zeros(value.u8, sizeof value - 2)) {
- uint16_t port = ntohs(value.be16[7]);
+ ofp_port_t port = u16_to_ofp(ntohs(value.be16[7]));
- if (port < OFPP_MAX
+ if (ofp_to_u16(port) < ofp_to_u16(OFPP_MAX)
|| port == OFPP_IN_PORT
|| port == OFPP_FLOOD
|| port == OFPP_LOCAL
fm->ofpacts_len = ofpacts->size;
}
+/* Perform a bitwise-OR on 'wc''s fields that are relevant as sources in
+ * the learn action 'learn'. */
+void
+learn_mask(const struct ofpact_learn *learn, struct flow_wildcards *wc)
+{
+ const struct ofpact_learn_spec *spec;
+ union mf_subvalue value;
+
+ memset(&value, 0xff, sizeof value);
+ for (spec = learn->specs; spec < &learn->specs[learn->n_specs]; spec++) {
+ if (spec->src_type == NX_LEARN_SRC_FIELD) {
+ mf_write_subfield_flow(&spec->src, &value, &wc->masks);
+ }
+ }
+}
+
static void
learn_parse_load_immediate(const char *s, struct ofpact_learn_spec *spec)
{
*
* Modifies 'arg'. */
void
-learn_parse(char *arg, const struct flow *flow, struct ofpbuf *ofpacts)
+learn_parse(char *arg, struct ofpbuf *ofpacts)
{
char *orig = xstrdup(arg);
char *name, *value;
struct ofpact_learn *learn;
struct match match;
- enum ofperr error;
learn = ofpact_put_LEARN(ofpacts);
learn->idle_timeout = OFP_FLOW_PERMANENT;
learn_parse_spec(orig, name, value, spec);
- /* Check prerequisites. */
- if (spec->src_type == NX_LEARN_SRC_FIELD
- && flow && !mf_are_prereqs_ok(spec->src.field, flow)) {
- ovs_fatal(0, "%s: cannot specify source field %s because "
- "prerequisites are not satisfied",
- orig, spec->src.field->name);
- }
- if ((spec->dst_type == NX_LEARN_DST_MATCH
- || spec->dst_type == NX_LEARN_DST_LOAD)
- && !mf_are_prereqs_ok(spec->dst.field, &match.flow)) {
- ovs_fatal(0, "%s: cannot specify destination field %s because "
- "prerequisites are not satisfied",
- orig, spec->dst.field->name);
- }
-
/* Update 'match' to allow for satisfying destination
* prerequisites. */
if (spec->src_type == NX_LEARN_SRC_IMMEDIATE
}
ofpact_update_len(ofpacts, &learn->ofpact);
- /* In theory the above should have caught any errors, but... */
- if (flow) {
- error = learn_check(learn, flow);
- if (error) {
- ovs_fatal(0, "%s: %s", orig, ofperr_to_string(error));
- }
- }
free(orig);
}