X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=lib%2Flearn.c;h=9ca8b65a3e152a5bdb2747697f67632c861e6639;hb=c9f716683d1d4302f026764effc17554c93a8c9f;hp=167646217007b0c0b71c80ba732cf1ed308ca2fc;hpb=816fd533f85923c03cf8d9d6450bd9a0845d5160;p=openvswitch diff --git a/lib/learn.c b/lib/learn.c index 16764621..9ca8b65a 100644 --- a/lib/learn.c +++ b/lib/learn.c @@ -125,7 +125,7 @@ learn_check(const struct nx_action_learn *learn, const struct flow *flow) cls_rule_init_catchall(&rule, 0); if (learn->flags & ~htons(OFPFF_SEND_FLOW_REM) - || !is_all_zeros(learn->pad, sizeof learn->pad) + || learn->pad || learn->table_id == 0xff) { return OFPERR_OFPBAC_BAD_ARGUMENT; } @@ -209,6 +209,14 @@ learn_execute(const struct nx_action_learn *learn, const struct flow *flow, ofpbuf_init(&actions, 64); + if (learn->fin_idle_timeout || learn->fin_hard_timeout) { + struct nx_action_fin_timeout *naft; + + naft = ofputil_put_NXAST_FIN_TIMEOUT(&actions); + naft->fin_idle_timeout = learn->fin_idle_timeout; + naft->fin_hard_timeout = learn->fin_hard_timeout; + } + for (p = learn + 1, end = (char *) learn + ntohs(learn->len); p != end; ) { uint16_t header = ntohs(get_be16(&p)); int n_bits = header & NX_LEARN_N_BITS_MASK; @@ -247,7 +255,7 @@ learn_execute(const struct nx_action_learn *learn, const struct flow *flow, break; case NX_LEARN_DST_OUTPUT: - ofputil_put_OFPAT_OUTPUT(&actions)->port = htons(value); + ofputil_put_OFPAT10_OUTPUT(&actions)->port = htons(value); break; } } @@ -384,6 +392,17 @@ learn_parse_spec(const char *orig, char *name, char *value, } } +/* Parses 'arg' as a set of arguments to the "learn" action and appends a + * matching NXAST_LEARN action to 'b'. The format parsed is described in + * ovs-ofctl(8). + * + * Prints an error on stderr and aborts the program if 'arg' syntax is invalid. + * + * If 'flow' is nonnull, then it should be the flow from a cls_rule that is + * the matching rule for the learning action. This helps to better validate + * the action's arguments. + * + * Modifies 'arg'. */ void learn_parse(struct ofpbuf *b, char *arg, const struct flow *flow) { @@ -420,6 +439,10 @@ learn_parse(struct ofpbuf *b, char *arg, const struct flow *flow) learn->idle_timeout = htons(atoi(value)); } else if (!strcmp(name, "hard_timeout")) { learn->hard_timeout = htons(atoi(value)); + } else if (!strcmp(name, "fin_idle_timeout")) { + learn->fin_idle_timeout = htons(atoi(value)); + } else if (!strcmp(name, "fin_hard_timeout")) { + learn->fin_hard_timeout = htons(atoi(value)); } else if (!strcmp(name, "cookie")) { learn->cookie = htonll(strtoull(value, NULL, 0)); } else { @@ -429,7 +452,7 @@ learn_parse(struct ofpbuf *b, char *arg, const struct flow *flow) /* Check prerequisites. */ if (spec.src_type == NX_LEARN_SRC_FIELD - && !mf_are_prereqs_ok(spec.src.field, flow)) { + && 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); @@ -487,9 +510,11 @@ learn_parse(struct ofpbuf *b, char *arg, const struct flow *flow) learn->len = htons(b->size - learn_ofs); /* In theory the above should have caught any errors, but... */ - error = learn_check(learn, flow); - if (error) { - ovs_fatal(0, "%s: %s", orig, ofperr_to_string(error)); + if (flow) { + error = learn_check(learn, flow); + if (error) { + ovs_fatal(0, "%s: %s", orig, ofperr_to_string(error)); + } } free(orig); } @@ -509,6 +534,14 @@ learn_format(const struct nx_action_learn *learn, struct ds *s) if (learn->hard_timeout != htons(OFP_FLOW_PERMANENT)) { ds_put_format(s, ",hard_timeout=%"PRIu16, ntohs(learn->hard_timeout)); } + if (learn->fin_idle_timeout) { + ds_put_format(s, ",fin_idle_timeout=%"PRIu16, + ntohs(learn->fin_idle_timeout)); + } + if (learn->fin_hard_timeout) { + ds_put_format(s, ",fin_hard_timeout=%"PRIu16, + ntohs(learn->fin_hard_timeout)); + } if (learn->priority != htons(OFP_DEFAULT_PRIORITY)) { ds_put_format(s, ",priority=%"PRIu16, ntohs(learn->priority)); } @@ -522,7 +555,7 @@ learn_format(const struct nx_action_learn *learn, struct ds *s) if (learn->cookie != htonll(0)) { ds_put_format(s, ",cookie=0x%"PRIx64, ntohll(learn->cookie)); } - if (!is_all_zeros(learn->pad, sizeof learn->pad)) { + if (learn->pad != 0) { ds_put_cstr(s, ",***nonzero pad***"); }