projects
/
openvswitch
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
netdev-linux: Cache error code from set-policing.
[openvswitch]
/
lib
/
learn.c
diff --git
a/lib/learn.c
b/lib/learn.c
index 167646217007b0c0b71c80ba732cf1ed308ca2fc..9ca8b65a3e152a5bdb2747697f67632c861e6639 100644
(file)
--- 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)
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;
}
|| 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);
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;
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:
break;
case NX_LEARN_DST_OUTPUT:
- ofputil_put_OFPAT_OUTPUT(&actions)->port = htons(value);
+ ofputil_put_OFPAT
10
_OUTPUT(&actions)->port = htons(value);
break;
}
}
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)
{
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));
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 {
} 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
/* 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);
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... */
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);
}
}
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->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));
}
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 (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***");
}
ds_put_cstr(s, ",***nonzero pad***");
}